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  * Copyright (C) 2010-2018 Oryx Embedded SARL. All rights reserved.
8  *
9  * This file is part of CycloneSSL Open.
10  *
11  * This program is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU General Public License
13  * as published by the Free Software Foundation; either version 2
14  * of the License, or (at your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software Foundation,
23  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
24  *
25  * @author Oryx Embedded SARL (www.oryx-embedded.com)
26  * @version 1.9.0
27  **/
28 
29 //Switch to the appropriate trace level
30 #define TRACE_LEVEL TLS_TRACE_LEVEL
31 
32 //Dependencies
33 #include <string.h>
34 #include "tls.h"
35 #include "tls_handshake.h"
36 #include "tls_misc.h"
37 #include "tls13_common.h"
38 #include "tls13_key_material.h"
39 #include "debug.h"
40 
41 //Check TLS library configuration
42 #if (TLS_SUPPORT == ENABLED && TLS_MAX_VERSION >= TLS_VERSION_1_3)
43 
44 
45 /**
46  * @brief Send KeyUpdate message
47  *
48  * The KeyUpdate handshake message is used to indicate that the sender is
49  * updating its sending cryptographic keys. This message can be sent by either
50  * peer after it has sent a Finished message
51  *
52  * @param[in] context Pointer to the TLS context
53  * @return Error code
54  **/
55 
57 {
58  error_t error;
59  size_t length;
60  uint8_t *appTrafficSecret;
62  const HashAlgo *hash;
63 
64  //Initialize pointer
65  appTrafficSecret = NULL;
66 
67  //Point to the buffer where to format the message
68  message = (Tls13KeyUpdate *) (context->txBuffer + context->txBufferLen);
69 
70  //Format KeyUpdate message
71  error = tls13FormatKeyUpdate(context, message, &length);
72 
73  //Check status code
74  if(!error)
75  {
76  //Debug message
77  TRACE_INFO("Sending KeyUpdate message (%" PRIuSIZE " bytes)...\r\n", length);
79 
80  //Send handshake message
81  error = tlsSendHandshakeMessage(context, message, length,
83  }
84 
85  //Check status code
86  if(error == NO_ERROR || error == ERROR_WOULD_BLOCK || error == ERROR_TIMEOUT)
87  {
88  //The hash function used by HKDF is the cipher suite hash algorithm
89  hash = context->cipherSuite.prfHashAlgo;
90 
91  //Make sure the hash algorithm is valid
92  if(hash != NULL)
93  {
94  //Check whether TLS operates as a client or a server
95  if(context->entity == TLS_CONNECTION_END_CLIENT)
96  appTrafficSecret = context->clientAppTrafficSecret;
97  else
98  appTrafficSecret = context->serverAppTrafficSecret;
99 
100  //Compute the next generation of application traffic secret
101  error = tls13HkdfExpandLabel(hash, appTrafficSecret, hash->digestSize,
102  "traffic upd", NULL, 0, appTrafficSecret, hash->digestSize);
103  }
104  else
105  {
106  //The hash algorithm is not valid
107  error = ERROR_FAILURE;
108  }
109  }
110 
111  //Check status code
112  if(!error)
113  {
114  //Release encryption engine
115  tlsFreeEncryptionEngine(&context->encryptionEngine);
116 
117  //All the traffic keying material is recomputed whenever the underlying
118  //secret changes
119  error = tlsInitEncryptionEngine(context, &context->encryptionEngine,
120  context->entity, appTrafficSecret);
121  }
122 
123  //Check status code
124  if(!error)
125  {
126  //After sending a KeyUpdate message, the sender shall send all its
127  //traffic using the next generation of keys
128  context->state = TLS_STATE_APPLICATION_DATA;
129  }
130 
131  //Return status code
132  return error;
133 }
134 
135 
136 /**
137  * @brief Format KeyUpdate message
138  * @param[in] context Pointer to the TLS context
139  * @param[out] message Buffer where to format the KeyUpdate message
140  * @param[out] length Length of the resulting KeyUpdate message
141  * @return Error code
142  **/
143 
145  size_t *length)
146 {
147  //The request_update field indicates whether the recipient of the KeyUpdate
148  //should respond with its own KeyUpdate
149  message->requestUpdate = TLS_KEY_UPDATE_NOT_REQUESTED;
150 
151  //The KeyUpdate message consists of a single byte
152  *length = sizeof(Tls13KeyUpdate);
153 
154  //Successful processing
155  return NO_ERROR;
156 }
157 
158 
159 /**
160  * @brief Parse KeyUpdate message
161  *
162  * The KeyUpdate handshake message is used to indicate that the sender is
163  * updating its sending cryptographic keys. This message can be sent by either
164  * peer after it has sent a Finished message
165  *
166  * @param[in] context Pointer to the TLS context
167  * @param[in] message Incoming EncryptedExtensions message to parse
168  * @param[in] length Message length
169  * @return Error code
170  **/
171 
173  size_t length)
174 {
175  error_t error;
176  uint8_t *appTrafficSecret;
177  TlsConnectionEnd entity;
178  const HashAlgo *hash;
179 
180  //Debug message
181  TRACE_INFO("KeyUpdate message received (%" PRIuSIZE " bytes)...\r\n", length);
183 
184  //Check TLS version
185  if(context->version != TLS_VERSION_1_3)
187 
188  //Ensure the value of the request_update field is valid
189  if(message->requestUpdate != TLS_KEY_UPDATE_NOT_REQUESTED &&
190  message->requestUpdate != TLS_KEY_UPDATE_REQUESTED)
191  {
192  //If an implementation receives any other value, it must terminate the
193  //connection with an illegal_parameter alert
195  }
196 
197  //Check the length of the KeyUpdate message
198  if(length != sizeof(Tls13KeyUpdate))
199  return ERROR_DECODING_FAILED;
200 
201  //Implementations that receive a KeyUpdate prior to receiving a Finished
202  //message must terminate the connection with an unexpected_message alert
203  if(context->state != TLS_STATE_APPLICATION_DATA &&
204  context->state != TLS_STATE_CLOSING)
205  {
206  //Report an error
208  }
209 
210 #if (TLS_MAX_KEY_UPDATE_MESSAGES > 0)
211  //Increment the count of consecutive KeyUpdate messages
212  context->keyUpdateCount++;
213 
214  //Do not allow too many consecutive KeyUpdate message
215  if(context->keyUpdateCount > TLS_MAX_KEY_UPDATE_MESSAGES)
217 #endif
218 
219  //The hash function used by HKDF is the cipher suite hash algorithm
220  hash = context->cipherSuite.prfHashAlgo;
221  //Make sure the hash algorithm is valid
222  if(hash == NULL)
223  return ERROR_FAILURE;
224 
225  //Upon receiving a KeyUpdate, the receiver must update its receiving keys
226  if(context->entity == TLS_CONNECTION_END_CLIENT)
227  {
228  entity = TLS_CONNECTION_END_SERVER;
229  appTrafficSecret = context->serverAppTrafficSecret;
230  }
231  else
232  {
233  entity = TLS_CONNECTION_END_CLIENT;
234  appTrafficSecret = context->clientAppTrafficSecret;
235  }
236 
237  //Compute the next generation of application traffic secret
238  error = tls13HkdfExpandLabel(hash, appTrafficSecret, hash->digestSize,
239  "traffic upd", NULL, 0, appTrafficSecret, hash->digestSize);
240  //Any error to report?
241  if(error)
242  return error;
243 
244  //The implementation must verify that its receive buffer is empty before
245  //rekeying
246  if(context->rxBufferLen != 0)
248 
249  //Release decryption engine
250  tlsFreeEncryptionEngine(&context->decryptionEngine);
251 
252  //All the traffic keying material is recomputed whenever the underlying
253  //secret changes
254  error = tlsInitEncryptionEngine(context, &context->decryptionEngine,
255  entity, appTrafficSecret);
256  //Any error to report?
257  if(error)
258  return error;
259 
260  //Check the value of the request_update field
261  if(message->requestUpdate == TLS_KEY_UPDATE_REQUESTED &&
262  context->state == TLS_STATE_APPLICATION_DATA)
263  {
264 #if (TLS_MAX_KEY_UPDATE_MESSAGES > 0)
265  if(context->keyUpdateCount == 1)
266 #endif
267  {
268  //If the request_update field is set to update_requested then the
269  //receiver must send a KeyUpdate of its own with request_update set to
270  //update_not_requested prior to sending its next application data
271  context->state = TLS_STATE_KEY_UPDATE;
272  }
273  }
274 
275  //Successful processing
276  return NO_ERROR;
277 }
278 
279 #endif
TLS (Transport Layer Security)
Debugging facilities.
uint8_t hash
Definition: tls.h:1363
TLS 1.3 key schedule.
Generic error code.
Definition: error.h:43
error_t tls13FormatKeyUpdate(TlsContext *context, Tls13KeyUpdate *message, size_t *length)
uint8_t message[]
Definition: chap.h:150
#define TLS_VERSION_1_3
Definition: tls.h:90
#define TRACE_DEBUG_ARRAY(p, a, n)
Definition: debug.h:99
Handshake message processing (TLS 1.3 client and server)
error_t tls13SendKeyUpdate(TlsContext *context)
TLS helper functions.
TLS handshake.
error_t tlsInitEncryptionEngine(TlsContext *context, TlsEncryptionEngine *encryptionEngine, TlsConnectionEnd entity, const uint8_t *secret)
Initialize encryption engine.
Definition: tls_misc.c:376
__start_packed struct @107 Tls13KeyUpdate
KeyUpdate message.
error_t tls13HkdfExpandLabel(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)
#define TRACE_INFO(...)
Definition: debug.h:86
Success.
Definition: error.h:42
error_t
Error codes.
Definition: error.h:40
#define PRIuSIZE
Definition: compiler_port.h:72
error_t tlsSendHandshakeMessage(TlsContext *context, const void *data, size_t length, TlsMessageType type)
Send handshake message.
TlsConnectionEnd
TLS connection end.
Definition: tls.h:855
void tlsFreeEncryptionEngine(TlsEncryptionEngine *encryptionEngine)
Release encryption engine.
Definition: tls_misc.c:599
Common interface for hash algorithms.
Definition: crypto.h:1054
uint8_t length
Definition: dtls_misc.h:140
error_t tls13ParseKeyUpdate(TlsContext *context, const Tls13KeyUpdate *message, size_t length)
#define TlsContext
Definition: tls.h:34
#define TLS_MAX_KEY_UPDATE_MESSAGES
Definition: tls.h:748