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-2024 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.4.0
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, 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  //Check the length of the KeyUpdate message
195  if(length != sizeof(Tls13KeyUpdate))
196  return ERROR_DECODING_FAILED;
197 
198  //Ensure the value of the request_update field is valid
199  if(message->requestUpdate != TLS_KEY_UPDATE_NOT_REQUESTED &&
200  message->requestUpdate != TLS_KEY_UPDATE_REQUESTED)
201  {
202  //If an implementation receives any other value, it must terminate the
203  //connection with an illegal_parameter alert
205  }
206 
207  //Implementations that receive a KeyUpdate prior to receiving a Finished
208  //message must terminate the connection with an unexpected_message alert
209  if(context->state != TLS_STATE_APPLICATION_DATA &&
210  context->state != TLS_STATE_CLOSING)
211  {
212  //Report an error
214  }
215 
216 #if (TLS_MAX_KEY_UPDATE_MESSAGES > 0)
217  //Increment the count of consecutive KeyUpdate messages
218  context->keyUpdateCount++;
219 
220  //Do not allow too many consecutive KeyUpdate message
221  if(context->keyUpdateCount > TLS_MAX_KEY_UPDATE_MESSAGES)
223 #endif
224 
225  //The hash function used by HKDF is the cipher suite hash algorithm
226  hash = context->cipherSuite.prfHashAlgo;
227  //Make sure the hash algorithm is valid
228  if(hash == NULL)
229  return ERROR_FAILURE;
230 
231  //Upon receiving a KeyUpdate, the receiver must update its receiving keys
232  if(context->entity == TLS_CONNECTION_END_CLIENT)
233  {
234  entity = TLS_CONNECTION_END_SERVER;
235  appTrafficSecret = context->serverAppTrafficSecret;
236  }
237  else
238  {
239  entity = TLS_CONNECTION_END_CLIENT;
240  appTrafficSecret = context->clientAppTrafficSecret;
241  }
242 
243  //Compute the next generation of application traffic secret
244  error = tls13HkdfExpandLabel(context->transportProtocol, hash,
245  appTrafficSecret, hash->digestSize, "traffic upd", NULL, 0,
246  appTrafficSecret, hash->digestSize);
247  //Any error to report?
248  if(error)
249  return error;
250 
251  //The implementation must verify that its receive buffer is empty before
252  //rekeying
253  if(context->rxBufferLen != 0)
255 
256  //Release decryption engine
257  tlsFreeEncryptionEngine(&context->decryptionEngine);
258 
259  //All the traffic keying material is recomputed whenever the underlying
260  //secret changes
261  error = tlsInitEncryptionEngine(context, &context->decryptionEngine,
262  entity, appTrafficSecret);
263  //Any error to report?
264  if(error)
265  return error;
266 
267  //Check the value of the request_update field
268  if(message->requestUpdate == TLS_KEY_UPDATE_REQUESTED &&
269  context->state == TLS_STATE_APPLICATION_DATA)
270  {
271 #if (TLS_MAX_KEY_UPDATE_MESSAGES > 0)
272  if(context->keyUpdateCount == 1)
273 #endif
274  {
275  //If the request_update field is set to update_requested then the
276  //receiver must send a KeyUpdate of its own with request_update set to
277  //update_not_requested prior to sending its next application data
279  }
280  }
281 
282  //Successful processing
283  return NO_ERROR;
284 }
285 
286 #endif
uint8_t message[]
Definition: chap.h:154
#define PRIuSIZE
Debugging facilities.
#define TRACE_DEBUG_ARRAY(p, a, n)
Definition: debug.h:108
#define TRACE_INFO(...)
Definition: debug.h:95
error_t
Error codes.
Definition: error.h:43
@ ERROR_ILLEGAL_PARAMETER
Definition: error.h:242
@ ERROR_WOULD_BLOCK
Definition: error.h:96
@ ERROR_TIMEOUT
Definition: error.h:95
@ ERROR_DECODING_FAILED
Definition: error.h:240
@ NO_ERROR
Success.
Definition: error.h:44
@ ERROR_FAILURE
Generic error code.
Definition: error.h:45
@ ERROR_UNEXPECTED_MESSAGE
Definition: error.h:194
Common interface for hash algorithms.
Definition: crypto.h:1014
size_t digestSize
Definition: crypto.h:1020
uint8_t length
Definition: tcp.h:368
error_t tls13FormatKeyUpdate(TlsContext *context, Tls13KeyUpdate *message, size_t *length)
Format KeyUpdate message.
Definition: tls13_common.c:150
error_t tls13SendKeyUpdate(TlsContext *context)
Send KeyUpdate message.
Definition: tls13_common.c:57
error_t tls13ParseKeyUpdate(TlsContext *context, const Tls13KeyUpdate *message, size_t length)
Parse KeyUpdate message.
Definition: tls13_common.c:178
Handshake message processing (TLS 1.3 client and server)
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 1.3 key schedule.
@ TLS_KEY_UPDATE_REQUESTED
Definition: tls13_misc.h:149
@ TLS_KEY_UPDATE_NOT_REQUESTED
Definition: tls13_misc.h:148
Tls13KeyUpdate
Definition: tls13_misc.h:324
TLS (Transport Layer Security)
@ TLS_STATE_KEY_UPDATE
Definition: tls.h:1467
@ TLS_STATE_APPLICATION_DATA
Definition: tls.h:1468
@ TLS_STATE_CLOSING
Definition: tls.h:1469
#define TLS_MAX_KEY_UPDATE_MESSAGES
Definition: tls.h:829
#define TLS_VERSION_1_3
Definition: tls.h:97
#define TlsContext
Definition: tls.h:36
TlsConnectionEnd
TLS connection end.
Definition: tls.h:952
@ TLS_CONNECTION_END_SERVER
Definition: tls.h:954
@ TLS_CONNECTION_END_CLIENT
Definition: tls.h:953
@ TLS_TYPE_KEY_UPDATE
Definition: tls.h:1045
error_t tlsSendHandshakeMessage(TlsContext *context, const void *data, size_t length, TlsMessageType type)
Send handshake message.
TLS handshake.
void tlsFreeEncryptionEngine(TlsEncryptionEngine *encryptionEngine)
Release encryption engine.
Definition: tls_misc.c:917
void tlsChangeState(TlsContext *context, TlsState newState)
Update TLS state.
Definition: tls_misc.c:54
__weak_func error_t tlsInitEncryptionEngine(TlsContext *context, TlsEncryptionEngine *encryptionEngine, TlsConnectionEnd entity, const uint8_t *secret)
Initialize encryption engine.
Definition: tls_misc.c:670
TLS helper functions.