1e71b7053SJung-uk Kim /*
2cfc39718SJung-uk Kim * Copyright 2016-2022 The OpenSSL Project Authors. All Rights Reserved.
3e71b7053SJung-uk Kim *
4b077aed3SPierre Pronchery * Licensed under the Apache License 2.0 (the "License"). You may not use
5e71b7053SJung-uk Kim * this file except in compliance with the License. You can obtain a copy
6e71b7053SJung-uk Kim * in the file LICENSE in the source distribution or at
7e71b7053SJung-uk Kim * https://www.openssl.org/source/license.html
8e71b7053SJung-uk Kim */
9e71b7053SJung-uk Kim
10e71b7053SJung-uk Kim #include <stdlib.h>
1117f01e99SJung-uk Kim #include "ssl_local.h"
12aa906e2aSJohn Baldwin #include "internal/ktls.h"
13aa906e2aSJohn Baldwin #include "record/record_local.h"
14e71b7053SJung-uk Kim #include "internal/cryptlib.h"
15e71b7053SJung-uk Kim #include <openssl/evp.h>
16e71b7053SJung-uk Kim #include <openssl/kdf.h>
17b077aed3SPierre Pronchery #include <openssl/core_names.h>
18e71b7053SJung-uk Kim
196935a639SJung-uk Kim #define TLS13_MAX_LABEL_LEN 249
20e71b7053SJung-uk Kim
21b077aed3SPierre Pronchery #ifdef CHARSET_EBCDIC
22b077aed3SPierre Pronchery static const unsigned char label_prefix[] = { 0x74, 0x6C, 0x73, 0x31, 0x33, 0x20, 0x00 };
23b077aed3SPierre Pronchery #else
24b077aed3SPierre Pronchery static const unsigned char label_prefix[] = "tls13 ";
25b077aed3SPierre Pronchery #endif
26e71b7053SJung-uk Kim
27e71b7053SJung-uk Kim /*
28e71b7053SJung-uk Kim * Given a |secret|; a |label| of length |labellen|; and |data| of length
29e71b7053SJung-uk Kim * |datalen| (e.g. typically a hash of the handshake messages), derive a new
30e71b7053SJung-uk Kim * secret |outlen| bytes long and store it in the location pointed to be |out|.
316935a639SJung-uk Kim * The |data| value may be zero length. Any errors will be treated as fatal if
326935a639SJung-uk Kim * |fatal| is set. Returns 1 on success 0 on failure.
33e71b7053SJung-uk Kim */
tls13_hkdf_expand(SSL * s,const EVP_MD * md,const unsigned char * secret,const unsigned char * label,size_t labellen,const unsigned char * data,size_t datalen,unsigned char * out,size_t outlen,int fatal)34e71b7053SJung-uk Kim int tls13_hkdf_expand(SSL *s, const EVP_MD *md, const unsigned char *secret,
35e71b7053SJung-uk Kim const unsigned char *label, size_t labellen,
36e71b7053SJung-uk Kim const unsigned char *data, size_t datalen,
376935a639SJung-uk Kim unsigned char *out, size_t outlen, int fatal)
38e71b7053SJung-uk Kim {
39b077aed3SPierre Pronchery EVP_KDF *kdf = EVP_KDF_fetch(s->ctx->libctx, OSSL_KDF_NAME_TLS1_3_KDF,
40b077aed3SPierre Pronchery s->ctx->propq);
41b077aed3SPierre Pronchery EVP_KDF_CTX *kctx;
42b077aed3SPierre Pronchery OSSL_PARAM params[7], *p = params;
43b077aed3SPierre Pronchery int mode = EVP_PKEY_HKDEF_MODE_EXPAND_ONLY;
44b077aed3SPierre Pronchery const char *mdname = EVP_MD_get0_name(md);
45e71b7053SJung-uk Kim int ret;
46e71b7053SJung-uk Kim size_t hashlen;
47e71b7053SJung-uk Kim
48b077aed3SPierre Pronchery kctx = EVP_KDF_CTX_new(kdf);
49b077aed3SPierre Pronchery EVP_KDF_free(kdf);
50b077aed3SPierre Pronchery if (kctx == NULL)
51e71b7053SJung-uk Kim return 0;
52e71b7053SJung-uk Kim
536935a639SJung-uk Kim if (labellen > TLS13_MAX_LABEL_LEN) {
546935a639SJung-uk Kim if (fatal) {
55b077aed3SPierre Pronchery SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
566935a639SJung-uk Kim } else {
576935a639SJung-uk Kim /*
586935a639SJung-uk Kim * Probably we have been called from SSL_export_keying_material(),
596935a639SJung-uk Kim * or SSL_export_keying_material_early().
606935a639SJung-uk Kim */
61b077aed3SPierre Pronchery ERR_raise(ERR_LIB_SSL, SSL_R_TLS_ILLEGAL_EXPORTER_LABEL);
626935a639SJung-uk Kim }
63b077aed3SPierre Pronchery EVP_KDF_CTX_free(kctx);
646935a639SJung-uk Kim return 0;
656935a639SJung-uk Kim }
666935a639SJung-uk Kim
67b077aed3SPierre Pronchery if ((ret = EVP_MD_get_size(md)) <= 0) {
68b077aed3SPierre Pronchery EVP_KDF_CTX_free(kctx);
696935a639SJung-uk Kim if (fatal)
70b077aed3SPierre Pronchery SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
716935a639SJung-uk Kim else
72b077aed3SPierre Pronchery ERR_raise(ERR_LIB_SSL, ERR_R_INTERNAL_ERROR);
73e71b7053SJung-uk Kim return 0;
74e71b7053SJung-uk Kim }
75b077aed3SPierre Pronchery hashlen = (size_t)ret;
76e71b7053SJung-uk Kim
77b077aed3SPierre Pronchery *p++ = OSSL_PARAM_construct_int(OSSL_KDF_PARAM_MODE, &mode);
78b077aed3SPierre Pronchery *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_DIGEST,
79b077aed3SPierre Pronchery (char *)mdname, 0);
80b077aed3SPierre Pronchery *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_KEY,
81b077aed3SPierre Pronchery (unsigned char *)secret, hashlen);
82b077aed3SPierre Pronchery *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_PREFIX,
83b077aed3SPierre Pronchery (unsigned char *)label_prefix,
84b077aed3SPierre Pronchery sizeof(label_prefix) - 1);
85b077aed3SPierre Pronchery *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_LABEL,
86b077aed3SPierre Pronchery (unsigned char *)label, labellen);
87b077aed3SPierre Pronchery if (data != NULL)
88b077aed3SPierre Pronchery *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_DATA,
89b077aed3SPierre Pronchery (unsigned char *)data,
90b077aed3SPierre Pronchery datalen);
91b077aed3SPierre Pronchery *p++ = OSSL_PARAM_construct_end();
92e71b7053SJung-uk Kim
93b077aed3SPierre Pronchery ret = EVP_KDF_derive(kctx, out, outlen, params) <= 0;
94b077aed3SPierre Pronchery EVP_KDF_CTX_free(kctx);
95e71b7053SJung-uk Kim
966935a639SJung-uk Kim if (ret != 0) {
976935a639SJung-uk Kim if (fatal)
98b077aed3SPierre Pronchery SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
996935a639SJung-uk Kim else
100b077aed3SPierre Pronchery ERR_raise(ERR_LIB_SSL, ERR_R_INTERNAL_ERROR);
1016935a639SJung-uk Kim }
102e71b7053SJung-uk Kim
103e71b7053SJung-uk Kim return ret == 0;
104e71b7053SJung-uk Kim }
105e71b7053SJung-uk Kim
106e71b7053SJung-uk Kim /*
107e71b7053SJung-uk Kim * Given a |secret| generate a |key| of length |keylen| bytes. Returns 1 on
108e71b7053SJung-uk Kim * success 0 on failure.
109e71b7053SJung-uk Kim */
tls13_derive_key(SSL * s,const EVP_MD * md,const unsigned char * secret,unsigned char * key,size_t keylen)110e71b7053SJung-uk Kim int tls13_derive_key(SSL *s, const EVP_MD *md, const unsigned char *secret,
111e71b7053SJung-uk Kim unsigned char *key, size_t keylen)
112e71b7053SJung-uk Kim {
113da327cd2SJung-uk Kim #ifdef CHARSET_EBCDIC
114da327cd2SJung-uk Kim static const unsigned char keylabel[] ={ 0x6B, 0x65, 0x79, 0x00 };
115da327cd2SJung-uk Kim #else
116e71b7053SJung-uk Kim static const unsigned char keylabel[] = "key";
117da327cd2SJung-uk Kim #endif
118e71b7053SJung-uk Kim
119e71b7053SJung-uk Kim return tls13_hkdf_expand(s, md, secret, keylabel, sizeof(keylabel) - 1,
1206935a639SJung-uk Kim NULL, 0, key, keylen, 1);
121e71b7053SJung-uk Kim }
122e71b7053SJung-uk Kim
123e71b7053SJung-uk Kim /*
124e71b7053SJung-uk Kim * Given a |secret| generate an |iv| of length |ivlen| bytes. Returns 1 on
125e71b7053SJung-uk Kim * success 0 on failure.
126e71b7053SJung-uk Kim */
tls13_derive_iv(SSL * s,const EVP_MD * md,const unsigned char * secret,unsigned char * iv,size_t ivlen)127e71b7053SJung-uk Kim int tls13_derive_iv(SSL *s, const EVP_MD *md, const unsigned char *secret,
128e71b7053SJung-uk Kim unsigned char *iv, size_t ivlen)
129e71b7053SJung-uk Kim {
130da327cd2SJung-uk Kim #ifdef CHARSET_EBCDIC
131da327cd2SJung-uk Kim static const unsigned char ivlabel[] = { 0x69, 0x76, 0x00 };
132da327cd2SJung-uk Kim #else
133e71b7053SJung-uk Kim static const unsigned char ivlabel[] = "iv";
134da327cd2SJung-uk Kim #endif
135e71b7053SJung-uk Kim
136e71b7053SJung-uk Kim return tls13_hkdf_expand(s, md, secret, ivlabel, sizeof(ivlabel) - 1,
1376935a639SJung-uk Kim NULL, 0, iv, ivlen, 1);
138e71b7053SJung-uk Kim }
139e71b7053SJung-uk Kim
tls13_derive_finishedkey(SSL * s,const EVP_MD * md,const unsigned char * secret,unsigned char * fin,size_t finlen)140e71b7053SJung-uk Kim int tls13_derive_finishedkey(SSL *s, const EVP_MD *md,
141e71b7053SJung-uk Kim const unsigned char *secret,
142e71b7053SJung-uk Kim unsigned char *fin, size_t finlen)
143e71b7053SJung-uk Kim {
144da327cd2SJung-uk Kim #ifdef CHARSET_EBCDIC
145da327cd2SJung-uk Kim static const unsigned char finishedlabel[] = { 0x66, 0x69, 0x6E, 0x69, 0x73, 0x68, 0x65, 0x64, 0x00 };
146da327cd2SJung-uk Kim #else
147e71b7053SJung-uk Kim static const unsigned char finishedlabel[] = "finished";
148da327cd2SJung-uk Kim #endif
149e71b7053SJung-uk Kim
150e71b7053SJung-uk Kim return tls13_hkdf_expand(s, md, secret, finishedlabel,
1516935a639SJung-uk Kim sizeof(finishedlabel) - 1, NULL, 0, fin, finlen, 1);
152e71b7053SJung-uk Kim }
153e71b7053SJung-uk Kim
154e71b7053SJung-uk Kim /*
155e71b7053SJung-uk Kim * Given the previous secret |prevsecret| and a new input secret |insecret| of
156e71b7053SJung-uk Kim * length |insecretlen|, generate a new secret and store it in the location
157e71b7053SJung-uk Kim * pointed to by |outsecret|. Returns 1 on success 0 on failure.
158e71b7053SJung-uk Kim */
tls13_generate_secret(SSL * s,const EVP_MD * md,const unsigned char * prevsecret,const unsigned char * insecret,size_t insecretlen,unsigned char * outsecret)159e71b7053SJung-uk Kim int tls13_generate_secret(SSL *s, const EVP_MD *md,
160e71b7053SJung-uk Kim const unsigned char *prevsecret,
161e71b7053SJung-uk Kim const unsigned char *insecret,
162e71b7053SJung-uk Kim size_t insecretlen,
163e71b7053SJung-uk Kim unsigned char *outsecret)
164e71b7053SJung-uk Kim {
165b077aed3SPierre Pronchery size_t mdlen;
166e71b7053SJung-uk Kim int mdleni;
167e71b7053SJung-uk Kim int ret;
168b077aed3SPierre Pronchery EVP_KDF *kdf;
169b077aed3SPierre Pronchery EVP_KDF_CTX *kctx;
170b077aed3SPierre Pronchery OSSL_PARAM params[7], *p = params;
171b077aed3SPierre Pronchery int mode = EVP_PKEY_HKDEF_MODE_EXTRACT_ONLY;
172b077aed3SPierre Pronchery const char *mdname = EVP_MD_get0_name(md);
173da327cd2SJung-uk Kim #ifdef CHARSET_EBCDIC
174da327cd2SJung-uk Kim static const char derived_secret_label[] = { 0x64, 0x65, 0x72, 0x69, 0x76, 0x65, 0x64, 0x00 };
175da327cd2SJung-uk Kim #else
176e71b7053SJung-uk Kim static const char derived_secret_label[] = "derived";
177da327cd2SJung-uk Kim #endif
178e71b7053SJung-uk Kim
179b077aed3SPierre Pronchery kdf = EVP_KDF_fetch(s->ctx->libctx, OSSL_KDF_NAME_TLS1_3_KDF, s->ctx->propq);
180b077aed3SPierre Pronchery kctx = EVP_KDF_CTX_new(kdf);
181b077aed3SPierre Pronchery EVP_KDF_free(kdf);
182b077aed3SPierre Pronchery if (kctx == NULL) {
183b077aed3SPierre Pronchery SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
184e71b7053SJung-uk Kim return 0;
185e71b7053SJung-uk Kim }
186e71b7053SJung-uk Kim
187b077aed3SPierre Pronchery mdleni = EVP_MD_get_size(md);
188e71b7053SJung-uk Kim /* Ensure cast to size_t is safe */
189e71b7053SJung-uk Kim if (!ossl_assert(mdleni >= 0)) {
190b077aed3SPierre Pronchery SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
191b077aed3SPierre Pronchery EVP_KDF_CTX_free(kctx);
192e71b7053SJung-uk Kim return 0;
193e71b7053SJung-uk Kim }
194e71b7053SJung-uk Kim mdlen = (size_t)mdleni;
195e71b7053SJung-uk Kim
196b077aed3SPierre Pronchery *p++ = OSSL_PARAM_construct_int(OSSL_KDF_PARAM_MODE, &mode);
197b077aed3SPierre Pronchery *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_DIGEST,
198b077aed3SPierre Pronchery (char *)mdname, 0);
199b077aed3SPierre Pronchery if (insecret != NULL)
200b077aed3SPierre Pronchery *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_KEY,
201b077aed3SPierre Pronchery (unsigned char *)insecret,
202b077aed3SPierre Pronchery insecretlen);
203b077aed3SPierre Pronchery if (prevsecret != NULL)
204b077aed3SPierre Pronchery *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_SALT,
205b077aed3SPierre Pronchery (unsigned char *)prevsecret, mdlen);
206b077aed3SPierre Pronchery *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_PREFIX,
207b077aed3SPierre Pronchery (unsigned char *)label_prefix,
208b077aed3SPierre Pronchery sizeof(label_prefix) - 1);
209b077aed3SPierre Pronchery *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_LABEL,
210e71b7053SJung-uk Kim (unsigned char *)derived_secret_label,
211b077aed3SPierre Pronchery sizeof(derived_secret_label) - 1);
212b077aed3SPierre Pronchery *p++ = OSSL_PARAM_construct_end();
213e71b7053SJung-uk Kim
214b077aed3SPierre Pronchery ret = EVP_KDF_derive(kctx, outsecret, mdlen, params) <= 0;
215e71b7053SJung-uk Kim
216e71b7053SJung-uk Kim if (ret != 0)
217b077aed3SPierre Pronchery SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
218e71b7053SJung-uk Kim
219b077aed3SPierre Pronchery EVP_KDF_CTX_free(kctx);
220e71b7053SJung-uk Kim return ret == 0;
221e71b7053SJung-uk Kim }
222e71b7053SJung-uk Kim
223e71b7053SJung-uk Kim /*
224e71b7053SJung-uk Kim * Given an input secret |insecret| of length |insecretlen| generate the
225e71b7053SJung-uk Kim * handshake secret. This requires the early secret to already have been
226e71b7053SJung-uk Kim * generated. Returns 1 on success 0 on failure.
227e71b7053SJung-uk Kim */
tls13_generate_handshake_secret(SSL * s,const unsigned char * insecret,size_t insecretlen)228e71b7053SJung-uk Kim int tls13_generate_handshake_secret(SSL *s, const unsigned char *insecret,
229e71b7053SJung-uk Kim size_t insecretlen)
230e71b7053SJung-uk Kim {
231e71b7053SJung-uk Kim /* Calls SSLfatal() if required */
232e71b7053SJung-uk Kim return tls13_generate_secret(s, ssl_handshake_md(s), s->early_secret,
233e71b7053SJung-uk Kim insecret, insecretlen,
234e71b7053SJung-uk Kim (unsigned char *)&s->handshake_secret);
235e71b7053SJung-uk Kim }
236e71b7053SJung-uk Kim
237e71b7053SJung-uk Kim /*
238e71b7053SJung-uk Kim * Given the handshake secret |prev| of length |prevlen| generate the master
239e71b7053SJung-uk Kim * secret and store its length in |*secret_size|. Returns 1 on success 0 on
240e71b7053SJung-uk Kim * failure.
241e71b7053SJung-uk Kim */
tls13_generate_master_secret(SSL * s,unsigned char * out,unsigned char * prev,size_t prevlen,size_t * secret_size)242e71b7053SJung-uk Kim int tls13_generate_master_secret(SSL *s, unsigned char *out,
243e71b7053SJung-uk Kim unsigned char *prev, size_t prevlen,
244e71b7053SJung-uk Kim size_t *secret_size)
245e71b7053SJung-uk Kim {
246e71b7053SJung-uk Kim const EVP_MD *md = ssl_handshake_md(s);
247e71b7053SJung-uk Kim
248b077aed3SPierre Pronchery *secret_size = EVP_MD_get_size(md);
249e71b7053SJung-uk Kim /* Calls SSLfatal() if required */
250e71b7053SJung-uk Kim return tls13_generate_secret(s, md, prev, NULL, 0, out);
251e71b7053SJung-uk Kim }
252e71b7053SJung-uk Kim
253e71b7053SJung-uk Kim /*
254e71b7053SJung-uk Kim * Generates the mac for the Finished message. Returns the length of the MAC or
255e71b7053SJung-uk Kim * 0 on error.
256e71b7053SJung-uk Kim */
tls13_final_finish_mac(SSL * s,const char * str,size_t slen,unsigned char * out)257e71b7053SJung-uk Kim size_t tls13_final_finish_mac(SSL *s, const char *str, size_t slen,
258e71b7053SJung-uk Kim unsigned char *out)
259e71b7053SJung-uk Kim {
260e71b7053SJung-uk Kim const EVP_MD *md = ssl_handshake_md(s);
261b077aed3SPierre Pronchery const char *mdname = EVP_MD_get0_name(md);
262e71b7053SJung-uk Kim unsigned char hash[EVP_MAX_MD_SIZE];
263b077aed3SPierre Pronchery unsigned char finsecret[EVP_MAX_MD_SIZE];
264b077aed3SPierre Pronchery unsigned char *key = NULL;
265b077aed3SPierre Pronchery size_t len = 0, hashlen;
266b077aed3SPierre Pronchery OSSL_PARAM params[2], *p = params;
267b077aed3SPierre Pronchery
268b077aed3SPierre Pronchery if (md == NULL)
269b077aed3SPierre Pronchery return 0;
270b077aed3SPierre Pronchery
271b077aed3SPierre Pronchery /* Safe to cast away const here since we're not "getting" any data */
272b077aed3SPierre Pronchery if (s->ctx->propq != NULL)
273b077aed3SPierre Pronchery *p++ = OSSL_PARAM_construct_utf8_string(OSSL_ALG_PARAM_PROPERTIES,
274b077aed3SPierre Pronchery (char *)s->ctx->propq,
275b077aed3SPierre Pronchery 0);
276b077aed3SPierre Pronchery *p = OSSL_PARAM_construct_end();
277e71b7053SJung-uk Kim
278e71b7053SJung-uk Kim if (!ssl_handshake_hash(s, hash, sizeof(hash), &hashlen)) {
279e71b7053SJung-uk Kim /* SSLfatal() already called */
280e71b7053SJung-uk Kim goto err;
281e71b7053SJung-uk Kim }
282e71b7053SJung-uk Kim
283e71b7053SJung-uk Kim if (str == s->method->ssl3_enc->server_finished_label) {
284b077aed3SPierre Pronchery key = s->server_finished_secret;
285e71b7053SJung-uk Kim } else if (SSL_IS_FIRST_HANDSHAKE(s)) {
286b077aed3SPierre Pronchery key = s->client_finished_secret;
287e71b7053SJung-uk Kim } else {
288b077aed3SPierre Pronchery if (!tls13_derive_finishedkey(s, md,
289e71b7053SJung-uk Kim s->client_app_traffic_secret,
290e71b7053SJung-uk Kim finsecret, hashlen))
291e71b7053SJung-uk Kim goto err;
292b077aed3SPierre Pronchery key = finsecret;
293e71b7053SJung-uk Kim }
294e71b7053SJung-uk Kim
295b077aed3SPierre Pronchery if (!EVP_Q_mac(s->ctx->libctx, "HMAC", s->ctx->propq, mdname,
296b077aed3SPierre Pronchery params, key, hashlen, hash, hashlen,
297b077aed3SPierre Pronchery /* outsize as per sizeof(peer_finish_md) */
298b077aed3SPierre Pronchery out, EVP_MAX_MD_SIZE * 2, &len)) {
299b077aed3SPierre Pronchery SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
300e71b7053SJung-uk Kim goto err;
301e71b7053SJung-uk Kim }
302e71b7053SJung-uk Kim
303e71b7053SJung-uk Kim err:
304b077aed3SPierre Pronchery OPENSSL_cleanse(finsecret, sizeof(finsecret));
305b077aed3SPierre Pronchery return len;
306e71b7053SJung-uk Kim }
307e71b7053SJung-uk Kim
308e71b7053SJung-uk Kim /*
309e71b7053SJung-uk Kim * There isn't really a key block in TLSv1.3, but we still need this function
310e71b7053SJung-uk Kim * for initialising the cipher and hash. Returns 1 on success or 0 on failure.
311e71b7053SJung-uk Kim */
tls13_setup_key_block(SSL * s)312e71b7053SJung-uk Kim int tls13_setup_key_block(SSL *s)
313e71b7053SJung-uk Kim {
314e71b7053SJung-uk Kim const EVP_CIPHER *c;
315e71b7053SJung-uk Kim const EVP_MD *hash;
316e71b7053SJung-uk Kim
317b077aed3SPierre Pronchery s->session->cipher = s->s3.tmp.new_cipher;
318b077aed3SPierre Pronchery if (!ssl_cipher_get_evp(s->ctx, s->session, &c, &hash, NULL, NULL, NULL,
319b077aed3SPierre Pronchery 0)) {
320b077aed3SPierre Pronchery /* Error is already recorded */
321b077aed3SPierre Pronchery SSLfatal_alert(s, SSL_AD_INTERNAL_ERROR);
322e71b7053SJung-uk Kim return 0;
323e71b7053SJung-uk Kim }
324e71b7053SJung-uk Kim
325b077aed3SPierre Pronchery ssl_evp_cipher_free(s->s3.tmp.new_sym_enc);
326b077aed3SPierre Pronchery s->s3.tmp.new_sym_enc = c;
327b077aed3SPierre Pronchery ssl_evp_md_free(s->s3.tmp.new_hash);
328b077aed3SPierre Pronchery s->s3.tmp.new_hash = hash;
329e71b7053SJung-uk Kim
330e71b7053SJung-uk Kim return 1;
331e71b7053SJung-uk Kim }
332e71b7053SJung-uk Kim
derive_secret_key_and_iv(SSL * s,int sending,const EVP_MD * md,const EVP_CIPHER * ciph,const unsigned char * insecret,const unsigned char * hash,const unsigned char * label,size_t labellen,unsigned char * secret,unsigned char * key,unsigned char * iv,EVP_CIPHER_CTX * ciph_ctx)333e71b7053SJung-uk Kim static int derive_secret_key_and_iv(SSL *s, int sending, const EVP_MD *md,
334e71b7053SJung-uk Kim const EVP_CIPHER *ciph,
335e71b7053SJung-uk Kim const unsigned char *insecret,
336e71b7053SJung-uk Kim const unsigned char *hash,
337e71b7053SJung-uk Kim const unsigned char *label,
338e71b7053SJung-uk Kim size_t labellen, unsigned char *secret,
339aa906e2aSJohn Baldwin unsigned char *key, unsigned char *iv,
340aa906e2aSJohn Baldwin EVP_CIPHER_CTX *ciph_ctx)
341e71b7053SJung-uk Kim {
342e71b7053SJung-uk Kim size_t ivlen, keylen, taglen;
343b077aed3SPierre Pronchery int hashleni = EVP_MD_get_size(md);
344e71b7053SJung-uk Kim size_t hashlen;
345e71b7053SJung-uk Kim
346e71b7053SJung-uk Kim /* Ensure cast to size_t is safe */
347e71b7053SJung-uk Kim if (!ossl_assert(hashleni >= 0)) {
348b077aed3SPierre Pronchery SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_EVP_LIB);
349aa906e2aSJohn Baldwin return 0;
350e71b7053SJung-uk Kim }
351e71b7053SJung-uk Kim hashlen = (size_t)hashleni;
352e71b7053SJung-uk Kim
353e71b7053SJung-uk Kim if (!tls13_hkdf_expand(s, md, insecret, label, labellen, hash, hashlen,
3546935a639SJung-uk Kim secret, hashlen, 1)) {
355e71b7053SJung-uk Kim /* SSLfatal() already called */
356aa906e2aSJohn Baldwin return 0;
357e71b7053SJung-uk Kim }
358e71b7053SJung-uk Kim
359b077aed3SPierre Pronchery keylen = EVP_CIPHER_get_key_length(ciph);
360b077aed3SPierre Pronchery if (EVP_CIPHER_get_mode(ciph) == EVP_CIPH_CCM_MODE) {
361e71b7053SJung-uk Kim uint32_t algenc;
362e71b7053SJung-uk Kim
363e71b7053SJung-uk Kim ivlen = EVP_CCM_TLS_IV_LEN;
364b077aed3SPierre Pronchery if (s->s3.tmp.new_cipher != NULL) {
365b077aed3SPierre Pronchery algenc = s->s3.tmp.new_cipher->algorithm_enc;
36658f35182SJung-uk Kim } else if (s->session->cipher != NULL) {
367e71b7053SJung-uk Kim /* We've not selected a cipher yet - we must be doing early data */
368e71b7053SJung-uk Kim algenc = s->session->cipher->algorithm_enc;
36958f35182SJung-uk Kim } else if (s->psksession != NULL && s->psksession->cipher != NULL) {
37058f35182SJung-uk Kim /* We must be doing early data with out-of-band PSK */
37158f35182SJung-uk Kim algenc = s->psksession->cipher->algorithm_enc;
372e71b7053SJung-uk Kim } else {
373b077aed3SPierre Pronchery SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_EVP_LIB);
374aa906e2aSJohn Baldwin return 0;
375e71b7053SJung-uk Kim }
376e71b7053SJung-uk Kim if (algenc & (SSL_AES128CCM8 | SSL_AES256CCM8))
377e71b7053SJung-uk Kim taglen = EVP_CCM8_TLS_TAG_LEN;
378e71b7053SJung-uk Kim else
379e71b7053SJung-uk Kim taglen = EVP_CCM_TLS_TAG_LEN;
380e71b7053SJung-uk Kim } else {
381b077aed3SPierre Pronchery ivlen = EVP_CIPHER_get_iv_length(ciph);
382e71b7053SJung-uk Kim taglen = 0;
383e71b7053SJung-uk Kim }
384e71b7053SJung-uk Kim
385e71b7053SJung-uk Kim if (!tls13_derive_key(s, md, secret, key, keylen)
386e71b7053SJung-uk Kim || !tls13_derive_iv(s, md, secret, iv, ivlen)) {
387e71b7053SJung-uk Kim /* SSLfatal() already called */
388aa906e2aSJohn Baldwin return 0;
389e71b7053SJung-uk Kim }
390e71b7053SJung-uk Kim
391e71b7053SJung-uk Kim if (EVP_CipherInit_ex(ciph_ctx, ciph, NULL, NULL, NULL, sending) <= 0
392b077aed3SPierre Pronchery || EVP_CIPHER_CTX_ctrl(ciph_ctx, EVP_CTRL_AEAD_SET_IVLEN, ivlen, NULL) <= 0
393b077aed3SPierre Pronchery || (taglen != 0 && EVP_CIPHER_CTX_ctrl(ciph_ctx, EVP_CTRL_AEAD_SET_TAG,
394b077aed3SPierre Pronchery taglen, NULL) <= 0)
395e71b7053SJung-uk Kim || EVP_CipherInit_ex(ciph_ctx, NULL, NULL, key, NULL, -1) <= 0) {
396b077aed3SPierre Pronchery SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_EVP_LIB);
397aa906e2aSJohn Baldwin return 0;
398e71b7053SJung-uk Kim }
399e71b7053SJung-uk Kim
400e71b7053SJung-uk Kim return 1;
401e71b7053SJung-uk Kim }
402e71b7053SJung-uk Kim
tls13_change_cipher_state(SSL * s,int which)403e71b7053SJung-uk Kim int tls13_change_cipher_state(SSL *s, int which)
404e71b7053SJung-uk Kim {
405da327cd2SJung-uk Kim #ifdef CHARSET_EBCDIC
406da327cd2SJung-uk Kim static const unsigned char client_early_traffic[] = {0x63, 0x20, 0x65, 0x20, /*traffic*/0x74, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, 0x00};
407da327cd2SJung-uk Kim static const unsigned char client_handshake_traffic[] = {0x63, 0x20, 0x68, 0x73, 0x20, /*traffic*/0x74, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, 0x00};
408da327cd2SJung-uk Kim static const unsigned char client_application_traffic[] = {0x63, 0x20, 0x61, 0x70, 0x20, /*traffic*/0x74, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, 0x00};
409da327cd2SJung-uk Kim static const unsigned char server_handshake_traffic[] = {0x73, 0x20, 0x68, 0x73, 0x20, /*traffic*/0x74, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, 0x00};
410da327cd2SJung-uk Kim static const unsigned char server_application_traffic[] = {0x73, 0x20, 0x61, 0x70, 0x20, /*traffic*/0x74, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, 0x00};
411da327cd2SJung-uk Kim static const unsigned char exporter_master_secret[] = {0x65, 0x78, 0x70, 0x20, /* master*/ 0x6D, 0x61, 0x73, 0x74, 0x65, 0x72, 0x00};
412da327cd2SJung-uk Kim static const unsigned char resumption_master_secret[] = {0x72, 0x65, 0x73, 0x20, /* master*/ 0x6D, 0x61, 0x73, 0x74, 0x65, 0x72, 0x00};
413da327cd2SJung-uk Kim static const unsigned char early_exporter_master_secret[] = {0x65, 0x20, 0x65, 0x78, 0x70, 0x20, /* master*/ 0x6D, 0x61, 0x73, 0x74, 0x65, 0x72, 0x00};
414da327cd2SJung-uk Kim #else
415e71b7053SJung-uk Kim static const unsigned char client_early_traffic[] = "c e traffic";
416e71b7053SJung-uk Kim static const unsigned char client_handshake_traffic[] = "c hs traffic";
417e71b7053SJung-uk Kim static const unsigned char client_application_traffic[] = "c ap traffic";
418e71b7053SJung-uk Kim static const unsigned char server_handshake_traffic[] = "s hs traffic";
419e71b7053SJung-uk Kim static const unsigned char server_application_traffic[] = "s ap traffic";
420e71b7053SJung-uk Kim static const unsigned char exporter_master_secret[] = "exp master";
421e71b7053SJung-uk Kim static const unsigned char resumption_master_secret[] = "res master";
422e71b7053SJung-uk Kim static const unsigned char early_exporter_master_secret[] = "e exp master";
423da327cd2SJung-uk Kim #endif
424e71b7053SJung-uk Kim unsigned char *iv;
425aa906e2aSJohn Baldwin unsigned char key[EVP_MAX_KEY_LENGTH];
426e71b7053SJung-uk Kim unsigned char secret[EVP_MAX_MD_SIZE];
427e71b7053SJung-uk Kim unsigned char hashval[EVP_MAX_MD_SIZE];
428e71b7053SJung-uk Kim unsigned char *hash = hashval;
429e71b7053SJung-uk Kim unsigned char *insecret;
430e71b7053SJung-uk Kim unsigned char *finsecret = NULL;
431e71b7053SJung-uk Kim const char *log_label = NULL;
432e71b7053SJung-uk Kim EVP_CIPHER_CTX *ciph_ctx;
433e71b7053SJung-uk Kim size_t finsecretlen = 0;
434e71b7053SJung-uk Kim const unsigned char *label;
435e71b7053SJung-uk Kim size_t labellen, hashlen = 0;
436e71b7053SJung-uk Kim int ret = 0;
437e71b7053SJung-uk Kim const EVP_MD *md = NULL;
438e71b7053SJung-uk Kim const EVP_CIPHER *cipher = NULL;
439aa906e2aSJohn Baldwin #if !defined(OPENSSL_NO_KTLS) && defined(OPENSSL_KTLS_TLS13)
440aa906e2aSJohn Baldwin ktls_crypto_info_t crypto_info;
441*6ed16d17SDaiki Ueno void *rl_sequence;
442aa906e2aSJohn Baldwin BIO *bio;
443aa906e2aSJohn Baldwin #endif
444e71b7053SJung-uk Kim
445e71b7053SJung-uk Kim if (which & SSL3_CC_READ) {
446e71b7053SJung-uk Kim if (s->enc_read_ctx != NULL) {
447e71b7053SJung-uk Kim EVP_CIPHER_CTX_reset(s->enc_read_ctx);
448e71b7053SJung-uk Kim } else {
449e71b7053SJung-uk Kim s->enc_read_ctx = EVP_CIPHER_CTX_new();
450e71b7053SJung-uk Kim if (s->enc_read_ctx == NULL) {
451b077aed3SPierre Pronchery SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE);
452e71b7053SJung-uk Kim goto err;
453e71b7053SJung-uk Kim }
454e71b7053SJung-uk Kim }
455e71b7053SJung-uk Kim ciph_ctx = s->enc_read_ctx;
456e71b7053SJung-uk Kim iv = s->read_iv;
457e71b7053SJung-uk Kim
458e71b7053SJung-uk Kim RECORD_LAYER_reset_read_sequence(&s->rlayer);
459e71b7053SJung-uk Kim } else {
460e71b7053SJung-uk Kim s->statem.enc_write_state = ENC_WRITE_STATE_INVALID;
461e71b7053SJung-uk Kim if (s->enc_write_ctx != NULL) {
462e71b7053SJung-uk Kim EVP_CIPHER_CTX_reset(s->enc_write_ctx);
463e71b7053SJung-uk Kim } else {
464e71b7053SJung-uk Kim s->enc_write_ctx = EVP_CIPHER_CTX_new();
465e71b7053SJung-uk Kim if (s->enc_write_ctx == NULL) {
466b077aed3SPierre Pronchery SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE);
467e71b7053SJung-uk Kim goto err;
468e71b7053SJung-uk Kim }
469e71b7053SJung-uk Kim }
470e71b7053SJung-uk Kim ciph_ctx = s->enc_write_ctx;
471e71b7053SJung-uk Kim iv = s->write_iv;
472e71b7053SJung-uk Kim
473e71b7053SJung-uk Kim RECORD_LAYER_reset_write_sequence(&s->rlayer);
474e71b7053SJung-uk Kim }
475e71b7053SJung-uk Kim
476e71b7053SJung-uk Kim if (((which & SSL3_CC_CLIENT) && (which & SSL3_CC_WRITE))
477e71b7053SJung-uk Kim || ((which & SSL3_CC_SERVER) && (which & SSL3_CC_READ))) {
478e71b7053SJung-uk Kim if (which & SSL3_CC_EARLY) {
479e71b7053SJung-uk Kim EVP_MD_CTX *mdctx = NULL;
480e71b7053SJung-uk Kim long handlen;
481e71b7053SJung-uk Kim void *hdata;
482e71b7053SJung-uk Kim unsigned int hashlenui;
483e71b7053SJung-uk Kim const SSL_CIPHER *sslcipher = SSL_SESSION_get0_cipher(s->session);
484e71b7053SJung-uk Kim
485e71b7053SJung-uk Kim insecret = s->early_secret;
486e71b7053SJung-uk Kim label = client_early_traffic;
487e71b7053SJung-uk Kim labellen = sizeof(client_early_traffic) - 1;
488e71b7053SJung-uk Kim log_label = CLIENT_EARLY_LABEL;
489e71b7053SJung-uk Kim
490b077aed3SPierre Pronchery handlen = BIO_get_mem_data(s->s3.handshake_buffer, &hdata);
491e71b7053SJung-uk Kim if (handlen <= 0) {
492b077aed3SPierre Pronchery SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_R_BAD_HANDSHAKE_LENGTH);
493e71b7053SJung-uk Kim goto err;
494e71b7053SJung-uk Kim }
495e71b7053SJung-uk Kim
496e71b7053SJung-uk Kim if (s->early_data_state == SSL_EARLY_DATA_CONNECTING
497e71b7053SJung-uk Kim && s->max_early_data > 0
498e71b7053SJung-uk Kim && s->session->ext.max_early_data == 0) {
499e71b7053SJung-uk Kim /*
500e71b7053SJung-uk Kim * If we are attempting to send early data, and we've decided to
501e71b7053SJung-uk Kim * actually do it but max_early_data in s->session is 0 then we
502e71b7053SJung-uk Kim * must be using an external PSK.
503e71b7053SJung-uk Kim */
504e71b7053SJung-uk Kim if (!ossl_assert(s->psksession != NULL
505e71b7053SJung-uk Kim && s->max_early_data ==
506e71b7053SJung-uk Kim s->psksession->ext.max_early_data)) {
507b077aed3SPierre Pronchery SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
508e71b7053SJung-uk Kim goto err;
509e71b7053SJung-uk Kim }
510e71b7053SJung-uk Kim sslcipher = SSL_SESSION_get0_cipher(s->psksession);
511e71b7053SJung-uk Kim }
512e71b7053SJung-uk Kim if (sslcipher == NULL) {
513b077aed3SPierre Pronchery SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_R_BAD_PSK);
514e71b7053SJung-uk Kim goto err;
515e71b7053SJung-uk Kim }
516e71b7053SJung-uk Kim
517e71b7053SJung-uk Kim /*
518e71b7053SJung-uk Kim * We need to calculate the handshake digest using the digest from
519e71b7053SJung-uk Kim * the session. We haven't yet selected our ciphersuite so we can't
520e71b7053SJung-uk Kim * use ssl_handshake_md().
521e71b7053SJung-uk Kim */
522e71b7053SJung-uk Kim mdctx = EVP_MD_CTX_new();
523e71b7053SJung-uk Kim if (mdctx == NULL) {
524b077aed3SPierre Pronchery SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE);
525e71b7053SJung-uk Kim goto err;
526e71b7053SJung-uk Kim }
527b077aed3SPierre Pronchery
528b077aed3SPierre Pronchery /*
529b077aed3SPierre Pronchery * This ups the ref count on cipher so we better make sure we free
530b077aed3SPierre Pronchery * it again
531b077aed3SPierre Pronchery */
532b077aed3SPierre Pronchery if (!ssl_cipher_get_evp_cipher(s->ctx, sslcipher, &cipher)) {
533b077aed3SPierre Pronchery /* Error is already recorded */
534b077aed3SPierre Pronchery SSLfatal_alert(s, SSL_AD_INTERNAL_ERROR);
535b077aed3SPierre Pronchery EVP_MD_CTX_free(mdctx);
536b077aed3SPierre Pronchery goto err;
537b077aed3SPierre Pronchery }
538b077aed3SPierre Pronchery
539b077aed3SPierre Pronchery md = ssl_md(s->ctx, sslcipher->algorithm2);
540e71b7053SJung-uk Kim if (md == NULL || !EVP_DigestInit_ex(mdctx, md, NULL)
541e71b7053SJung-uk Kim || !EVP_DigestUpdate(mdctx, hdata, handlen)
542e71b7053SJung-uk Kim || !EVP_DigestFinal_ex(mdctx, hashval, &hashlenui)) {
543b077aed3SPierre Pronchery SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
544e71b7053SJung-uk Kim EVP_MD_CTX_free(mdctx);
545e71b7053SJung-uk Kim goto err;
546e71b7053SJung-uk Kim }
547e71b7053SJung-uk Kim hashlen = hashlenui;
548e71b7053SJung-uk Kim EVP_MD_CTX_free(mdctx);
549e71b7053SJung-uk Kim
550e71b7053SJung-uk Kim if (!tls13_hkdf_expand(s, md, insecret,
551e71b7053SJung-uk Kim early_exporter_master_secret,
552e71b7053SJung-uk Kim sizeof(early_exporter_master_secret) - 1,
553e71b7053SJung-uk Kim hashval, hashlen,
5546935a639SJung-uk Kim s->early_exporter_master_secret, hashlen,
5556935a639SJung-uk Kim 1)) {
556b077aed3SPierre Pronchery SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
557e71b7053SJung-uk Kim goto err;
558e71b7053SJung-uk Kim }
559e71b7053SJung-uk Kim
560e71b7053SJung-uk Kim if (!ssl_log_secret(s, EARLY_EXPORTER_SECRET_LABEL,
561e71b7053SJung-uk Kim s->early_exporter_master_secret, hashlen)) {
562e71b7053SJung-uk Kim /* SSLfatal() already called */
563e71b7053SJung-uk Kim goto err;
564e71b7053SJung-uk Kim }
565e71b7053SJung-uk Kim } else if (which & SSL3_CC_HANDSHAKE) {
566e71b7053SJung-uk Kim insecret = s->handshake_secret;
567e71b7053SJung-uk Kim finsecret = s->client_finished_secret;
568b077aed3SPierre Pronchery finsecretlen = EVP_MD_get_size(ssl_handshake_md(s));
569e71b7053SJung-uk Kim label = client_handshake_traffic;
570e71b7053SJung-uk Kim labellen = sizeof(client_handshake_traffic) - 1;
571e71b7053SJung-uk Kim log_label = CLIENT_HANDSHAKE_LABEL;
572e71b7053SJung-uk Kim /*
573e71b7053SJung-uk Kim * The handshake hash used for the server read/client write handshake
574e71b7053SJung-uk Kim * traffic secret is the same as the hash for the server
575e71b7053SJung-uk Kim * write/client read handshake traffic secret. However, if we
576e71b7053SJung-uk Kim * processed early data then we delay changing the server
577e71b7053SJung-uk Kim * read/client write cipher state until later, and the handshake
578e71b7053SJung-uk Kim * hashes have moved on. Therefore we use the value saved earlier
579e71b7053SJung-uk Kim * when we did the server write/client read change cipher state.
580e71b7053SJung-uk Kim */
581e71b7053SJung-uk Kim hash = s->handshake_traffic_hash;
582e71b7053SJung-uk Kim } else {
583e71b7053SJung-uk Kim insecret = s->master_secret;
584e71b7053SJung-uk Kim label = client_application_traffic;
585e71b7053SJung-uk Kim labellen = sizeof(client_application_traffic) - 1;
586e71b7053SJung-uk Kim log_label = CLIENT_APPLICATION_LABEL;
587e71b7053SJung-uk Kim /*
588e71b7053SJung-uk Kim * For this we only use the handshake hashes up until the server
589e71b7053SJung-uk Kim * Finished hash. We do not include the client's Finished, which is
590e71b7053SJung-uk Kim * what ssl_handshake_hash() would give us. Instead we use the
591e71b7053SJung-uk Kim * previously saved value.
592e71b7053SJung-uk Kim */
593e71b7053SJung-uk Kim hash = s->server_finished_hash;
594e71b7053SJung-uk Kim }
595e71b7053SJung-uk Kim } else {
596e71b7053SJung-uk Kim /* Early data never applies to client-read/server-write */
597e71b7053SJung-uk Kim if (which & SSL3_CC_HANDSHAKE) {
598e71b7053SJung-uk Kim insecret = s->handshake_secret;
599e71b7053SJung-uk Kim finsecret = s->server_finished_secret;
600b077aed3SPierre Pronchery finsecretlen = EVP_MD_get_size(ssl_handshake_md(s));
601e71b7053SJung-uk Kim label = server_handshake_traffic;
602e71b7053SJung-uk Kim labellen = sizeof(server_handshake_traffic) - 1;
603e71b7053SJung-uk Kim log_label = SERVER_HANDSHAKE_LABEL;
604e71b7053SJung-uk Kim } else {
605e71b7053SJung-uk Kim insecret = s->master_secret;
606e71b7053SJung-uk Kim label = server_application_traffic;
607e71b7053SJung-uk Kim labellen = sizeof(server_application_traffic) - 1;
608e71b7053SJung-uk Kim log_label = SERVER_APPLICATION_LABEL;
609e71b7053SJung-uk Kim }
610e71b7053SJung-uk Kim }
611e71b7053SJung-uk Kim
612e71b7053SJung-uk Kim if (!(which & SSL3_CC_EARLY)) {
613e71b7053SJung-uk Kim md = ssl_handshake_md(s);
614b077aed3SPierre Pronchery cipher = s->s3.tmp.new_sym_enc;
615e71b7053SJung-uk Kim if (!ssl3_digest_cached_records(s, 1)
616e71b7053SJung-uk Kim || !ssl_handshake_hash(s, hashval, sizeof(hashval), &hashlen)) {
617e71b7053SJung-uk Kim /* SSLfatal() already called */;
618e71b7053SJung-uk Kim goto err;
619e71b7053SJung-uk Kim }
620e71b7053SJung-uk Kim }
621e71b7053SJung-uk Kim
622e71b7053SJung-uk Kim /*
623e71b7053SJung-uk Kim * Save the hash of handshakes up to now for use when we calculate the
624e71b7053SJung-uk Kim * client application traffic secret
625e71b7053SJung-uk Kim */
626e71b7053SJung-uk Kim if (label == server_application_traffic)
627e71b7053SJung-uk Kim memcpy(s->server_finished_hash, hashval, hashlen);
628e71b7053SJung-uk Kim
629e71b7053SJung-uk Kim if (label == server_handshake_traffic)
630e71b7053SJung-uk Kim memcpy(s->handshake_traffic_hash, hashval, hashlen);
631e71b7053SJung-uk Kim
632e71b7053SJung-uk Kim if (label == client_application_traffic) {
633e71b7053SJung-uk Kim /*
634e71b7053SJung-uk Kim * We also create the resumption master secret, but this time use the
635e71b7053SJung-uk Kim * hash for the whole handshake including the Client Finished
636e71b7053SJung-uk Kim */
637e71b7053SJung-uk Kim if (!tls13_hkdf_expand(s, ssl_handshake_md(s), insecret,
638e71b7053SJung-uk Kim resumption_master_secret,
639e71b7053SJung-uk Kim sizeof(resumption_master_secret) - 1,
640e71b7053SJung-uk Kim hashval, hashlen, s->resumption_master_secret,
6416935a639SJung-uk Kim hashlen, 1)) {
642e71b7053SJung-uk Kim /* SSLfatal() already called */
643e71b7053SJung-uk Kim goto err;
644e71b7053SJung-uk Kim }
645e71b7053SJung-uk Kim }
646e71b7053SJung-uk Kim
647aa906e2aSJohn Baldwin /* check whether cipher is known */
648aa906e2aSJohn Baldwin if(!ossl_assert(cipher != NULL))
649aa906e2aSJohn Baldwin goto err;
650aa906e2aSJohn Baldwin
651e71b7053SJung-uk Kim if (!derive_secret_key_and_iv(s, which & SSL3_CC_WRITE, md, cipher,
652aa906e2aSJohn Baldwin insecret, hash, label, labellen, secret, key,
653aa906e2aSJohn Baldwin iv, ciph_ctx)) {
654e71b7053SJung-uk Kim /* SSLfatal() already called */
655e71b7053SJung-uk Kim goto err;
656e71b7053SJung-uk Kim }
657e71b7053SJung-uk Kim
658e71b7053SJung-uk Kim if (label == server_application_traffic) {
659e71b7053SJung-uk Kim memcpy(s->server_app_traffic_secret, secret, hashlen);
660e71b7053SJung-uk Kim /* Now we create the exporter master secret */
661e71b7053SJung-uk Kim if (!tls13_hkdf_expand(s, ssl_handshake_md(s), insecret,
662e71b7053SJung-uk Kim exporter_master_secret,
663e71b7053SJung-uk Kim sizeof(exporter_master_secret) - 1,
664e71b7053SJung-uk Kim hash, hashlen, s->exporter_master_secret,
6656935a639SJung-uk Kim hashlen, 1)) {
666e71b7053SJung-uk Kim /* SSLfatal() already called */
667e71b7053SJung-uk Kim goto err;
668e71b7053SJung-uk Kim }
669e71b7053SJung-uk Kim
670e71b7053SJung-uk Kim if (!ssl_log_secret(s, EXPORTER_SECRET_LABEL, s->exporter_master_secret,
671e71b7053SJung-uk Kim hashlen)) {
672e71b7053SJung-uk Kim /* SSLfatal() already called */
673e71b7053SJung-uk Kim goto err;
674e71b7053SJung-uk Kim }
675e71b7053SJung-uk Kim } else if (label == client_application_traffic)
676e71b7053SJung-uk Kim memcpy(s->client_app_traffic_secret, secret, hashlen);
677e71b7053SJung-uk Kim
678e71b7053SJung-uk Kim if (!ssl_log_secret(s, log_label, secret, hashlen)) {
679e71b7053SJung-uk Kim /* SSLfatal() already called */
680e71b7053SJung-uk Kim goto err;
681e71b7053SJung-uk Kim }
682e71b7053SJung-uk Kim
683e71b7053SJung-uk Kim if (finsecret != NULL
684e71b7053SJung-uk Kim && !tls13_derive_finishedkey(s, ssl_handshake_md(s), secret,
685e71b7053SJung-uk Kim finsecret, finsecretlen)) {
686e71b7053SJung-uk Kim /* SSLfatal() already called */
687e71b7053SJung-uk Kim goto err;
688e71b7053SJung-uk Kim }
689e71b7053SJung-uk Kim
690e71b7053SJung-uk Kim if (!s->server && label == client_early_traffic)
691e71b7053SJung-uk Kim s->statem.enc_write_state = ENC_WRITE_STATE_WRITE_PLAIN_ALERTS;
692e71b7053SJung-uk Kim else
693e71b7053SJung-uk Kim s->statem.enc_write_state = ENC_WRITE_STATE_VALID;
694aa906e2aSJohn Baldwin #ifndef OPENSSL_NO_KTLS
695aa906e2aSJohn Baldwin # if defined(OPENSSL_KTLS_TLS13)
696*6ed16d17SDaiki Ueno if (!(which & SSL3_CC_APPLICATION)
69762ca9fc1SJohn Baldwin || (s->options & SSL_OP_ENABLE_KTLS) == 0)
698aa906e2aSJohn Baldwin goto skip_ktls;
699aa906e2aSJohn Baldwin
700aa906e2aSJohn Baldwin /* ktls supports only the maximum fragment size */
701aa906e2aSJohn Baldwin if (ssl_get_max_send_fragment(s) != SSL3_RT_MAX_PLAIN_LENGTH)
702aa906e2aSJohn Baldwin goto skip_ktls;
703aa906e2aSJohn Baldwin
704aa906e2aSJohn Baldwin /* ktls does not support record padding */
705aa906e2aSJohn Baldwin if (s->record_padding_cb != NULL)
706aa906e2aSJohn Baldwin goto skip_ktls;
707aa906e2aSJohn Baldwin
708aa906e2aSJohn Baldwin /* check that cipher is supported */
709aa906e2aSJohn Baldwin if (!ktls_check_supported_cipher(s, cipher, ciph_ctx))
710aa906e2aSJohn Baldwin goto skip_ktls;
711aa906e2aSJohn Baldwin
712*6ed16d17SDaiki Ueno if (which & SSL3_CC_WRITE)
713aa906e2aSJohn Baldwin bio = s->wbio;
714*6ed16d17SDaiki Ueno else
715*6ed16d17SDaiki Ueno bio = s->rbio;
716aa906e2aSJohn Baldwin
717aa906e2aSJohn Baldwin if (!ossl_assert(bio != NULL)) {
718b077aed3SPierre Pronchery SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
719aa906e2aSJohn Baldwin goto err;
720aa906e2aSJohn Baldwin }
721aa906e2aSJohn Baldwin
722aa906e2aSJohn Baldwin /* All future data will get encrypted by ktls. Flush the BIO or skip ktls */
723*6ed16d17SDaiki Ueno if (which & SSL3_CC_WRITE) {
724aa906e2aSJohn Baldwin if (BIO_flush(bio) <= 0)
725aa906e2aSJohn Baldwin goto skip_ktls;
726*6ed16d17SDaiki Ueno }
727aa906e2aSJohn Baldwin
728aa906e2aSJohn Baldwin /* configure kernel crypto structure */
729*6ed16d17SDaiki Ueno if (which & SSL3_CC_WRITE)
730*6ed16d17SDaiki Ueno rl_sequence = RECORD_LAYER_get_write_sequence(&s->rlayer);
731*6ed16d17SDaiki Ueno else
732*6ed16d17SDaiki Ueno rl_sequence = RECORD_LAYER_get_read_sequence(&s->rlayer);
733*6ed16d17SDaiki Ueno
734*6ed16d17SDaiki Ueno if (!ktls_configure_crypto(s, cipher, ciph_ctx, rl_sequence, &crypto_info,
735*6ed16d17SDaiki Ueno which & SSL3_CC_WRITE, iv, key, NULL, 0))
736aa906e2aSJohn Baldwin goto skip_ktls;
737aa906e2aSJohn Baldwin
738aa906e2aSJohn Baldwin /* ktls works with user provided buffers directly */
739*6ed16d17SDaiki Ueno if (BIO_set_ktls(bio, &crypto_info, which & SSL3_CC_WRITE)) {
740*6ed16d17SDaiki Ueno if (which & SSL3_CC_WRITE)
741aa906e2aSJohn Baldwin ssl3_release_write_buffer(s);
742*6ed16d17SDaiki Ueno }
743aa906e2aSJohn Baldwin skip_ktls:
744aa906e2aSJohn Baldwin # endif
745aa906e2aSJohn Baldwin #endif
746e71b7053SJung-uk Kim ret = 1;
747e71b7053SJung-uk Kim err:
748b077aed3SPierre Pronchery if ((which & SSL3_CC_EARLY) != 0) {
749b077aed3SPierre Pronchery /* We up-refed this so now we need to down ref */
750b077aed3SPierre Pronchery ssl_evp_cipher_free(cipher);
751b077aed3SPierre Pronchery }
752aa906e2aSJohn Baldwin OPENSSL_cleanse(key, sizeof(key));
753e71b7053SJung-uk Kim OPENSSL_cleanse(secret, sizeof(secret));
754e71b7053SJung-uk Kim return ret;
755e71b7053SJung-uk Kim }
756e71b7053SJung-uk Kim
tls13_update_key(SSL * s,int sending)757e71b7053SJung-uk Kim int tls13_update_key(SSL *s, int sending)
758e71b7053SJung-uk Kim {
759da327cd2SJung-uk Kim #ifdef CHARSET_EBCDIC
760da327cd2SJung-uk Kim static const unsigned char application_traffic[] = { 0x74, 0x72 ,0x61 ,0x66 ,0x66 ,0x69 ,0x63 ,0x20 ,0x75 ,0x70 ,0x64, 0x00};
761da327cd2SJung-uk Kim #else
762e71b7053SJung-uk Kim static const unsigned char application_traffic[] = "traffic upd";
763da327cd2SJung-uk Kim #endif
764e71b7053SJung-uk Kim const EVP_MD *md = ssl_handshake_md(s);
765b077aed3SPierre Pronchery size_t hashlen;
766aa906e2aSJohn Baldwin unsigned char key[EVP_MAX_KEY_LENGTH];
767e71b7053SJung-uk Kim unsigned char *insecret, *iv;
768e71b7053SJung-uk Kim unsigned char secret[EVP_MAX_MD_SIZE];
769b077aed3SPierre Pronchery char *log_label;
770e71b7053SJung-uk Kim EVP_CIPHER_CTX *ciph_ctx;
771b077aed3SPierre Pronchery int ret = 0, l;
772b077aed3SPierre Pronchery
773b077aed3SPierre Pronchery if ((l = EVP_MD_get_size(md)) <= 0) {
774b077aed3SPierre Pronchery SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
775b077aed3SPierre Pronchery return 0;
776b077aed3SPierre Pronchery }
777b077aed3SPierre Pronchery hashlen = (size_t)l;
778e71b7053SJung-uk Kim
779e71b7053SJung-uk Kim if (s->server == sending)
780e71b7053SJung-uk Kim insecret = s->server_app_traffic_secret;
781e71b7053SJung-uk Kim else
782e71b7053SJung-uk Kim insecret = s->client_app_traffic_secret;
783e71b7053SJung-uk Kim
784e71b7053SJung-uk Kim if (sending) {
785e71b7053SJung-uk Kim s->statem.enc_write_state = ENC_WRITE_STATE_INVALID;
786e71b7053SJung-uk Kim iv = s->write_iv;
787e71b7053SJung-uk Kim ciph_ctx = s->enc_write_ctx;
788e71b7053SJung-uk Kim RECORD_LAYER_reset_write_sequence(&s->rlayer);
789e71b7053SJung-uk Kim } else {
790e71b7053SJung-uk Kim iv = s->read_iv;
791e71b7053SJung-uk Kim ciph_ctx = s->enc_read_ctx;
792e71b7053SJung-uk Kim RECORD_LAYER_reset_read_sequence(&s->rlayer);
793e71b7053SJung-uk Kim }
794e71b7053SJung-uk Kim
795b077aed3SPierre Pronchery if (!derive_secret_key_and_iv(s, sending, md,
796b077aed3SPierre Pronchery s->s3.tmp.new_sym_enc, insecret, NULL,
797e71b7053SJung-uk Kim application_traffic,
798aa906e2aSJohn Baldwin sizeof(application_traffic) - 1, secret, key,
799aa906e2aSJohn Baldwin iv, ciph_ctx)) {
800e71b7053SJung-uk Kim /* SSLfatal() already called */
801e71b7053SJung-uk Kim goto err;
802e71b7053SJung-uk Kim }
803e71b7053SJung-uk Kim
804e71b7053SJung-uk Kim memcpy(insecret, secret, hashlen);
805e71b7053SJung-uk Kim
806b077aed3SPierre Pronchery /* Call Key log on successful traffic secret update */
807b077aed3SPierre Pronchery log_label = s->server == sending ? SERVER_APPLICATION_N_LABEL : CLIENT_APPLICATION_N_LABEL;
808b077aed3SPierre Pronchery if (!ssl_log_secret(s, log_label, secret, hashlen)) {
809b077aed3SPierre Pronchery /* SSLfatal() already called */
810b077aed3SPierre Pronchery goto err;
811b077aed3SPierre Pronchery }
812b077aed3SPierre Pronchery
813e71b7053SJung-uk Kim s->statem.enc_write_state = ENC_WRITE_STATE_VALID;
814e71b7053SJung-uk Kim ret = 1;
815e71b7053SJung-uk Kim err:
816aa906e2aSJohn Baldwin OPENSSL_cleanse(key, sizeof(key));
817e71b7053SJung-uk Kim OPENSSL_cleanse(secret, sizeof(secret));
818e71b7053SJung-uk Kim return ret;
819e71b7053SJung-uk Kim }
820e71b7053SJung-uk Kim
tls13_alert_code(int code)821e71b7053SJung-uk Kim int tls13_alert_code(int code)
822e71b7053SJung-uk Kim {
823e71b7053SJung-uk Kim /* There are 2 additional alerts in TLSv1.3 compared to TLSv1.2 */
824e71b7053SJung-uk Kim if (code == SSL_AD_MISSING_EXTENSION || code == SSL_AD_CERTIFICATE_REQUIRED)
825e71b7053SJung-uk Kim return code;
826e71b7053SJung-uk Kim
827e71b7053SJung-uk Kim return tls1_alert_code(code);
828e71b7053SJung-uk Kim }
829e71b7053SJung-uk Kim
tls13_export_keying_material(SSL * s,unsigned char * out,size_t olen,const char * label,size_t llen,const unsigned char * context,size_t contextlen,int use_context)830e71b7053SJung-uk Kim int tls13_export_keying_material(SSL *s, unsigned char *out, size_t olen,
831e71b7053SJung-uk Kim const char *label, size_t llen,
832e71b7053SJung-uk Kim const unsigned char *context,
833e71b7053SJung-uk Kim size_t contextlen, int use_context)
834e71b7053SJung-uk Kim {
835e71b7053SJung-uk Kim unsigned char exportsecret[EVP_MAX_MD_SIZE];
836da327cd2SJung-uk Kim #ifdef CHARSET_EBCDIC
837da327cd2SJung-uk Kim static const unsigned char exporterlabel[] = {0x65, 0x78, 0x70, 0x6F, 0x72, 0x74, 0x65, 0x72, 0x00};
838da327cd2SJung-uk Kim #else
839e71b7053SJung-uk Kim static const unsigned char exporterlabel[] = "exporter";
840da327cd2SJung-uk Kim #endif
841e71b7053SJung-uk Kim unsigned char hash[EVP_MAX_MD_SIZE], data[EVP_MAX_MD_SIZE];
842e71b7053SJung-uk Kim const EVP_MD *md = ssl_handshake_md(s);
843e71b7053SJung-uk Kim EVP_MD_CTX *ctx = EVP_MD_CTX_new();
844e71b7053SJung-uk Kim unsigned int hashsize, datalen;
845e71b7053SJung-uk Kim int ret = 0;
846e71b7053SJung-uk Kim
847b077aed3SPierre Pronchery if (ctx == NULL || md == NULL || !ossl_statem_export_allowed(s))
848e71b7053SJung-uk Kim goto err;
849e71b7053SJung-uk Kim
850e71b7053SJung-uk Kim if (!use_context)
851e71b7053SJung-uk Kim contextlen = 0;
852e71b7053SJung-uk Kim
853e71b7053SJung-uk Kim if (EVP_DigestInit_ex(ctx, md, NULL) <= 0
854e71b7053SJung-uk Kim || EVP_DigestUpdate(ctx, context, contextlen) <= 0
855e71b7053SJung-uk Kim || EVP_DigestFinal_ex(ctx, hash, &hashsize) <= 0
856e71b7053SJung-uk Kim || EVP_DigestInit_ex(ctx, md, NULL) <= 0
857e71b7053SJung-uk Kim || EVP_DigestFinal_ex(ctx, data, &datalen) <= 0
858e71b7053SJung-uk Kim || !tls13_hkdf_expand(s, md, s->exporter_master_secret,
859e71b7053SJung-uk Kim (const unsigned char *)label, llen,
8606935a639SJung-uk Kim data, datalen, exportsecret, hashsize, 0)
861e71b7053SJung-uk Kim || !tls13_hkdf_expand(s, md, exportsecret, exporterlabel,
862e71b7053SJung-uk Kim sizeof(exporterlabel) - 1, hash, hashsize,
8636935a639SJung-uk Kim out, olen, 0))
864e71b7053SJung-uk Kim goto err;
865e71b7053SJung-uk Kim
866e71b7053SJung-uk Kim ret = 1;
867e71b7053SJung-uk Kim err:
868e71b7053SJung-uk Kim EVP_MD_CTX_free(ctx);
869e71b7053SJung-uk Kim return ret;
870e71b7053SJung-uk Kim }
871e71b7053SJung-uk Kim
tls13_export_keying_material_early(SSL * s,unsigned char * out,size_t olen,const char * label,size_t llen,const unsigned char * context,size_t contextlen)872e71b7053SJung-uk Kim int tls13_export_keying_material_early(SSL *s, unsigned char *out, size_t olen,
873e71b7053SJung-uk Kim const char *label, size_t llen,
874e71b7053SJung-uk Kim const unsigned char *context,
875e71b7053SJung-uk Kim size_t contextlen)
876e71b7053SJung-uk Kim {
877da327cd2SJung-uk Kim #ifdef CHARSET_EBCDIC
878da327cd2SJung-uk Kim static const unsigned char exporterlabel[] = {0x65, 0x78, 0x70, 0x6F, 0x72, 0x74, 0x65, 0x72, 0x00};
879da327cd2SJung-uk Kim #else
880e71b7053SJung-uk Kim static const unsigned char exporterlabel[] = "exporter";
881da327cd2SJung-uk Kim #endif
882e71b7053SJung-uk Kim unsigned char exportsecret[EVP_MAX_MD_SIZE];
883e71b7053SJung-uk Kim unsigned char hash[EVP_MAX_MD_SIZE], data[EVP_MAX_MD_SIZE];
884e71b7053SJung-uk Kim const EVP_MD *md;
885e71b7053SJung-uk Kim EVP_MD_CTX *ctx = EVP_MD_CTX_new();
886e71b7053SJung-uk Kim unsigned int hashsize, datalen;
887e71b7053SJung-uk Kim int ret = 0;
888e71b7053SJung-uk Kim const SSL_CIPHER *sslcipher;
889e71b7053SJung-uk Kim
890e71b7053SJung-uk Kim if (ctx == NULL || !ossl_statem_export_early_allowed(s))
891e71b7053SJung-uk Kim goto err;
892e71b7053SJung-uk Kim
893e71b7053SJung-uk Kim if (!s->server && s->max_early_data > 0
894e71b7053SJung-uk Kim && s->session->ext.max_early_data == 0)
895e71b7053SJung-uk Kim sslcipher = SSL_SESSION_get0_cipher(s->psksession);
896e71b7053SJung-uk Kim else
897e71b7053SJung-uk Kim sslcipher = SSL_SESSION_get0_cipher(s->session);
898e71b7053SJung-uk Kim
899b077aed3SPierre Pronchery md = ssl_md(s->ctx, sslcipher->algorithm2);
900e71b7053SJung-uk Kim
901e71b7053SJung-uk Kim /*
902e71b7053SJung-uk Kim * Calculate the hash value and store it in |data|. The reason why
903e71b7053SJung-uk Kim * the empty string is used is that the definition of TLS-Exporter
904e71b7053SJung-uk Kim * is like so:
905e71b7053SJung-uk Kim *
906e71b7053SJung-uk Kim * TLS-Exporter(label, context_value, key_length) =
907e71b7053SJung-uk Kim * HKDF-Expand-Label(Derive-Secret(Secret, label, ""),
908e71b7053SJung-uk Kim * "exporter", Hash(context_value), key_length)
909e71b7053SJung-uk Kim *
910e71b7053SJung-uk Kim * Derive-Secret(Secret, Label, Messages) =
911e71b7053SJung-uk Kim * HKDF-Expand-Label(Secret, Label,
912e71b7053SJung-uk Kim * Transcript-Hash(Messages), Hash.length)
913e71b7053SJung-uk Kim *
914e71b7053SJung-uk Kim * Here Transcript-Hash is the cipher suite hash algorithm.
915e71b7053SJung-uk Kim */
916b077aed3SPierre Pronchery if (md == NULL
917b077aed3SPierre Pronchery || EVP_DigestInit_ex(ctx, md, NULL) <= 0
918e71b7053SJung-uk Kim || EVP_DigestUpdate(ctx, context, contextlen) <= 0
919e71b7053SJung-uk Kim || EVP_DigestFinal_ex(ctx, hash, &hashsize) <= 0
920e71b7053SJung-uk Kim || EVP_DigestInit_ex(ctx, md, NULL) <= 0
921e71b7053SJung-uk Kim || EVP_DigestFinal_ex(ctx, data, &datalen) <= 0
922e71b7053SJung-uk Kim || !tls13_hkdf_expand(s, md, s->early_exporter_master_secret,
923e71b7053SJung-uk Kim (const unsigned char *)label, llen,
9246935a639SJung-uk Kim data, datalen, exportsecret, hashsize, 0)
925e71b7053SJung-uk Kim || !tls13_hkdf_expand(s, md, exportsecret, exporterlabel,
926e71b7053SJung-uk Kim sizeof(exporterlabel) - 1, hash, hashsize,
9276935a639SJung-uk Kim out, olen, 0))
928e71b7053SJung-uk Kim goto err;
929e71b7053SJung-uk Kim
930e71b7053SJung-uk Kim ret = 1;
931e71b7053SJung-uk Kim err:
932e71b7053SJung-uk Kim EVP_MD_CTX_free(ctx);
933e71b7053SJung-uk Kim return ret;
934e71b7053SJung-uk Kim }
935