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-2025 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.5.4
29  **/
30 
31 //Switch to the appropriate trace level
32 #define TRACE_LEVEL TLS_TRACE_LEVEL
33 
34 //Dependencies
35 #include "tls.h"
36 #include "tls_handshake.h"
37 #include "tls_misc.h"
38 #include "tls13_common.h"
39 #include "tls13_key_material.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  //Release encryption engine
121  tlsFreeEncryptionEngine(&context->encryptionEngine);
122 
123  //All the traffic keying material is recomputed whenever the underlying
124  //secret changes
125  error = tlsInitEncryptionEngine(context, &context->encryptionEngine,
126  context->entity, TLS_ENCRYPTION_LEVEL_APPLICATION, appTrafficSecret);
127  }
128 
129  //Check status code
130  if(!error)
131  {
132  //After sending a KeyUpdate message, the sender shall send all its
133  //traffic using the next generation of keys
135  }
136 
137  //Return status code
138  return error;
139 }
140 
141 
142 /**
143  * @brief Format KeyUpdate message
144  * @param[in] context Pointer to the TLS context
145  * @param[out] message Buffer where to format the KeyUpdate message
146  * @param[out] length Length of the resulting KeyUpdate message
147  * @return Error code
148  **/
149 
151  size_t *length)
152 {
153  //The request_update field indicates whether the recipient of the KeyUpdate
154  //should respond with its own KeyUpdate
155  message->requestUpdate = TLS_KEY_UPDATE_NOT_REQUESTED;
156 
157  //The KeyUpdate message consists of a single byte
158  *length = sizeof(Tls13KeyUpdate);
159 
160  //Successful processing
161  return NO_ERROR;
162 }
163 
164 
165 /**
166  * @brief Parse KeyUpdate message
167  *
168  * The KeyUpdate handshake message is used to indicate that the sender is
169  * updating its sending cryptographic keys. This message can be sent by either
170  * peer after it has sent a Finished message
171  *
172  * @param[in] context Pointer to the TLS context
173  * @param[in] message Incoming EncryptedExtensions message to parse
174  * @param[in] length Message length
175  * @return Error code
176  **/
177 
179  size_t length)
180 {
181  error_t error;
182  uint8_t *appTrafficSecret;
183  TlsConnectionEnd entity;
184  const HashAlgo *hash;
185 
186  //Debug message
187  TRACE_INFO("KeyUpdate message received (%" PRIuSIZE " bytes)...\r\n", length);
189 
190  //Check TLS version
191  if(context->version != TLS_VERSION_1_3)
193 
194 #if (TLS_QUIC_SUPPORT == ENABLED)
195  //QUIC transport?
196  if(context->transportProtocol == TLS_TRANSPORT_PROTOCOL_QUIC)
197  {
198  //Endpoints must treat the receipt of a TLS KeyUpdate message as a
199  //connection error of type 0x010a, equivalent to a fatal TLS alert of
200  //unexpected_message (refer to RFC 9001, section 6)
202  }
203 #endif
204 
205  //Check the length of the KeyUpdate message
206  if(length != sizeof(Tls13KeyUpdate))
207  return ERROR_DECODING_FAILED;
208 
209  //Ensure the value of the request_update field is valid
210  if(message->requestUpdate != TLS_KEY_UPDATE_NOT_REQUESTED &&
211  message->requestUpdate != TLS_KEY_UPDATE_REQUESTED)
212  {
213  //If an implementation receives any other value, it must terminate the
214  //connection with an illegal_parameter alert
216  }
217 
218  //Implementations that receive a KeyUpdate prior to receiving a Finished
219  //message must terminate the connection with an unexpected_message alert
220  if(context->state != TLS_STATE_APPLICATION_DATA &&
221  context->state != TLS_STATE_CLOSING)
222  {
223  //Report an error
225  }
226 
227 #if (TLS_MAX_KEY_UPDATE_MESSAGES > 0)
228  //Increment the count of consecutive KeyUpdate messages
229  context->keyUpdateCount++;
230 
231  //Do not allow too many consecutive KeyUpdate message
232  if(context->keyUpdateCount > TLS_MAX_KEY_UPDATE_MESSAGES)
234 #endif
235 
236  //The hash function used by HKDF is the cipher suite hash algorithm
237  hash = context->cipherSuite.prfHashAlgo;
238  //Make sure the hash algorithm is valid
239  if(hash == NULL)
240  return ERROR_FAILURE;
241 
242  //Upon receiving a KeyUpdate, the receiver must update its receiving keys
243  if(context->entity == TLS_CONNECTION_END_CLIENT)
244  {
245  entity = TLS_CONNECTION_END_SERVER;
246  appTrafficSecret = context->serverAppTrafficSecret;
247  }
248  else
249  {
250  entity = TLS_CONNECTION_END_CLIENT;
251  appTrafficSecret = context->clientAppTrafficSecret;
252  }
253 
254  //Compute the next generation of application traffic secret
255  error = tls13HkdfExpandLabel(context->transportProtocol, hash,
256  appTrafficSecret, hash->digestSize, "traffic upd", NULL, 0,
257  appTrafficSecret, hash->digestSize);
258  //Any error to report?
259  if(error)
260  return error;
261 
262  //The implementation must verify that its receive buffer is empty before
263  //rekeying
264  if(context->rxBufferLen != 0)
266 
267  //Release decryption engine
268  tlsFreeEncryptionEngine(&context->decryptionEngine);
269 
270  //All the traffic keying material is recomputed whenever the underlying
271  //secret changes
272  error = tlsInitEncryptionEngine(context, &context->decryptionEngine,
273  entity, TLS_ENCRYPTION_LEVEL_APPLICATION, appTrafficSecret);
274  //Any error to report?
275  if(error)
276  return error;
277 
278  //Check the value of the request_update field
279  if(message->requestUpdate == TLS_KEY_UPDATE_REQUESTED &&
280  context->state == TLS_STATE_APPLICATION_DATA)
281  {
282 #if (TLS_MAX_KEY_UPDATE_MESSAGES > 0)
283  if(context->keyUpdateCount == 1)
284 #endif
285  {
286  //If the request_update field is set to update_requested then the
287  //receiver must send a KeyUpdate of its own with request_update set to
288  //update_not_requested prior to sending its next application data
290  }
291  }
292 
293  //Successful processing
294  return NO_ERROR;
295 }
296 
297 #endif
TLS helper functions.
@ TLS_TRANSPORT_PROTOCOL_QUIC
Definition: tls.h:1001
@ 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:1011
size_t digestSize
Definition: crypto.h:1130
Handshake message processing (TLS 1.3 client and server)
@ TLS_STATE_APPLICATION_DATA
Definition: tls.h:1568
error_t tlsSendHandshakeMessage(TlsContext *context, const void *data, size_t length, TlsMessageType type)
Send handshake message.
@ TLS_STATE_KEY_UPDATE
Definition: tls.h:1567
#define TlsContext
Definition: tls.h:36
error_t
Error codes.
Definition: error.h:43
@ TLS_CONNECTION_END_SERVER
Definition: tls.h:1013
void tlsFreeEncryptionEngine(TlsEncryptionEngine *encryptionEngine)
Release encryption engine.
Definition: tls_misc.c:928
@ ERROR_FAILURE
Generic error code.
Definition: error.h:45
#define TLS_VERSION_1_3
Definition: tls.h:97
#define TLS_MAX_KEY_UPDATE_MESSAGES
Definition: tls.h:871
#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:1583
error_t tls13ParseKeyUpdate(TlsContext *context, const Tls13KeyUpdate *message, size_t length)
Parse KeyUpdate message.
Definition: tls13_common.c:178
@ TLS_STATE_CLOSING
Definition: tls.h:1569
#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:150
@ TLS_KEY_UPDATE_REQUESTED
Definition: tls13_misc.h:177
@ TLS_CONNECTION_END_CLIENT
Definition: tls.h:1012
TLS (Transport Layer Security)
TLS 1.3 key schedule.
Common interface for hash algorithms.
Definition: crypto.h:1124
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_TYPE_KEY_UPDATE
Definition: tls.h:1104
@ NO_ERROR
Success.
Definition: error.h:44
Debugging facilities.
__weak_func error_t tlsInitEncryptionEngine(TlsContext *context, TlsEncryptionEngine *encryptionEngine, TlsConnectionEnd entity, TlsEncryptionLevel level, const uint8_t *secret)
Initialize encryption engine.
Definition: tls_misc.c:675
error_t tls13SendKeyUpdate(TlsContext *context)
Send KeyUpdate message.
Definition: tls13_common.c:57