tls13_key_material.c
Go to the documentation of this file.
1 /**
2  * @file tls13_key_material.c
3  * @brief TLS 1.3 key schedule
4  *
5  * @section License
6  *
7  * SPDX-License-Identifier: GPL-2.0-or-later
8  *
9  * Copyright (C) 2010-2025 Oryx Embedded SARL. All rights reserved.
10  *
11  * This file is part of CycloneSSL Open.
12  *
13  * This program is free software; you can redistribute it and/or
14  * modify it under the terms of the GNU General Public License
15  * as published by the Free Software Foundation; either version 2
16  * of the License, or (at your option) any later version.
17  *
18  * This program is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License
24  * along with this program; if not, write to the Free Software Foundation,
25  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
26  *
27  * @author Oryx Embedded SARL (www.oryx-embedded.com)
28  * @version 2.5.4
29  **/
30 
31 //Switch to the appropriate trace level
32 #define TRACE_LEVEL TLS_TRACE_LEVEL
33 
34 //Dependencies
35 #include "tls.h"
36 #include "tls_key_material.h"
37 #include "tls_transcript_hash.h"
38 #include "tls_quic_misc.h"
39 #include "tls_misc.h"
40 #include "tls13_key_material.h"
41 #include "tls13_ticket.h"
42 #include "kdf/hkdf.h"
43 #include "debug.h"
44 
45 //Check TLS library configuration
46 #if (TLS_SUPPORT == ENABLED && TLS_MAX_VERSION >= TLS_VERSION_1_3)
47 
48 
49 /**
50  * @brief HKDF-Expand-Label function
51  * @param[in] transportProtocol Transport protocol (TLS or DTLS)
52  * @param[in] hash Hash function used by HKDF
53  * @param[in] secret Pointer to the secret
54  * @param[in] secretLen Length of the secret
55  * @param[in] label Identifying label (NULL-terminated string)
56  * @param[in] context Pointer to the upper-layer context
57  * @param[in] contextLen Length of the upper-layer context
58  * @param[out] output Pointer to the output
59  * @param[in] outputLen Desired output length
60  * @return Error code
61  **/
62 
64  const HashAlgo *hash, const uint8_t *secret, size_t secretLen,
65  const char_t *label, const uint8_t *context, size_t contextLen,
66  uint8_t *output, size_t outputLen)
67 {
68  error_t error;
69  size_t n;
70  size_t labelLen;
71  uint8_t *hkdfLabel;
72  const char_t *prefix;
73 
74  //Check parameters
75  if(label == NULL)
77  if(context == NULL && contextLen != 0)
79 
80  //Retrieve the length of the label
81  labelLen = osStrlen(label);
82 
83  //Check parameters
84  if(labelLen > (255 - 6) || contextLen > 255)
85  return ERROR_INVALID_LENGTH;
86 
87  //Compute the length of the HkdfLabel structure
88  n = labelLen + contextLen + 10;
89  //Allocate a memory buffer to hold the HkdfLabel structure
90  hkdfLabel = tlsAllocMem(n);
91 
92  //Successful memory allocation?
93  if(hkdfLabel != NULL)
94  {
95 #if (DTLS_SUPPORT == ENABLED)
96  //DTLS protocol?
97  if(transportProtocol == TLS_TRANSPORT_PROTOCOL_DATAGRAM)
98  {
99  //For DTLS 1.3, the label prefix shall be "dtls13". This ensures key
100  //separation between DTLS 1.3 and TLS 1.3. Note that there is no
101  //trailing space (refer to RFC 9147, section 5.9)
102  prefix = "dtls13";
103  }
104  else
105 #endif
106  //TLS protocol?
107  {
108  //For TLS 1.3, the label prefix shall be "tls13 " (refer to RFC 8446,
109  //section 7.1)
110  prefix = "tls13 ";
111  }
112 
113  //Format the HkdfLabel structure
114  hkdfLabel[0] = MSB(outputLen);
115  hkdfLabel[1] = LSB(outputLen);
116  hkdfLabel[2] = (uint8_t) (labelLen + 6);
117  osMemcpy(hkdfLabel + 3, prefix, 6);
118  osMemcpy(hkdfLabel + 9, label, labelLen);
119  hkdfLabel[labelLen + 9] = (uint8_t) contextLen;
120  osMemcpy(hkdfLabel + labelLen + 10, context, contextLen);
121 
122  //Debug message
123  TRACE_DEBUG("HkdfLabel (%" PRIuSIZE " bytes):\r\n", n);
124  TRACE_DEBUG_ARRAY(" ", hkdfLabel, n);
125 
126  //Compute HKDF-Expand(Secret, HkdfLabel, Length)
127  error = hkdfExpand(hash, secret, secretLen, hkdfLabel, n, output,
128  outputLen);
129 
130  //Release previously allocated memory
131  tlsFreeMem(hkdfLabel);
132  }
133  else
134  {
135  //Failed to allocate memory
136  error = ERROR_OUT_OF_MEMORY;
137  }
138 
139  //Return status code
140  return error;
141 }
142 
143 
144 /**
145  * @brief Derive-Secret function
146  * @param[in] context Pointer to the TLS context
147  * @param[in] secret Pointer to the secret
148  * @param[in] secretLen Length of the secret
149  * @param[in] label Identifying label (NULL-terminated string)
150  * @param[in] message Concatenation of the indicated handshake messages
151  * @param[in] messageLen Length of the indicated handshake messages
152  * @param[out] output Pointer to the output
153  * @param[in] outputLen Desired output length
154  * @return Error code
155  **/
156 
157 error_t tls13DeriveSecret(TlsContext *context, const uint8_t *secret,
158  size_t secretLen, const char_t *label, const char_t *message,
159  size_t messageLen, uint8_t *output, size_t outputLen)
160 {
161  error_t error;
162  const HashAlgo *hash;
163  uint8_t digest[TLS_MAX_HKDF_DIGEST_SIZE];
164 
165  //The hash function used by HKDF is the cipher suite hash algorithm
166  hash = context->cipherSuite.prfHashAlgo;
167 
168  //Make sure the hash algorithm is valid
169  if(hash != NULL)
170  {
171  //Any handshake messages specified?
172  if(message != NULL)
173  {
174  //Compute Transcript-Hash(Messages);
175  error = hash->compute(message, messageLen, digest);
176  }
177  else
178  {
179  //Implementations can implement the transcript by keeping a running
180  //transcript hash value based on the negotiated hash
181  error = tlsFinalizeTranscriptHash(context, hash,
182  context->transcriptHashContext, "", digest);
183  }
184 
185  //Debug message
186  TRACE_DEBUG("Transcript hash (%" PRIuSIZE " bytes):\r\n", hash->digestSize);
187  TRACE_DEBUG_ARRAY(" ", digest, hash->digestSize);
188 
189  //Check status code
190  if(!error)
191  {
192  //Compute HKDF-Expand-Label(Secret, Label, Transcript-Hash, Hash.length)
193  error = tls13HkdfExpandLabel(context->transportProtocol, hash, secret,
194  secretLen, label, digest, hash->digestSize, output, outputLen);
195  }
196  }
197  else
198  {
199  //Invalid HKDF hash algorithm
200  error = ERROR_FAILURE;
201  }
202 
203  //Return status code
204  return error;
205 }
206 
207 
208 /**
209  * @brief Compute early traffic keys
210  * @param[in] context Pointer to the TLS context
211  * @return Error code
212  **/
213 
215 {
216  error_t error;
217  size_t ikmLen;
218  const uint8_t *ikm;
219  const HashAlgo *hash;
220 
221  //The hash function used by HKDF is the cipher suite hash algorithm
222  hash = context->cipherSuite.prfHashAlgo;
223  //Make sure the hash algorithm is valid
224  if(hash == NULL)
225  return ERROR_FAILURE;
226 
227  //Although PSKs can be established out of band, PSKs can also be established
228  //in a previous connection
229  if(tls13IsPskValid(context))
230  {
231  //IKM is a pre-shared key established externally
232  ikm = context->psk;
233  ikmLen = context->pskLen;
234  }
235  else if(tls13IsTicketValid(context))
236  {
237  //IKM is a pre-shared key derived from the resumption master secret from
238  //a previous connection
239  ikm = context->ticketPsk;
240  ikmLen = context->ticketPskLen;
241  }
242  else
243  {
244  //The pre-shared key is not valid
245  return ERROR_FAILURE;
246  }
247 
248  //Calculate early secret
249  error = hkdfExtract(hash, ikm, ikmLen, NULL, 0, context->secret);
250  //Any error to report?
251  if(error)
252  return error;
253 
254  //Debug message
255  TRACE_DEBUG("Early secret:\r\n");
256  TRACE_DEBUG_ARRAY(" ", context->secret, hash->digestSize);
257 
258  //Calculate client early traffic secret
259  error = tls13DeriveSecret(context, context->secret, hash->digestSize,
260  "c e traffic", NULL, 0, context->clientEarlyTrafficSecret,
261  hash->digestSize);
262  //Any error to report?
263  if(error)
264  return error;
265 
266  //Debug message
267  TRACE_DEBUG("Client early secret:\r\n");
268  TRACE_DEBUG_ARRAY(" ", context->clientEarlyTrafficSecret, hash->digestSize);
269 
270  //The traffic keying material is generated from the traffic secret value
271  if(context->entity == TLS_CONNECTION_END_CLIENT)
272  {
273  //Calculate client early traffic keys
274  error = tlsInitEncryptionEngine(context, &context->encryptionEngine,
276  context->clientEarlyTrafficSecret);
277  }
278  else
279  {
280  //The implementation must verify that its receive buffer is empty
281  if(context->rxBufferLen == 0)
282  {
283  //Calculate client early traffic keys
284  error = tlsInitEncryptionEngine(context, &context->decryptionEngine,
286  context->clientEarlyTrafficSecret);
287  }
288  else
289  {
290  //The receive buffer is not empty
291  error = ERROR_UNEXPECTED_MESSAGE;
292  }
293  }
294 
295  //Failed to generate traffic keying material?
296  if(error)
297  return error;
298 
299  //Calculate early exporter master secret
300  error = tls13DeriveSecret(context, context->secret, hash->digestSize,
301  "e exp master", NULL, 0, context->exporterMasterSecret, hash->digestSize);
302  //Any error to report?
303  if(error)
304  return error;
305 
306  //Debug message
307  TRACE_DEBUG("Early exporter master secret:\r\n");
308  TRACE_DEBUG_ARRAY(" ", context->exporterMasterSecret, hash->digestSize);
309 
310 #if (TLS_QUIC_SUPPORT == ENABLED)
311  //After providing a QUIC client with the first handshake bytes, the TLS stack
312  //might signal the change to 0-RTT keys (refer to RFC 9001, section 4.1.4)
314  context->clientEarlyTrafficSecret, NULL, hash->digestSize);
315  //Any error to report?
316  if(error)
317  return error;
318 #endif
319 
320 #if (TLS_KEY_LOG_SUPPORT == ENABLED)
321  //Log client early traffic secret
322  tlsDumpSecret(context, "CLIENT_EARLY_TRAFFIC_SECRET",
323  context->clientEarlyTrafficSecret, hash->digestSize);
324 
325  //Log early exporter master secret
326  tlsDumpSecret(context, "EARLY_EXPORTER_SECRET",
327  context->exporterMasterSecret, hash->digestSize);
328 #endif
329 
330  //When a PSK is used and early data is allowed for that PSK, the client can
331  //send application data in its first flight of messages
333 
334  //Successful processing
335  return NO_ERROR;
336 }
337 
338 
339 /**
340  * @brief Compute handshake traffic keys
341  * @param[in] context Pointer to the TLS context
342  * @return Error code
343  **/
344 
346 {
347  error_t error;
348  size_t ikmLen;
349  const uint8_t *ikm;
350  const HashAlgo *hash;
351 
352  //The hash function used by HKDF is the cipher suite hash algorithm
353  hash = context->cipherSuite.prfHashAlgo;
354  //Make sure the hash algorithm is valid
355  if(hash == NULL)
356  return ERROR_FAILURE;
357 
358 #if (TLS13_DHE_KE_SUPPORT == ENABLED || TLS13_ECDHE_KE_SUPPORT == ENABLED || \
359  TLS13_MLKEM_KE_SUPPORT == ENABLED || TLS13_HYBRID_KE_SUPPORT == ENABLED)
360  //(EC)DHE key exchange method?
361  if(context->keyExchMethod == TLS13_KEY_EXCH_DHE ||
362  context->keyExchMethod == TLS13_KEY_EXCH_ECDHE ||
363  context->keyExchMethod == TLS13_KEY_EXCH_MLKEM ||
364  context->keyExchMethod == TLS13_KEY_EXCH_HYBRID)
365  {
366  //If PSK is not in use, IKM is a string of Hash-lengths bytes set to 0
367  osMemset(context->secret, 0, hash->digestSize);
368 
369  //Point to the IKM argument
370  ikm = context->secret;
371  ikmLen = hash->digestSize;
372  }
373  else
374 #endif
375 #if (TLS13_PSK_KE_SUPPORT == ENABLED || TLS13_PSK_DHE_KE_SUPPORT == ENABLED || \
376  TLS13_PSK_ECDHE_KE_SUPPORT == ENABLED || TLS13_PSK_MLKEM_KE_SUPPORT == ENABLED || \
377  TLS13_PSK_HYBRID_KE_SUPPORT == ENABLED)
378  //PSK-only or PSK with (EC)DHE key exchange method?
379  if(context->keyExchMethod == TLS13_KEY_EXCH_PSK ||
380  context->keyExchMethod == TLS13_KEY_EXCH_PSK_DHE ||
381  context->keyExchMethod == TLS13_KEY_EXCH_PSK_ECDHE ||
382  context->keyExchMethod == TLS13_KEY_EXCH_PSK_MLKEM ||
383  context->keyExchMethod == TLS13_KEY_EXCH_PSK_HYBRID)
384  {
385  //Although PSKs can be established out of band, PSKs can also be
386  //established in a previous connection
387  if(tls13IsPskValid(context))
388  {
389  //IKM is a pre-shared key established externally
390  ikm = context->psk;
391  ikmLen = context->pskLen;
392  }
393  else if(tls13IsTicketValid(context))
394  {
395  //IKM is a pre-shared key derived from the resumption master secret
396  //from a previous connection
397  ikm = context->ticketPsk;
398  ikmLen = context->ticketPskLen;
399  }
400  else
401  {
402  //The pre-shared key is not valid
403  return ERROR_FAILURE;
404  }
405  }
406  else
407 #endif
408  //Invalid key exchange method?
409  {
410  //Report an error
411  return ERROR_FAILURE;
412  }
413 
414  //Calculate early secret
415  error = hkdfExtract(hash, ikm, ikmLen, NULL, 0, context->secret);
416  //Any error to report?
417  if(error)
418  return error;
419 
420  //Debug message
421  TRACE_DEBUG("Early secret:\r\n");
422  TRACE_DEBUG_ARRAY(" ", context->secret, hash->digestSize);
423 
424  //Derive early secret
425  error = tls13DeriveSecret(context, context->secret, hash->digestSize,
426  "derived", "", 0, context->secret, hash->digestSize);
427  //Any error to report?
428  if(error)
429  return error;
430 
431  //Debug message
432  TRACE_DEBUG("Derived secret:\r\n");
433  TRACE_DEBUG_ARRAY(" ", context->secret, hash->digestSize);
434 
435  //PSK-only key exchange method?
436  if(context->keyExchMethod == TLS13_KEY_EXCH_PSK)
437  {
438  //If the (EC)DHE shared secret is not available, then the 0-value
439  //consisting of a string of Hash.length bytes set to zeros is used
440  osMemset(context->premasterSecret, 0, hash->digestSize);
441  context->premasterSecretLen = hash->digestSize;
442  }
443 
444  //Calculate handshake secret
445  error = hkdfExtract(hash, context->premasterSecret,
446  context->premasterSecretLen, context->secret, hash->digestSize,
447  context->secret);
448  //Any error to report?
449  if(error)
450  return error;
451 
452  //Debug message
453  TRACE_DEBUG("Handshake secret:\r\n");
454  TRACE_DEBUG_ARRAY(" ", context->secret, hash->digestSize);
455 
456  //Calculate client handshake traffic secret
457  error = tls13DeriveSecret(context, context->secret, hash->digestSize,
458  "c hs traffic", NULL, 0, context->clientHsTrafficSecret,
459  hash->digestSize);
460  //Any error to report?
461  if(error)
462  return error;
463 
464  //Debug message
465  TRACE_DEBUG("Client handshake secret:\r\n");
466  TRACE_DEBUG_ARRAY(" ", context->clientHsTrafficSecret, hash->digestSize);
467 
468  //Calculate server handshake traffic secret
469  error = tls13DeriveSecret(context, context->secret, hash->digestSize,
470  "s hs traffic", NULL, 0, context->serverHsTrafficSecret,
471  hash->digestSize);
472  //Any error to report?
473  if(error)
474  return error;
475 
476  //Debug message
477  TRACE_DEBUG("Server handshake secret:\r\n");
478  TRACE_DEBUG_ARRAY(" ", context->serverHsTrafficSecret, hash->digestSize);
479 
480  //The implementation must verify that its receive buffer is empty before
481  //switching to encrypted handshake
482  if(context->rxBufferLen != 0)
483  return ERROR_HANDSHAKE_FAILED;
484 
485  //The traffic keying material is generated from the traffic secret value
486  if(context->entity == TLS_CONNECTION_END_CLIENT)
487  {
488  //Release encryption engine
489  tlsFreeEncryptionEngine(&context->encryptionEngine);
490 
491  //Calculate client handshake traffic keys
492  error = tlsInitEncryptionEngine(context, &context->encryptionEngine,
494  context->clientHsTrafficSecret);
495 
496  //Check status code
497  if(!error)
498  {
499  //Calculate server handshake traffic keys
500  error = tlsInitEncryptionEngine(context, &context->decryptionEngine,
502  context->serverHsTrafficSecret);
503  }
504  }
505  else
506  {
507  //Release decryption engine
508  tlsFreeEncryptionEngine(&context->decryptionEngine);
509 
510  //Calculate client handshake traffic keys
511  error = tlsInitEncryptionEngine(context, &context->decryptionEngine,
513  context->clientHsTrafficSecret);
514 
515  //Check status code
516  if(!error)
517  {
518  //Calculate server handshake traffic keys
519  error = tlsInitEncryptionEngine(context, &context->encryptionEngine,
521  context->serverHsTrafficSecret);
522  }
523  }
524 
525  //Failed to generate traffic keying material?
526  if(error)
527  return error;
528 
529 #if (TLS_QUIC_SUPPORT == ENABLED)
530  //As keys at a given encryption level become available to TLS, TLS indicates
531  //to QUIC that reading or writing keys at that encryption level are available
532  //(refer to RFC 9001, section 4.1.4)
534  context->clientHsTrafficSecret, context->serverHsTrafficSecret,
535  hash->digestSize);
536  //Any error to report?
537  if(error)
538  return error;
539 #endif
540 
541 #if (TLS_KEY_LOG_SUPPORT == ENABLED)
542  //Log client handshake traffic secret
543  tlsDumpSecret(context, "CLIENT_HANDSHAKE_TRAFFIC_SECRET",
544  context->clientHsTrafficSecret, hash->digestSize);
545 
546  //Log server handshake traffic secret
547  tlsDumpSecret(context, "SERVER_HANDSHAKE_TRAFFIC_SECRET",
548  context->serverHsTrafficSecret, hash->digestSize);
549 #endif
550 
551 #if (DTLS_SUPPORT == ENABLED)
552  //DTLS protocol?
553  if(context->transportProtocol == TLS_TRANSPORT_PROTOCOL_DATAGRAM)
554  {
555  //Because each epoch resets the sequence number space, a separate sliding
556  //window is needed for each epoch (refer to RFC 9147, section 4.5.1)
557  dtlsInitReplayWindow(context);
558  }
559 #endif
560 
561  //In all handshakes, the server must send the EncryptedExtensions message
562  //immediately after the ServerHello message
564 
565  //Successful processing
566  return NO_ERROR;
567 }
568 
569 
570 /**
571  * @brief Compute server application traffic keys
572  * @param[in] context Pointer to the TLS context
573  * @return Error code
574  **/
575 
577 {
578  error_t error;
579  const HashAlgo *hash;
580  uint8_t ikm[TLS_MAX_HKDF_DIGEST_SIZE];
581 
582  //The hash function used by HKDF is the cipher suite hash algorithm
583  hash = context->cipherSuite.prfHashAlgo;
584  //Make sure the hash algorithm is valid
585  if(hash == NULL)
586  return ERROR_FAILURE;
587 
588  //Derive handshake secret
589  error = tls13DeriveSecret(context, context->secret, hash->digestSize,
590  "derived", "", 0, context->secret, hash->digestSize);
591  //Any error to report?
592  if(error)
593  return error;
594 
595  //Debug message
596  TRACE_DEBUG("Derived secret:\r\n");
597  TRACE_DEBUG_ARRAY(" ", context->secret, hash->digestSize);
598 
599  //IKM is a string of Hash-lengths bytes set to 0
600  osMemset(ikm, 0, hash->digestSize);
601 
602  //Calculate master secret
603  error = hkdfExtract(hash, ikm, hash->digestSize, context->secret,
604  hash->digestSize, context->secret);
605  //Any error to report?
606  if(error)
607  return error;
608 
609  //Debug message
610  TRACE_DEBUG("Master secret:\r\n");
611  TRACE_DEBUG_ARRAY(" ", context->secret, hash->digestSize);
612 
613  //Calculate client application traffic secret
614  error = tls13DeriveSecret(context, context->secret, hash->digestSize,
615  "c ap traffic", NULL, 0, context->clientAppTrafficSecret,
616  hash->digestSize);
617  //Any error to report?
618  if(error)
619  return error;
620 
621  //Debug message
622  TRACE_DEBUG("Client application secret:\r\n");
623  TRACE_DEBUG_ARRAY(" ", context->clientAppTrafficSecret, hash->digestSize);
624 
625  //Calculate server application traffic secret
626  error = tls13DeriveSecret(context, context->secret, hash->digestSize,
627  "s ap traffic", NULL, 0, context->serverAppTrafficSecret,
628  hash->digestSize);
629  //Any error to report?
630  if(error)
631  return error;
632 
633  //Debug message
634  TRACE_DEBUG("Server application secret:\r\n");
635  TRACE_DEBUG_ARRAY(" ", context->serverAppTrafficSecret, hash->digestSize);
636 
637  //All the traffic keying material is recomputed when changing from the
638  //handshake to application data keys
639  if(context->entity == TLS_CONNECTION_END_CLIENT)
640  {
641  //The implementation must verify that its receive buffer is empty before
642  //rekeying
643  if(context->rxBufferLen == 0)
644  {
645  //Release decryption engine
646  tlsFreeEncryptionEngine(&context->decryptionEngine);
647 
648  //Inform the record layer that subsequent records will be protected
649  //under the new traffic keys
650  error = tlsInitEncryptionEngine(context, &context->decryptionEngine,
652  context->serverAppTrafficSecret);
653  }
654  else
655  {
656  //The receive buffer is not empty
657  error = ERROR_UNEXPECTED_MESSAGE;
658  }
659  }
660  else
661  {
662  //Release encryption engine
663  tlsFreeEncryptionEngine(&context->encryptionEngine);
664 
665  //Inform the record layer that subsequent records will be protected
666  //under the new traffic keys
667  error = tlsInitEncryptionEngine(context, &context->encryptionEngine,
669  context->serverAppTrafficSecret);
670  }
671 
672  //Failed to generate traffic keying material?
673  if(error)
674  return error;
675 
676  //Calculate exporter master secret
677  error = tls13DeriveSecret(context, context->secret, hash->digestSize,
678  "exp master", NULL, 0, context->exporterMasterSecret, hash->digestSize);
679  //Any error to report?
680  if(error)
681  return error;
682 
683  //Debug message
684  TRACE_DEBUG("Exporter master secret:\r\n");
685  TRACE_DEBUG_ARRAY(" ", context->exporterMasterSecret, hash->digestSize);
686 
687 #if (TLS_QUIC_SUPPORT == ENABLED)
688  //As keys at a given encryption level become available to TLS, TLS indicates
689  //to QUIC that reading or writing keys at that encryption level are available
690  //(refer to RFC 9001, section 4.1.4)
692  context->clientAppTrafficSecret, context->serverAppTrafficSecret,
693  hash->digestSize);
694  //Any error to report?
695  if(error)
696  return error;
697 #endif
698 
699 #if (TLS_KEY_LOG_SUPPORT == ENABLED)
700  //Log client application traffic secret
701  tlsDumpSecret(context, "CLIENT_TRAFFIC_SECRET_0",
702  context->clientAppTrafficSecret, hash->digestSize);
703 
704  //Log server application traffic secret
705  tlsDumpSecret(context, "SERVER_TRAFFIC_SECRET_0",
706  context->serverAppTrafficSecret, hash->digestSize);
707 
708  //Log exporter master secret
709  tlsDumpSecret(context, "EXPORTER_SECRET",
710  context->exporterMasterSecret, hash->digestSize);
711 #endif
712 
713 #if (DTLS_SUPPORT == ENABLED)
714  //DTLS protocol?
715  if(context->transportProtocol == TLS_TRANSPORT_PROTOCOL_DATAGRAM &&
716  context->entity == TLS_CONNECTION_END_CLIENT)
717  {
718  //Because each epoch resets the sequence number space, a separate sliding
719  //window is needed for each epoch (refer to RFC 9147, section 4.5.1)
720  dtlsInitReplayWindow(context);
721  }
722 #endif
723 
724  //Check whether TLS operates as a client or a server
725  if(context->entity == TLS_CONNECTION_END_CLIENT)
726  {
727  //In DTLS 1.3, the EndOfEarlyData message is omitted both from the wire
728  //and the handshake transcript. Because DTLS records have epochs,
729  //EndOfEarlyData is not necessary to determine when the early data is
730  //complete (refer to RFC 9147, section 5.6)
731  if(context->transportProtocol == TLS_TRANSPORT_PROTOCOL_STREAM &&
732  context->earlyDataEnabled && context->earlyDataExtReceived)
733  {
734  //If the server sent an EarlyData extension, the client must send an
735  //EndOfEarlyData message after receiving the server Finished
737  }
738  else
739  {
740  //PSK key exchange method?
741  if(context->keyExchMethod == TLS13_KEY_EXCH_PSK ||
742  context->keyExchMethod == TLS13_KEY_EXCH_PSK_DHE ||
743  context->keyExchMethod == TLS13_KEY_EXCH_PSK_ECDHE ||
744  context->keyExchMethod == TLS13_KEY_EXCH_PSK_HYBRID)
745  {
746  //Send a Finished message to the server
748  }
749  else
750  {
751  //Send a Certificate message if the server requests it
753  }
754  }
755  }
756  else
757  {
758  //PSK key exchange method?
759  if(context->keyExchMethod == TLS13_KEY_EXCH_PSK ||
760  context->keyExchMethod == TLS13_KEY_EXCH_PSK_DHE ||
761  context->keyExchMethod == TLS13_KEY_EXCH_PSK_ECDHE ||
762  context->keyExchMethod == TLS13_KEY_EXCH_PSK_HYBRID)
763  {
764  //Wait for a Finished message from the client
766  }
767  else
768  {
769  //The client must send a Certificate message if the server requests it
770  if(context->clientAuthMode != TLS_CLIENT_AUTH_NONE)
771  {
773  }
774  else
775  {
777  }
778  }
779  }
780 
781  //Successful processing
782  return NO_ERROR;
783 }
784 
785 
786 /**
787  * @brief Compute client application traffic keys
788  * @param[in] context Pointer to the TLS context
789  * @return Error code
790  **/
791 
793 {
794  error_t error;
795  const HashAlgo *hash;
796 
797  //The hash function used by HKDF is the cipher suite hash algorithm
798  hash = context->cipherSuite.prfHashAlgo;
799  //Make sure the hash algorithm is valid
800  if(hash == NULL)
801  return ERROR_FAILURE;
802 
803  //At this point, the handshake is complete, and the client and server
804  //derive the keying material required by the record layer to exchange
805  //application-layer data protected through authenticated encryption
806  if(context->entity == TLS_CONNECTION_END_CLIENT)
807  {
808  //Release encryption engine
809  tlsFreeEncryptionEngine(&context->encryptionEngine);
810 
811  //Inform the record layer that subsequent records will be protected
812  //under the new traffic keys
813  error = tlsInitEncryptionEngine(context, &context->encryptionEngine,
815  context->clientAppTrafficSecret);
816  }
817  else
818  {
819  //The implementation must verify that its receive buffer is empty before
820  //rekeying
821  if(context->rxBufferLen == 0)
822  {
823  //Release decryption engine
824  tlsFreeEncryptionEngine(&context->decryptionEngine);
825 
826  //Inform the record layer that subsequent records will be protected
827  //under the new traffic keys
828  error = tlsInitEncryptionEngine(context, &context->decryptionEngine,
830  context->clientAppTrafficSecret);
831  }
832  else
833  {
834  //The receive buffer is not empty
835  error = ERROR_UNEXPECTED_MESSAGE;
836  }
837  }
838 
839  //Failed to generate traffic keying material?
840  if(error)
841  return error;
842 
843  //Calculate resumption master secret
844  error = tls13DeriveSecret(context, context->secret, hash->digestSize,
845  "res master", NULL, 0, context->resumptionMasterSecret, hash->digestSize);
846  //Any error to report?
847  if(error)
848  return error;
849 
850  //Debug message
851  TRACE_DEBUG("Resumption master secret:\r\n");
852  TRACE_DEBUG_ARRAY(" ", context->resumptionMasterSecret, hash->digestSize);
853 
854  //Once all the values which are to be derived from a given secret have been
855  //computed, that secret should be erased
856  osMemset(context->secret, 0, TLS13_MAX_HKDF_DIGEST_SIZE);
857  osMemset(context->clientEarlyTrafficSecret, 0, TLS13_MAX_HKDF_DIGEST_SIZE);
858  osMemset(context->clientHsTrafficSecret, 0, TLS13_MAX_HKDF_DIGEST_SIZE);
859  osMemset(context->serverHsTrafficSecret, 0, TLS13_MAX_HKDF_DIGEST_SIZE);
860 
861 #if (DTLS_SUPPORT == ENABLED)
862  //DTLS protocol?
863  if(context->transportProtocol == TLS_TRANSPORT_PROTOCOL_DATAGRAM &&
864  context->entity == TLS_CONNECTION_END_SERVER)
865  {
866  //Because each epoch resets the sequence number space, a separate sliding
867  //window is needed for each epoch (refer to RFC 9147, section 4.5.1)
868  dtlsInitReplayWindow(context);
869  }
870 #endif
871 
872 #if (TLS_TICKET_SUPPORT == ENABLED)
873  //Check whether session ticket mechanism is enabled
874  if(context->entity == TLS_CONNECTION_END_SERVER &&
875  context->ticketEncryptCallback != NULL &&
876  context->pskKeModeSupported)
877  {
878  //At any time after the server has received the client Finished message,
879  //it may send a NewSessionTicket message
881  }
882  else
883 #endif
884  {
885  //At this point, the handshake is complete, and the client and server
886  //can exchange application-layer data
888  }
889 
890  //Successful processing
891  return NO_ERROR;
892 }
893 
894 #endif
@ TLS13_KEY_EXCH_PSK
Definition: tls.h:1207
#define tlsAllocMem(size)
Definition: tls.h:888
error_t tls13GenerateEarlyTrafficKeys(TlsContext *context)
Compute early traffic keys.
TLS helper functions.
#define TLS13_MAX_HKDF_DIGEST_SIZE
Definition: tls13_misc.h:148
void dtlsInitReplayWindow(TlsContext *context)
Initialize sliding window.
Definition: dtls_misc.c:452
error_t tls13DeriveSecret(TlsContext *context, const uint8_t *secret, size_t secretLen, const char_t *label, const char_t *message, size_t messageLen, uint8_t *output, size_t outputLen)
Derive-Secret function.
@ TLS13_KEY_EXCH_MLKEM
Definition: tls.h:1205
error_t tls13GenerateHandshakeTrafficKeys(TlsContext *context)
Compute handshake traffic keys.
@ TLS13_KEY_EXCH_PSK_DHE
Definition: tls.h:1208
Key material generation.
error_t tlsFinalizeTranscriptHash(TlsContext *context, const HashAlgo *hash, const void *hashContext, const char_t *label, uint8_t *output)
Finalize hash calculation from previous handshake messages.
@ ERROR_UNEXPECTED_MESSAGE
Definition: error.h:195
QUIC helper functions.
uint8_t message[]
Definition: chap.h:154
size_t digestSize
Definition: crypto.h:1130
TLS 1.3 session tickets.
@ TLS_TRANSPORT_PROTOCOL_DATAGRAM
Definition: tls.h:1000
void tlsDumpSecret(TlsContext *context, const char_t *label, const uint8_t *secret, size_t secretLen)
Dump secret key (for debugging purpose only)
@ TLS13_KEY_EXCH_PSK_MLKEM
Definition: tls.h:1210
@ TLS_STATE_APPLICATION_DATA
Definition: tls.h:1568
@ ERROR_HANDSHAKE_FAILED
Definition: error.h:234
@ ERROR_OUT_OF_MEMORY
Definition: error.h:63
@ TLS13_KEY_EXCH_ECDHE
Definition: tls.h:1204
#define osStrlen(s)
Definition: os_port.h:168
Ipv6Addr prefix
@ TLS_ENCRYPTION_LEVEL_EARLY_DATA
Definition: tls.h:1581
error_t tls13GenerateClientAppTrafficKeys(TlsContext *context)
Compute client application traffic keys.
@ TLS_ENCRYPTION_LEVEL_HANDSHAKE
Definition: tls.h:1582
@ TLS13_KEY_EXCH_PSK_HYBRID
Definition: tls.h:1211
@ ERROR_INVALID_PARAMETER
Invalid parameter.
Definition: error.h:47
#define osMemcpy(dest, src, length)
Definition: os_port.h:144
#define TlsContext
Definition: tls.h:36
error_t
Error codes.
Definition: error.h:43
HashAlgoCompute compute
Definition: crypto.h:1133
@ TLS_CONNECTION_END_SERVER
Definition: tls.h:1013
void tlsFreeEncryptionEngine(TlsEncryptionEngine *encryptionEngine)
Release encryption engine.
Definition: tls_misc.c:928
@ ERROR_FAILURE
Generic error code.
Definition: error.h:45
@ TLS13_KEY_EXCH_DHE
Definition: tls.h:1203
@ TLS_STATE_EARLY_DATA
Definition: tls.h:1541
@ ERROR_INVALID_LENGTH
Definition: error.h:111
error_t tlsSetQuicEncryptionKeys(TlsContext *context, TlsEncryptionLevel level, const uint8_t *clientKey, const uint8_t *serverKey, size_t keyLen)
Set encryption keys.
bool_t tls13IsTicketValid(TlsContext *context)
Check whether a session ticket is valid.
Definition: tls13_ticket.c:51
error_t tls13GenerateServerAppTrafficKeys(TlsContext *context)
Compute server application traffic keys.
#define MSB(x)
Definition: os_port.h:59
@ TLS_STATE_END_OF_EARLY_DATA
Definition: tls.h:1564
#define LSB(x)
Definition: os_port.h:55
error_t hkdfExpand(const HashAlgo *hash, const uint8_t *prk, size_t prkLen, const uint8_t *info, size_t infoLen, uint8_t *okm, size_t okmLen)
HKDF expand step.
Definition: hkdf.c:158
@ TLS_CLIENT_AUTH_NONE
Definition: tls.h:1023
@ TLS_STATE_NEW_SESSION_TICKET
Definition: tls.h:1566
Transcript hash calculation.
uint8_t secret[TLS_MASTER_SECRET_SIZE]
Master secret.
Definition: tls.h:2002
#define TRACE_DEBUG(...)
Definition: debug.h:119
char char_t
Definition: compiler_port.h:55
@ TLS13_KEY_EXCH_PSK_ECDHE
Definition: tls.h:1209
@ TLS_ENCRYPTION_LEVEL_APPLICATION
Definition: tls.h:1583
#define TRACE_DEBUG_ARRAY(p, a, n)
Definition: debug.h:120
bool_t tls13IsPskValid(TlsContext *context)
Check whether an externally established PSK is valid.
Definition: tls13_misc.c:915
uint8_t n
TlsTransportProtocol
TLS transport protocols.
Definition: tls.h:998
HKDF (HMAC-based Key Derivation Function)
@ TLS_STATE_CLIENT_CERTIFICATE
Definition: tls.h:1554
@ TLS13_KEY_EXCH_HYBRID
Definition: tls.h:1206
@ TLS_STATE_ENCRYPTED_EXTENSIONS
Definition: tls.h:1548
#define TLS_MAX_HKDF_DIGEST_SIZE
Definition: tls.h:964
@ TLS_CONNECTION_END_CLIENT
Definition: tls.h:1012
TLS (Transport Layer Security)
@ TLS_TRANSPORT_PROTOCOL_STREAM
Definition: tls.h:999
TLS 1.3 key schedule.
Common interface for hash algorithms.
Definition: crypto.h:1124
error_t hkdfExtract(const HashAlgo *hash, const uint8_t *ikm, size_t ikmLen, const uint8_t *salt, size_t saltLen, uint8_t *prk)
HKDF extract step.
Definition: hkdf.c:97
error_t tls13HkdfExpandLabel(TlsTransportProtocol transportProtocol, const HashAlgo *hash, const uint8_t *secret, size_t secretLen, const char_t *label, const uint8_t *context, size_t contextLen, uint8_t *output, size_t outputLen)
HKDF-Expand-Label function.
void tlsChangeState(TlsContext *context, TlsState newState)
Update TLS state.
Definition: tls_misc.c:54
#define PRIuSIZE
#define osMemset(p, value, length)
Definition: os_port.h:138
#define tlsFreeMem(p)
Definition: tls.h:893
@ TLS_STATE_CLIENT_FINISHED
Definition: tls.h:1559
@ NO_ERROR
Success.
Definition: error.h:44
Debugging facilities.
__weak_func error_t tlsInitEncryptionEngine(TlsContext *context, TlsEncryptionEngine *encryptionEngine, TlsConnectionEnd entity, TlsEncryptionLevel level, const uint8_t *secret)
Initialize encryption engine.
Definition: tls_misc.c:675