tls: add openssl engine
[vpp.git] / src / plugins / tlsopenssl / tls_openssl.c
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 <openssl/ssl.h>
17 #include <openssl/conf.h>
18 #include <openssl/err.h>
19 #include <vnet/plugin/plugin.h>
20 #include <vpp/app/version.h>
21 #include <vnet/tls/tls.h>
22
23 typedef struct tls_ctx_openssl_
24 {
25   tls_ctx_t ctx;                        /**< First */
26   u32 openssl_ctx_index;
27   SSL_CTX *ssl_ctx;
28   SSL *ssl;
29   BIO *rbio;
30   BIO *wbio;
31   X509 *srvcert;
32   EVP_PKEY *pkey;
33 } openssl_ctx_t;
34
35 typedef struct openssl_main_
36 {
37   openssl_ctx_t ***ctx_pool;
38   X509_STORE *cert_store;
39 } openssl_main_t;
40
41 static openssl_main_t openssl_main;
42
43 static u32
44 openssl_ctx_alloc (void)
45 {
46   u8 thread_index = vlib_get_thread_index ();
47   openssl_main_t *tm = &openssl_main;
48   openssl_ctx_t **ctx;
49
50   pool_get (tm->ctx_pool[thread_index], ctx);
51   if (!(*ctx))
52     *ctx = clib_mem_alloc (sizeof (openssl_ctx_t));
53
54   memset (*ctx, 0, sizeof (openssl_ctx_t));
55   (*ctx)->ctx.c_thread_index = thread_index;
56   (*ctx)->ctx.tls_ctx_engine = TLS_ENGINE_OPENSSL;
57   (*ctx)->ctx.app_session_handle = SESSION_INVALID_HANDLE;
58   (*ctx)->openssl_ctx_index = ctx - tm->ctx_pool[thread_index];
59   return ((*ctx)->openssl_ctx_index);
60 }
61
62 static void
63 openssl_ctx_free (tls_ctx_t * ctx)
64 {
65   openssl_ctx_t *oc = (openssl_ctx_t *) ctx;
66
67   if (SSL_is_init_finished (oc->ssl) && !ctx->is_passive_close)
68     SSL_shutdown (oc->ssl);
69
70   if (SSL_is_server (oc->ssl))
71     {
72       X509_free (oc->srvcert);
73       EVP_PKEY_free (oc->pkey);
74     }
75   SSL_free (oc->ssl);
76
77   pool_put_index (openssl_main.ctx_pool[ctx->c_thread_index],
78                   oc->openssl_ctx_index);
79 }
80
81 static tls_ctx_t *
82 openssl_ctx_get (u32 ctx_index)
83 {
84   openssl_ctx_t **ctx;
85   ctx = pool_elt_at_index (openssl_main.ctx_pool[vlib_get_thread_index ()],
86                            ctx_index);
87   return &(*ctx)->ctx;
88 }
89
90 static tls_ctx_t *
91 openssl_ctx_get_w_thread (u32 ctx_index, u8 thread_index)
92 {
93   openssl_ctx_t **ctx;
94   ctx = pool_elt_at_index (openssl_main.ctx_pool[thread_index], ctx_index);
95   return &(*ctx)->ctx;
96 }
97
98 static int
99 openssl_try_handshake_read (openssl_ctx_t * oc,
100                             stream_session_t * tls_session)
101 {
102   u32 deq_max, deq_now;
103   svm_fifo_t *f;
104   int wrote, rv;
105
106   f = tls_session->server_rx_fifo;
107   deq_max = svm_fifo_max_dequeue (f);
108   if (!deq_max)
109     return 0;
110
111   deq_now = clib_min (svm_fifo_max_read_chunk (f), deq_max);
112   wrote = BIO_write (oc->wbio, svm_fifo_head (f), deq_now);
113   if (wrote <= 0)
114     return 0;
115
116   svm_fifo_dequeue_drop (f, wrote);
117   if (wrote < deq_max)
118     {
119       deq_now = clib_min (svm_fifo_max_read_chunk (f), deq_max - wrote);
120       rv = BIO_write (oc->wbio, svm_fifo_head (f), deq_now);
121       if (rv > 0)
122         {
123           svm_fifo_dequeue_drop (f, rv);
124           wrote += rv;
125         }
126     }
127   return wrote;
128 }
129
130 static int
131 openssl_try_handshake_write (openssl_ctx_t * oc,
132                              stream_session_t * tls_session)
133 {
134   u32 enq_max, deq_now;
135   svm_fifo_t *f;
136   int read, rv;
137
138   if (BIO_ctrl_pending (oc->rbio) <= 0)
139     return 0;
140
141   f = tls_session->server_tx_fifo;
142   enq_max = svm_fifo_max_enqueue (f);
143   if (!enq_max)
144     return 0;
145
146   deq_now = clib_min (svm_fifo_max_write_chunk (f), enq_max);
147   read = BIO_read (oc->rbio, svm_fifo_tail (f), deq_now);
148   if (read <= 0)
149     return 0;
150
151   svm_fifo_enqueue_nocopy (f, read);
152   tls_add_vpp_q_evt (f, FIFO_EVENT_APP_TX);
153
154   if (read < enq_max)
155     {
156       deq_now = clib_min (svm_fifo_max_write_chunk (f), enq_max - read);
157       rv = BIO_read (oc->rbio, svm_fifo_tail (f), deq_now);
158       if (rv > 0)
159         {
160           svm_fifo_enqueue_nocopy (f, rv);
161           read += rv;
162         }
163     }
164
165   return read;
166 }
167
168 static int
169 openssl_ctx_handshake_rx (tls_ctx_t * ctx, stream_session_t * tls_session)
170 {
171   openssl_ctx_t *oc = (openssl_ctx_t *) ctx;
172   int rv = 0, err;
173   while (SSL_in_init (oc->ssl))
174     {
175       if (!openssl_try_handshake_read (oc, tls_session))
176         break;
177
178       rv = SSL_do_handshake (oc->ssl);
179       err = SSL_get_error (oc->ssl, rv);
180       openssl_try_handshake_write (oc, tls_session);
181       if (err != SSL_ERROR_WANT_WRITE)
182         {
183           if (err == SSL_ERROR_SSL)
184             {
185               char buf[512];
186               ERR_error_string (ERR_get_error (), buf);
187               clib_warning ("Err: %s", buf);
188             }
189           break;
190         }
191     }
192   TLS_DBG (2, "tls state for %u is %s", oc->openssl_ctx_index,
193            SSL_state_string_long (oc->ssl));
194
195   if (SSL_in_init (oc->ssl))
196     return 0;
197
198   /*
199    * Handshake complete
200    */
201   if (!SSL_is_server (oc->ssl))
202     {
203       /*
204        * Verify server certificate
205        */
206       if ((rv = SSL_get_verify_result (oc->ssl)) != X509_V_OK)
207         {
208           TLS_DBG (1, " failed verify: %s\n",
209                    X509_verify_cert_error_string (rv));
210
211           /*
212            * Presence of hostname enforces strict certificate verification
213            */
214           if (ctx->srv_hostname)
215             {
216               tls_notify_app_connected (ctx, /* is failed */ 0);
217               return -1;
218             }
219         }
220       tls_notify_app_connected (ctx, /* is failed */ 0);
221     }
222   else
223     {
224       tls_notify_app_accept (ctx);
225     }
226
227   TLS_DBG (1, "Handshake for %u complete. TLS cipher is %s",
228            oc->openssl_ctx_index, SSL_get_cipher (oc->ssl));
229   return rv;
230 }
231
232 static inline int
233 openssl_ctx_write (tls_ctx_t * ctx, stream_session_t * app_session)
234 {
235   openssl_ctx_t *oc = (openssl_ctx_t *) ctx;
236   int wrote = 0, rv, read, max_buf = 100 * TLS_CHUNK_SIZE, max_space;
237   u32 enq_max, deq_max, deq_now, to_write;
238   stream_session_t *tls_session;
239   svm_fifo_t *f;
240
241   f = app_session->server_tx_fifo;
242   deq_max = svm_fifo_max_dequeue (f);
243   if (!deq_max)
244     goto check_tls_fifo;
245
246   max_space = max_buf - BIO_ctrl_pending (oc->rbio);
247   max_space = (max_space < 0) ? 0 : max_space;
248   deq_now = clib_min (deq_max, (u32) max_space);
249   to_write = clib_min (svm_fifo_max_read_chunk (f), deq_now);
250   wrote = SSL_write (oc->ssl, svm_fifo_head (f), to_write);
251   if (wrote <= 0)
252     {
253       tls_add_vpp_q_evt (app_session->server_tx_fifo, FIFO_EVENT_APP_TX);
254       goto check_tls_fifo;
255     }
256   svm_fifo_dequeue_drop (app_session->server_tx_fifo, wrote);
257   if (wrote < deq_now)
258     {
259       to_write = clib_min (svm_fifo_max_read_chunk (f), deq_now - wrote);
260       rv = SSL_write (oc->ssl, svm_fifo_head (f), to_write);
261       if (rv > 0)
262         {
263           svm_fifo_dequeue_drop (app_session->server_tx_fifo, rv);
264           wrote += rv;
265         }
266     }
267
268   if (deq_now < deq_max)
269     tls_add_vpp_q_evt (app_session->server_tx_fifo, FIFO_EVENT_APP_TX);
270
271 check_tls_fifo:
272
273   if (BIO_ctrl_pending (oc->rbio) <= 0)
274     return wrote;
275
276   tls_session = session_get_from_handle (ctx->tls_session_handle);
277   f = tls_session->server_tx_fifo;
278   enq_max = svm_fifo_max_enqueue (f);
279   if (!enq_max)
280     {
281       tls_add_vpp_q_evt (app_session->server_tx_fifo, FIFO_EVENT_APP_TX);
282       return wrote;
283     }
284
285   deq_now = clib_min (svm_fifo_max_write_chunk (f), enq_max);
286   read = BIO_read (oc->rbio, svm_fifo_tail (f), deq_now);
287   if (read <= 0)
288     {
289       tls_add_vpp_q_evt (app_session->server_tx_fifo, FIFO_EVENT_APP_TX);
290       return wrote;
291     }
292
293   svm_fifo_enqueue_nocopy (f, read);
294   tls_add_vpp_q_evt (f, FIFO_EVENT_APP_TX);
295
296   if (read < enq_max && BIO_ctrl_pending (oc->rbio) > 0)
297     {
298       deq_now = clib_min (svm_fifo_max_write_chunk (f), enq_max - read);
299       read = BIO_read (oc->rbio, svm_fifo_tail (f), deq_now);
300       if (read > 0)
301         svm_fifo_enqueue_nocopy (f, read);
302     }
303
304   if (BIO_ctrl_pending (oc->rbio) > 0)
305     tls_add_vpp_q_evt (app_session->server_tx_fifo, FIFO_EVENT_APP_TX);
306
307   return wrote;
308 }
309
310 static inline int
311 openssl_ctx_read (tls_ctx_t * ctx, stream_session_t * tls_session)
312 {
313   int read, wrote = 0, max_space, max_buf = 100 * TLS_CHUNK_SIZE, rv;
314   openssl_ctx_t *oc = (openssl_ctx_t *) ctx;
315   u32 deq_max, enq_max, deq_now, to_read;
316   stream_session_t *app_session;
317   svm_fifo_t *f;
318
319   if (PREDICT_FALSE (SSL_in_init (oc->ssl)))
320     {
321       openssl_ctx_handshake_rx (ctx, tls_session);
322       return 0;
323     }
324
325   f = tls_session->server_rx_fifo;
326   deq_max = svm_fifo_max_dequeue (f);
327   max_space = max_buf - BIO_ctrl_pending (oc->wbio);
328   max_space = max_space < 0 ? 0 : max_space;
329   deq_now = clib_min (deq_max, max_space);
330   if (!deq_now)
331     goto check_app_fifo;
332
333   to_read = clib_min (svm_fifo_max_read_chunk (f), deq_now);
334   wrote = BIO_write (oc->wbio, svm_fifo_head (f), to_read);
335   if (wrote <= 0)
336     {
337       tls_add_vpp_q_evt (tls_session->server_rx_fifo, FIFO_EVENT_BUILTIN_RX);
338       goto check_app_fifo;
339     }
340   svm_fifo_dequeue_drop (f, wrote);
341   if (wrote < deq_now)
342     {
343       to_read = clib_min (svm_fifo_max_read_chunk (f), deq_now - wrote);
344       rv = BIO_write (oc->wbio, svm_fifo_head (f), to_read);
345       if (rv > 0)
346         {
347           svm_fifo_dequeue_drop (f, rv);
348           wrote += rv;
349         }
350     }
351   if (svm_fifo_max_dequeue (f))
352     tls_add_vpp_q_evt (tls_session->server_rx_fifo, FIFO_EVENT_BUILTIN_RX);
353
354 check_app_fifo:
355
356   if (BIO_ctrl_pending (oc->wbio) <= 0)
357     return wrote;
358
359   app_session = session_get_from_handle (ctx->app_session_handle);
360   f = app_session->server_rx_fifo;
361   enq_max = svm_fifo_max_enqueue (f);
362   if (!enq_max)
363     {
364       tls_add_vpp_q_evt (tls_session->server_rx_fifo, FIFO_EVENT_BUILTIN_RX);
365       return wrote;
366     }
367
368   deq_now = clib_min (svm_fifo_max_write_chunk (f), enq_max);
369   read = SSL_read (oc->ssl, svm_fifo_tail (f), deq_now);
370   if (read <= 0)
371     {
372       tls_add_vpp_q_evt (tls_session->server_rx_fifo, FIFO_EVENT_BUILTIN_RX);
373       return wrote;
374     }
375   svm_fifo_enqueue_nocopy (f, read);
376   if (read < enq_max && BIO_ctrl_pending (oc->wbio) > 0)
377     {
378       deq_now = clib_min (svm_fifo_max_write_chunk (f), enq_max - read);
379       read = SSL_read (oc->ssl, svm_fifo_tail (f), deq_now);
380       if (read > 0)
381         svm_fifo_enqueue_nocopy (f, read);
382     }
383
384   tls_notify_app_enqueue (ctx, app_session);
385   if (BIO_ctrl_pending (oc->wbio) > 0)
386     tls_add_vpp_q_evt (tls_session->server_rx_fifo, FIFO_EVENT_BUILTIN_RX);
387
388   return wrote;
389 }
390
391 static int
392 openssl_ctx_init_client (tls_ctx_t * ctx)
393 {
394   char *ciphers = "ALL:!ADH:!LOW:!EXP:!MD5:!RC4-SHA:!DES-CBC3-SHA:@STRENGTH";
395   long flags = SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_COMPRESSION;
396   openssl_ctx_t *oc = (openssl_ctx_t *) ctx;
397   openssl_main_t *om = &openssl_main;
398   stream_session_t *tls_session;
399   const SSL_METHOD *method;
400   int rv, err;
401
402   method = SSLv23_client_method ();
403   if (method == NULL)
404     {
405       TLS_DBG (1, "SSLv23_method returned null");
406       return -1;
407     }
408
409   oc->ssl_ctx = SSL_CTX_new (method);
410   if (oc->ssl_ctx == NULL)
411     {
412       TLS_DBG (1, "SSL_CTX_new returned null");
413       return -1;
414     }
415
416   SSL_CTX_set_ecdh_auto (oc->ssl_ctx, 1);
417   SSL_CTX_set_mode (oc->ssl_ctx, SSL_MODE_ENABLE_PARTIAL_WRITE);
418   rv = SSL_CTX_set_cipher_list (oc->ssl_ctx, (const char *) ciphers);
419   if (rv != 1)
420     {
421       TLS_DBG (1, "Couldn't set cipher");
422       return -1;
423     }
424
425   SSL_CTX_set_options (oc->ssl_ctx, flags);
426   SSL_CTX_set_cert_store (oc->ssl_ctx, om->cert_store);
427
428   oc->ssl = SSL_new (oc->ssl_ctx);
429   if (oc->ssl == NULL)
430     {
431       TLS_DBG (1, "Couldn't initialize ssl struct");
432       return -1;
433     }
434
435   oc->rbio = BIO_new (BIO_s_mem ());
436   oc->wbio = BIO_new (BIO_s_mem ());
437
438   BIO_set_mem_eof_return (oc->rbio, -1);
439   BIO_set_mem_eof_return (oc->wbio, -1);
440
441   SSL_set_bio (oc->ssl, oc->wbio, oc->rbio);
442   SSL_set_connect_state (oc->ssl);
443
444   rv = SSL_set_tlsext_host_name (oc->ssl, ctx->srv_hostname);
445   if (rv != 1)
446     {
447       TLS_DBG (1, "Couldn't set hostname");
448       return -1;
449     }
450
451   /*
452    * 2. Do the first steps in the handshake.
453    */
454   TLS_DBG (1, "Initiating handshake for [%u]%u", ctx->c_thread_index,
455            oc->openssl_ctx_index);
456
457   tls_session = session_get_from_handle (ctx->tls_session_handle);
458   while (1)
459     {
460       rv = SSL_do_handshake (oc->ssl);
461       err = SSL_get_error (oc->ssl, rv);
462       openssl_try_handshake_write (oc, tls_session);
463       if (err != SSL_ERROR_WANT_WRITE)
464         break;
465     }
466
467   TLS_DBG (2, "tls state for [%u]%u is su", ctx->c_thread_index,
468            oc->openssl_ctx_index, SSL_state_string_long (oc->ssl));
469   return 0;
470 }
471
472 static int
473 openssl_ctx_init_server (tls_ctx_t * ctx)
474 {
475   char *ciphers = "ALL:!ADH:!LOW:!EXP:!MD5:!RC4-SHA:!DES-CBC3-SHA:@STRENGTH";
476   long flags = SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_COMPRESSION;
477   openssl_ctx_t *oc = (openssl_ctx_t *) ctx;
478   stream_session_t *tls_session;
479   const SSL_METHOD *method;
480   application_t *app;
481   int rv, err;
482   BIO *cert_bio;
483
484   app = application_get (ctx->parent_app_index);
485   if (!app->tls_cert || !app->tls_key)
486     {
487       TLS_DBG (1, "tls cert and/or key not configured %d",
488                ctx->parent_app_index);
489       return -1;
490     }
491
492   method = SSLv23_method ();
493   oc->ssl_ctx = SSL_CTX_new (method);
494   if (!oc->ssl_ctx)
495     {
496       clib_warning ("Unable to create SSL context");
497       return -1;
498     }
499
500   SSL_CTX_set_mode (oc->ssl_ctx, SSL_MODE_ENABLE_PARTIAL_WRITE);
501   SSL_CTX_set_options (oc->ssl_ctx, flags);
502   SSL_CTX_set_ecdh_auto (oc->ssl_ctx, 1);
503
504   rv = SSL_CTX_set_cipher_list (oc->ssl_ctx, (const char *) ciphers);
505   if (rv != 1)
506     {
507       TLS_DBG (1, "Couldn't set cipher");
508       return -1;
509     }
510
511   /*
512    * Set the key and cert
513    */
514   cert_bio = BIO_new (BIO_s_mem ());
515   BIO_write (cert_bio, app->tls_cert, vec_len (app->tls_cert));
516   oc->srvcert = PEM_read_bio_X509 (cert_bio, NULL, NULL, NULL);
517   if (!oc->srvcert)
518     {
519       clib_warning ("unable to parse certificate");
520       return -1;
521     }
522   BIO_free (cert_bio);
523   cert_bio = BIO_new (BIO_s_mem ());
524   BIO_write (cert_bio, app->tls_key, vec_len (app->tls_key));
525   oc->pkey = PEM_read_bio_PrivateKey (cert_bio, NULL, NULL, NULL);
526   if (!oc->pkey)
527     {
528       clib_warning ("unable to parse pkey");
529       return -1;
530     }
531
532   BIO_free (cert_bio);
533
534   oc->ssl = SSL_new (oc->ssl_ctx);
535   if (oc->ssl == NULL)
536     {
537       TLS_DBG (1, "Couldn't initialize ssl struct");
538       return -1;
539     }
540
541   oc->rbio = BIO_new (BIO_s_mem ());
542   oc->wbio = BIO_new (BIO_s_mem ());
543
544   BIO_set_mem_eof_return (oc->rbio, -1);
545   BIO_set_mem_eof_return (oc->wbio, -1);
546
547   SSL_set_bio (oc->ssl, oc->wbio, oc->rbio);
548   SSL_set_accept_state (oc->ssl);
549
550   TLS_DBG (1, "Initiating handshake for [%u]%u", ctx->c_thread_index,
551            oc->openssl_ctx_index);
552
553   tls_session = session_get_from_handle (ctx->tls_session_handle);
554   while (1)
555     {
556       rv = SSL_do_handshake (oc->ssl);
557       err = SSL_get_error (oc->ssl, rv);
558       openssl_try_handshake_write (oc, tls_session);
559       if (err != SSL_ERROR_WANT_WRITE)
560         break;
561     }
562
563   TLS_DBG (2, "tls state for [%u]%u is su", ctx->c_thread_index,
564            oc->openssl_ctx_index, SSL_state_string_long (oc->ssl));
565   return 0;
566 }
567
568 static u8
569 openssl_handshake_is_over (tls_ctx_t * ctx)
570 {
571   openssl_ctx_t *mc = (openssl_ctx_t *) ctx;
572   if (!mc->ssl)
573     return 0;
574   return SSL_is_init_finished (mc->ssl);
575 }
576
577 const static tls_engine_vft_t openssl_engine = {
578   .ctx_alloc = openssl_ctx_alloc,
579   .ctx_free = openssl_ctx_free,
580   .ctx_get = openssl_ctx_get,
581   .ctx_get_w_thread = openssl_ctx_get_w_thread,
582   .ctx_init_server = openssl_ctx_init_server,
583   .ctx_init_client = openssl_ctx_init_client,
584   .ctx_write = openssl_ctx_write,
585   .ctx_read = openssl_ctx_read,
586   .ctx_handshake_is_over = openssl_handshake_is_over,
587 };
588
589 int
590 tls_init_ca_chain (void)
591 {
592   openssl_main_t *om = &openssl_main;
593   tls_main_t *tm = vnet_tls_get_main ();
594   BIO *cert_bio;
595   X509 *testcert;
596   int rv;
597
598   if (access (tm->ca_cert_path, F_OK | R_OK) == -1)
599     {
600       clib_warning ("Could not initialize TLS CA certificates");
601       return -1;
602     }
603
604   if (!(om->cert_store = X509_STORE_new ()))
605     {
606       clib_warning ("failed to create cert store");
607       return -1;
608     }
609
610   rv = X509_STORE_load_locations (om->cert_store, tm->ca_cert_path, 0);
611   if (rv < 0)
612     {
613       clib_warning ("failed to load ca certificate");
614     }
615
616   if (tm->use_test_cert_in_ca)
617     {
618       cert_bio = BIO_new (BIO_s_mem ());
619       BIO_write (cert_bio, test_srv_crt_rsa, test_srv_crt_rsa_len);
620       testcert = PEM_read_bio_X509 (cert_bio, NULL, NULL, NULL);
621       if (!testcert)
622         {
623           clib_warning ("unable to parse certificate");
624           return -1;
625         }
626       X509_STORE_add_cert (om->cert_store, testcert);
627       rv = 0;
628     }
629   return (rv < 0 ? -1 : 0);
630 }
631
632 static clib_error_t *
633 tls_openssl_init (vlib_main_t * vm)
634 {
635   vlib_thread_main_t *vtm = vlib_get_thread_main ();
636   openssl_main_t *om = &openssl_main;
637   clib_error_t *error;
638   u32 num_threads;
639
640   num_threads = 1 /* main thread */  + vtm->n_threads;
641
642   if ((error = vlib_call_init_function (vm, tls_init)))
643     return error;
644
645   SSL_library_init ();
646   SSL_load_error_strings ();
647
648   if (tls_init_ca_chain ())
649     {
650       clib_warning ("failed to initialize TLS CA chain");
651       return 0;
652     }
653
654   vec_validate (om->ctx_pool, num_threads - 1);
655
656   tls_register_engine (&openssl_engine, TLS_ENGINE_OPENSSL);
657   return 0;
658 }
659
660 VLIB_INIT_FUNCTION (tls_openssl_init);
661
662 /* *INDENT-OFF* */
663 VLIB_PLUGIN_REGISTER () = {
664     .version = VPP_BUILD_VER,
665     .description = "openssl based TLS Engine",
666 };
667 /* *INDENT-ON* */
668
669 /*
670  * fd.io coding-style-patch-verification: ON
671  *
672  * Local Variables:
673  * eval: (c-set-style "gnu")
674  * End:
675  */