tls13_common.c
Go to the documentation of this file.
1 /**
2  * @file tls13_common.c
3  * @brief Handshake message processing (TLS 1.3 client and server)
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_handshake.h"
38 #include "tls_misc.h"
39 #include "tls13_common.h"
40 #include "tls13_key_material.h"
41 #include "debug.h"
42 
43 //Check TLS library configuration
44 #if (TLS_SUPPORT == ENABLED && TLS_MAX_VERSION >= TLS_VERSION_1_3)
45 
46 
47 /**
48  * @brief Send KeyUpdate message
49  *
50  * The KeyUpdate handshake message is used to indicate that the sender is
51  * updating its sending cryptographic keys. This message can be sent by either
52  * peer after it has sent a Finished message
53  *
54  * @param[in] context Pointer to the TLS context
55  * @return Error code
56  **/
57 
59 {
60  error_t error;
61  size_t length;
62  uint8_t *appTrafficSecret;
64  const HashAlgo *hash;
65 
66  //Initialize pointer
67  appTrafficSecret = NULL;
68 
69  //Point to the buffer where to format the message
70  message = (Tls13KeyUpdate *) (context->txBuffer + context->txBufferLen);
71 
72  //Format KeyUpdate message
73  error = tls13FormatKeyUpdate(context, message, &length);
74 
75  //Check status code
76  if(!error)
77  {
78  //Debug message
79  TRACE_INFO("Sending KeyUpdate message (%" PRIuSIZE " bytes)...\r\n", length);
81 
82  //Send handshake message
83  error = tlsSendHandshakeMessage(context, message, length,
85  }
86 
87  //Check status code
88  if(error == NO_ERROR || error == ERROR_WOULD_BLOCK || error == ERROR_TIMEOUT)
89  {
90  //The hash function used by HKDF is the cipher suite hash algorithm
91  hash = context->cipherSuite.prfHashAlgo;
92 
93  //Make sure the hash algorithm is valid
94  if(hash != NULL)
95  {
96  //Check whether TLS operates as a client or a server
97  if(context->entity == TLS_CONNECTION_END_CLIENT)
98  appTrafficSecret = context->clientAppTrafficSecret;
99  else
100  appTrafficSecret = context->serverAppTrafficSecret;
101 
102  //Compute the next generation of application traffic secret
103  error = tls13HkdfExpandLabel(hash, appTrafficSecret, hash->digestSize,
104  "traffic upd", NULL, 0, appTrafficSecret, hash->digestSize);
105  }
106  else
107  {
108  //The hash algorithm is not valid
109  error = ERROR_FAILURE;
110  }
111  }
112 
113  //Check status code
114  if(!error)
115  {
116  //Release encryption engine
117  tlsFreeEncryptionEngine(&context->encryptionEngine);
118 
119  //All the traffic keying material is recomputed whenever the underlying
120  //secret changes
121  error = tlsInitEncryptionEngine(context, &context->encryptionEngine,
122  context->entity, appTrafficSecret);
123  }
124 
125  //Check status code
126  if(!error)
127  {
128  //After sending a KeyUpdate message, the sender shall send all its
129  //traffic using the next generation of keys
130  context->state = TLS_STATE_APPLICATION_DATA;
131  }
132 
133  //Return status code
134  return error;
135 }
136 
137 
138 /**
139  * @brief Format KeyUpdate message
140  * @param[in] context Pointer to the TLS context
141  * @param[out] message Buffer where to format the KeyUpdate message
142  * @param[out] length Length of the resulting KeyUpdate message
143  * @return Error code
144  **/
145 
147  size_t *length)
148 {
149  //The request_update field indicates whether the recipient of the KeyUpdate
150  //should respond with its own KeyUpdate
151  message->requestUpdate = TLS_KEY_UPDATE_NOT_REQUESTED;
152 
153  //The KeyUpdate message consists of a single byte
154  *length = sizeof(Tls13KeyUpdate);
155 
156  //Successful processing
157  return NO_ERROR;
158 }
159 
160 
161 /**
162  * @brief Parse KeyUpdate message
163  *
164  * The KeyUpdate handshake message is used to indicate that the sender is
165  * updating its sending cryptographic keys. This message can be sent by either
166  * peer after it has sent a Finished message
167  *
168  * @param[in] context Pointer to the TLS context
169  * @param[in] message Incoming EncryptedExtensions message to parse
170  * @param[in] length Message length
171  * @return Error code
172  **/
173 
175  size_t length)
176 {
177  error_t error;
178  uint8_t *appTrafficSecret;
179  TlsConnectionEnd entity;
180  const HashAlgo *hash;
181 
182  //Debug message
183  TRACE_INFO("KeyUpdate message received (%" PRIuSIZE " bytes)...\r\n", length);
185 
186  //Check TLS version
187  if(context->version != TLS_VERSION_1_3)
189 
190  //Ensure the value of the request_update field is valid
191  if(message->requestUpdate != TLS_KEY_UPDATE_NOT_REQUESTED &&
192  message->requestUpdate != TLS_KEY_UPDATE_REQUESTED)
193  {
194  //If an implementation receives any other value, it must terminate the
195  //connection with an illegal_parameter alert
197  }
198 
199  //Check the length of the KeyUpdate message
200  if(length != sizeof(Tls13KeyUpdate))
201  return ERROR_DECODING_FAILED;
202 
203  //Implementations that receive a KeyUpdate prior to receiving a Finished
204  //message must terminate the connection with an unexpected_message alert
205  if(context->state != TLS_STATE_APPLICATION_DATA &&
206  context->state != TLS_STATE_CLOSING)
207  {
208  //Report an error
210  }
211 
212 #if (TLS_MAX_KEY_UPDATE_MESSAGES > 0)
213  //Increment the count of consecutive KeyUpdate messages
214  context->keyUpdateCount++;
215 
216  //Do not allow too many consecutive KeyUpdate message
217  if(context->keyUpdateCount > TLS_MAX_KEY_UPDATE_MESSAGES)
219 #endif
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  //Upon receiving a KeyUpdate, the receiver must update its receiving keys
228  if(context->entity == TLS_CONNECTION_END_CLIENT)
229  {
230  entity = TLS_CONNECTION_END_SERVER;
231  appTrafficSecret = context->serverAppTrafficSecret;
232  }
233  else
234  {
235  entity = TLS_CONNECTION_END_CLIENT;
236  appTrafficSecret = context->clientAppTrafficSecret;
237  }
238 
239  //Compute the next generation of application traffic secret
240  error = tls13HkdfExpandLabel(hash, appTrafficSecret, hash->digestSize,
241  "traffic upd", NULL, 0, appTrafficSecret, hash->digestSize);
242  //Any error to report?
243  if(error)
244  return error;
245 
246  //The implementation must verify that its receive buffer is empty before
247  //rekeying
248  if(context->rxBufferLen != 0)
250 
251  //Release decryption engine
252  tlsFreeEncryptionEngine(&context->decryptionEngine);
253 
254  //All the traffic keying material is recomputed whenever the underlying
255  //secret changes
256  error = tlsInitEncryptionEngine(context, &context->decryptionEngine,
257  entity, appTrafficSecret);
258  //Any error to report?
259  if(error)
260  return error;
261 
262  //Check the value of the request_update field
263  if(message->requestUpdate == TLS_KEY_UPDATE_REQUESTED &&
264  context->state == TLS_STATE_APPLICATION_DATA)
265  {
266 #if (TLS_MAX_KEY_UPDATE_MESSAGES > 0)
267  if(context->keyUpdateCount == 1)
268 #endif
269  {
270  //If the request_update field is set to update_requested then the
271  //receiver must send a KeyUpdate of its own with request_update set to
272  //update_not_requested prior to sending its next application data
273  context->state = TLS_STATE_KEY_UPDATE;
274  }
275  }
276 
277  //Successful processing
278  return NO_ERROR;
279 }
280 
281 #endif
TLS helper functions.
uint8_t length
Definition: dtls_misc.h:149
error_t tlsInitEncryptionEngine(TlsContext *context, TlsEncryptionEngine *encryptionEngine, TlsConnectionEnd entity, const uint8_t *secret)
Initialize encryption engine.
Definition: tls_misc.c:354
@ ERROR_WOULD_BLOCK
Definition: error.h:95
TLS handshake.
@ ERROR_ILLEGAL_PARAMETER
Definition: error.h:237
@ ERROR_UNEXPECTED_MESSAGE
Definition: error.h:192
TlsConnectionEnd
TLS connection end.
Definition: tls.h:859
__start_packed struct @103 Tls13KeyUpdate
KeyUpdate message.
Handshake message processing (TLS 1.3 client and server)
@ TLS_STATE_APPLICATION_DATA
Definition: tls.h:1319
error_t tlsSendHandshakeMessage(TlsContext *context, const void *data, size_t length, TlsMessageType type)
Send handshake message.
error_t tls13FormatKeyUpdate(TlsContext *context, Tls13KeyUpdate *message, size_t *length)
@ TLS_STATE_KEY_UPDATE
Definition: tls.h:1318
#define TlsContext
Definition: tls.h:36
error_t
Error codes.
Definition: error.h:42
@ TLS_CONNECTION_END_SERVER
Definition: tls.h:862
error_t tls13SendKeyUpdate(TlsContext *context)
void tlsFreeEncryptionEngine(TlsEncryptionEngine *encryptionEngine)
Release encryption engine.
Definition: tls_misc.c:592
@ ERROR_FAILURE
Generic error code.
Definition: error.h:45
#define TLS_VERSION_1_3
Definition: tls.h:95
#define TLS_MAX_KEY_UPDATE_MESSAGES
Definition: tls.h:750
#define TRACE_INFO(...)
Definition: debug.h:94
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)
uint8_t hash
Definition: tls.h:1369
@ ERROR_TIMEOUT
Definition: error.h:94
@ TLS_STATE_CLOSING
Definition: tls.h:1320
#define TRACE_DEBUG_ARRAY(p, a, n)
Definition: debug.h:107
@ TLS_KEY_UPDATE_REQUESTED
Definition: tls13_misc.h:178
@ TLS_CONNECTION_END_CLIENT
Definition: tls.h:861
uint8_t message[]
Definition: chap.h:152
TLS (Transport Layer Security)
TLS 1.3 key schedule.
Common interface for hash algorithms.
Definition: crypto.h:1128
@ TLS_KEY_UPDATE_NOT_REQUESTED
Definition: tls13_misc.h:177
@ ERROR_DECODING_FAILED
Definition: error.h:235
#define PRIuSIZE
Definition: compiler_port.h:78
error_t tls13ParseKeyUpdate(TlsContext *context, const Tls13KeyUpdate *message, size_t length)
@ TLS_TYPE_KEY_UPDATE
Definition: tls.h:950
@ NO_ERROR
Success.
Definition: error.h:44
Debugging facilities.