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-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.2
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_handshake.h"
37 #include "tls/tls_misc.h"
38 #include "tls13/tls13_common.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 Send KeyUpdate message
48  *
49  * The KeyUpdate handshake message is used to indicate that the sender is
50  * updating its sending cryptographic keys. This message can be sent by either
51  * peer after it has sent a Finished message
52  *
53  * @param[in] context Pointer to the TLS context
54  * @return Error code
55  **/
56 
58 {
59  error_t error;
60  size_t length;
61  uint8_t *appTrafficSecret;
63  const HashAlgo *hash;
64 
65  //Initialize pointer
66  appTrafficSecret = NULL;
67 
68  //Point to the buffer where to format the message
69  message = (Tls13KeyUpdate *) (context->txBuffer + context->txBufferLen);
70 
71  //Format KeyUpdate message
72  error = tls13FormatKeyUpdate(context, message, &length);
73 
74  //Check status code
75  if(!error)
76  {
77  //Debug message
78  TRACE_INFO("Sending KeyUpdate message (%" PRIuSIZE " bytes)...\r\n", length);
80 
81  //Send handshake message
82  error = tlsSendHandshakeMessage(context, message, length,
84  }
85 
86  //Check status code
87  if(error == NO_ERROR || error == ERROR_WOULD_BLOCK || error == ERROR_TIMEOUT)
88  {
89  //The hash function used by HKDF is the cipher suite hash algorithm
90  hash = context->cipherSuite.prfHashAlgo;
91 
92  //Make sure the hash algorithm is valid
93  if(hash != NULL)
94  {
95  //Check whether TLS operates as a client or a server
96  if(context->entity == TLS_CONNECTION_END_CLIENT)
97  {
98  appTrafficSecret = context->clientAppTrafficSecret;
99  }
100  else
101  {
102  appTrafficSecret = context->serverAppTrafficSecret;
103  }
104 
105  //Compute the next generation of application traffic secret
106  error = tls13HkdfExpandLabel(context->transportProtocol, hash,
107  appTrafficSecret, hash->digestSize, "traffic upd", NULL, 0,
108  appTrafficSecret, hash->digestSize);
109  }
110  else
111  {
112  //The hash algorithm is not valid
113  error = ERROR_FAILURE;
114  }
115  }
116 
117  //Check status code
118  if(!error)
119  {
120  //All the traffic keying material is recomputed whenever the underlying
121  //secret changes
122  error = tlsUpdateEncryptionEngine(context, context->encryptionEngine,
123  context->entity, TLS_ENCRYPTION_LEVEL_APPLICATION, appTrafficSecret);
124  }
125 
126  //Check status code
127  if(!error)
128  {
129  //DTLS protocol?
130  if(context->transportProtocol == TLS_TRANSPORT_PROTOCOL_DATAGRAM)
131  {
132  //KeyUpdate messages must be acknowledged (refer to RFC 9147,
133  //section 8)
135  }
136  else
137  {
138  //After sending a KeyUpdate message, the sender shall send all its
139  //traffic using the next generation of keys
141  }
142  }
143 
144  //Return status code
145  return error;
146 }
147 
148 
149 /**
150  * @brief Format KeyUpdate message
151  * @param[in] context Pointer to the TLS context
152  * @param[out] message Buffer where to format the KeyUpdate message
153  * @param[out] length Length of the resulting KeyUpdate message
154  * @return Error code
155  **/
156 
158  size_t *length)
159 {
160  //The request_update field indicates whether the recipient of the KeyUpdate
161  //should respond with its own KeyUpdate
162  message->requestUpdate = TLS_KEY_UPDATE_NOT_REQUESTED;
163 
164  //The KeyUpdate message consists of a single byte
165  *length = sizeof(Tls13KeyUpdate);
166 
167  //Successful processing
168  return NO_ERROR;
169 }
170 
171 
172 /**
173  * @brief Parse KeyUpdate message
174  *
175  * The KeyUpdate handshake message is used to indicate that the sender is
176  * updating its sending cryptographic keys. This message can be sent by either
177  * peer after it has sent a Finished message
178  *
179  * @param[in] context Pointer to the TLS context
180  * @param[in] message Incoming EncryptedExtensions message to parse
181  * @param[in] length Message length
182  * @return Error code
183  **/
184 
186  size_t length)
187 {
188  error_t error;
189  uint8_t *appTrafficSecret;
190  TlsConnectionEnd entity;
191  const HashAlgo *hash;
192 
193  //Debug message
194  TRACE_INFO("KeyUpdate message received (%" PRIuSIZE " bytes)...\r\n", length);
196 
197 #if (TLS_QUIC_SUPPORT == ENABLED)
198  //QUIC transport?
199  if(context->transportProtocol == TLS_TRANSPORT_PROTOCOL_QUIC)
200  {
201  //Endpoints must treat the receipt of a TLS KeyUpdate message as a
202  //connection error of type 0x010a, equivalent to a fatal TLS alert of
203  //unexpected_message (refer to RFC 9001, section 6)
205  }
206 #endif
207 
208  //Check TLS version
209  if(context->version != TLS_VERSION_1_3)
211 
212  //Check the length of the KeyUpdate message
213  if(length != sizeof(Tls13KeyUpdate))
214  return ERROR_DECODING_FAILED;
215 
216  //Ensure the value of the request_update field is valid
217  if(message->requestUpdate != TLS_KEY_UPDATE_NOT_REQUESTED &&
218  message->requestUpdate != TLS_KEY_UPDATE_REQUESTED)
219  {
220  //If an implementation receives any other value, it must terminate the
221  //connection with an illegal_parameter alert
223  }
224 
225  //Implementations that receive a KeyUpdate prior to receiving a Finished
226  //message must terminate the connection with an unexpected_message alert
227  if(context->state != TLS_STATE_APPLICATION_DATA &&
228  context->state != TLS_STATE_CLIENT_FINISHED_ACK &&
229  context->state != TLS_STATE_NEW_SESSION_TICKET_ACK &&
230  context->state != TLS_STATE_KEY_UPDATE_ACK &&
231  context->state != TLS_STATE_CLOSING)
232  {
233  //Report an error
235  }
236 
237 #if (TLS_MAX_KEY_UPDATE_MESSAGES > 0)
238  //Increment the count of consecutive KeyUpdate messages
239  context->keyUpdateCount++;
240 
241  //Do not allow too many consecutive KeyUpdate message
242  if(context->keyUpdateCount > TLS_MAX_KEY_UPDATE_MESSAGES)
244 #endif
245 
246  //The hash function used by HKDF is the cipher suite hash algorithm
247  hash = context->cipherSuite.prfHashAlgo;
248  //Make sure the hash algorithm is valid
249  if(hash == NULL)
250  return ERROR_FAILURE;
251 
252  //Upon receiving a KeyUpdate, the receiver must update its receiving keys
253  if(context->entity == TLS_CONNECTION_END_CLIENT)
254  {
255  entity = TLS_CONNECTION_END_SERVER;
256  appTrafficSecret = context->serverAppTrafficSecret;
257  }
258  else
259  {
260  entity = TLS_CONNECTION_END_CLIENT;
261  appTrafficSecret = context->clientAppTrafficSecret;
262  }
263 
264  //Compute the next generation of application traffic secret
265  error = tls13HkdfExpandLabel(context->transportProtocol, hash,
266  appTrafficSecret, hash->digestSize, "traffic upd", NULL, 0,
267  appTrafficSecret, hash->digestSize);
268  //Any error to report?
269  if(error)
270  return error;
271 
272  //The implementation must verify that its receive buffer is empty before
273  //rekeying
274  if(context->rxBufferLen != 0)
276 
277  //All the traffic keying material is recomputed whenever the underlying
278  //secret changes
279  error = tlsUpdateEncryptionEngine(context, context->decryptionEngine,
280  entity, TLS_ENCRYPTION_LEVEL_APPLICATION, appTrafficSecret);
281  //Any error to report?
282  if(error)
283  return error;
284 
285  //Check the value of the request_update field
286  if(message->requestUpdate == TLS_KEY_UPDATE_REQUESTED &&
287  context->state == TLS_STATE_APPLICATION_DATA)
288  {
289 #if (TLS_MAX_KEY_UPDATE_MESSAGES > 0)
290  if(context->keyUpdateCount == 1)
291 #endif
292  {
293  //If the request_update field is set to update_requested then the
294  //receiver must send a KeyUpdate of its own with request_update set to
295  //update_not_requested prior to sending its next application data
297  }
298  }
299 
300  //Successful processing
301  return NO_ERROR;
302 }
303 
304 #endif
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
@ TLS_TRANSPORT_PROTOCOL_QUIC
Definition: tls.h:1018
@ ERROR_WOULD_BLOCK
Definition: error.h:96
TLS handshake.
Tls13KeyUpdate
Definition: tls13_misc.h:352
@ ERROR_ILLEGAL_PARAMETER
Definition: error.h:244
@ ERROR_UNEXPECTED_MESSAGE
Definition: error.h:195
uint8_t message[]
Definition: chap.h:154
TlsConnectionEnd
TLS connection end.
Definition: tls.h:1028
size_t digestSize
Definition: crypto.h:1157
@ TLS_TRANSPORT_PROTOCOL_DATAGRAM
Definition: tls.h:1017
Handshake message processing (TLS 1.3 client and server)
@ TLS_STATE_APPLICATION_DATA
Definition: tls.h:1589
error_t tlsSendHandshakeMessage(TlsContext *context, const void *data, size_t length, TlsMessageType type)
Send handshake message.
@ TLS_STATE_KEY_UPDATE
Definition: tls.h:1592
#define TlsContext
Definition: tls.h:36
error_t
Error codes.
Definition: error.h:43
@ TLS_CONNECTION_END_SERVER
Definition: tls.h:1030
@ ERROR_FAILURE
Generic error code.
Definition: error.h:45
#define TLS_VERSION_1_3
Definition: tls.h:98
#define TLS_MAX_KEY_UPDATE_MESSAGES
Definition: tls.h:872
#define TRACE_INFO(...)
Definition: debug.h:105
uint8_t length
Definition: tcp.h:375
@ ERROR_TIMEOUT
Definition: error.h:95
@ TLS_ENCRYPTION_LEVEL_APPLICATION
Definition: tls.h:1608
error_t tls13ParseKeyUpdate(TlsContext *context, const Tls13KeyUpdate *message, size_t length)
Parse KeyUpdate message.
Definition: tls13_common.c:185
@ TLS_STATE_CLOSING
Definition: tls.h:1594
#define TRACE_DEBUG_ARRAY(p, a, n)
Definition: debug.h:120
error_t tls13FormatKeyUpdate(TlsContext *context, Tls13KeyUpdate *message, size_t *length)
Format KeyUpdate message.
Definition: tls13_common.c:157
@ TLS_KEY_UPDATE_REQUESTED
Definition: tls13_misc.h:177
@ TLS_STATE_CLIENT_FINISHED_ACK
Definition: tls.h:1590
@ TLS_CONNECTION_END_CLIENT
Definition: tls.h:1029
TLS (Transport Layer Security)
TLS 1.3 key schedule.
Common interface for hash algorithms.
Definition: crypto.h:1151
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.
@ TLS_KEY_UPDATE_NOT_REQUESTED
Definition: tls13_misc.h:176
void tlsChangeState(TlsContext *context, TlsState newState)
Update TLS state.
Definition: tls_misc.c:54
@ ERROR_DECODING_FAILED
Definition: error.h:242
#define PRIuSIZE
@ TLS_STATE_KEY_UPDATE_ACK
Definition: tls.h:1593
@ TLS_TYPE_KEY_UPDATE
Definition: tls.h:1121
@ NO_ERROR
Success.
Definition: error.h:44
Debugging facilities.
@ TLS_STATE_NEW_SESSION_TICKET_ACK
Definition: tls.h:1591
error_t tls13SendKeyUpdate(TlsContext *context)
Send KeyUpdate message.
Definition: tls13_common.c:57