1*7901324dSJerome Forissier /* 2*7901324dSJerome Forissier * TLS 1.3 key schedule 3*7901324dSJerome Forissier * 4*7901324dSJerome Forissier * Copyright The Mbed TLS Contributors 5*7901324dSJerome Forissier * SPDX-License-Identifier: Apache-2.0 6*7901324dSJerome Forissier * 7*7901324dSJerome Forissier * Licensed under the Apache License, Version 2.0 ( the "License" ); you may 8*7901324dSJerome Forissier * not use this file except in compliance with the License. 9*7901324dSJerome Forissier * You may obtain a copy of the License at 10*7901324dSJerome Forissier * 11*7901324dSJerome Forissier * http://www.apache.org/licenses/LICENSE-2.0 12*7901324dSJerome Forissier * 13*7901324dSJerome Forissier * Unless required by applicable law or agreed to in writing, software 14*7901324dSJerome Forissier * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 15*7901324dSJerome Forissier * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16*7901324dSJerome Forissier * See the License for the specific language governing permissions and 17*7901324dSJerome Forissier * limitations under the License. 18*7901324dSJerome Forissier */ 19*7901324dSJerome Forissier 20*7901324dSJerome Forissier #include "common.h" 21*7901324dSJerome Forissier 22*7901324dSJerome Forissier #if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL) 23*7901324dSJerome Forissier 24*7901324dSJerome Forissier #include "mbedtls/hkdf.h" 25*7901324dSJerome Forissier #include "mbedtls/ssl_internal.h" 26*7901324dSJerome Forissier #include "ssl_tls13_keys.h" 27*7901324dSJerome Forissier 28*7901324dSJerome Forissier #include <stdint.h> 29*7901324dSJerome Forissier #include <string.h> 30*7901324dSJerome Forissier 31*7901324dSJerome Forissier #define MBEDTLS_SSL_TLS1_3_LABEL( name, string ) \ 32*7901324dSJerome Forissier .name = string, 33*7901324dSJerome Forissier 34*7901324dSJerome Forissier struct mbedtls_ssl_tls1_3_labels_struct const mbedtls_ssl_tls1_3_labels = 35*7901324dSJerome Forissier { 36*7901324dSJerome Forissier /* This seems to work in C, despite the string literal being one 37*7901324dSJerome Forissier * character too long due to the 0-termination. */ 38*7901324dSJerome Forissier MBEDTLS_SSL_TLS1_3_LABEL_LIST 39*7901324dSJerome Forissier }; 40*7901324dSJerome Forissier 41*7901324dSJerome Forissier #undef MBEDTLS_SSL_TLS1_3_LABEL 42*7901324dSJerome Forissier 43*7901324dSJerome Forissier /* 44*7901324dSJerome Forissier * This function creates a HkdfLabel structure used in the TLS 1.3 key schedule. 45*7901324dSJerome Forissier * 46*7901324dSJerome Forissier * The HkdfLabel is specified in RFC 8446 as follows: 47*7901324dSJerome Forissier * 48*7901324dSJerome Forissier * struct HkdfLabel { 49*7901324dSJerome Forissier * uint16 length; // Length of expanded key material 50*7901324dSJerome Forissier * opaque label<7..255>; // Always prefixed by "tls13 " 51*7901324dSJerome Forissier * opaque context<0..255>; // Usually a communication transcript hash 52*7901324dSJerome Forissier * }; 53*7901324dSJerome Forissier * 54*7901324dSJerome Forissier * Parameters: 55*7901324dSJerome Forissier * - desired_length: Length of expanded key material 56*7901324dSJerome Forissier * Even though the standard allows expansion to up to 57*7901324dSJerome Forissier * 2**16 Bytes, TLS 1.3 never uses expansion to more than 58*7901324dSJerome Forissier * 255 Bytes, so we require `desired_length` to be at most 59*7901324dSJerome Forissier * 255. This allows us to save a few Bytes of code by 60*7901324dSJerome Forissier * hardcoding the writing of the high bytes. 61*7901324dSJerome Forissier * - (label, llen): label + label length, without "tls13 " prefix 62*7901324dSJerome Forissier * The label length MUST be less than or equal to 63*7901324dSJerome Forissier * MBEDTLS_SSL_TLS1_3_KEY_SCHEDULE_MAX_LABEL_LEN 64*7901324dSJerome Forissier * It is the caller's responsibility to ensure this. 65*7901324dSJerome Forissier * All (label, label length) pairs used in TLS 1.3 66*7901324dSJerome Forissier * can be obtained via MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN(). 67*7901324dSJerome Forissier * - (ctx, clen): context + context length 68*7901324dSJerome Forissier * The context length MUST be less than or equal to 69*7901324dSJerome Forissier * MBEDTLS_SSL_TLS1_3_KEY_SCHEDULE_MAX_CONTEXT_LEN 70*7901324dSJerome Forissier * It is the caller's responsibility to ensure this. 71*7901324dSJerome Forissier * - dst: Target buffer for HkdfLabel structure, 72*7901324dSJerome Forissier * This MUST be a writable buffer of size 73*7901324dSJerome Forissier * at least SSL_TLS1_3_KEY_SCHEDULE_MAX_HKDF_LABEL_LEN Bytes. 74*7901324dSJerome Forissier * - dlen: Pointer at which to store the actual length of 75*7901324dSJerome Forissier * the HkdfLabel structure on success. 76*7901324dSJerome Forissier */ 77*7901324dSJerome Forissier 78*7901324dSJerome Forissier static const char tls1_3_label_prefix[6] = "tls13 "; 79*7901324dSJerome Forissier 80*7901324dSJerome Forissier #define SSL_TLS1_3_KEY_SCHEDULE_HKDF_LABEL_LEN( label_len, context_len ) \ 81*7901324dSJerome Forissier ( 2 /* expansion length */ \ 82*7901324dSJerome Forissier + 1 /* label length */ \ 83*7901324dSJerome Forissier + label_len \ 84*7901324dSJerome Forissier + 1 /* context length */ \ 85*7901324dSJerome Forissier + context_len ) 86*7901324dSJerome Forissier 87*7901324dSJerome Forissier #define SSL_TLS1_3_KEY_SCHEDULE_MAX_HKDF_LABEL_LEN \ 88*7901324dSJerome Forissier SSL_TLS1_3_KEY_SCHEDULE_HKDF_LABEL_LEN( \ 89*7901324dSJerome Forissier sizeof(tls1_3_label_prefix) + \ 90*7901324dSJerome Forissier MBEDTLS_SSL_TLS1_3_KEY_SCHEDULE_MAX_LABEL_LEN, \ 91*7901324dSJerome Forissier MBEDTLS_SSL_TLS1_3_KEY_SCHEDULE_MAX_CONTEXT_LEN ) 92*7901324dSJerome Forissier 93*7901324dSJerome Forissier static void ssl_tls1_3_hkdf_encode_label( 94*7901324dSJerome Forissier size_t desired_length, 95*7901324dSJerome Forissier const unsigned char *label, size_t llen, 96*7901324dSJerome Forissier const unsigned char *ctx, size_t clen, 97*7901324dSJerome Forissier unsigned char *dst, size_t *dlen ) 98*7901324dSJerome Forissier { 99*7901324dSJerome Forissier size_t total_label_len = 100*7901324dSJerome Forissier sizeof(tls1_3_label_prefix) + llen; 101*7901324dSJerome Forissier size_t total_hkdf_lbl_len = 102*7901324dSJerome Forissier SSL_TLS1_3_KEY_SCHEDULE_HKDF_LABEL_LEN( total_label_len, clen ); 103*7901324dSJerome Forissier 104*7901324dSJerome Forissier unsigned char *p = dst; 105*7901324dSJerome Forissier 106*7901324dSJerome Forissier /* Add the size of the expanded key material. 107*7901324dSJerome Forissier * We're hardcoding the high byte to 0 here assuming that we never use 108*7901324dSJerome Forissier * TLS 1.3 HKDF key expansion to more than 255 Bytes. */ 109*7901324dSJerome Forissier #if MBEDTLS_SSL_TLS1_3_KEY_SCHEDULE_MAX_EXPANSION_LEN > 255 110*7901324dSJerome Forissier #error "The implementation of ssl_tls1_3_hkdf_encode_label() is not fit for the \ 111*7901324dSJerome Forissier value of MBEDTLS_SSL_TLS1_3_KEY_SCHEDULE_MAX_EXPANSION_LEN" 112*7901324dSJerome Forissier #endif 113*7901324dSJerome Forissier 114*7901324dSJerome Forissier *p++ = 0; 115*7901324dSJerome Forissier *p++ = (unsigned char)( ( desired_length >> 0 ) & 0xFF ); 116*7901324dSJerome Forissier 117*7901324dSJerome Forissier /* Add label incl. prefix */ 118*7901324dSJerome Forissier *p++ = (unsigned char)( total_label_len & 0xFF ); 119*7901324dSJerome Forissier memcpy( p, tls1_3_label_prefix, sizeof(tls1_3_label_prefix) ); 120*7901324dSJerome Forissier p += sizeof(tls1_3_label_prefix); 121*7901324dSJerome Forissier memcpy( p, label, llen ); 122*7901324dSJerome Forissier p += llen; 123*7901324dSJerome Forissier 124*7901324dSJerome Forissier /* Add context value */ 125*7901324dSJerome Forissier *p++ = (unsigned char)( clen & 0xFF ); 126*7901324dSJerome Forissier if( clen != 0 ) 127*7901324dSJerome Forissier memcpy( p, ctx, clen ); 128*7901324dSJerome Forissier 129*7901324dSJerome Forissier /* Return total length to the caller. */ 130*7901324dSJerome Forissier *dlen = total_hkdf_lbl_len; 131*7901324dSJerome Forissier } 132*7901324dSJerome Forissier 133*7901324dSJerome Forissier int mbedtls_ssl_tls1_3_hkdf_expand_label( 134*7901324dSJerome Forissier mbedtls_md_type_t hash_alg, 135*7901324dSJerome Forissier const unsigned char *secret, size_t slen, 136*7901324dSJerome Forissier const unsigned char *label, size_t llen, 137*7901324dSJerome Forissier const unsigned char *ctx, size_t clen, 138*7901324dSJerome Forissier unsigned char *buf, size_t blen ) 139*7901324dSJerome Forissier { 140*7901324dSJerome Forissier const mbedtls_md_info_t *md; 141*7901324dSJerome Forissier unsigned char hkdf_label[ SSL_TLS1_3_KEY_SCHEDULE_MAX_HKDF_LABEL_LEN ]; 142*7901324dSJerome Forissier size_t hkdf_label_len; 143*7901324dSJerome Forissier 144*7901324dSJerome Forissier if( llen > MBEDTLS_SSL_TLS1_3_KEY_SCHEDULE_MAX_LABEL_LEN ) 145*7901324dSJerome Forissier { 146*7901324dSJerome Forissier /* Should never happen since this is an internal 147*7901324dSJerome Forissier * function, and we know statically which labels 148*7901324dSJerome Forissier * are allowed. */ 149*7901324dSJerome Forissier return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); 150*7901324dSJerome Forissier } 151*7901324dSJerome Forissier 152*7901324dSJerome Forissier if( clen > MBEDTLS_SSL_TLS1_3_KEY_SCHEDULE_MAX_CONTEXT_LEN ) 153*7901324dSJerome Forissier { 154*7901324dSJerome Forissier /* Should not happen, as above. */ 155*7901324dSJerome Forissier return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); 156*7901324dSJerome Forissier } 157*7901324dSJerome Forissier 158*7901324dSJerome Forissier if( blen > MBEDTLS_SSL_TLS1_3_KEY_SCHEDULE_MAX_EXPANSION_LEN ) 159*7901324dSJerome Forissier { 160*7901324dSJerome Forissier /* Should not happen, as above. */ 161*7901324dSJerome Forissier return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); 162*7901324dSJerome Forissier } 163*7901324dSJerome Forissier 164*7901324dSJerome Forissier md = mbedtls_md_info_from_type( hash_alg ); 165*7901324dSJerome Forissier if( md == NULL ) 166*7901324dSJerome Forissier return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); 167*7901324dSJerome Forissier 168*7901324dSJerome Forissier ssl_tls1_3_hkdf_encode_label( blen, 169*7901324dSJerome Forissier label, llen, 170*7901324dSJerome Forissier ctx, clen, 171*7901324dSJerome Forissier hkdf_label, 172*7901324dSJerome Forissier &hkdf_label_len ); 173*7901324dSJerome Forissier 174*7901324dSJerome Forissier return( mbedtls_hkdf_expand( md, 175*7901324dSJerome Forissier secret, slen, 176*7901324dSJerome Forissier hkdf_label, hkdf_label_len, 177*7901324dSJerome Forissier buf, blen ) ); 178*7901324dSJerome Forissier } 179*7901324dSJerome Forissier 180*7901324dSJerome Forissier /* 181*7901324dSJerome Forissier * The traffic keying material is generated from the following inputs: 182*7901324dSJerome Forissier * 183*7901324dSJerome Forissier * - One secret value per sender. 184*7901324dSJerome Forissier * - A purpose value indicating the specific value being generated 185*7901324dSJerome Forissier * - The desired lengths of key and IV. 186*7901324dSJerome Forissier * 187*7901324dSJerome Forissier * The expansion itself is based on HKDF: 188*7901324dSJerome Forissier * 189*7901324dSJerome Forissier * [sender]_write_key = HKDF-Expand-Label( Secret, "key", "", key_length ) 190*7901324dSJerome Forissier * [sender]_write_iv = HKDF-Expand-Label( Secret, "iv" , "", iv_length ) 191*7901324dSJerome Forissier * 192*7901324dSJerome Forissier * [sender] denotes the sending side and the Secret value is provided 193*7901324dSJerome Forissier * by the function caller. Note that we generate server and client side 194*7901324dSJerome Forissier * keys in a single function call. 195*7901324dSJerome Forissier */ 196*7901324dSJerome Forissier int mbedtls_ssl_tls1_3_make_traffic_keys( 197*7901324dSJerome Forissier mbedtls_md_type_t hash_alg, 198*7901324dSJerome Forissier const unsigned char *client_secret, 199*7901324dSJerome Forissier const unsigned char *server_secret, 200*7901324dSJerome Forissier size_t slen, size_t key_len, size_t iv_len, 201*7901324dSJerome Forissier mbedtls_ssl_key_set *keys ) 202*7901324dSJerome Forissier { 203*7901324dSJerome Forissier int ret = 0; 204*7901324dSJerome Forissier 205*7901324dSJerome Forissier ret = mbedtls_ssl_tls1_3_hkdf_expand_label( hash_alg, 206*7901324dSJerome Forissier client_secret, slen, 207*7901324dSJerome Forissier MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN( key ), 208*7901324dSJerome Forissier NULL, 0, 209*7901324dSJerome Forissier keys->client_write_key, key_len ); 210*7901324dSJerome Forissier if( ret != 0 ) 211*7901324dSJerome Forissier return( ret ); 212*7901324dSJerome Forissier 213*7901324dSJerome Forissier ret = mbedtls_ssl_tls1_3_hkdf_expand_label( hash_alg, 214*7901324dSJerome Forissier server_secret, slen, 215*7901324dSJerome Forissier MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN( key ), 216*7901324dSJerome Forissier NULL, 0, 217*7901324dSJerome Forissier keys->server_write_key, key_len ); 218*7901324dSJerome Forissier if( ret != 0 ) 219*7901324dSJerome Forissier return( ret ); 220*7901324dSJerome Forissier 221*7901324dSJerome Forissier ret = mbedtls_ssl_tls1_3_hkdf_expand_label( hash_alg, 222*7901324dSJerome Forissier client_secret, slen, 223*7901324dSJerome Forissier MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN( iv ), 224*7901324dSJerome Forissier NULL, 0, 225*7901324dSJerome Forissier keys->client_write_iv, iv_len ); 226*7901324dSJerome Forissier if( ret != 0 ) 227*7901324dSJerome Forissier return( ret ); 228*7901324dSJerome Forissier 229*7901324dSJerome Forissier ret = mbedtls_ssl_tls1_3_hkdf_expand_label( hash_alg, 230*7901324dSJerome Forissier server_secret, slen, 231*7901324dSJerome Forissier MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN( iv ), 232*7901324dSJerome Forissier NULL, 0, 233*7901324dSJerome Forissier keys->server_write_iv, iv_len ); 234*7901324dSJerome Forissier if( ret != 0 ) 235*7901324dSJerome Forissier return( ret ); 236*7901324dSJerome Forissier 237*7901324dSJerome Forissier keys->key_len = key_len; 238*7901324dSJerome Forissier keys->iv_len = iv_len; 239*7901324dSJerome Forissier 240*7901324dSJerome Forissier return( 0 ); 241*7901324dSJerome Forissier } 242*7901324dSJerome Forissier 243*7901324dSJerome Forissier int mbedtls_ssl_tls1_3_derive_secret( 244*7901324dSJerome Forissier mbedtls_md_type_t hash_alg, 245*7901324dSJerome Forissier const unsigned char *secret, size_t slen, 246*7901324dSJerome Forissier const unsigned char *label, size_t llen, 247*7901324dSJerome Forissier const unsigned char *ctx, size_t clen, 248*7901324dSJerome Forissier int ctx_hashed, 249*7901324dSJerome Forissier unsigned char *dstbuf, size_t buflen ) 250*7901324dSJerome Forissier { 251*7901324dSJerome Forissier int ret; 252*7901324dSJerome Forissier unsigned char hashed_context[ MBEDTLS_MD_MAX_SIZE ]; 253*7901324dSJerome Forissier 254*7901324dSJerome Forissier const mbedtls_md_info_t *md; 255*7901324dSJerome Forissier md = mbedtls_md_info_from_type( hash_alg ); 256*7901324dSJerome Forissier if( md == NULL ) 257*7901324dSJerome Forissier return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); 258*7901324dSJerome Forissier 259*7901324dSJerome Forissier if( ctx_hashed == MBEDTLS_SSL_TLS1_3_CONTEXT_UNHASHED ) 260*7901324dSJerome Forissier { 261*7901324dSJerome Forissier ret = mbedtls_md( md, ctx, clen, hashed_context ); 262*7901324dSJerome Forissier if( ret != 0 ) 263*7901324dSJerome Forissier return( ret ); 264*7901324dSJerome Forissier clen = mbedtls_md_get_size( md ); 265*7901324dSJerome Forissier } 266*7901324dSJerome Forissier else 267*7901324dSJerome Forissier { 268*7901324dSJerome Forissier if( clen > sizeof(hashed_context) ) 269*7901324dSJerome Forissier { 270*7901324dSJerome Forissier /* This should never happen since this function is internal 271*7901324dSJerome Forissier * and the code sets `ctx_hashed` correctly. 272*7901324dSJerome Forissier * Let's double-check nonetheless to not run at the risk 273*7901324dSJerome Forissier * of getting a stack overflow. */ 274*7901324dSJerome Forissier return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); 275*7901324dSJerome Forissier } 276*7901324dSJerome Forissier 277*7901324dSJerome Forissier memcpy( hashed_context, ctx, clen ); 278*7901324dSJerome Forissier } 279*7901324dSJerome Forissier 280*7901324dSJerome Forissier return( mbedtls_ssl_tls1_3_hkdf_expand_label( hash_alg, 281*7901324dSJerome Forissier secret, slen, 282*7901324dSJerome Forissier label, llen, 283*7901324dSJerome Forissier hashed_context, clen, 284*7901324dSJerome Forissier dstbuf, buflen ) ); 285*7901324dSJerome Forissier } 286*7901324dSJerome Forissier 287*7901324dSJerome Forissier int mbedtls_ssl_tls1_3_evolve_secret( 288*7901324dSJerome Forissier mbedtls_md_type_t hash_alg, 289*7901324dSJerome Forissier const unsigned char *secret_old, 290*7901324dSJerome Forissier const unsigned char *input, size_t input_len, 291*7901324dSJerome Forissier unsigned char *secret_new ) 292*7901324dSJerome Forissier { 293*7901324dSJerome Forissier int ret = MBEDTLS_ERR_SSL_INTERNAL_ERROR; 294*7901324dSJerome Forissier size_t hlen, ilen; 295*7901324dSJerome Forissier unsigned char tmp_secret[ MBEDTLS_MD_MAX_SIZE ] = { 0 }; 296*7901324dSJerome Forissier unsigned char tmp_input [ MBEDTLS_MD_MAX_SIZE ] = { 0 }; 297*7901324dSJerome Forissier 298*7901324dSJerome Forissier const mbedtls_md_info_t *md; 299*7901324dSJerome Forissier md = mbedtls_md_info_from_type( hash_alg ); 300*7901324dSJerome Forissier if( md == NULL ) 301*7901324dSJerome Forissier return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); 302*7901324dSJerome Forissier 303*7901324dSJerome Forissier hlen = mbedtls_md_get_size( md ); 304*7901324dSJerome Forissier 305*7901324dSJerome Forissier /* For non-initial runs, call Derive-Secret( ., "derived", "") 306*7901324dSJerome Forissier * on the old secret. */ 307*7901324dSJerome Forissier if( secret_old != NULL ) 308*7901324dSJerome Forissier { 309*7901324dSJerome Forissier ret = mbedtls_ssl_tls1_3_derive_secret( 310*7901324dSJerome Forissier hash_alg, 311*7901324dSJerome Forissier secret_old, hlen, 312*7901324dSJerome Forissier MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN( derived ), 313*7901324dSJerome Forissier NULL, 0, /* context */ 314*7901324dSJerome Forissier MBEDTLS_SSL_TLS1_3_CONTEXT_UNHASHED, 315*7901324dSJerome Forissier tmp_secret, hlen ); 316*7901324dSJerome Forissier if( ret != 0 ) 317*7901324dSJerome Forissier goto cleanup; 318*7901324dSJerome Forissier } 319*7901324dSJerome Forissier 320*7901324dSJerome Forissier if( input != NULL ) 321*7901324dSJerome Forissier { 322*7901324dSJerome Forissier memcpy( tmp_input, input, input_len ); 323*7901324dSJerome Forissier ilen = input_len; 324*7901324dSJerome Forissier } 325*7901324dSJerome Forissier else 326*7901324dSJerome Forissier { 327*7901324dSJerome Forissier ilen = hlen; 328*7901324dSJerome Forissier } 329*7901324dSJerome Forissier 330*7901324dSJerome Forissier /* HKDF-Extract takes a salt and input key material. 331*7901324dSJerome Forissier * The salt is the old secret, and the input key material 332*7901324dSJerome Forissier * is the input secret (PSK / ECDHE). */ 333*7901324dSJerome Forissier ret = mbedtls_hkdf_extract( md, 334*7901324dSJerome Forissier tmp_secret, hlen, 335*7901324dSJerome Forissier tmp_input, ilen, 336*7901324dSJerome Forissier secret_new ); 337*7901324dSJerome Forissier if( ret != 0 ) 338*7901324dSJerome Forissier goto cleanup; 339*7901324dSJerome Forissier 340*7901324dSJerome Forissier ret = 0; 341*7901324dSJerome Forissier 342*7901324dSJerome Forissier cleanup: 343*7901324dSJerome Forissier 344*7901324dSJerome Forissier mbedtls_platform_zeroize( tmp_secret, sizeof(tmp_secret) ); 345*7901324dSJerome Forissier mbedtls_platform_zeroize( tmp_input, sizeof(tmp_input) ); 346*7901324dSJerome Forissier return( ret ); 347*7901324dSJerome Forissier } 348*7901324dSJerome Forissier 349*7901324dSJerome Forissier #endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */ 350