1 /***************************************************************************
2  * Copyright (c) 2024 Microsoft Corporation
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the MIT License which is available at
6  * https://opensource.org/licenses/MIT.
7  *
8  * SPDX-License-Identifier: MIT
9  **************************************************************************/
10 
11 
12 /**************************************************************************/
13 /**************************************************************************/
14 /**                                                                       */
15 /** NetX Secure Component                                                 */
16 /**                                                                       */
17 /**    Transport Layer Security (TLS)                                     */
18 /**                                                                       */
19 /**************************************************************************/
20 /**************************************************************************/
21 
22 #define NX_SECURE_SOURCE_CODE
23 
24 #include "nx_secure_tls.h"
25 
26 
27 /**************************************************************************/
28 /*                                                                        */
29 /*  FUNCTION                                               RELEASE        */
30 /*                                                                        */
31 /*    _nx_secure_tls_1_3_transcript_hash_save             PORTABLE C      */
32 /*                                                           6.1.8        */
33 /*  AUTHOR                                                                */
34 /*                                                                        */
35 /*    Timothy Stapko, Microsoft Corporation                               */
36 /*                                                                        */
37 /*  DESCRIPTION                                                           */
38 /*                                                                        */
39 /*    TLS 1.3 requires that a hash of handshake messages (the             */
40 /*    "transcript hash") be generated at various points to be fed into    */
41 /*    secrets and key generation process. This Function is used to        */
42 /*    indicate when a hash needs to be generated, and what that hash is   */
43 /*    stored as (e.g. ClientHello transcript hash).                       */
44 /*                                                                        */
45 /*  INPUT                                                                 */
46 /*                                                                        */
47 /*    tls_session                           TLS control block             */
48 /*                                                                        */
49 /*  OUTPUT                                                                */
50 /*                                                                        */
51 /*    status                                Completion status             */
52 /*                                                                        */
53 /*  CALLS                                                                 */
54 /*                                                                        */
55 /*                                                                        */
56 /*  CALLED BY                                                             */
57 /*                                                                        */
58 /*                                                                        */
59 /*                                                                        */
60 /*  RELEASE HISTORY                                                       */
61 /*                                                                        */
62 /*    DATE              NAME                      DESCRIPTION             */
63 /*                                                                        */
64 /*  05-19-2020     Timothy Stapko           Initial Version 6.0           */
65 /*  09-30-2020     Timothy Stapko           Modified comment(s),          */
66 /*                                            verified memcpy use cases,  */
67 /*                                            resulting in version 6.1    */
68 /*  08-02-2021     Timothy Stapko           Modified comment(s), added    */
69 /*                                            hash clone and cleanup,     */
70 /*                                            resulting in version 6.1.8  */
71 /*                                                                        */
72 /**************************************************************************/
73 #if (NX_SECURE_TLS_TLS_1_3_ENABLED)
74 
_nx_secure_tls_1_3_transcript_hash_save(NX_SECURE_TLS_SESSION * tls_session,UINT hash_index,UINT need_copy)75 UINT _nx_secure_tls_1_3_transcript_hash_save(NX_SECURE_TLS_SESSION *tls_session, UINT hash_index, UINT need_copy)
76 {
77 UINT status = NX_NOT_SUCCESSFUL;
78 const NX_CRYPTO_METHOD *method_ptr;
79 UINT  hash_size;
80 CHAR *metadata;
81 
82 
83     /* Don't oveflow the hash array. */
84     if(hash_index > NX_SECURE_TLS_1_3_MAX_TRANSCRIPT_HASHES)
85     {
86         return(NX_INVALID_PARAMETERS);
87     }
88 
89     /* Hash handshake record using ciphersuite hash routine. */
90     if (tls_session -> nx_secure_tls_session_ciphersuite == NX_NULL)
91     {
92         /* Set the hash method to the default of SHA-256 if no ciphersuite is available. */
93         method_ptr = tls_session -> nx_secure_tls_crypto_table->nx_secure_tls_handshake_hash_sha256_method;
94 
95     }
96     else
97     {
98         /* The handshake transcript hash in TLS 1.3 uses the hash routine associated with the chosen ciphersuite. */
99         method_ptr = tls_session -> nx_secure_tls_session_ciphersuite -> nx_secure_tls_hash;
100     }
101 
102     /* Generate the "transcript hash" for the point in the handshake where this message falls.
103      * This is needed for TLS 1.3 key generation which uses the hash of all previous handshake
104      * messages at multiple points during the handshake. Instead of saving the entirety of the
105      * handshake messages, just generate a hash when each record is hashed. */
106 
107     /* If nx_secure_tls_handshake_hash_sha256_metadata can't be modified for it will be used later, copy it to scratch buffer. */
108     if (need_copy)
109     {
110 
111         /* Copy over the handshake hash state into a local structure to do the intermediate calculation. */
112         NX_SECURE_HASH_METADATA_CLONE(tls_session -> nx_secure_tls_handshake_hash.nx_secure_tls_handshake_hash_scratch,
113                                       tls_session -> nx_secure_tls_handshake_hash.nx_secure_tls_handshake_hash_sha256_metadata,
114                                       tls_session -> nx_secure_tls_handshake_hash.nx_secure_tls_handshake_hash_sha256_metadata_size); /* Use case of memcpy is verified. */
115 
116         metadata = tls_session -> nx_secure_tls_handshake_hash.nx_secure_tls_handshake_hash_scratch;
117     }
118     else
119     {
120         metadata = tls_session -> nx_secure_tls_handshake_hash.nx_secure_tls_handshake_hash_sha256_metadata;
121     }
122 
123     /* Get hash output size. */
124     hash_size = (method_ptr ->nx_crypto_ICV_size_in_bits >> 3);
125 
126 
127     /* Generate a hash using our temporary copy of the hash metadata, place it into the TLS Session transcript hash array. */
128     if (method_ptr  -> nx_crypto_operation != NX_NULL)
129     {
130         status = method_ptr  -> nx_crypto_operation(NX_CRYPTO_HASH_CALCULATE,
131                                            tls_session -> nx_secure_tls_handshake_hash.nx_secure_tls_handshake_hash_sha256_handler,
132                                            (NX_CRYPTO_METHOD*)method_ptr,
133                                            NX_NULL,
134                                            0,
135                                            NX_NULL,
136                                            0,
137                                            NX_NULL,
138                                            &tls_session->nx_secure_tls_key_material.nx_secure_tls_transcript_hashes[hash_index][0],
139                                            hash_size,
140                                            metadata,
141                                            tls_session -> nx_secure_tls_handshake_hash.nx_secure_tls_handshake_hash_sha256_metadata_size,
142                                            NX_NULL,
143                                            NX_NULL);
144     }
145 
146     if (need_copy)
147     {
148         NX_SECURE_HASH_CLONE_CLEANUP(metadata, tls_session -> nx_secure_tls_handshake_hash.nx_secure_tls_handshake_hash_sha256_metadata_size);
149     }
150 
151     return(status);
152 }
153 
154 #endif
155