xref: /optee_os/lib/libmbedtls/mbedtls/library/ssl_tls13_keys.c (revision 039e02df2716a0ed886b56e1e07b7ac1d8597228)
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