b6d274ad1264f333f505495ecf0a92bcd171e2ee
[librecmc/librecmc.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