Add implementation of TLS-1.2 PSK-to-MS key derivation

This commit is contained in:
Hanno Becker 2018-11-16 11:35:34 +00:00
parent 8dbfca4628
commit 1aaedc03d4

View File

@ -3275,7 +3275,9 @@ psa_status_t psa_generator_abort( psa_crypto_generator_t *generator )
mbedtls_free( generator->ctx.hkdf.info );
status = psa_hmac_abort_internal( &generator->ctx.hkdf.hmac );
}
else if( PSA_ALG_IS_TLS12_PRF( generator->alg ) )
else if( PSA_ALG_IS_TLS12_PRF( generator->alg ) ||
/* TLS-1.2 PSK-to-MS KDF uses the same generator as TLS-1.2 PRF */
PSA_ALG_IS_TLS12_PSK_TO_MS( generator->alg ) )
{
if( generator->ctx.tls12_prf.key != NULL )
{
@ -3578,7 +3580,8 @@ psa_status_t psa_generator_read( psa_crypto_generator_t *generator,
status = psa_generator_hkdf_read( &generator->ctx.hkdf, hash_alg,
output, output_length );
}
else if( PSA_ALG_IS_TLS12_PRF( generator->alg ) )
else if( PSA_ALG_IS_TLS12_PRF( generator->alg ) ||
PSA_ALG_IS_TLS12_PSK_TO_MS( generator->alg ) )
{
status = psa_generator_tls12_prf_read( &generator->ctx.tls12_prf,
generator->alg, output,
@ -3749,6 +3752,47 @@ static psa_status_t psa_generator_tls12_prf_setup(
return( PSA_SUCCESS );
}
/* Set up a TLS-1.2-PSK-to-MS-based generator. */
static psa_status_t psa_generator_tls12_psk_to_ms_setup(
psa_tls12_prf_generator_t *tls12_prf,
const unsigned char *psk,
size_t psk_len,
psa_algorithm_t hash_alg,
const uint8_t *salt,
size_t salt_length,
const uint8_t *label,
size_t label_length )
{
psa_status_t status;
unsigned char pms[ 4 + 2 * PSA_ALG_TLS12_PSK_TO_MS_MAX_PSK_LEN ];
if( psk_len > PSA_ALG_TLS12_PSK_TO_MS_MAX_PSK_LEN )
return( PSA_ERROR_INVALID_ARGUMENT );
/* Quoting RFC 4279, Section 2:
*
* The premaster secret is formed as follows: if the PSK is N octets
* long, concatenate a uint16 with the value N, N zero octets, a second
* uint16 with the value N, and the PSK itself.
*/
pms[0] = ( psk_len >> 8 ) & 0xff;
pms[1] = ( psk_len >> 0 ) & 0xff;
memset( pms + 2, 0, psk_len );
pms[2 + psk_len + 0] = pms[0];
pms[2 + psk_len + 1] = pms[1];
memcpy( pms + 4 + psk_len, psk, psk_len );
status = psa_generator_tls12_prf_setup( tls12_prf,
pms, 4 + 2 * psk_len,
hash_alg,
salt, salt_length,
label, label_length );
mbedtls_zeroize( pms, sizeof( pms ) );
return( status );
}
#endif /* MBEDTLS_MD_C */
/* Note that if this function fails, you must call psa_generator_abort()
@ -3799,7 +3843,9 @@ static psa_status_t psa_key_derivation_internal(
salt, salt_length,
label, label_length );
}
else if( PSA_ALG_IS_TLS12_PRF( alg ) )
/* TLS-1.2 PRF and TLS-1.2 PSK-to-MS are very similar, so share code. */
else if( PSA_ALG_IS_TLS12_PRF( alg ) ||
PSA_ALG_IS_TLS12_PSK_TO_MS( alg ) )
{
psa_algorithm_t hash_alg = PSA_ALG_TLS12_PRF_GET_HASH( alg );
size_t hash_size = PSA_HASH_SIZE( hash_alg );
@ -3812,10 +3858,22 @@ static psa_status_t psa_key_derivation_internal(
}
max_capacity = 255 * hash_size;
status = psa_generator_tls12_prf_setup( &generator->ctx.tls12_prf,
secret, secret_length,
hash_alg, salt, salt_length,
label, label_length );
if( PSA_ALG_IS_TLS12_PRF( alg ) )
{
status = psa_generator_tls12_prf_setup( &generator->ctx.tls12_prf,
secret, secret_length,
hash_alg, salt, salt_length,
label, label_length );
}
else
{
status = psa_generator_tls12_psk_to_ms_setup(
&generator->ctx.tls12_prf,
secret, secret_length,
hash_alg, salt, salt_length,
label, label_length );
}
}
else
#endif