openssl: backport devcrypto changes from master
[openwrt/openwrt.git] / package / libs / openssl / patches / 430-e_devcrypto-make-the-dev-crypto-engine-dynamic.patch
1 From 37a5c14aad5051201e4bd18faf1a4b25a824cc30 Mon Sep 17 00:00:00 2001
2 From: Eneas U de Queiroz <cote2004-github@yahoo.com>
3 Date: Tue, 6 Nov 2018 10:57:03 -0200
4 Subject: [PATCH 4/4] e_devcrypto: make the /dev/crypto engine dynamic
5
6 Engine has been moved from crypto/engine/eng_devcrypto.c to
7 engines/e_devcrypto.c.
8
9 Signed-off-by: Eneas U de Queiroz <cote2004-github@yahoo.com>
10
11 --- a/crypto/engine/build.info
12 +++ b/crypto/engine/build.info
13 @@ -6,6 +6,3 @@ SOURCE[../../libcrypto]=\
14 tb_cipher.c tb_digest.c tb_pkmeth.c tb_asnmth.c tb_eckey.c \
15 eng_openssl.c eng_cnf.c eng_dyn.c \
16 eng_rdrand.c
17 -IF[{- !$disabled{devcryptoeng} -}]
18 - SOURCE[../../libcrypto]=eng_devcrypto.c
19 -ENDIF
20 --- a/crypto/init.c
21 +++ b/crypto/init.c
22 @@ -330,18 +330,6 @@ DEFINE_RUN_ONCE_STATIC(ossl_init_engine_
23 engine_load_openssl_int();
24 return 1;
25 }
26 -# ifndef OPENSSL_NO_DEVCRYPTOENG
27 -static CRYPTO_ONCE engine_devcrypto = CRYPTO_ONCE_STATIC_INIT;
28 -DEFINE_RUN_ONCE_STATIC(ossl_init_engine_devcrypto)
29 -{
30 -# ifdef OPENSSL_INIT_DEBUG
31 - fprintf(stderr, "OPENSSL_INIT: ossl_init_engine_devcrypto: "
32 - "engine_load_devcrypto_int()\n");
33 -# endif
34 - engine_load_devcrypto_int();
35 - return 1;
36 -}
37 -# endif
38
39 # ifndef OPENSSL_NO_RDRAND
40 static CRYPTO_ONCE engine_rdrand = CRYPTO_ONCE_STATIC_INIT;
41 @@ -366,6 +354,18 @@ DEFINE_RUN_ONCE_STATIC(ossl_init_engine_
42 return 1;
43 }
44 # ifndef OPENSSL_NO_STATIC_ENGINE
45 +# ifndef OPENSSL_NO_DEVCRYPTOENG
46 +static CRYPTO_ONCE engine_devcrypto = CRYPTO_ONCE_STATIC_INIT;
47 +DEFINE_RUN_ONCE_STATIC(ossl_init_engine_devcrypto)
48 +{
49 +# ifdef OPENSSL_INIT_DEBUG
50 + fprintf(stderr, "OPENSSL_INIT: ossl_init_engine_devcrypto: "
51 + "engine_load_devcrypto_int()\n");
52 +# endif
53 + engine_load_devcrypto_int();
54 + return 1;
55 +}
56 +# endif
57 # if !defined(OPENSSL_NO_HW) && !defined(OPENSSL_NO_HW_PADLOCK)
58 static CRYPTO_ONCE engine_padlock = CRYPTO_ONCE_STATIC_INIT;
59 DEFINE_RUN_ONCE_STATIC(ossl_init_engine_padlock)
60 @@ -714,11 +714,6 @@ int OPENSSL_init_crypto(uint64_t opts, c
61 if ((opts & OPENSSL_INIT_ENGINE_OPENSSL)
62 && !RUN_ONCE(&engine_openssl, ossl_init_engine_openssl))
63 return 0;
64 -# if !defined(OPENSSL_NO_HW) && !defined(OPENSSL_NO_DEVCRYPTOENG)
65 - if ((opts & OPENSSL_INIT_ENGINE_CRYPTODEV)
66 - && !RUN_ONCE(&engine_devcrypto, ossl_init_engine_devcrypto))
67 - return 0;
68 -# endif
69 # ifndef OPENSSL_NO_RDRAND
70 if ((opts & OPENSSL_INIT_ENGINE_RDRAND)
71 && !RUN_ONCE(&engine_rdrand, ossl_init_engine_rdrand))
72 @@ -728,6 +723,11 @@ int OPENSSL_init_crypto(uint64_t opts, c
73 && !RUN_ONCE(&engine_dynamic, ossl_init_engine_dynamic))
74 return 0;
75 # ifndef OPENSSL_NO_STATIC_ENGINE
76 +# ifndef OPENSSL_NO_DEVCRYPTOENG
77 + if ((opts & OPENSSL_INIT_ENGINE_CRYPTODEV)
78 + && !RUN_ONCE(&engine_devcrypto, ossl_init_engine_devcrypto))
79 + return 0;
80 +# endif
81 # if !defined(OPENSSL_NO_HW) && !defined(OPENSSL_NO_HW_PADLOCK)
82 if ((opts & OPENSSL_INIT_ENGINE_PADLOCK)
83 && !RUN_ONCE(&engine_padlock, ossl_init_engine_padlock))
84 --- a/engines/build.info
85 +++ b/engines/build.info
86 @@ -10,6 +10,9 @@ IF[{- !$disabled{"engine"} -}]
87 IF[{- !$disabled{afalgeng} -}]
88 SOURCE[../libcrypto]=e_afalg.c
89 ENDIF
90 + IF[{- !$disabled{"devcryptoeng"} -}]
91 + SOURCE[../libcrypto]=e_devcrypto.c
92 + ENDIF
93 ELSE
94 ENGINES=padlock
95 SOURCE[padlock]=e_padlock.c {- $target{padlock_asm_src} -}
96 @@ -27,6 +30,12 @@ IF[{- !$disabled{"engine"} -}]
97 DEPEND[afalg]=../libcrypto
98 INCLUDE[afalg]= ../include
99 ENDIF
100 + IF[{- !$disabled{"devcryptoeng"} -}]
101 + ENGINES=devcrypto
102 + SOURCE[devcrypto]=e_devcrypto.c
103 + DEPEND[devcrypto]=../libcrypto
104 + INCLUDE[devcrypto]=../include
105 + ENDIF
106
107 ENGINES_NO_INST=ossltest dasync
108 SOURCE[dasync]=e_dasync.c
109 --- a/crypto/engine/eng_devcrypto.c
110 +++ /dev/null
111 @@ -1,1264 +0,0 @@
112 -/*
113 - * Copyright 2017-2019 The OpenSSL Project Authors. All Rights Reserved.
114 - *
115 - * Licensed under the OpenSSL license (the "License"). You may not use
116 - * this file except in compliance with the License. You can obtain a copy
117 - * in the file LICENSE in the source distribution or at
118 - * https://www.openssl.org/source/license.html
119 - */
120 -
121 -#include "e_os.h"
122 -#include <string.h>
123 -#include <sys/types.h>
124 -#include <sys/stat.h>
125 -#include <fcntl.h>
126 -#include <sys/ioctl.h>
127 -#include <unistd.h>
128 -#include <assert.h>
129 -
130 -#include <openssl/conf.h>
131 -#include <openssl/evp.h>
132 -#include <openssl/err.h>
133 -#include <openssl/engine.h>
134 -#include <openssl/objects.h>
135 -#include <crypto/cryptodev.h>
136 -
137 -#include "internal/engine.h"
138 -
139 -/* #define ENGINE_DEVCRYPTO_DEBUG */
140 -
141 -#ifdef CRYPTO_ALGORITHM_MIN
142 -# define CHECK_BSD_STYLE_MACROS
143 -#endif
144 -
145 -/*
146 - * ONE global file descriptor for all sessions. This allows operations
147 - * such as digest session data copying (see digest_copy()), but is also
148 - * saner... why re-open /dev/crypto for every session?
149 - */
150 -static int cfd;
151 -#define DEVCRYPTO_REQUIRE_ACCELERATED 0 /* require confirmation of acceleration */
152 -#define DEVCRYPTO_USE_SOFTWARE 1 /* allow software drivers */
153 -#define DEVCRYPTO_REJECT_SOFTWARE 2 /* only disallow confirmed software drivers */
154 -
155 -#define DEVCRYPTO_DEFAULT_USE_SOFDTRIVERS DEVCRYPTO_REJECT_SOFTWARE
156 -static int use_softdrivers = DEVCRYPTO_DEFAULT_USE_SOFDTRIVERS;
157 -
158 -/*
159 - * cipher/digest status & acceleration definitions
160 - * Make sure the defaults are set to 0
161 - */
162 -struct driver_info_st {
163 - enum devcrypto_status_t {
164 - DEVCRYPTO_STATUS_FAILURE = -3, /* unusable for other reason */
165 - DEVCRYPTO_STATUS_NO_CIOCCPHASH = -2, /* hash state copy not supported */
166 - DEVCRYPTO_STATUS_NO_CIOCGSESSION = -1, /* session open failed */
167 - DEVCRYPTO_STATUS_UNKNOWN = 0, /* not tested yet */
168 - DEVCRYPTO_STATUS_USABLE = 1 /* algo can be used */
169 - } status;
170 -
171 - enum devcrypto_accelerated_t {
172 - DEVCRYPTO_NOT_ACCELERATED = -1, /* software implemented */
173 - DEVCRYPTO_ACCELERATION_UNKNOWN = 0, /* acceleration support unkown */
174 - DEVCRYPTO_ACCELERATED = 1 /* hardware accelerated */
175 - } accelerated;
176 -
177 - char *driver_name;
178 -};
179 -
180 -static int clean_devcrypto_session(struct session_op *sess) {
181 - if (ioctl(cfd, CIOCFSESSION, &sess->ses) < 0) {
182 - SYSerr(SYS_F_IOCTL, errno);
183 - return 0;
184 - }
185 - memset(sess, 0, sizeof(struct session_op));
186 - return 1;
187 -}
188 -
189 -/******************************************************************************
190 - *
191 - * Ciphers
192 - *
193 - * Because they all do the same basic operation, we have only one set of
194 - * method functions for them all to share, and a mapping table between
195 - * NIDs and cryptodev IDs, with all the necessary size data.
196 - *
197 - *****/
198 -
199 -struct cipher_ctx {
200 - struct session_op sess;
201 - int op; /* COP_ENCRYPT or COP_DECRYPT */
202 - unsigned long mode; /* EVP_CIPH_*_MODE */
203 -
204 - /* to handle ctr mode being a stream cipher */
205 - unsigned char partial[EVP_MAX_BLOCK_LENGTH];
206 - unsigned int blocksize, num;
207 -};
208 -
209 -static const struct cipher_data_st {
210 - int nid;
211 - int blocksize;
212 - int keylen;
213 - int ivlen;
214 - int flags;
215 - int devcryptoid;
216 -} cipher_data[] = {
217 -#ifndef OPENSSL_NO_DES
218 - { NID_des_cbc, 8, 8, 8, EVP_CIPH_CBC_MODE, CRYPTO_DES_CBC },
219 - { NID_des_ede3_cbc, 8, 24, 8, EVP_CIPH_CBC_MODE, CRYPTO_3DES_CBC },
220 -#endif
221 -#ifndef OPENSSL_NO_BF
222 - { NID_bf_cbc, 8, 16, 8, EVP_CIPH_CBC_MODE, CRYPTO_BLF_CBC },
223 -#endif
224 -#ifndef OPENSSL_NO_CAST
225 - { NID_cast5_cbc, 8, 16, 8, EVP_CIPH_CBC_MODE, CRYPTO_CAST_CBC },
226 -#endif
227 - { NID_aes_128_cbc, 16, 128 / 8, 16, EVP_CIPH_CBC_MODE, CRYPTO_AES_CBC },
228 - { NID_aes_192_cbc, 16, 192 / 8, 16, EVP_CIPH_CBC_MODE, CRYPTO_AES_CBC },
229 - { NID_aes_256_cbc, 16, 256 / 8, 16, EVP_CIPH_CBC_MODE, CRYPTO_AES_CBC },
230 -#ifndef OPENSSL_NO_RC4
231 - { NID_rc4, 1, 16, 0, EVP_CIPH_STREAM_CIPHER, CRYPTO_ARC4 },
232 -#endif
233 -#if !defined(CHECK_BSD_STYLE_MACROS) || defined(CRYPTO_AES_CTR)
234 - { NID_aes_128_ctr, 16, 128 / 8, 16, EVP_CIPH_CTR_MODE, CRYPTO_AES_CTR },
235 - { NID_aes_192_ctr, 16, 192 / 8, 16, EVP_CIPH_CTR_MODE, CRYPTO_AES_CTR },
236 - { NID_aes_256_ctr, 16, 256 / 8, 16, EVP_CIPH_CTR_MODE, CRYPTO_AES_CTR },
237 -#endif
238 -#if 0 /* Not yet supported */
239 - { NID_aes_128_xts, 16, 128 / 8 * 2, 16, EVP_CIPH_XTS_MODE, CRYPTO_AES_XTS },
240 - { NID_aes_256_xts, 16, 256 / 8 * 2, 16, EVP_CIPH_XTS_MODE, CRYPTO_AES_XTS },
241 -#endif
242 -#if !defined(CHECK_BSD_STYLE_MACROS) || defined(CRYPTO_AES_ECB)
243 - { NID_aes_128_ecb, 16, 128 / 8, 0, EVP_CIPH_ECB_MODE, CRYPTO_AES_ECB },
244 - { NID_aes_192_ecb, 16, 192 / 8, 0, EVP_CIPH_ECB_MODE, CRYPTO_AES_ECB },
245 - { NID_aes_256_ecb, 16, 256 / 8, 0, EVP_CIPH_ECB_MODE, CRYPTO_AES_ECB },
246 -#endif
247 -#if 0 /* Not yet supported */
248 - { NID_aes_128_gcm, 16, 128 / 8, 16, EVP_CIPH_GCM_MODE, CRYPTO_AES_GCM },
249 - { NID_aes_192_gcm, 16, 192 / 8, 16, EVP_CIPH_GCM_MODE, CRYPTO_AES_GCM },
250 - { NID_aes_256_gcm, 16, 256 / 8, 16, EVP_CIPH_GCM_MODE, CRYPTO_AES_GCM },
251 -#endif
252 -#ifndef OPENSSL_NO_CAMELLIA
253 - { NID_camellia_128_cbc, 16, 128 / 8, 16, EVP_CIPH_CBC_MODE,
254 - CRYPTO_CAMELLIA_CBC },
255 - { NID_camellia_192_cbc, 16, 192 / 8, 16, EVP_CIPH_CBC_MODE,
256 - CRYPTO_CAMELLIA_CBC },
257 - { NID_camellia_256_cbc, 16, 256 / 8, 16, EVP_CIPH_CBC_MODE,
258 - CRYPTO_CAMELLIA_CBC },
259 -#endif
260 -};
261 -
262 -static size_t find_cipher_data_index(int nid)
263 -{
264 - size_t i;
265 -
266 - for (i = 0; i < OSSL_NELEM(cipher_data); i++)
267 - if (nid == cipher_data[i].nid)
268 - return i;
269 - return (size_t)-1;
270 -}
271 -
272 -static size_t get_cipher_data_index(int nid)
273 -{
274 - size_t i = find_cipher_data_index(nid);
275 -
276 - if (i != (size_t)-1)
277 - return i;
278 -
279 - /*
280 - * Code further down must make sure that only NIDs in the table above
281 - * are used. If any other NID reaches this function, there's a grave
282 - * coding error further down.
283 - */
284 - assert("Code that never should be reached" == NULL);
285 - return -1;
286 -}
287 -
288 -static const struct cipher_data_st *get_cipher_data(int nid)
289 -{
290 - return &cipher_data[get_cipher_data_index(nid)];
291 -}
292 -
293 -/*
294 - * Following are the three necessary functions to map OpenSSL functionality
295 - * with cryptodev.
296 - */
297 -
298 -static int cipher_init(EVP_CIPHER_CTX *ctx, const unsigned char *key,
299 - const unsigned char *iv, int enc)
300 -{
301 - struct cipher_ctx *cipher_ctx =
302 - (struct cipher_ctx *)EVP_CIPHER_CTX_get_cipher_data(ctx);
303 - const struct cipher_data_st *cipher_d =
304 - get_cipher_data(EVP_CIPHER_CTX_nid(ctx));
305 -
306 - /* cleanup a previous session */
307 - if (cipher_ctx->sess.ses != 0 &&
308 - clean_devcrypto_session(&cipher_ctx->sess) == 0)
309 - return 0;
310 -
311 - cipher_ctx->sess.cipher = cipher_d->devcryptoid;
312 - cipher_ctx->sess.keylen = cipher_d->keylen;
313 - cipher_ctx->sess.key = (void *)key;
314 - cipher_ctx->op = enc ? COP_ENCRYPT : COP_DECRYPT;
315 - cipher_ctx->mode = cipher_d->flags & EVP_CIPH_MODE;
316 - cipher_ctx->blocksize = cipher_d->blocksize;
317 - if (ioctl(cfd, CIOCGSESSION, &cipher_ctx->sess) < 0) {
318 - SYSerr(SYS_F_IOCTL, errno);
319 - return 0;
320 - }
321 -
322 - return 1;
323 -}
324 -
325 -static int cipher_do_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
326 - const unsigned char *in, size_t inl)
327 -{
328 - struct cipher_ctx *cipher_ctx =
329 - (struct cipher_ctx *)EVP_CIPHER_CTX_get_cipher_data(ctx);
330 - struct crypt_op cryp;
331 - unsigned char *iv = EVP_CIPHER_CTX_iv_noconst(ctx);
332 -#if !defined(COP_FLAG_WRITE_IV)
333 - unsigned char saved_iv[EVP_MAX_IV_LENGTH];
334 - const unsigned char *ivptr;
335 - size_t nblocks, ivlen;
336 -#endif
337 -
338 - memset(&cryp, 0, sizeof(cryp));
339 - cryp.ses = cipher_ctx->sess.ses;
340 - cryp.len = inl;
341 - cryp.src = (void *)in;
342 - cryp.dst = (void *)out;
343 - cryp.iv = (void *)iv;
344 - cryp.op = cipher_ctx->op;
345 -#if !defined(COP_FLAG_WRITE_IV)
346 - cryp.flags = 0;
347 -
348 - ivlen = EVP_CIPHER_CTX_iv_length(ctx);
349 - if (ivlen > 0)
350 - switch (cipher_ctx->mode) {
351 - case EVP_CIPH_CBC_MODE:
352 - assert(inl >= ivlen);
353 - if (!EVP_CIPHER_CTX_encrypting(ctx)) {
354 - ivptr = in + inl - ivlen;
355 - memcpy(saved_iv, ivptr, ivlen);
356 - }
357 - break;
358 -
359 - case EVP_CIPH_CTR_MODE:
360 - break;
361 -
362 - default: /* should not happen */
363 - return 0;
364 - }
365 -#else
366 - cryp.flags = COP_FLAG_WRITE_IV;
367 -#endif
368 -
369 - if (ioctl(cfd, CIOCCRYPT, &cryp) < 0) {
370 - SYSerr(SYS_F_IOCTL, errno);
371 - return 0;
372 - }
373 -
374 -#if !defined(COP_FLAG_WRITE_IV)
375 - if (ivlen > 0)
376 - switch (cipher_ctx->mode) {
377 - case EVP_CIPH_CBC_MODE:
378 - assert(inl >= ivlen);
379 - if (EVP_CIPHER_CTX_encrypting(ctx))
380 - ivptr = out + inl - ivlen;
381 - else
382 - ivptr = saved_iv;
383 -
384 - memcpy(iv, ivptr, ivlen);
385 - break;
386 -
387 - case EVP_CIPH_CTR_MODE:
388 - nblocks = (inl + cipher_ctx->blocksize - 1)
389 - / cipher_ctx->blocksize;
390 - do {
391 - ivlen--;
392 - nblocks += iv[ivlen];
393 - iv[ivlen] = (uint8_t) nblocks;
394 - nblocks >>= 8;
395 - } while (ivlen);
396 - break;
397 -
398 - default: /* should not happen */
399 - return 0;
400 - }
401 -#endif
402 -
403 - return 1;
404 -}
405 -
406 -static int ctr_do_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
407 - const unsigned char *in, size_t inl)
408 -{
409 - struct cipher_ctx *cipher_ctx =
410 - (struct cipher_ctx *)EVP_CIPHER_CTX_get_cipher_data(ctx);
411 - size_t nblocks, len;
412 -
413 - /* initial partial block */
414 - while (cipher_ctx->num && inl) {
415 - (*out++) = *(in++) ^ cipher_ctx->partial[cipher_ctx->num];
416 - --inl;
417 - cipher_ctx->num = (cipher_ctx->num + 1) % cipher_ctx->blocksize;
418 - }
419 -
420 - /* full blocks */
421 - if (inl > (unsigned int) cipher_ctx->blocksize) {
422 - nblocks = inl/cipher_ctx->blocksize;
423 - len = nblocks * cipher_ctx->blocksize;
424 - if (cipher_do_cipher(ctx, out, in, len) < 1)
425 - return 0;
426 - inl -= len;
427 - out += len;
428 - in += len;
429 - }
430 -
431 - /* final partial block */
432 - if (inl) {
433 - memset(cipher_ctx->partial, 0, cipher_ctx->blocksize);
434 - if (cipher_do_cipher(ctx, cipher_ctx->partial, cipher_ctx->partial,
435 - cipher_ctx->blocksize) < 1)
436 - return 0;
437 - while (inl--) {
438 - out[cipher_ctx->num] = in[cipher_ctx->num]
439 - ^ cipher_ctx->partial[cipher_ctx->num];
440 - cipher_ctx->num++;
441 - }
442 - }
443 -
444 - return 1;
445 -}
446 -
447 -static int cipher_ctrl(EVP_CIPHER_CTX *ctx, int type, int p1, void* p2)
448 -{
449 - struct cipher_ctx *cipher_ctx =
450 - (struct cipher_ctx *)EVP_CIPHER_CTX_get_cipher_data(ctx);
451 - EVP_CIPHER_CTX *to_ctx = (EVP_CIPHER_CTX *)p2;
452 - struct cipher_ctx *to_cipher_ctx;
453 -
454 - switch (type) {
455 - case EVP_CTRL_COPY:
456 - if (cipher_ctx == NULL)
457 - return 1;
458 - /* when copying the context, a new session needs to be initialized */
459 - to_cipher_ctx =
460 - (struct cipher_ctx *)EVP_CIPHER_CTX_get_cipher_data(to_ctx);
461 - memset(&to_cipher_ctx->sess, 0, sizeof(to_cipher_ctx->sess));
462 - return cipher_init(to_ctx, cipher_ctx->sess.key, EVP_CIPHER_CTX_iv(ctx),
463 - (cipher_ctx->op == COP_ENCRYPT));
464 -
465 - case EVP_CTRL_INIT:
466 - memset(&cipher_ctx->sess, 0, sizeof(cipher_ctx->sess));
467 - return 1;
468 -
469 - default:
470 - break;
471 - }
472 -
473 - return -1;
474 -}
475 -
476 -static int cipher_cleanup(EVP_CIPHER_CTX *ctx)
477 -{
478 - struct cipher_ctx *cipher_ctx =
479 - (struct cipher_ctx *)EVP_CIPHER_CTX_get_cipher_data(ctx);
480 -
481 - return clean_devcrypto_session(&cipher_ctx->sess);
482 -}
483 -
484 -/*
485 - * Keep tables of known nids, associated methods, selected ciphers, and driver
486 - * info.
487 - * Note that known_cipher_nids[] isn't necessarily indexed the same way as
488 - * cipher_data[] above, which the other tables are.
489 - */
490 -static int known_cipher_nids[OSSL_NELEM(cipher_data)];
491 -static int known_cipher_nids_amount = -1; /* -1 indicates not yet initialised */
492 -static EVP_CIPHER *known_cipher_methods[OSSL_NELEM(cipher_data)] = { NULL, };
493 -static int selected_ciphers[OSSL_NELEM(cipher_data)];
494 -static struct driver_info_st cipher_driver_info[OSSL_NELEM(cipher_data)];
495 -
496 -
497 -static int devcrypto_test_cipher(size_t cipher_data_index)
498 -{
499 - return (cipher_driver_info[cipher_data_index].status == DEVCRYPTO_STATUS_USABLE
500 - && selected_ciphers[cipher_data_index] == 1
501 - && (cipher_driver_info[cipher_data_index].accelerated
502 - == DEVCRYPTO_ACCELERATED
503 - || use_softdrivers == DEVCRYPTO_USE_SOFTWARE
504 - || (cipher_driver_info[cipher_data_index].accelerated
505 - != DEVCRYPTO_NOT_ACCELERATED
506 - && use_softdrivers == DEVCRYPTO_REJECT_SOFTWARE)));
507 -}
508 -
509 -static void prepare_cipher_methods(void)
510 -{
511 - size_t i;
512 - struct session_op sess;
513 - unsigned long cipher_mode;
514 -#ifdef CIOCGSESSINFO
515 - struct session_info_op siop;
516 -#endif
517 -
518 - memset(&cipher_driver_info, 0, sizeof(cipher_driver_info));
519 -
520 - memset(&sess, 0, sizeof(sess));
521 - sess.key = (void *)"01234567890123456789012345678901234567890123456789";
522 -
523 - for (i = 0, known_cipher_nids_amount = 0;
524 - i < OSSL_NELEM(cipher_data); i++) {
525 -
526 - selected_ciphers[i] = 1;
527 - /*
528 - * Check that the cipher is usable
529 - */
530 - sess.cipher = cipher_data[i].devcryptoid;
531 - sess.keylen = cipher_data[i].keylen;
532 - if (ioctl(cfd, CIOCGSESSION, &sess) < 0) {
533 - cipher_driver_info[i].status = DEVCRYPTO_STATUS_NO_CIOCGSESSION;
534 - continue;
535 - }
536 -
537 - cipher_mode = cipher_data[i].flags & EVP_CIPH_MODE;
538 -
539 - if ((known_cipher_methods[i] =
540 - EVP_CIPHER_meth_new(cipher_data[i].nid,
541 - cipher_mode == EVP_CIPH_CTR_MODE ? 1 :
542 - cipher_data[i].blocksize,
543 - cipher_data[i].keylen)) == NULL
544 - || !EVP_CIPHER_meth_set_iv_length(known_cipher_methods[i],
545 - cipher_data[i].ivlen)
546 - || !EVP_CIPHER_meth_set_flags(known_cipher_methods[i],
547 - cipher_data[i].flags
548 - | EVP_CIPH_CUSTOM_COPY
549 - | EVP_CIPH_CTRL_INIT
550 - | EVP_CIPH_FLAG_DEFAULT_ASN1)
551 - || !EVP_CIPHER_meth_set_init(known_cipher_methods[i], cipher_init)
552 - || !EVP_CIPHER_meth_set_do_cipher(known_cipher_methods[i],
553 - cipher_mode == EVP_CIPH_CTR_MODE ?
554 - ctr_do_cipher :
555 - cipher_do_cipher)
556 - || !EVP_CIPHER_meth_set_ctrl(known_cipher_methods[i], cipher_ctrl)
557 - || !EVP_CIPHER_meth_set_cleanup(known_cipher_methods[i],
558 - cipher_cleanup)
559 - || !EVP_CIPHER_meth_set_impl_ctx_size(known_cipher_methods[i],
560 - sizeof(struct cipher_ctx))) {
561 - cipher_driver_info[i].status = DEVCRYPTO_STATUS_FAILURE;
562 - EVP_CIPHER_meth_free(known_cipher_methods[i]);
563 - known_cipher_methods[i] = NULL;
564 - } else {
565 - cipher_driver_info[i].status = DEVCRYPTO_STATUS_USABLE;
566 -#ifdef CIOCGSESSINFO
567 - siop.ses = sess.ses;
568 - if (ioctl(cfd, CIOCGSESSINFO, &siop) < 0) {
569 - cipher_driver_info[i].accelerated = DEVCRYPTO_ACCELERATION_UNKNOWN;
570 - } else {
571 - cipher_driver_info[i].driver_name =
572 - OPENSSL_strndup(siop.cipher_info.cra_driver_name,
573 - CRYPTODEV_MAX_ALG_NAME);
574 - if (!(siop.flags & SIOP_FLAG_KERNEL_DRIVER_ONLY))
575 - cipher_driver_info[i].accelerated = DEVCRYPTO_NOT_ACCELERATED;
576 - else
577 - cipher_driver_info[i].accelerated = DEVCRYPTO_ACCELERATED;
578 - }
579 -#endif /* CIOCGSESSINFO */
580 - }
581 - ioctl(cfd, CIOCFSESSION, &sess.ses);
582 - if (devcrypto_test_cipher(i)) {
583 - known_cipher_nids[known_cipher_nids_amount++] =
584 - cipher_data[i].nid;
585 - }
586 - }
587 -}
588 -
589 -static void rebuild_known_cipher_nids(ENGINE *e)
590 -{
591 - size_t i;
592 -
593 - for (i = 0, known_cipher_nids_amount = 0; i < OSSL_NELEM(cipher_data); i++) {
594 - if (devcrypto_test_cipher(i))
595 - known_cipher_nids[known_cipher_nids_amount++] = cipher_data[i].nid;
596 - }
597 - ENGINE_unregister_ciphers(e);
598 - ENGINE_register_ciphers(e);
599 -}
600 -
601 -static const EVP_CIPHER *get_cipher_method(int nid)
602 -{
603 - size_t i = get_cipher_data_index(nid);
604 -
605 - if (i == (size_t)-1)
606 - return NULL;
607 - return known_cipher_methods[i];
608 -}
609 -
610 -static int get_cipher_nids(const int **nids)
611 -{
612 - *nids = known_cipher_nids;
613 - return known_cipher_nids_amount;
614 -}
615 -
616 -static void destroy_cipher_method(int nid)
617 -{
618 - size_t i = get_cipher_data_index(nid);
619 -
620 - EVP_CIPHER_meth_free(known_cipher_methods[i]);
621 - known_cipher_methods[i] = NULL;
622 -}
623 -
624 -static void destroy_all_cipher_methods(void)
625 -{
626 - size_t i;
627 -
628 - for (i = 0; i < OSSL_NELEM(cipher_data); i++) {
629 - destroy_cipher_method(cipher_data[i].nid);
630 - OPENSSL_free(cipher_driver_info[i].driver_name);
631 - cipher_driver_info[i].driver_name = NULL;
632 - }
633 -}
634 -
635 -static int devcrypto_ciphers(ENGINE *e, const EVP_CIPHER **cipher,
636 - const int **nids, int nid)
637 -{
638 - if (cipher == NULL)
639 - return get_cipher_nids(nids);
640 -
641 - *cipher = get_cipher_method(nid);
642 -
643 - return *cipher != NULL;
644 -}
645 -
646 -static void devcrypto_select_all_ciphers(int *cipher_list)
647 -{
648 - size_t i;
649 -
650 - for (i = 0; i < OSSL_NELEM(cipher_data); i++)
651 - cipher_list[i] = 1;
652 -}
653 -
654 -static int cryptodev_select_cipher_cb(const char *str, int len, void *usr)
655 -{
656 - int *cipher_list = (int *)usr;
657 - char *name;
658 - const EVP_CIPHER *EVP;
659 - size_t i;
660 -
661 - if (len == 0)
662 - return 1;
663 - if (usr == NULL || (name = OPENSSL_strndup(str, len)) == NULL)
664 - return 0;
665 - EVP = EVP_get_cipherbyname(name);
666 - if (EVP == NULL)
667 - fprintf(stderr, "devcrypto: unknown cipher %s\n", name);
668 - else if ((i = find_cipher_data_index(EVP_CIPHER_nid(EVP))) != (size_t)-1)
669 - cipher_list[i] = 1;
670 - else
671 - fprintf(stderr, "devcrypto: cipher %s not available\n", name);
672 - OPENSSL_free(name);
673 - return 1;
674 -}
675 -
676 -static void dump_cipher_info(void)
677 -{
678 - size_t i;
679 - const char *name;
680 -
681 - fprintf (stderr, "Information about ciphers supported by the /dev/crypto"
682 - " engine:\n");
683 -#ifndef CIOCGSESSINFO
684 - fprintf(stderr, "CIOCGSESSINFO (session info call) unavailable\n");
685 -#endif
686 - for (i = 0; i < OSSL_NELEM(cipher_data); i++) {
687 - name = OBJ_nid2sn(cipher_data[i].nid);
688 - fprintf (stderr, "Cipher %s, NID=%d, /dev/crypto info: id=%d, ",
689 - name ? name : "unknown", cipher_data[i].nid,
690 - cipher_data[i].devcryptoid);
691 - if (cipher_driver_info[i].status == DEVCRYPTO_STATUS_NO_CIOCGSESSION ) {
692 - fprintf (stderr, "CIOCGSESSION (session open call) failed\n");
693 - continue;
694 - }
695 - fprintf (stderr, "driver=%s ", cipher_driver_info[i].driver_name ?
696 - cipher_driver_info[i].driver_name : "unknown");
697 - if (cipher_driver_info[i].accelerated == DEVCRYPTO_ACCELERATED)
698 - fprintf(stderr, "(hw accelerated)");
699 - else if (cipher_driver_info[i].accelerated == DEVCRYPTO_NOT_ACCELERATED)
700 - fprintf(stderr, "(software)");
701 - else
702 - fprintf(stderr, "(acceleration status unknown)");
703 - if (cipher_driver_info[i].status == DEVCRYPTO_STATUS_FAILURE)
704 - fprintf (stderr, ". Cipher setup failed");
705 - fprintf(stderr, "\n");
706 - }
707 - fprintf(stderr, "\n");
708 -}
709 -
710 -/*
711 - * We only support digests if the cryptodev implementation supports multiple
712 - * data updates and session copying. Otherwise, we would be forced to maintain
713 - * a cache, which is perilous if there's a lot of data coming in (if someone
714 - * wants to checksum an OpenSSL tarball, for example).
715 - */
716 -#if defined(CIOCCPHASH) && defined(COP_FLAG_UPDATE) && defined(COP_FLAG_FINAL)
717 -#define IMPLEMENT_DIGEST
718 -
719 -/******************************************************************************
720 - *
721 - * Digests
722 - *
723 - * Because they all do the same basic operation, we have only one set of
724 - * method functions for them all to share, and a mapping table between
725 - * NIDs and cryptodev IDs, with all the necessary size data.
726 - *
727 - *****/
728 -
729 -struct digest_ctx {
730 - struct session_op sess;
731 - /* This signals that the init function was called, not that it succeeded. */
732 - int init_called;
733 - unsigned char digest_res[HASH_MAX_LEN];
734 -};
735 -
736 -static const struct digest_data_st {
737 - int nid;
738 - int blocksize;
739 - int digestlen;
740 - int devcryptoid;
741 -} digest_data[] = {
742 -#ifndef OPENSSL_NO_MD5
743 - { NID_md5, /* MD5_CBLOCK */ 64, 16, CRYPTO_MD5 },
744 -#endif
745 - { NID_sha1, SHA_CBLOCK, 20, CRYPTO_SHA1 },
746 -#ifndef OPENSSL_NO_RMD160
747 -# if !defined(CHECK_BSD_STYLE_MACROS) || defined(CRYPTO_RIPEMD160)
748 - { NID_ripemd160, /* RIPEMD160_CBLOCK */ 64, 20, CRYPTO_RIPEMD160 },
749 -# endif
750 -#endif
751 -#if !defined(CHECK_BSD_STYLE_MACROS) || defined(CRYPTO_SHA2_224)
752 - { NID_sha224, SHA256_CBLOCK, 224 / 8, CRYPTO_SHA2_224 },
753 -#endif
754 -#if !defined(CHECK_BSD_STYLE_MACROS) || defined(CRYPTO_SHA2_256)
755 - { NID_sha256, SHA256_CBLOCK, 256 / 8, CRYPTO_SHA2_256 },
756 -#endif
757 -#if !defined(CHECK_BSD_STYLE_MACROS) || defined(CRYPTO_SHA2_384)
758 - { NID_sha384, SHA512_CBLOCK, 384 / 8, CRYPTO_SHA2_384 },
759 -#endif
760 -#if !defined(CHECK_BSD_STYLE_MACROS) || defined(CRYPTO_SHA2_512)
761 - { NID_sha512, SHA512_CBLOCK, 512 / 8, CRYPTO_SHA2_512 },
762 -#endif
763 -};
764 -
765 -static size_t find_digest_data_index(int nid)
766 -{
767 - size_t i;
768 -
769 - for (i = 0; i < OSSL_NELEM(digest_data); i++)
770 - if (nid == digest_data[i].nid)
771 - return i;
772 - return (size_t)-1;
773 -}
774 -
775 -static size_t get_digest_data_index(int nid)
776 -{
777 - size_t i = find_digest_data_index(nid);
778 -
779 - if (i != (size_t)-1)
780 - return i;
781 -
782 - /*
783 - * Code further down must make sure that only NIDs in the table above
784 - * are used. If any other NID reaches this function, there's a grave
785 - * coding error further down.
786 - */
787 - assert("Code that never should be reached" == NULL);
788 - return -1;
789 -}
790 -
791 -static const struct digest_data_st *get_digest_data(int nid)
792 -{
793 - return &digest_data[get_digest_data_index(nid)];
794 -}
795 -
796 -/*
797 - * Following are the five necessary functions to map OpenSSL functionality
798 - * with cryptodev: init, update, final, cleanup, and copy.
799 - */
800 -
801 -static int digest_init(EVP_MD_CTX *ctx)
802 -{
803 - struct digest_ctx *digest_ctx =
804 - (struct digest_ctx *)EVP_MD_CTX_md_data(ctx);
805 - const struct digest_data_st *digest_d =
806 - get_digest_data(EVP_MD_CTX_type(ctx));
807 -
808 - digest_ctx->init_called = 1;
809 -
810 - memset(&digest_ctx->sess, 0, sizeof(digest_ctx->sess));
811 - digest_ctx->sess.mac = digest_d->devcryptoid;
812 - if (ioctl(cfd, CIOCGSESSION, &digest_ctx->sess) < 0) {
813 - SYSerr(SYS_F_IOCTL, errno);
814 - return 0;
815 - }
816 -
817 - return 1;
818 -}
819 -
820 -static int digest_op(struct digest_ctx *ctx, const void *src, size_t srclen,
821 - void *res, unsigned int flags)
822 -{
823 - struct crypt_op cryp;
824 -
825 - memset(&cryp, 0, sizeof(cryp));
826 - cryp.ses = ctx->sess.ses;
827 - cryp.len = srclen;
828 - cryp.src = (void *)src;
829 - cryp.dst = NULL;
830 - cryp.mac = res;
831 - cryp.flags = flags;
832 - return ioctl(cfd, CIOCCRYPT, &cryp);
833 -}
834 -
835 -static int digest_update(EVP_MD_CTX *ctx, const void *data, size_t count)
836 -{
837 - struct digest_ctx *digest_ctx =
838 - (struct digest_ctx *)EVP_MD_CTX_md_data(ctx);
839 -
840 - if (count == 0)
841 - return 1;
842 -
843 - if (digest_ctx == NULL)
844 - return 0;
845 -
846 - if (EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_ONESHOT)) {
847 - if (digest_op(digest_ctx, data, count, digest_ctx->digest_res, 0) >= 0)
848 - return 1;
849 - } else if (digest_op(digest_ctx, data, count, NULL, COP_FLAG_UPDATE) >= 0) {
850 - return 1;
851 - }
852 -
853 - SYSerr(SYS_F_IOCTL, errno);
854 - return 0;
855 -}
856 -
857 -static int digest_final(EVP_MD_CTX *ctx, unsigned char *md)
858 -{
859 - struct digest_ctx *digest_ctx =
860 - (struct digest_ctx *)EVP_MD_CTX_md_data(ctx);
861 -
862 - if (md == NULL || digest_ctx == NULL)
863 - return 0;
864 -
865 - if (EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_ONESHOT)) {
866 - memcpy(md, digest_ctx->digest_res, EVP_MD_CTX_size(ctx));
867 - } else if (digest_op(digest_ctx, NULL, 0, md, COP_FLAG_FINAL) < 0) {
868 - SYSerr(SYS_F_IOCTL, errno);
869 - return 0;
870 - }
871 -
872 - return 1;
873 -}
874 -
875 -static int digest_copy(EVP_MD_CTX *to, const EVP_MD_CTX *from)
876 -{
877 - struct digest_ctx *digest_from =
878 - (struct digest_ctx *)EVP_MD_CTX_md_data(from);
879 - struct digest_ctx *digest_to =
880 - (struct digest_ctx *)EVP_MD_CTX_md_data(to);
881 - struct cphash_op cphash;
882 -
883 - if (digest_from == NULL || digest_from->init_called != 1)
884 - return 1;
885 -
886 - if (!digest_init(to)) {
887 - SYSerr(SYS_F_IOCTL, errno);
888 - return 0;
889 - }
890 -
891 - cphash.src_ses = digest_from->sess.ses;
892 - cphash.dst_ses = digest_to->sess.ses;
893 - if (ioctl(cfd, CIOCCPHASH, &cphash) < 0) {
894 - SYSerr(SYS_F_IOCTL, errno);
895 - return 0;
896 - }
897 - return 1;
898 -}
899 -
900 -static int digest_cleanup(EVP_MD_CTX *ctx)
901 -{
902 - struct digest_ctx *digest_ctx =
903 - (struct digest_ctx *)EVP_MD_CTX_md_data(ctx);
904 -
905 - if (digest_ctx == NULL)
906 - return 1;
907 -
908 - return clean_devcrypto_session(&digest_ctx->sess);
909 -}
910 -
911 -/*
912 - * Keep tables of known nids, associated methods, selected digests, and
913 - * driver info.
914 - * Note that known_digest_nids[] isn't necessarily indexed the same way as
915 - * digest_data[] above, which the other tables are.
916 - */
917 -static int known_digest_nids[OSSL_NELEM(digest_data)];
918 -static int known_digest_nids_amount = -1; /* -1 indicates not yet initialised */
919 -static EVP_MD *known_digest_methods[OSSL_NELEM(digest_data)] = { NULL, };
920 -static int selected_digests[OSSL_NELEM(digest_data)];
921 -static struct driver_info_st digest_driver_info[OSSL_NELEM(digest_data)];
922 -
923 -static int devcrypto_test_digest(size_t digest_data_index)
924 -{
925 - return (digest_driver_info[digest_data_index].status == DEVCRYPTO_STATUS_USABLE
926 - && selected_digests[digest_data_index] == 1
927 - && (digest_driver_info[digest_data_index].accelerated
928 - == DEVCRYPTO_ACCELERATED
929 - || use_softdrivers == DEVCRYPTO_USE_SOFTWARE
930 - || (digest_driver_info[digest_data_index].accelerated
931 - != DEVCRYPTO_NOT_ACCELERATED
932 - && use_softdrivers == DEVCRYPTO_REJECT_SOFTWARE)));
933 -}
934 -
935 -static void rebuild_known_digest_nids(ENGINE *e)
936 -{
937 - size_t i;
938 -
939 - for (i = 0, known_digest_nids_amount = 0; i < OSSL_NELEM(digest_data); i++) {
940 - if (devcrypto_test_digest(i))
941 - known_digest_nids[known_digest_nids_amount++] = digest_data[i].nid;
942 - }
943 - ENGINE_unregister_digests(e);
944 - ENGINE_register_digests(e);
945 -}
946 -
947 -static void prepare_digest_methods(void)
948 -{
949 - size_t i;
950 - struct session_op sess1, sess2;
951 -#ifdef CIOCGSESSINFO
952 - struct session_info_op siop;
953 -#endif
954 - struct cphash_op cphash;
955 -
956 - memset(&digest_driver_info, 0, sizeof(digest_driver_info));
957 -
958 - memset(&sess1, 0, sizeof(sess1));
959 - memset(&sess2, 0, sizeof(sess2));
960 -
961 - for (i = 0, known_digest_nids_amount = 0; i < OSSL_NELEM(digest_data);
962 - i++) {
963 -
964 - selected_digests[i] = 1;
965 -
966 - /*
967 - * Check that the digest is usable
968 - */
969 - sess1.mac = digest_data[i].devcryptoid;
970 - sess2.ses = 0;
971 - if (ioctl(cfd, CIOCGSESSION, &sess1) < 0) {
972 - digest_driver_info[i].status = DEVCRYPTO_STATUS_NO_CIOCGSESSION;
973 - goto finish;
974 - }
975 -
976 -#ifdef CIOCGSESSINFO
977 - /* gather hardware acceleration info from the driver */
978 - siop.ses = sess1.ses;
979 - if (ioctl(cfd, CIOCGSESSINFO, &siop) < 0) {
980 - digest_driver_info[i].accelerated = DEVCRYPTO_ACCELERATION_UNKNOWN;
981 - } else {
982 - digest_driver_info[i].driver_name =
983 - OPENSSL_strndup(siop.hash_info.cra_driver_name,
984 - CRYPTODEV_MAX_ALG_NAME);
985 - if (siop.flags & SIOP_FLAG_KERNEL_DRIVER_ONLY)
986 - digest_driver_info[i].accelerated = DEVCRYPTO_ACCELERATED;
987 - else
988 - digest_driver_info[i].accelerated = DEVCRYPTO_NOT_ACCELERATED;
989 - }
990 -#endif
991 -
992 - /* digest must be capable of hash state copy */
993 - sess2.mac = sess1.mac;
994 - if (ioctl(cfd, CIOCGSESSION, &sess2) < 0) {
995 - digest_driver_info[i].status = DEVCRYPTO_STATUS_FAILURE;
996 - goto finish;
997 - }
998 - cphash.src_ses = sess1.ses;
999 - cphash.dst_ses = sess2.ses;
1000 - if (ioctl(cfd, CIOCCPHASH, &cphash) < 0) {
1001 - digest_driver_info[i].status = DEVCRYPTO_STATUS_NO_CIOCCPHASH;
1002 - goto finish;
1003 - }
1004 - if ((known_digest_methods[i] = EVP_MD_meth_new(digest_data[i].nid,
1005 - NID_undef)) == NULL
1006 - || !EVP_MD_meth_set_input_blocksize(known_digest_methods[i],
1007 - digest_data[i].blocksize)
1008 - || !EVP_MD_meth_set_result_size(known_digest_methods[i],
1009 - digest_data[i].digestlen)
1010 - || !EVP_MD_meth_set_init(known_digest_methods[i], digest_init)
1011 - || !EVP_MD_meth_set_update(known_digest_methods[i], digest_update)
1012 - || !EVP_MD_meth_set_final(known_digest_methods[i], digest_final)
1013 - || !EVP_MD_meth_set_copy(known_digest_methods[i], digest_copy)
1014 - || !EVP_MD_meth_set_cleanup(known_digest_methods[i], digest_cleanup)
1015 - || !EVP_MD_meth_set_app_datasize(known_digest_methods[i],
1016 - sizeof(struct digest_ctx))) {
1017 - digest_driver_info[i].status = DEVCRYPTO_STATUS_FAILURE;
1018 - EVP_MD_meth_free(known_digest_methods[i]);
1019 - known_digest_methods[i] = NULL;
1020 - goto finish;
1021 - }
1022 - digest_driver_info[i].status = DEVCRYPTO_STATUS_USABLE;
1023 -finish:
1024 - ioctl(cfd, CIOCFSESSION, &sess1.ses);
1025 - if (sess2.ses != 0)
1026 - ioctl(cfd, CIOCFSESSION, &sess2.ses);
1027 - if (devcrypto_test_digest(i))
1028 - known_digest_nids[known_digest_nids_amount++] = digest_data[i].nid;
1029 - }
1030 -}
1031 -
1032 -static const EVP_MD *get_digest_method(int nid)
1033 -{
1034 - size_t i = get_digest_data_index(nid);
1035 -
1036 - if (i == (size_t)-1)
1037 - return NULL;
1038 - return known_digest_methods[i];
1039 -}
1040 -
1041 -static int get_digest_nids(const int **nids)
1042 -{
1043 - *nids = known_digest_nids;
1044 - return known_digest_nids_amount;
1045 -}
1046 -
1047 -static void destroy_digest_method(int nid)
1048 -{
1049 - size_t i = get_digest_data_index(nid);
1050 -
1051 - EVP_MD_meth_free(known_digest_methods[i]);
1052 - known_digest_methods[i] = NULL;
1053 -}
1054 -
1055 -static void destroy_all_digest_methods(void)
1056 -{
1057 - size_t i;
1058 -
1059 - for (i = 0; i < OSSL_NELEM(digest_data); i++) {
1060 - destroy_digest_method(digest_data[i].nid);
1061 - OPENSSL_free(digest_driver_info[i].driver_name);
1062 - digest_driver_info[i].driver_name = NULL;
1063 - }
1064 -}
1065 -
1066 -static int devcrypto_digests(ENGINE *e, const EVP_MD **digest,
1067 - const int **nids, int nid)
1068 -{
1069 - if (digest == NULL)
1070 - return get_digest_nids(nids);
1071 -
1072 - *digest = get_digest_method(nid);
1073 -
1074 - return *digest != NULL;
1075 -}
1076 -
1077 -static void devcrypto_select_all_digests(int *digest_list)
1078 -{
1079 - size_t i;
1080 -
1081 - for (i = 0; i < OSSL_NELEM(digest_data); i++)
1082 - digest_list[i] = 1;
1083 -}
1084 -
1085 -static int cryptodev_select_digest_cb(const char *str, int len, void *usr)
1086 -{
1087 - int *digest_list = (int *)usr;
1088 - char *name;
1089 - const EVP_MD *EVP;
1090 - size_t i;
1091 -
1092 - if (len == 0)
1093 - return 1;
1094 - if (usr == NULL || (name = OPENSSL_strndup(str, len)) == NULL)
1095 - return 0;
1096 - EVP = EVP_get_digestbyname(name);
1097 - if (EVP == NULL)
1098 - fprintf(stderr, "devcrypto: unknown digest %s\n", name);
1099 - else if ((i = find_digest_data_index(EVP_MD_type(EVP))) != (size_t)-1)
1100 - digest_list[i] = 1;
1101 - else
1102 - fprintf(stderr, "devcrypto: digest %s not available\n", name);
1103 - OPENSSL_free(name);
1104 - return 1;
1105 -}
1106 -
1107 -static void dump_digest_info(void)
1108 -{
1109 - size_t i;
1110 - const char *name;
1111 -
1112 - fprintf (stderr, "Information about digests supported by the /dev/crypto"
1113 - " engine:\n");
1114 -#ifndef CIOCGSESSINFO
1115 - fprintf(stderr, "CIOCGSESSINFO (session info call) unavailable\n");
1116 -#endif
1117 -
1118 - for (i = 0; i < OSSL_NELEM(digest_data); i++) {
1119 - name = OBJ_nid2sn(digest_data[i].nid);
1120 - fprintf (stderr, "Digest %s, NID=%d, /dev/crypto info: id=%d, driver=%s",
1121 - name ? name : "unknown", digest_data[i].nid,
1122 - digest_data[i].devcryptoid,
1123 - digest_driver_info[i].driver_name ? digest_driver_info[i].driver_name : "unknown");
1124 - if (digest_driver_info[i].status == DEVCRYPTO_STATUS_NO_CIOCGSESSION) {
1125 - fprintf (stderr, ". CIOCGSESSION (session open) failed\n");
1126 - continue;
1127 - }
1128 - if (digest_driver_info[i].accelerated == DEVCRYPTO_ACCELERATED)
1129 - fprintf(stderr, " (hw accelerated)");
1130 - else if (digest_driver_info[i].accelerated == DEVCRYPTO_NOT_ACCELERATED)
1131 - fprintf(stderr, " (software)");
1132 - else
1133 - fprintf(stderr, " (acceleration status unknown)");
1134 - if (cipher_driver_info[i].status == DEVCRYPTO_STATUS_FAILURE)
1135 - fprintf (stderr, ". Cipher setup failed\n");
1136 - else if (digest_driver_info[i].status == DEVCRYPTO_STATUS_NO_CIOCCPHASH)
1137 - fprintf(stderr, ", CIOCCPHASH failed\n");
1138 - else
1139 - fprintf(stderr, ", CIOCCPHASH capable\n");
1140 - }
1141 - fprintf(stderr, "\n");
1142 -}
1143 -
1144 -#endif
1145 -
1146 -/******************************************************************************
1147 - *
1148 - * CONTROL COMMANDS
1149 - *
1150 - *****/
1151 -
1152 -#define DEVCRYPTO_CMD_USE_SOFTDRIVERS ENGINE_CMD_BASE
1153 -#define DEVCRYPTO_CMD_CIPHERS (ENGINE_CMD_BASE + 1)
1154 -#define DEVCRYPTO_CMD_DIGESTS (ENGINE_CMD_BASE + 2)
1155 -#define DEVCRYPTO_CMD_DUMP_INFO (ENGINE_CMD_BASE + 3)
1156 -
1157 -/* Helper macros for CPP string composition */
1158 -#ifndef OPENSSL_MSTR
1159 -# define OPENSSL_MSTR_HELPER(x) #x
1160 -# define OPENSSL_MSTR(x) OPENSSL_MSTR_HELPER(x)
1161 -#endif
1162 -
1163 -static const ENGINE_CMD_DEFN devcrypto_cmds[] = {
1164 -#ifdef CIOCGSESSINFO
1165 - {DEVCRYPTO_CMD_USE_SOFTDRIVERS,
1166 - "USE_SOFTDRIVERS",
1167 - "specifies whether to use software (not accelerated) drivers ("
1168 - OPENSSL_MSTR(DEVCRYPTO_REQUIRE_ACCELERATED) "=use only accelerated drivers, "
1169 - OPENSSL_MSTR(DEVCRYPTO_USE_SOFTWARE) "=allow all drivers, "
1170 - OPENSSL_MSTR(DEVCRYPTO_REJECT_SOFTWARE)
1171 - "=use if acceleration can't be determined) [default="
1172 - OPENSSL_MSTR(DEVCRYPTO_DEFAULT_USE_SOFDTRIVERS) "]",
1173 - ENGINE_CMD_FLAG_NUMERIC},
1174 -#endif
1175 -
1176 - {DEVCRYPTO_CMD_CIPHERS,
1177 - "CIPHERS",
1178 - "either ALL, NONE, or a comma-separated list of ciphers to enable [default=ALL]",
1179 - ENGINE_CMD_FLAG_STRING},
1180 -
1181 -#ifdef IMPLEMENT_DIGEST
1182 - {DEVCRYPTO_CMD_DIGESTS,
1183 - "DIGESTS",
1184 - "either ALL, NONE, or a comma-separated list of digests to enable [default=ALL]",
1185 - ENGINE_CMD_FLAG_STRING},
1186 -#endif
1187 -
1188 - {DEVCRYPTO_CMD_DUMP_INFO,
1189 - "DUMP_INFO",
1190 - "dump info about each algorithm to stderr; use 'openssl engine -pre DUMP_INFO devcrypto'",
1191 - ENGINE_CMD_FLAG_NO_INPUT},
1192 -
1193 - {0, NULL, NULL, 0}
1194 -};
1195 -
1196 -static int devcrypto_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f) (void))
1197 -{
1198 - int *new_list;
1199 - switch (cmd) {
1200 -#ifdef CIOCGSESSINFO
1201 - case DEVCRYPTO_CMD_USE_SOFTDRIVERS:
1202 - switch (i) {
1203 - case DEVCRYPTO_REQUIRE_ACCELERATED:
1204 - case DEVCRYPTO_USE_SOFTWARE:
1205 - case DEVCRYPTO_REJECT_SOFTWARE:
1206 - break;
1207 - default:
1208 - fprintf(stderr, "devcrypto: invalid value (%ld) for USE_SOFTDRIVERS\n", i);
1209 - return 0;
1210 - }
1211 - if (use_softdrivers == i)
1212 - return 1;
1213 - use_softdrivers = i;
1214 -#ifdef IMPLEMENT_DIGEST
1215 - rebuild_known_digest_nids(e);
1216 -#endif
1217 - rebuild_known_cipher_nids(e);
1218 - return 1;
1219 -#endif /* CIOCGSESSINFO */
1220 -
1221 - case DEVCRYPTO_CMD_CIPHERS:
1222 - if (p == NULL)
1223 - return 1;
1224 - if (strcasecmp((const char *)p, "ALL") == 0) {
1225 - devcrypto_select_all_ciphers(selected_ciphers);
1226 - } else if (strcasecmp((const char*)p, "NONE") == 0) {
1227 - memset(selected_ciphers, 0, sizeof(selected_ciphers));
1228 - } else {
1229 - new_list=OPENSSL_zalloc(sizeof(selected_ciphers));
1230 - if (!CONF_parse_list(p, ',', 1, cryptodev_select_cipher_cb, new_list)) {
1231 - OPENSSL_free(new_list);
1232 - return 0;
1233 - }
1234 - memcpy(selected_ciphers, new_list, sizeof(selected_ciphers));
1235 - OPENSSL_free(new_list);
1236 - }
1237 - rebuild_known_cipher_nids(e);
1238 - return 1;
1239 -
1240 -#ifdef IMPLEMENT_DIGEST
1241 - case DEVCRYPTO_CMD_DIGESTS:
1242 - if (p == NULL)
1243 - return 1;
1244 - if (strcasecmp((const char *)p, "ALL") == 0) {
1245 - devcrypto_select_all_digests(selected_digests);
1246 - } else if (strcasecmp((const char*)p, "NONE") == 0) {
1247 - memset(selected_digests, 0, sizeof(selected_digests));
1248 - } else {
1249 - new_list=OPENSSL_zalloc(sizeof(selected_digests));
1250 - if (!CONF_parse_list(p, ',', 1, cryptodev_select_digest_cb, new_list)) {
1251 - OPENSSL_free(new_list);
1252 - return 0;
1253 - }
1254 - memcpy(selected_digests, new_list, sizeof(selected_digests));
1255 - OPENSSL_free(new_list);
1256 - }
1257 - rebuild_known_digest_nids(e);
1258 - return 1;
1259 -#endif /* IMPLEMENT_DIGEST */
1260 -
1261 - case DEVCRYPTO_CMD_DUMP_INFO:
1262 - dump_cipher_info();
1263 -#ifdef IMPLEMENT_DIGEST
1264 - dump_digest_info();
1265 -#endif
1266 - return 1;
1267 -
1268 - default:
1269 - break;
1270 - }
1271 - return 0;
1272 -}
1273 -
1274 -/******************************************************************************
1275 - *
1276 - * LOAD / UNLOAD
1277 - *
1278 - *****/
1279 -
1280 -static int devcrypto_unload(ENGINE *e)
1281 -{
1282 - destroy_all_cipher_methods();
1283 -#ifdef IMPLEMENT_DIGEST
1284 - destroy_all_digest_methods();
1285 -#endif
1286 -
1287 - close(cfd);
1288 -
1289 - return 1;
1290 -}
1291 -/*
1292 - * This engine is always built into libcrypto, so it doesn't offer any
1293 - * ability to be dynamically loadable.
1294 - */
1295 -void engine_load_devcrypto_int()
1296 -{
1297 - ENGINE *e = NULL;
1298 -
1299 - if ((cfd = open("/dev/crypto", O_RDWR, 0)) < 0) {
1300 -#ifndef ENGINE_DEVCRYPTO_DEBUG
1301 - if (errno != ENOENT)
1302 -#endif
1303 - fprintf(stderr, "Could not open /dev/crypto: %s\n", strerror(errno));
1304 - return;
1305 - }
1306 -
1307 - if ((e = ENGINE_new()) == NULL
1308 - || !ENGINE_set_destroy_function(e, devcrypto_unload)) {
1309 - ENGINE_free(e);
1310 - /*
1311 - * We know that devcrypto_unload() won't be called when one of the
1312 - * above two calls have failed, so we close cfd explicitly here to
1313 - * avoid leaking resources.
1314 - */
1315 - close(cfd);
1316 - return;
1317 - }
1318 -
1319 - prepare_cipher_methods();
1320 -#ifdef IMPLEMENT_DIGEST
1321 - prepare_digest_methods();
1322 -#endif
1323 -
1324 - if (!ENGINE_set_id(e, "devcrypto")
1325 - || !ENGINE_set_name(e, "/dev/crypto engine")
1326 - || !ENGINE_set_cmd_defns(e, devcrypto_cmds)
1327 - || !ENGINE_set_ctrl_function(e, devcrypto_ctrl)
1328 -
1329 -/*
1330 - * Asymmetric ciphers aren't well supported with /dev/crypto. Among the BSD
1331 - * implementations, it seems to only exist in FreeBSD, and regarding the
1332 - * parameters in its crypt_kop, the manual crypto(4) has this to say:
1333 - *
1334 - * The semantics of these arguments are currently undocumented.
1335 - *
1336 - * Reading through the FreeBSD source code doesn't give much more than
1337 - * their CRK_MOD_EXP implementation for ubsec.
1338 - *
1339 - * It doesn't look much better with cryptodev-linux. They have the crypt_kop
1340 - * structure as well as the command (CRK_*) in cryptodev.h, but no support
1341 - * seems to be implemented at all for the moment.
1342 - *
1343 - * At the time of writing, it seems impossible to write proper support for
1344 - * FreeBSD's asym features without some very deep knowledge and access to
1345 - * specific kernel modules.
1346 - *
1347 - * /Richard Levitte, 2017-05-11
1348 - */
1349 -#if 0
1350 -# ifndef OPENSSL_NO_RSA
1351 - || !ENGINE_set_RSA(e, devcrypto_rsa)
1352 -# endif
1353 -# ifndef OPENSSL_NO_DSA
1354 - || !ENGINE_set_DSA(e, devcrypto_dsa)
1355 -# endif
1356 -# ifndef OPENSSL_NO_DH
1357 - || !ENGINE_set_DH(e, devcrypto_dh)
1358 -# endif
1359 -# ifndef OPENSSL_NO_EC
1360 - || !ENGINE_set_EC(e, devcrypto_ec)
1361 -# endif
1362 -#endif
1363 - || !ENGINE_set_ciphers(e, devcrypto_ciphers)
1364 -#ifdef IMPLEMENT_DIGEST
1365 - || !ENGINE_set_digests(e, devcrypto_digests)
1366 -#endif
1367 - ) {
1368 - ENGINE_free(e);
1369 - return;
1370 - }
1371 -
1372 - ENGINE_add(e);
1373 - ENGINE_free(e); /* Loose our local reference */
1374 - ERR_clear_error();
1375 -}
1376 --- /dev/null
1377 +++ b/engines/e_devcrypto.c
1378 @@ -0,0 +1,1315 @@
1379 +/*
1380 + * Copyright 2017-2019 The OpenSSL Project Authors. All Rights Reserved.
1381 + *
1382 + * Licensed under the OpenSSL license (the "License"). You may not use
1383 + * this file except in compliance with the License. You can obtain a copy
1384 + * in the file LICENSE in the source distribution or at
1385 + * https://www.openssl.org/source/license.html
1386 + */
1387 +
1388 +#include "../e_os.h"
1389 +#include <string.h>
1390 +#include <sys/types.h>
1391 +#include <sys/stat.h>
1392 +#include <fcntl.h>
1393 +#include <sys/ioctl.h>
1394 +#include <unistd.h>
1395 +#include <assert.h>
1396 +
1397 +#include <openssl/conf.h>
1398 +#include <openssl/evp.h>
1399 +#include <openssl/err.h>
1400 +#include <openssl/engine.h>
1401 +#include <openssl/objects.h>
1402 +#include <crypto/cryptodev.h>
1403 +
1404 +/* #define ENGINE_DEVCRYPTO_DEBUG */
1405 +
1406 +#ifdef CRYPTO_ALGORITHM_MIN
1407 +# define CHECK_BSD_STYLE_MACROS
1408 +#endif
1409 +
1410 +#define engine_devcrypto_id "devcrypto"
1411 +
1412 +/*
1413 + * ONE global file descriptor for all sessions. This allows operations
1414 + * such as digest session data copying (see digest_copy()), but is also
1415 + * saner... why re-open /dev/crypto for every session?
1416 + */
1417 +static int cfd = -1;
1418 +#define DEVCRYPTO_REQUIRE_ACCELERATED 0 /* require confirmation of acceleration */
1419 +#define DEVCRYPTO_USE_SOFTWARE 1 /* allow software drivers */
1420 +#define DEVCRYPTO_REJECT_SOFTWARE 2 /* only disallow confirmed software drivers */
1421 +
1422 +#define DEVCRYPTO_DEFAULT_USE_SOFTDRIVERS DEVCRYPTO_REJECT_SOFTWARE
1423 +static int use_softdrivers = DEVCRYPTO_DEFAULT_USE_SOFTDRIVERS;
1424 +
1425 +/*
1426 + * cipher/digest status & acceleration definitions
1427 + * Make sure the defaults are set to 0
1428 + */
1429 +struct driver_info_st {
1430 + enum devcrypto_status_t {
1431 + DEVCRYPTO_STATUS_FAILURE = -3, /* unusable for other reason */
1432 + DEVCRYPTO_STATUS_NO_CIOCCPHASH = -2, /* hash state copy not supported */
1433 + DEVCRYPTO_STATUS_NO_CIOCGSESSION = -1, /* session open failed */
1434 + DEVCRYPTO_STATUS_UNKNOWN = 0, /* not tested yet */
1435 + DEVCRYPTO_STATUS_USABLE = 1 /* algo can be used */
1436 + } status;
1437 +
1438 + enum devcrypto_accelerated_t {
1439 + DEVCRYPTO_NOT_ACCELERATED = -1, /* software implemented */
1440 + DEVCRYPTO_ACCELERATION_UNKNOWN = 0, /* acceleration support unkown */
1441 + DEVCRYPTO_ACCELERATED = 1 /* hardware accelerated */
1442 + } accelerated;
1443 +
1444 + char *driver_name;
1445 +};
1446 +
1447 +#ifdef OPENSSL_NO_DYNAMIC_ENGINE
1448 +void engine_load_devcrypto_int(void);
1449 +#endif
1450 +
1451 +static int clean_devcrypto_session(struct session_op *sess) {
1452 + if (ioctl(cfd, CIOCFSESSION, &sess->ses) < 0) {
1453 + SYSerr(SYS_F_IOCTL, errno);
1454 + return 0;
1455 + }
1456 + memset(sess, 0, sizeof(struct session_op));
1457 + return 1;
1458 +}
1459 +
1460 +/******************************************************************************
1461 + *
1462 + * Ciphers
1463 + *
1464 + * Because they all do the same basic operation, we have only one set of
1465 + * method functions for them all to share, and a mapping table between
1466 + * NIDs and cryptodev IDs, with all the necessary size data.
1467 + *
1468 + *****/
1469 +
1470 +struct cipher_ctx {
1471 + struct session_op sess;
1472 + int op; /* COP_ENCRYPT or COP_DECRYPT */
1473 + unsigned long mode; /* EVP_CIPH_*_MODE */
1474 +
1475 + /* to handle ctr mode being a stream cipher */
1476 + unsigned char partial[EVP_MAX_BLOCK_LENGTH];
1477 + unsigned int blocksize, num;
1478 +};
1479 +
1480 +static const struct cipher_data_st {
1481 + int nid;
1482 + int blocksize;
1483 + int keylen;
1484 + int ivlen;
1485 + int flags;
1486 + int devcryptoid;
1487 +} cipher_data[] = {
1488 +#ifndef OPENSSL_NO_DES
1489 + { NID_des_cbc, 8, 8, 8, EVP_CIPH_CBC_MODE, CRYPTO_DES_CBC },
1490 + { NID_des_ede3_cbc, 8, 24, 8, EVP_CIPH_CBC_MODE, CRYPTO_3DES_CBC },
1491 +#endif
1492 +#ifndef OPENSSL_NO_BF
1493 + { NID_bf_cbc, 8, 16, 8, EVP_CIPH_CBC_MODE, CRYPTO_BLF_CBC },
1494 +#endif
1495 +#ifndef OPENSSL_NO_CAST
1496 + { NID_cast5_cbc, 8, 16, 8, EVP_CIPH_CBC_MODE, CRYPTO_CAST_CBC },
1497 +#endif
1498 + { NID_aes_128_cbc, 16, 128 / 8, 16, EVP_CIPH_CBC_MODE, CRYPTO_AES_CBC },
1499 + { NID_aes_192_cbc, 16, 192 / 8, 16, EVP_CIPH_CBC_MODE, CRYPTO_AES_CBC },
1500 + { NID_aes_256_cbc, 16, 256 / 8, 16, EVP_CIPH_CBC_MODE, CRYPTO_AES_CBC },
1501 +#ifndef OPENSSL_NO_RC4
1502 + { NID_rc4, 1, 16, 0, EVP_CIPH_STREAM_CIPHER, CRYPTO_ARC4 },
1503 +#endif
1504 +#if !defined(CHECK_BSD_STYLE_MACROS) || defined(CRYPTO_AES_CTR)
1505 + { NID_aes_128_ctr, 16, 128 / 8, 16, EVP_CIPH_CTR_MODE, CRYPTO_AES_CTR },
1506 + { NID_aes_192_ctr, 16, 192 / 8, 16, EVP_CIPH_CTR_MODE, CRYPTO_AES_CTR },
1507 + { NID_aes_256_ctr, 16, 256 / 8, 16, EVP_CIPH_CTR_MODE, CRYPTO_AES_CTR },
1508 +#endif
1509 +#if 0 /* Not yet supported */
1510 + { NID_aes_128_xts, 16, 128 / 8 * 2, 16, EVP_CIPH_XTS_MODE, CRYPTO_AES_XTS },
1511 + { NID_aes_256_xts, 16, 256 / 8 * 2, 16, EVP_CIPH_XTS_MODE, CRYPTO_AES_XTS },
1512 +#endif
1513 +#if !defined(CHECK_BSD_STYLE_MACROS) || defined(CRYPTO_AES_ECB)
1514 + { NID_aes_128_ecb, 16, 128 / 8, 0, EVP_CIPH_ECB_MODE, CRYPTO_AES_ECB },
1515 + { NID_aes_192_ecb, 16, 192 / 8, 0, EVP_CIPH_ECB_MODE, CRYPTO_AES_ECB },
1516 + { NID_aes_256_ecb, 16, 256 / 8, 0, EVP_CIPH_ECB_MODE, CRYPTO_AES_ECB },
1517 +#endif
1518 +#if 0 /* Not yet supported */
1519 + { NID_aes_128_gcm, 16, 128 / 8, 16, EVP_CIPH_GCM_MODE, CRYPTO_AES_GCM },
1520 + { NID_aes_192_gcm, 16, 192 / 8, 16, EVP_CIPH_GCM_MODE, CRYPTO_AES_GCM },
1521 + { NID_aes_256_gcm, 16, 256 / 8, 16, EVP_CIPH_GCM_MODE, CRYPTO_AES_GCM },
1522 +#endif
1523 +#ifndef OPENSSL_NO_CAMELLIA
1524 + { NID_camellia_128_cbc, 16, 128 / 8, 16, EVP_CIPH_CBC_MODE,
1525 + CRYPTO_CAMELLIA_CBC },
1526 + { NID_camellia_192_cbc, 16, 192 / 8, 16, EVP_CIPH_CBC_MODE,
1527 + CRYPTO_CAMELLIA_CBC },
1528 + { NID_camellia_256_cbc, 16, 256 / 8, 16, EVP_CIPH_CBC_MODE,
1529 + CRYPTO_CAMELLIA_CBC },
1530 +#endif
1531 +};
1532 +
1533 +static size_t find_cipher_data_index(int nid)
1534 +{
1535 + size_t i;
1536 +
1537 + for (i = 0; i < OSSL_NELEM(cipher_data); i++)
1538 + if (nid == cipher_data[i].nid)
1539 + return i;
1540 + return (size_t)-1;
1541 +}
1542 +
1543 +static size_t get_cipher_data_index(int nid)
1544 +{
1545 + size_t i = find_cipher_data_index(nid);
1546 +
1547 + if (i != (size_t)-1)
1548 + return i;
1549 +
1550 + /*
1551 + * Code further down must make sure that only NIDs in the table above
1552 + * are used. If any other NID reaches this function, there's a grave
1553 + * coding error further down.
1554 + */
1555 + assert("Code that never should be reached" == NULL);
1556 + return -1;
1557 +}
1558 +
1559 +static const struct cipher_data_st *get_cipher_data(int nid)
1560 +{
1561 + return &cipher_data[get_cipher_data_index(nid)];
1562 +}
1563 +
1564 +/*
1565 + * Following are the three necessary functions to map OpenSSL functionality
1566 + * with cryptodev.
1567 + */
1568 +
1569 +static int cipher_init(EVP_CIPHER_CTX *ctx, const unsigned char *key,
1570 + const unsigned char *iv, int enc)
1571 +{
1572 + struct cipher_ctx *cipher_ctx =
1573 + (struct cipher_ctx *)EVP_CIPHER_CTX_get_cipher_data(ctx);
1574 + const struct cipher_data_st *cipher_d =
1575 + get_cipher_data(EVP_CIPHER_CTX_nid(ctx));
1576 +
1577 + /* cleanup a previous session */
1578 + if (cipher_ctx->sess.ses != 0 &&
1579 + clean_devcrypto_session(&cipher_ctx->sess) == 0)
1580 + return 0;
1581 +
1582 + cipher_ctx->sess.cipher = cipher_d->devcryptoid;
1583 + cipher_ctx->sess.keylen = cipher_d->keylen;
1584 + cipher_ctx->sess.key = (void *)key;
1585 + cipher_ctx->op = enc ? COP_ENCRYPT : COP_DECRYPT;
1586 + cipher_ctx->mode = cipher_d->flags & EVP_CIPH_MODE;
1587 + cipher_ctx->blocksize = cipher_d->blocksize;
1588 + if (ioctl(cfd, CIOCGSESSION, &cipher_ctx->sess) < 0) {
1589 + SYSerr(SYS_F_IOCTL, errno);
1590 + return 0;
1591 + }
1592 +
1593 + return 1;
1594 +}
1595 +
1596 +static int cipher_do_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
1597 + const unsigned char *in, size_t inl)
1598 +{
1599 + struct cipher_ctx *cipher_ctx =
1600 + (struct cipher_ctx *)EVP_CIPHER_CTX_get_cipher_data(ctx);
1601 + struct crypt_op cryp;
1602 + unsigned char *iv = EVP_CIPHER_CTX_iv_noconst(ctx);
1603 +#if !defined(COP_FLAG_WRITE_IV)
1604 + unsigned char saved_iv[EVP_MAX_IV_LENGTH];
1605 + const unsigned char *ivptr;
1606 + size_t nblocks, ivlen;
1607 +#endif
1608 +
1609 + memset(&cryp, 0, sizeof(cryp));
1610 + cryp.ses = cipher_ctx->sess.ses;
1611 + cryp.len = inl;
1612 + cryp.src = (void *)in;
1613 + cryp.dst = (void *)out;
1614 + cryp.iv = (void *)iv;
1615 + cryp.op = cipher_ctx->op;
1616 +#if !defined(COP_FLAG_WRITE_IV)
1617 + cryp.flags = 0;
1618 +
1619 + ivlen = EVP_CIPHER_CTX_iv_length(ctx);
1620 + if (ivlen > 0)
1621 + switch (cipher_ctx->mode) {
1622 + case EVP_CIPH_CBC_MODE:
1623 + assert(inl >= ivlen);
1624 + if (!EVP_CIPHER_CTX_encrypting(ctx)) {
1625 + ivptr = in + inl - ivlen;
1626 + memcpy(saved_iv, ivptr, ivlen);
1627 + }
1628 + break;
1629 +
1630 + case EVP_CIPH_CTR_MODE:
1631 + break;
1632 +
1633 + default: /* should not happen */
1634 + return 0;
1635 + }
1636 +#else
1637 + cryp.flags = COP_FLAG_WRITE_IV;
1638 +#endif
1639 +
1640 + if (ioctl(cfd, CIOCCRYPT, &cryp) < 0) {
1641 + SYSerr(SYS_F_IOCTL, errno);
1642 + return 0;
1643 + }
1644 +
1645 +#if !defined(COP_FLAG_WRITE_IV)
1646 + if (ivlen > 0)
1647 + switch (cipher_ctx->mode) {
1648 + case EVP_CIPH_CBC_MODE:
1649 + assert(inl >= ivlen);
1650 + if (EVP_CIPHER_CTX_encrypting(ctx))
1651 + ivptr = out + inl - ivlen;
1652 + else
1653 + ivptr = saved_iv;
1654 +
1655 + memcpy(iv, ivptr, ivlen);
1656 + break;
1657 +
1658 + case EVP_CIPH_CTR_MODE:
1659 + nblocks = (inl + cipher_ctx->blocksize - 1)
1660 + / cipher_ctx->blocksize;
1661 + do {
1662 + ivlen--;
1663 + nblocks += iv[ivlen];
1664 + iv[ivlen] = (uint8_t) nblocks;
1665 + nblocks >>= 8;
1666 + } while (ivlen);
1667 + break;
1668 +
1669 + default: /* should not happen */
1670 + return 0;
1671 + }
1672 +#endif
1673 +
1674 + return 1;
1675 +}
1676 +
1677 +static int ctr_do_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
1678 + const unsigned char *in, size_t inl)
1679 +{
1680 + struct cipher_ctx *cipher_ctx =
1681 + (struct cipher_ctx *)EVP_CIPHER_CTX_get_cipher_data(ctx);
1682 + size_t nblocks, len;
1683 +
1684 + /* initial partial block */
1685 + while (cipher_ctx->num && inl) {
1686 + (*out++) = *(in++) ^ cipher_ctx->partial[cipher_ctx->num];
1687 + --inl;
1688 + cipher_ctx->num = (cipher_ctx->num + 1) % cipher_ctx->blocksize;
1689 + }
1690 +
1691 + /* full blocks */
1692 + if (inl > (unsigned int) cipher_ctx->blocksize) {
1693 + nblocks = inl/cipher_ctx->blocksize;
1694 + len = nblocks * cipher_ctx->blocksize;
1695 + if (cipher_do_cipher(ctx, out, in, len) < 1)
1696 + return 0;
1697 + inl -= len;
1698 + out += len;
1699 + in += len;
1700 + }
1701 +
1702 + /* final partial block */
1703 + if (inl) {
1704 + memset(cipher_ctx->partial, 0, cipher_ctx->blocksize);
1705 + if (cipher_do_cipher(ctx, cipher_ctx->partial, cipher_ctx->partial,
1706 + cipher_ctx->blocksize) < 1)
1707 + return 0;
1708 + while (inl--) {
1709 + out[cipher_ctx->num] = in[cipher_ctx->num]
1710 + ^ cipher_ctx->partial[cipher_ctx->num];
1711 + cipher_ctx->num++;
1712 + }
1713 + }
1714 +
1715 + return 1;
1716 +}
1717 +
1718 +static int cipher_ctrl(EVP_CIPHER_CTX *ctx, int type, int p1, void* p2)
1719 +{
1720 + struct cipher_ctx *cipher_ctx =
1721 + (struct cipher_ctx *)EVP_CIPHER_CTX_get_cipher_data(ctx);
1722 + EVP_CIPHER_CTX *to_ctx = (EVP_CIPHER_CTX *)p2;
1723 + struct cipher_ctx *to_cipher_ctx;
1724 +
1725 + switch (type) {
1726 +
1727 + case EVP_CTRL_COPY:
1728 + if (cipher_ctx == NULL)
1729 + return 1;
1730 + /* when copying the context, a new session needs to be initialized */
1731 + to_cipher_ctx =
1732 + (struct cipher_ctx *)EVP_CIPHER_CTX_get_cipher_data(to_ctx);
1733 + memset(&to_cipher_ctx->sess, 0, sizeof(to_cipher_ctx->sess));
1734 + return cipher_init(to_ctx, cipher_ctx->sess.key, EVP_CIPHER_CTX_iv(ctx),
1735 + (cipher_ctx->op == COP_ENCRYPT));
1736 +
1737 + case EVP_CTRL_INIT:
1738 + memset(&cipher_ctx->sess, 0, sizeof(cipher_ctx->sess));
1739 + return 1;
1740 +
1741 + default:
1742 + break;
1743 + }
1744 +
1745 + return -1;
1746 +}
1747 +
1748 +static int cipher_cleanup(EVP_CIPHER_CTX *ctx)
1749 +{
1750 + struct cipher_ctx *cipher_ctx =
1751 + (struct cipher_ctx *)EVP_CIPHER_CTX_get_cipher_data(ctx);
1752 +
1753 + return clean_devcrypto_session(&cipher_ctx->sess);
1754 +}
1755 +
1756 +/*
1757 + * Keep tables of known nids, associated methods, selected ciphers, and driver
1758 + * info.
1759 + * Note that known_cipher_nids[] isn't necessarily indexed the same way as
1760 + * cipher_data[] above, which the other tables are.
1761 + */
1762 +static int known_cipher_nids[OSSL_NELEM(cipher_data)];
1763 +static int known_cipher_nids_amount = -1; /* -1 indicates not yet initialised */
1764 +static EVP_CIPHER *known_cipher_methods[OSSL_NELEM(cipher_data)] = { NULL, };
1765 +static int selected_ciphers[OSSL_NELEM(cipher_data)];
1766 +static struct driver_info_st cipher_driver_info[OSSL_NELEM(cipher_data)];
1767 +
1768 +
1769 +static int devcrypto_test_cipher(size_t cipher_data_index)
1770 +{
1771 + return (cipher_driver_info[cipher_data_index].status == DEVCRYPTO_STATUS_USABLE
1772 + && selected_ciphers[cipher_data_index] == 1
1773 + && (cipher_driver_info[cipher_data_index].accelerated
1774 + == DEVCRYPTO_ACCELERATED
1775 + || use_softdrivers == DEVCRYPTO_USE_SOFTWARE
1776 + || (cipher_driver_info[cipher_data_index].accelerated
1777 + != DEVCRYPTO_NOT_ACCELERATED
1778 + && use_softdrivers == DEVCRYPTO_REJECT_SOFTWARE)));
1779 +}
1780 +
1781 +static void prepare_cipher_methods(void)
1782 +{
1783 + size_t i;
1784 + struct session_op sess;
1785 + unsigned long cipher_mode;
1786 +#ifdef CIOCGSESSINFO
1787 + struct session_info_op siop;
1788 +#endif
1789 +
1790 + memset(&cipher_driver_info, 0, sizeof(cipher_driver_info));
1791 +
1792 + memset(&sess, 0, sizeof(sess));
1793 + sess.key = (void *)"01234567890123456789012345678901234567890123456789";
1794 +
1795 + for (i = 0, known_cipher_nids_amount = 0;
1796 + i < OSSL_NELEM(cipher_data); i++) {
1797 +
1798 + selected_ciphers[i] = 1;
1799 + /*
1800 + * Check that the cipher is usable
1801 + */
1802 + sess.cipher = cipher_data[i].devcryptoid;
1803 + sess.keylen = cipher_data[i].keylen;
1804 + if (ioctl(cfd, CIOCGSESSION, &sess) < 0) {
1805 + cipher_driver_info[i].status = DEVCRYPTO_STATUS_NO_CIOCGSESSION;
1806 + continue;
1807 + }
1808 +
1809 + cipher_mode = cipher_data[i].flags & EVP_CIPH_MODE;
1810 +
1811 + if ((known_cipher_methods[i] =
1812 + EVP_CIPHER_meth_new(cipher_data[i].nid,
1813 + cipher_mode == EVP_CIPH_CTR_MODE ? 1 :
1814 + cipher_data[i].blocksize,
1815 + cipher_data[i].keylen)) == NULL
1816 + || !EVP_CIPHER_meth_set_iv_length(known_cipher_methods[i],
1817 + cipher_data[i].ivlen)
1818 + || !EVP_CIPHER_meth_set_flags(known_cipher_methods[i],
1819 + cipher_data[i].flags
1820 + | EVP_CIPH_CUSTOM_COPY
1821 + | EVP_CIPH_CTRL_INIT
1822 + | EVP_CIPH_FLAG_DEFAULT_ASN1)
1823 + || !EVP_CIPHER_meth_set_init(known_cipher_methods[i], cipher_init)
1824 + || !EVP_CIPHER_meth_set_do_cipher(known_cipher_methods[i],
1825 + cipher_mode == EVP_CIPH_CTR_MODE ?
1826 + ctr_do_cipher :
1827 + cipher_do_cipher)
1828 + || !EVP_CIPHER_meth_set_ctrl(known_cipher_methods[i], cipher_ctrl)
1829 + || !EVP_CIPHER_meth_set_cleanup(known_cipher_methods[i],
1830 + cipher_cleanup)
1831 + || !EVP_CIPHER_meth_set_impl_ctx_size(known_cipher_methods[i],
1832 + sizeof(struct cipher_ctx))) {
1833 + cipher_driver_info[i].status = DEVCRYPTO_STATUS_FAILURE;
1834 + EVP_CIPHER_meth_free(known_cipher_methods[i]);
1835 + known_cipher_methods[i] = NULL;
1836 + } else {
1837 + cipher_driver_info[i].status = DEVCRYPTO_STATUS_USABLE;
1838 +#ifdef CIOCGSESSINFO
1839 + siop.ses = sess.ses;
1840 + if (ioctl(cfd, CIOCGSESSINFO, &siop) < 0) {
1841 + cipher_driver_info[i].accelerated = DEVCRYPTO_ACCELERATION_UNKNOWN;
1842 + } else {
1843 + cipher_driver_info[i].driver_name =
1844 + OPENSSL_strndup(siop.cipher_info.cra_driver_name,
1845 + CRYPTODEV_MAX_ALG_NAME);
1846 + if (!(siop.flags & SIOP_FLAG_KERNEL_DRIVER_ONLY))
1847 + cipher_driver_info[i].accelerated = DEVCRYPTO_NOT_ACCELERATED;
1848 + else
1849 + cipher_driver_info[i].accelerated = DEVCRYPTO_ACCELERATED;
1850 + }
1851 +#endif /* CIOCGSESSINFO */
1852 + }
1853 + ioctl(cfd, CIOCFSESSION, &sess.ses);
1854 + if (devcrypto_test_cipher(i)) {
1855 + known_cipher_nids[known_cipher_nids_amount++] =
1856 + cipher_data[i].nid;
1857 + }
1858 + }
1859 +}
1860 +
1861 +static void rebuild_known_cipher_nids(ENGINE *e)
1862 +{
1863 + size_t i;
1864 +
1865 + for (i = 0, known_cipher_nids_amount = 0; i < OSSL_NELEM(cipher_data); i++) {
1866 + if (devcrypto_test_cipher(i))
1867 + known_cipher_nids[known_cipher_nids_amount++] = cipher_data[i].nid;
1868 + }
1869 + ENGINE_unregister_ciphers(e);
1870 + ENGINE_register_ciphers(e);
1871 +}
1872 +
1873 +static const EVP_CIPHER *get_cipher_method(int nid)
1874 +{
1875 + size_t i = get_cipher_data_index(nid);
1876 +
1877 + if (i == (size_t)-1)
1878 + return NULL;
1879 + return known_cipher_methods[i];
1880 +}
1881 +
1882 +static int get_cipher_nids(const int **nids)
1883 +{
1884 + *nids = known_cipher_nids;
1885 + return known_cipher_nids_amount;
1886 +}
1887 +
1888 +static void destroy_cipher_method(int nid)
1889 +{
1890 + size_t i = get_cipher_data_index(nid);
1891 +
1892 + EVP_CIPHER_meth_free(known_cipher_methods[i]);
1893 + known_cipher_methods[i] = NULL;
1894 +}
1895 +
1896 +static void destroy_all_cipher_methods(void)
1897 +{
1898 + size_t i;
1899 +
1900 + for (i = 0; i < OSSL_NELEM(cipher_data); i++) {
1901 + destroy_cipher_method(cipher_data[i].nid);
1902 + OPENSSL_free(cipher_driver_info[i].driver_name);
1903 + cipher_driver_info[i].driver_name = NULL;
1904 + }
1905 +}
1906 +
1907 +static int devcrypto_ciphers(ENGINE *e, const EVP_CIPHER **cipher,
1908 + const int **nids, int nid)
1909 +{
1910 + if (cipher == NULL)
1911 + return get_cipher_nids(nids);
1912 +
1913 + *cipher = get_cipher_method(nid);
1914 +
1915 + return *cipher != NULL;
1916 +}
1917 +
1918 +static void devcrypto_select_all_ciphers(int *cipher_list)
1919 +{
1920 + size_t i;
1921 +
1922 + for (i = 0; i < OSSL_NELEM(cipher_data); i++)
1923 + cipher_list[i] = 1;
1924 +}
1925 +
1926 +static int cryptodev_select_cipher_cb(const char *str, int len, void *usr)
1927 +{
1928 + int *cipher_list = (int *)usr;
1929 + char *name;
1930 + const EVP_CIPHER *EVP;
1931 + size_t i;
1932 +
1933 + if (len == 0)
1934 + return 1;
1935 + if (usr == NULL || (name = OPENSSL_strndup(str, len)) == NULL)
1936 + return 0;
1937 + EVP = EVP_get_cipherbyname(name);
1938 + if (EVP == NULL)
1939 + fprintf(stderr, "devcrypto: unknown cipher %s\n", name);
1940 + else if ((i = find_cipher_data_index(EVP_CIPHER_nid(EVP))) != (size_t)-1)
1941 + cipher_list[i] = 1;
1942 + else
1943 + fprintf(stderr, "devcrypto: cipher %s not available\n", name);
1944 + OPENSSL_free(name);
1945 + return 1;
1946 +}
1947 +
1948 +static void dump_cipher_info(void)
1949 +{
1950 + size_t i;
1951 + const char *name;
1952 +
1953 + fprintf (stderr, "Information about ciphers supported by the /dev/crypto"
1954 + " engine:\n");
1955 +#ifndef CIOCGSESSINFO
1956 + fprintf(stderr, "CIOCGSESSINFO (session info call) unavailable\n");
1957 +#endif
1958 + for (i = 0; i < OSSL_NELEM(cipher_data); i++) {
1959 + name = OBJ_nid2sn(cipher_data[i].nid);
1960 + fprintf (stderr, "Cipher %s, NID=%d, /dev/crypto info: id=%d, ",
1961 + name ? name : "unknown", cipher_data[i].nid,
1962 + cipher_data[i].devcryptoid);
1963 + if (cipher_driver_info[i].status == DEVCRYPTO_STATUS_NO_CIOCGSESSION ) {
1964 + fprintf (stderr, "CIOCGSESSION (session open call) failed\n");
1965 + continue;
1966 + }
1967 + fprintf (stderr, "driver=%s ", cipher_driver_info[i].driver_name ?
1968 + cipher_driver_info[i].driver_name : "unknown");
1969 + if (cipher_driver_info[i].accelerated == DEVCRYPTO_ACCELERATED)
1970 + fprintf(stderr, "(hw accelerated)");
1971 + else if (cipher_driver_info[i].accelerated == DEVCRYPTO_NOT_ACCELERATED)
1972 + fprintf(stderr, "(software)");
1973 + else
1974 + fprintf(stderr, "(acceleration status unknown)");
1975 + if (cipher_driver_info[i].status == DEVCRYPTO_STATUS_FAILURE)
1976 + fprintf (stderr, ". Cipher setup failed");
1977 + fprintf(stderr, "\n");
1978 + }
1979 + fprintf(stderr, "\n");
1980 +}
1981 +
1982 +/*
1983 + * We only support digests if the cryptodev implementation supports multiple
1984 + * data updates and session copying. Otherwise, we would be forced to maintain
1985 + * a cache, which is perilous if there's a lot of data coming in (if someone
1986 + * wants to checksum an OpenSSL tarball, for example).
1987 + */
1988 +#if defined(CIOCCPHASH) && defined(COP_FLAG_UPDATE) && defined(COP_FLAG_FINAL)
1989 +#define IMPLEMENT_DIGEST
1990 +
1991 +/******************************************************************************
1992 + *
1993 + * Digests
1994 + *
1995 + * Because they all do the same basic operation, we have only one set of
1996 + * method functions for them all to share, and a mapping table between
1997 + * NIDs and cryptodev IDs, with all the necessary size data.
1998 + *
1999 + *****/
2000 +
2001 +struct digest_ctx {
2002 + struct session_op sess;
2003 + /* This signals that the init function was called, not that it succeeded. */
2004 + int init_called;
2005 + unsigned char digest_res[HASH_MAX_LEN];
2006 +};
2007 +
2008 +static const struct digest_data_st {
2009 + int nid;
2010 + int blocksize;
2011 + int digestlen;
2012 + int devcryptoid;
2013 +} digest_data[] = {
2014 +#ifndef OPENSSL_NO_MD5
2015 + { NID_md5, /* MD5_CBLOCK */ 64, 16, CRYPTO_MD5 },
2016 +#endif
2017 + { NID_sha1, SHA_CBLOCK, 20, CRYPTO_SHA1 },
2018 +#ifndef OPENSSL_NO_RMD160
2019 +# if !defined(CHECK_BSD_STYLE_MACROS) || defined(CRYPTO_RIPEMD160)
2020 + { NID_ripemd160, /* RIPEMD160_CBLOCK */ 64, 20, CRYPTO_RIPEMD160 },
2021 +# endif
2022 +#endif
2023 +#if !defined(CHECK_BSD_STYLE_MACROS) || defined(CRYPTO_SHA2_224)
2024 + { NID_sha224, SHA256_CBLOCK, 224 / 8, CRYPTO_SHA2_224 },
2025 +#endif
2026 +#if !defined(CHECK_BSD_STYLE_MACROS) || defined(CRYPTO_SHA2_256)
2027 + { NID_sha256, SHA256_CBLOCK, 256 / 8, CRYPTO_SHA2_256 },
2028 +#endif
2029 +#if !defined(CHECK_BSD_STYLE_MACROS) || defined(CRYPTO_SHA2_384)
2030 + { NID_sha384, SHA512_CBLOCK, 384 / 8, CRYPTO_SHA2_384 },
2031 +#endif
2032 +#if !defined(CHECK_BSD_STYLE_MACROS) || defined(CRYPTO_SHA2_512)
2033 + { NID_sha512, SHA512_CBLOCK, 512 / 8, CRYPTO_SHA2_512 },
2034 +#endif
2035 +};
2036 +
2037 +static size_t find_digest_data_index(int nid)
2038 +{
2039 + size_t i;
2040 +
2041 + for (i = 0; i < OSSL_NELEM(digest_data); i++)
2042 + if (nid == digest_data[i].nid)
2043 + return i;
2044 + return (size_t)-1;
2045 +}
2046 +
2047 +static size_t get_digest_data_index(int nid)
2048 +{
2049 + size_t i = find_digest_data_index(nid);
2050 +
2051 + if (i != (size_t)-1)
2052 + return i;
2053 +
2054 + /*
2055 + * Code further down must make sure that only NIDs in the table above
2056 + * are used. If any other NID reaches this function, there's a grave
2057 + * coding error further down.
2058 + */
2059 + assert("Code that never should be reached" == NULL);
2060 + return -1;
2061 +}
2062 +
2063 +static const struct digest_data_st *get_digest_data(int nid)
2064 +{
2065 + return &digest_data[get_digest_data_index(nid)];
2066 +}
2067 +
2068 +/*
2069 + * Following are the five necessary functions to map OpenSSL functionality
2070 + * with cryptodev: init, update, final, cleanup, and copy.
2071 + */
2072 +
2073 +static int digest_init(EVP_MD_CTX *ctx)
2074 +{
2075 + struct digest_ctx *digest_ctx =
2076 + (struct digest_ctx *)EVP_MD_CTX_md_data(ctx);
2077 + const struct digest_data_st *digest_d =
2078 + get_digest_data(EVP_MD_CTX_type(ctx));
2079 +
2080 + digest_ctx->init_called = 1;
2081 +
2082 + memset(&digest_ctx->sess, 0, sizeof(digest_ctx->sess));
2083 + digest_ctx->sess.mac = digest_d->devcryptoid;
2084 + if (ioctl(cfd, CIOCGSESSION, &digest_ctx->sess) < 0) {
2085 + SYSerr(SYS_F_IOCTL, errno);
2086 + return 0;
2087 + }
2088 + return 1;
2089 +}
2090 +
2091 +static int digest_op(struct digest_ctx *ctx, const void *src, size_t srclen,
2092 + void *res, unsigned int flags)
2093 +{
2094 + struct crypt_op cryp;
2095 +
2096 + memset(&cryp, 0, sizeof(cryp));
2097 + cryp.ses = ctx->sess.ses;
2098 + cryp.len = srclen;
2099 + cryp.src = (void *)src;
2100 + cryp.dst = NULL;
2101 + cryp.mac = res;
2102 + cryp.flags = flags;
2103 + return ioctl(cfd, CIOCCRYPT, &cryp);
2104 +}
2105 +
2106 +static int digest_update(EVP_MD_CTX *ctx, const void *data, size_t count)
2107 +{
2108 + struct digest_ctx *digest_ctx =
2109 + (struct digest_ctx *)EVP_MD_CTX_md_data(ctx);
2110 +
2111 + if (count == 0)
2112 + return 1;
2113 +
2114 + if (digest_ctx == NULL)
2115 + return 0;
2116 +
2117 + if (EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_ONESHOT)) {
2118 + if (digest_op(digest_ctx, data, count, digest_ctx->digest_res, 0) >= 0)
2119 + return 1;
2120 + } else if (digest_op(digest_ctx, data, count, NULL, COP_FLAG_UPDATE) >= 0) {
2121 + return 1;
2122 + }
2123 +
2124 + SYSerr(SYS_F_IOCTL, errno);
2125 + return 0;
2126 +}
2127 +
2128 +static int digest_final(EVP_MD_CTX *ctx, unsigned char *md)
2129 +{
2130 + struct digest_ctx *digest_ctx =
2131 + (struct digest_ctx *)EVP_MD_CTX_md_data(ctx);
2132 +
2133 + if (md == NULL || digest_ctx == NULL)
2134 + return 0;
2135 +
2136 + if (EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_ONESHOT)) {
2137 + memcpy(md, digest_ctx->digest_res, EVP_MD_CTX_size(ctx));
2138 + } else if (digest_op(digest_ctx, NULL, 0, md, COP_FLAG_FINAL) < 0) {
2139 + SYSerr(SYS_F_IOCTL, errno);
2140 + return 0;
2141 + }
2142 +
2143 + return 1;
2144 +}
2145 +
2146 +static int digest_copy(EVP_MD_CTX *to, const EVP_MD_CTX *from)
2147 +{
2148 + struct digest_ctx *digest_from =
2149 + (struct digest_ctx *)EVP_MD_CTX_md_data(from);
2150 + struct digest_ctx *digest_to =
2151 + (struct digest_ctx *)EVP_MD_CTX_md_data(to);
2152 + struct cphash_op cphash;
2153 +
2154 + if (digest_from == NULL || digest_from->init_called != 1)
2155 + return 1;
2156 +
2157 + if (!digest_init(to)) {
2158 + SYSerr(SYS_F_IOCTL, errno);
2159 + return 0;
2160 + }
2161 +
2162 + cphash.src_ses = digest_from->sess.ses;
2163 + cphash.dst_ses = digest_to->sess.ses;
2164 + if (ioctl(cfd, CIOCCPHASH, &cphash) < 0) {
2165 + SYSerr(SYS_F_IOCTL, errno);
2166 + return 0;
2167 + }
2168 + return 1;
2169 +}
2170 +
2171 +static int digest_cleanup(EVP_MD_CTX *ctx)
2172 +{
2173 + struct digest_ctx *digest_ctx =
2174 + (struct digest_ctx *)EVP_MD_CTX_md_data(ctx);
2175 +
2176 + if (digest_ctx == NULL)
2177 + return 1;
2178 +
2179 + return clean_devcrypto_session(&digest_ctx->sess);
2180 +}
2181 +
2182 +/*
2183 + * Keep tables of known nids, associated methods, selected digests, and
2184 + * driver info.
2185 + * Note that known_digest_nids[] isn't necessarily indexed the same way as
2186 + * digest_data[] above, which the other tables are.
2187 + */
2188 +static int known_digest_nids[OSSL_NELEM(digest_data)];
2189 +static int known_digest_nids_amount = -1; /* -1 indicates not yet initialised */
2190 +static EVP_MD *known_digest_methods[OSSL_NELEM(digest_data)] = { NULL, };
2191 +static int selected_digests[OSSL_NELEM(digest_data)];
2192 +static struct driver_info_st digest_driver_info[OSSL_NELEM(digest_data)];
2193 +
2194 +static int devcrypto_test_digest(size_t digest_data_index)
2195 +{
2196 + return (digest_driver_info[digest_data_index].status == DEVCRYPTO_STATUS_USABLE
2197 + && selected_digests[digest_data_index] == 1
2198 + && (digest_driver_info[digest_data_index].accelerated
2199 + == DEVCRYPTO_ACCELERATED
2200 + || use_softdrivers == DEVCRYPTO_USE_SOFTWARE
2201 + || (digest_driver_info[digest_data_index].accelerated
2202 + != DEVCRYPTO_NOT_ACCELERATED
2203 + && use_softdrivers == DEVCRYPTO_REJECT_SOFTWARE)));
2204 +}
2205 +
2206 +static void rebuild_known_digest_nids(ENGINE *e)
2207 +{
2208 + size_t i;
2209 +
2210 + for (i = 0, known_digest_nids_amount = 0; i < OSSL_NELEM(digest_data); i++) {
2211 + if (devcrypto_test_digest(i))
2212 + known_digest_nids[known_digest_nids_amount++] = digest_data[i].nid;
2213 + }
2214 + ENGINE_unregister_digests(e);
2215 + ENGINE_register_digests(e);
2216 +}
2217 +
2218 +static void prepare_digest_methods(void)
2219 +{
2220 + size_t i;
2221 + struct session_op sess1, sess2;
2222 +#ifdef CIOCGSESSINFO
2223 + struct session_info_op siop;
2224 +#endif
2225 + struct cphash_op cphash;
2226 +
2227 + memset(&digest_driver_info, 0, sizeof(digest_driver_info));
2228 +
2229 + memset(&sess1, 0, sizeof(sess1));
2230 + memset(&sess2, 0, sizeof(sess2));
2231 +
2232 + for (i = 0, known_digest_nids_amount = 0; i < OSSL_NELEM(digest_data);
2233 + i++) {
2234 +
2235 + selected_digests[i] = 1;
2236 +
2237 + /*
2238 + * Check that the digest is usable
2239 + */
2240 + sess1.mac = digest_data[i].devcryptoid;
2241 + sess2.ses = 0;
2242 + if (ioctl(cfd, CIOCGSESSION, &sess1) < 0) {
2243 + digest_driver_info[i].status = DEVCRYPTO_STATUS_NO_CIOCGSESSION;
2244 + goto finish;
2245 + }
2246 +
2247 +#ifdef CIOCGSESSINFO
2248 + /* gather hardware acceleration info from the driver */
2249 + siop.ses = sess1.ses;
2250 + if (ioctl(cfd, CIOCGSESSINFO, &siop) < 0) {
2251 + digest_driver_info[i].accelerated = DEVCRYPTO_ACCELERATION_UNKNOWN;
2252 + } else {
2253 + digest_driver_info[i].driver_name =
2254 + OPENSSL_strndup(siop.hash_info.cra_driver_name,
2255 + CRYPTODEV_MAX_ALG_NAME);
2256 + if (siop.flags & SIOP_FLAG_KERNEL_DRIVER_ONLY)
2257 + digest_driver_info[i].accelerated = DEVCRYPTO_ACCELERATED;
2258 + else
2259 + digest_driver_info[i].accelerated = DEVCRYPTO_NOT_ACCELERATED;
2260 + }
2261 +#endif
2262 +
2263 + /* digest must be capable of hash state copy */
2264 + sess2.mac = sess1.mac;
2265 + if (ioctl(cfd, CIOCGSESSION, &sess2) < 0) {
2266 + digest_driver_info[i].status = DEVCRYPTO_STATUS_FAILURE;
2267 + goto finish;
2268 + }
2269 + cphash.src_ses = sess1.ses;
2270 + cphash.dst_ses = sess2.ses;
2271 + if (ioctl(cfd, CIOCCPHASH, &cphash) < 0) {
2272 + digest_driver_info[i].status = DEVCRYPTO_STATUS_NO_CIOCCPHASH;
2273 + goto finish;
2274 + }
2275 + if ((known_digest_methods[i] = EVP_MD_meth_new(digest_data[i].nid,
2276 + NID_undef)) == NULL
2277 + || !EVP_MD_meth_set_input_blocksize(known_digest_methods[i],
2278 + digest_data[i].blocksize)
2279 + || !EVP_MD_meth_set_result_size(known_digest_methods[i],
2280 + digest_data[i].digestlen)
2281 + || !EVP_MD_meth_set_init(known_digest_methods[i], digest_init)
2282 + || !EVP_MD_meth_set_update(known_digest_methods[i], digest_update)
2283 + || !EVP_MD_meth_set_final(known_digest_methods[i], digest_final)
2284 + || !EVP_MD_meth_set_copy(known_digest_methods[i], digest_copy)
2285 + || !EVP_MD_meth_set_cleanup(known_digest_methods[i], digest_cleanup)
2286 + || !EVP_MD_meth_set_app_datasize(known_digest_methods[i],
2287 + sizeof(struct digest_ctx))) {
2288 + digest_driver_info[i].status = DEVCRYPTO_STATUS_FAILURE;
2289 + EVP_MD_meth_free(known_digest_methods[i]);
2290 + known_digest_methods[i] = NULL;
2291 + goto finish;
2292 + }
2293 + digest_driver_info[i].status = DEVCRYPTO_STATUS_USABLE;
2294 +finish:
2295 + ioctl(cfd, CIOCFSESSION, &sess1.ses);
2296 + if (sess2.ses != 0)
2297 + ioctl(cfd, CIOCFSESSION, &sess2.ses);
2298 + if (devcrypto_test_digest(i))
2299 + known_digest_nids[known_digest_nids_amount++] = digest_data[i].nid;
2300 + }
2301 +}
2302 +
2303 +static const EVP_MD *get_digest_method(int nid)
2304 +{
2305 + size_t i = get_digest_data_index(nid);
2306 +
2307 + if (i == (size_t)-1)
2308 + return NULL;
2309 + return known_digest_methods[i];
2310 +}
2311 +
2312 +static int get_digest_nids(const int **nids)
2313 +{
2314 + *nids = known_digest_nids;
2315 + return known_digest_nids_amount;
2316 +}
2317 +
2318 +static void destroy_digest_method(int nid)
2319 +{
2320 + size_t i = get_digest_data_index(nid);
2321 +
2322 + EVP_MD_meth_free(known_digest_methods[i]);
2323 + known_digest_methods[i] = NULL;
2324 +}
2325 +
2326 +static void destroy_all_digest_methods(void)
2327 +{
2328 + size_t i;
2329 +
2330 + for (i = 0; i < OSSL_NELEM(digest_data); i++) {
2331 + destroy_digest_method(digest_data[i].nid);
2332 + OPENSSL_free(digest_driver_info[i].driver_name);
2333 + digest_driver_info[i].driver_name = NULL;
2334 + }
2335 +}
2336 +
2337 +static int devcrypto_digests(ENGINE *e, const EVP_MD **digest,
2338 + const int **nids, int nid)
2339 +{
2340 + if (digest == NULL)
2341 + return get_digest_nids(nids);
2342 +
2343 + *digest = get_digest_method(nid);
2344 +
2345 + return *digest != NULL;
2346 +}
2347 +
2348 +static void devcrypto_select_all_digests(int *digest_list)
2349 +{
2350 + size_t i;
2351 +
2352 + for (i = 0; i < OSSL_NELEM(digest_data); i++)
2353 + digest_list[i] = 1;
2354 +}
2355 +
2356 +static int cryptodev_select_digest_cb(const char *str, int len, void *usr)
2357 +{
2358 + int *digest_list = (int *)usr;
2359 + char *name;
2360 + const EVP_MD *EVP;
2361 + size_t i;
2362 +
2363 + if (len == 0)
2364 + return 1;
2365 + if (usr == NULL || (name = OPENSSL_strndup(str, len)) == NULL)
2366 + return 0;
2367 + EVP = EVP_get_digestbyname(name);
2368 + if (EVP == NULL)
2369 + fprintf(stderr, "devcrypto: unknown digest %s\n", name);
2370 + else if ((i = find_digest_data_index(EVP_MD_type(EVP))) != (size_t)-1)
2371 + digest_list[i] = 1;
2372 + else
2373 + fprintf(stderr, "devcrypto: digest %s not available\n", name);
2374 + OPENSSL_free(name);
2375 + return 1;
2376 +}
2377 +
2378 +static void dump_digest_info(void)
2379 +{
2380 + size_t i;
2381 + const char *name;
2382 +
2383 + fprintf (stderr, "Information about digests supported by the /dev/crypto"
2384 + " engine:\n");
2385 +#ifndef CIOCGSESSINFO
2386 + fprintf(stderr, "CIOCGSESSINFO (session info call) unavailable\n");
2387 +#endif
2388 +
2389 + for (i = 0; i < OSSL_NELEM(digest_data); i++) {
2390 + name = OBJ_nid2sn(digest_data[i].nid);
2391 + fprintf (stderr, "Digest %s, NID=%d, /dev/crypto info: id=%d, driver=%s",
2392 + name ? name : "unknown", digest_data[i].nid,
2393 + digest_data[i].devcryptoid,
2394 + digest_driver_info[i].driver_name ? digest_driver_info[i].driver_name : "unknown");
2395 + if (digest_driver_info[i].status == DEVCRYPTO_STATUS_NO_CIOCGSESSION) {
2396 + fprintf (stderr, ". CIOCGSESSION (session open) failed\n");
2397 + continue;
2398 + }
2399 + if (digest_driver_info[i].accelerated == DEVCRYPTO_ACCELERATED)
2400 + fprintf(stderr, " (hw accelerated)");
2401 + else if (digest_driver_info[i].accelerated == DEVCRYPTO_NOT_ACCELERATED)
2402 + fprintf(stderr, " (software)");
2403 + else
2404 + fprintf(stderr, " (acceleration status unknown)");
2405 + if (cipher_driver_info[i].status == DEVCRYPTO_STATUS_FAILURE)
2406 + fprintf (stderr, ". Cipher setup failed\n");
2407 + else if (digest_driver_info[i].status == DEVCRYPTO_STATUS_NO_CIOCCPHASH)
2408 + fprintf(stderr, ", CIOCCPHASH failed\n");
2409 + else
2410 + fprintf(stderr, ", CIOCCPHASH capable\n");
2411 + }
2412 + fprintf(stderr, "\n");
2413 +}
2414 +
2415 +#endif
2416 +
2417 +/******************************************************************************
2418 + *
2419 + * CONTROL COMMANDS
2420 + *
2421 + *****/
2422 +
2423 +#define DEVCRYPTO_CMD_USE_SOFTDRIVERS ENGINE_CMD_BASE
2424 +#define DEVCRYPTO_CMD_CIPHERS (ENGINE_CMD_BASE + 1)
2425 +#define DEVCRYPTO_CMD_DIGESTS (ENGINE_CMD_BASE + 2)
2426 +#define DEVCRYPTO_CMD_DUMP_INFO (ENGINE_CMD_BASE + 3)
2427 +
2428 +/* Helper macros for CPP string composition */
2429 +#ifndef OPENSSL_MSTR
2430 +# define OPENSSL_MSTR_HELPER(x) #x
2431 +# define OPENSSL_MSTR(x) OPENSSL_MSTR_HELPER(x)
2432 +#endif
2433 +
2434 +static const ENGINE_CMD_DEFN devcrypto_cmds[] = {
2435 +#ifdef CIOCGSESSINFO
2436 + {DEVCRYPTO_CMD_USE_SOFTDRIVERS,
2437 + "USE_SOFTDRIVERS",
2438 + "specifies whether to use software (not accelerated) drivers ("
2439 + OPENSSL_MSTR(DEVCRYPTO_REQUIRE_ACCELERATED) "=use only accelerated drivers, "
2440 + OPENSSL_MSTR(DEVCRYPTO_USE_SOFTWARE) "=allow all drivers, "
2441 + OPENSSL_MSTR(DEVCRYPTO_REJECT_SOFTWARE)
2442 + "=use if acceleration can't be determined) [default="
2443 + OPENSSL_MSTR(DEVCRYPTO_DEFAULT_USE_SOFTDRIVERS) "]",
2444 + ENGINE_CMD_FLAG_NUMERIC},
2445 +#endif
2446 +
2447 + {DEVCRYPTO_CMD_CIPHERS,
2448 + "CIPHERS",
2449 + "either ALL, NONE, or a comma-separated list of ciphers to enable [default=ALL]",
2450 + ENGINE_CMD_FLAG_STRING},
2451 +
2452 +#ifdef IMPLEMENT_DIGEST
2453 + {DEVCRYPTO_CMD_DIGESTS,
2454 + "DIGESTS",
2455 + "either ALL, NONE, or a comma-separated list of digests to enable [default=ALL]",
2456 + ENGINE_CMD_FLAG_STRING},
2457 +#endif
2458 +
2459 + {DEVCRYPTO_CMD_DUMP_INFO,
2460 + "DUMP_INFO",
2461 + "dump info about each algorithm to stderr; use 'openssl engine -pre DUMP_INFO devcrypto'",
2462 + ENGINE_CMD_FLAG_NO_INPUT},
2463 +
2464 + {0, NULL, NULL, 0}
2465 +};
2466 +
2467 +static int devcrypto_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f) (void))
2468 +{
2469 + int *new_list;
2470 + switch (cmd) {
2471 +#ifdef CIOCGSESSINFO
2472 + case DEVCRYPTO_CMD_USE_SOFTDRIVERS:
2473 + switch (i) {
2474 + case DEVCRYPTO_REQUIRE_ACCELERATED:
2475 + case DEVCRYPTO_USE_SOFTWARE:
2476 + case DEVCRYPTO_REJECT_SOFTWARE:
2477 + break;
2478 + default:
2479 + fprintf(stderr, "devcrypto: invalid value (%ld) for USE_SOFTDRIVERS\n", i);
2480 + return 0;
2481 + }
2482 + if (use_softdrivers == i)
2483 + return 1;
2484 + use_softdrivers = i;
2485 +#ifdef IMPLEMENT_DIGEST
2486 + rebuild_known_digest_nids(e);
2487 +#endif
2488 + rebuild_known_cipher_nids(e);
2489 + return 1;
2490 +#endif /* CIOCGSESSINFO */
2491 +
2492 + case DEVCRYPTO_CMD_CIPHERS:
2493 + if (p == NULL)
2494 + return 1;
2495 + if (strcasecmp((const char *)p, "ALL") == 0) {
2496 + devcrypto_select_all_ciphers(selected_ciphers);
2497 + } else if (strcasecmp((const char*)p, "NONE") == 0) {
2498 + memset(selected_ciphers, 0, sizeof(selected_ciphers));
2499 + } else {
2500 + new_list=OPENSSL_zalloc(sizeof(selected_ciphers));
2501 + if (!CONF_parse_list(p, ',', 1, cryptodev_select_cipher_cb, new_list)) {
2502 + OPENSSL_free(new_list);
2503 + return 0;
2504 + }
2505 + memcpy(selected_ciphers, new_list, sizeof(selected_ciphers));
2506 + OPENSSL_free(new_list);
2507 + }
2508 + rebuild_known_cipher_nids(e);
2509 + return 1;
2510 +
2511 +#ifdef IMPLEMENT_DIGEST
2512 + case DEVCRYPTO_CMD_DIGESTS:
2513 + if (p == NULL)
2514 + return 1;
2515 + if (strcasecmp((const char *)p, "ALL") == 0) {
2516 + devcrypto_select_all_digests(selected_digests);
2517 + } else if (strcasecmp((const char*)p, "NONE") == 0) {
2518 + memset(selected_digests, 0, sizeof(selected_digests));
2519 + } else {
2520 + new_list=OPENSSL_zalloc(sizeof(selected_digests));
2521 + if (!CONF_parse_list(p, ',', 1, cryptodev_select_digest_cb, new_list)) {
2522 + OPENSSL_free(new_list);
2523 + return 0;
2524 + }
2525 + memcpy(selected_digests, new_list, sizeof(selected_digests));
2526 + OPENSSL_free(new_list);
2527 + }
2528 + rebuild_known_digest_nids(e);
2529 + return 1;
2530 +#endif /* IMPLEMENT_DIGEST */
2531 +
2532 + case DEVCRYPTO_CMD_DUMP_INFO:
2533 + dump_cipher_info();
2534 +#ifdef IMPLEMENT_DIGEST
2535 + dump_digest_info();
2536 +#endif
2537 + return 1;
2538 +
2539 + default:
2540 + break;
2541 + }
2542 + return 0;
2543 +}
2544 +
2545 +/******************************************************************************
2546 + *
2547 + * LOAD / UNLOAD
2548 + *
2549 + *****/
2550 +
2551 +/*
2552 + * Opens /dev/crypto
2553 + */
2554 +static int open_devcrypto(void)
2555 +{
2556 + if (cfd >= 0)
2557 + return 1;
2558 +
2559 + if ((cfd = open("/dev/crypto", O_RDWR, 0)) < 0) {
2560 +#ifndef ENGINE_DEVCRYPTO_DEBUG
2561 + if (errno != ENOENT)
2562 +#endif
2563 + fprintf(stderr, "Could not open /dev/crypto: %s\n", strerror(errno));
2564 + return 0;
2565 + }
2566 +
2567 + return 1;
2568 +}
2569 +
2570 +static int close_devcrypto(void)
2571 +{
2572 + int ret;
2573 +
2574 + if (cfd < 0)
2575 + return 1;
2576 + ret = close(cfd);
2577 + cfd = -1;
2578 + if (ret != 0) {
2579 + fprintf(stderr, "Error closing /dev/crypto: %s\n", strerror(errno));
2580 + return 0;
2581 + }
2582 + return 1;
2583 +}
2584 +
2585 +static int devcrypto_unload(ENGINE *e)
2586 +{
2587 + destroy_all_cipher_methods();
2588 +#ifdef IMPLEMENT_DIGEST
2589 + destroy_all_digest_methods();
2590 +#endif
2591 +
2592 + close_devcrypto();
2593 +
2594 + return 1;
2595 +}
2596 +
2597 +static int bind_devcrypto(ENGINE *e) {
2598 +
2599 + if (!ENGINE_set_id(e, engine_devcrypto_id)
2600 + || !ENGINE_set_name(e, "/dev/crypto engine")
2601 + || !ENGINE_set_destroy_function(e, devcrypto_unload)
2602 + || !ENGINE_set_cmd_defns(e, devcrypto_cmds)
2603 + || !ENGINE_set_ctrl_function(e, devcrypto_ctrl))
2604 + return 0;
2605 +
2606 + prepare_cipher_methods();
2607 +#ifdef IMPLEMENT_DIGEST
2608 + prepare_digest_methods();
2609 +#endif
2610 +
2611 + return (ENGINE_set_ciphers(e, devcrypto_ciphers)
2612 +#ifdef IMPLEMENT_DIGEST
2613 + && ENGINE_set_digests(e, devcrypto_digests)
2614 +#endif
2615 +/*
2616 + * Asymmetric ciphers aren't well supported with /dev/crypto. Among the BSD
2617 + * implementations, it seems to only exist in FreeBSD, and regarding the
2618 + * parameters in its crypt_kop, the manual crypto(4) has this to say:
2619 + *
2620 + * The semantics of these arguments are currently undocumented.
2621 + *
2622 + * Reading through the FreeBSD source code doesn't give much more than
2623 + * their CRK_MOD_EXP implementation for ubsec.
2624 + *
2625 + * It doesn't look much better with cryptodev-linux. They have the crypt_kop
2626 + * structure as well as the command (CRK_*) in cryptodev.h, but no support
2627 + * seems to be implemented at all for the moment.
2628 + *
2629 + * At the time of writing, it seems impossible to write proper support for
2630 + * FreeBSD's asym features without some very deep knowledge and access to
2631 + * specific kernel modules.
2632 + *
2633 + * /Richard Levitte, 2017-05-11
2634 + */
2635 +#if 0
2636 +# ifndef OPENSSL_NO_RSA
2637 + && ENGINE_set_RSA(e, devcrypto_rsa)
2638 +# endif
2639 +# ifndef OPENSSL_NO_DSA
2640 + && ENGINE_set_DSA(e, devcrypto_dsa)
2641 +# endif
2642 +# ifndef OPENSSL_NO_DH
2643 + && ENGINE_set_DH(e, devcrypto_dh)
2644 +# endif
2645 +# ifndef OPENSSL_NO_EC
2646 + && ENGINE_set_EC(e, devcrypto_ec)
2647 +# endif
2648 +#endif
2649 + );
2650 +}
2651 +
2652 +#ifdef OPENSSL_NO_DYNAMIC_ENGINE
2653 +/*
2654 + * In case this engine is built into libcrypto, then it doesn't offer any
2655 + * ability to be dynamically loadable.
2656 + */
2657 +void engine_load_devcrypto_int(void)
2658 +{
2659 + ENGINE *e = NULL;
2660 +
2661 + if (!open_devcrypto())
2662 + return;
2663 +
2664 + if ((e = ENGINE_new()) == NULL
2665 + || !bind_devcrypto(e)) {
2666 + close_devcrypto();
2667 + ENGINE_free(e);
2668 + return;
2669 + }
2670 +
2671 + ENGINE_add(e);
2672 + ENGINE_free(e); /* Loose our local reference */
2673 + ERR_clear_error();
2674 +}
2675 +
2676 +#else
2677 +
2678 +static int bind_helper(ENGINE *e, const char *id)
2679 +{
2680 + if ((id && (strcmp(id, engine_devcrypto_id) != 0))
2681 + || !open_devcrypto())
2682 + return 0;
2683 + if (!bind_devcrypto(e)) {
2684 + close_devcrypto();
2685 + return 0;
2686 + }
2687 + return 1;
2688 +}
2689 +
2690 +IMPLEMENT_DYNAMIC_CHECK_FN()
2691 +IMPLEMENT_DYNAMIC_BIND_FN(bind_helper)
2692 +
2693 +#endif