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