FD.io VPP  v21.10.1-2-g0a485f517
Vector Packet Processing
tls_picotls.c
Go to the documentation of this file.
1 #include <math.h>
2 
3 #include <tlspicotls/certs.h>
6 
8 
9 #define MAX_QUEUE 12000
10 #define PTLS_MAX_PLAINTEXT_RECORD_SIZE 16384
11 
12 static ptls_key_exchange_algorithm_t *default_key_exchange[] = {
13 #ifdef PTLS_OPENSSL_HAVE_X25519
14  &ptls_openssl_x25519,
15 #endif
16 #ifdef PTLS_OPENSSL_HAVE_SECP256R1
17  &ptls_openssl_secp256r1,
18 #endif
19 #ifdef PTLS_OPENSSL_HAVE_SECP384R1
20  &ptls_openssl_secp384r1,
21 #endif
22 #ifdef PTLS_OPENSSL_HAVE_SECP521R1
23  &ptls_openssl_secp521r1
24 #endif
25 };
26 
27 static u32
29 {
30  u8 thread_id = vlib_get_thread_index ();
33 
34  pool_get (pm->ctx_pool[thread_id], ctx);
35  if (!(*ctx))
36  *ctx = clib_mem_alloc (sizeof (picotls_ctx_t));
37 
38  clib_memset (*ctx, 0, sizeof (picotls_ctx_t));
39  (*ctx)->ctx.c_thread_index = thread_id;
40  (*ctx)->ctx.tls_ctx_engine = CRYPTO_ENGINE_PICOTLS;
41  (*ctx)->ctx.app_session_handle = SESSION_INVALID_HANDLE;
42  (*ctx)->ptls_ctx_idx = ctx - pm->ctx_pool[thread_id];
43  return (*ctx)->ptls_ctx_idx;
44 }
45 
46 static void
48 {
49  picotls_ctx_t *ptls_ctx = (picotls_ctx_t *) ctx;
50  vec_free (ptls_ctx->rx_content);
51  ptls_free (ptls_ctx->tls);
52  pool_put_index (picotls_main.ctx_pool[ctx->c_thread_index],
53  ptls_ctx->ptls_ctx_idx);
54 }
55 
56 static u32
58 {
60  picotls_listen_ctx_t *ptls_lctx;
61 
62  pool_get (pm->lctx_pool, ptls_lctx);
63 
64  clib_memset (ptls_lctx, 0, sizeof (picotls_listen_ctx_t));
65  ptls_lctx->ptls_lctx_index = ptls_lctx - pm->lctx_pool;
66  return ptls_lctx->ptls_lctx_index;
67 }
68 
69 static void
71 {
73 }
74 
75 tls_ctx_t *
76 picotls_ctx_get (u32 ctx_index)
77 {
79  ctx =
81  ctx_index);
82  return &(*ctx)->ctx;
83 }
84 
86 picotls_lctx_get (u32 lctx_index)
87 {
88  return pool_elt_at_index (picotls_main.lctx_pool, lctx_index);
89 }
90 
91 static u8
93 {
94  picotls_ctx_t *ptls_ctx = (picotls_ctx_t *) ctx;
95  assert (ptls_ctx->tls);
96  return ptls_handshake_is_complete (ptls_ctx->tls);
97 }
98 
99 static int
101  session_t * tls_session, ptls_buffer_t * buf)
102 {
103  u32 enq_max, enq_now;
104  svm_fifo_t *f;
105  int write, buf_left;
106 
107  if (buf->off <= 0)
108  return 0;
109 
110  f = tls_session->tx_fifo;
111  buf_left = buf->off;
112  enq_max = svm_fifo_max_enqueue_prod (f);
113  if (!enq_max)
114  return 0;
115 
116  enq_now = clib_min (svm_fifo_max_write_chunk (f), enq_max);
117  enq_now = clib_min (enq_now, buf_left);
118  write = svm_fifo_enqueue (f, enq_now, buf->base);
119  buf_left -= write;
120  tls_add_vpp_q_tx_evt (tls_session);
121  return write;
122 }
123 
124 static int
126 {
127  picotls_listen_ctx_t *ptls_lctx;
128  ptls_context_t *ptls_ctx;
129  u32 ptls_lctx_idx;
130  app_cert_key_pair_t *ckpair;
131 
133  if (!ckpair || !ckpair->cert || !ckpair->key)
134  {
135  TLS_DBG (1, "tls cert and/or key not configured %d",
136  lctx->parent_app_wrk_index);
137  return -1;
138  }
139 
140  ptls_lctx_idx = picotls_listen_ctx_alloc ();
141  ptls_lctx = picotls_lctx_get (ptls_lctx_idx);
142  ptls_ctx = malloc (sizeof (ptls_context_t));
143  ptls_lctx->ptls_ctx = ptls_ctx;
144 
145  memset (ptls_ctx, 0, sizeof (ptls_context_t));
146  ptls_ctx->update_open_count = NULL;
147 
148  /*
149  * Process certificate & private key.
150  */
151  load_bio_certificate_chain (ptls_ctx, (char *) ckpair->cert);
152  load_bio_private_key (ptls_ctx, (char *) ckpair->key);
153 
154  /* setup protocol related functions */
155  ptls_ctx->key_exchanges = default_key_exchange;
156  ptls_ctx->random_bytes = ptls_openssl_random_bytes;
157  ptls_ctx->cipher_suites = ptls_vpp_crypto_cipher_suites;
158  ptls_ctx->get_time = &ptls_get_time;
159 
160  lctx->tls_ssl_ctx = ptls_lctx_idx;
161 
162  return 0;
163 }
164 
165 static int
167 {
168  u32 ptls_lctx_index;
169  picotls_listen_ctx_t *ptls_lctx;
170 
171  ptls_lctx_index = lctx->tls_ssl_ctx;
172  ptls_lctx = picotls_lctx_get (ptls_lctx_index);
173 
174  picotls_listen_ctx_free (ptls_lctx);
175 
176  return 0;
177 }
178 
179 static void
181 {
182  session_free (session_get (ctx->c_s_index, ctx->c_thread_index));
183  ctx->no_app_session = 1;
184  ctx->c_s_index = SESSION_INVALID_INDEX;
186 }
187 
188 static void
190 {
192  session_transport_closed_notify (&ctx->connection);
193 }
194 
195 static int
197 {
199  {
201  return 0;
202  }
203  session_transport_closing_notify (&ctx->connection);
204  return 0;
205 }
206 
207 static int
209 {
210  session_t *app_session;
211 
212  app_session = session_get_from_handle (ctx->app_session_handle);
213  if (!svm_fifo_max_dequeue_cons (app_session->tx_fifo))
215  else
216  ctx->app_closed = 1;
217 
218  return 0;
219 }
220 
221 static inline int
223 {
224  int rv = PTLS_ERROR_IN_PROGRESS, write = 0, i = 0, read = 0, len;
225  svm_fifo_t *tcp_rx_fifo = tcp_session->rx_fifo;
226  ptls_buffer_t *buf = &ptls_ctx->read_buffer;
227  const int n_segs = 2, max_len = 16384;
228  ptls_t *tls = ptls_ctx->tls;
229  svm_fifo_seg_t fs[n_segs];
230  uword deq_now;
231 
232  ptls_buffer_init (buf, "", 0);
233 
234  len = svm_fifo_segments (tcp_rx_fifo, 0, fs, n_segs, max_len);
235  if (len <= 0)
236  return 0;
237 
238  while (read < len && i < n_segs)
239  {
240  deq_now = fs[i].len;
241  rv = ptls_handshake (tls, buf, fs[i].data, &deq_now, NULL);
242 
243  write += picotls_try_handshake_write (ptls_ctx, tcp_session, buf);
244  read += deq_now;
245 
246  if (!(rv == 0 || rv == PTLS_ERROR_IN_PROGRESS))
247  {
248  clib_error ("unexpected error %u", rv);
249  break;
250  }
251 
252  if (!rv)
253  break;
254 
255  if (deq_now < fs[i].len)
256  {
257  fs[i].data += deq_now;
258  fs[i].len -= deq_now;
259  }
260  else
261  i++;
262  }
263 
264  if (read)
265  svm_fifo_dequeue_drop (tcp_rx_fifo, read);
266 
267  ptls_buffer_dispose (buf);
268 
269  return write;
270 }
271 
272 static inline int
273 ptls_copy_buf_to_fs (ptls_buffer_t *buf, u32 to_copy, svm_fifo_seg_t *fs,
274  u32 *fs_idx, u32 max_fs)
275 {
276  u32 idx = *fs_idx;
277 
278  while (to_copy)
279  {
280  if (fs[idx].len <= to_copy)
281  {
282  clib_memcpy_fast (fs[idx].data, buf->base + (buf->off - to_copy),
283  fs[idx].len);
284  to_copy -= fs[idx].len;
285  idx += 1;
286  /* no more space in the app's rx fifo */
287  if (idx == max_fs)
288  break;
289  }
290  else
291  {
292  clib_memcpy_fast (fs[idx].data, buf->base + (buf->off - to_copy),
293  to_copy);
294  fs[idx].len -= to_copy;
295  fs[idx].data += to_copy;
296  to_copy = 0;
297  }
298  }
299 
300  *fs_idx = idx;
301 
302  return to_copy;
303 }
304 
305 static u32
307  svm_fifo_t *tcp_rx_fifo)
308 {
309  u32 ai = 0, thread_index, min_buf_len, to_copy, left, wrote = 0;
310  ptls_buffer_t *buf = &ptls_ctx->read_buffer;
311  int ret, i = 0, read = 0, tcp_len, n_fs_app;
312  const int n_segs = 4, max_len = 1 << 16;
313  svm_fifo_seg_t tcp_fs[n_segs], app_fs[n_segs];
315  uword deq_now;
316  u8 is_nocopy;
317 
318  thread_index = ptls_ctx->ctx.c_thread_index;
319 
320  n_fs_app = svm_fifo_provision_chunks (app_rx_fifo, app_fs, n_segs, max_len);
321  if (n_fs_app <= 0)
322  return 0;
323 
324  tcp_len = svm_fifo_segments (tcp_rx_fifo, 0, tcp_fs, n_segs, max_len);
325  if (tcp_len <= 0)
326  return 0;
327 
328  if (ptls_ctx->read_buffer_offset)
329  {
330  to_copy = buf->off - ptls_ctx->read_buffer_offset;
331  left = ptls_copy_buf_to_fs (buf, to_copy, app_fs, &ai, n_fs_app);
332  wrote += to_copy - left;
333  if (left)
334  {
335  ptls_ctx->read_buffer_offset = buf->off - left;
336  goto do_checks;
337  }
338  ptls_ctx->read_buffer_offset = 0;
339  }
340 
341  while (ai < n_fs_app && read < tcp_len)
342  {
343  deq_now = clib_min (tcp_fs[i].len, tcp_len - read);
344  min_buf_len = deq_now + (16 << 10);
345  is_nocopy = app_fs[ai].len < min_buf_len ? 0 : 1;
346  if (is_nocopy)
347  {
348  ptls_buffer_init (buf, app_fs[ai].data, app_fs[ai].len);
349  ret = ptls_receive (ptls_ctx->tls, buf, tcp_fs[i].data, &deq_now);
350  assert (ret == 0 || ret == PTLS_ERROR_IN_PROGRESS);
351 
352  wrote += buf->off;
353  if (buf->off == app_fs[ai].len)
354  {
355  ai++;
356  }
357  else
358  {
359  app_fs[ai].len -= buf->off;
360  app_fs[ai].data += buf->off;
361  }
362  }
363  else
364  {
365  vec_validate (pm->rx_bufs[thread_index], min_buf_len);
366  ptls_buffer_init (buf, pm->rx_bufs[thread_index], min_buf_len);
367  ret = ptls_receive (ptls_ctx->tls, buf, tcp_fs[i].data, &deq_now);
368  assert (ret == 0 || ret == PTLS_ERROR_IN_PROGRESS);
369 
370  left = ptls_copy_buf_to_fs (buf, buf->off, app_fs, &ai, n_fs_app);
371  if (!left)
372  {
373  ptls_ctx->read_buffer_offset = 0;
374  wrote += buf->off;
375  }
376  else
377  {
378  ptls_ctx->read_buffer_offset = buf->off - left;
379  wrote += ptls_ctx->read_buffer_offset;
380  }
381  }
382 
383  assert (deq_now <= tcp_fs[i].len);
384  read += deq_now;
385  if (deq_now < tcp_fs[i].len)
386  {
387  tcp_fs[i].data += deq_now;
388  tcp_fs[i].len -= deq_now;
389  }
390  else
391  i++;
392  }
393 
394 do_checks:
395 
396  if (read)
397  {
398  svm_fifo_dequeue_drop (tcp_rx_fifo, read);
399  if (svm_fifo_needs_deq_ntf (tcp_rx_fifo, read))
400  {
401  svm_fifo_clear_deq_ntf (tcp_rx_fifo);
403  }
404  }
405 
406  if (wrote)
407  svm_fifo_enqueue_nocopy (app_rx_fifo, wrote);
408 
409  return wrote;
410 }
411 
412 static inline int
414 {
415  picotls_ctx_t *ptls_ctx = (picotls_ctx_t *) ctx;
416  svm_fifo_t *tcp_rx_fifo;
417  session_t *app_session;
418  int wrote;
419 
420  if (PREDICT_FALSE (!ptls_handshake_is_complete (ptls_ctx->tls)))
421  {
422  picotls_do_handshake (ptls_ctx, tcp_session);
424  {
425  if (ptls_is_server (ptls_ctx->tls))
426  {
428  {
429  ctx->c_s_index = SESSION_INVALID_INDEX;
431  return -1;
432  }
433  }
434  else
435  {
436  tls_notify_app_connected (ctx, SESSION_E_NONE);
437  }
438  }
439 
440  if (!svm_fifo_max_dequeue (tcp_session->rx_fifo))
441  return 0;
442  }
443 
444  tcp_rx_fifo = tcp_session->rx_fifo;
445  app_session = session_get_from_handle (ctx->app_session_handle);
446  wrote = ptls_tcp_to_app_write (ptls_ctx, app_session->rx_fifo, tcp_rx_fifo);
447 
448  if (wrote && app_session->session_state >= SESSION_STATE_READY)
449  tls_notify_app_enqueue (ctx, app_session);
450 
451  if (ptls_ctx->read_buffer_offset || svm_fifo_max_dequeue (tcp_rx_fifo))
452  tls_add_vpp_q_builtin_rx_evt (tcp_session);
453 
454  return wrote;
455 }
456 
457 static inline u32
458 ptls_compute_deq_len (picotls_ctx_t *ptls_ctx, u32 dst_chunk, u32 src_chunk,
459  u32 dst_space, u8 *is_nocopy)
460 {
461  int record_overhead = ptls_get_record_overhead (ptls_ctx->tls);
462  int num_records;
463  u32 deq_len, total_overhead;
464 
465  if (dst_chunk >= clib_min (8192, src_chunk + record_overhead))
466  {
467  *is_nocopy = 1;
468  deq_len = clib_min (src_chunk, dst_chunk);
469  num_records = ceil ((f64) deq_len / PTLS_MAX_PLAINTEXT_RECORD_SIZE);
470  total_overhead = num_records * record_overhead;
471  if (deq_len + total_overhead > dst_chunk)
472  deq_len = dst_chunk - total_overhead;
473  }
474  else
475  {
476  deq_len = clib_min (src_chunk, dst_space);
477  num_records = ceil ((f64) deq_len / PTLS_MAX_PLAINTEXT_RECORD_SIZE);
478  total_overhead = num_records * record_overhead;
479  if (deq_len + total_overhead > dst_space)
480  deq_len = dst_space - total_overhead;
481  }
482 
483  return deq_len;
484 }
485 
486 static u32
488  svm_fifo_t *tcp_tx_fifo, u32 max_len)
489 {
490  u32 wrote = 0, max_enq, thread_index, app_buf_len, left, ti = 0;
491  int read = 0, rv, i = 0, len, n_tcp_segs = 4, deq_len;
492  const int n_app_segs = 2, min_chunk = 2048;
493  svm_fifo_seg_t app_fs[n_app_segs], tcp_fs[n_tcp_segs];
495  ptls_buffer_t _buf, *buf = &_buf;
496  svm_fifo_t *app_tx_fifo;
497  u8 is_nocopy, *app_buf;
498  u32 first_chunk_len;
499 
500  thread_index = app_session->thread_index;
501  app_tx_fifo = app_session->tx_fifo;
502 
503  len = svm_fifo_segments (app_tx_fifo, 0, app_fs, n_app_segs, max_len);
504  if (len <= 0)
505  return 0;
506 
507  n_tcp_segs = svm_fifo_provision_chunks (tcp_tx_fifo, tcp_fs, n_tcp_segs,
508  1000 + max_len);
509  if (n_tcp_segs <= 0)
510  return 0;
511 
512  while ((left = len - read) && ti < n_tcp_segs)
513  {
514  /* If we wrote something and are left with few bytes, postpone write
515  * as we may be able to encrypt a bigger chunk next time */
516  if (wrote && left < min_chunk)
517  break;
518 
519  /* Avoid short records if possible */
520  if (app_fs[i].len < min_chunk && min_chunk < left)
521  {
522  app_buf_len = app_fs[i].len + app_fs[i + 1].len;
523  app_buf = pm->rx_bufs[thread_index];
524  vec_validate (pm->rx_bufs[thread_index], app_buf_len);
525  clib_memcpy_fast (pm->rx_bufs[thread_index], app_fs[i].data,
526  app_fs[i].len);
527  clib_memcpy_fast (pm->rx_bufs[thread_index] + app_fs[i].len,
528  app_fs[i + 1].data, app_buf_len - app_fs[i].len);
529  first_chunk_len = app_fs[i].len;
530  i += 1;
531  }
532  else
533  {
534  app_buf = app_fs[i].data;
535  app_buf_len = app_fs[i].len;
536  first_chunk_len = 0;
537  }
538 
539  is_nocopy = 0;
540  max_enq = tcp_fs[ti].len;
541  max_enq += ti < (n_tcp_segs - 1) ? tcp_fs[ti + 1].len : 0;
542 
543  deq_len = ptls_compute_deq_len (ptls_ctx, tcp_fs[ti].len, app_buf_len,
544  max_enq, &is_nocopy);
545  if (is_nocopy)
546  {
547  ptls_buffer_init (buf, tcp_fs[ti].data, tcp_fs[ti].len);
548  rv = ptls_send (ptls_ctx->tls, buf, app_buf, deq_len);
549 
550  assert (rv == 0);
551  wrote += buf->off;
552 
553  tcp_fs[ti].len -= buf->off;
554  tcp_fs[ti].data += buf->off;
555  if (!tcp_fs[ti].len)
556  ti += 1;
557  }
558  else
559  {
560  vec_validate (pm->tx_bufs[thread_index], max_enq);
561  ptls_buffer_init (buf, pm->tx_bufs[thread_index], max_enq);
562  rv = ptls_send (ptls_ctx->tls, buf, app_buf, deq_len);
563 
564  assert (rv == 0);
565  wrote += buf->off;
566 
567  left = ptls_copy_buf_to_fs (buf, buf->off, tcp_fs, &ti, n_tcp_segs);
568  assert (left == 0);
569  }
570 
571  read += deq_len;
572  ASSERT (deq_len >= first_chunk_len);
573 
574  if (deq_len == app_buf_len)
575  {
576  i += 1;
577  }
578  else
579  {
580  app_fs[i].len -= deq_len - first_chunk_len;
581  app_fs[i].data += deq_len - first_chunk_len;
582  }
583  }
584 
585  if (read)
586  {
587  svm_fifo_dequeue_drop (app_tx_fifo, read);
588  if (svm_fifo_needs_deq_ntf (app_tx_fifo, read))
589  session_dequeue_notify (app_session);
590  }
591 
592  if (wrote)
593  {
594  svm_fifo_enqueue_nocopy (tcp_tx_fifo, wrote);
595  if (svm_fifo_set_event (tcp_tx_fifo))
597  }
598 
599  return wrote;
600 }
601 
602 static inline int
605 {
606  picotls_ctx_t *ptls_ctx = (picotls_ctx_t *) ctx;
607  u32 deq_max, deq_now, enq_max, enq_buf, wrote = 0;
608  svm_fifo_t *tcp_tx_fifo;
609  session_t *tcp_session;
610 
611  tcp_session = session_get_from_handle (ctx->tls_session_handle);
612  tcp_tx_fifo = tcp_session->tx_fifo;
613 
614  enq_max = svm_fifo_max_enqueue_prod (tcp_tx_fifo);
615  if (enq_max < 2048)
616  goto check_tls_fifo;
617 
618  deq_max = svm_fifo_max_dequeue_cons (app_session->tx_fifo);
619  deq_max = clib_min (deq_max, enq_max);
620  if (!deq_max)
621  goto check_tls_fifo;
622 
623  deq_now = clib_min (deq_max, sp->max_burst_size);
624  wrote = ptls_app_to_tcp_write (ptls_ctx, app_session, tcp_tx_fifo, deq_now);
625 
626 check_tls_fifo:
627 
628  if (ctx->app_closed)
630 
631  /* Deschedule and wait for deq notification if fifo is almost full */
632  enq_buf = clib_min (svm_fifo_size (tcp_tx_fifo) / 2, TLSP_MIN_ENQ_SPACE);
633  if (enq_max < wrote + enq_buf)
634  {
636  transport_connection_deschedule (&ctx->connection);
638  }
639  else
640  /* Request tx reschedule of the app session */
641  app_session->flags |= SESSION_F_CUSTOM_TX;
642 
643  return wrote;
644 }
645 
646 static int
648 {
649  picotls_ctx_t *ptls_ctx = (picotls_ctx_t *) ctx;
650  u32 ptls_lctx_idx = ctx->tls_ssl_ctx;
651  picotls_listen_ctx_t *ptls_lctx;
652 
653  ptls_lctx = picotls_lctx_get (ptls_lctx_idx);
654  ptls_ctx->tls = ptls_new (ptls_lctx->ptls_ctx, 1);
655  if (ptls_ctx->tls == NULL)
656  {
657  TLS_DBG (1, "Failed to initialize ptls_ssl structure");
658  return -1;
659  }
660 
661  ptls_ctx->rx_len = 0;
662  ptls_ctx->rx_offset = 0;
663 
664  return 0;
665 }
666 
667 static int
669 {
670  picotls_ctx_t *ptls_ctx = (picotls_ctx_t *) ctx;
672  ptls_context_t *client_ptls_ctx = pm->client_ptls_ctx;
673  ptls_handshake_properties_t hsprop = { { { { NULL } } } };
674 
675  session_t *tls_session = session_get_from_handle (ctx->tls_session_handle);
676  ptls_buffer_t hs_buf;
677 
678  ptls_ctx->tls = ptls_new (client_ptls_ctx, 0);
679  if (ptls_ctx->tls == NULL)
680  {
681  TLS_DBG (1, "Failed to initialize ptls_ssl structure");
682  return -1;
683  }
684 
685  ptls_ctx->rx_len = 0;
686  ptls_ctx->rx_offset = 0;
687 
688  ptls_buffer_init (&hs_buf, "", 0);
689  if (ptls_handshake (ptls_ctx->tls, &hs_buf, NULL, NULL, &hsprop) !=
690  PTLS_ERROR_IN_PROGRESS)
691  {
692  TLS_DBG (1, "Failed to initialize tls connection");
693  }
694 
695  picotls_try_handshake_write (ptls_ctx, tls_session, &hs_buf);
696 
697  ptls_buffer_dispose (&hs_buf);
698 
699  return 0;
700 }
701 
702 tls_ctx_t *
704 {
705  picotls_ctx_t **ctx;
707  return &(*ctx)->ctx;
708 }
709 
710 int
711 picotls_init_client_ptls_ctx (ptls_context_t **client_ptls_ctx)
712 {
713  *client_ptls_ctx = clib_mem_alloc (sizeof (ptls_context_t));
714  memset (*client_ptls_ctx, 0, sizeof (ptls_context_t));
715 
716  (*client_ptls_ctx)->update_open_count = NULL;
717  (*client_ptls_ctx)->key_exchanges = default_key_exchange;
718  (*client_ptls_ctx)->random_bytes = ptls_openssl_random_bytes;
719  (*client_ptls_ctx)->cipher_suites = ptls_vpp_crypto_cipher_suites;
720  (*client_ptls_ctx)->get_time = &ptls_get_time;
721 
722  return 0;
723 }
724 
727  .ctx_free = picotls_ctx_free,
728  .ctx_get = picotls_ctx_get,
729  .ctx_get_w_thread = picotls_ctx_get_w_thread,
730  .ctx_handshake_is_over = picotls_handshake_is_over,
731  .ctx_start_listen = picotls_start_listen,
732  .ctx_stop_listen = picotls_stop_listen,
733  .ctx_init_server = picotls_ctx_init_server,
734  .ctx_init_client = picotls_ctx_init_client,
735  .ctx_read = picotls_ctx_read,
736  .ctx_write = picotls_ctx_write,
737  .ctx_transport_close = picotls_transport_close,
738  .ctx_app_close = picotls_app_close,
739 };
740 
741 static clib_error_t *
743 {
746  clib_error_t *error = 0;
747  u32 num_threads;
748 
749  num_threads = 1 + vtm->n_threads;
750 
751  vec_validate (pm->ctx_pool, num_threads - 1);
752  vec_validate (pm->rx_bufs, num_threads - 1);
753  vec_validate (pm->tx_bufs, num_threads - 1);
754 
756 
758 
760 
761  return error;
762 }
763 
764 /* *INDENT-OFF* */
766  .runs_after = VLIB_INITS ("tls_init"),
767 };
768 /* *INDENT-ON* */
769 
770 /* *INDENT-OFF* */
772  .version = VPP_BUILD_VER,
773  .description = "Transport Layer Security (TLS) Engine, Picotls Based",
774 };
775 /* *INDENT-ON* */
776 
777 /*
778  * fd.io coding-style-patch-verification: ON
779  *
780  * Local Variables:
781  * eval: (c-set-style "gnu")
782  * End:
783  */
picotls_init_client_ptls_ctx
int picotls_init_client_ptls_ctx(ptls_context_t **client_ptls_ctx)
Definition: tls_picotls.c:711
svm_fifo_set_event
static u8 svm_fifo_set_event(svm_fifo_t *f)
Set fifo event flag.
Definition: svm_fifo.h:733
CRYPTO_ENGINE_PICOTLS
@ CRYPTO_ENGINE_PICOTLS
Definition: application_interface.h:180
svm_fifo_segments
int svm_fifo_segments(svm_fifo_t *f, u32 offset, svm_fifo_seg_t *fs, u32 n_segs, u32 max_bytes)
Get pointers to fifo chunks data in svm_fifo_seg_t array.
Definition: svm_fifo.c:1283
picotls_try_handshake_write
static int picotls_try_handshake_write(picotls_ctx_t *ptls_ctx, session_t *tls_session, ptls_buffer_t *buf)
Definition: tls_picotls.c:100
svm_fifo_size
static u32 svm_fifo_size(svm_fifo_t *f)
Definition: svm_fifo.h:697
thread_index
u32 thread_index
Definition: nat44_ei_hairpinning.c:495
certificate_
Definition: application_interface.h:24
assert
#define assert(x)
Definition: dlmalloc.c:31
tls_ctx_picotls_::read_buffer_offset
int read_buffer_offset
Definition: tls_picotls.h:30
session_dequeue_notify
int session_dequeue_notify(session_t *s)
Definition: session.c:816
picotls_listen_ctx_free
static void picotls_listen_ctx_free(picotls_listen_ctx_t *lctx)
Definition: tls_picotls.c:70
tls_notify_app_connected
int tls_notify_app_connected(tls_ctx_t *ctx, session_error_t err)
Definition: tls.c:212
tls_ctx_picotls_::rx_content
u8 * rx_content
Definition: tls_picotls.h:26
tls_picotls.h
tls_listen_ctx_picotls_::ptls_ctx
ptls_context_t * ptls_ctx
Definition: tls_picotls.h:36
picotls_ctx_init_server
static int picotls_ctx_init_server(tls_ctx_t *ctx)
Definition: tls_picotls.c:647
session_transport_closing_notify
void session_transport_closing_notify(transport_connection_t *tc)
Notification from transport that connection is being closed.
Definition: session.c:1062
f
vlib_frame_t * f
Definition: interface_output.c:1098
pool_elt_at_index
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
Definition: pool.h:549
picotls_do_handshake
static int picotls_do_handshake(picotls_ctx_t *ptls_ctx, session_t *tcp_session)
Definition: tls_picotls.c:222
session_::tx_fifo
svm_fifo_t * tx_fifo
Definition: session_types.h:179
picotls_app_close
static int picotls_app_close(tls_ctx_t *ctx)
Definition: tls_picotls.c:208
svm_fifo_needs_deq_ntf
static u8 svm_fifo_needs_deq_ntf(svm_fifo_t *f, u32 n_last_deq)
Check if fifo needs dequeue notification.
Definition: svm_fifo.h:825
load_bio_certificate_chain
int load_bio_certificate_chain(ptls_context_t *ctx, const char *cert_data)
Definition: certs.c:178
session_
Definition: session_types.h:175
picotls_main_::tx_bufs
u8 ** tx_bufs
Definition: tls_picotls.h:43
svm_fifo_provision_chunks
int svm_fifo_provision_chunks(svm_fifo_t *f, svm_fifo_seg_t *fs, u32 n_segs, u32 len)
Provision and return chunks for number of bytes requested.
Definition: svm_fifo.c:1244
tls_notify_app_accept
int tls_notify_app_accept(tls_ctx_t *ctx)
Definition: tls.c:182
tls_notify_app_enqueue
void tls_notify_app_enqueue(tls_ctx_t *ctx, session_t *app_session)
Definition: tls.c:173
SESSION_INVALID_INDEX
#define SESSION_INVALID_INDEX
Definition: session_types.h:22
SESSION_IO_EVT_RX
@ SESSION_IO_EVT_RX
Definition: session_types.h:328
session_::thread_index
u8 thread_index
Index of the thread that allocated the session.
Definition: session_types.h:194
svm_fifo_seg_::len
u32 len
Definition: svm_fifo.h:55
picotls_main_::client_ptls_ctx
ptls_context_t * client_ptls_ctx
Definition: tls_picotls.h:45
vm
vlib_main_t * vm
X-connect all packets from the HOST to the PHY.
Definition: nat44_ei.c:3047
tls_engine_vft_
Definition: tls.h:108
certificate_::key
u8 * key
Definition: application_interface.h:28
session_transport_closed_notify
void session_transport_closed_notify(transport_connection_t *tc)
Notification from transport that it is closed.
Definition: session.c:1150
picotls_handshake_is_over
static u8 picotls_handshake_is_over(tls_ctx_t *ctx)
Definition: tls_picotls.c:92
load_bio_private_key
int load_bio_private_key(ptls_context_t *ctx, const char *pk_data)
Definition: certs.c:192
clib_memcpy_fast
static_always_inline void * clib_memcpy_fast(void *restrict dst, const void *restrict src, size_t n)
Definition: string.h:92
session_free
void session_free(session_t *s)
Definition: session.c:227
pool_put_index
#define pool_put_index(p, i)
Free pool element with given index.
Definition: pool.h:337
picotls_main
picotls_main_t picotls_main
Definition: tls_picotls.c:7
error
Definition: cJSON.c:88
picotls_ctx_get_w_thread
tls_ctx_t * picotls_ctx_get_w_thread(u32 ctx_index, u8 thread_index)
Definition: tls_picotls.c:703
ptls_vpp_crypto_cipher_suites
ptls_cipher_suite_t * ptls_vpp_crypto_cipher_suites[]
Definition: pico_vpp_crypto.c:342
tls_disconnect_transport
void tls_disconnect_transport(tls_ctx_t *ctx)
Definition: tls.c:30
tls_ctx_picotls_::tls
ptls_t * tls
Definition: tls_picotls.h:25
tls_ctx_picotls_::read_buffer
ptls_buffer_t read_buffer
Definition: tls_picotls.h:29
svm_fifo_t
struct _svm_fifo svm_fifo_t
picotls_ctx_read
static int picotls_ctx_read(tls_ctx_t *ctx, session_t *tcp_session)
Definition: tls_picotls.c:413
ti
u32 ti
Definition: interface_output.c:425
ptls_tcp_to_app_write
static u32 ptls_tcp_to_app_write(picotls_ctx_t *ptls_ctx, svm_fifo_t *app_rx_fifo, svm_fifo_t *tcp_rx_fifo)
Definition: tls_picotls.c:306
TRANSPORT_SND_F_DESCHED
@ TRANSPORT_SND_F_DESCHED
Definition: transport.h:40
svm_fifo_seg_
Definition: svm_fifo.h:52
SVM_FIFO_WANT_DEQ_NOTIF
@ SVM_FIFO_WANT_DEQ_NOTIF
Notify on dequeue.
Definition: svm_fifo.h:35
TLS_DBG
#define TLS_DBG(_lvl, _fmt, _args...)
Definition: tls.h:36
session_::rx_fifo
svm_fifo_t * rx_fifo
Pointers to rx/tx buffers.
Definition: session_types.h:178
math.h
len
u8 len
Definition: ip_types.api:103
tls_add_vpp_q_builtin_rx_evt
int tls_add_vpp_q_builtin_rx_evt(session_t *s)
Definition: tls.c:62
tls_ctx_
Definition: tls.h:59
picotls_ctx_get
tls_ctx_t * picotls_ctx_get(u32 ctx_index)
Definition: tls_picotls.c:76
svm_fifo_clear_deq_ntf
static void svm_fifo_clear_deq_ntf(svm_fifo_t *f)
Clear the want notification flag and set has notification.
Definition: svm_fifo.h:791
tls_ctx_picotls_::ctx
tls_ctx_t ctx
Definition: tls_picotls.h:23
svm_fifo_enqueue_nocopy
void svm_fifo_enqueue_nocopy(svm_fifo_t *f, u32 len)
Advance tail.
Definition: svm_fifo.c:946
picotls_main_::crypto_keys_rw_lock
clib_rwlock_t crypto_keys_rw_lock
Definition: tls_picotls.h:46
PREDICT_FALSE
#define PREDICT_FALSE(x)
Definition: clib.h:124
picotls_transport_close
static int picotls_transport_close(tls_ctx_t *ctx)
Definition: tls_picotls.c:196
vlib_get_thread_index
static_always_inline uword vlib_get_thread_index(void)
Definition: threads.h:187
uword
u64 uword
Definition: types.h:112
picotls_lctx_get
picotls_listen_ctx_t * picotls_lctx_get(u32 lctx_index)
Definition: tls_picotls.c:86
svm_fifo_dequeue_drop
int svm_fifo_dequeue_drop(svm_fifo_t *f, u32 len)
Dequeue and drop bytes from fifo.
Definition: svm_fifo.c:1168
f64
double f64
Definition: types.h:142
tls_ctx_picotls_
Definition: tls_picotls.h:21
svm_fifo_enqueue
int svm_fifo_enqueue(svm_fifo_t *f, u32 len, const u8 *src)
Enqueue data to fifo.
Definition: svm_fifo.c:847
svm_fifo_max_write_chunk
u32 svm_fifo_max_write_chunk(svm_fifo_t *f)
Max contiguous chunk of data that can be written.
Definition: svm_fifo.c:534
pool_get
#define pool_get(P, E)
Allocate an object E from a pool P (unspecified alignment).
Definition: pool.h:255
session_get_from_handle
static session_t * session_get_from_handle(session_handle_t handle)
Definition: session.h:357
vec_validate
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment)
Definition: vec.h:523
SESSION_IO_EVT_TX
@ SESSION_IO_EVT_TX
Definition: session_types.h:329
certs.h
picotls_ctx_alloc
static u32 picotls_ctx_alloc(void)
Definition: tls_picotls.c:28
picotls_listen_ctx_alloc
static u32 picotls_listen_ctx_alloc(void)
Definition: tls_picotls.c:57
clib_min
#define clib_min(x, y)
Definition: clib.h:342
session_get
static session_t * session_get(u32 si, u32 thread_index)
Definition: session.h:337
clib_rwlock_init
static void clib_rwlock_init(clib_rwlock_t *p)
Definition: lock.h:152
picotls_ctx_init_client
static int picotls_ctx_init_client(tls_ctx_t *ctx)
Definition: tls_picotls.c:668
tls_picotls_init
static clib_error_t * tls_picotls_init(vlib_main_t *vm)
Definition: tls_picotls.c:742
ptls_compute_deq_len
static u32 ptls_compute_deq_len(picotls_ctx_t *ptls_ctx, u32 dst_chunk, u32 src_chunk, u32 dst_space, u8 *is_nocopy)
Definition: tls_picotls.c:458
picotls_start_listen
static int picotls_start_listen(tls_ctx_t *lctx)
Definition: tls_picotls.c:125
left
left
Definition: vector_altivec.h:73
transport_send_params_
Definition: transport.h:45
data
u8 data[128]
Definition: ipsec_types.api:95
default_key_exchange
static ptls_key_exchange_algorithm_t * default_key_exchange[]
Definition: tls_picotls.c:12
picotls_ctx_write
static int picotls_ctx_write(tls_ctx_t *ctx, session_t *app_session, transport_send_params_t *sp)
Definition: tls_picotls.c:603
vec_free
#define vec_free(V)
Free vector's memory (no header).
Definition: vec.h:395
picotls_handle_handshake_failure
static void picotls_handle_handshake_failure(tls_ctx_t *ctx)
Definition: tls_picotls.c:180
tls_listen_ctx_picotls_::ptls_lctx_index
u32 ptls_lctx_index
Definition: tls_picotls.h:35
picotls_main_::rx_bufs
u8 ** rx_bufs
Definition: tls_picotls.h:44
TLSP_MIN_ENQ_SPACE
#define TLSP_MIN_ENQ_SPACE
Definition: tls_picotls.h:19
svm_fifo_max_enqueue_prod
static u32 svm_fifo_max_enqueue_prod(svm_fifo_t *f)
Maximum number of bytes that can be enqueued into fifo.
Definition: svm_fifo.h:607
tls_ctx_picotls_::rx_len
int rx_len
Definition: tls_picotls.h:28
ASSERT
#define ASSERT(truth)
Definition: error_bootstrap.h:69
vlib_thread_main_t::n_threads
u32 n_threads
Definition: threads.h:271
buf
u64 buf
Definition: application.c:493
tls_ctx_::ckpair_index
u32 ckpair_index
Definition: tls.h:86
u32
unsigned int u32
Definition: types.h:88
VLIB_INIT_FUNCTION
#define VLIB_INIT_FUNCTION(x)
Definition: init.h:172
vlib_thread_main_t
Definition: threads.h:243
ctx
long ctx[MAX_CONNS]
Definition: main.c:144
tls_listen_ctx_picotls_
Definition: tls_picotls.h:33
tls_ctx_picotls_::rx_offset
int rx_offset
Definition: tls_picotls.h:27
SESSION_INVALID_HANDLE
#define SESSION_INVALID_HANDLE
Definition: session_types.h:23
tls_add_vpp_q_tx_evt
int tls_add_vpp_q_tx_evt(session_t *s)
Definition: tls.c:70
picotls_main_::ctx_pool
picotls_ctx_t *** ctx_pool
Definition: tls_picotls.h:41
clib_memset
clib_memset(h->entries, 0, sizeof(h->entries[0]) *entries)
vlib_main_t
Definition: main.h:102
VLIB_INITS
#define VLIB_INITS(...)
Definition: init.h:352
transport_send_params_::max_burst_size
u32 max_burst_size
Definition: transport.h:59
picotls_main_::lctx_pool
picotls_listen_ctx_t * lctx_pool
Definition: tls_picotls.h:42
u8
unsigned char u8
Definition: types.h:56
clib_error_t
Definition: clib_error.h:21
vlib_init_function_t
clib_error_t *() vlib_init_function_t(struct vlib_main_t *vm)
Definition: init.h:51
tls_engine_vft_::ctx_alloc
u32(* ctx_alloc)(void)
Definition: tls.h:110
clib_error
#define clib_error(format, args...)
Definition: error.h:62
i
int i
Definition: flowhash_template.h:376
transport_send_params_::flags
transport_snd_flags_t flags
Definition: transport.h:62
malloc
void * malloc(size_t size)
Definition: mem.c:33
app_cert_key_pair_get_if_valid
app_cert_key_pair_t * app_cert_key_pair_get_if_valid(u32 index)
Definition: application.c:2016
session_::flags
u32 flags
Session flags.
Definition: session_types.h:197
pico_vpp_crypto.h
rv
int __clib_unused rv
Definition: application.c:491
picotls_stop_listen
static int picotls_stop_listen(tls_ctx_t *lctx)
Definition: tls_picotls.c:166
picotls_engine
const static tls_engine_vft_t picotls_engine
Definition: tls_picotls.c:725
certificate_::cert
u8 * cert
Definition: application_interface.h:29
VLIB_PLUGIN_REGISTER
VLIB_PLUGIN_REGISTER()
ptls_copy_buf_to_fs
static int ptls_copy_buf_to_fs(ptls_buffer_t *buf, u32 to_copy, svm_fifo_seg_t *fs, u32 *fs_idx, u32 max_fs)
Definition: tls_picotls.c:273
tls_register_engine
void tls_register_engine(const tls_engine_vft_t *vft, crypto_engine_type_t type)
Definition: tls.c:1296
picotls_main_
Definition: tls_picotls.h:39
vlib_get_thread_main
static vlib_thread_main_t * vlib_get_thread_main()
Definition: global_funcs.h:56
svm_fifo_max_dequeue_cons
static u32 svm_fifo_max_dequeue_cons(svm_fifo_t *f)
Fifo max bytes to dequeue optimized for consumer.
Definition: svm_fifo.h:487
svm_fifo_add_want_deq_ntf
static void svm_fifo_add_want_deq_ntf(svm_fifo_t *f, u8 ntf_type)
Set specific want notification flag.
Definition: svm_fifo.h:760
session_send_io_evt_to_thread
int session_send_io_evt_to_thread(svm_fifo_t *f, session_evt_type_t evt_type)
Definition: session.c:84
session_::session_state
volatile u8 session_state
State in session layer state machine.
Definition: session_types.h:185
picotls_ctx_free
static void picotls_ctx_free(tls_ctx_t *ctx)
Definition: tls_picotls.c:47
clib_mem_alloc
static void * clib_mem_alloc(uword size)
Definition: mem.h:256
tls_ctx_picotls_::ptls_ctx_idx
u32 ptls_ctx_idx
Definition: tls_picotls.h:24
svm_fifo_seg_::data
u8 * data
Definition: svm_fifo.h:54
picotls_confirm_app_close
static void picotls_confirm_app_close(tls_ctx_t *ctx)
Definition: tls_picotls.c:189
svm_fifo_max_dequeue
static u32 svm_fifo_max_dequeue(svm_fifo_t *f)
Fifo max bytes to dequeue.
Definition: svm_fifo.h:516
ptls_app_to_tcp_write
static u32 ptls_app_to_tcp_write(picotls_ctx_t *ptls_ctx, session_t *app_session, svm_fifo_t *tcp_tx_fifo, u32 max_len)
Definition: tls_picotls.c:487
PTLS_MAX_PLAINTEXT_RECORD_SIZE
#define PTLS_MAX_PLAINTEXT_RECORD_SIZE
Definition: tls_picotls.c:10
transport_connection_deschedule
static void transport_connection_deschedule(transport_connection_t *tc)
Definition: transport.h:215