tls13_client_misc.c
Go to the documentation of this file.
1 /**
2  * @file tls13_client_misc.c
3  * @brief Helper functions for TLS 1.3 client
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 <string.h>
36 #include "tls.h"
37 #include "tls_handshake.h"
38 #include "tls_client.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_client_misc.h"
44 #include "tls13_key_material.h"
45 #include "debug.h"
46 
47 //Check TLS library configuration
48 #if (TLS_SUPPORT == ENABLED && TLS_CLIENT_SUPPORT == ENABLED && \
49  TLS_MAX_VERSION >= TLS_VERSION_1_3)
50 
51 
52 /**
53  * @brief Check whether an incoming ServerHello message is a HelloRetryRequest
54  * @param[in] message Pointer to the ServerHello message
55  * @param[in] length Length of the ServerHello message
56  * @return TRUE is the message is a HelloRetryRequest, else FALSE
57  **/
58 
60 {
61  bool_t res;
62 
63  //Initialize flag
64  res = FALSE;
65 
66  //Check the length of the incoming ServerHello message
67  if(length >= sizeof(TlsServerHello))
68  {
69  //Upon receiving a message with type ServerHello, implementations must
70  //first examine the Random field
71  if(!memcmp(&message->random, tls13HelloRetryRequestRandom,
73  {
74  //The Random field matches the special value
75  res = TRUE;
76  }
77  }
78 
79  //Return TRUE is the message is a HelloRetryRequest, else FALSE
80  return res;
81 }
82 
83 
84 /**
85  * @brief Compute PSK binder values
86  * @param[in] context Pointer to the TLS context
87  * @param[in] clientHello Pointer to the ClientHello message
88  * @param[in] clientHelloLen Length of the ClientHello message
89  * @param[in] identityList List of the identities that the client is willing
90  * to negotiate with the server
91  * @param[in,out] binderList List of HMAC values, one for each PSK offered in
92  * the PreSharedKey extension
93  * @return Error code
94  **/
95 
96 error_t tls13ComputePskBinders(TlsContext *context, const void *clientHello,
97  size_t clientHelloLen, const Tls13PskIdentityList *identityList,
98  Tls13PskBinderList *binderList)
99 {
100  error_t error;
101  size_t n;
102  size_t m;
103  size_t truncatedClientHelloLen;
104  uint8_t *q;
105  const uint8_t *p;
106  Tls13PskBinder *binder;
107  const Tls13PskIdentity *identity;
108 
109  //Initialize status code
110  error = NO_ERROR;
111 
112 #if (TLS13_PSK_KE_SUPPORT == ENABLED || TLS13_PSK_DHE_KE_SUPPORT == ENABLED || \
113  TLS13_PSK_ECDHE_KE_SUPPORT == ENABLED)
114  //Check whether the ClientHello message contains a PreSharedKey extension
115  if(identityList != NULL && binderList != NULL)
116  {
117  //Point to the list of the identities that the client is willing to
118  //negotiate with the server
119  p = identityList->value;
120  n = ntohs(identityList->length);
121 
122  //Point to the list of HMAC values, one for each PSK offered in the
123  //PreSharedKey extension
124  q = binderList->value;
125  m = ntohs(binderList->length);
126 
127  //Each entry in the binders list is computed as an HMAC over a transcript
128  //hash containing a partial ClientHello up to the binders list itself
129  truncatedClientHelloLen = (uint8_t *) binderList - (uint8_t *) clientHello;
130 
131  //Loop through the list of PSK identities
132  while(n > 0)
133  {
134  //Point to the current PskIdentity entry
135  identity = (Tls13PskIdentity *) p;
136 
137  //Malformed PreSharedKey extension?
138  if(n < sizeof(TlsPskIdentity))
139  return ERROR_DECODING_FAILED;
140  if(n < (sizeof(TlsPskIdentity) + ntohs(identity->length)))
141  return ERROR_DECODING_FAILED;
142 
143  //Point to the obfuscated_ticket_age field
144  p += sizeof(TlsPskIdentity) + ntohs(identity->length);
145  n -= sizeof(TlsPskIdentity) + ntohs(identity->length);
146 
147  //The obfuscated_ticket_age field is a 32-bit unsigned integer
148  if(n < sizeof(uint32_t))
149  return ERROR_DECODING_FAILED;
150 
151  //Point to the next PskIdentity entry
152  p += sizeof(uint32_t);
153  n -= sizeof(uint32_t);
154 
155  //Point to the PskBinderEntry
156  binder = (Tls13PskBinder *) q;
157 
158  //Malformed PreSharedKey extension?
159  if(m < sizeof(Tls13PskBinder))
160  return ERROR_DECODING_FAILED;
161  if(m < (sizeof(Tls13PskBinder) + binder->length))
162  return ERROR_DECODING_FAILED;
163 
164  //Point to the next PskBinderEntry
165  q += sizeof(Tls13PskBinder) + binder->length;
166  m -= sizeof(Tls13PskBinder) + binder->length;
167 
168  //Fix the value of the PSK binder
169  error = tls13ComputePskBinder(context, clientHello, clientHelloLen,
170  truncatedClientHelloLen, identity, binder->value, binder->length);
171  //Any error to report?
172  if(error)
173  break;
174  }
175  }
176 #endif
177 
178  //Return status code
179  return error;
180 }
181 
182 
183 /**
184  * @brief Send early data to the remote TLS server
185  * @param[in] context Pointer to the TLS context
186  * @param[in] data Pointer to a buffer containing the data to be transmitted
187  * @param[in] length Number of bytes to be transmitted
188  * @param[out] written Actual number of bytes written
189  * @return Error code
190  **/
191 
192 error_t tls13SendEarlyData(TlsContext *context, const void *data,
193  size_t length, size_t *written)
194 {
195 #if (TLS13_EARLY_DATA_SUPPORT == ENABLED)
196  error_t error;
197  size_t n;
198 
199  //Actual number of bytes written
200  *written = 0;
201 
202  //Valid PSK?
203  if(tls13IsPskValid(context))
204  {
205  //Make sure a valid cipher suite has been provisioned
206  if(context->pskCipherSuite == 0)
207  return ERROR_END_OF_STREAM;
208  }
209  else if(tls13IsTicketValid(context))
210  {
211  //Make sure the cipher suite associated with the ticket is valid
212  if(context->ticketCipherSuite == 0)
213  return ERROR_END_OF_STREAM;
214  }
215  else
216  {
217  //The pre-shared key is not valid
218  return ERROR_END_OF_STREAM;
219  }
220 
221  //Initialize status code
222  error = NO_ERROR;
223 
224  //TLS 1.3 allows clients to send data on the first flight
225  while(!error)
226  {
227  //TLS protocol?
228  if(context->transportProtocol == TLS_TRANSPORT_PROTOCOL_STREAM)
229  {
230  //Check current state
231  if(context->state != TLS_STATE_INIT &&
232  context->state != TLS_STATE_CLOSED)
233  {
234  //Flush send buffer
235  error = tlsWriteProtocolData(context, NULL, 0, TLS_TYPE_NONE);
236  //Any error to report?
237  if(error)
238  break;
239  }
240  }
241 
242  //The TLS handshake is implemented as a state machine representing the
243  //current location in the protocol
244  if(context->state == TLS_STATE_INIT)
245  {
246  //TLS handshake initialization
247  error = tlsInitHandshake(context);
248  }
249  else if(context->state == TLS_STATE_CLIENT_HELLO)
250  {
251  //If the client opts to send application data in its first flight
252  //of messages, it must supply both the PreSharedKey and EarlyData
253  //extensions
254  context->earlyDataEnabled = TRUE;
255 
256  //When a client first connects to a server, it is required to send
257  //the ClientHello as its first message
258  error = tlsSendClientHello(context);
259  }
260  else if(context->state == TLS_STATE_SERVER_HELLO)
261  {
262  //Initialize handshake message hashing
263  error = tlsInitTranscriptHash(context);
264 
265 #if (TLS13_MIDDLEBOX_COMPAT_SUPPORT == ENABLED)
266  //In middlebox compatibility mode, the client sends a dummy
267  //ChangeCipherSpec record immediately before its second flight
268  context->state = TLS_STATE_CLIENT_CHANGE_CIPHER_SPEC;
269 #else
270  //The client can send its second flight
271  context->state = TLS_STATE_CLIENT_HELLO_2;
272 #endif
273  }
274  else if(context->state == TLS_STATE_CLIENT_CHANGE_CIPHER_SPEC)
275  {
276  //Send a dummy ChangeCipherSpec record
277  error = tlsSendChangeCipherSpec(context);
278  }
279  else if(context->state == TLS_STATE_CLIENT_HELLO_2)
280  {
281  //Compute early traffic keys
282  error = tls13GenerateEarlyTrafficKeys(context);
283  }
284  else if(context->state == TLS_STATE_EARLY_DATA)
285  {
286  //Send as much data as possible
287  if(*written < length &&
288  context->earlyDataLen < context->maxEarlyDataSize)
289  {
290  //Calculate the number of bytes to write at a time
291  n = MIN(context->txBufferMaxLen, length - *written);
292  n = MIN(n, context->maxEarlyDataSize - context->earlyDataLen);
293 
294  //The record length must not exceed 16384 bytes
296 
297  //Debug message
298  TRACE_INFO("Sending early data (%" PRIuSIZE " bytes)...\r\n", n);
299 
300  //Send 0-RTT data
301  error = tlsWriteProtocolData(context, data, n,
303 
304  //Check status code
305  if(!error)
306  {
307  //Advance data pointer
308  data = (uint8_t *) data + n;
309  //Update byte counter
310  *written += n;
311 
312  //Total amount of 0-RTT data that have been sent by the client
313  context->earlyDataLen += n;
314  }
315  }
316  else
317  {
318  //Clients must not more than max_early_data_size bytes of 0-RTT data
319  break;
320  }
321  }
322  else
323  {
324  //Report an error
325  error = ERROR_UNEXPECTED_STATE;
326  }
327  }
328 
329  //Check status code
330  if(error == NO_ERROR && length != 0 && *written == 0)
331  {
332  error = ERROR_END_OF_STREAM;
333  }
334 
335  //Return status code
336  return error;
337 #else
338  //Not implemented
339  return ERROR_NOT_IMPLEMENTED;
340 #endif
341 }
342 
343 #endif
#define TLS_MAX_RECORD_LENGTH
Definition: tls.h:830
TLS helper functions.
uint8_t length
Definition: dtls_misc.h:149
__start_packed struct @94 Tls13PskIdentity
PSK identity.
__start_packed struct @95 Tls13PskIdentityList
List of PSK identities.
int bool_t
Definition: compiler_port.h:49
error_t tlsSendChangeCipherSpec(TlsContext *context)
Send ChangeCipherSpec message.
Definition: tls_common.c:268
TLS handshake.
@ ERROR_NOT_IMPLEMENTED
Definition: error.h:66
__start_packed struct @97 Tls13PskBinderList
List of PSK binders.
uint8_t p
Definition: ndp.h:298
#define TRUE
Definition: os_port.h:50
@ ERROR_END_OF_STREAM
Definition: error.h:208
const uint8_t res[]
@ TLS_STATE_CLIENT_HELLO
Definition: tls.h:1290
@ TLS_STATE_SERVER_HELLO
Definition: tls.h:1295
#define FALSE
Definition: os_port.h:46
bool_t tls13IsHelloRetryRequest(const TlsServerHello *message, size_t length)
#define TlsContext
Definition: tls.h:36
error_t
Error codes.
Definition: error.h:42
@ TLS_TYPE_APPLICATION_DATA
Definition: tls.h:920
Helper functions for TLS 1.3 client.
@ TLS_STATE_EARLY_DATA
Definition: tls.h:1292
Handshake message processing (TLS client and server)
TLS record protocol.
error_t tls13SendEarlyData(TlsContext *context, const void *data, size_t length, size_t *written)
#define TRACE_INFO(...)
Definition: debug.h:94
#define MIN(a, b)
Definition: os_port.h:62
@ TLS_STATE_CLIENT_CHANGE_CIPHER_SPEC
Definition: tls.h:1308
Transcript hash calculation.
#define ntohs(value)
Definition: cpu_endian.h:398
@ TLS_TYPE_NONE
Definition: tls.h:916
error_t tls13ComputePskBinder(TlsContext *context, const void *clientHello, size_t clientHelloLen, size_t truncatedClientHelloLen, const Tls13PskIdentity *identity, uint8_t *binder, size_t binderLen)
@ TLS_STATE_CLIENT_HELLO_2
Definition: tls.h:1291
uint8_t m
Definition: ndp.h:302
uint8_t n
@ ERROR_UNEXPECTED_STATE
Definition: error.h:98
bool_t tls13IsPskValid(TlsContext *context)
__start_packed struct @86 TlsServerHello
ServerHello message.
@ TLS_STATE_INIT
Definition: tls.h:1289
bool_t tls13IsTicketValid(TlsContext *context)
error_t tlsInitTranscriptHash(TlsContext *context)
Initialize handshake message hashing.
error_t tlsWriteProtocolData(TlsContext *context, const uint8_t *data, size_t length, TlsContentType contentType)
Write protocol data.
Definition: tls_record.c:55
uint8_t message[]
Definition: chap.h:152
error_t tls13ComputePskBinders(TlsContext *context, const void *clientHello, size_t clientHelloLen, const Tls13PskIdentityList *identityList, Tls13PskBinderList *binderList)
error_t tls13GenerateEarlyTrafficKeys(TlsContext *context)
TLS (Transport Layer Security)
@ TLS_TRANSPORT_PROTOCOL_STREAM
Definition: tls.h:850
__start_packed struct @79 TlsPskIdentity
PSK identity.
TLS 1.3 key schedule.
error_t tlsSendClientHello(TlsContext *context)
Send ClientHello message.
Definition: tls_client.c:82
@ ERROR_DECODING_FAILED
Definition: error.h:235
#define PRIuSIZE
Definition: compiler_port.h:78
Handshake message processing (TLS client)
uint8_t data[]
Definition: dtls_misc.h:176
__start_packed struct @96 Tls13PskBinder
PSK binder.
@ NO_ERROR
Success.
Definition: error.h:44
Debugging facilities.
const uint8_t tls13HelloRetryRequestRandom[32]
error_t tlsInitHandshake(TlsContext *context)
TLS handshake initialization.
Definition: tls_handshake.c:56
@ TLS_STATE_CLOSED
Definition: tls.h:1321