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