EVE 1.0
tls.h
Go to the documentation of this file.
1 #ifndef EVE_TLS_H_INCLUDED
2 #define EVE_TLS_H_INCLUDED
3 /**********************************************************************/
4 /*
5  * Copyright (c) 2016, Jetro AS
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without modification,
9  * are permitted provided that the following conditions are met:
10  *
11  * 1. Redistributions of source code must retain the above copyright notice,
12  * this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright notice,
14  * this list of conditions and the following disclaimer in the documentation
15  * and/or other materials provided with the distribution.
16  * 3. The name of the author may not be used to endorse or promote products
17  * derived from this software without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONRIBUTORS ``AS IS'' AND ANY EXPRESS
20  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
21  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
22  * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
24  * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
27  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
28  * OF SUCH DAMAGE.
29  *
30  * This file is part of the EVE platform.
31  */
32 
33 /**
34  * \file
35  * \brief Header file for TLS interface.
36  *
37  * \author SE, Jetro AS
38  */ /******************************************************************/
39 
40 #include <net/uiplib.h>
41 
42 #include <mbedtls/config.h>
43 #include <mbedtls/net.h>
44 #include <mbedtls/ssl.h>
45 #include <mbedtls/entropy.h>
46 #include <mbedtls/x509_crt.h>
47 #include <mbedtls/ctr_drbg.h>
48 #include <mbedtls/debug.h>
49 
50 #include <core/datapump.h>
51 
52 /**
53  * \defgroup tls mbedtls library interface
54  * \ingroup net
55  * \{
56  *
57  */
58 
59 #ifndef TLS_RSA
60  #define TLS_RSA 1 //!< Set to 0 to slightly reduce ram and flash footprint if RSA is not needed (i.e. PSK-only)
61 #endif
62 
63 #define DEBUG_ERR 1
64 #define DEBUG_WARN 2
65 #define DEBUG_MSG 3
66 #define DEBUG_ALL 5
67 #define TLS_DEBUG_LEVEL DEBUG_MSG
68 
69 #if TLS_DEBUG_LEVEL == 0
70  #define TLS_PRINTD(level, FORMAT, args...) do {} while (0)
71 #else
72  #define TLS_PRINTD(level, FORMAT, args...) \
73  do { if ((level) <= TLS_DEBUG_LEVEL) printf("[TLS] " FORMAT, ##args); } while(0)
74 #endif
75 
76 #define TLS_CHECK_RET(ret, string) \
77  do { if (ret) { TLS_PRINTD(1, string " FAILED with error %s0x%04X\n", \
78  ((ret)<0) ? "-" : "", ((ret) < 0) ? -(ret) : (ret)); goto exit; } } while(0)
79 
80 struct md_heap_t;
81 
82 extern const struct md_heap_t TlsRxBufferHeap; //!< User-defined TLS Rx heap
83 extern const struct md_heap_t TlsTxBufferHeap; //!< User-defined TLS Tx heap
84 extern const struct md_heap_t TlsHeap; //!< User-defined TLS processing
85 
86 /** TLS instance (client or server) configuration. */
87 typedef struct tls_cfg_t
88 {
89  int Role; /*!< MBEDTLS_SSL_IS_CLIENT or MBEDTLS_SSL_IS_SERVER */
90  mbedtls_entropy_context Entropy; /*!< Internal: entropy context */
91  mbedtls_ctr_drbg_context Drbg; /*!< Indernal: DRBG context */
92  mbedtls_ssl_config Conf; /*!< Internal: SSL configuration */
93 #if TLS_RSA == 1
94  mbedtls_x509_crt X509; /*!< Internal: X509 certificate */
95  mbedtls_pk_context Pk; /*!< Internal: Private key */
96 #endif /* TLS_RSA */
97 } tls_cfg_t;
98 
99 /** Wrapper type for sockets. */
100 typedef struct
101 {
102  int Fd; /*!< The underlying file descriptor */
103 } tls_net_ctx_t;
104 
105 /** TLS connection instance. */
106 typedef struct tls_conn_t
107 {
108  mbedtls_ssl_context Ssl; /*!< SSL context */
109  tls_net_ctx_t Net; /*!< Network context */
110 } tls_conn_t;
111 
112 /** TLS datapump */
113 typedef struct tls_pump_t
114 {
115  tls_conn_t Conn; /*!< TLS connection */
116  struct datapump_t Pump; /*!< Datapump */
117 } tls_pump_t;
118 
119 /**
120  * Initializes TLS subsystem
121  */
122 void TlsPlatformInit(void);
123 
124 /**
125  * Initializes a TLS instance configuration (RSA variant)
126  *
127  * @param TlsCfg Pointer to an uninitialized TLS configuration
128  * @param Role MBEDTLS_SSL_IS_CLIENT or MBEDTLS_SSL_IS_SERVER
129  * @param Cert Pointer to an RSA sertificate
130  * @param CertLen RSA certificate length
131  * @param Key Pointer to an RSA private key
132  * @param KeyLen RSA private key length
133  * @return 0 if finished successfully, otherwise an mbedtls error code.
134  */
135 int TlsCfgInitRsa(tls_cfg_t* TlsCfg, int Role,
136  const uint8_t* Cert, int CertLen,
137  const uint8_t* Key, int KeyLen);
138 
139 /**
140  * Initializes a TLS instance configuration (PSK variant)
141  *
142  * @param TlsCfg Pointer to an uninitialized TLS configuration
143  * @param Role MBEDTLS_SSL_IS_CLIENT or MBEDTLS_SSL_IS_SERVER
144  * @param Psk Pointer to a PSK key
145  * @param PskLen PSK key length
146  * @param Identity Pointer to PSK identity
147  * @param IdentityLen PSK identity length
148  * @return 0 if finished successfully, otherwise an mbedtls error code.
149  */
150 int TlsCfgInitPsk(tls_cfg_t* TlsCfg, int Role,
151  const uint8_t* Psk, int PskLen,
152  const uint8_t* Identity, int IdentityLen);
153 
154 /**
155  * Free a previously allocated TLS instance configuration
156  *
157  * @param TlsCfg Pointer to a previously allocated TLS configuration
158  */
159 void TlsCfgFree(tls_cfg_t* TlsCfg);
160 
161 /**
162  * Initializes a TLS connection
163  *
164  * @param TlsConn Pointer to an uninitialized TLS connection instance
165  * @param TlsCfg Pointer to a TLS instance configuration
166  * @return 0 if finished successfully, otherwise an mbedtls error code.
167  */
168 int TlsConnectionInit(tls_conn_t* TlsConn, tls_cfg_t* TlsCfg);
169 
170 /**
171  * Initializes a TLS connection and starts data pump tasks
172  *
173  * @param TlsPump Pointer to an uninitialized TLS data pump instance
174  * @param TlsCfg Pointer to a TLS instance configuration
175  * @param PumpCfg Constant pointer to a data pump configuration
176  * @return 0 if finished successfully, otherwise an mbedtls error code.
177  */
178 int TlsPumpInit(tls_pump_t* TlsPump, tls_cfg_t* TlsCfg, const struct datapump_cfg_t *PumpCfg);
179 
180 /**
181  * Deallocates resources, associated with datapump.
182  *
183  * @param TlsPump Pointer to a data pump instance
184  */
185 void TlsPumpFree(tls_pump_t* TlsPump);
186 
187 /**
188  * Performes a TLS handshake.
189  *
190  * The function uses sockets directly and thus must be called from a task.
191  *
192  * @param TlsConn Pointer to a TLS connection instance
193  * @param Timeout Timeout (in system ticks)
194  * @return 0 if finished successfully, otherwise an mbedtls error code.
195  */
196 int TlsHandshake(tls_conn_t* TlsConn, uint32_t Timeout);
197 
198 /**
199  * Terminates an ongoing TLS connection.
200  *
201  * The function uses sockets directly and thus must be called from a task
202  *
203  * @param TlsConn Pointer to a TLS connection instance
204  */
205 void TlsConnectionClose(tls_conn_t* TlsConn);
206 
207 /**
208  * Deallocates resources, associated with a TlsConn.
209  *
210  * @param TlsConn Pointer to a TLS connection instance
211  */
212 void TlsConnectionFree(tls_conn_t* TlsConn);
213 
214 /**
215  * Receives data from a TLS connection.
216  *
217  * The function uses sockets directly and thus must be called from a task.
218  * It has same semantic as a BSD socket recv() function and can return less
219  * bytes than it was requested.
220  *
221  * @param TlsConn Pointer to a TLS connection instance
222  * @param Buffer A buffer to put data into
223  * @param Length Length of the buffer (max number of bytes to read)
224  * @param Timeout Timeout (in system ticks)
225  * @return A positive value shows length of the data read,
226  * 0 indicates end-of-stream condition,
227  * and an (mbedtls) negative code indicates an error.
228  */
229 int TlsReceive(tls_conn_t* TlsConn, uint8_t* Buffer, size_t Length, uint32_t Timeout);
230 
231 /**
232  * Sends data to a TLS connection.
233  *
234  * The function uses sockets directly and thus must be called from a task.
235  * It has same semantic as a BSD socket send() function and can send less
236  * bytes than it was requested.
237  *
238  * @param TlsConn Pointer to a TLS connection instance
239  * @param Buffer A buffer containing the data to send
240  * @param Length Length of the buffer (max number of bytes to send)
241  * @param Timeout Timeout (in system ticks)
242  * @return A positive value shows length of the data sent,
243  * 0 indicates end-of-stream condition,
244  * and an (mbedtls) negative code indicates an error.
245  */
246 int TlsSend(tls_conn_t* TlsConn, const uint8_t* Buffer, size_t Length, uint32_t Timeout);
247 
248 /*extern*/ struct md_heap_t;
249 extern const struct md_heap_t TlsHeap;
250 extern const struct md_heap_t TlsRxBufferHeap;
251 extern const struct md_heap_t TlsTxBufferHeap;
252 
253 enum tls_swap_direction_t
254 {
255  TLS_SWAP_IN,
256  TLS_SWAP_OUT,
257 };
258 
259 enum tls_swap_target_t
260 {
261  TLS_SWAP_RX,
262  TLS_SWAP_TX,
263 };
264 
265 struct tls_swap_params_t
266 {
267  enum tls_swap_direction_t Dir;
268  enum tls_swap_target_t Target;
269  void *Data;
270  uint32_t Pos;
271  uint32_t Size;
272 };
273 
274 extern bool TlsSwapCallback(const struct tls_swap_params_t *Params);
275 
276 bool TlsRxBufferHeapSwapOut(const struct md_heap_t *RxHeap, uint32_t Pos, const uint8_t **DataPtr, uint32_t Size);
277 bool TlsRxBufferHeapSwapIn(const struct md_heap_t *RxHeap, uint8_t **DataPtr, uint32_t Pos, uint32_t Size);
278 bool TlsTxBufferHeapSwapOut(const struct md_heap_t *TxHeap, uint32_t Pos, const uint8_t **DataPtr, uint32_t Size);
279 bool TlsTxBufferHeapSwapIn(const struct md_heap_t *TxHeap, uint8_t **DataPtr, uint32_t Pos, uint32_t Size);
280 
281 /* XXX: heuristic */
282 #ifndef TLS_HEAP_AUX_NUM_ENTRIES
283  #define TLS_HEAP_AUX_NUM_ENTRIES(NumRsaConfigs, NumPskConfigs, NumSockets) \
284  (MAX(80, ((NumPskConfigs) * 7 + (NumRsaConfigs) * 30)) + 16 * (NumSockets))
285 #endif /* TLS_HEAP_AUX_NUM_ENTRIES */
286 
287 /* XXX: heuristic */
288 #ifndef TLS_HEAP_AUX_RAM_BUFFER_SIZE
289  #define TLS_HEAP_AUX_RAM_BUFFER_SIZE(NumRsaConfigs, NumPskConfigs, NumSockets) \
290  (512 + 1600 + 1000 * (NumPskConfigs) + 3600 * (NumRsaConfigs) + 2200 * (NumSockets))
291 #endif /* TLS_HEAP_AUX_RAM_BUFFER_SIZE */
292 
293 #define TLS_HEAP_NUM_ENTRIES(NumRsaConfigs, NumPskConfigs, NumSockets) \
294  ((NumSockets) + 4)
295 
296 #define TLS_HEAP_RAM_BUFFER_SIZE(NumRsaConfigs, NumPskConfigs, NumSockets) \
297  ((NumSockets) * (1348 + 4) + 4)
298 
299 #define TLS_HEAP_TINY_RAM_BUFFER_SIZE(NumRsaConfigs, NumPskConfigs, NumSockets) \
300  ((NumSockets) * 4 + 1348 + 4)
301 
302 #define TLS_HEAP_EXT_RAM_SIZE(NumSockets) \
303  ((NumSockets) * 1348)
304 
305 #define TLS_HEAP_AUX_IMPL(NumRsaConfigs, NumPskConfigs, NumSockets) \
306  static struct md_descriptor_t TlsHeapEntries[TLS_HEAP_AUX_NUM_ENTRIES(NumRsaConfigs, NumPskConfigs, NumSockets)]; \
307  static uint8_t TlsHeapRamBuffer[TLS_HEAP_AUX_RAM_BUFFER_SIZE(NumRsaConfigs, NumPskConfigs, NumSockets)];\
308  static struct md_state_t TlsHeapState; \
309  const struct md_heap_t TlsHeap; \
310  static void TlsHeapCtor(void) __attribute__((constructor)); \
311  static void TlsHeapCtor(void) \
312  { \
313  MemInit(&TlsHeap); \
314  } \
315  const struct md_heap_t TlsHeap = \
316  { \
317  .Entries = TlsHeapEntries, \
318  .NumEntries = TLS_HEAP_AUX_NUM_ENTRIES(NumRsaConfigs, NumPskConfigs, NumSockets), \
319  .RamBuffer = TlsHeapRamBuffer, \
320  .RamBufferSize = TLS_HEAP_AUX_RAM_BUFFER_SIZE(NumRsaConfigs, NumPskConfigs, NumSockets), \
321  .State = &TlsHeapState, \
322  .ExtRamSize = 0, \
323  .SwapOut = NULL, \
324  .SwapIn = NULL, \
325  }
326 
327 #define TLS_HEAP_IMPL(NumRsaConfigs, NumPskConfigs, NumSockets, Direction) \
328  static struct md_descriptor_t Tls ## Direction ## BufferHeapEntries[TLS_HEAP_NUM_ENTRIES(NumRsaConfigs, NumPskConfigs, NumSockets)]; \
329  static uint8_t Tls ## Direction ## BufferHeapRamBuffer[TLS_HEAP_RAM_BUFFER_SIZE(NumRsaConfigs, NumPskConfigs, NumSockets)]; \
330  static struct md_state_t Tls ## Direction ## BufferHeapState; \
331  const struct md_heap_t Tls ## Direction ## BufferHeap; \
332  static void Tls ## Direction ## BufferHeapCtor(void) __attribute__((constructor)); \
333  static void Tls ## Direction ## BufferHeapCtor(void) \
334  { \
335  MemInit(&Tls ## Direction ## BufferHeap); \
336  } \
337  const struct md_heap_t Tls ## Direction ## BufferHeap = \
338  { \
339  .Entries = Tls ## Direction ## BufferHeapEntries, \
340  .NumEntries = TLS_HEAP_NUM_ENTRIES(NumRsaConfigs, NumPskConfigs, NumSockets), \
341  .RamBuffer = Tls ## Direction ## BufferHeapRamBuffer, \
342  .RamBufferSize = TLS_HEAP_RAM_BUFFER_SIZE(NumRsaConfigs, NumPskConfigs, NumSockets), \
343  .State = &Tls ## Direction ## BufferHeapState, \
344  .ExtRamSize = 0, \
345  .SwapOut = NULL, \
346  .SwapIn = NULL, \
347  }
348 #define TLS_HEAP(NumRsaConfigs, NumPskConfigs, NumSockets) \
349  TLS_HEAP_IMPL(NumRsaConfigs, NumPskConfigs, NumSockets, Rx); \
350  TLS_HEAP_IMPL(NumRsaConfigs, NumPskConfigs, NumSockets, Tx); \
351  TLS_HEAP_AUX_IMPL(NumRsaConfigs, NumPskConfigs, NumSockets)
352 
353 #define TLS_TINY_HEAP_IMPL(NumRsaConfigs, NumPskConfigs, NumSockets, Direction) \
354  static struct md_descriptor_t Tls ## Direction ## BufferHeapEntries[TLS_HEAP_NUM_ENTRIES(NumRsaConfigs, NumPskConfigs, NumSockets)]; \
355  static uint8_t Tls ## Direction ## BufferHeapRamBuffer[TLS_HEAP_TINY_RAM_BUFFER_SIZE(NumRsaConfigs, NumPskConfigs, NumSockets)]; \
356  static struct md_state_t Tls ## Direction ## BufferHeapState; \
357  const struct md_heap_t Tls ## Direction ## BufferHeap; \
358  static void Tls ## Direction ## BufferHeapCtor(void) __attribute__((constructor)); \
359  static void Tls ## Direction ## BufferHeapCtor(void) \
360  { \
361  MemInit(&Tls ## Direction ## BufferHeap); \
362  } \
363  const struct md_heap_t Tls ## Direction ## BufferHeap = \
364  { \
365  .Entries = Tls ## Direction ## BufferHeapEntries, \
366  .NumEntries = TLS_HEAP_NUM_ENTRIES(NumRsaConfigs, NumPskConfigs, NumSockets), \
367  .RamBuffer = Tls ## Direction ## BufferHeapRamBuffer, \
368  .RamBufferSize = TLS_HEAP_TINY_RAM_BUFFER_SIZE(NumRsaConfigs, NumPskConfigs, NumSockets), \
369  .State = &Tls ## Direction ## BufferHeapState, \
370  .ExtRamSize = TLS_HEAP_EXT_RAM_SIZE(NumSockets), \
371  .SwapOut = Tls ## Direction ## BufferHeapSwapOut, \
372  .SwapIn = Tls ## Direction ## BufferHeapSwapIn, \
373  }
374 #define TLS_TINY_HEAP(NumRsaConfigs, NumPskConfigs, NumSockets) \
375  TLS_TINY_HEAP_IMPL(NumRsaConfigs, NumPskConfigs, NumSockets, Rx); \
376  TLS_TINY_HEAP_IMPL(NumRsaConfigs, NumPskConfigs, NumSockets, Tx); \
377  TLS_HEAP_AUX_IMPL(NumRsaConfigs, NumPskConfigs, NumSockets)
378 
379 /** \} */
380 
381 #endif // EVE_TLS_H_INCLUDED
Definition: tls.h:87
int TlsConnectionInit(tls_conn_t *TlsConn, tls_cfg_t *TlsCfg)
tls_net_ctx_t Net
Definition: tls.h:109
void TlsConnectionFree(tls_conn_t *TlsConn)
int TlsReceive(tls_conn_t *TlsConn, uint8_t *Buffer, size_t Length, uint32_t Timeout)
mbedtls_x509_crt X509
Definition: tls.h:94
int TlsSend(tls_conn_t *TlsConn, const uint8_t *Buffer, size_t Length, uint32_t Timeout)
const struct datapump_cfg_t * PumpCfg
Definition: datapump.h:97
void TlsPlatformInit(void)
tls_conn_t Conn
Definition: tls.h:115
int TlsHandshake(tls_conn_t *TlsConn, uint32_t Timeout)
void TlsPumpFree(tls_pump_t *TlsPump)
mbedtls_entropy_context Entropy
Definition: tls.h:90
mbedtls_ctr_drbg_context Drbg
Definition: tls.h:91
Header file for datapump interface.
int TlsPumpInit(tls_pump_t *TlsPump, tls_cfg_t *TlsCfg, const struct datapump_cfg_t *PumpCfg)
struct tls_cfg_t tls_cfg_t
struct tls_conn_t tls_conn_t
mbedtls_ssl_context Ssl
Definition: tls.h:108
const struct md_heap_t TlsTxBufferHeap
User-defined TLS Tx heap.
Definition: tls.h:251
int TlsCfgInitPsk(tls_cfg_t *TlsCfg, int Role, const uint8_t *Psk, int PskLen, const uint8_t *Identity, int IdentityLen)
void TlsCfgFree(tls_cfg_t *TlsCfg)
int Fd
Definition: tls.h:102
void TlsConnectionClose(tls_conn_t *TlsConn)
int TlsCfgInitRsa(tls_cfg_t *TlsCfg, int Role, const uint8_t *Cert, int CertLen, const uint8_t *Key, int KeyLen)
const struct md_heap_t TlsHeap
User-defined TLS processing.
Definition: tls.h:249
mbedtls_pk_context Pk
Definition: tls.h:95
int Role
Definition: tls.h:89
struct tls_pump_t tls_pump_t
const struct md_heap_t TlsRxBufferHeap
User-defined TLS Rx heap.
Definition: tls.h:250
mbedtls_ssl_config Conf
Definition: tls.h:92