tls13_server.c
Go to the documentation of this file.
1 /**
2  * @file tls13_server.c
3  * @brief Handshake message processing (TLS 1.3 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_server_extensions.h"
38 #include "tls_server_misc.h"
39 #include "tls_extensions.h"
40 #include "tls_transcript_hash.h"
41 #include "tls_ffdhe.h"
42 #include "tls_misc.h"
43 #include "tls13_server.h"
45 #include "tls13_server_misc.h"
46 #include "tls13_ticket.h"
47 #include "tls13_misc.h"
48 #include "debug.h"
49 
50 //Check TLS library configuration
51 #if (TLS_SUPPORT == ENABLED && TLS_SERVER_SUPPORT == ENABLED && \
52  TLS_MAX_VERSION >= TLS_VERSION_1_3)
53 
54 
55 /**
56  * @brief Send HelloRetryRequest message
57  *
58  * The server will send this message in response to a ClientHello message if it
59  * is able to find an acceptable set of parameters but the ClientHello does not
60  * contain sufficient information to proceed with the handshake
61  *
62  * @param[in] context Pointer to the TLS context
63  * @return Error code
64  **/
65 
67 {
68  error_t error;
69  size_t length;
71 
72  //Point to the buffer where to format the message
73  message = (Tls13HelloRetryRequest *) (context->txBuffer + context->txBufferLen);
74 
75  //When the server responds to a ClientHello with a HelloRetryRequest, the
76  //value of ClientHello1 is replaced with a special synthetic handshake
77  //message of handshake type MessageHash containing Hash(ClientHello1)
78  error = tls13DigestClientHello1(context);
79 
80  //Check status code
81  if(!error)
82  {
83  //Format HelloRetryRequest message
84  error = tls13FormatHelloRetryRequest(context, message, &length);
85  }
86 
87  //Check status code
88  if(!error)
89  {
90  //Debug message
91  TRACE_INFO("Sending HelloRetryRequest message (%" PRIuSIZE " bytes)...\r\n", length);
93 
94  //For reasons of backward compatibility with middleboxes the
95  //HelloRetryRequest message uses the same format as the ServerHello
96  error = tlsSendHandshakeMessage(context, message, length,
98  }
99 
100  //Check status code
101  if(error == NO_ERROR || error == ERROR_WOULD_BLOCK || error == ERROR_TIMEOUT)
102  {
103 #if (TLS13_MIDDLEBOX_COMPAT_SUPPORT == ENABLED)
104  //DTLS implementations do not use the "compatibility mode" and must
105  //not send ChangeCipherSpec messages (refer to RFC 9147, section 5)
106  if(context->transportProtocol == TLS_TRANSPORT_PROTOCOL_STREAM)
107  {
108  //In middlebox compatibility mode, the server sends a dummy
109  //ChangeCipherSpec record immediately after its first handshake
110  //message. This may either be after a ServerHello or a
111  //HelloRetryRequest
113  }
114  else
115 #endif
116  {
117  //Wait for the second updated ClientHello
119  }
120  }
121 
122  //Return status code
123  return error;
124 }
125 
126 
127 /**
128  * @brief Send EncryptedExtensions message
129  *
130  * The server sends the EncryptedExtensions message immediately after the
131  * ServerHello message. The EncryptedExtensions message contains extensions
132  * that can be protected
133  *
134  * @param[in] context Pointer to the TLS context
135  * @return Error code
136  **/
137 
139 {
140  error_t error;
141  size_t length;
143 
144  //Point to the buffer where to format the message
145  message = (Tls13EncryptedExtensions *) (context->txBuffer + context->txBufferLen);
146 
147  //Format EncryptedExtensions message
148  error = tls13FormatEncryptedExtensions(context, message, &length);
149 
150  //Check status code
151  if(!error)
152  {
153  //Debug message
154  TRACE_INFO("Sending EncryptedExtensions message (%" PRIuSIZE " bytes)...\r\n", length);
156 
157  //Send handshake message
158  error = tlsSendHandshakeMessage(context, message, length,
160  }
161 
162  //Check status code
163  if(error == NO_ERROR || error == ERROR_WOULD_BLOCK || error == ERROR_TIMEOUT)
164  {
165  //PSK key exchange method?
166  if(context->keyExchMethod == TLS13_KEY_EXCH_PSK ||
167  context->keyExchMethod == TLS13_KEY_EXCH_PSK_DHE ||
168  context->keyExchMethod == TLS13_KEY_EXCH_PSK_ECDHE)
169  {
170  //As the server is authenticating via a PSK, it does not send a
171  //Certificate or a CertificateVerify message
173  }
174  else
175  {
176  //A server can optionally request a certificate from the client
178  }
179  }
180 
181  //Return status code
182  return error;
183 }
184 
185 
186 /**
187  * @brief Send NewSessionTicket message
188  *
189  * At any time after the server has received the client Finished message, it
190  * may send a NewSessionTicket message
191  *
192  * @param[in] context Pointer to the TLS context
193  * @return Error code
194  **/
195 
197 {
198  error_t error;
199  size_t length;
201 
202  //Initialize status code
203  error = NO_ERROR;
204 
205  //Send as many NewSessionTicket messages as requested
206  if(context->newSessionTicketCount < TLS13_NEW_SESSION_TICKET_COUNT)
207  {
208  //Point to the buffer where to format the message
209  message = (Tls13NewSessionTicket *) (context->txBuffer + context->txBufferLen);
210 
211  //Format NewSessionTicket message
212  error = tls13FormatNewSessionTicket(context, message, &length);
213 
214  //Check status code
215  if(!error)
216  {
217  //Increment the number of NewSessionTicket messages that have been sent
218  context->newSessionTicketCount++;
219 
220  //Debug message
221  TRACE_INFO("Sending NewSessionTicket message (%" PRIuSIZE " bytes)...\r\n", length);
223 
224  //Send handshake message
225  error = tlsSendHandshakeMessage(context, message, length,
227  }
228  }
229  else
230  {
231  //The client and server can now exchange application-layer data
233  }
234 
235  //Return status code
236  return error;
237 }
238 
239 
240 /**
241  * @brief Format HelloRetryRequest message
242  * @param[in] context Pointer to the TLS context
243  * @param[out] message Buffer where to format the HelloRetryRequest message
244  * @param[out] length Length of the resulting HelloRetryRequest message
245  * @return Error code
246  **/
247 
250 {
251  error_t error;
252  size_t n;
253  uint8_t *p;
254  TlsExtensionList *extensionList;
255 
256  //In TLS 1.3, the client indicates its version preferences in the
257  //SupportedVersions extension and the legacy_version field must be set
258  //to 0x0303, which is the version number for TLS 1.2
259  if(context->transportProtocol == TLS_TRANSPORT_PROTOCOL_DATAGRAM)
260  {
261  message->serverVersion = HTONS(DTLS_VERSION_1_2);
262  }
263  else
264  {
265  message->serverVersion = HTONS(TLS_VERSION_1_2);
266  }
267 
268  //For backward compatibility with middleboxes the HelloRetryRequest message
269  //uses the same structure as the ServerHello, but with Random field set to
270  //a special value
272 
273  //Point to the session ID
274  p = message->sessionId;
275  //Length of the handshake message
276  *length = sizeof(Tls13HelloRetryRequest);
277 
278  //The legacy_session_id_echo echoes the contents of the client's
279  //legacy_session_id field
280  osMemcpy(message->sessionId, context->sessionId, context->sessionIdLen);
281  message->sessionIdLen = (uint8_t) context->sessionIdLen;
282 
283  //Debug message
284  TRACE_INFO("Session ID (%" PRIu8 " bytes):\r\n", message->sessionIdLen);
285  TRACE_INFO_ARRAY(" ", message->sessionId, message->sessionIdLen);
286 
287  //Advance data pointer
288  p += message->sessionIdLen;
289  //Adjust the length of the message
290  *length += message->sessionIdLen;
291 
292  //The cipher_suite field contains the cipher suite selected by the server
293  STORE16BE(context->cipherSuite.identifier, p);
294 
295  //Advance data pointer
296  p += sizeof(uint16_t);
297  //Adjust the length of the message
298  *length += sizeof(uint16_t);
299 
300  //The legacy_compression_method field must have the value 0
302 
303  //Advance data pointer
304  p += sizeof(uint8_t);
305  //Adjust the length of the message
306  *length += sizeof(uint8_t);
307 
308  //Point to the list of extensions
309  extensionList = (TlsExtensionList *) p;
310  //Total length of the extension list
311  extensionList->length = 0;
312 
313  //Point to the first extension of the list
314  p += sizeof(TlsExtensionList);
315  //Adjust the length of the message
316  *length += sizeof(TlsExtensionList);
317 
318  //The HelloRetryRequest message must contain a SupportedVersions extension
319  error = tls13FormatServerSupportedVersionsExtension(context, p, &n);
320  //Any error to report?
321  if(error)
322  return error;
323 
324  //Fix the length of the extension list
325  extensionList->length += (uint16_t) n;
326  //Point to the next field
327  p += n;
328 
329  //The KeyShare extension contains the mutually supported group the server
330  //intends to negotiate
331  error = tls13FormatSelectedGroupExtension(context, p, &n);
332  //Any error to report?
333  if(error)
334  return error;
335 
336  //Fix the length of the extension list
337  extensionList->length += (uint16_t) n;
338  //Point to the next field
339  p += n;
340 
341  //Convert the length of the extension list to network byte order
342  extensionList->length = htons(extensionList->length);
343  //Total length of the message
344  *length += htons(extensionList->length);
345 
346  //Successful processing
347  return NO_ERROR;
348 }
349 
350 
351 /**
352  * @brief Format EncryptedExtensions message
353  * @param[in] context Pointer to the TLS context
354  * @param[out] message Buffer where to format the EncryptedExtensions message
355  * @param[out] length Length of the resulting EncryptedExtensions message
356  * @return Error code
357  **/
358 
361 {
362  error_t error;
363  size_t n;
364  uint8_t *p;
365 
366  //Point to the extension of the list
367  p = message->extensions;
368  //Length of the handshake message
369  *length = sizeof(Tls13EncryptedExtensions);
370 
371  //Total length of the extension list
372  message->extensionsLen = 0;
373 
374 #if (TLS_SNI_SUPPORT == ENABLED)
375  //The server may include a SNI extension in the ServerHello
376  error = tlsFormatServerSniExtension(context, p, &n);
377  //Any error to report?
378  if(error)
379  return error;
380 
381  //Fix the length of the extension list
382  message->extensionsLen += (uint16_t) n;
383  //Point to the next field
384  p += n;
385 #endif
386 
387 #if (TLS_MAX_FRAG_LEN_SUPPORT == ENABLED)
388  //Servers that receive an ClientHello containing a MaxFragmentLength
389  //extension may accept the requested maximum fragment length by including
390  //an extension of type MaxFragmentLength in the ServerHello
391  error = tlsFormatServerMaxFragLenExtension(context, p, &n);
392  //Any error to report?
393  if(error)
394  return error;
395 
396  //Fix the length of the extension list
397  message->extensionsLen += (uint16_t) n;
398  //Point to the next field
399  p += n;
400 #endif
401 
402 #if (TLS_RECORD_SIZE_LIMIT_SUPPORT == ENABLED)
403  //The value of RecordSizeLimit is the maximum size of record in octets
404  //that the endpoint is willing to receive
405  error = tlsFormatServerRecordSizeLimitExtension(context, p, &n);
406  //Any error to report?
407  if(error)
408  return error;
409 
410  //Fix the length of the extension list
411  message->extensionsLen += (uint16_t) n;
412  //Point to the next field
413  p += n;
414 #endif
415 
416 #if (TLS_ALPN_SUPPORT == ENABLED)
417  //The ALPN extension contains the name of the selected protocol
418  error = tlsFormatServerAlpnExtension(context, p, &n);
419  //Any error to report?
420  if(error)
421  return error;
422 
423  //Fix the length of the extension list
424  message->extensionsLen += (uint16_t) n;
425  //Point to the next field
426  p += n;
427 #endif
428 
429 #if (TLS_RAW_PUBLIC_KEY_SUPPORT == ENABLED)
430  //The ClientCertType extension in the ServerHello indicates the type
431  //of certificates the client is requested to provide in a subsequent
432  //certificate payload
433  error = tlsFormatClientCertTypeExtension(context, p, &n);
434  //Any error to report?
435  if(error)
436  return error;
437 
438  //Fix the length of the extension list
439  message->extensionsLen += (uint16_t) n;
440  //Point to the next field
441  p += n;
442 
443  //With the ServerCertType extension in the ServerHello, the TLS server
444  //indicates the certificate type carried in the certificate payload
445  error = tlsFormatServerCertTypeExtension(context, p, &n);
446  //Any error to report?
447  if(error)
448  return error;
449 
450  //Fix the length of the extension list
451  message->extensionsLen += (uint16_t) n;
452  //Point to the next field
453  p += n;
454 #endif
455 
456 #if (TLS13_EARLY_DATA_SUPPORT == ENABLED)
457  //If the server intends to process the early data, then it returns its
458  //own EarlyData extension in the EncryptedExtensions message
459  error = tls13FormatServerEarlyDataExtension(context,
461  //Any error to report?
462  if(error)
463  return error;
464 
465  //Fix the length of the extension list
466  message->extensionsLen += (uint16_t) n;
467  //Point to the next field
468  p += n;
469 #endif
470 
471  //Convert the length of the extension list to network byte order
472  message->extensionsLen = htons(message->extensionsLen);
473  //Total length of the message
474  *length += htons(message->extensionsLen);
475 
476  //Successful processing
477  return NO_ERROR;
478 }
479 
480 
481 /**
482  * @brief Format NewSessionTicket message
483  * @param[in] context Pointer to the TLS context
484  * @param[out] message Buffer where to format the NewSessionTicket message
485  * @param[out] length Length of the resulting NewSessionTicket message
486  * @return Error code
487  **/
488 
491 {
492 #if (TLS_TICKET_SUPPORT == ENABLED)
493  error_t error;
494  size_t n;
495  uint8_t *p;
497  TlsExtensionList *extensionList;
498 
499  //Set the lifetime of the ticket, in seconds
500  message->ticketLifetime = HTONL(TLS_TICKET_LIFETIME / 1000);
501 
502  //The ticket_age_add field is used to obscure the age of the ticket
503  error = context->prngAlgo->read(context->prngContext,
504  (uint8_t *) &message->ticketAgeAdd, sizeof(uint32_t));
505  //Any error to report?
506  if(error)
507  return error;
508 
509  //Point to ticket nonce
510  p = message->ticketNonce;
511  //Length of the handshake message
512  *length = sizeof(Tls13NewSessionTicket);
513 
514  //The ticket nonce is a per-ticket value that is unique across all tickets
515  //issued on this connection
516  context->ticketNonce++;
517 
518  //Copy ticket nonce
519  STORE32BE(context->ticketNonce, message->ticketNonce);
520  //Set the length of the nonce
521  message->ticketNonceLen = sizeof(uint32_t);
522 
523  //Advance data pointer
524  p += message->ticketNonceLen;
525  //Adjust the length of the message
526  *length += message->ticketNonceLen;
527 
528  //Point to the value of the ticket
529  ticket = (Tls13Ticket *) p;
530 
531  //The ticket itself is an opaque label. It may be either a database lookup
532  //key or a self-encrypted and self-authenticated value
533  error = tls13GenerateTicket(context, message, ticket->data, &n);
534  //Any error to report?
535  if(error)
536  return error;
537 
538  //Fix the length of the ticket
539  ticket->length = htons(n);
540 
541  //Advance data pointer
542  p += sizeof(Tls13Ticket) + n;
543  //Adjust the length of the message
544  *length += sizeof(Tls13Ticket) + n;
545 
546  //Point to the list of extensions
547  extensionList = (TlsExtensionList *) p;
548  //Total length of the extension list
549  extensionList->length = 0;
550 
551  //Point to the first extension of the list
552  p += sizeof(TlsExtensionList);
553  //Adjust the length of the message
554  *length += sizeof(TlsExtensionList);
555 
556 #if (TLS13_EARLY_DATA_SUPPORT == ENABLED)
557  //The sole extension currently defined for NewSessionTicket is EarlyData
558  //indicating that the ticket may be used to send 0-RTT data
559  error = tls13FormatServerEarlyDataExtension(context,
561  //Any error to report?
562  if(error)
563  return error;
564 
565  //Fix the length of the extension list
566  extensionList->length += (uint16_t) n;
567  //Point to the next field
568  p += n;
569 #endif
570 
571  //Convert the length of the extension list to network byte order
572  extensionList->length = htons(extensionList->length);
573  //Total length of the message
574  *length += htons(extensionList->length);
575 
576  //Successful processing
577  return NO_ERROR;
578 #else
579  //Session ticket mechanism is not implemented
580  return ERROR_NOT_IMPLEMENTED;
581 #endif
582 }
583 
584 #endif
uint8_t message[]
Definition: chap.h:154
#define PRIuSIZE
#define HTONS(value)
Definition: cpu_endian.h:410
#define htons(value)
Definition: cpu_endian.h:413
#define STORE32BE(a, p)
Definition: cpu_endian.h:286
#define STORE16BE(a, p)
Definition: cpu_endian.h:262
#define HTONL(value)
Definition: cpu_endian.h:411
Debugging facilities.
#define TRACE_DEBUG_ARRAY(p, a, n)
Definition: debug.h:108
#define TRACE_INFO_ARRAY(p, a, n)
Definition: debug.h:96
#define TRACE_INFO(...)
Definition: debug.h:95
uint8_t n
#define DTLS_VERSION_1_2
Definition: dtls_misc.h:36
error_t
Error codes.
Definition: error.h:43
@ ERROR_WOULD_BLOCK
Definition: error.h:96
@ ERROR_TIMEOUT
Definition: error.h:95
@ ERROR_NOT_IMPLEMENTED
Definition: error.h:66
@ NO_ERROR
Success.
Definition: error.h:44
uint8_t p
Definition: ndp.h:300
#define osMemcpy(dest, src, length)
Definition: os_port.h:141
uint8_t length
Definition: tcp.h:368
error_t tls13DigestClientHello1(TlsContext *context)
Hash ClientHello1 in the transcript when HelloRetryRequest is used.
Definition: tls13_misc.c:493
const uint8_t tls13HelloRetryRequestRandom[32]
Definition: tls13_misc.c:65
TLS 1.3 helper functions.
Tls13NewSessionTicket
Definition: tls13_misc.h:314
Tls13Ticket
Definition: tls13_misc.h:335
Tls13EncryptedExtensions
Definition: tls13_misc.h:301
Tls13HelloRetryRequest
Definition: tls13_misc.h:283
#define TLS13_NEW_SESSION_TICKET_COUNT
Definition: tls13_misc.h:113
error_t tls13SendNewSessionTicket(TlsContext *context)
Send NewSessionTicket message.
Definition: tls13_server.c:196
error_t tls13SendEncryptedExtensions(TlsContext *context)
Send EncryptedExtensions message.
Definition: tls13_server.c:138
error_t tls13FormatHelloRetryRequest(TlsContext *context, Tls13HelloRetryRequest *message, size_t *length)
Format HelloRetryRequest message.
Definition: tls13_server.c:248
error_t tls13FormatNewSessionTicket(TlsContext *context, Tls13NewSessionTicket *message, size_t *length)
Format NewSessionTicket message.
Definition: tls13_server.c:489
error_t tls13SendHelloRetryRequest(TlsContext *context)
Send HelloRetryRequest message.
Definition: tls13_server.c:66
error_t tls13FormatEncryptedExtensions(TlsContext *context, Tls13EncryptedExtensions *message, size_t *length)
Format EncryptedExtensions message.
Definition: tls13_server.c:359
Handshake message processing (TLS 1.3 server)
error_t tls13FormatSelectedGroupExtension(TlsContext *context, uint8_t *p, size_t *written)
Format KeyShare extension (HelloRetryRequest message)
error_t tls13FormatServerEarlyDataExtension(TlsContext *context, TlsMessageType msgType, uint8_t *p, size_t *written)
Format EarlyData extension.
error_t tls13FormatServerSupportedVersionsExtension(TlsContext *context, uint8_t *p, size_t *written)
Format SupportedVersions extension.
Formatting and parsing of extensions (TLS 1.3 server)
Helper functions for TLS 1.3 server.
error_t tls13GenerateTicket(TlsContext *context, const Tls13NewSessionTicket *message, uint8_t *ticket, size_t *length)
Session ticket generation.
Definition: tls13_ticket.c:306
TLS 1.3 session tickets.
TLS (Transport Layer Security)
@ TLS_STATE_SERVER_CHANGE_CIPHER_SPEC_2
Definition: tls.h:1462
@ TLS_STATE_SERVER_FINISHED
Definition: tls.h:1463
@ TLS_STATE_CLIENT_HELLO_2
Definition: tls.h:1440
@ TLS_STATE_APPLICATION_DATA
Definition: tls.h:1468
@ TLS_STATE_CERTIFICATE_REQUEST
Definition: tls.h:1452
@ TLS13_KEY_EXCH_PSK_DHE
Definition: tls.h:1146
@ TLS13_KEY_EXCH_PSK
Definition: tls.h:1145
@ TLS13_KEY_EXCH_PSK_ECDHE
Definition: tls.h:1147
@ TLS_TRANSPORT_PROTOCOL_STREAM
Definition: tls.h:941
@ TLS_TRANSPORT_PROTOCOL_DATAGRAM
Definition: tls.h:942
@ TLS_COMPRESSION_METHOD_NULL
Definition: tls.h:1113
uint8_t ticket[]
Definition: tls.h:1827
TlsExtensionList
Definition: tls.h:1567
#define TlsContext
Definition: tls.h:36
#define TLS_TICKET_LIFETIME
Definition: tls.h:164
@ TLS_TYPE_SERVER_HELLO
Definition: tls.h:1027
@ TLS_TYPE_ENCRYPTED_EXTENSIONS
Definition: tls.h:1032
@ TLS_TYPE_NEW_SESSION_TICKET
Definition: tls.h:1029
#define TLS_VERSION_1_2
Definition: tls.h:96
Parsing and checking of TLS extensions.
FFDHE key exchange.
error_t tlsSendHandshakeMessage(TlsContext *context, const void *data, size_t length, TlsMessageType type)
Send handshake message.
TLS handshake.
void tlsChangeState(TlsContext *context, TlsState newState)
Update TLS state.
Definition: tls_misc.c:54
TLS helper functions.
error_t tlsFormatServerCertTypeExtension(TlsContext *context, uint8_t *p, size_t *written)
Format ServerCertType extension.
error_t tlsFormatClientCertTypeExtension(TlsContext *context, uint8_t *p, size_t *written)
Format ClientCertType extension.
error_t tlsFormatServerMaxFragLenExtension(TlsContext *context, uint8_t *p, size_t *written)
Format MaxFragmentLength extension.
error_t tlsFormatServerSniExtension(TlsContext *context, uint8_t *p, size_t *written)
Format SNI extension.
error_t tlsFormatServerRecordSizeLimitExtension(TlsContext *context, uint8_t *p, size_t *written)
Format RecordSizeLimit extension.
error_t tlsFormatServerAlpnExtension(TlsContext *context, uint8_t *p, size_t *written)
Format ALPN extension.
Formatting and parsing of extensions (TLS server)
Helper functions for TLS server.
Transcript hash calculation.