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-2026 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.6.6
29  **/
30 
31 //Switch to the appropriate trace level
32 #define TRACE_LEVEL TLS_TRACE_LEVEL
33 
34 //Dependencies
35 #include "tls/tls.h"
36 #include "tls/tls_key_material.h"
38 #include "tls/tls_misc.h"
40 #include "tls13/tls13_ticket.h"
41 #include "quic/tls_quic_misc.h"
42 #include "kdf/hkdf.h"
43 #include "kdf/tls_kdf.h"
44 #include "debug.h"
45 
46 //Check TLS library configuration
47 #if (TLS_SUPPORT == ENABLED && TLS_MAX_VERSION >= TLS_VERSION_1_3)
48 
49 
50 /**
51  * @brief HKDF-Expand-Label function
52  * @param[in] transportProtocol Transport protocol (TLS or DTLS)
53  * @param[in] hash Hash function used by HKDF
54  * @param[in] secret Pointer to the secret
55  * @param[in] secretLen Length of the secret
56  * @param[in] label Identifying label (NULL-terminated string)
57  * @param[in] context Pointer to the upper-layer context
58  * @param[in] contextLen Length of the upper-layer context
59  * @param[out] output Pointer to the output
60  * @param[in] outputLen Desired output length
61  * @return Error code
62  **/
63 
65  const HashAlgo *hash, const uint8_t *secret, size_t secretLen,
66  const char_t *label, const uint8_t *context, size_t contextLen,
67  uint8_t *output, size_t outputLen)
68 {
69  const char_t *prefix;
70 
71 #if (DTLS_SUPPORT == ENABLED)
72  //DTLS protocol?
73  if(transportProtocol == TLS_TRANSPORT_PROTOCOL_DATAGRAM)
74  {
75  //For DTLS 1.3, the label prefix shall be "dtls13". This ensures key
76  //separation between DTLS 1.3 and TLS 1.3. Note that there is no trailing
77  //space (refer to RFC 9147, section 5.9)
78  prefix = "dtls13";
79  }
80  else
81 #endif
82  //TLS protocol?
83  {
84  //For TLS 1.3, the label prefix shall be "tls13 " (refer to RFC 8446,
85  //section 7.1)
86  prefix = "tls13 ";
87  }
88 
89  //Compute HKDF-Expand-Label(Secret, Label, Context, Length)
90  return hkdfExpandLabel(hash, secret, secretLen, prefix, label, context,
91  contextLen, output, outputLen);
92 }
93 
94 
95 /**
96  * @brief Derive-Secret function
97  * @param[in] context Pointer to the TLS context
98  * @param[in] secret Pointer to the secret
99  * @param[in] secretLen Length of the secret
100  * @param[in] label Identifying label (NULL-terminated string)
101  * @param[in] message Concatenation of the indicated handshake messages
102  * @param[in] messageLen Length of the indicated handshake messages
103  * @param[out] output Pointer to the output
104  * @param[in] outputLen Desired output length
105  * @return Error code
106  **/
107 
108 error_t tls13DeriveSecret(TlsContext *context, const uint8_t *secret,
109  size_t secretLen, const char_t *label, const char_t *message,
110  size_t messageLen, uint8_t *output, size_t outputLen)
111 {
112  error_t error;
113  const HashAlgo *hash;
114  uint8_t digest[TLS_MAX_HKDF_DIGEST_SIZE];
115 
116  //The hash function used by HKDF is the cipher suite hash algorithm
117  hash = context->cipherSuite.prfHashAlgo;
118 
119  //Make sure the hash algorithm is valid
120  if(hash != NULL)
121  {
122  //Any handshake messages specified?
123  if(message != NULL)
124  {
125  //Compute Transcript-Hash(Messages);
126  error = hash->compute(message, messageLen, digest);
127  }
128  else
129  {
130  //Implementations can implement the transcript by keeping a running
131  //transcript hash value based on the negotiated hash
132  error = tlsFinalizeTranscriptHash(context, hash,
133  context->transcriptHashContext, digest);
134  }
135 
136  //Debug message
137  TRACE_DEBUG("Transcript hash (%" PRIuSIZE " bytes):\r\n", hash->digestSize);
138  TRACE_DEBUG_ARRAY(" ", digest, hash->digestSize);
139 
140  //Check status code
141  if(!error)
142  {
143  //Compute HKDF-Expand-Label(Secret, Label, Transcript-Hash, Hash.length)
144  error = tls13HkdfExpandLabel(context->transportProtocol, hash, secret,
145  secretLen, label, digest, hash->digestSize, output, outputLen);
146  }
147  }
148  else
149  {
150  //Invalid HKDF hash algorithm
151  error = ERROR_FAILURE;
152  }
153 
154  //Return status code
155  return error;
156 }
157 
158 
159 /**
160  * @brief Compute early traffic keys
161  * @param[in] context Pointer to the TLS context
162  * @return Error code
163  **/
164 
166 {
167  error_t error;
168  size_t ikmLen;
169  const uint8_t *ikm;
170  const HashAlgo *hash;
171 
172  //The hash function used by HKDF is the cipher suite hash algorithm
173  hash = context->cipherSuite.prfHashAlgo;
174  //Make sure the hash algorithm is valid
175  if(hash == NULL)
176  return ERROR_FAILURE;
177 
178  //Although PSKs can be established out of band, PSKs can also be established
179  //in a previous connection
180  if(tls13IsPskValid(context))
181  {
182  //IKM is a pre-shared key established externally
183  ikm = context->psk;
184  ikmLen = context->pskLen;
185  }
186  else if(tls13IsTicketValid(context))
187  {
188  //IKM is a pre-shared key derived from the resumption master secret from
189  //a previous connection
190  ikm = context->ticketPsk;
191  ikmLen = context->ticketPskLen;
192  }
193  else
194  {
195  //The pre-shared key is not valid
196  return ERROR_FAILURE;
197  }
198 
199  //Calculate early secret
200  error = hkdfExtract(hash, ikm, ikmLen, NULL, 0, context->secret);
201  //Any error to report?
202  if(error)
203  return error;
204 
205  //Debug message
206  TRACE_DEBUG("Early secret:\r\n");
207  TRACE_DEBUG_ARRAY(" ", context->secret, hash->digestSize);
208 
209  //Calculate client early traffic secret
210  error = tls13DeriveSecret(context, context->secret, hash->digestSize,
211  "c e traffic", NULL, 0, context->clientEarlyTrafficSecret,
212  hash->digestSize);
213  //Any error to report?
214  if(error)
215  return error;
216 
217  //Debug message
218  TRACE_DEBUG("Client early secret:\r\n");
219  TRACE_DEBUG_ARRAY(" ", context->clientEarlyTrafficSecret, hash->digestSize);
220 
221  //The traffic keying material is generated from the traffic secret value
222  if(context->entity == TLS_CONNECTION_END_CLIENT)
223  {
224  //Calculate client early traffic keys
225  error = tlsUpdateEncryptionEngine(context, context->encryptionEngine,
227  context->clientEarlyTrafficSecret);
228  }
229  else
230  {
231  //The implementation must verify that its receive buffer is empty
232  if(context->rxBufferLen == 0)
233  {
234  //Calculate client early traffic keys
235  error = tlsUpdateEncryptionEngine(context, context->decryptionEngine,
237  context->clientEarlyTrafficSecret);
238  }
239  else
240  {
241  //The receive buffer is not empty
242  error = ERROR_UNEXPECTED_MESSAGE;
243  }
244  }
245 
246  //Failed to generate traffic keying material?
247  if(error)
248  return error;
249 
250  //Calculate early exporter master secret
251  error = tls13DeriveSecret(context, context->secret, hash->digestSize,
252  "e exp master", NULL, 0, context->exporterMasterSecret, hash->digestSize);
253  //Any error to report?
254  if(error)
255  return error;
256 
257  //Debug message
258  TRACE_DEBUG("Early exporter master secret:\r\n");
259  TRACE_DEBUG_ARRAY(" ", context->exporterMasterSecret, hash->digestSize);
260 
261 #if (TLS_QUIC_SUPPORT == ENABLED)
262  //After providing a QUIC client with the first handshake bytes, the TLS stack
263  //might signal the change to 0-RTT keys (refer to RFC 9001, section 4.1.4)
265  context->clientEarlyTrafficSecret, NULL, hash->digestSize);
266  //Any error to report?
267  if(error)
268  return error;
269 #endif
270 
271 #if (TLS_KEY_LOG_SUPPORT == ENABLED)
272  //Log client early traffic secret
273  tlsDumpSecret(context, "CLIENT_EARLY_TRAFFIC_SECRET",
274  context->clientEarlyTrafficSecret, hash->digestSize);
275 
276  //Log early exporter master secret
277  tlsDumpSecret(context, "EARLY_EXPORTER_SECRET",
278  context->exporterMasterSecret, hash->digestSize);
279 #endif
280 
281  //When a PSK is used and early data is allowed for that PSK, the client can
282  //send application data in its first flight of messages
284 
285  //Successful processing
286  return NO_ERROR;
287 }
288 
289 
290 /**
291  * @brief Compute handshake traffic keys
292  * @param[in] context Pointer to the TLS context
293  * @return Error code
294  **/
295 
297 {
298  error_t error;
299  size_t ikmLen;
300  const uint8_t *ikm;
301  const HashAlgo *hash;
302 
303  //The hash function used by HKDF is the cipher suite hash algorithm
304  hash = context->cipherSuite.prfHashAlgo;
305  //Make sure the hash algorithm is valid
306  if(hash == NULL)
307  return ERROR_FAILURE;
308 
309 #if (TLS13_DHE_KE_SUPPORT == ENABLED || TLS13_ECDHE_KE_SUPPORT == ENABLED || \
310  TLS13_MLKEM_KE_SUPPORT == ENABLED || TLS13_HYBRID_KE_SUPPORT == ENABLED)
311  //(EC)DHE key exchange method?
312  if(context->keyExchMethod == TLS13_KEY_EXCH_DHE ||
313  context->keyExchMethod == TLS13_KEY_EXCH_ECDHE ||
314  context->keyExchMethod == TLS13_KEY_EXCH_MLKEM ||
315  context->keyExchMethod == TLS13_KEY_EXCH_HYBRID)
316  {
317  //If PSK is not in use, IKM is a string of Hash-lengths bytes set to 0
318  osMemset(context->secret, 0, hash->digestSize);
319 
320  //Point to the IKM argument
321  ikm = context->secret;
322  ikmLen = hash->digestSize;
323  }
324  else
325 #endif
326 #if (TLS13_PSK_KE_SUPPORT == ENABLED || TLS13_PSK_DHE_KE_SUPPORT == ENABLED || \
327  TLS13_PSK_ECDHE_KE_SUPPORT == ENABLED || TLS13_PSK_MLKEM_KE_SUPPORT == ENABLED || \
328  TLS13_PSK_HYBRID_KE_SUPPORT == ENABLED)
329  //PSK-only or PSK with (EC)DHE key exchange method?
330  if(context->keyExchMethod == TLS13_KEY_EXCH_PSK ||
331  context->keyExchMethod == TLS13_KEY_EXCH_PSK_DHE ||
332  context->keyExchMethod == TLS13_KEY_EXCH_PSK_ECDHE ||
333  context->keyExchMethod == TLS13_KEY_EXCH_PSK_MLKEM ||
334  context->keyExchMethod == TLS13_KEY_EXCH_PSK_HYBRID)
335  {
336  //Although PSKs can be established out of band, PSKs can also be
337  //established in a previous connection
338  if(tls13IsPskValid(context))
339  {
340  //IKM is a pre-shared key established externally
341  ikm = context->psk;
342  ikmLen = context->pskLen;
343  }
344  else if(tls13IsTicketValid(context))
345  {
346  //IKM is a pre-shared key derived from the resumption master secret
347  //from a previous connection
348  ikm = context->ticketPsk;
349  ikmLen = context->ticketPskLen;
350  }
351  else
352  {
353  //The pre-shared key is not valid
354  return ERROR_FAILURE;
355  }
356  }
357  else
358 #endif
359  //Invalid key exchange method?
360  {
361  //Report an error
362  return ERROR_FAILURE;
363  }
364 
365  //Calculate early secret
366  error = hkdfExtract(hash, ikm, ikmLen, NULL, 0, context->secret);
367  //Any error to report?
368  if(error)
369  return error;
370 
371  //Debug message
372  TRACE_DEBUG("Early secret:\r\n");
373  TRACE_DEBUG_ARRAY(" ", context->secret, hash->digestSize);
374 
375  //Derive early secret
376  error = tls13DeriveSecret(context, context->secret, hash->digestSize,
377  "derived", "", 0, context->secret, hash->digestSize);
378  //Any error to report?
379  if(error)
380  return error;
381 
382  //Debug message
383  TRACE_DEBUG("Derived secret:\r\n");
384  TRACE_DEBUG_ARRAY(" ", context->secret, hash->digestSize);
385 
386  //PSK-only key exchange method?
387  if(context->keyExchMethod == TLS13_KEY_EXCH_PSK)
388  {
389  //If the (EC)DHE shared secret is not available, then the 0-value
390  //consisting of a string of Hash.length bytes set to zeros is used
391  osMemset(context->premasterSecret, 0, hash->digestSize);
392  context->premasterSecretLen = hash->digestSize;
393  }
394 
395  //Calculate handshake secret
396  error = hkdfExtract(hash, context->premasterSecret,
397  context->premasterSecretLen, context->secret, hash->digestSize,
398  context->secret);
399  //Any error to report?
400  if(error)
401  return error;
402 
403  //Debug message
404  TRACE_DEBUG("Handshake secret:\r\n");
405  TRACE_DEBUG_ARRAY(" ", context->secret, hash->digestSize);
406 
407  //Calculate client handshake traffic secret
408  error = tls13DeriveSecret(context, context->secret, hash->digestSize,
409  "c hs traffic", NULL, 0, context->clientHsTrafficSecret,
410  hash->digestSize);
411  //Any error to report?
412  if(error)
413  return error;
414 
415  //Debug message
416  TRACE_DEBUG("Client handshake secret:\r\n");
417  TRACE_DEBUG_ARRAY(" ", context->clientHsTrafficSecret, hash->digestSize);
418 
419  //Calculate server handshake traffic secret
420  error = tls13DeriveSecret(context, context->secret, hash->digestSize,
421  "s hs traffic", NULL, 0, context->serverHsTrafficSecret,
422  hash->digestSize);
423  //Any error to report?
424  if(error)
425  return error;
426 
427  //Debug message
428  TRACE_DEBUG("Server handshake secret:\r\n");
429  TRACE_DEBUG_ARRAY(" ", context->serverHsTrafficSecret, hash->digestSize);
430 
431  //The implementation must verify that its receive buffer is empty before
432  //switching to encrypted handshake
433  if(context->rxBufferLen != 0)
434  return ERROR_HANDSHAKE_FAILED;
435 
436  //The traffic keying material is generated from the traffic secret value
437  if(context->entity == TLS_CONNECTION_END_CLIENT)
438  {
439  //Calculate client handshake traffic keys
440  error = tlsUpdateEncryptionEngine(context, context->encryptionEngine,
442  context->clientHsTrafficSecret);
443 
444  //Check status code
445  if(!error)
446  {
447  //Calculate server handshake traffic keys
448  error = tlsUpdateEncryptionEngine(context, context->decryptionEngine,
450  context->serverHsTrafficSecret);
451  }
452  }
453  else
454  {
455  //Calculate client handshake traffic keys
456  error = tlsUpdateEncryptionEngine(context, context->decryptionEngine,
458  context->clientHsTrafficSecret);
459 
460  //Check status code
461  if(!error)
462  {
463  //Calculate server handshake traffic keys
464  error = tlsUpdateEncryptionEngine(context, context->encryptionEngine,
466  context->serverHsTrafficSecret);
467  }
468  }
469 
470  //Failed to generate traffic keying material?
471  if(error)
472  return error;
473 
474 #if (TLS_QUIC_SUPPORT == ENABLED)
475  //As keys at a given encryption level become available to TLS, TLS indicates
476  //to QUIC that reading or writing keys at that encryption level are available
477  //(refer to RFC 9001, section 4.1.4)
479  context->clientHsTrafficSecret, context->serverHsTrafficSecret,
480  hash->digestSize);
481  //Any error to report?
482  if(error)
483  return error;
484 #endif
485 
486 #if (TLS_KEY_LOG_SUPPORT == ENABLED)
487  //Log client handshake traffic secret
488  tlsDumpSecret(context, "CLIENT_HANDSHAKE_TRAFFIC_SECRET",
489  context->clientHsTrafficSecret, hash->digestSize);
490 
491  //Log server handshake traffic secret
492  tlsDumpSecret(context, "SERVER_HANDSHAKE_TRAFFIC_SECRET",
493  context->serverHsTrafficSecret, hash->digestSize);
494 #endif
495 
496  //In all handshakes, the server must send the EncryptedExtensions message
497  //immediately after the ServerHello message
499 
500  //Successful processing
501  return NO_ERROR;
502 }
503 
504 
505 /**
506  * @brief Compute server application traffic keys
507  * @param[in] context Pointer to the TLS context
508  * @return Error code
509  **/
510 
512 {
513  error_t error;
514  const HashAlgo *hash;
515  uint8_t ikm[TLS_MAX_HKDF_DIGEST_SIZE];
516 
517  //The hash function used by HKDF is the cipher suite hash algorithm
518  hash = context->cipherSuite.prfHashAlgo;
519  //Make sure the hash algorithm is valid
520  if(hash == NULL)
521  return ERROR_FAILURE;
522 
523  //Derive handshake secret
524  error = tls13DeriveSecret(context, context->secret, hash->digestSize,
525  "derived", "", 0, context->secret, hash->digestSize);
526  //Any error to report?
527  if(error)
528  return error;
529 
530  //Debug message
531  TRACE_DEBUG("Derived secret:\r\n");
532  TRACE_DEBUG_ARRAY(" ", context->secret, hash->digestSize);
533 
534  //IKM is a string of Hash-lengths bytes set to 0
535  osMemset(ikm, 0, hash->digestSize);
536 
537  //Calculate master secret
538  error = hkdfExtract(hash, ikm, hash->digestSize, context->secret,
539  hash->digestSize, context->secret);
540  //Any error to report?
541  if(error)
542  return error;
543 
544  //Debug message
545  TRACE_DEBUG("Master secret:\r\n");
546  TRACE_DEBUG_ARRAY(" ", context->secret, hash->digestSize);
547 
548  //Calculate client application traffic secret
549  error = tls13DeriveSecret(context, context->secret, hash->digestSize,
550  "c ap traffic", NULL, 0, context->clientAppTrafficSecret,
551  hash->digestSize);
552  //Any error to report?
553  if(error)
554  return error;
555 
556  //Debug message
557  TRACE_DEBUG("Client application secret:\r\n");
558  TRACE_DEBUG_ARRAY(" ", context->clientAppTrafficSecret, hash->digestSize);
559 
560  //Calculate server application traffic secret
561  error = tls13DeriveSecret(context, context->secret, hash->digestSize,
562  "s ap traffic", NULL, 0, context->serverAppTrafficSecret,
563  hash->digestSize);
564  //Any error to report?
565  if(error)
566  return error;
567 
568  //Debug message
569  TRACE_DEBUG("Server application secret:\r\n");
570  TRACE_DEBUG_ARRAY(" ", context->serverAppTrafficSecret, hash->digestSize);
571 
572  //All the traffic keying material is recomputed when changing from the
573  //handshake to application data keys
574  if(context->entity == TLS_CONNECTION_END_CLIENT)
575  {
576  //The implementation must verify that its receive buffer is empty before
577  //rekeying
578  if(context->rxBufferLen == 0)
579  {
580  //Inform the record layer that subsequent records will be protected
581  //under the new traffic keys
582  error = tlsUpdateEncryptionEngine(context, context->decryptionEngine,
584  context->serverAppTrafficSecret);
585  }
586  else
587  {
588  //The receive buffer is not empty
589  error = ERROR_UNEXPECTED_MESSAGE;
590  }
591  }
592  else
593  {
594  //Inform the record layer that subsequent records will be protected
595  //under the new traffic keys
596  error = tlsUpdateEncryptionEngine(context, context->encryptionEngine,
598  context->serverAppTrafficSecret);
599  }
600 
601  //Failed to generate traffic keying material?
602  if(error)
603  return error;
604 
605  //Calculate exporter master secret
606  error = tls13DeriveSecret(context, context->secret, hash->digestSize,
607  "exp master", NULL, 0, context->exporterMasterSecret, hash->digestSize);
608  //Any error to report?
609  if(error)
610  return error;
611 
612  //Debug message
613  TRACE_DEBUG("Exporter master secret:\r\n");
614  TRACE_DEBUG_ARRAY(" ", context->exporterMasterSecret, hash->digestSize);
615 
616 #if (TLS_QUIC_SUPPORT == ENABLED)
617  //As keys at a given encryption level become available to TLS, TLS indicates
618  //to QUIC that reading or writing keys at that encryption level are available
619  //(refer to RFC 9001, section 4.1.4)
621  context->clientAppTrafficSecret, context->serverAppTrafficSecret,
622  hash->digestSize);
623  //Any error to report?
624  if(error)
625  return error;
626 #endif
627 
628 #if (TLS_KEY_LOG_SUPPORT == ENABLED)
629  //Log client application traffic secret
630  tlsDumpSecret(context, "CLIENT_TRAFFIC_SECRET_0",
631  context->clientAppTrafficSecret, hash->digestSize);
632 
633  //Log server application traffic secret
634  tlsDumpSecret(context, "SERVER_TRAFFIC_SECRET_0",
635  context->serverAppTrafficSecret, hash->digestSize);
636 
637  //Log exporter master secret
638  tlsDumpSecret(context, "EXPORTER_SECRET",
639  context->exporterMasterSecret, hash->digestSize);
640 #endif
641 
642  //Check whether TLS operates as a client or a server
643  if(context->entity == TLS_CONNECTION_END_CLIENT)
644  {
645  //In DTLS 1.3, the EndOfEarlyData message is omitted both from the wire
646  //and the handshake transcript. Because DTLS records have epochs,
647  //EndOfEarlyData is not necessary to determine when the early data is
648  //complete (refer to RFC 9147, section 5.6)
649  if(context->transportProtocol == TLS_TRANSPORT_PROTOCOL_STREAM &&
650  context->earlyDataEnabled && context->earlyDataExtReceived)
651  {
652  //If the server sent an EarlyData extension, the client must send an
653  //EndOfEarlyData message after receiving the server Finished
655  }
656  else
657  {
658  //PSK key exchange method?
659  if(context->keyExchMethod == TLS13_KEY_EXCH_PSK ||
660  context->keyExchMethod == TLS13_KEY_EXCH_PSK_DHE ||
661  context->keyExchMethod == TLS13_KEY_EXCH_PSK_ECDHE ||
662  context->keyExchMethod == TLS13_KEY_EXCH_PSK_HYBRID)
663  {
664  //Send a Finished message to the server
666  }
667  else
668  {
669  //Send a Certificate message if the server requests it
671  }
672  }
673  }
674  else
675  {
676  //PSK key exchange method?
677  if(context->keyExchMethod == TLS13_KEY_EXCH_PSK ||
678  context->keyExchMethod == TLS13_KEY_EXCH_PSK_DHE ||
679  context->keyExchMethod == TLS13_KEY_EXCH_PSK_ECDHE ||
680  context->keyExchMethod == TLS13_KEY_EXCH_PSK_HYBRID)
681  {
682  //Wait for a Finished message from the client
684  }
685  else
686  {
687  //The client must send a Certificate message if the server requests it
688  if(context->clientAuthMode != TLS_CLIENT_AUTH_NONE)
689  {
691  }
692  else
693  {
695  }
696  }
697  }
698 
699  //Successful processing
700  return NO_ERROR;
701 }
702 
703 
704 /**
705  * @brief Compute client application traffic keys
706  * @param[in] context Pointer to the TLS context
707  * @return Error code
708  **/
709 
711 {
712  error_t error;
713  const HashAlgo *hash;
714 
715  //The hash function used by HKDF is the cipher suite hash algorithm
716  hash = context->cipherSuite.prfHashAlgo;
717  //Make sure the hash algorithm is valid
718  if(hash == NULL)
719  return ERROR_FAILURE;
720 
721  //At this point, the handshake is complete, and the client and server
722  //derive the keying material required by the record layer to exchange
723  //application-layer data protected through authenticated encryption
724  if(context->entity == TLS_CONNECTION_END_CLIENT)
725  {
726  //Inform the record layer that subsequent records will be protected
727  //under the new traffic keys
728  error = tlsUpdateEncryptionEngine(context, context->encryptionEngine,
730  context->clientAppTrafficSecret);
731  }
732  else
733  {
734  //The implementation must verify that its receive buffer is empty before
735  //rekeying
736  if(context->rxBufferLen == 0)
737  {
738  //Inform the record layer that subsequent records will be protected
739  //under the new traffic keys
740  error = tlsUpdateEncryptionEngine(context, context->decryptionEngine,
742  context->clientAppTrafficSecret);
743  }
744  else
745  {
746  //The receive buffer is not empty
747  error = ERROR_UNEXPECTED_MESSAGE;
748  }
749  }
750 
751  //Failed to generate traffic keying material?
752  if(error)
753  return error;
754 
755  //Calculate resumption master secret
756  error = tls13DeriveSecret(context, context->secret, hash->digestSize,
757  "res master", NULL, 0, context->resumptionMasterSecret, hash->digestSize);
758  //Any error to report?
759  if(error)
760  return error;
761 
762  //Debug message
763  TRACE_DEBUG("Resumption master secret:\r\n");
764  TRACE_DEBUG_ARRAY(" ", context->resumptionMasterSecret, hash->digestSize);
765 
766  //Once all the values which are to be derived from a given secret have been
767  //computed, that secret should be erased
768  osMemset(context->secret, 0, TLS13_MAX_HKDF_DIGEST_SIZE);
769  osMemset(context->clientEarlyTrafficSecret, 0, TLS13_MAX_HKDF_DIGEST_SIZE);
770  osMemset(context->clientHsTrafficSecret, 0, TLS13_MAX_HKDF_DIGEST_SIZE);
771  osMemset(context->serverHsTrafficSecret, 0, TLS13_MAX_HKDF_DIGEST_SIZE);
772 
773  //DTLS protocol?
774  if(context->transportProtocol == TLS_TRANSPORT_PROTOCOL_DATAGRAM)
775  {
776  //When a handshake flight is sent without any expected response, as is
777  //the case with the client's final flight, the flight must be
778  //acknowledged with an ACK message (refer to RFC 9147, section 5.7)
779  if(context->entity == TLS_CONNECTION_END_CLIENT)
780  {
782  }
783  else
784  {
786  }
787  }
788  else
789  {
790 #if (TLS_TICKET_SUPPORT == ENABLED)
791  //Check whether session ticket mechanism is enabled at server side
792  if(context->entity == TLS_CONNECTION_END_SERVER &&
793  context->ticketEncryptCallback != NULL &&
794  context->pskKeModeSupported)
795  {
796  //At any time after the server has received the client Finished
797  //message, it may send a NewSessionTicket message
799  }
800  else
801 #endif
802  {
803  //The client and server can now exchange application-layer data
805  }
806  }
807 
808  //Successful processing
809  return NO_ERROR;
810 }
811 
812 #endif
@ TLS13_KEY_EXCH_PSK
Definition: tls.h:1247
error_t tls13GenerateEarlyTrafficKeys(TlsContext *context)
Compute early traffic keys.
TLS helper functions.
error_t tlsUpdateEncryptionEngine(TlsContext *context, TlsEncryptionEngine *encryptionEngine, TlsConnectionEnd entity, TlsEncryptionLevel level, const uint8_t *secret)
Update encryption engine.
Definition: tls_misc.c:1051
#define TLS13_MAX_HKDF_DIGEST_SIZE
Definition: tls13_misc.h:148
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:1245
error_t tls13GenerateHandshakeTrafficKeys(TlsContext *context)
Compute handshake traffic keys.
@ TLS13_KEY_EXCH_PSK_DHE
Definition: tls.h:1248
Key material generation.
@ ERROR_UNEXPECTED_MESSAGE
Definition: error.h:195
QUIC helper functions.
uint8_t message[]
Definition: chap.h:154
size_t digestSize
Definition: crypto.h:1249
TLS 1.3 session tickets.
@ TLS_TRANSPORT_PROTOCOL_DATAGRAM
Definition: tls.h:1039
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:1250
@ TLS_STATE_APPLICATION_DATA
Definition: tls.h:1615
@ ERROR_HANDSHAKE_FAILED
Definition: error.h:234
@ TLS13_KEY_EXCH_ECDHE
Definition: tls.h:1244
error_t tlsFinalizeTranscriptHash(TlsContext *context, const HashAlgo *hash, const void *hashContext, uint8_t *output)
Finalize hash calculation from previous handshake messages.
Ipv6Addr prefix
@ TLS_ENCRYPTION_LEVEL_EARLY_DATA
Definition: tls.h:1632
error_t tls13GenerateClientAppTrafficKeys(TlsContext *context)
Compute client application traffic keys.
@ TLS_ENCRYPTION_LEVEL_HANDSHAKE
Definition: tls.h:1633
@ TLS13_KEY_EXCH_PSK_HYBRID
Definition: tls.h:1251
TLS key derivation functions.
#define TlsContext
Definition: tls.h:36
error_t
Error codes.
Definition: error.h:43
HashAlgoCompute compute
Definition: crypto.h:1252
@ TLS_CONNECTION_END_SERVER
Definition: tls.h:1052
@ ERROR_FAILURE
Generic error code.
Definition: error.h:45
@ TLS13_KEY_EXCH_DHE
Definition: tls.h:1243
@ TLS_STATE_EARLY_DATA
Definition: tls.h:1587
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.
@ TLS_STATE_END_OF_EARLY_DATA
Definition: tls.h:1612
@ TLS_CLIENT_AUTH_NONE
Definition: tls.h:1062
@ TLS_STATE_NEW_SESSION_TICKET_2
Definition: tls.h:1608
Transcript hash calculation.
uint8_t secret[TLS_MASTER_SECRET_SIZE]
Master secret.
Definition: tls.h:2053
#define TRACE_DEBUG(...)
Definition: debug.h:119
char char_t
Definition: compiler_port.h:55
error_t hkdfExpandLabel(const HashAlgo *hashAlgo, const uint8_t *secret, size_t secretLen, const char_t *prefix, const char_t *label, const uint8_t *context, size_t contextLen, uint8_t *output, size_t outputLen)
HKDF-Expand-Label function (TLS 1.3)
Definition: tls_kdf.c:270
@ TLS13_KEY_EXCH_PSK_ECDHE
Definition: tls.h:1249
@ TLS_ENCRYPTION_LEVEL_APPLICATION
Definition: tls.h:1634
#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:911
error_t hkdfExtract(const HashAlgo *hashAlgo, const uint8_t *ikm, size_t ikmLen, const uint8_t *salt, size_t saltLen, uint8_t *prk)
HKDF extract step.
Definition: hkdf.c:97
TlsTransportProtocol
TLS transport protocols.
Definition: tls.h:1037
HKDF (HMAC-based Key Derivation Function)
@ TLS_STATE_CLIENT_CERTIFICATE
Definition: tls.h:1600
@ TLS13_KEY_EXCH_HYBRID
Definition: tls.h:1246
@ TLS_STATE_ENCRYPTED_EXTENSIONS
Definition: tls.h:1594
@ TLS_STATE_CLIENT_FINISHED_ACK
Definition: tls.h:1616
#define TLS_MAX_HKDF_DIGEST_SIZE
Definition: tls.h:987
@ TLS_CONNECTION_END_CLIENT
Definition: tls.h:1051
TLS (Transport Layer Security)
@ TLS_STATE_FINAL_ACK
Definition: tls.h:1614
@ TLS_TRANSPORT_PROTOCOL_STREAM
Definition: tls.h:1038
TLS 1.3 key schedule.
Common interface for hash algorithms.
Definition: crypto.h:1243
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:141
@ TLS_STATE_CLIENT_FINISHED
Definition: tls.h:1605
@ NO_ERROR
Success.
Definition: error.h:44
Debugging facilities.