Branch data Line data Source code
1 : : /*
2 : : * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3 : : *
4 : : * Licensed under the Apache License, Version 2.0 (the "License").
5 : : * You may not use this file except in compliance with the License.
6 : : * A copy of the License is located at
7 : : *
8 : : * http://aws.amazon.com/apache2.0
9 : : *
10 : : * or in the "license" file accompanying this file. This file is distributed
11 : : * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12 : : * express or implied. See the License for the specific language governing
13 : : * permissions and limitations under the License.
14 : : */
15 : :
16 : : #include "crypto/s2n_tls13_keys.h"
17 : :
18 : : #include <stdio.h>
19 : :
20 : : #include "crypto/s2n_hkdf.h"
21 : : #include "crypto/s2n_hmac.h"
22 : : #include "error/s2n_errno.h"
23 : : #include "stuffer/s2n_stuffer.h"
24 : : #include "utils/s2n_blob.h"
25 : : #include "utils/s2n_mem.h"
26 : : #include "utils/s2n_safety.h"
27 : :
28 : : /*
29 : : * There are 9 keys that can be generated by the end of a TLS 1.3 handshake.
30 : : * We currently support the following, more will be supported
31 : : * when the relevant TLS 1.3 features are worked on.
32 : : *
33 : : * [x] binder_key
34 : : * [x] client_early_traffic_secret
35 : : * [ ] early_exporter_master_secret
36 : : * [x] client_handshake_traffic_secret
37 : : * [x] server_handshake_traffic_secret
38 : : * [x] client_application_traffic_secret_0
39 : : * [x] server_application_traffic_secret_0
40 : : * [x] exporter_master_secret
41 : : * [x] resumption_master_secret
42 : : *
43 : : * The TLS 1.3 key generation can be divided into 3 phases
44 : : * 1. early secrets
45 : : * 2. handshake secrets
46 : : * 3. master secrets
47 : : *
48 : : * In each phase, secrets are first extracted with HKDF-Extract that takes in
49 : : * both an ikm (input keying material) and a salt. Some keys can be derived/expanded
50 : : * from the extract before a "tls13 derived" Derive-Secret is used to
51 : : * derive the input salt for the next phase.
52 : : */
53 : :
54 : : /*
55 : : * Define TLS 1.3 HKDF labels as specified in
56 : : * https://tools.ietf.org/html/rfc8446#section-7.1
57 : : */
58 : : S2N_BLOB_LABEL(s2n_tls13_label_derived_secret, "derived")
59 : :
60 : : S2N_BLOB_LABEL(s2n_tls13_label_external_psk_binder_key, "ext binder")
61 : : S2N_BLOB_LABEL(s2n_tls13_label_resumption_psk_binder_key, "res binder")
62 : :
63 : : S2N_BLOB_LABEL(s2n_tls13_label_client_early_traffic_secret, "c e traffic")
64 : : S2N_BLOB_LABEL(s2n_tls13_label_early_exporter_master_secret, "e exp master")
65 : :
66 : : S2N_BLOB_LABEL(s2n_tls13_label_client_handshake_traffic_secret, "c hs traffic")
67 : : S2N_BLOB_LABEL(s2n_tls13_label_server_handshake_traffic_secret, "s hs traffic")
68 : :
69 : : S2N_BLOB_LABEL(s2n_tls13_label_client_application_traffic_secret, "c ap traffic")
70 : : S2N_BLOB_LABEL(s2n_tls13_label_server_application_traffic_secret, "s ap traffic")
71 : :
72 : : S2N_BLOB_LABEL(s2n_tls13_label_exporter_master_secret, "exp master")
73 : : S2N_BLOB_LABEL(s2n_tls13_label_resumption_master_secret, "res master")
74 : : S2N_BLOB_LABEL(s2n_tls13_label_session_ticket_secret, "resumption")
75 : :
76 : : /*
77 : : * Traffic secret labels
78 : : */
79 : : S2N_BLOB_LABEL(s2n_tls13_label_traffic_secret_key, "key")
80 : : S2N_BLOB_LABEL(s2n_tls13_label_traffic_secret_iv, "iv")
81 : :
82 : : /*
83 : : * TLS 1.3 Exporter label
84 : : */
85 : : S2N_BLOB_LABEL(s2n_tls13_label_exporter, "exporter")
86 : :
87 : : /*
88 : : * TLS 1.3 Finished label
89 : : */
90 : : S2N_BLOB_LABEL(s2n_tls13_label_finished, "finished")
91 : :
92 : : /*
93 : : * TLS 1.3 KeyUpdate label
94 : : */
95 : : S2N_BLOB_LABEL(s2n_tls13_label_application_traffic_secret_update, "traffic upd")
96 : :
97 : : static const struct s2n_blob zero_length_blob = { .data = NULL, .size = 0 };
98 : :
99 : : /*
100 : : * Initializes the tls13_keys struct
101 : : */
102 : : int s2n_tls13_keys_init(struct s2n_tls13_keys *keys, s2n_hmac_algorithm alg)
103 : 23867 : {
104 [ # # ][ - + ]: 23867 : POSIX_ENSURE_REF(keys);
105 : :
106 : 23867 : keys->hmac_algorithm = alg;
107 [ - + ]: 23867 : POSIX_GUARD(s2n_hmac_hash_alg(alg, &keys->hash_algorithm));
108 [ - + ]: 23867 : POSIX_GUARD(s2n_hash_digest_size(keys->hash_algorithm, &keys->size));
109 [ - + ]: 23867 : POSIX_GUARD(s2n_blob_init(&keys->extract_secret, keys->extract_secret_bytes, keys->size));
110 [ - + ]: 23867 : POSIX_GUARD(s2n_blob_init(&keys->derive_secret, keys->derive_secret_bytes, keys->size));
111 [ - + ]: 23867 : POSIX_GUARD(s2n_hmac_new(&keys->hmac));
112 : :
113 : 23867 : return 0;
114 : 23867 : }
115 : :
116 : : /*
117 : : * Frees any allocation
118 : : */
119 : : int s2n_tls13_keys_free(struct s2n_tls13_keys *keys)
120 : 23867 : {
121 [ - + ][ # # ]: 23867 : POSIX_ENSURE_REF(keys);
122 : :
123 [ - + ]: 23867 : POSIX_GUARD(s2n_hmac_free(&keys->hmac));
124 : :
125 : 23867 : return 0;
126 : 23867 : }
127 : :
128 : : /*
129 : : * Derive Traffic Key and IV based on input secret
130 : : */
131 : : int s2n_tls13_derive_traffic_keys(struct s2n_tls13_keys *keys, struct s2n_blob *secret, struct s2n_blob *key, struct s2n_blob *iv)
132 : 1801 : {
133 [ # # ][ - + ]: 1801 : POSIX_ENSURE_REF(keys);
134 [ - + ][ # # ]: 1801 : POSIX_ENSURE_REF(secret);
135 [ - + ][ # # ]: 1801 : POSIX_ENSURE_REF(key);
136 [ - + ][ # # ]: 1801 : POSIX_ENSURE_REF(iv);
137 : :
138 [ - + ]: 1801 : POSIX_GUARD(s2n_hkdf_expand_label(&keys->hmac, keys->hmac_algorithm, secret,
139 : 1801 : &s2n_tls13_label_traffic_secret_key, &zero_length_blob, key));
140 [ - + ]: 1801 : POSIX_GUARD(s2n_hkdf_expand_label(&keys->hmac, keys->hmac_algorithm, secret,
141 : 1801 : &s2n_tls13_label_traffic_secret_iv, &zero_length_blob, iv));
142 : 1801 : return 0;
143 : 1801 : }
144 : :
145 : : /*
146 : : * Generate finished key for compute finished hashes/MACs
147 : : * https://tools.ietf.org/html/rfc8446#section-4.4.4
148 : : */
149 : : int s2n_tls13_derive_finished_key(struct s2n_tls13_keys *keys, struct s2n_blob *secret_key, struct s2n_blob *output_finish_key)
150 : 2181 : {
151 [ - + ]: 2181 : POSIX_GUARD(s2n_hkdf_expand_label(&keys->hmac, keys->hmac_algorithm, secret_key, &s2n_tls13_label_finished, &zero_length_blob, output_finish_key));
152 : :
153 : 2181 : return 0;
154 : 2181 : }
155 : :
156 : : /*
157 : : * Compute finished verify data using HMAC
158 : : * with a finished key and hash state
159 : : * https://tools.ietf.org/html/rfc8446#section-4.4.4
160 : : */
161 : : int s2n_tls13_calculate_finished_mac(struct s2n_tls13_keys *keys, struct s2n_blob *finished_key, struct s2n_hash_state *hash_state, struct s2n_blob *finished_verify)
162 : 11510 : {
163 [ - + ][ - + ]: 11510 : s2n_tls13_key_blob(transcript_hash, keys->size);
[ # # ]
164 [ - + ]: 11510 : POSIX_GUARD(s2n_hash_digest(hash_state, transcript_hash.data, transcript_hash.size));
165 [ - + ]: 11510 : POSIX_GUARD(s2n_hkdf_extract(&keys->hmac, keys->hmac_algorithm, finished_key, &transcript_hash, finished_verify));
166 : 11510 : return S2N_SUCCESS;
167 : 11510 : }
168 : :
169 : : /*
170 : : * Derives next generation of traffic secret
171 : : */
172 : : int s2n_tls13_update_application_traffic_secret(struct s2n_tls13_keys *keys, struct s2n_blob *old_secret, struct s2n_blob *new_secret)
173 : 1802 : {
174 [ - + ][ # # ]: 1802 : POSIX_ENSURE_REF(keys);
175 [ - + ][ # # ]: 1802 : POSIX_ENSURE_REF(old_secret);
176 [ - + ][ # # ]: 1802 : POSIX_ENSURE_REF(new_secret);
177 : :
178 [ - + ]: 1802 : POSIX_GUARD(s2n_hkdf_expand_label(&keys->hmac, keys->hmac_algorithm, old_secret,
179 : 1802 : &s2n_tls13_label_application_traffic_secret_update, &zero_length_blob, new_secret));
180 : :
181 : 1802 : return 0;
182 : 1802 : }
183 : :
184 : : S2N_RESULT s2n_tls13_derive_session_ticket_secret(struct s2n_tls13_keys *keys, struct s2n_blob *resumption_secret,
185 : : struct s2n_blob *ticket_nonce, struct s2n_blob *secret_blob)
186 : 889 : {
187 [ - + ][ # # ]: 889 : RESULT_ENSURE_REF(keys);
188 [ - + ][ # # ]: 889 : RESULT_ENSURE_REF(resumption_secret);
189 [ - + ][ # # ]: 889 : RESULT_ENSURE_REF(ticket_nonce);
190 [ - + ][ # # ]: 889 : RESULT_ENSURE_REF(secret_blob);
191 : :
192 : : /* Derive session ticket secret from master session resumption secret */
193 [ - + ]: 889 : RESULT_GUARD_POSIX(s2n_hkdf_expand_label(&keys->hmac, keys->hmac_algorithm, resumption_secret,
194 : 889 : &s2n_tls13_label_session_ticket_secret, ticket_nonce, secret_blob));
195 : :
196 : 889 : return S2N_RESULT_OK;
197 : 889 : }
|