Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mixed PSK 2b: support DHE-PSK #5664

Closed
mpg opened this issue Mar 28, 2022 · 3 comments · Fixed by #5704
Closed

Mixed PSK 2b: support DHE-PSK #5664

mpg opened this issue Mar 28, 2022 · 3 comments · Fixed by #5704
Assignees
Labels
enhancement size-s Estimated task size: small (~2d)

Comments

@mpg
Copy link
Contributor

mpg commented Mar 28, 2022

This task is to add support for DHE-PSK using PSA-held (aka opaque) keys, that is, keys provisioned with mbedtls_ssl_conf_psk_opaque() or mbedtls_ssl_set_hs_psk_opaque() (used in the PSK callback).

The task is done when there are passing tests in ssl-opt.sh using DHE-PSK with psk_opaque=1 with sufficient coverage (client and/or server, static conf and/or callback, see existing tests for pure PSK).

Depends on: #5662 (also provides context and references).
Related: #5663, #5665

@mpg mpg added enhancement Product Backlog size-s Estimated task size: small (~2d) labels Mar 28, 2022
@mpg mpg changed the title Mixed PSK 2a: support DHE-PSK Mixed PSK 2b: support DHE-PSK Mar 28, 2022
@mprse mprse self-assigned this Apr 5, 2022
@mprse
Copy link
Contributor

mprse commented Apr 15, 2022

Got a question regarding this one.
I'm reworking this PR and I want to handle RSA/ECDHE/DHE-PSK key exchange in one PR.
I got it working for RSA and ECDH, but got problem with DHE-SPK.

The PSA Mixed-PSK master key derivation is handled here (in this version only RSA-PSK is handled):

mbedtls/library/ssl_tls.c

Lines 5150 to 5199 in 36dc5b3

if( ( handshake->ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK ||
handshake->ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK ) &&
ssl_use_opaque_psk( ssl ) == 1 )
{
/* Perform PSK-to-MS expansion in a single step. */
psa_status_t status;
psa_algorithm_t alg;
mbedtls_svc_key_id_t psk;
psa_key_derivation_operation_t derivation =
PSA_KEY_DERIVATION_OPERATION_INIT;
mbedtls_md_type_t hash_alg = handshake->ciphersuite_info->mac;
MBEDTLS_SSL_DEBUG_MSG( 2, ( "perform PSA-based PSK-to-MS expansion" ) );
psk = mbedtls_ssl_get_opaque_psk( ssl );
if( hash_alg == MBEDTLS_MD_SHA384 )
alg = PSA_ALG_TLS12_PSK_TO_MS(PSA_ALG_SHA_384);
else
alg = PSA_ALG_TLS12_PSK_TO_MS(PSA_ALG_SHA_256);
size_t salt_len = 0;
unsigned char* salt = NULL;
if ( handshake->ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK )
{
/* Provide other key as salt.
* For RSA-PKS other key length is always 48 bytes.
* Other key is stored in premaster, where first 2 bytes hold the
* length of the other key. Skip them.
*/
salt_len = 48;
salt = handshake->premaster + 2;
}
status = setup_psa_key_derivation( &derivation, psk, alg,
seed, seed_len,
(unsigned char const *) lbl,
(size_t) strlen( lbl ),
salt, salt_len,
master_secret_len );
if( status != PSA_SUCCESS )
{
psa_key_derivation_abort( &derivation );
return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
}
status = psa_key_derivation_output_bytes( &derivation,
master,
master_secret_len );

The other secret needed for master key derivation is kept in premaster:

  • RSA
    if( ( ret = ssl_write_encrypted_pms( ssl, header_len,
    &content_len, 2 ) ) != 0 )
  • ECDHE
    status = psa_raw_key_agreement( PSA_ALG_ECDH,
    handshake->ecdh_psa_privkey,
    handshake->ecdh_psa_peerkey,
    handshake->ecdh_psa_peerkey_len,
    pms + zlen_size,
    pms_end - ( pms + zlen_size ),
    &zlen );

But for DHE seems that premaster is not filled in this part of code:
https://github.com/Mbed-TLS/mbedtls/blob/development/library/ssl_tls12_client.c#L3238-L3241

I focused here on client side only.

@gilles-peskine-arm
Copy link
Contributor

The PSA crypto layer doesn't support DH yet. USE_PSA_CRYPTO code can't support DHE until that's done.

I haven't followed when we've scheduled to do that — probably later, because non-EC DH isn't used much anymore.

@mpg
Copy link
Contributor Author

mpg commented Apr 19, 2022

Yes, sorry, I should have mentioned that bit of context in the task's description. For DHE-PSK, the DHE part will still be done by the legacy API, and only the derivation "DHE output + PSK -> MS" will be done by PSA. (More generally, for all the xxx-PSK tasks, no change is intended in the xxx part: either it has already been done in previous EPICs, or to be done later.)

The DHE part of the DHE-PSK key exchange goes as follows client-side:

  • In ssl_parse_server_key_exchange() we parse the server parameters and remember them.
  • In ssl_write_client_key_exchange() we pick our ephemeral private key and send the public part with mbedtls_dhm_make_public() and then later call mbedtls_ssl_psk_derive_premaster()
  • In mbedtls_ssl_psk_derive_premaster() (in ssl_tls.c!) we compute the shared secret with mbedtls_dhm_calc_secret() and write it to the PMS buffer.

The thing is, mbedtls_ssl_psk_derive_premaster() won't work unmodified with an opaque PSK key, so we probably need to arrange for it to skip the PSK part when we have an opaque key, and just leave the DHM shared secret in handshake->premaster when we'll pick it up later to pass to the PSA KDF.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement size-s Estimated task size: small (~2d)
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants