Line data Source code
1 : /*
2 : *------------------------------------------------------------------
3 : * Copyright (c) 2019 Cisco and/or its affiliates.
4 : * Licensed under the Apache License, Version 2.0 (the "License");
5 : * you may not use this file except in compliance with the License.
6 : * You may obtain a copy of the License at:
7 : *
8 : * http://www.apache.org/licenses/LICENSE-2.0
9 : *
10 : * Unless required by applicable law or agreed to in writing, software
11 : * distributed under the License is distributed on an "AS IS" BASIS,
12 : * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 : * See the License for the specific language governing permissions and
14 : * limitations under the License.
15 : *------------------------------------------------------------------
16 : */
17 :
18 : #include <sys/syscall.h>
19 :
20 : #include <openssl/evp.h>
21 : #include <openssl/hmac.h>
22 : #include <openssl/rand.h>
23 : #include <openssl/sha.h>
24 :
25 : #include <vlib/vlib.h>
26 : #include <vnet/plugin/plugin.h>
27 : #include <vnet/crypto/crypto.h>
28 : #include <vpp/app/version.h>
29 :
30 : typedef struct
31 : {
32 : CLIB_CACHE_LINE_ALIGN_MARK (cacheline0);
33 : EVP_CIPHER_CTX *evp_cipher_ctx;
34 : HMAC_CTX *hmac_ctx;
35 : EVP_MD_CTX *hash_ctx;
36 : #if OPENSSL_VERSION_NUMBER < 0x10100000L
37 : HMAC_CTX _hmac_ctx;
38 : #endif
39 : } openssl_per_thread_data_t;
40 :
41 : static openssl_per_thread_data_t *per_thread_data = 0;
42 :
43 : #define foreach_openssl_aes_evp_op \
44 : _ (cbc, DES_CBC, EVP_des_cbc, 8) \
45 : _ (cbc, 3DES_CBC, EVP_des_ede3_cbc, 8) \
46 : _ (cbc, AES_128_CBC, EVP_aes_128_cbc, 16) \
47 : _ (cbc, AES_192_CBC, EVP_aes_192_cbc, 16) \
48 : _ (cbc, AES_256_CBC, EVP_aes_256_cbc, 16) \
49 : _ (gcm, AES_128_GCM, EVP_aes_128_gcm, 8) \
50 : _ (gcm, AES_192_GCM, EVP_aes_192_gcm, 8) \
51 : _ (gcm, AES_256_GCM, EVP_aes_256_gcm, 8) \
52 : _ (cbc, AES_128_CTR, EVP_aes_128_ctr, 8) \
53 : _ (cbc, AES_192_CTR, EVP_aes_192_ctr, 8) \
54 : _ (cbc, AES_256_CTR, EVP_aes_256_ctr, 8) \
55 : _ (null_gmac, AES_128_NULL_GMAC, EVP_aes_128_gcm, 8) \
56 : _ (null_gmac, AES_192_NULL_GMAC, EVP_aes_192_gcm, 8) \
57 : _ (null_gmac, AES_256_NULL_GMAC, EVP_aes_256_gcm, 8)
58 :
59 : #define foreach_openssl_chacha20_evp_op \
60 : _ (chacha20_poly1305, CHACHA20_POLY1305, EVP_chacha20_poly1305, 8)
61 :
62 : #if OPENSSL_VERSION_NUMBER >= 0x10100000L
63 : #define foreach_openssl_evp_op foreach_openssl_aes_evp_op \
64 : foreach_openssl_chacha20_evp_op
65 : #else
66 : #define foreach_openssl_evp_op foreach_openssl_aes_evp_op
67 : #endif
68 :
69 : #ifndef EVP_CTRL_AEAD_GET_TAG
70 : #define EVP_CTRL_AEAD_GET_TAG EVP_CTRL_GCM_GET_TAG
71 : #endif
72 :
73 : #ifndef EVP_CTRL_AEAD_SET_TAG
74 : #define EVP_CTRL_AEAD_SET_TAG EVP_CTRL_GCM_SET_TAG
75 : #endif
76 :
77 : #define foreach_openssl_hash_op \
78 : _ (SHA1, EVP_sha1) \
79 : _ (SHA224, EVP_sha224) \
80 : _ (SHA256, EVP_sha256) \
81 : _ (SHA384, EVP_sha384) \
82 : _ (SHA512, EVP_sha512)
83 :
84 : #define foreach_openssl_hmac_op \
85 : _(MD5, EVP_md5) \
86 : _(SHA1, EVP_sha1) \
87 : _(SHA224, EVP_sha224) \
88 : _(SHA256, EVP_sha256) \
89 : _(SHA384, EVP_sha384) \
90 : _(SHA512, EVP_sha512)
91 :
92 : static_always_inline u32
93 1591 : openssl_ops_enc_cbc (vlib_main_t *vm, vnet_crypto_op_t *ops[],
94 : vnet_crypto_op_chunk_t *chunks, u32 n_ops,
95 : const EVP_CIPHER *cipher, const int iv_len)
96 : {
97 1591 : openssl_per_thread_data_t *ptd = vec_elt_at_index (per_thread_data,
98 : vm->thread_index);
99 1591 : EVP_CIPHER_CTX *ctx = ptd->evp_cipher_ctx;
100 : vnet_crypto_op_chunk_t *chp;
101 1591 : u32 i, j, curr_len = 0;
102 : u8 out_buf[VLIB_BUFFER_DEFAULT_DATA_SIZE * 5];
103 :
104 71331 : for (i = 0; i < n_ops; i++)
105 : {
106 69740 : vnet_crypto_op_t *op = ops[i];
107 69740 : vnet_crypto_key_t *key = vnet_crypto_get_key (op->key_index);
108 69740 : int out_len = 0;
109 :
110 69740 : EVP_EncryptInit_ex (ctx, cipher, NULL, key->data, op->iv);
111 :
112 69740 : if (op->flags & VNET_CRYPTO_OP_FLAG_CHAINED_BUFFERS)
113 : {
114 34305 : chp = chunks + op->chunk_index;
115 34305 : u32 offset = 0;
116 112831 : for (j = 0; j < op->n_chunks; j++)
117 : {
118 78526 : EVP_EncryptUpdate (ctx, out_buf + offset, &out_len, chp->src,
119 78526 : chp->len);
120 78526 : curr_len = chp->len;
121 78526 : offset += out_len;
122 78526 : chp += 1;
123 : }
124 34305 : if (out_len < curr_len)
125 0 : EVP_EncryptFinal_ex (ctx, out_buf + offset, &out_len);
126 :
127 34305 : offset = 0;
128 34305 : chp = chunks + op->chunk_index;
129 112831 : for (j = 0; j < op->n_chunks; j++)
130 : {
131 78526 : clib_memcpy_fast (chp->dst, out_buf + offset, chp->len);
132 78526 : offset += chp->len;
133 78526 : chp += 1;
134 : }
135 : }
136 : else
137 : {
138 35435 : EVP_EncryptUpdate (ctx, op->dst, &out_len, op->src, op->len);
139 35435 : if (out_len < op->len)
140 0 : EVP_EncryptFinal_ex (ctx, op->dst + out_len, &out_len);
141 : }
142 69740 : op->status = VNET_CRYPTO_OP_STATUS_COMPLETED;
143 : }
144 1591 : return n_ops;
145 : }
146 :
147 : static_always_inline u32
148 1681 : openssl_ops_dec_cbc (vlib_main_t *vm, vnet_crypto_op_t *ops[],
149 : vnet_crypto_op_chunk_t *chunks, u32 n_ops,
150 : const EVP_CIPHER *cipher, const int iv_len)
151 : {
152 1681 : openssl_per_thread_data_t *ptd = vec_elt_at_index (per_thread_data,
153 : vm->thread_index);
154 1681 : EVP_CIPHER_CTX *ctx = ptd->evp_cipher_ctx;
155 : vnet_crypto_op_chunk_t *chp;
156 1681 : u32 i, j, curr_len = 0;
157 : u8 out_buf[VLIB_BUFFER_DEFAULT_DATA_SIZE * 5];
158 :
159 72276 : for (i = 0; i < n_ops; i++)
160 : {
161 70595 : vnet_crypto_op_t *op = ops[i];
162 70595 : vnet_crypto_key_t *key = vnet_crypto_get_key (op->key_index);
163 70595 : int out_len = 0;
164 :
165 70595 : EVP_DecryptInit_ex (ctx, cipher, NULL, key->data, op->iv);
166 :
167 70595 : if (op->flags & VNET_CRYPTO_OP_FLAG_CHAINED_BUFFERS)
168 : {
169 36181 : chp = chunks + op->chunk_index;
170 36181 : u32 offset = 0;
171 120871 : for (j = 0; j < op->n_chunks; j++)
172 : {
173 84690 : EVP_DecryptUpdate (ctx, out_buf + offset, &out_len, chp->src,
174 84690 : chp->len);
175 84690 : curr_len = chp->len;
176 84690 : offset += out_len;
177 84690 : chp += 1;
178 : }
179 36181 : if (out_len < curr_len)
180 24120 : EVP_DecryptFinal_ex (ctx, out_buf + offset, &out_len);
181 :
182 36181 : offset = 0;
183 36181 : chp = chunks + op->chunk_index;
184 120871 : for (j = 0; j < op->n_chunks; j++)
185 : {
186 84690 : clib_memcpy_fast (chp->dst, out_buf + offset, chp->len);
187 84690 : offset += chp->len;
188 84690 : chp += 1;
189 : }
190 : }
191 : else
192 : {
193 34414 : EVP_DecryptUpdate (ctx, op->dst, &out_len, op->src, op->len);
194 34414 : if (out_len < op->len)
195 22891 : EVP_DecryptFinal_ex (ctx, op->dst + out_len, &out_len);
196 : }
197 70595 : op->status = VNET_CRYPTO_OP_STATUS_COMPLETED;
198 : }
199 1681 : return n_ops;
200 : }
201 :
202 : static_always_inline u32
203 1218 : openssl_ops_enc_aead (vlib_main_t *vm, vnet_crypto_op_t *ops[],
204 : vnet_crypto_op_chunk_t *chunks, u32 n_ops,
205 : const EVP_CIPHER *cipher, int is_gcm, int is_gmac,
206 : const int iv_len)
207 : {
208 1218 : openssl_per_thread_data_t *ptd = vec_elt_at_index (per_thread_data,
209 : vm->thread_index);
210 1218 : EVP_CIPHER_CTX *ctx = ptd->evp_cipher_ctx;
211 : vnet_crypto_op_chunk_t *chp;
212 : u32 i, j;
213 48420 : for (i = 0; i < n_ops; i++)
214 : {
215 47202 : vnet_crypto_op_t *op = ops[i];
216 47202 : vnet_crypto_key_t *key = vnet_crypto_get_key (op->key_index);
217 47202 : int len = 0;
218 :
219 47202 : EVP_EncryptInit_ex (ctx, cipher, 0, 0, 0);
220 47202 : if (is_gcm)
221 47202 : EVP_CIPHER_CTX_ctrl (ctx, EVP_CTRL_GCM_SET_IVLEN, 12, NULL);
222 47202 : EVP_EncryptInit_ex (ctx, 0, 0, key->data, op->iv);
223 47202 : if (op->aad_len)
224 47157 : EVP_EncryptUpdate (ctx, NULL, &len, op->aad, op->aad_len);
225 47202 : if (op->flags & VNET_CRYPTO_OP_FLAG_CHAINED_BUFFERS)
226 : {
227 22512 : chp = chunks + op->chunk_index;
228 73968 : for (j = 0; j < op->n_chunks; j++)
229 : {
230 51456 : EVP_EncryptUpdate (ctx, is_gmac ? 0 : chp->dst, &len, chp->src,
231 51456 : chp->len);
232 51456 : chp += 1;
233 : }
234 : }
235 : else
236 24690 : EVP_EncryptUpdate (ctx, is_gmac ? 0 : op->dst, &len, op->src, op->len);
237 47202 : EVP_EncryptFinal_ex (ctx, is_gmac ? 0 : op->dst + len, &len);
238 47202 : EVP_CIPHER_CTX_ctrl (ctx, EVP_CTRL_AEAD_GET_TAG, op->tag_len, op->tag);
239 47202 : op->status = VNET_CRYPTO_OP_STATUS_COMPLETED;
240 : }
241 1218 : return n_ops;
242 : }
243 :
244 : static_always_inline u32
245 702 : openssl_ops_enc_null_gmac (vlib_main_t *vm, vnet_crypto_op_t *ops[],
246 : vnet_crypto_op_chunk_t *chunks, u32 n_ops,
247 : const EVP_CIPHER *cipher, const int iv_len)
248 : {
249 702 : return openssl_ops_enc_aead (vm, ops, chunks, n_ops, cipher,
250 : /* is_gcm */ 1, /* is_gmac */ 1, iv_len);
251 : }
252 :
253 : static_always_inline u32
254 516 : openssl_ops_enc_gcm (vlib_main_t *vm, vnet_crypto_op_t *ops[],
255 : vnet_crypto_op_chunk_t *chunks, u32 n_ops,
256 : const EVP_CIPHER *cipher, const int iv_len)
257 : {
258 516 : return openssl_ops_enc_aead (vm, ops, chunks, n_ops, cipher,
259 : /* is_gcm */ 1, /* is_gmac */ 0, iv_len);
260 : }
261 :
262 : static_always_inline __clib_unused u32
263 0 : openssl_ops_enc_chacha20_poly1305 (vlib_main_t *vm, vnet_crypto_op_t *ops[],
264 : vnet_crypto_op_chunk_t *chunks, u32 n_ops,
265 : const EVP_CIPHER *cipher, const int iv_len)
266 : {
267 0 : return openssl_ops_enc_aead (vm, ops, chunks, n_ops, cipher,
268 : /* is_gcm */ 0, /* is_gmac */ 0, iv_len);
269 : }
270 :
271 : static_always_inline u32
272 1278 : openssl_ops_dec_aead (vlib_main_t *vm, vnet_crypto_op_t *ops[],
273 : vnet_crypto_op_chunk_t *chunks, u32 n_ops,
274 : const EVP_CIPHER *cipher, int is_gcm, int is_gmac,
275 : const int iv_len)
276 : {
277 1278 : openssl_per_thread_data_t *ptd = vec_elt_at_index (per_thread_data,
278 : vm->thread_index);
279 1278 : EVP_CIPHER_CTX *ctx = ptd->evp_cipher_ctx;
280 : vnet_crypto_op_chunk_t *chp;
281 1278 : u32 i, j, n_fail = 0;
282 49050 : for (i = 0; i < n_ops; i++)
283 : {
284 47772 : vnet_crypto_op_t *op = ops[i];
285 47772 : vnet_crypto_key_t *key = vnet_crypto_get_key (op->key_index);
286 47772 : int len = 0;
287 :
288 47772 : EVP_DecryptInit_ex (ctx, cipher, 0, 0, 0);
289 47772 : if (is_gcm)
290 47772 : EVP_CIPHER_CTX_ctrl (ctx, EVP_CTRL_GCM_SET_IVLEN, 12, 0);
291 47772 : EVP_DecryptInit_ex (ctx, 0, 0, key->data, op->iv);
292 47772 : if (op->aad_len)
293 47727 : EVP_DecryptUpdate (ctx, 0, &len, op->aad, op->aad_len);
294 47772 : if (op->flags & VNET_CRYPTO_OP_FLAG_CHAINED_BUFFERS)
295 : {
296 24120 : chp = chunks + op->chunk_index;
297 78792 : for (j = 0; j < op->n_chunks; j++)
298 : {
299 54672 : EVP_DecryptUpdate (ctx, is_gmac ? 0 : chp->dst, &len, chp->src,
300 54672 : chp->len);
301 54672 : chp += 1;
302 : }
303 : }
304 : else
305 : {
306 23652 : EVP_DecryptUpdate (ctx, is_gmac ? 0 : op->dst, &len, op->src,
307 23652 : op->len);
308 : }
309 47772 : EVP_CIPHER_CTX_ctrl (ctx, EVP_CTRL_AEAD_SET_TAG, op->tag_len, op->tag);
310 :
311 47772 : if (EVP_DecryptFinal_ex (ctx, is_gmac ? 0 : op->dst + len, &len) > 0)
312 47424 : op->status = VNET_CRYPTO_OP_STATUS_COMPLETED;
313 : else
314 : {
315 348 : n_fail++;
316 348 : op->status = VNET_CRYPTO_OP_STATUS_FAIL_BAD_HMAC;
317 : }
318 : }
319 1278 : return n_ops - n_fail;
320 : }
321 :
322 : static_always_inline u32
323 732 : openssl_ops_dec_null_gmac (vlib_main_t *vm, vnet_crypto_op_t *ops[],
324 : vnet_crypto_op_chunk_t *chunks, u32 n_ops,
325 : const EVP_CIPHER *cipher, const int iv_len)
326 : {
327 732 : return openssl_ops_dec_aead (vm, ops, chunks, n_ops, cipher,
328 : /* is_gcm */ 1, /* is_gmac */ 1, iv_len);
329 : }
330 :
331 : static_always_inline u32
332 546 : openssl_ops_dec_gcm (vlib_main_t *vm, vnet_crypto_op_t *ops[],
333 : vnet_crypto_op_chunk_t *chunks, u32 n_ops,
334 : const EVP_CIPHER *cipher, const int iv_len)
335 : {
336 546 : return openssl_ops_dec_aead (vm, ops, chunks, n_ops, cipher,
337 : /* is_gcm */ 1, /* is_gmac */ 0, iv_len);
338 : }
339 :
340 : static_always_inline __clib_unused u32
341 0 : openssl_ops_dec_chacha20_poly1305 (vlib_main_t *vm, vnet_crypto_op_t *ops[],
342 : vnet_crypto_op_chunk_t *chunks, u32 n_ops,
343 : const EVP_CIPHER *cipher, const int iv_len)
344 : {
345 0 : return openssl_ops_dec_aead (vm, ops, chunks, n_ops, cipher,
346 : /* is_gcm */ 0, /* is_gmac */ 0, iv_len);
347 : }
348 :
349 : static_always_inline u32
350 308 : openssl_ops_hash (vlib_main_t *vm, vnet_crypto_op_t *ops[],
351 : vnet_crypto_op_chunk_t *chunks, u32 n_ops, const EVP_MD *md)
352 : {
353 308 : openssl_per_thread_data_t *ptd =
354 308 : vec_elt_at_index (per_thread_data, vm->thread_index);
355 308 : EVP_MD_CTX *ctx = ptd->hash_ctx;
356 : vnet_crypto_op_chunk_t *chp;
357 308 : u32 md_len, i, j, n_fail = 0;
358 :
359 616 : for (i = 0; i < n_ops; i++)
360 : {
361 308 : vnet_crypto_op_t *op = ops[i];
362 :
363 308 : EVP_DigestInit_ex (ctx, md, NULL);
364 308 : if (op->flags & VNET_CRYPTO_OP_FLAG_CHAINED_BUFFERS)
365 : {
366 0 : chp = chunks + op->chunk_index;
367 0 : for (j = 0; j < op->n_chunks; j++)
368 : {
369 0 : EVP_DigestUpdate (ctx, chp->src, chp->len);
370 0 : chp += 1;
371 : }
372 : }
373 : else
374 308 : EVP_DigestUpdate (ctx, op->src, op->len);
375 :
376 308 : EVP_DigestFinal_ex (ctx, op->digest, &md_len);
377 308 : op->digest_len = md_len;
378 308 : op->status = VNET_CRYPTO_OP_STATUS_COMPLETED;
379 : }
380 308 : return n_ops - n_fail;
381 : }
382 :
383 : static_always_inline u32
384 3677 : openssl_ops_hmac (vlib_main_t * vm, vnet_crypto_op_t * ops[],
385 : vnet_crypto_op_chunk_t * chunks, u32 n_ops,
386 : const EVP_MD * md)
387 : {
388 : u8 buffer[64];
389 3677 : openssl_per_thread_data_t *ptd = vec_elt_at_index (per_thread_data,
390 : vm->thread_index);
391 3677 : HMAC_CTX *ctx = ptd->hmac_ctx;
392 : vnet_crypto_op_chunk_t *chp;
393 3677 : u32 i, j, n_fail = 0;
394 160990 : for (i = 0; i < n_ops; i++)
395 : {
396 157313 : vnet_crypto_op_t *op = ops[i];
397 157313 : vnet_crypto_key_t *key = vnet_crypto_get_key (op->key_index);
398 157313 : unsigned int out_len = 0;
399 157313 : size_t sz = op->digest_len ? op->digest_len : EVP_MD_size (md);
400 :
401 157313 : HMAC_Init_ex (ctx, key->data, vec_len (key->data), md, NULL);
402 157313 : if (op->flags & VNET_CRYPTO_OP_FLAG_CHAINED_BUFFERS)
403 : {
404 77455 : chp = chunks + op->chunk_index;
405 256889 : for (j = 0; j < op->n_chunks; j++)
406 : {
407 179434 : HMAC_Update (ctx, chp->src, chp->len);
408 179434 : chp += 1;
409 : }
410 : }
411 : else
412 79858 : HMAC_Update (ctx, op->src, op->len);
413 157313 : HMAC_Final (ctx, buffer, &out_len);
414 :
415 157313 : if (op->flags & VNET_CRYPTO_OP_FLAG_HMAC_CHECK)
416 : {
417 79126 : if ((memcmp (op->digest, buffer, sz)))
418 : {
419 580 : n_fail++;
420 580 : op->status = VNET_CRYPTO_OP_STATUS_FAIL_BAD_HMAC;
421 580 : continue;
422 : }
423 : }
424 : else
425 78187 : clib_memcpy_fast (op->digest, buffer, sz);
426 156733 : op->status = VNET_CRYPTO_OP_STATUS_COMPLETED;
427 : }
428 3677 : return n_ops - n_fail;
429 : }
430 :
431 : #define _(m, a, b, iv) \
432 : static u32 openssl_ops_enc_##a (vlib_main_t *vm, vnet_crypto_op_t *ops[], \
433 : u32 n_ops) \
434 : { \
435 : return openssl_ops_enc_##m (vm, ops, 0, n_ops, b (), iv); \
436 : } \
437 : \
438 : u32 openssl_ops_dec_##a (vlib_main_t *vm, vnet_crypto_op_t *ops[], \
439 : u32 n_ops) \
440 : { \
441 : return openssl_ops_dec_##m (vm, ops, 0, n_ops, b (), iv); \
442 : } \
443 : \
444 : static u32 openssl_ops_enc_chained_##a ( \
445 : vlib_main_t *vm, vnet_crypto_op_t *ops[], vnet_crypto_op_chunk_t *chunks, \
446 : u32 n_ops) \
447 : { \
448 : return openssl_ops_enc_##m (vm, ops, chunks, n_ops, b (), iv); \
449 : } \
450 : \
451 : static u32 openssl_ops_dec_chained_##a ( \
452 : vlib_main_t *vm, vnet_crypto_op_t *ops[], vnet_crypto_op_chunk_t *chunks, \
453 : u32 n_ops) \
454 : { \
455 : return openssl_ops_dec_##m (vm, ops, chunks, n_ops, b (), iv); \
456 : }
457 :
458 5768 : foreach_openssl_evp_op;
459 : #undef _
460 :
461 : #define _(a, b) \
462 : static u32 openssl_ops_hash_##a (vlib_main_t *vm, vnet_crypto_op_t *ops[], \
463 : u32 n_ops) \
464 : { \
465 : return openssl_ops_hash (vm, ops, 0, n_ops, b ()); \
466 : } \
467 : static u32 openssl_ops_hash_chained_##a ( \
468 : vlib_main_t *vm, vnet_crypto_op_t *ops[], vnet_crypto_op_chunk_t *chunks, \
469 : u32 n_ops) \
470 : { \
471 : return openssl_ops_hash (vm, ops, chunks, n_ops, b ()); \
472 : }
473 :
474 308 : foreach_openssl_hash_op;
475 : #undef _
476 :
477 : #define _(a, b) \
478 : static u32 \
479 : openssl_ops_hmac_##a (vlib_main_t * vm, vnet_crypto_op_t * ops[], u32 n_ops) \
480 : { return openssl_ops_hmac (vm, ops, 0, n_ops, b ()); } \
481 : static u32 \
482 : openssl_ops_hmac_chained_##a (vlib_main_t * vm, vnet_crypto_op_t * ops[], \
483 : vnet_crypto_op_chunk_t *chunks, u32 n_ops) \
484 : { return openssl_ops_hmac (vm, ops, chunks, n_ops, b ()); } \
485 :
486 3677 : foreach_openssl_hmac_op;
487 : #undef _
488 :
489 :
490 : clib_error_t *
491 575 : crypto_openssl_init (vlib_main_t * vm)
492 : {
493 575 : vlib_thread_main_t *tm = vlib_get_thread_main ();
494 : openssl_per_thread_data_t *ptd;
495 : u8 seed[32];
496 :
497 575 : if (syscall (SYS_getrandom, &seed, sizeof (seed), 0) != sizeof (seed))
498 0 : return clib_error_return_unix (0, "getrandom() failed");
499 :
500 575 : RAND_seed (seed, sizeof (seed));
501 :
502 575 : u32 eidx = vnet_crypto_register_engine (vm, "openssl", 50, "OpenSSL");
503 :
504 : #define _(m, a, b, iv) \
505 : vnet_crypto_register_ops_handlers (vm, eidx, VNET_CRYPTO_OP_##a##_ENC, \
506 : openssl_ops_enc_##a, \
507 : openssl_ops_enc_chained_##a); \
508 : vnet_crypto_register_ops_handlers (vm, eidx, VNET_CRYPTO_OP_##a##_DEC, \
509 : openssl_ops_dec_##a, \
510 : openssl_ops_dec_chained_##a);
511 :
512 575 : foreach_openssl_evp_op;
513 : #undef _
514 :
515 : #define _(a, b) \
516 : vnet_crypto_register_ops_handlers (vm, eidx, VNET_CRYPTO_OP_##a##_HMAC, \
517 : openssl_ops_hmac_##a, \
518 : openssl_ops_hmac_chained_##a); \
519 :
520 575 : foreach_openssl_hmac_op;
521 : #undef _
522 :
523 : #define _(a, b) \
524 : vnet_crypto_register_ops_handlers (vm, eidx, VNET_CRYPTO_OP_##a##_HASH, \
525 : openssl_ops_hash_##a, \
526 : openssl_ops_hash_chained_##a);
527 :
528 575 : foreach_openssl_hash_op;
529 : #undef _
530 :
531 575 : vec_validate_aligned (per_thread_data, tm->n_vlib_mains - 1,
532 : CLIB_CACHE_LINE_BYTES);
533 :
534 1205 : vec_foreach (ptd, per_thread_data)
535 : {
536 630 : ptd->evp_cipher_ctx = EVP_CIPHER_CTX_new ();
537 630 : EVP_CIPHER_CTX_set_padding (ptd->evp_cipher_ctx, 0);
538 : #if OPENSSL_VERSION_NUMBER >= 0x10100000L
539 630 : ptd->hmac_ctx = HMAC_CTX_new ();
540 630 : ptd->hash_ctx = EVP_MD_CTX_create ();
541 : #else
542 : HMAC_CTX_init (&(ptd->_hmac_ctx));
543 : ptd->hmac_ctx = &ptd->_hmac_ctx;
544 : #endif
545 : }
546 :
547 575 : return 0;
548 : }
549 :
550 : /* *INDENT-OFF* */
551 1151 : VLIB_INIT_FUNCTION (crypto_openssl_init) =
552 : {
553 : .runs_after = VLIB_INITS ("vnet_crypto_init"),
554 : };
555 : /* *INDENT-ON* */
556 :
557 :
558 : /* *INDENT-OFF* */
559 : VLIB_PLUGIN_REGISTER () = {
560 : .version = VPP_BUILD_VER,
561 : .description = "OpenSSL Crypto Engine",
562 : };
563 : /* *INDENT-ON* */
564 :
565 : /*
566 : * fd.io coding-style-patch-verification: ON
567 : *
568 : * Local Variables:
569 : * eval: (c-set-style "gnu")
570 : * End:
571 : */
|