Skip to content

TLS 1.2 doesn't work with an opaque key for deterministic ECDSA #10220

Open
@gilles-peskine-arm

Description

@gilles-peskine-arm

In Mbed TLS 3.6, a PSA key pair whose policy restricts it to deterministic ECDSA cannot be used for TLS 1.2.

Note that this is the default policy for an ECC signature key created using mbedtls_pk_get_psa_attributes() and mbedtls_pk_import_into_psa(), so this may impact applications written for Mbed TLS 3.x that are transitioning to PSA for compatibility with Mbed TLS 4.x.

Analysis

Consider a TLS 1.2 server using a cipher suite that involves an ECDSA signature. The private key passed to mbedtls_ssl_conf_own_cert() can either be a built-in key (mbedtls_ecp_context) or an opaque key stored in PSA. When the key is an opaque key, its policy must include PSA_ALG_ECDSA(hash): PSA_ALG_DETERMINISTIC_ECDSA(hash) won't do, even though the two are effectively indistinguishable.

Observed in both 3.6.3 and in my work on #10075 while preparing 4.0. It doesn't matter whether the PSA key is exportable or not.

TLS 1.3 works as expected (private keys can indifferently impose deterministic or randomized ECDSA).

In test logs, I see:

Server: ssl_tls12_server.c:0772: |3| 0x7ffe0b5a21f8: trying ciphersuite: 0xcca9 (TLS-ECDHE-ECDSA-WITH-CHACHA20-POLY1305-SHA256)
Server: ssl_tls12_server.c:0682: |3| 0x7ffe0b5a21f8: ciphersuite requires certificate
Server: ssl_tls12_server.c:0691: |3| 0x7ffe0b5a21f8: candidate certificate chain, certificate #1:
Server: ssl_tls12_server.c:0691: |3| 0x7ffe0b5a21f8: cert. version     : 3
Server: ssl_tls12_server.c:0691: |3| 0x7ffe0b5a21f8: serial number     : 09
Server: ssl_tls12_server.c:0691: |3| 0x7ffe0b5a21f8: issuer name       : C=NL, O=PolarSSL, CN=Polarssl Test EC CA
Server: ssl_tls12_server.c:0691: |3| 0x7ffe0b5a21f8: subject name      : C=NL, O=PolarSSL, CN=localhost
Server: ssl_tls12_server.c:0691: |3| 0x7ffe0b5a21f8: issued  on        : 2023-05-17 07:10:36
Server: ssl_tls12_server.c:0691: |3| 0x7ffe0b5a21f8: expires on        : 2033-05-14 07:10:36
Server: ssl_tls12_server.c:0691: |3| 0x7ffe0b5a21f8: signed using      : ECDSA with SHA256
Server: ssl_tls12_server.c:0691: |3| 0x7ffe0b5a21f8: EC key size       : 256 bits
Server: ssl_tls12_server.c:0691: |3| 0x7ffe0b5a21f8: basic constraints : CA=false
Server: ssl_tls12_server.c:0691: |3| 0x7ffe0b5a21f8: value of 'crt->eckey.Q(X)' (254 bits) is:
Server: ssl_tls12_server.c:0691: |3| 0x7ffe0b5a21f8:  37 cc 56 d9 76 09 1e 5a 72 3e c7 59 2d ff 20 6e
Server: ssl_tls12_server.c:0691: |3| 0x7ffe0b5a21f8:  ee 7c f9 06 91 74 d0 ad 14 b5 f7 68 22 59 62 92
Server: ssl_tls12_server.c:0691: |3| 0x7ffe0b5a21f8: value of 'crt->eckey.Q(Y)' (255 bits) is:
Server: ssl_tls12_server.c:0691: |3| 0x7ffe0b5a21f8:  4e e5 00 d8 23 11 ff ea 2f d2 34 5d 5d 16 bd 8a
Server: ssl_tls12_server.c:0691: |3| 0x7ffe0b5a21f8:  88 c2 6b 77 0d 55 cd 8a 2a 0e fa 01 c8 b4 ed ff
Server: ssl_tls12_server.c:0704: |3| 0x7ffe0b5a21f8: certificate mismatch: key type
Server: ssl_tls12_server.c:0823: |3| 0x7ffe0b5a21f8: ciphersuite mismatch: no suitable certificate

The same test with a key whose policy says PSA_ALG_ECDSA(PSA_ALG_ANY_HASH) instead of PSA_ALG_DETERMINISTIC_ECDSA(PSA_ALG_ANY_HASH):

Server: ssl_tls12_server.c:0772: |3| 0x7ffe0b5a21f8: trying ciphersuite: 0xcca9 (TLS-ECDHE-ECDSA-WITH-CHACHA20-POLY1305-SHA256)
Server: ssl_tls12_server.c:0682: |3| 0x7ffe0b5a21f8: ciphersuite requires certificate
Server: ssl_tls12_server.c:0691: |3| 0x7ffe0b5a21f8: candidate certificate chain, certificate #1:
Server: ssl_tls12_server.c:0691: |3| 0x7ffe0b5a21f8: cert. version     : 3
Server: ssl_tls12_server.c:0691: |3| 0x7ffe0b5a21f8: serial number     : 09
Server: ssl_tls12_server.c:0691: |3| 0x7ffe0b5a21f8: issuer name       : C=NL, O=PolarSSL, CN=Polarssl Test EC CA
Server: ssl_tls12_server.c:0691: |3| 0x7ffe0b5a21f8: subject name      : C=NL, O=PolarSSL, CN=localhost
Server: ssl_tls12_server.c:0691: |3| 0x7ffe0b5a21f8: issued  on        : 2023-05-17 07:10:36
Server: ssl_tls12_server.c:0691: |3| 0x7ffe0b5a21f8: expires on        : 2033-05-14 07:10:36
Server: ssl_tls12_server.c:0691: |3| 0x7ffe0b5a21f8: signed using      : ECDSA with SHA256
Server: ssl_tls12_server.c:0691: |3| 0x7ffe0b5a21f8: EC key size       : 256 bits
Server: ssl_tls12_server.c:0691: |3| 0x7ffe0b5a21f8: basic constraints : CA=false
Server: ssl_tls12_server.c:0691: |3| 0x7ffe0b5a21f8: value of 'crt->eckey.Q(X)' (254 bits) is:
Server: ssl_tls12_server.c:0691: |3| 0x7ffe0b5a21f8:  37 cc 56 d9 76 09 1e 5a 72 3e c7 59 2d ff 20 6e
Server: ssl_tls12_server.c:0691: |3| 0x7ffe0b5a21f8:  ee 7c f9 06 91 74 d0 ad 14 b5 f7 68 22 59 62 92
Server: ssl_tls12_server.c:0691: |3| 0x7ffe0b5a21f8: value of 'crt->eckey.Q(Y)' (255 bits) is:
Server: ssl_tls12_server.c:0691: |3| 0x7ffe0b5a21f8:  4e e5 00 d8 23 11 ff ea 2f d2 34 5d 5d 16 bd 8a
Server: ssl_tls12_server.c:0691: |3| 0x7ffe0b5a21f8:  88 c2 6b 77 0d 55 cd 8a 2a 0e fa 01 c8 b4 ed ff
Server: ssl_tls12_server.c:0741: |3| 0x7ffe0b5a21f8: selected certificate chain, certificate #1:
Server: ssl_tls12_server.c:0741: |3| 0x7ffe0b5a21f8: cert. version     : 3
Server: ssl_tls12_server.c:0741: |3| 0x7ffe0b5a21f8: serial number     : 09
Server: ssl_tls12_server.c:0741: |3| 0x7ffe0b5a21f8: issuer name       : C=NL, O=PolarSSL, CN=Polarssl Test EC CA
Server: ssl_tls12_server.c:0741: |3| 0x7ffe0b5a21f8: subject name      : C=NL, O=PolarSSL, CN=localhost
Server: ssl_tls12_server.c:0741: |3| 0x7ffe0b5a21f8: issued  on        : 2023-05-17 07:10:36
Server: ssl_tls12_server.c:0741: |3| 0x7ffe0b5a21f8: expires on        : 2033-05-14 07:10:36
Server: ssl_tls12_server.c:0741: |3| 0x7ffe0b5a21f8: signed using      : ECDSA with SHA256
Server: ssl_tls12_server.c:0741: |3| 0x7ffe0b5a21f8: EC key size       : 256 bits
Server: ssl_tls12_server.c:0741: |3| 0x7ffe0b5a21f8: basic constraints : CA=false
Server: ssl_tls12_server.c:0741: |3| 0x7ffe0b5a21f8: value of 'crt->eckey.Q(X)' (254 bits) is:
Server: ssl_tls12_server.c:0741: |3| 0x7ffe0b5a21f8:  37 cc 56 d9 76 09 1e 5a 72 3e c7 59 2d ff 20 6e
Server: ssl_tls12_server.c:0741: |3| 0x7ffe0b5a21f8:  ee 7c f9 06 91 74 d0 ad 14 b5 f7 68 22 59 62 92
Server: ssl_tls12_server.c:0741: |3| 0x7ffe0b5a21f8: value of 'crt->eckey.Q(Y)' (255 bits) is:
Server: ssl_tls12_server.c:0741: |3| 0x7ffe0b5a21f8:  4e e5 00 d8 23 11 ff ea 2f d2 34 5d 5d 16 bd 8a
Server: ssl_tls12_server.c:0741: |3| 0x7ffe0b5a21f8:  88 c2 6b 77 0d 55 cd 8a 2a 0e fa 01 c8 b4 ed ff
Server: ssl_tls12_server.c:1595: |2| 0x7ffe0b5a21f8: selected ciphersuite: TLS-ECDHE-ECDSA-WITH-CHACHA20-POLY1305-SHA256

Loosely related, but not the same root cause: #10208

Reproducer

6d2ba03 "Add PK opaque test case with deterministic ECDSA" in https://github.com/gilles-peskine-arm/mbedtls/tree/tls12-pk-psa-alg2-3.6

Root cause

Looking at the code, ssl_pick_cert for TLS 1.2 calls mbedtls_pk_can_do_ext() and insists on the specific ECDSA variant returned by mbedtls_ssl_get_ciphersuite_sig_pk_psa_alg(), which is PSA_ALG_ECDSA(hash) for ECDSA cipher suites. This function should also allow deterministic ECDSA.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugcomponent-tlssize-xsEstimated task size: extra small (a few hours at most)

    Type

    Projects

    Status

    No status

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions