17901324dSJerome Forissier /* 27901324dSJerome Forissier * TLS 1.3 key schedule 37901324dSJerome Forissier * 47901324dSJerome Forissier * Copyright The Mbed TLS Contributors 57901324dSJerome Forissier * SPDX-License-Identifier: Apache-2.0 67901324dSJerome Forissier * 77901324dSJerome Forissier * Licensed under the Apache License, Version 2.0 ( the "License" ); you may 87901324dSJerome Forissier * not use this file except in compliance with the License. 97901324dSJerome Forissier * You may obtain a copy of the License at 107901324dSJerome Forissier * 117901324dSJerome Forissier * http://www.apache.org/licenses/LICENSE-2.0 127901324dSJerome Forissier * 137901324dSJerome Forissier * Unless required by applicable law or agreed to in writing, software 147901324dSJerome Forissier * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 157901324dSJerome Forissier * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 167901324dSJerome Forissier * See the License for the specific language governing permissions and 177901324dSJerome Forissier * limitations under the License. 187901324dSJerome Forissier */ 197901324dSJerome Forissier 207901324dSJerome Forissier #include "common.h" 217901324dSJerome Forissier 227901324dSJerome Forissier #if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL) 237901324dSJerome Forissier 247901324dSJerome Forissier #include "mbedtls/hkdf.h" 257901324dSJerome Forissier #include "mbedtls/ssl_internal.h" 267901324dSJerome Forissier #include "ssl_tls13_keys.h" 277901324dSJerome Forissier 287901324dSJerome Forissier #include <stdint.h> 297901324dSJerome Forissier #include <string.h> 307901324dSJerome Forissier 317901324dSJerome Forissier #define MBEDTLS_SSL_TLS1_3_LABEL( name, string ) \ 327901324dSJerome Forissier .name = string, 337901324dSJerome Forissier 347901324dSJerome Forissier struct mbedtls_ssl_tls1_3_labels_struct const mbedtls_ssl_tls1_3_labels = 357901324dSJerome Forissier { 367901324dSJerome Forissier /* This seems to work in C, despite the string literal being one 377901324dSJerome Forissier * character too long due to the 0-termination. */ 387901324dSJerome Forissier MBEDTLS_SSL_TLS1_3_LABEL_LIST 397901324dSJerome Forissier }; 407901324dSJerome Forissier 417901324dSJerome Forissier #undef MBEDTLS_SSL_TLS1_3_LABEL 427901324dSJerome Forissier 437901324dSJerome Forissier /* 447901324dSJerome Forissier * This function creates a HkdfLabel structure used in the TLS 1.3 key schedule. 457901324dSJerome Forissier * 467901324dSJerome Forissier * The HkdfLabel is specified in RFC 8446 as follows: 477901324dSJerome Forissier * 487901324dSJerome Forissier * struct HkdfLabel { 497901324dSJerome Forissier * uint16 length; // Length of expanded key material 507901324dSJerome Forissier * opaque label<7..255>; // Always prefixed by "tls13 " 517901324dSJerome Forissier * opaque context<0..255>; // Usually a communication transcript hash 527901324dSJerome Forissier * }; 537901324dSJerome Forissier * 547901324dSJerome Forissier * Parameters: 557901324dSJerome Forissier * - desired_length: Length of expanded key material 567901324dSJerome Forissier * Even though the standard allows expansion to up to 577901324dSJerome Forissier * 2**16 Bytes, TLS 1.3 never uses expansion to more than 587901324dSJerome Forissier * 255 Bytes, so we require `desired_length` to be at most 597901324dSJerome Forissier * 255. This allows us to save a few Bytes of code by 607901324dSJerome Forissier * hardcoding the writing of the high bytes. 617901324dSJerome Forissier * - (label, llen): label + label length, without "tls13 " prefix 627901324dSJerome Forissier * The label length MUST be less than or equal to 637901324dSJerome Forissier * MBEDTLS_SSL_TLS1_3_KEY_SCHEDULE_MAX_LABEL_LEN 647901324dSJerome Forissier * It is the caller's responsibility to ensure this. 657901324dSJerome Forissier * All (label, label length) pairs used in TLS 1.3 667901324dSJerome Forissier * can be obtained via MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN(). 677901324dSJerome Forissier * - (ctx, clen): context + context length 687901324dSJerome Forissier * The context length MUST be less than or equal to 697901324dSJerome Forissier * MBEDTLS_SSL_TLS1_3_KEY_SCHEDULE_MAX_CONTEXT_LEN 707901324dSJerome Forissier * It is the caller's responsibility to ensure this. 717901324dSJerome Forissier * - dst: Target buffer for HkdfLabel structure, 727901324dSJerome Forissier * This MUST be a writable buffer of size 737901324dSJerome Forissier * at least SSL_TLS1_3_KEY_SCHEDULE_MAX_HKDF_LABEL_LEN Bytes. 747901324dSJerome Forissier * - dlen: Pointer at which to store the actual length of 757901324dSJerome Forissier * the HkdfLabel structure on success. 767901324dSJerome Forissier */ 777901324dSJerome Forissier 787901324dSJerome Forissier static const char tls1_3_label_prefix[6] = "tls13 "; 797901324dSJerome Forissier 807901324dSJerome Forissier #define SSL_TLS1_3_KEY_SCHEDULE_HKDF_LABEL_LEN( label_len, context_len ) \ 817901324dSJerome Forissier ( 2 /* expansion length */ \ 827901324dSJerome Forissier + 1 /* label length */ \ 837901324dSJerome Forissier + label_len \ 847901324dSJerome Forissier + 1 /* context length */ \ 857901324dSJerome Forissier + context_len ) 867901324dSJerome Forissier 877901324dSJerome Forissier #define SSL_TLS1_3_KEY_SCHEDULE_MAX_HKDF_LABEL_LEN \ 887901324dSJerome Forissier SSL_TLS1_3_KEY_SCHEDULE_HKDF_LABEL_LEN( \ 897901324dSJerome Forissier sizeof(tls1_3_label_prefix) + \ 907901324dSJerome Forissier MBEDTLS_SSL_TLS1_3_KEY_SCHEDULE_MAX_LABEL_LEN, \ 917901324dSJerome Forissier MBEDTLS_SSL_TLS1_3_KEY_SCHEDULE_MAX_CONTEXT_LEN ) 927901324dSJerome Forissier 937901324dSJerome Forissier static void ssl_tls1_3_hkdf_encode_label( 947901324dSJerome Forissier size_t desired_length, 957901324dSJerome Forissier const unsigned char *label, size_t llen, 967901324dSJerome Forissier const unsigned char *ctx, size_t clen, 977901324dSJerome Forissier unsigned char *dst, size_t *dlen ) 987901324dSJerome Forissier { 997901324dSJerome Forissier size_t total_label_len = 1007901324dSJerome Forissier sizeof(tls1_3_label_prefix) + llen; 1017901324dSJerome Forissier size_t total_hkdf_lbl_len = 1027901324dSJerome Forissier SSL_TLS1_3_KEY_SCHEDULE_HKDF_LABEL_LEN( total_label_len, clen ); 1037901324dSJerome Forissier 1047901324dSJerome Forissier unsigned char *p = dst; 1057901324dSJerome Forissier 1067901324dSJerome Forissier /* Add the size of the expanded key material. 1077901324dSJerome Forissier * We're hardcoding the high byte to 0 here assuming that we never use 1087901324dSJerome Forissier * TLS 1.3 HKDF key expansion to more than 255 Bytes. */ 1097901324dSJerome Forissier #if MBEDTLS_SSL_TLS1_3_KEY_SCHEDULE_MAX_EXPANSION_LEN > 255 1107901324dSJerome Forissier #error "The implementation of ssl_tls1_3_hkdf_encode_label() is not fit for the \ 1117901324dSJerome Forissier value of MBEDTLS_SSL_TLS1_3_KEY_SCHEDULE_MAX_EXPANSION_LEN" 1127901324dSJerome Forissier #endif 1137901324dSJerome Forissier 1147901324dSJerome Forissier *p++ = 0; 115*039e02dfSJerome Forissier *p++ = MBEDTLS_BYTE_0( desired_length ); 1167901324dSJerome Forissier 1177901324dSJerome Forissier /* Add label incl. prefix */ 118*039e02dfSJerome Forissier *p++ = MBEDTLS_BYTE_0( total_label_len ); 1197901324dSJerome Forissier memcpy( p, tls1_3_label_prefix, sizeof(tls1_3_label_prefix) ); 1207901324dSJerome Forissier p += sizeof(tls1_3_label_prefix); 1217901324dSJerome Forissier memcpy( p, label, llen ); 1227901324dSJerome Forissier p += llen; 1237901324dSJerome Forissier 1247901324dSJerome Forissier /* Add context value */ 125*039e02dfSJerome Forissier *p++ = MBEDTLS_BYTE_0( clen ); 1267901324dSJerome Forissier if( clen != 0 ) 1277901324dSJerome Forissier memcpy( p, ctx, clen ); 1287901324dSJerome Forissier 1297901324dSJerome Forissier /* Return total length to the caller. */ 1307901324dSJerome Forissier *dlen = total_hkdf_lbl_len; 1317901324dSJerome Forissier } 1327901324dSJerome Forissier 1337901324dSJerome Forissier int mbedtls_ssl_tls1_3_hkdf_expand_label( 1347901324dSJerome Forissier mbedtls_md_type_t hash_alg, 1357901324dSJerome Forissier const unsigned char *secret, size_t slen, 1367901324dSJerome Forissier const unsigned char *label, size_t llen, 1377901324dSJerome Forissier const unsigned char *ctx, size_t clen, 1387901324dSJerome Forissier unsigned char *buf, size_t blen ) 1397901324dSJerome Forissier { 1407901324dSJerome Forissier const mbedtls_md_info_t *md; 1417901324dSJerome Forissier unsigned char hkdf_label[ SSL_TLS1_3_KEY_SCHEDULE_MAX_HKDF_LABEL_LEN ]; 1427901324dSJerome Forissier size_t hkdf_label_len; 1437901324dSJerome Forissier 1447901324dSJerome Forissier if( llen > MBEDTLS_SSL_TLS1_3_KEY_SCHEDULE_MAX_LABEL_LEN ) 1457901324dSJerome Forissier { 1467901324dSJerome Forissier /* Should never happen since this is an internal 1477901324dSJerome Forissier * function, and we know statically which labels 1487901324dSJerome Forissier * are allowed. */ 1497901324dSJerome Forissier return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); 1507901324dSJerome Forissier } 1517901324dSJerome Forissier 1527901324dSJerome Forissier if( clen > MBEDTLS_SSL_TLS1_3_KEY_SCHEDULE_MAX_CONTEXT_LEN ) 1537901324dSJerome Forissier { 1547901324dSJerome Forissier /* Should not happen, as above. */ 1557901324dSJerome Forissier return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); 1567901324dSJerome Forissier } 1577901324dSJerome Forissier 1587901324dSJerome Forissier if( blen > MBEDTLS_SSL_TLS1_3_KEY_SCHEDULE_MAX_EXPANSION_LEN ) 1597901324dSJerome Forissier { 1607901324dSJerome Forissier /* Should not happen, as above. */ 1617901324dSJerome Forissier return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); 1627901324dSJerome Forissier } 1637901324dSJerome Forissier 1647901324dSJerome Forissier md = mbedtls_md_info_from_type( hash_alg ); 1657901324dSJerome Forissier if( md == NULL ) 1667901324dSJerome Forissier return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); 1677901324dSJerome Forissier 1687901324dSJerome Forissier ssl_tls1_3_hkdf_encode_label( blen, 1697901324dSJerome Forissier label, llen, 1707901324dSJerome Forissier ctx, clen, 1717901324dSJerome Forissier hkdf_label, 1727901324dSJerome Forissier &hkdf_label_len ); 1737901324dSJerome Forissier 1747901324dSJerome Forissier return( mbedtls_hkdf_expand( md, 1757901324dSJerome Forissier secret, slen, 1767901324dSJerome Forissier hkdf_label, hkdf_label_len, 1777901324dSJerome Forissier buf, blen ) ); 1787901324dSJerome Forissier } 1797901324dSJerome Forissier 1807901324dSJerome Forissier /* 1817901324dSJerome Forissier * The traffic keying material is generated from the following inputs: 1827901324dSJerome Forissier * 1837901324dSJerome Forissier * - One secret value per sender. 1847901324dSJerome Forissier * - A purpose value indicating the specific value being generated 1857901324dSJerome Forissier * - The desired lengths of key and IV. 1867901324dSJerome Forissier * 1877901324dSJerome Forissier * The expansion itself is based on HKDF: 1887901324dSJerome Forissier * 1897901324dSJerome Forissier * [sender]_write_key = HKDF-Expand-Label( Secret, "key", "", key_length ) 1907901324dSJerome Forissier * [sender]_write_iv = HKDF-Expand-Label( Secret, "iv" , "", iv_length ) 1917901324dSJerome Forissier * 1927901324dSJerome Forissier * [sender] denotes the sending side and the Secret value is provided 1937901324dSJerome Forissier * by the function caller. Note that we generate server and client side 1947901324dSJerome Forissier * keys in a single function call. 1957901324dSJerome Forissier */ 1967901324dSJerome Forissier int mbedtls_ssl_tls1_3_make_traffic_keys( 1977901324dSJerome Forissier mbedtls_md_type_t hash_alg, 1987901324dSJerome Forissier const unsigned char *client_secret, 1997901324dSJerome Forissier const unsigned char *server_secret, 2007901324dSJerome Forissier size_t slen, size_t key_len, size_t iv_len, 2017901324dSJerome Forissier mbedtls_ssl_key_set *keys ) 2027901324dSJerome Forissier { 2037901324dSJerome Forissier int ret = 0; 2047901324dSJerome Forissier 2057901324dSJerome Forissier ret = mbedtls_ssl_tls1_3_hkdf_expand_label( hash_alg, 2067901324dSJerome Forissier client_secret, slen, 2077901324dSJerome Forissier MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN( key ), 2087901324dSJerome Forissier NULL, 0, 2097901324dSJerome Forissier keys->client_write_key, key_len ); 2107901324dSJerome Forissier if( ret != 0 ) 2117901324dSJerome Forissier return( ret ); 2127901324dSJerome Forissier 2137901324dSJerome Forissier ret = mbedtls_ssl_tls1_3_hkdf_expand_label( hash_alg, 2147901324dSJerome Forissier server_secret, slen, 2157901324dSJerome Forissier MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN( key ), 2167901324dSJerome Forissier NULL, 0, 2177901324dSJerome Forissier keys->server_write_key, key_len ); 2187901324dSJerome Forissier if( ret != 0 ) 2197901324dSJerome Forissier return( ret ); 2207901324dSJerome Forissier 2217901324dSJerome Forissier ret = mbedtls_ssl_tls1_3_hkdf_expand_label( hash_alg, 2227901324dSJerome Forissier client_secret, slen, 2237901324dSJerome Forissier MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN( iv ), 2247901324dSJerome Forissier NULL, 0, 2257901324dSJerome Forissier keys->client_write_iv, iv_len ); 2267901324dSJerome Forissier if( ret != 0 ) 2277901324dSJerome Forissier return( ret ); 2287901324dSJerome Forissier 2297901324dSJerome Forissier ret = mbedtls_ssl_tls1_3_hkdf_expand_label( hash_alg, 2307901324dSJerome Forissier server_secret, slen, 2317901324dSJerome Forissier MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN( iv ), 2327901324dSJerome Forissier NULL, 0, 2337901324dSJerome Forissier keys->server_write_iv, iv_len ); 2347901324dSJerome Forissier if( ret != 0 ) 2357901324dSJerome Forissier return( ret ); 2367901324dSJerome Forissier 2377901324dSJerome Forissier keys->key_len = key_len; 2387901324dSJerome Forissier keys->iv_len = iv_len; 2397901324dSJerome Forissier 2407901324dSJerome Forissier return( 0 ); 2417901324dSJerome Forissier } 2427901324dSJerome Forissier 2437901324dSJerome Forissier int mbedtls_ssl_tls1_3_derive_secret( 2447901324dSJerome Forissier mbedtls_md_type_t hash_alg, 2457901324dSJerome Forissier const unsigned char *secret, size_t slen, 2467901324dSJerome Forissier const unsigned char *label, size_t llen, 2477901324dSJerome Forissier const unsigned char *ctx, size_t clen, 2487901324dSJerome Forissier int ctx_hashed, 2497901324dSJerome Forissier unsigned char *dstbuf, size_t buflen ) 2507901324dSJerome Forissier { 2517901324dSJerome Forissier int ret; 2527901324dSJerome Forissier unsigned char hashed_context[ MBEDTLS_MD_MAX_SIZE ]; 2537901324dSJerome Forissier 2547901324dSJerome Forissier const mbedtls_md_info_t *md; 2557901324dSJerome Forissier md = mbedtls_md_info_from_type( hash_alg ); 2567901324dSJerome Forissier if( md == NULL ) 2577901324dSJerome Forissier return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); 2587901324dSJerome Forissier 2597901324dSJerome Forissier if( ctx_hashed == MBEDTLS_SSL_TLS1_3_CONTEXT_UNHASHED ) 2607901324dSJerome Forissier { 2617901324dSJerome Forissier ret = mbedtls_md( md, ctx, clen, hashed_context ); 2627901324dSJerome Forissier if( ret != 0 ) 2637901324dSJerome Forissier return( ret ); 2647901324dSJerome Forissier clen = mbedtls_md_get_size( md ); 2657901324dSJerome Forissier } 2667901324dSJerome Forissier else 2677901324dSJerome Forissier { 2687901324dSJerome Forissier if( clen > sizeof(hashed_context) ) 2697901324dSJerome Forissier { 2707901324dSJerome Forissier /* This should never happen since this function is internal 2717901324dSJerome Forissier * and the code sets `ctx_hashed` correctly. 2727901324dSJerome Forissier * Let's double-check nonetheless to not run at the risk 2737901324dSJerome Forissier * of getting a stack overflow. */ 2747901324dSJerome Forissier return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); 2757901324dSJerome Forissier } 2767901324dSJerome Forissier 2777901324dSJerome Forissier memcpy( hashed_context, ctx, clen ); 2787901324dSJerome Forissier } 2797901324dSJerome Forissier 2807901324dSJerome Forissier return( mbedtls_ssl_tls1_3_hkdf_expand_label( hash_alg, 2817901324dSJerome Forissier secret, slen, 2827901324dSJerome Forissier label, llen, 2837901324dSJerome Forissier hashed_context, clen, 2847901324dSJerome Forissier dstbuf, buflen ) ); 2857901324dSJerome Forissier } 2867901324dSJerome Forissier 2877901324dSJerome Forissier int mbedtls_ssl_tls1_3_evolve_secret( 2887901324dSJerome Forissier mbedtls_md_type_t hash_alg, 2897901324dSJerome Forissier const unsigned char *secret_old, 2907901324dSJerome Forissier const unsigned char *input, size_t input_len, 2917901324dSJerome Forissier unsigned char *secret_new ) 2927901324dSJerome Forissier { 2937901324dSJerome Forissier int ret = MBEDTLS_ERR_SSL_INTERNAL_ERROR; 2947901324dSJerome Forissier size_t hlen, ilen; 2957901324dSJerome Forissier unsigned char tmp_secret[ MBEDTLS_MD_MAX_SIZE ] = { 0 }; 2967901324dSJerome Forissier unsigned char tmp_input [ MBEDTLS_MD_MAX_SIZE ] = { 0 }; 2977901324dSJerome Forissier 2987901324dSJerome Forissier const mbedtls_md_info_t *md; 2997901324dSJerome Forissier md = mbedtls_md_info_from_type( hash_alg ); 3007901324dSJerome Forissier if( md == NULL ) 3017901324dSJerome Forissier return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); 3027901324dSJerome Forissier 3037901324dSJerome Forissier hlen = mbedtls_md_get_size( md ); 3047901324dSJerome Forissier 3057901324dSJerome Forissier /* For non-initial runs, call Derive-Secret( ., "derived", "") 3067901324dSJerome Forissier * on the old secret. */ 3077901324dSJerome Forissier if( secret_old != NULL ) 3087901324dSJerome Forissier { 3097901324dSJerome Forissier ret = mbedtls_ssl_tls1_3_derive_secret( 3107901324dSJerome Forissier hash_alg, 3117901324dSJerome Forissier secret_old, hlen, 3127901324dSJerome Forissier MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN( derived ), 3137901324dSJerome Forissier NULL, 0, /* context */ 3147901324dSJerome Forissier MBEDTLS_SSL_TLS1_3_CONTEXT_UNHASHED, 3157901324dSJerome Forissier tmp_secret, hlen ); 3167901324dSJerome Forissier if( ret != 0 ) 3177901324dSJerome Forissier goto cleanup; 3187901324dSJerome Forissier } 3197901324dSJerome Forissier 3207901324dSJerome Forissier if( input != NULL ) 3217901324dSJerome Forissier { 3227901324dSJerome Forissier memcpy( tmp_input, input, input_len ); 3237901324dSJerome Forissier ilen = input_len; 3247901324dSJerome Forissier } 3257901324dSJerome Forissier else 3267901324dSJerome Forissier { 3277901324dSJerome Forissier ilen = hlen; 3287901324dSJerome Forissier } 3297901324dSJerome Forissier 3307901324dSJerome Forissier /* HKDF-Extract takes a salt and input key material. 3317901324dSJerome Forissier * The salt is the old secret, and the input key material 3327901324dSJerome Forissier * is the input secret (PSK / ECDHE). */ 3337901324dSJerome Forissier ret = mbedtls_hkdf_extract( md, 3347901324dSJerome Forissier tmp_secret, hlen, 3357901324dSJerome Forissier tmp_input, ilen, 3367901324dSJerome Forissier secret_new ); 3377901324dSJerome Forissier if( ret != 0 ) 3387901324dSJerome Forissier goto cleanup; 3397901324dSJerome Forissier 3407901324dSJerome Forissier ret = 0; 3417901324dSJerome Forissier 3427901324dSJerome Forissier cleanup: 3437901324dSJerome Forissier 3447901324dSJerome Forissier mbedtls_platform_zeroize( tmp_secret, sizeof(tmp_secret) ); 3457901324dSJerome Forissier mbedtls_platform_zeroize( tmp_input, sizeof(tmp_input) ); 3467901324dSJerome Forissier return( ret ); 3477901324dSJerome Forissier } 3487901324dSJerome Forissier 3497901324dSJerome Forissier #endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */ 350