tls_handshake.c
Go to the documentation of this file.
1 /**
2  * @file tls_handshake.c
3  * @brief TLS handshake
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.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_client_fsm.h"
38 #include "tls_server_fsm.h"
39 #include "tls_common.h"
40 #include "tls_transcript_hash.h"
41 #include "tls_record.h"
42 #include "tls_misc.h"
43 #include "tls13_server_misc.h"
44 #include "dtls_record.h"
45 #include "debug.h"
46 
47 //Check TLS library configuration
48 #if (TLS_SUPPORT == ENABLED)
49 
50 
51 /**
52  * @brief TLS handshake initialization
53  * @param[in] context Pointer to the TLS context
54  * @return Error code
55  **/
56 
58 {
59  //Allocate send buffer if necessary
60  if(context->txBuffer == NULL)
61  {
62  //Allocate TX buffer
63  context->txBuffer = tlsAllocMem(context->txBufferSize);
64 
65  //Failed to allocate memory?
66  if(context->txBuffer == NULL)
67  return ERROR_OUT_OF_MEMORY;
68 
69  //Clear TX buffer
70  osMemset(context->txBuffer, 0, context->txBufferSize);
71  }
72 
73  //Allocate receive buffer if necessary
74  if(context->rxBuffer == NULL)
75  {
76  //Allocate RX buffer
77  context->rxBuffer = tlsAllocMem(context->rxBufferSize);
78 
79  //Failed to allocate memory?
80  if(context->rxBuffer == NULL)
81  return ERROR_OUT_OF_MEMORY;
82 
83  //Clear RX buffer
84  osMemset(context->rxBuffer, 0, context->rxBufferSize);
85  }
86 
87 #if (TLS_MAX_VERSION >= TLS_VERSION_1_3 && TLS_MIN_VERSION <= TLS_VERSION_1_3)
88  //Server mode?
89  if(context->entity == TLS_CONNECTION_END_SERVER)
90  {
91  //A server implementation may choose to reject the early data
92  context->earlyDataRejected = TRUE;
93  }
94 #endif
95 
96  //The client initiates the TLS handshake by sending a ClientHello message
97  //to the server
99 
100  //Successful processing
101  return NO_ERROR;
102 }
103 
104 
105 /**
106  * @brief Perform TLS handshake
107  *
108  * TLS handshake protocol is responsible for the authentication and key
109  * exchange necessary to establish a secure session
110  *
111  * @param[in] context Pointer to the TLS context
112  * @return Error code
113  **/
114 
116 {
117  error_t error;
118 
119 #if (TLS_CLIENT_SUPPORT == ENABLED)
120  //Client mode?
121  if(context->entity == TLS_CONNECTION_END_CLIENT)
122  {
123  //Perform TLS handshake with the remote server
124  error = tlsPerformClientHandshake(context);
125  }
126  else
127 #endif
128 #if (TLS_SERVER_SUPPORT == ENABLED)
129  //Server mode?
130  if(context->entity == TLS_CONNECTION_END_SERVER)
131  {
132  //Perform TLS handshake with the remote client
133  error = tlsPerformServerHandshake(context);
134  }
135  else
136 #endif
137  //Unsupported mode of operation?
138  {
139  //Report an error
140  error = ERROR_INVALID_PARAMETER;
141  }
142 
143  //Return status code
144  return error;
145 }
146 
147 
148 /**
149  * @brief Send handshake message
150  * @param[in] context Pointer to the TLS context
151  * @param[in] data Pointer to the handshake message
152  * @param[in] length Length of the handshake message
153  * @param[in] type Handshake message type
154  * @return Error code
155  **/
156 
158  size_t length, TlsMessageType type)
159 {
160  error_t error;
161 
162 #if (DTLS_SUPPORT == ENABLED)
163  //DTLS protocol?
164  if(context->transportProtocol == TLS_TRANSPORT_PROTOCOL_DATAGRAM)
165  {
167 
168  //Point to the handshake message header
169  message = (DtlsHandshake *) data;
170 
171  //Make room for the handshake message header
172  osMemmove(message->data, data, length);
173 
174  //Handshake message type
175  message->msgType = type;
176  //Number of bytes in the message
177  STORE24BE(length, message->length);
178  //Message sequence number
179  message->msgSeq = htons(context->txMsgSeq);
180  //Fragment offset
181  STORE24BE(0, message->fragOffset);
182  //Fragment length
183  STORE24BE(length, message->fragLength);
184 
185  //Whenever a new message is generated, the message sequence number is
186  //incremented by one
187  context->txMsgSeq++;
188 
189  //Total length of the handshake message
190  length += sizeof(DtlsHandshake);
191  }
192  else
193 #endif
194  //TLS protocol?
195  {
197 
198  //Point to the handshake message header
199  message = (TlsHandshake *) data;
200 
201  //Make room for the handshake message header
202  osMemmove(message->data, data, length);
203 
204  //Handshake message type
205  message->msgType = type;
206  //Number of bytes in the message
207  STORE24BE(length, message->length);
208 
209  //Total length of the handshake message
210  length += sizeof(TlsHandshake);
211  }
212 
213  //The HelloRequest message must not be included in the message hashes
214  //that are maintained throughout the handshake and used in the Finished
215  //messages and the CertificateVerify message
217  {
219  }
220 
221 #if (DTLS_SUPPORT == ENABLED)
222  //DTLS protocol?
223  if(context->transportProtocol == TLS_TRANSPORT_PROTOCOL_DATAGRAM)
224  {
225  //Send handshake message
227  }
228  else
229 #endif
230  //TLS protocol?
231  {
232  //Send handshake message
234  }
235 
236  //Return status code
237  return error;
238 }
239 
240 
241 /**
242  * @brief Receive peer's message
243  * @param[in] context Pointer to the TLS context
244  * @return Error code
245  **/
246 
248 {
249  error_t error;
250  size_t length;
251  uint8_t *data;
252  TlsContentType contentType;
253 
254 #if (DTLS_SUPPORT == ENABLED)
255  //DTLS protocol?
256  if(context->transportProtocol == TLS_TRANSPORT_PROTOCOL_DATAGRAM)
257  {
258  //A message can be fragmented across several DTLS records
259  error = dtlsReadProtocolData(context, &data, &length, &contentType);
260  }
261  else
262 #endif
263  //TLS protocol?
264  {
265  //A message can be fragmented across several TLS records
266  error = tlsReadProtocolData(context, &data, &length, &contentType);
267  }
268 
269  //Check status code
270  if(!error)
271  {
272  //Advance data pointer
273  context->rxBufferPos += length;
274  //Number of bytes still pending in the receive buffer
275  context->rxBufferLen -= length;
276 
277  //Handshake message received?
278  if(contentType == TLS_TYPE_HANDSHAKE)
279  {
280  //Parse handshake message
281  error = tlsParseHandshakeMessage(context, data, length);
282  }
283  //ChangeCipherSpec message received?
284  else if(contentType == TLS_TYPE_CHANGE_CIPHER_SPEC)
285  {
286  //The ChangeCipherSpec message is sent by an endpoint to notify the
287  //peer that subsequent records will be protected under the newly
288  //negotiated CipherSpec and keys
290  length);
291  }
292  //Alert message received?
293  else if(contentType == TLS_TYPE_ALERT)
294  {
295  //Parse Alert message
296  error = tlsParseAlert(context, (TlsAlert *) data, length);
297  }
298 #if (TLS_MAX_VERSION >= TLS_VERSION_1_3 && TLS_MIN_VERSION <= TLS_VERSION_1_3)
299  //Application data received?
300  else if(contentType == TLS_TYPE_APPLICATION_DATA)
301  {
302 #if (TLS_SERVER_SUPPORT == ENABLED)
303  //Server mode?
304  if(context->entity == TLS_CONNECTION_END_SERVER)
305  {
306  //Process early data
307  error = tls13ProcessEarlyData(context, data, length);
308  }
309  else
310 #endif
311  {
312  //The server cannot transmit application data before the handshake
313  //is completed
314  error = ERROR_UNEXPECTED_MESSAGE;
315  }
316  }
317 #endif
318  //Unexpected message received?
319  else
320  {
321  //Abort the handshake with an unexpected_message alert
322  error = ERROR_UNEXPECTED_MESSAGE;
323  }
324  }
325 
326  //Return status code
327  return error;
328 }
329 
330 
331 /**
332  * @brief Parse handshake message
333  * @param[in] context Pointer to the TLS context
334  * @param[in] message Pointer to the handshake message to parse
335  * @param[in] length Length of the handshake messaged
336  * @return Error code
337  **/
338 
340  size_t length)
341 {
342  error_t error;
343  uint8_t msgType;
344  size_t n;
345  const void *p;
346 
347 #if (DTLS_SUPPORT == ENABLED)
348  //DTLS protocol?
349  if(context->transportProtocol == TLS_TRANSPORT_PROTOCOL_DATAGRAM)
350  {
351  //Retrieve handshake message type
352  msgType = ((DtlsHandshake *) message)->msgType;
353  //Point to the handshake message
354  p = message + sizeof(DtlsHandshake);
355  //Calculate the length of the handshake message
356  n = length - sizeof(DtlsHandshake);
357  }
358  else
359 #endif
360  //TLS protocol?
361  {
362  //Retrieve handshake message type
363  msgType = ((TlsHandshake *) message)->msgType;
364  //Point to the handshake message
365  p = message + sizeof(TlsHandshake);
366  //Calculate the length of the handshake message
367  n = length - sizeof(TlsHandshake);
368  }
369 
370 #if (TLS_MAX_KEY_UPDATE_MESSAGES > 0)
371  //Reset the count of consecutive KeyUpdate messages
373  {
374  context->keyUpdateCount = 0;
375  }
376 #endif
377 
378 #if (TLS_CLIENT_SUPPORT == ENABLED)
379  //Client mode?
380  if(context->entity == TLS_CONNECTION_END_CLIENT)
381  {
382  //Parse server's handshake message
383  error = tlsParseServerHandshakeMessage(context, msgType, p, n);
384 
385  //Update the hash value with the incoming handshake message
387  }
388  else
389 #endif
390 #if (TLS_SERVER_SUPPORT == ENABLED)
391  //Server mode?
392  if(context->entity == TLS_CONNECTION_END_SERVER)
393  {
394  //Update the hash value with the incoming handshake message
396  {
398  }
399 
400  //Parse client's handshake message
401  error = tlsParseClientHandshakeMessage(context, msgType, p, n);
402 
403  //Update the hash value with the incoming handshake message
405  {
407  }
408  }
409  else
410 #endif
411  //Unsupported mode of operation?
412  {
413  //Report an error
414  error = ERROR_FAILURE;
415  }
416 
417  //Return status code
418  return error;
419 }
420 
421 #endif
#define tlsAllocMem(size)
Definition: tls.h:853
#define htons(value)
Definition: cpu_endian.h:413
TLS helper functions.
TLS state machine (TLS server)
error_t tlsPerformHandshake(TlsContext *context)
Perform TLS handshake.
TLS handshake.
@ ERROR_UNEXPECTED_MESSAGE
Definition: error.h:194
uint8_t p
Definition: ndp.h:300
uint8_t message[]
Definition: chap.h:154
error_t tlsPerformClientHandshake(TlsContext *context)
TLS client handshake.
#define TRUE
Definition: os_port.h:50
@ TLS_TYPE_CHANGE_CIPHER_SPEC
Definition: tls.h:1024
uint8_t data[]
Definition: ethernet.h:222
@ TLS_TYPE_HANDSHAKE
Definition: tls.h:1026
error_t tlsPerformServerHandshake(TlsContext *context)
TLS server handshake.
@ TLS_TRANSPORT_PROTOCOL_DATAGRAM
Definition: tls.h:957
TlsMessageType
Handshake message type.
Definition: tls.h:1039
error_t tlsParseChangeCipherSpec(TlsContext *context, const TlsChangeCipherSpec *message, size_t length)
Parse ChangeCipherSpec message.
Definition: tls_common.c:1324
uint8_t type
Definition: coap_common.h:176
@ ERROR_OUT_OF_MEMORY
Definition: error.h:63
error_t tlsReceiveHandshakeMessage(TlsContext *context)
Receive peer's message.
TlsChangeCipherSpec
Definition: tls.h:1862
error_t tlsSendHandshakeMessage(TlsContext *context, const void *data, size_t length, TlsMessageType type)
Send handshake message.
@ TLS_STATE_CLIENT_HELLO
Definition: tls.h:1456
TlsHandshake
Definition: tls.h:1754
error_t tlsParseAlert(TlsContext *context, const TlsAlert *message, size_t length)
Parse Alert message.
Definition: tls_common.c:1601
@ ERROR_INVALID_PARAMETER
Invalid parameter.
Definition: error.h:47
#define TlsContext
Definition: tls.h:36
error_t
Error codes.
Definition: error.h:43
DTLS record protocol.
@ TLS_CONNECTION_END_SERVER
Definition: tls.h:969
@ ERROR_FAILURE
Generic error code.
Definition: error.h:45
TlsAlert
Definition: tls.h:1873
@ TLS_TYPE_APPLICATION_DATA
Definition: tls.h:1027
@ TLS_TYPE_ALERT
Definition: tls.h:1025
Handshake message processing (TLS client and server)
TLS record protocol.
error_t tlsReadProtocolData(TlsContext *context, uint8_t **data, size_t *length, TlsContentType *contentType)
Read protocol data.
Definition: tls_record.c:157
error_t dtlsWriteProtocolData(TlsContext *context, const uint8_t *data, size_t length, TlsContentType contentType)
Write protocol data.
Definition: dtls_record.c:58
uint8_t length
Definition: tcp.h:368
@ TLS_TYPE_CLIENT_KEY_EXCHANGE
Definition: tls.h:1055
Helper functions for TLS 1.3 server.
TLS state machine (TLS client)
void tlsUpdateTranscriptHash(TlsContext *context, const void *data, size_t length)
Update hash value with a handshake message.
Transcript hash calculation.
TlsContentType
Content type.
Definition: tls.h:1022
uint8_t msgType
error_t dtlsReadProtocolData(TlsContext *context, uint8_t **data, size_t *length, TlsContentType *contentType)
Read protocol data.
Definition: dtls_record.c:130
uint8_t n
error_t tlsParseHandshakeMessage(TlsContext *context, const uint8_t *message, size_t length)
Parse handshake message.
DtlsHandshake
Definition: dtls_misc.h:195
error_t tlsWriteProtocolData(TlsContext *context, const uint8_t *data, size_t length, TlsContentType contentType)
Write protocol data.
Definition: tls_record.c:54
@ TLS_CONNECTION_END_CLIENT
Definition: tls.h:968
TLS (Transport Layer Security)
#define STORE24BE(a, p)
Definition: cpu_endian.h:273
error_t tlsParseServerHandshakeMessage(TlsContext *context, uint8_t msgType, const void *message, size_t length)
Parse server's handshake message.
error_t tlsParseClientHandshakeMessage(TlsContext *context, uint8_t msgType, const void *message, size_t length)
Parse client's handshake message.
void tlsChangeState(TlsContext *context, TlsState newState)
Update TLS state.
Definition: tls_misc.c:54
@ TLS_TYPE_HELLO_REQUEST
Definition: tls.h:1040
#define osMemset(p, value, length)
Definition: os_port.h:135
@ TLS_TYPE_KEY_UPDATE
Definition: tls.h:1060
error_t tls13ProcessEarlyData(TlsContext *context, const uint8_t *data, size_t length)
Process early data.
@ NO_ERROR
Success.
Definition: error.h:44
Debugging facilities.
#define osMemmove(dest, src, length)
Definition: os_port.h:147
error_t tlsInitHandshake(TlsContext *context)
TLS handshake initialization.
Definition: tls_handshake.c:57