tls_mbedtls.c revision 82fc5fd4
1/*
2 * Copyright (c) 2018 Cisco and/or its affiliates.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at:
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#include <mbedtls/ssl.h>
17#include <mbedtls/certs.h>
18#include <mbedtls/entropy.h>
19#include <mbedtls/ctr_drbg.h>
20#include <mbedtls/timing.h>
21#include <mbedtls/debug.h>
22#include <vnet/plugin/plugin.h>
23#include <vpp/app/version.h>
24#include <vnet/tls/tls.h>
25
26#define TLS_USE_OUR_MEM_FUNCS	0
27
28typedef struct tls_ctx_mbedtls_
29{
30  tls_ctx_t ctx;			/**< First */
31  u32 mbedtls_ctx_index;
32  mbedtls_ssl_context ssl;
33  mbedtls_ssl_config conf;
34  mbedtls_x509_crt srvcert;
35  mbedtls_pk_context pkey;
36} mbedtls_ctx_t;
37
38typedef struct mbedtls_main_
39{
40  mbedtls_ctx_t ***ctx_pool;
41  mbedtls_ctr_drbg_context *ctr_drbgs;
42  mbedtls_entropy_context *entropy_pools;
43  mbedtls_x509_crt cacert;
44  u8 **rx_bufs;
45  u8 **tx_bufs;
46} mbedtls_main_t;
47
48static mbedtls_main_t mbedtls_main;
49
50#if TLS_USE_OUR_MEM_FUNCS
51#include <mbedtls/platform.h>
52
53void *
54mbedtls_calloc_fn (size_t n, size_t size)
55{
56  void *ptr;
57  ptr = clib_mem_alloc (n * size);
58  clib_memset (ptr, 0, sizeof (*ptr));
59  return ptr;
60}
61
62void
63mbedtls_free_fn (void *ptr)
64{
65  if (ptr)
66    clib_mem_free (ptr);
67}
68#endif
69
70static u32
71mbedtls_ctx_alloc (void)
72{
73  u8 thread_index = vlib_get_thread_index ();
74  mbedtls_main_t *tm = &mbedtls_main;
75  mbedtls_ctx_t **ctx;
76
77  pool_get (tm->ctx_pool[thread_index], ctx);
78  if (!(*ctx))
79    *ctx = clib_mem_alloc (sizeof (mbedtls_ctx_t));
80
81  clib_memset (*ctx, 0, sizeof (mbedtls_ctx_t));
82  (*ctx)->ctx.c_thread_index = thread_index;
83  (*ctx)->ctx.tls_ctx_engine = CRYPTO_ENGINE_MBEDTLS;
84  (*ctx)->mbedtls_ctx_index = ctx - tm->ctx_pool[thread_index];
85  return ((*ctx)->mbedtls_ctx_index);
86}
87
88static void
89mbedtls_ctx_free (tls_ctx_t * ctx)
90{
91  mbedtls_ctx_t *mc = (mbedtls_ctx_t *) ctx;
92
93  if (mc->ssl.state == MBEDTLS_SSL_HANDSHAKE_OVER && !ctx->is_passive_close)
94    mbedtls_ssl_close_notify (&mc->ssl);
95  if (mc->ssl.conf->endpoint == MBEDTLS_SSL_IS_SERVER)
96    {
97      mbedtls_x509_crt_free (&mc->srvcert);
98      mbedtls_pk_free (&mc->pkey);
99    }
100  mbedtls_ssl_free (&mc->ssl);
101  mbedtls_ssl_config_free (&mc->conf);
102
103  vec_free (ctx->srv_hostname);
104  pool_put_index (mbedtls_main.ctx_pool[ctx->c_thread_index],
105		  mc->mbedtls_ctx_index);
106}
107
108static tls_ctx_t *
109mbedtls_ctx_get (u32 ctx_index)
110{
111  mbedtls_ctx_t **ctx;
112  ctx = pool_elt_at_index (mbedtls_main.ctx_pool[vlib_get_thread_index ()],
113			   ctx_index);
114  return &(*ctx)->ctx;
115}
116
117static tls_ctx_t *
118mbedtls_ctx_get_w_thread (u32 ctx_index, u8 thread_index)
119{
120  mbedtls_ctx_t **ctx;
121  ctx = pool_elt_at_index (mbedtls_main.ctx_pool[thread_index], ctx_index);
122  return &(*ctx)->ctx;
123}
124
125static int
126tls_init_ctr_seed_drbgs (void)
127{
128  u32 thread_index = vlib_get_thread_index ();
129  mbedtls_main_t *tm = &mbedtls_main;
130  u8 *pers;
131  int rv;
132  pers = format (0, "vpp thread %u", thread_index);
133
134  mbedtls_entropy_init (&tm->entropy_pools[thread_index]);
135  mbedtls_ctr_drbg_init (&mbedtls_main.ctr_drbgs[thread_index]);
136  if ((rv = mbedtls_ctr_drbg_seed (&tm->ctr_drbgs[thread_index],
137				   mbedtls_entropy_func,
138				   &tm->entropy_pools[thread_index],
139				   (const unsigned char *) pers,
140				   vec_len (pers))) != 0)
141    {
142      vec_free (pers);
143      TLS_DBG (1, " failed\n  ! mbedtls_ctr_drbg_seed returned %d\n", rv);
144      return -1;
145    }
146  vec_free (pers);
147  return 0;
148}
149
150mbedtls_ctr_drbg_context *
151tls_get_ctr_drbg ()
152{
153  u8 thread_index = vlib_get_thread_index ();
154  if (PREDICT_FALSE (!mbedtls_main.ctr_drbgs[thread_index].f_entropy))
155    tls_init_ctr_seed_drbgs ();
156  return &mbedtls_main.ctr_drbgs[thread_index];
157}
158
159static int
160tls_net_send (void *ctx_indexp, const unsigned char *buf, size_t len)
161{
162  session_t *tls_session;
163  uword ctx_index;
164  tls_ctx_t *ctx;
165  int rv;
166
167  ctx_index = pointer_to_uword (ctx_indexp);
168  ctx = mbedtls_ctx_get (ctx_index);
169  tls_session = session_get_from_handle (ctx->tls_session_handle);
170  rv = svm_fifo_enqueue (tls_session->tx_fifo, len, buf);
171  if (rv < 0)
172    return MBEDTLS_ERR_SSL_WANT_WRITE;
173  tls_add_vpp_q_tx_evt (tls_session);
174  return rv;
175}
176
177static int
178tls_net_recv (void *ctx_indexp, unsigned char *buf, size_t len)
179{
180  session_t *tls_session;
181  uword ctx_index;
182  tls_ctx_t *ctx;
183  int rv;
184
185  ctx_index = pointer_to_uword (ctx_indexp);
186  ctx = mbedtls_ctx_get (ctx_index);
187  tls_session = session_get_from_handle (ctx->tls_session_handle);
188  rv = svm_fifo_dequeue (tls_session->rx_fifo, len, buf);
189  return (rv < 0) ? 0 : rv;
190}
191
192static void
193mbedtls_debug (void *ctx, int level, const char *file, int line,
194	       const char *str)
195{
196  ((void) level);
197  fprintf ((FILE *) ctx, "%s:%04d: %s", file, line, str);
198  fflush ((FILE *) ctx);
199}
200
201static int
202mbedtls_ctx_init_client (tls_ctx_t * ctx)
203{
204  mbedtls_ctx_t *mc = (mbedtls_ctx_t *) ctx;
205  mbedtls_main_t *mm = &mbedtls_main;
206  void *ctx_ptr;
207  int rv;
208
209  /*
210   * 1. Setup SSL
211   */
212  mbedtls_ssl_init (&mc->ssl);
213  mbedtls_ssl_config_init (&mc->conf);
214  if ((rv = mbedtls_ssl_config_defaults (&mc->conf, MBEDTLS_SSL_IS_CLIENT,
215					 MBEDTLS_SSL_TRANSPORT_STREAM,
216					 MBEDTLS_SSL_PRESET_DEFAULT)) != 0)
217    {
218      TLS_DBG (1, "failed\n  ! mbedtls_ssl_config_defaults returned %d\n\n",
219	       rv);
220      return -1;
221    }
222
223  mbedtls_ssl_conf_authmode (&mc->conf, MBEDTLS_SSL_VERIFY_OPTIONAL);
224  mbedtls_ssl_conf_ca_chain (&mc->conf, &mm->cacert, NULL);
225  mbedtls_ssl_conf_rng (&mc->conf, mbedtls_ctr_drbg_random,
226			tls_get_ctr_drbg ());
227  mbedtls_ssl_conf_dbg (&mc->conf, mbedtls_debug, stdout);
228
229  if ((rv = mbedtls_ssl_setup (&mc->ssl, &mc->conf)) != 0)
230    {
231      TLS_DBG (1, "failed\n  ! mbedtls_ssl_setup returned %d\n", rv);
232      return -1;
233    }
234
235  if ((rv = mbedtls_ssl_set_hostname (&mc->ssl,
236				      (const char *) ctx->srv_hostname)) != 0)
237    {
238      TLS_DBG (1, "failed\n  ! mbedtls_ssl_set_hostname returned %d\n", rv);
239      return -1;
240    }
241
242  ctx_ptr = uword_to_pointer (mc->mbedtls_ctx_index, void *);
243  mbedtls_ssl_set_bio (&mc->ssl, ctx_ptr, tls_net_send, tls_net_recv, NULL);
244  mbedtls_debug_set_threshold (TLS_DEBUG_LEVEL_CLIENT);
245
246  /*
247   * 2. Do the first 2 steps in the handshake.
248   */
249  TLS_DBG (1, "Initiating handshake for [%u]%u", ctx->c_thread_index,
250	   mc->mbedtls_ctx_index);
251  while (mc->ssl.state != MBEDTLS_SSL_HANDSHAKE_OVER)
252    {
253      rv = mbedtls_ssl_handshake_step (&mc->ssl);
254      if (rv != 0)
255	break;
256    }
257  TLS_DBG (2, "tls state for [%u]%u is %u", ctx->c_thread_index,
258	   mc->mbedtls_ctx_index, mc->ssl.state);
259  return 0;
260}
261
262static int
263mbedtls_start_listen (tls_ctx_t * lctx)
264{
265  return 0;
266}
267
268static int
269mbedtls_stop_listen (tls_ctx_t * lctx)
270{
271  return 0;
272}
273
274static int
275mbedtls_ctx_init_server (tls_ctx_t * ctx)
276{
277  mbedtls_ctx_t *mc = (mbedtls_ctx_t *) ctx;
278  mbedtls_main_t *mm = &mbedtls_main;
279  app_cert_key_pair_t *ckpair;
280  void *ctx_ptr;
281  int rv;
282
283  mbedtls_ssl_init (&mc->ssl);
284  mbedtls_ssl_config_init (&mc->conf);
285  mbedtls_x509_crt_init (&mc->srvcert);
286  mbedtls_pk_init (&mc->pkey);
287
288  /*
289   * 1. Cert
290   */
291  ckpair = app_cert_key_pair_get_if_valid (ctx->ckpair_index);
292  if (!ckpair)
293    return -1;
294
295  if (!ckpair->cert || !ckpair->key)
296    {
297      TLS_DBG (1, " failed\n  ! tls cert and/or key not configured %d",
298	       ctx->parent_app_wrk_index);
299      return -1;
300    }
301
302  rv = mbedtls_x509_crt_parse (&mc->srvcert,
303			       (const unsigned char *) ckpair->cert,
304			       vec_len (ckpair->cert));
305  if (rv != 0)
306    {
307      TLS_DBG (1, " failed\n  !  mbedtls_x509_crt_parse returned %d", rv);
308      goto exit;
309    }
310
311  rv = mbedtls_pk_parse_key (&mc->pkey,
312			     (const unsigned char *) ckpair->key,
313			     vec_len (ckpair->key), NULL, 0);
314  if (rv != 0)
315    {
316      TLS_DBG (1, " failed\n  !  mbedtls_pk_parse_key returned %d", rv);
317      goto exit;
318    }
319
320  /*
321   * 2. SSL context config
322   */
323  if ((rv = mbedtls_ssl_config_defaults (&mc->conf, MBEDTLS_SSL_IS_SERVER,
324					 MBEDTLS_SSL_TRANSPORT_STREAM,
325					 MBEDTLS_SSL_PRESET_DEFAULT)) != 0)
326    {
327      TLS_DBG (1, " failed\n  ! mbedtls_ssl_config_defaults returned %d", rv);
328      goto exit;
329    }
330
331  mbedtls_ssl_conf_rng (&mc->conf, mbedtls_ctr_drbg_random,
332			tls_get_ctr_drbg ());
333  mbedtls_ssl_conf_dbg (&mc->conf, mbedtls_debug, stdout);
334
335  /* TODO CACHE
336     mbedtls_ssl_conf_session_cache( &ctx->conf, &cache,
337     mbedtls_ssl_cache_get,
338     mbedtls_ssl_cache_set );
339   */
340
341  mbedtls_ssl_conf_ca_chain (&mc->conf, &mm->cacert, NULL);
342  if ((rv = mbedtls_ssl_conf_own_cert (&mc->conf, &mc->srvcert, &mc->pkey))
343      != 0)
344    {
345      TLS_DBG (1, " failed\n  ! mbedtls_ssl_conf_own_cert returned %d", rv);
346      goto exit;
347    }
348
349  if ((rv = mbedtls_ssl_setup (&mc->ssl, &mc->conf)) != 0)
350    {
351      TLS_DBG (1, " failed\n  ! mbedtls_ssl_setup returned %d", rv);
352      goto exit;
353    }
354
355  mbedtls_ssl_session_reset (&mc->ssl);
356  ctx_ptr = uword_to_pointer (mc->mbedtls_ctx_index, void *);
357  mbedtls_ssl_set_bio (&mc->ssl, ctx_ptr, tls_net_send, tls_net_recv, NULL);
358  mbedtls_debug_set_threshold (TLS_DEBUG_LEVEL_SERVER);
359
360  /*
361   * 3. Start handshake state machine
362   */
363  TLS_DBG (1, "Initiating handshake for [%u]%u", ctx->c_thread_index,
364	   mc->mbedtls_ctx_index);
365  while (mc->ssl.state != MBEDTLS_SSL_HANDSHAKE_OVER)
366    {
367      rv = mbedtls_ssl_handshake_step (&mc->ssl);
368      if (rv != 0)
369	break;
370    }
371
372  TLS_DBG (2, "tls state for [%u]%u is %u", ctx->c_thread_index,
373	   mc->mbedtls_ctx_index, mc->ssl.state);
374  return 0;
375
376exit:
377  return -1;
378}
379
380static int
381mbedtls_ctx_handshake_rx (tls_ctx_t * ctx)
382{
383  mbedtls_ctx_t *mc = (mbedtls_ctx_t *) ctx;
384  u32 flags;
385  int rv;
386  while (mc->ssl.state != MBEDTLS_SSL_HANDSHAKE_OVER)
387    {
388      rv = mbedtls_ssl_handshake_step (&mc->ssl);
389      if (rv != 0)
390	break;
391    }
392  TLS_DBG (2, "tls state for %u is %u", mc->mbedtls_ctx_index, mc->ssl.state);
393
394  if (mc->ssl.state != MBEDTLS_SSL_HANDSHAKE_OVER)
395    return 0;
396
397  /*
398   * Handshake complete
399   */
400  if (mc->ssl.conf->endpoint == MBEDTLS_SSL_IS_CLIENT)
401    {
402      /*
403       * Verify server certificate
404       */
405      if ((flags = mbedtls_ssl_get_verify_result (&mc->ssl)) != 0)
406	{
407	  char buf[512];
408	  TLS_DBG (1, " failed\n");
409	  mbedtls_x509_crt_verify_info (buf, sizeof (buf), "  ! ", flags);
410	  TLS_DBG (1, "%s\n", buf);
411
412	  /*
413	   * Presence of hostname enforces strict certificate verification
414	   */
415	  if (ctx->srv_hostname)
416	    {
417	      tls_notify_app_connected (ctx, /* is failed */ 0);
418	      return -1;
419	    }
420	}
421      tls_notify_app_connected (ctx, /* is failed */ 0);
422    }
423  else
424    {
425      tls_notify_app_accept (ctx);
426    }
427
428  TLS_DBG (1, "Handshake for %u complete. TLS cipher is %x",
429	   mc->mbedtls_ctx_index, mc->ssl.session->ciphersuite);
430  return 0;
431}
432
433static int
434mbedtls_ctx_write (tls_ctx_t * ctx, session_t * app_session)
435{
436  mbedtls_ctx_t *mc = (mbedtls_ctx_t *) ctx;
437  u8 thread_index = ctx->c_thread_index;
438  mbedtls_main_t *mm = &mbedtls_main;
439  u32 enq_max, deq_max, deq_now;
440  session_t *tls_session;
441  int wrote;
442
443  ASSERT (mc->ssl.state == MBEDTLS_SSL_HANDSHAKE_OVER);
444
445  deq_max = svm_fifo_max_dequeue_cons (app_session->tx_fifo);
446  if (!deq_max)
447    return 0;
448
449  tls_session = session_get_from_handle (ctx->tls_session_handle);
450  enq_max = svm_fifo_max_enqueue_prod (tls_session->tx_fifo);
451  deq_now = clib_min (deq_max, TLS_CHUNK_SIZE);
452
453  if (PREDICT_FALSE (enq_max == 0))
454    {
455      tls_add_vpp_q_builtin_tx_evt (app_session);
456      return 0;
457    }
458
459  vec_validate (mm->tx_bufs[thread_index], deq_now);
460  svm_fifo_peek (app_session->tx_fifo, 0, deq_now, mm->tx_bufs[thread_index]);
461
462  wrote = mbedtls_ssl_write (&mc->ssl, mm->tx_bufs[thread_index], deq_now);
463  if (wrote <= 0)
464    {
465      tls_add_vpp_q_builtin_tx_evt (app_session);
466      return 0;
467    }
468
469  svm_fifo_dequeue_drop (app_session->tx_fifo, wrote);
470  vec_reset_length (mm->tx_bufs[thread_index]);
471  tls_add_vpp_q_tx_evt (tls_session);
472
473  if (deq_now < deq_max)
474    tls_add_vpp_q_builtin_tx_evt (app_session);
475
476  return 0;
477}
478
479static int
480mbedtls_ctx_read (tls_ctx_t * ctx, session_t * tls_session)
481{
482  mbedtls_ctx_t *mc = (mbedtls_ctx_t *) ctx;
483  mbedtls_main_t *mm = &mbedtls_main;
484  u8 thread_index = ctx->c_thread_index;
485  u32 deq_max, enq_max, enq_now;
486  session_t *app_session;
487  int read, enq;
488
489  if (PREDICT_FALSE (mc->ssl.state != MBEDTLS_SSL_HANDSHAKE_OVER))
490    {
491      mbedtls_ctx_handshake_rx (ctx);
492      return 0;
493    }
494
495  deq_max = svm_fifo_max_dequeue_cons (tls_session->rx_fifo);
496  if (!deq_max)
497    return 0;
498
499  app_session = session_get_from_handle (ctx->app_session_handle);
500  enq_max = svm_fifo_max_enqueue_prod (app_session->rx_fifo);
501  enq_now = clib_min (enq_max, TLS_CHUNK_SIZE);
502
503  if (PREDICT_FALSE (enq_now == 0))
504    {
505      tls_add_vpp_q_builtin_rx_evt (tls_session);
506      return 0;
507    }
508
509  vec_validate (mm->rx_bufs[thread_index], enq_now);
510  read = mbedtls_ssl_read (&mc->ssl, mm->rx_bufs[thread_index], enq_now);
511  if (read <= 0)
512    {
513      tls_add_vpp_q_builtin_rx_evt (tls_session);
514      return 0;
515    }
516
517  enq = svm_fifo_enqueue (app_session->rx_fifo, read,
518			  mm->rx_bufs[thread_index]);
519  ASSERT (enq == read);
520  vec_reset_length (mm->rx_bufs[thread_index]);
521
522  if (svm_fifo_max_dequeue_cons (tls_session->rx_fifo))
523    tls_add_vpp_q_builtin_rx_evt (tls_session);
524
525  if (enq > 0)
526    tls_notify_app_enqueue (ctx, app_session);
527
528  return enq;
529}
530
531static u8
532mbedtls_handshake_is_over (tls_ctx_t * ctx)
533{
534  mbedtls_ctx_t *mc = (mbedtls_ctx_t *) ctx;
535  return (mc->ssl.state == MBEDTLS_SSL_HANDSHAKE_OVER);
536}
537
538static int
539mbedtls_transport_close (tls_ctx_t * ctx)
540{
541  if (!mbedtls_handshake_is_over (ctx))
542    {
543      session_close (session_get_from_handle (ctx->tls_session_handle));
544      return 0;
545    }
546  session_transport_closing_notify (&ctx->connection);
547  return 0;
548}
549
550static int
551mbedtls_app_close (tls_ctx_t * ctx)
552{
553  tls_disconnect_transport (ctx);
554  session_transport_delete_notify (&ctx->connection);
555  mbedtls_ctx_free (ctx);
556  return 0;
557}
558
559const static tls_engine_vft_t mbedtls_engine = {
560  .ctx_alloc = mbedtls_ctx_alloc,
561  .ctx_free = mbedtls_ctx_free,
562  .ctx_get = mbedtls_ctx_get,
563  .ctx_get_w_thread = mbedtls_ctx_get_w_thread,
564  .ctx_init_server = mbedtls_ctx_init_server,
565  .ctx_init_client = mbedtls_ctx_init_client,
566  .ctx_write = mbedtls_ctx_write,
567  .ctx_read = mbedtls_ctx_read,
568  .ctx_handshake_is_over = mbedtls_handshake_is_over,
569  .ctx_start_listen = mbedtls_start_listen,
570  .ctx_stop_listen = mbedtls_stop_listen,
571  .ctx_transport_close = mbedtls_transport_close,
572  .ctx_app_close = mbedtls_app_close,
573};
574
575int
576tls_init_mem (void)
577{
578#if TLS_USE_OUR_MEM_FUNCS
579  mbedtls_platform_set_calloc_free (mbedtls_calloc_fn, mbedtls_free_fn);
580#endif
581  return 0;
582}
583
584static int
585tls_init_ctr_drbgs_and_entropy (u32 num_threads)
586{
587  mbedtls_main_t *mm = &mbedtls_main;
588  int i;
589
590  vec_validate (mm->ctr_drbgs, num_threads - 1);
591  vec_validate (mm->entropy_pools, num_threads - 1);
592  for (i = 0; i < num_threads; i++)
593    mm->ctr_drbgs[i].f_entropy = 0;
594
595  return 0;
596}
597
598int
599tls_init_ca_chain (void)
600{
601  mbedtls_main_t *mm = &mbedtls_main;
602  tls_main_t *tm = vnet_tls_get_main ();
603  int rv;
604
605  if (access (tm->ca_cert_path, F_OK | R_OK) == -1)
606    {
607      clib_warning ("Could not initialize TLS CA certificates");
608      return -1;
609    }
610
611  mbedtls_x509_crt_init (&mm->cacert);
612  rv = mbedtls_x509_crt_parse_file (&mm->cacert, tm->ca_cert_path);
613  if (rv < 0)
614    {
615      clib_warning ("Couldn't parse system CA certificates: -0x%x", -rv);
616    }
617  if (tm->use_test_cert_in_ca)
618    {
619      rv = mbedtls_x509_crt_parse (&mm->cacert,
620				   (const unsigned char *) test_srv_crt_rsa,
621				   test_srv_crt_rsa_len);
622      if (rv < 0)
623	{
624	  clib_warning ("Couldn't parse test certificate: -0x%x", -rv);
625	  return -1;
626	}
627    }
628  return (rv < 0 ? -1 : 0);
629}
630
631static clib_error_t *
632tls_mbedtls_init (vlib_main_t * vm)
633{
634  vlib_thread_main_t *vtm = vlib_get_thread_main ();
635  mbedtls_main_t *mm = &mbedtls_main;
636  u32 num_threads;
637
638  num_threads = 1 /* main thread */  + vtm->n_threads;
639
640  if (tls_init_ca_chain ())
641    {
642      clib_warning ("failed to initialize TLS CA chain");
643      return 0;
644    }
645  if (tls_init_mem ())
646    {
647      clib_warning ("failed to initialize mem");
648      return 0;
649    }
650  if (tls_init_ctr_drbgs_and_entropy (num_threads))
651    {
652      clib_warning ("failed to initialize entropy and random generators");
653      return 0;
654    }
655
656  vec_validate (mm->ctx_pool, num_threads - 1);
657  vec_validate (mm->rx_bufs, num_threads - 1);
658  vec_validate (mm->tx_bufs, num_threads - 1);
659
660  tls_register_engine (&mbedtls_engine, CRYPTO_ENGINE_MBEDTLS);
661  return 0;
662}
663
664/* *INDENT-OFF* */
665VLIB_INIT_FUNCTION (tls_mbedtls_init) =
666{
667  .runs_after = VLIB_INITS("tls_init"),
668};
669/* *INDENT-ON* */
670
671/* *INDENT-OFF* */
672VLIB_PLUGIN_REGISTER () = {
673    .version = VPP_BUILD_VER,
674    .description = "Transport Layer Security (TLS) Engine, Mbedtls Based",
675};
676/* *INDENT-ON* */
677
678/*
679 * fd.io coding-style-patch-verification: ON
680 *
681 * Local Variables:
682 * eval: (c-set-style "gnu")
683 * End:
684 */
685