From 8dbfca462818038190f3690ae48b5ef6173fde26 Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Fri, 12 Oct 2018 11:56:55 +0100 Subject: [PATCH 1/6] Add TLS-1.2 PSK-to-MS key derivation algorithm identifier to PSA API --- include/psa/crypto.h | 39 ++++++++++++++++++++++++++++++++++++++ include/psa/crypto_sizes.h | 16 ++++++++++++++++ 2 files changed, 55 insertions(+) diff --git a/include/psa/crypto.h b/include/psa/crypto.h index 15c8130ef..bdddeca59 100644 --- a/include/psa/crypto.h +++ b/include/psa/crypto.h @@ -1232,6 +1232,45 @@ typedef uint32_t psa_algorithm_t; #define PSA_ALG_TLS12_PRF_GET_HASH(hkdf_alg) \ (PSA_ALG_CATEGORY_HASH | ((hkdf_alg) & PSA_ALG_HASH_MASK)) +#define PSA_ALG_TLS12_PSK_TO_MS_BASE ((psa_algorithm_t)0x30000300) +/** Macro to build a TLS-1.2 PSK-to-MasterSecret algorithm. + * + * For example, `PSA_ALG_TLS12_PSK_TO_MS(PSA_ALG_SHA256)` represents the + * TLS-1.2 PSK to MasterSecret derivation PRF using HMAC-SHA-256. + * + * \param hash_alg A hash algorithm (\c PSA_ALG_XXX value such that + * #PSA_ALG_IS_HASH(\p hash_alg) is true). + * + * \return The corresponding TLS-1.2 PSK to MS algorithm. + * \return Unspecified if \p alg is not a supported + * hash algorithm. + */ +#define PSA_ALG_TLS12_PSK_TO_MS(hash_alg) \ + (PSA_ALG_TLS12_PSK_TO_MS_BASE | ((hash_alg) & PSA_ALG_HASH_MASK)) + +/** Whether the specified algorithm is a TLS-1.2 PSK to MS algorithm. + * + * In a pure-PSK handshake in TLS 1.2, the master secret is derived + * from the PreSharedKey (PSK) through the application of padding and + * the TLS-1.2 PRF (see below). The latter is based on HMAC and can + * be used with either SHA-256 or SHA-384. + * + * For the application to TLS-1.2, the salt passed to psa_key_derivation() + * (and forwarded to the TLS-1.2 PRF) is the concatenation of the + * ClientHello.Random + ServerHello.Random, while the label is "master secret". + * See RFC 5246, Section 8.1, Computing the Master Secret. + * + * \param alg An algorithm identifier (value of type #psa_algorithm_t). + * + * \return 1 if \c alg is a TLS-1.2 PSK to MS algorithm, 0 otherwise. + * This macro may return either 0 or 1 if \c alg is not a supported + * key derivation algorithm identifier. + */ +#define PSA_ALG_IS_TLS12_PSK_TO_MS(alg) \ + (((alg) & ~PSA_ALG_HASH_MASK) == PSA_ALG_TLS12_PSK_TO_MS_BASE) +#define PSA_ALG_TLS12_PSK_TO_MS_GET_HASH(hkdf_alg) \ + (PSA_ALG_CATEGORY_HASH | ((hkdf_alg) & PSA_ALG_HASH_MASK)) + #define PSA_ALG_KEY_DERIVATION_MASK ((psa_algorithm_t)0x010fffff) /** Use a shared secret as is. diff --git a/include/psa/crypto_sizes.h b/include/psa/crypto_sizes.h index f0a1ba7dd..7e1795673 100644 --- a/include/psa/crypto_sizes.h +++ b/include/psa/crypto_sizes.h @@ -131,6 +131,22 @@ #define PSA_VENDOR_ECC_MAX_CURVE_BITS 0 #endif +/** \def PSA_ALG_TLS12_PSK_TO_MS_MAX_PSK_LEN + * + * This macro returns the maximum length of the PSK supported + * by the TLS-1.2 PSK-to-MS key derivation. + * + * Quoting RFC 4279, Sect 5.3: + * TLS implementations supporting these ciphersuites MUST support + * arbitrary PSK identities up to 128 octets in length, and arbitrary + * PSKs up to 64 octets in length. Supporting longer identities and + * keys is RECOMMENDED. + * + * Therefore, no implementation should define a value smaller than 64 + * for #PSA_ALG_TLS12_PSK_TO_MS_MAX_PSK_LEN. + */ +#define PSA_ALG_TLS12_PSK_TO_MS_MAX_PSK_LEN 128 + /** \def PSA_ASYMMETRIC_SIGNATURE_MAX_SIZE * * Maximum size of an asymmetric signature. From 1aaedc03d4402d5f6147b0e0a653fa7c7c9c5e13 Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Fri, 16 Nov 2018 11:35:34 +0000 Subject: [PATCH 2/6] Add implementation of TLS-1.2 PSK-to-MS key derivation --- library/psa_crypto.c | 72 +++++++++++++++++++++++++++++++++++++++----- 1 file changed, 65 insertions(+), 7 deletions(-) diff --git a/library/psa_crypto.c b/library/psa_crypto.c index b0fb5a883..010c338c0 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -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 From a198f06feb5d2ab7a453d1708bf28c3717f98710 Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Fri, 12 Oct 2018 15:48:17 +0100 Subject: [PATCH 3/6] Add tests for TLS-1.2 PSK-to-MS derivation --- tests/suites/test_suite_psa_crypto.data | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/tests/suites/test_suite_psa_crypto.data b/tests/suites/test_suite_psa_crypto.data index da105d2d1..b09eb307d 100644 --- a/tests/suites/test_suite_psa_crypto.data +++ b/tests/suites/test_suite_psa_crypto.data @@ -1537,6 +1537,21 @@ PSA key derivation: TLS 1.2 PRF SHA-384, output 74+73 depends_on:MBEDTLS_MD_C:MBEDTLS_SHA512_C derive_output:PSA_ALG_TLS12_PRF(PSA_ALG_SHA_384):"b80b733d6ceefcdc71566ea48e5567df":"cd665cf6a8447dd6ff8b27555edb7465":"74657374206c6162656c":148:"7b0c18e9ced410ed1804f2cfa34a336a1c14dffb4900bb5fd7942107e81c83cde9ca0faa60be9fe34f82b1233c9146a0e534cb400fed2700884f9dc236f80edd8bfa961144c9e8d792ec":"a722a7b32fc3d416d473ebc2c5fd4abfdad05d9184259b5bf8cd4d90fa0d31e2dec479e4f1a26066f2eea9a69236a3e52655c9e9aee691c8f3a26854308d5eaa3be85e0990703d73e5" +# Test case manually extracted from debug output of TLS-PSK run +# Label: "master secret" +# Salt: Concatenation of ClientHello.Random and ServerHello.Random +PSA key derivation: TLS 1.2 PSK-to-MS, SHA-256, 48+0 +depends_on:MBEDTLS_MD_C:MBEDTLS_SHA256_C +derive_output:PSA_ALG_TLS12_PSK_TO_MS(PSA_ALG_SHA_256):"01020304":"5bc0b19b4a8b24b07afe7ec65c471e94a7d518fcef06c3574315255c52afe21b5bc0b19b872b9b26508458f03603744d575f463a11ae7f1b090c012606fd3e9f":"6d617374657220736563726574":48:"5a9dd5ffa78b4d1f28f40d91b4e6e6ed37849042d61ba32ca43d866e744cee7cd1baaa497e1ecd5c2e60f9f13030a710":"" + +PSA key derivation: TLS 1.2 PSK-to-MS, SHA-256, 24+24 +depends_on:MBEDTLS_MD_C:MBEDTLS_SHA256_C +derive_output:PSA_ALG_TLS12_PSK_TO_MS(PSA_ALG_SHA_256):"01020304":"5bc0b19b4a8b24b07afe7ec65c471e94a7d518fcef06c3574315255c52afe21b5bc0b19b872b9b26508458f03603744d575f463a11ae7f1b090c012606fd3e9f":"6d617374657220736563726574":48:"5a9dd5ffa78b4d1f28f40d91b4e6e6ed37849042d61ba32c":"a43d866e744cee7cd1baaa497e1ecd5c2e60f9f13030a710" + +PSA key derivation: TLS 1.2 PSK-to-MS, SHA-256, 0+48 +depends_on:MBEDTLS_MD_C:MBEDTLS_SHA256_C +derive_output:PSA_ALG_TLS12_PSK_TO_MS(PSA_ALG_SHA_256):"01020304":"5bc0b19b4a8b24b07afe7ec65c471e94a7d518fcef06c3574315255c52afe21b5bc0b19b872b9b26508458f03603744d575f463a11ae7f1b090c012606fd3e9f":"6d617374657220736563726574":48:"":"5a9dd5ffa78b4d1f28f40d91b4e6e6ed37849042d61ba32ca43d866e744cee7cd1baaa497e1ecd5c2e60f9f13030a710" + PSA key derivation: HKDF SHA-256, request maximum capacity depends_on:MBEDTLS_MD_C:MBEDTLS_SHA256_C derive_output:PSA_ALG_HKDF(PSA_ALG_SHA_256):"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":"000102030405060708090a0b0c":"f0f1f2f3f4f5f6f7f8f9":255 * 32:"3cb25f25faacd57a90434f64d0362f2a2d2d0a90cf1a5a4c5db02d56ecc4c5bf34007208d5b887185865":"" From f074938aaeb87425cd24df333e047d1238297163 Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Thu, 15 Nov 2018 10:18:09 +0000 Subject: [PATCH 4/6] Add SHA-384 tests for TLS 1.2 PSK-to-MS key derivation --- tests/suites/test_suite_psa_crypto.data | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/tests/suites/test_suite_psa_crypto.data b/tests/suites/test_suite_psa_crypto.data index b09eb307d..5f09c8dc0 100644 --- a/tests/suites/test_suite_psa_crypto.data +++ b/tests/suites/test_suite_psa_crypto.data @@ -1552,6 +1552,18 @@ PSA key derivation: TLS 1.2 PSK-to-MS, SHA-256, 0+48 depends_on:MBEDTLS_MD_C:MBEDTLS_SHA256_C derive_output:PSA_ALG_TLS12_PSK_TO_MS(PSA_ALG_SHA_256):"01020304":"5bc0b19b4a8b24b07afe7ec65c471e94a7d518fcef06c3574315255c52afe21b5bc0b19b872b9b26508458f03603744d575f463a11ae7f1b090c012606fd3e9f":"6d617374657220736563726574":48:"":"5a9dd5ffa78b4d1f28f40d91b4e6e6ed37849042d61ba32ca43d866e744cee7cd1baaa497e1ecd5c2e60f9f13030a710" +PSA key derivation: TLS 1.2 PSK-to-MS, SHA-384, 48+0 +depends_on:MBEDTLS_MD_C:MBEDTLS_SHA512_C +derive_output:PSA_ALG_TLS12_PSK_TO_MS(PSA_ALG_SHA_384):"01020304":"5bed47716a11a49a6268a8350b085929116ad9ccc8181f09a05b07a7741576d65bed47718dfd82f2d3f57544afe52decae6819b970dc716ada72ae0dd3072e9a":"6d617374657220736563726574":48:"f5a61fbdd2ec415762abb8042a6c16645a53d2edb6dec8c85ca71689301f9f4d875128c87608b75250b20a9550e4fe18":"" + +PSA key derivation: TLS 1.2 PSK-to-MS, SHA-384, 24+24 +depends_on:MBEDTLS_MD_C:MBEDTLS_SHA512_C +derive_output:PSA_ALG_TLS12_PSK_TO_MS(PSA_ALG_SHA_384):"01020304":"5bed47716a11a49a6268a8350b085929116ad9ccc8181f09a05b07a7741576d65bed47718dfd82f2d3f57544afe52decae6819b970dc716ada72ae0dd3072e9a":"6d617374657220736563726574":48:"":"f5a61fbdd2ec415762abb8042a6c16645a53d2edb6dec8c85ca71689301f9f4d875128c87608b75250b20a9550e4fe18" + +PSA key derivation: TLS 1.2 PSK-to-MS, SHA-384, 0+48 +depends_on:MBEDTLS_MD_C:MBEDTLS_SHA512_C +derive_output:PSA_ALG_TLS12_PSK_TO_MS(PSA_ALG_SHA_384):"01020304":"5bed47716a11a49a6268a8350b085929116ad9ccc8181f09a05b07a7741576d65bed47718dfd82f2d3f57544afe52decae6819b970dc716ada72ae0dd3072e9a":"6d617374657220736563726574":48:"f5a61fbdd2ec415762abb8042a6c16645a53d2edb6dec8c8":"5ca71689301f9f4d875128c87608b75250b20a9550e4fe18" + PSA key derivation: HKDF SHA-256, request maximum capacity depends_on:MBEDTLS_MD_C:MBEDTLS_SHA256_C derive_output:PSA_ALG_HKDF(PSA_ALG_SHA_256):"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":"000102030405060708090a0b0c":"f0f1f2f3f4f5f6f7f8f9":255 * 32:"3cb25f25faacd57a90434f64d0362f2a2d2d0a90cf1a5a4c5db02d56ecc4c5bf34007208d5b887185865":"" From 6b123fbc39b2a1364dc0a7f51860461935c43f04 Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Fri, 16 Nov 2018 14:34:55 +0000 Subject: [PATCH 5/6] Add test for overly long PSK in TLS-1.2 PSK-to-MS KDF --- tests/suites/test_suite_psa_crypto.data | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/suites/test_suite_psa_crypto.data b/tests/suites/test_suite_psa_crypto.data index 5f09c8dc0..ea214d25a 100644 --- a/tests/suites/test_suite_psa_crypto.data +++ b/tests/suites/test_suite_psa_crypto.data @@ -1580,6 +1580,10 @@ PSA key derivation: HKDF SHA-1, request too much capacity depends_on:MBEDTLS_MD_C:MBEDTLS_SHA1_C derive_setup:PSA_KEY_TYPE_DERIVE:"0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c":PSA_ALG_HKDF(PSA_ALG_SHA_1):"":"":255 * 20 + 1:PSA_ERROR_INVALID_ARGUMENT +PSA key derivation: TLS 1.2 PSK-to-MS, SHA-256, PSK too long (160 Bytes) +depends_on:MBEDTLS_MD_C:MBEDTLS_SHA256_C +derive_setup:PSA_KEY_TYPE_DERIVE:"01020304050607080102030405060708010203040506070801020304050607080102030405060708010203040506070801020304050607080102030405060708010203040506070801020304050607080102030405060708010203040506070801020304050607080102030405060708010203040506070801020304050607080102030405060708010203040506070801020304050607080102030405060708":PSA_ALG_TLS12_PSK_TO_MS(PSA_ALG_SHA_256):"":"":100:PSA_ERROR_INVALID_ARGUMENT + PSA key derivation: over capacity 42: output 42+1 depends_on:MBEDTLS_MD_C:MBEDTLS_SHA256_C derive_output:PSA_ALG_HKDF(PSA_ALG_SHA_256):"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":"000102030405060708090a0b0c":"f0f1f2f3f4f5f6f7f8f9":42:"3cb25f25faacd57a90434f64d0362f2a2d2d0a90cf1a5a4c5db02d56ecc4c5bf34007208d5b887185865":"ff" From 2255a360a6d1b86735f479678a220092658447da Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Fri, 16 Nov 2018 16:05:13 +0000 Subject: [PATCH 6/6] Improve documentation of TLS-1.2 PRF and PSK-to-MS KDF --- include/psa/crypto.h | 35 +++++++++++++++++++++-------------- 1 file changed, 21 insertions(+), 14 deletions(-) diff --git a/include/psa/crypto.h b/include/psa/crypto.h index bdddeca59..d1a3f0f3b 100644 --- a/include/psa/crypto.h +++ b/include/psa/crypto.h @@ -1201,6 +1201,16 @@ typedef uint32_t psa_algorithm_t; #define PSA_ALG_TLS12_PRF_BASE ((psa_algorithm_t)0x30000200) /** Macro to build a TLS-1.2 PRF algorithm. + * + * TLS 1.2 uses a custom pseudorandom function (PRF) for key schedule, + * specified in Section 5 of RFC 5246. It is based on HMAC and can be + * used with either SHA-256 or SHA-384. + * + * For the application to TLS-1.2, the salt and label arguments passed + * to psa_key_derivation() are what's called 'seed' and 'label' in RFC 5246, + * respectively. For example, for TLS key expansion, the salt is the + * concatenation of ServerHello.Random + ClientHello.Random, + * while the label is "key expansion". * * For example, `PSA_ALG_TLS12_PRF(PSA_ALG_SHA256)` represents the * TLS 1.2 PRF using HMAC-SHA-256. @@ -1216,10 +1226,6 @@ typedef uint32_t psa_algorithm_t; (PSA_ALG_TLS12_PRF_BASE | ((hash_alg) & PSA_ALG_HASH_MASK)) /** Whether the specified algorithm is a TLS-1.2 PRF algorithm. - * - * TLS 1.2 uses a custom pseudorandom function (PRF) for key schedule, - * specified in Section 5 of RFC 5246. It is based on HMAC and can be - * used with either SHA-256 or SHA-384. * * \param alg An algorithm identifier (value of type #psa_algorithm_t). * @@ -1234,6 +1240,17 @@ typedef uint32_t psa_algorithm_t; #define PSA_ALG_TLS12_PSK_TO_MS_BASE ((psa_algorithm_t)0x30000300) /** Macro to build a TLS-1.2 PSK-to-MasterSecret algorithm. + * + * In a pure-PSK handshake in TLS 1.2, the master secret is derived + * from the PreSharedKey (PSK) through the application of padding + * (RFC 4279, Section 2) and the TLS-1.2 PRF (RFC 5246, Section 5). + * The latter is based on HMAC and can be used with either SHA-256 + * or SHA-384. + * + * For the application to TLS-1.2, the salt passed to psa_key_derivation() + * (and forwarded to the TLS-1.2 PRF) is the concatenation of the + * ClientHello.Random + ServerHello.Random, while the label is "master secret" + * or "extended master secret". * * For example, `PSA_ALG_TLS12_PSK_TO_MS(PSA_ALG_SHA256)` represents the * TLS-1.2 PSK to MasterSecret derivation PRF using HMAC-SHA-256. @@ -1249,16 +1266,6 @@ typedef uint32_t psa_algorithm_t; (PSA_ALG_TLS12_PSK_TO_MS_BASE | ((hash_alg) & PSA_ALG_HASH_MASK)) /** Whether the specified algorithm is a TLS-1.2 PSK to MS algorithm. - * - * In a pure-PSK handshake in TLS 1.2, the master secret is derived - * from the PreSharedKey (PSK) through the application of padding and - * the TLS-1.2 PRF (see below). The latter is based on HMAC and can - * be used with either SHA-256 or SHA-384. - * - * For the application to TLS-1.2, the salt passed to psa_key_derivation() - * (and forwarded to the TLS-1.2 PRF) is the concatenation of the - * ClientHello.Random + ServerHello.Random, while the label is "master secret". - * See RFC 5246, Section 8.1, Computing the Master Secret. * * \param alg An algorithm identifier (value of type #psa_algorithm_t). *