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