1 /* 2 * Copyright 2017-2022 The OpenSSL Project Authors. All Rights Reserved. 3 * 4 * Licensed under the Apache License 2.0 (the "License"). You may not use 5 * this file except in compliance with the License. You can obtain a copy 6 * in the file LICENSE in the source distribution or at 7 * https://www.openssl.org/source/license.html 8 */ 9 10 /* We need to use some deprecated APIs */ 11 #define OPENSSL_SUPPRESS_DEPRECATED 12 13 #include "../e_os.h" 14 #include <string.h> 15 #include <sys/types.h> 16 #include <sys/stat.h> 17 #include <fcntl.h> 18 #include <sys/ioctl.h> 19 #include <unistd.h> 20 #include <assert.h> 21 22 #include <openssl/conf.h> 23 #include <openssl/evp.h> 24 #include <openssl/err.h> 25 #include <openssl/engine.h> 26 #include <openssl/objects.h> 27 #include "crypto/cryptodev.h" 28 29 /* #define ENGINE_DEVCRYPTO_DEBUG */ 30 31 #if CRYPTO_ALGORITHM_MIN < CRYPTO_ALGORITHM_MAX 32 # define CHECK_BSD_STYLE_MACROS 33 #endif 34 35 #define engine_devcrypto_id "devcrypto" 36 37 /* 38 * Use session2_op on FreeBSD which permits requesting specific 39 * drivers or classes of drivers at session creation time. 40 */ 41 #ifdef CIOCGSESSION2 42 typedef struct session2_op session_op_t; 43 #else 44 typedef struct session_op session_op_t; 45 #endif 46 47 /* 48 * ONE global file descriptor for all sessions. This allows operations 49 * such as digest session data copying (see digest_copy()), but is also 50 * saner... why re-open /dev/crypto for every session? 51 */ 52 static int cfd = -1; 53 #define DEVCRYPTO_REQUIRE_ACCELERATED 0 /* require confirmation of acceleration */ 54 #define DEVCRYPTO_USE_SOFTWARE 1 /* allow software drivers */ 55 #define DEVCRYPTO_REJECT_SOFTWARE 2 /* only disallow confirmed software drivers */ 56 57 #define DEVCRYPTO_DEFAULT_USE_SOFTDRIVERS DEVCRYPTO_REJECT_SOFTWARE 58 static int use_softdrivers = DEVCRYPTO_DEFAULT_USE_SOFTDRIVERS; 59 60 /* 61 * cipher/digest status & acceleration definitions 62 * Make sure the defaults are set to 0 63 */ 64 struct driver_info_st { 65 enum devcrypto_status_t { 66 DEVCRYPTO_STATUS_FAILURE = -3, /* unusable for other reason */ 67 DEVCRYPTO_STATUS_NO_CIOCCPHASH = -2, /* hash state copy not supported */ 68 DEVCRYPTO_STATUS_NO_CIOCGSESSION = -1, /* session open failed */ 69 DEVCRYPTO_STATUS_UNKNOWN = 0, /* not tested yet */ 70 DEVCRYPTO_STATUS_USABLE = 1 /* algo can be used */ 71 } status; 72 73 enum devcrypto_accelerated_t { 74 DEVCRYPTO_NOT_ACCELERATED = -1, /* software implemented */ 75 DEVCRYPTO_ACCELERATION_UNKNOWN = 0, /* acceleration support unknown */ 76 DEVCRYPTO_ACCELERATED = 1 /* hardware accelerated */ 77 } accelerated; 78 79 char *driver_name; 80 }; 81 82 #ifdef OPENSSL_NO_DYNAMIC_ENGINE 83 void engine_load_devcrypto_int(void); 84 #endif 85 86 static int clean_devcrypto_session(session_op_t *sess) { 87 if (ioctl(cfd, CIOCFSESSION, &sess->ses) < 0) { 88 ERR_raise_data(ERR_LIB_SYS, errno, "calling ioctl()"); 89 return 0; 90 } 91 memset(sess, 0, sizeof(*sess)); 92 return 1; 93 } 94 95 /****************************************************************************** 96 * 97 * Ciphers 98 * 99 * Because they all do the same basic operation, we have only one set of 100 * method functions for them all to share, and a mapping table between 101 * NIDs and cryptodev IDs, with all the necessary size data. 102 * 103 *****/ 104 105 struct cipher_ctx { 106 session_op_t sess; 107 int op; /* COP_ENCRYPT or COP_DECRYPT */ 108 unsigned long mode; /* EVP_CIPH_*_MODE */ 109 110 /* to handle ctr mode being a stream cipher */ 111 unsigned char partial[EVP_MAX_BLOCK_LENGTH]; 112 unsigned int blocksize, num; 113 }; 114 115 static const struct cipher_data_st { 116 int nid; 117 int blocksize; 118 int keylen; 119 int ivlen; 120 int flags; 121 int devcryptoid; 122 } cipher_data[] = { 123 #ifndef OPENSSL_NO_DES 124 { NID_des_cbc, 8, 8, 8, EVP_CIPH_CBC_MODE, CRYPTO_DES_CBC }, 125 { NID_des_ede3_cbc, 8, 24, 8, EVP_CIPH_CBC_MODE, CRYPTO_3DES_CBC }, 126 #endif 127 #ifndef OPENSSL_NO_BF 128 { NID_bf_cbc, 8, 16, 8, EVP_CIPH_CBC_MODE, CRYPTO_BLF_CBC }, 129 #endif 130 #ifndef OPENSSL_NO_CAST 131 { NID_cast5_cbc, 8, 16, 8, EVP_CIPH_CBC_MODE, CRYPTO_CAST_CBC }, 132 #endif 133 { NID_aes_128_cbc, 16, 128 / 8, 16, EVP_CIPH_CBC_MODE, CRYPTO_AES_CBC }, 134 { NID_aes_192_cbc, 16, 192 / 8, 16, EVP_CIPH_CBC_MODE, CRYPTO_AES_CBC }, 135 { NID_aes_256_cbc, 16, 256 / 8, 16, EVP_CIPH_CBC_MODE, CRYPTO_AES_CBC }, 136 #ifndef OPENSSL_NO_RC4 137 { NID_rc4, 1, 16, 0, EVP_CIPH_STREAM_CIPHER, CRYPTO_ARC4 }, 138 #endif 139 #if !defined(CHECK_BSD_STYLE_MACROS) || defined(CRYPTO_AES_CTR) 140 { NID_aes_128_ctr, 16, 128 / 8, 16, EVP_CIPH_CTR_MODE, CRYPTO_AES_CTR }, 141 { NID_aes_192_ctr, 16, 192 / 8, 16, EVP_CIPH_CTR_MODE, CRYPTO_AES_CTR }, 142 { NID_aes_256_ctr, 16, 256 / 8, 16, EVP_CIPH_CTR_MODE, CRYPTO_AES_CTR }, 143 #endif 144 #if 0 /* Not yet supported */ 145 { NID_aes_128_xts, 16, 128 / 8 * 2, 16, EVP_CIPH_XTS_MODE, CRYPTO_AES_XTS }, 146 { NID_aes_256_xts, 16, 256 / 8 * 2, 16, EVP_CIPH_XTS_MODE, CRYPTO_AES_XTS }, 147 #endif 148 #if !defined(CHECK_BSD_STYLE_MACROS) || defined(CRYPTO_AES_ECB) 149 { NID_aes_128_ecb, 16, 128 / 8, 0, EVP_CIPH_ECB_MODE, CRYPTO_AES_ECB }, 150 { NID_aes_192_ecb, 16, 192 / 8, 0, EVP_CIPH_ECB_MODE, CRYPTO_AES_ECB }, 151 { NID_aes_256_ecb, 16, 256 / 8, 0, EVP_CIPH_ECB_MODE, CRYPTO_AES_ECB }, 152 #endif 153 #if 0 /* Not yet supported */ 154 { NID_aes_128_gcm, 16, 128 / 8, 16, EVP_CIPH_GCM_MODE, CRYPTO_AES_GCM }, 155 { NID_aes_192_gcm, 16, 192 / 8, 16, EVP_CIPH_GCM_MODE, CRYPTO_AES_GCM }, 156 { NID_aes_256_gcm, 16, 256 / 8, 16, EVP_CIPH_GCM_MODE, CRYPTO_AES_GCM }, 157 #endif 158 #ifndef OPENSSL_NO_CAMELLIA 159 { NID_camellia_128_cbc, 16, 128 / 8, 16, EVP_CIPH_CBC_MODE, 160 CRYPTO_CAMELLIA_CBC }, 161 { NID_camellia_192_cbc, 16, 192 / 8, 16, EVP_CIPH_CBC_MODE, 162 CRYPTO_CAMELLIA_CBC }, 163 { NID_camellia_256_cbc, 16, 256 / 8, 16, EVP_CIPH_CBC_MODE, 164 CRYPTO_CAMELLIA_CBC }, 165 #endif 166 }; 167 168 static size_t find_cipher_data_index(int nid) 169 { 170 size_t i; 171 172 for (i = 0; i < OSSL_NELEM(cipher_data); i++) 173 if (nid == cipher_data[i].nid) 174 return i; 175 return (size_t)-1; 176 } 177 178 static size_t get_cipher_data_index(int nid) 179 { 180 size_t i = find_cipher_data_index(nid); 181 182 if (i != (size_t)-1) 183 return i; 184 185 /* 186 * Code further down must make sure that only NIDs in the table above 187 * are used. If any other NID reaches this function, there's a grave 188 * coding error further down. 189 */ 190 assert("Code that never should be reached" == NULL); 191 return -1; 192 } 193 194 static const struct cipher_data_st *get_cipher_data(int nid) 195 { 196 return &cipher_data[get_cipher_data_index(nid)]; 197 } 198 199 /* 200 * Following are the three necessary functions to map OpenSSL functionality 201 * with cryptodev. 202 */ 203 204 static int cipher_init(EVP_CIPHER_CTX *ctx, const unsigned char *key, 205 const unsigned char *iv, int enc) 206 { 207 struct cipher_ctx *cipher_ctx = 208 (struct cipher_ctx *)EVP_CIPHER_CTX_get_cipher_data(ctx); 209 const struct cipher_data_st *cipher_d = 210 get_cipher_data(EVP_CIPHER_CTX_get_nid(ctx)); 211 int ret; 212 213 /* cleanup a previous session */ 214 if (cipher_ctx->sess.ses != 0 && 215 clean_devcrypto_session(&cipher_ctx->sess) == 0) 216 return 0; 217 218 cipher_ctx->sess.cipher = cipher_d->devcryptoid; 219 cipher_ctx->sess.keylen = cipher_d->keylen; 220 cipher_ctx->sess.key = (void *)key; 221 cipher_ctx->op = enc ? COP_ENCRYPT : COP_DECRYPT; 222 cipher_ctx->mode = cipher_d->flags & EVP_CIPH_MODE; 223 cipher_ctx->blocksize = cipher_d->blocksize; 224 #ifdef CIOCGSESSION2 225 cipher_ctx->sess.crid = (use_softdrivers == DEVCRYPTO_USE_SOFTWARE) ? 226 CRYPTO_FLAG_SOFTWARE | CRYPTO_FLAG_HARDWARE : 227 CRYPTO_FLAG_HARDWARE; 228 ret = ioctl(cfd, CIOCGSESSION2, &cipher_ctx->sess); 229 #else 230 ret = ioctl(cfd, CIOCGSESSION, &cipher_ctx->sess); 231 #endif 232 if (ret < 0) { 233 ERR_raise_data(ERR_LIB_SYS, errno, "calling ioctl()"); 234 return 0; 235 } 236 237 return 1; 238 } 239 240 static int cipher_do_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, 241 const unsigned char *in, size_t inl) 242 { 243 struct cipher_ctx *cipher_ctx = 244 (struct cipher_ctx *)EVP_CIPHER_CTX_get_cipher_data(ctx); 245 struct crypt_op cryp; 246 unsigned char *iv = EVP_CIPHER_CTX_iv_noconst(ctx); 247 #if !defined(COP_FLAG_WRITE_IV) 248 unsigned char saved_iv[EVP_MAX_IV_LENGTH]; 249 const unsigned char *ivptr; 250 size_t nblocks, ivlen; 251 #endif 252 253 memset(&cryp, 0, sizeof(cryp)); 254 cryp.ses = cipher_ctx->sess.ses; 255 cryp.len = inl; 256 cryp.src = (void *)in; 257 cryp.dst = (void *)out; 258 cryp.iv = (void *)iv; 259 cryp.op = cipher_ctx->op; 260 #if !defined(COP_FLAG_WRITE_IV) 261 cryp.flags = 0; 262 263 ivlen = EVP_CIPHER_CTX_get_iv_length(ctx); 264 if (ivlen > 0) 265 switch (cipher_ctx->mode) { 266 case EVP_CIPH_CBC_MODE: 267 assert(inl >= ivlen); 268 if (!EVP_CIPHER_CTX_is_encrypting(ctx)) { 269 ivptr = in + inl - ivlen; 270 memcpy(saved_iv, ivptr, ivlen); 271 } 272 break; 273 274 case EVP_CIPH_CTR_MODE: 275 break; 276 277 default: /* should not happen */ 278 return 0; 279 } 280 #else 281 cryp.flags = COP_FLAG_WRITE_IV; 282 #endif 283 284 if (ioctl(cfd, CIOCCRYPT, &cryp) < 0) { 285 ERR_raise_data(ERR_LIB_SYS, errno, "calling ioctl()"); 286 return 0; 287 } 288 289 #if !defined(COP_FLAG_WRITE_IV) 290 if (ivlen > 0) 291 switch (cipher_ctx->mode) { 292 case EVP_CIPH_CBC_MODE: 293 assert(inl >= ivlen); 294 if (EVP_CIPHER_CTX_is_encrypting(ctx)) 295 ivptr = out + inl - ivlen; 296 else 297 ivptr = saved_iv; 298 299 memcpy(iv, ivptr, ivlen); 300 break; 301 302 case EVP_CIPH_CTR_MODE: 303 nblocks = (inl + cipher_ctx->blocksize - 1) 304 / cipher_ctx->blocksize; 305 do { 306 ivlen--; 307 nblocks += iv[ivlen]; 308 iv[ivlen] = (uint8_t) nblocks; 309 nblocks >>= 8; 310 } while (ivlen); 311 break; 312 313 default: /* should not happen */ 314 return 0; 315 } 316 #endif 317 318 return 1; 319 } 320 321 static int ctr_do_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, 322 const unsigned char *in, size_t inl) 323 { 324 struct cipher_ctx *cipher_ctx = 325 (struct cipher_ctx *)EVP_CIPHER_CTX_get_cipher_data(ctx); 326 size_t nblocks, len; 327 328 /* initial partial block */ 329 while (cipher_ctx->num && inl) { 330 (*out++) = *(in++) ^ cipher_ctx->partial[cipher_ctx->num]; 331 --inl; 332 cipher_ctx->num = (cipher_ctx->num + 1) % cipher_ctx->blocksize; 333 } 334 335 /* full blocks */ 336 if (inl > (unsigned int) cipher_ctx->blocksize) { 337 nblocks = inl/cipher_ctx->blocksize; 338 len = nblocks * cipher_ctx->blocksize; 339 if (cipher_do_cipher(ctx, out, in, len) < 1) 340 return 0; 341 inl -= len; 342 out += len; 343 in += len; 344 } 345 346 /* final partial block */ 347 if (inl) { 348 memset(cipher_ctx->partial, 0, cipher_ctx->blocksize); 349 if (cipher_do_cipher(ctx, cipher_ctx->partial, cipher_ctx->partial, 350 cipher_ctx->blocksize) < 1) 351 return 0; 352 while (inl--) { 353 out[cipher_ctx->num] = in[cipher_ctx->num] 354 ^ cipher_ctx->partial[cipher_ctx->num]; 355 cipher_ctx->num++; 356 } 357 } 358 359 return 1; 360 } 361 362 static int cipher_ctrl(EVP_CIPHER_CTX *ctx, int type, int p1, void* p2) 363 { 364 struct cipher_ctx *cipher_ctx = 365 (struct cipher_ctx *)EVP_CIPHER_CTX_get_cipher_data(ctx); 366 EVP_CIPHER_CTX *to_ctx = (EVP_CIPHER_CTX *)p2; 367 struct cipher_ctx *to_cipher_ctx; 368 369 switch (type) { 370 371 case EVP_CTRL_COPY: 372 if (cipher_ctx == NULL) 373 return 1; 374 /* when copying the context, a new session needs to be initialized */ 375 to_cipher_ctx = 376 (struct cipher_ctx *)EVP_CIPHER_CTX_get_cipher_data(to_ctx); 377 memset(&to_cipher_ctx->sess, 0, sizeof(to_cipher_ctx->sess)); 378 return cipher_init(to_ctx, (void *)cipher_ctx->sess.key, EVP_CIPHER_CTX_iv(ctx), 379 (cipher_ctx->op == COP_ENCRYPT)); 380 381 case EVP_CTRL_INIT: 382 memset(&cipher_ctx->sess, 0, sizeof(cipher_ctx->sess)); 383 return 1; 384 385 default: 386 break; 387 } 388 389 return -1; 390 } 391 392 static int cipher_cleanup(EVP_CIPHER_CTX *ctx) 393 { 394 struct cipher_ctx *cipher_ctx = 395 (struct cipher_ctx *)EVP_CIPHER_CTX_get_cipher_data(ctx); 396 397 return clean_devcrypto_session(&cipher_ctx->sess); 398 } 399 400 /* 401 * Keep tables of known nids, associated methods, selected ciphers, and driver 402 * info. 403 * Note that known_cipher_nids[] isn't necessarily indexed the same way as 404 * cipher_data[] above, which the other tables are. 405 */ 406 static int known_cipher_nids[OSSL_NELEM(cipher_data)]; 407 static int known_cipher_nids_amount = -1; /* -1 indicates not yet initialised */ 408 static EVP_CIPHER *known_cipher_methods[OSSL_NELEM(cipher_data)] = { NULL, }; 409 static int selected_ciphers[OSSL_NELEM(cipher_data)]; 410 static struct driver_info_st cipher_driver_info[OSSL_NELEM(cipher_data)]; 411 412 413 static int devcrypto_test_cipher(size_t cipher_data_index) 414 { 415 return (cipher_driver_info[cipher_data_index].status == DEVCRYPTO_STATUS_USABLE 416 && selected_ciphers[cipher_data_index] == 1 417 && (cipher_driver_info[cipher_data_index].accelerated 418 == DEVCRYPTO_ACCELERATED 419 || use_softdrivers == DEVCRYPTO_USE_SOFTWARE 420 || (cipher_driver_info[cipher_data_index].accelerated 421 != DEVCRYPTO_NOT_ACCELERATED 422 && use_softdrivers == DEVCRYPTO_REJECT_SOFTWARE))); 423 } 424 425 static void prepare_cipher_methods(void) 426 { 427 size_t i; 428 session_op_t sess; 429 unsigned long cipher_mode; 430 #ifdef CIOCGSESSION2 431 struct crypt_find_op fop; 432 enum devcrypto_accelerated_t accelerated; 433 #elif defined(CIOCGSESSINFO) 434 struct session_info_op siop; 435 #endif 436 437 memset(&cipher_driver_info, 0, sizeof(cipher_driver_info)); 438 439 memset(&sess, 0, sizeof(sess)); 440 sess.key = (void *)"01234567890123456789012345678901234567890123456789"; 441 442 for (i = 0, known_cipher_nids_amount = 0; 443 i < OSSL_NELEM(cipher_data); i++) { 444 445 selected_ciphers[i] = 1; 446 /* 447 * Check that the cipher is usable 448 */ 449 sess.cipher = cipher_data[i].devcryptoid; 450 sess.keylen = cipher_data[i].keylen; 451 #ifdef CIOCGSESSION2 452 /* 453 * When using CIOCGSESSION2, first try to allocate a hardware 454 * ("accelerated") session. If that fails, fall back to 455 * allocating a software session. 456 */ 457 sess.crid = CRYPTO_FLAG_HARDWARE; 458 if (ioctl(cfd, CIOCGSESSION2, &sess) == 0) { 459 accelerated = DEVCRYPTO_ACCELERATED; 460 } else { 461 sess.crid = CRYPTO_FLAG_SOFTWARE; 462 if (ioctl(cfd, CIOCGSESSION2, &sess) < 0) { 463 cipher_driver_info[i].status = DEVCRYPTO_STATUS_NO_CIOCGSESSION; 464 continue; 465 } 466 accelerated = DEVCRYPTO_NOT_ACCELERATED; 467 } 468 #else 469 if (ioctl(cfd, CIOCGSESSION, &sess) < 0) { 470 cipher_driver_info[i].status = DEVCRYPTO_STATUS_NO_CIOCGSESSION; 471 continue; 472 } 473 #endif 474 475 cipher_mode = cipher_data[i].flags & EVP_CIPH_MODE; 476 477 if ((known_cipher_methods[i] = 478 EVP_CIPHER_meth_new(cipher_data[i].nid, 479 cipher_mode == EVP_CIPH_CTR_MODE ? 1 : 480 cipher_data[i].blocksize, 481 cipher_data[i].keylen)) == NULL 482 || !EVP_CIPHER_meth_set_iv_length(known_cipher_methods[i], 483 cipher_data[i].ivlen) 484 || !EVP_CIPHER_meth_set_flags(known_cipher_methods[i], 485 cipher_data[i].flags 486 | EVP_CIPH_CUSTOM_COPY 487 | EVP_CIPH_CTRL_INIT 488 | EVP_CIPH_FLAG_DEFAULT_ASN1) 489 || !EVP_CIPHER_meth_set_init(known_cipher_methods[i], cipher_init) 490 || !EVP_CIPHER_meth_set_do_cipher(known_cipher_methods[i], 491 cipher_mode == EVP_CIPH_CTR_MODE ? 492 ctr_do_cipher : 493 cipher_do_cipher) 494 || !EVP_CIPHER_meth_set_ctrl(known_cipher_methods[i], cipher_ctrl) 495 || !EVP_CIPHER_meth_set_cleanup(known_cipher_methods[i], 496 cipher_cleanup) 497 || !EVP_CIPHER_meth_set_impl_ctx_size(known_cipher_methods[i], 498 sizeof(struct cipher_ctx))) { 499 cipher_driver_info[i].status = DEVCRYPTO_STATUS_FAILURE; 500 EVP_CIPHER_meth_free(known_cipher_methods[i]); 501 known_cipher_methods[i] = NULL; 502 } else { 503 cipher_driver_info[i].status = DEVCRYPTO_STATUS_USABLE; 504 #ifdef CIOCGSESSION2 505 cipher_driver_info[i].accelerated = accelerated; 506 fop.crid = sess.crid; 507 if (ioctl(cfd, CIOCFINDDEV, &fop) == 0) { 508 cipher_driver_info[i].driver_name = 509 OPENSSL_strndup(fop.name, sizeof(fop.name)); 510 } 511 #elif defined(CIOCGSESSINFO) 512 siop.ses = sess.ses; 513 if (ioctl(cfd, CIOCGSESSINFO, &siop) < 0) { 514 cipher_driver_info[i].accelerated = DEVCRYPTO_ACCELERATION_UNKNOWN; 515 } else { 516 cipher_driver_info[i].driver_name = 517 OPENSSL_strndup(siop.cipher_info.cra_driver_name, 518 CRYPTODEV_MAX_ALG_NAME); 519 if (!(siop.flags & SIOP_FLAG_KERNEL_DRIVER_ONLY)) 520 cipher_driver_info[i].accelerated = DEVCRYPTO_NOT_ACCELERATED; 521 else 522 cipher_driver_info[i].accelerated = DEVCRYPTO_ACCELERATED; 523 } 524 #endif /* CIOCGSESSINFO */ 525 } 526 ioctl(cfd, CIOCFSESSION, &sess.ses); 527 if (devcrypto_test_cipher(i)) { 528 known_cipher_nids[known_cipher_nids_amount++] = 529 cipher_data[i].nid; 530 } 531 } 532 } 533 534 static void rebuild_known_cipher_nids(ENGINE *e) 535 { 536 size_t i; 537 538 for (i = 0, known_cipher_nids_amount = 0; i < OSSL_NELEM(cipher_data); i++) { 539 if (devcrypto_test_cipher(i)) 540 known_cipher_nids[known_cipher_nids_amount++] = cipher_data[i].nid; 541 } 542 ENGINE_unregister_ciphers(e); 543 ENGINE_register_ciphers(e); 544 } 545 546 static const EVP_CIPHER *get_cipher_method(int nid) 547 { 548 size_t i = get_cipher_data_index(nid); 549 550 if (i == (size_t)-1) 551 return NULL; 552 return known_cipher_methods[i]; 553 } 554 555 static int get_cipher_nids(const int **nids) 556 { 557 *nids = known_cipher_nids; 558 return known_cipher_nids_amount; 559 } 560 561 static void destroy_cipher_method(int nid) 562 { 563 size_t i = get_cipher_data_index(nid); 564 565 EVP_CIPHER_meth_free(known_cipher_methods[i]); 566 known_cipher_methods[i] = NULL; 567 } 568 569 static void destroy_all_cipher_methods(void) 570 { 571 size_t i; 572 573 for (i = 0; i < OSSL_NELEM(cipher_data); i++) { 574 destroy_cipher_method(cipher_data[i].nid); 575 OPENSSL_free(cipher_driver_info[i].driver_name); 576 cipher_driver_info[i].driver_name = NULL; 577 } 578 } 579 580 static int devcrypto_ciphers(ENGINE *e, const EVP_CIPHER **cipher, 581 const int **nids, int nid) 582 { 583 if (cipher == NULL) 584 return get_cipher_nids(nids); 585 586 *cipher = get_cipher_method(nid); 587 588 return *cipher != NULL; 589 } 590 591 static void devcrypto_select_all_ciphers(int *cipher_list) 592 { 593 size_t i; 594 595 for (i = 0; i < OSSL_NELEM(cipher_data); i++) 596 cipher_list[i] = 1; 597 } 598 599 static int cryptodev_select_cipher_cb(const char *str, int len, void *usr) 600 { 601 int *cipher_list = (int *)usr; 602 char *name; 603 const EVP_CIPHER *EVP; 604 size_t i; 605 606 if (len == 0) 607 return 1; 608 if (usr == NULL || (name = OPENSSL_strndup(str, len)) == NULL) 609 return 0; 610 EVP = EVP_get_cipherbyname(name); 611 if (EVP == NULL) 612 fprintf(stderr, "devcrypto: unknown cipher %s\n", name); 613 else if ((i = find_cipher_data_index(EVP_CIPHER_get_nid(EVP))) != (size_t)-1) 614 cipher_list[i] = 1; 615 else 616 fprintf(stderr, "devcrypto: cipher %s not available\n", name); 617 OPENSSL_free(name); 618 return 1; 619 } 620 621 static void dump_cipher_info(void) 622 { 623 size_t i; 624 const char *name; 625 626 fprintf (stderr, "Information about ciphers supported by the /dev/crypto" 627 " engine:\n"); 628 #ifndef CIOCGSESSINFO 629 fprintf(stderr, "CIOCGSESSINFO (session info call) unavailable\n"); 630 #endif 631 for (i = 0; i < OSSL_NELEM(cipher_data); i++) { 632 name = OBJ_nid2sn(cipher_data[i].nid); 633 fprintf (stderr, "Cipher %s, NID=%d, /dev/crypto info: id=%d, ", 634 name ? name : "unknown", cipher_data[i].nid, 635 cipher_data[i].devcryptoid); 636 if (cipher_driver_info[i].status == DEVCRYPTO_STATUS_NO_CIOCGSESSION ) { 637 fprintf (stderr, "CIOCGSESSION (session open call) failed\n"); 638 continue; 639 } 640 fprintf (stderr, "driver=%s ", cipher_driver_info[i].driver_name ? 641 cipher_driver_info[i].driver_name : "unknown"); 642 if (cipher_driver_info[i].accelerated == DEVCRYPTO_ACCELERATED) 643 fprintf(stderr, "(hw accelerated)"); 644 else if (cipher_driver_info[i].accelerated == DEVCRYPTO_NOT_ACCELERATED) 645 fprintf(stderr, "(software)"); 646 else 647 fprintf(stderr, "(acceleration status unknown)"); 648 if (cipher_driver_info[i].status == DEVCRYPTO_STATUS_FAILURE) 649 fprintf (stderr, ". Cipher setup failed"); 650 fprintf(stderr, "\n"); 651 } 652 fprintf(stderr, "\n"); 653 } 654 655 /* 656 * We only support digests if the cryptodev implementation supports multiple 657 * data updates and session copying. Otherwise, we would be forced to maintain 658 * a cache, which is perilous if there's a lot of data coming in (if someone 659 * wants to checksum an OpenSSL tarball, for example). 660 */ 661 #if defined(CIOCCPHASH) && defined(COP_FLAG_UPDATE) && defined(COP_FLAG_FINAL) 662 #define IMPLEMENT_DIGEST 663 664 /****************************************************************************** 665 * 666 * Digests 667 * 668 * Because they all do the same basic operation, we have only one set of 669 * method functions for them all to share, and a mapping table between 670 * NIDs and cryptodev IDs, with all the necessary size data. 671 * 672 *****/ 673 674 struct digest_ctx { 675 session_op_t sess; 676 /* This signals that the init function was called, not that it succeeded. */ 677 int init_called; 678 unsigned char digest_res[HASH_MAX_LEN]; 679 }; 680 681 static const struct digest_data_st { 682 int nid; 683 int blocksize; 684 int digestlen; 685 int devcryptoid; 686 } digest_data[] = { 687 #ifndef OPENSSL_NO_MD5 688 { NID_md5, /* MD5_CBLOCK */ 64, 16, CRYPTO_MD5 }, 689 #endif 690 { NID_sha1, SHA_CBLOCK, 20, CRYPTO_SHA1 }, 691 #ifndef OPENSSL_NO_RMD160 692 # if !defined(CHECK_BSD_STYLE_MACROS) || defined(CRYPTO_RIPEMD160) 693 { NID_ripemd160, /* RIPEMD160_CBLOCK */ 64, 20, CRYPTO_RIPEMD160 }, 694 # endif 695 #endif 696 #if !defined(CHECK_BSD_STYLE_MACROS) || defined(CRYPTO_SHA2_224) 697 { NID_sha224, SHA256_CBLOCK, 224 / 8, CRYPTO_SHA2_224 }, 698 #endif 699 #if !defined(CHECK_BSD_STYLE_MACROS) || defined(CRYPTO_SHA2_256) 700 { NID_sha256, SHA256_CBLOCK, 256 / 8, CRYPTO_SHA2_256 }, 701 #endif 702 #if !defined(CHECK_BSD_STYLE_MACROS) || defined(CRYPTO_SHA2_384) 703 { NID_sha384, SHA512_CBLOCK, 384 / 8, CRYPTO_SHA2_384 }, 704 #endif 705 #if !defined(CHECK_BSD_STYLE_MACROS) || defined(CRYPTO_SHA2_512) 706 { NID_sha512, SHA512_CBLOCK, 512 / 8, CRYPTO_SHA2_512 }, 707 #endif 708 }; 709 710 static size_t find_digest_data_index(int nid) 711 { 712 size_t i; 713 714 for (i = 0; i < OSSL_NELEM(digest_data); i++) 715 if (nid == digest_data[i].nid) 716 return i; 717 return (size_t)-1; 718 } 719 720 static size_t get_digest_data_index(int nid) 721 { 722 size_t i = find_digest_data_index(nid); 723 724 if (i != (size_t)-1) 725 return i; 726 727 /* 728 * Code further down must make sure that only NIDs in the table above 729 * are used. If any other NID reaches this function, there's a grave 730 * coding error further down. 731 */ 732 assert("Code that never should be reached" == NULL); 733 return -1; 734 } 735 736 static const struct digest_data_st *get_digest_data(int nid) 737 { 738 return &digest_data[get_digest_data_index(nid)]; 739 } 740 741 /* 742 * Following are the five necessary functions to map OpenSSL functionality 743 * with cryptodev: init, update, final, cleanup, and copy. 744 */ 745 746 static int digest_init(EVP_MD_CTX *ctx) 747 { 748 struct digest_ctx *digest_ctx = 749 (struct digest_ctx *)EVP_MD_CTX_get0_md_data(ctx); 750 const struct digest_data_st *digest_d = 751 get_digest_data(EVP_MD_CTX_get_type(ctx)); 752 753 digest_ctx->init_called = 1; 754 755 memset(&digest_ctx->sess, 0, sizeof(digest_ctx->sess)); 756 digest_ctx->sess.mac = digest_d->devcryptoid; 757 if (ioctl(cfd, CIOCGSESSION, &digest_ctx->sess) < 0) { 758 ERR_raise_data(ERR_LIB_SYS, errno, "calling ioctl()"); 759 return 0; 760 } 761 return 1; 762 } 763 764 static int digest_op(struct digest_ctx *ctx, const void *src, size_t srclen, 765 void *res, unsigned int flags) 766 { 767 struct crypt_op cryp; 768 769 memset(&cryp, 0, sizeof(cryp)); 770 cryp.ses = ctx->sess.ses; 771 cryp.len = srclen; 772 cryp.src = (void *)src; 773 cryp.dst = NULL; 774 cryp.mac = res; 775 cryp.flags = flags; 776 return ioctl(cfd, CIOCCRYPT, &cryp); 777 } 778 779 static int digest_update(EVP_MD_CTX *ctx, const void *data, size_t count) 780 { 781 struct digest_ctx *digest_ctx = 782 (struct digest_ctx *)EVP_MD_CTX_get0_md_data(ctx); 783 784 if (count == 0) 785 return 1; 786 787 if (digest_ctx == NULL) 788 return 0; 789 790 if (EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_ONESHOT)) { 791 if (digest_op(digest_ctx, data, count, digest_ctx->digest_res, 0) >= 0) 792 return 1; 793 } else if (digest_op(digest_ctx, data, count, NULL, COP_FLAG_UPDATE) >= 0) { 794 return 1; 795 } 796 797 ERR_raise_data(ERR_LIB_SYS, errno, "calling ioctl()"); 798 return 0; 799 } 800 801 static int digest_final(EVP_MD_CTX *ctx, unsigned char *md) 802 { 803 struct digest_ctx *digest_ctx = 804 (struct digest_ctx *)EVP_MD_CTX_get0_md_data(ctx); 805 806 if (md == NULL || digest_ctx == NULL) 807 return 0; 808 809 if (EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_ONESHOT)) { 810 memcpy(md, digest_ctx->digest_res, EVP_MD_CTX_get_size(ctx)); 811 } else if (digest_op(digest_ctx, NULL, 0, md, COP_FLAG_FINAL) < 0) { 812 ERR_raise_data(ERR_LIB_SYS, errno, "calling ioctl()"); 813 return 0; 814 } 815 816 return 1; 817 } 818 819 static int digest_copy(EVP_MD_CTX *to, const EVP_MD_CTX *from) 820 { 821 struct digest_ctx *digest_from = 822 (struct digest_ctx *)EVP_MD_CTX_get0_md_data(from); 823 struct digest_ctx *digest_to = 824 (struct digest_ctx *)EVP_MD_CTX_get0_md_data(to); 825 struct cphash_op cphash; 826 827 if (digest_from == NULL || digest_from->init_called != 1) 828 return 1; 829 830 if (!digest_init(to)) { 831 ERR_raise_data(ERR_LIB_SYS, errno, "calling ioctl()"); 832 return 0; 833 } 834 835 cphash.src_ses = digest_from->sess.ses; 836 cphash.dst_ses = digest_to->sess.ses; 837 if (ioctl(cfd, CIOCCPHASH, &cphash) < 0) { 838 ERR_raise_data(ERR_LIB_SYS, errno, "calling ioctl()"); 839 return 0; 840 } 841 return 1; 842 } 843 844 static int digest_cleanup(EVP_MD_CTX *ctx) 845 { 846 struct digest_ctx *digest_ctx = 847 (struct digest_ctx *)EVP_MD_CTX_get0_md_data(ctx); 848 849 if (digest_ctx == NULL) 850 return 1; 851 852 return clean_devcrypto_session(&digest_ctx->sess); 853 } 854 855 /* 856 * Keep tables of known nids, associated methods, selected digests, and 857 * driver info. 858 * Note that known_digest_nids[] isn't necessarily indexed the same way as 859 * digest_data[] above, which the other tables are. 860 */ 861 static int known_digest_nids[OSSL_NELEM(digest_data)]; 862 static int known_digest_nids_amount = -1; /* -1 indicates not yet initialised */ 863 static EVP_MD *known_digest_methods[OSSL_NELEM(digest_data)] = { NULL, }; 864 static int selected_digests[OSSL_NELEM(digest_data)]; 865 static struct driver_info_st digest_driver_info[OSSL_NELEM(digest_data)]; 866 867 static int devcrypto_test_digest(size_t digest_data_index) 868 { 869 return (digest_driver_info[digest_data_index].status == DEVCRYPTO_STATUS_USABLE 870 && selected_digests[digest_data_index] == 1 871 && (digest_driver_info[digest_data_index].accelerated 872 == DEVCRYPTO_ACCELERATED 873 || use_softdrivers == DEVCRYPTO_USE_SOFTWARE 874 || (digest_driver_info[digest_data_index].accelerated 875 != DEVCRYPTO_NOT_ACCELERATED 876 && use_softdrivers == DEVCRYPTO_REJECT_SOFTWARE))); 877 } 878 879 static void rebuild_known_digest_nids(ENGINE *e) 880 { 881 size_t i; 882 883 for (i = 0, known_digest_nids_amount = 0; i < OSSL_NELEM(digest_data); i++) { 884 if (devcrypto_test_digest(i)) 885 known_digest_nids[known_digest_nids_amount++] = digest_data[i].nid; 886 } 887 ENGINE_unregister_digests(e); 888 ENGINE_register_digests(e); 889 } 890 891 static void prepare_digest_methods(void) 892 { 893 size_t i; 894 session_op_t sess1, sess2; 895 #ifdef CIOCGSESSINFO 896 struct session_info_op siop; 897 #endif 898 struct cphash_op cphash; 899 900 memset(&digest_driver_info, 0, sizeof(digest_driver_info)); 901 902 memset(&sess1, 0, sizeof(sess1)); 903 memset(&sess2, 0, sizeof(sess2)); 904 905 for (i = 0, known_digest_nids_amount = 0; i < OSSL_NELEM(digest_data); 906 i++) { 907 908 selected_digests[i] = 1; 909 910 /* 911 * Check that the digest is usable 912 */ 913 sess1.mac = digest_data[i].devcryptoid; 914 sess2.ses = 0; 915 if (ioctl(cfd, CIOCGSESSION, &sess1) < 0) { 916 digest_driver_info[i].status = DEVCRYPTO_STATUS_NO_CIOCGSESSION; 917 goto finish; 918 } 919 920 #ifdef CIOCGSESSINFO 921 /* gather hardware acceleration info from the driver */ 922 siop.ses = sess1.ses; 923 if (ioctl(cfd, CIOCGSESSINFO, &siop) < 0) { 924 digest_driver_info[i].accelerated = DEVCRYPTO_ACCELERATION_UNKNOWN; 925 } else { 926 digest_driver_info[i].driver_name = 927 OPENSSL_strndup(siop.hash_info.cra_driver_name, 928 CRYPTODEV_MAX_ALG_NAME); 929 if (siop.flags & SIOP_FLAG_KERNEL_DRIVER_ONLY) 930 digest_driver_info[i].accelerated = DEVCRYPTO_ACCELERATED; 931 else 932 digest_driver_info[i].accelerated = DEVCRYPTO_NOT_ACCELERATED; 933 } 934 #endif 935 936 /* digest must be capable of hash state copy */ 937 sess2.mac = sess1.mac; 938 if (ioctl(cfd, CIOCGSESSION, &sess2) < 0) { 939 digest_driver_info[i].status = DEVCRYPTO_STATUS_FAILURE; 940 goto finish; 941 } 942 cphash.src_ses = sess1.ses; 943 cphash.dst_ses = sess2.ses; 944 if (ioctl(cfd, CIOCCPHASH, &cphash) < 0) { 945 digest_driver_info[i].status = DEVCRYPTO_STATUS_NO_CIOCCPHASH; 946 goto finish; 947 } 948 if ((known_digest_methods[i] = EVP_MD_meth_new(digest_data[i].nid, 949 NID_undef)) == NULL 950 || !EVP_MD_meth_set_input_blocksize(known_digest_methods[i], 951 digest_data[i].blocksize) 952 || !EVP_MD_meth_set_result_size(known_digest_methods[i], 953 digest_data[i].digestlen) 954 || !EVP_MD_meth_set_init(known_digest_methods[i], digest_init) 955 || !EVP_MD_meth_set_update(known_digest_methods[i], digest_update) 956 || !EVP_MD_meth_set_final(known_digest_methods[i], digest_final) 957 || !EVP_MD_meth_set_copy(known_digest_methods[i], digest_copy) 958 || !EVP_MD_meth_set_cleanup(known_digest_methods[i], digest_cleanup) 959 || !EVP_MD_meth_set_app_datasize(known_digest_methods[i], 960 sizeof(struct digest_ctx))) { 961 digest_driver_info[i].status = DEVCRYPTO_STATUS_FAILURE; 962 EVP_MD_meth_free(known_digest_methods[i]); 963 known_digest_methods[i] = NULL; 964 goto finish; 965 } 966 digest_driver_info[i].status = DEVCRYPTO_STATUS_USABLE; 967 finish: 968 ioctl(cfd, CIOCFSESSION, &sess1.ses); 969 if (sess2.ses != 0) 970 ioctl(cfd, CIOCFSESSION, &sess2.ses); 971 if (devcrypto_test_digest(i)) 972 known_digest_nids[known_digest_nids_amount++] = digest_data[i].nid; 973 } 974 } 975 976 static const EVP_MD *get_digest_method(int nid) 977 { 978 size_t i = get_digest_data_index(nid); 979 980 if (i == (size_t)-1) 981 return NULL; 982 return known_digest_methods[i]; 983 } 984 985 static int get_digest_nids(const int **nids) 986 { 987 *nids = known_digest_nids; 988 return known_digest_nids_amount; 989 } 990 991 static void destroy_digest_method(int nid) 992 { 993 size_t i = get_digest_data_index(nid); 994 995 EVP_MD_meth_free(known_digest_methods[i]); 996 known_digest_methods[i] = NULL; 997 } 998 999 static void destroy_all_digest_methods(void) 1000 { 1001 size_t i; 1002 1003 for (i = 0; i < OSSL_NELEM(digest_data); i++) { 1004 destroy_digest_method(digest_data[i].nid); 1005 OPENSSL_free(digest_driver_info[i].driver_name); 1006 digest_driver_info[i].driver_name = NULL; 1007 } 1008 } 1009 1010 static int devcrypto_digests(ENGINE *e, const EVP_MD **digest, 1011 const int **nids, int nid) 1012 { 1013 if (digest == NULL) 1014 return get_digest_nids(nids); 1015 1016 *digest = get_digest_method(nid); 1017 1018 return *digest != NULL; 1019 } 1020 1021 static void devcrypto_select_all_digests(int *digest_list) 1022 { 1023 size_t i; 1024 1025 for (i = 0; i < OSSL_NELEM(digest_data); i++) 1026 digest_list[i] = 1; 1027 } 1028 1029 static int cryptodev_select_digest_cb(const char *str, int len, void *usr) 1030 { 1031 int *digest_list = (int *)usr; 1032 char *name; 1033 const EVP_MD *EVP; 1034 size_t i; 1035 1036 if (len == 0) 1037 return 1; 1038 if (usr == NULL || (name = OPENSSL_strndup(str, len)) == NULL) 1039 return 0; 1040 EVP = EVP_get_digestbyname(name); 1041 if (EVP == NULL) 1042 fprintf(stderr, "devcrypto: unknown digest %s\n", name); 1043 else if ((i = find_digest_data_index(EVP_MD_get_type(EVP))) != (size_t)-1) 1044 digest_list[i] = 1; 1045 else 1046 fprintf(stderr, "devcrypto: digest %s not available\n", name); 1047 OPENSSL_free(name); 1048 return 1; 1049 } 1050 1051 static void dump_digest_info(void) 1052 { 1053 size_t i; 1054 const char *name; 1055 1056 fprintf (stderr, "Information about digests supported by the /dev/crypto" 1057 " engine:\n"); 1058 #ifndef CIOCGSESSINFO 1059 fprintf(stderr, "CIOCGSESSINFO (session info call) unavailable\n"); 1060 #endif 1061 1062 for (i = 0; i < OSSL_NELEM(digest_data); i++) { 1063 name = OBJ_nid2sn(digest_data[i].nid); 1064 fprintf (stderr, "Digest %s, NID=%d, /dev/crypto info: id=%d, driver=%s", 1065 name ? name : "unknown", digest_data[i].nid, 1066 digest_data[i].devcryptoid, 1067 digest_driver_info[i].driver_name ? digest_driver_info[i].driver_name : "unknown"); 1068 if (digest_driver_info[i].status == DEVCRYPTO_STATUS_NO_CIOCGSESSION) { 1069 fprintf (stderr, ". CIOCGSESSION (session open) failed\n"); 1070 continue; 1071 } 1072 if (digest_driver_info[i].accelerated == DEVCRYPTO_ACCELERATED) 1073 fprintf(stderr, " (hw accelerated)"); 1074 else if (digest_driver_info[i].accelerated == DEVCRYPTO_NOT_ACCELERATED) 1075 fprintf(stderr, " (software)"); 1076 else 1077 fprintf(stderr, " (acceleration status unknown)"); 1078 if (cipher_driver_info[i].status == DEVCRYPTO_STATUS_FAILURE) 1079 fprintf (stderr, ". Cipher setup failed\n"); 1080 else if (digest_driver_info[i].status == DEVCRYPTO_STATUS_NO_CIOCCPHASH) 1081 fprintf(stderr, ", CIOCCPHASH failed\n"); 1082 else 1083 fprintf(stderr, ", CIOCCPHASH capable\n"); 1084 } 1085 fprintf(stderr, "\n"); 1086 } 1087 1088 #endif 1089 1090 /****************************************************************************** 1091 * 1092 * CONTROL COMMANDS 1093 * 1094 *****/ 1095 1096 #define DEVCRYPTO_CMD_USE_SOFTDRIVERS ENGINE_CMD_BASE 1097 #define DEVCRYPTO_CMD_CIPHERS (ENGINE_CMD_BASE + 1) 1098 #define DEVCRYPTO_CMD_DIGESTS (ENGINE_CMD_BASE + 2) 1099 #define DEVCRYPTO_CMD_DUMP_INFO (ENGINE_CMD_BASE + 3) 1100 1101 static const ENGINE_CMD_DEFN devcrypto_cmds[] = { 1102 #if defined(CIOCGSESSINFO) || defined(CIOCGSESSION2) 1103 {DEVCRYPTO_CMD_USE_SOFTDRIVERS, 1104 "USE_SOFTDRIVERS", 1105 "specifies whether to use software (not accelerated) drivers (" 1106 OPENSSL_MSTR(DEVCRYPTO_REQUIRE_ACCELERATED) "=use only accelerated drivers, " 1107 OPENSSL_MSTR(DEVCRYPTO_USE_SOFTWARE) "=allow all drivers, " 1108 OPENSSL_MSTR(DEVCRYPTO_REJECT_SOFTWARE) 1109 "=use if acceleration can't be determined) [default=" 1110 OPENSSL_MSTR(DEVCRYPTO_DEFAULT_USE_SOFTDRIVERS) "]", 1111 ENGINE_CMD_FLAG_NUMERIC}, 1112 #endif 1113 1114 {DEVCRYPTO_CMD_CIPHERS, 1115 "CIPHERS", 1116 "either ALL, NONE, or a comma-separated list of ciphers to enable [default=ALL]", 1117 ENGINE_CMD_FLAG_STRING}, 1118 1119 #ifdef IMPLEMENT_DIGEST 1120 {DEVCRYPTO_CMD_DIGESTS, 1121 "DIGESTS", 1122 "either ALL, NONE, or a comma-separated list of digests to enable [default=ALL]", 1123 ENGINE_CMD_FLAG_STRING}, 1124 #endif 1125 1126 {DEVCRYPTO_CMD_DUMP_INFO, 1127 "DUMP_INFO", 1128 "dump info about each algorithm to stderr; use 'openssl engine -pre DUMP_INFO devcrypto'", 1129 ENGINE_CMD_FLAG_NO_INPUT}, 1130 1131 {0, NULL, NULL, 0} 1132 }; 1133 1134 static int devcrypto_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f) (void)) 1135 { 1136 int *new_list; 1137 switch (cmd) { 1138 #if defined(CIOCGSESSINFO) || defined(CIOCGSESSION2) 1139 case DEVCRYPTO_CMD_USE_SOFTDRIVERS: 1140 switch (i) { 1141 case DEVCRYPTO_REQUIRE_ACCELERATED: 1142 case DEVCRYPTO_USE_SOFTWARE: 1143 case DEVCRYPTO_REJECT_SOFTWARE: 1144 break; 1145 default: 1146 fprintf(stderr, "devcrypto: invalid value (%ld) for USE_SOFTDRIVERS\n", i); 1147 return 0; 1148 } 1149 if (use_softdrivers == i) 1150 return 1; 1151 use_softdrivers = i; 1152 #ifdef IMPLEMENT_DIGEST 1153 rebuild_known_digest_nids(e); 1154 #endif 1155 rebuild_known_cipher_nids(e); 1156 return 1; 1157 #endif /* CIOCGSESSINFO || CIOCGSESSION2 */ 1158 1159 case DEVCRYPTO_CMD_CIPHERS: 1160 if (p == NULL) 1161 return 1; 1162 if (OPENSSL_strcasecmp((const char *)p, "ALL") == 0) { 1163 devcrypto_select_all_ciphers(selected_ciphers); 1164 } else if (OPENSSL_strcasecmp((const char*)p, "NONE") == 0) { 1165 memset(selected_ciphers, 0, sizeof(selected_ciphers)); 1166 } else { 1167 new_list=OPENSSL_zalloc(sizeof(selected_ciphers)); 1168 if (!CONF_parse_list(p, ',', 1, cryptodev_select_cipher_cb, new_list)) { 1169 OPENSSL_free(new_list); 1170 return 0; 1171 } 1172 memcpy(selected_ciphers, new_list, sizeof(selected_ciphers)); 1173 OPENSSL_free(new_list); 1174 } 1175 rebuild_known_cipher_nids(e); 1176 return 1; 1177 1178 #ifdef IMPLEMENT_DIGEST 1179 case DEVCRYPTO_CMD_DIGESTS: 1180 if (p == NULL) 1181 return 1; 1182 if (OPENSSL_strcasecmp((const char *)p, "ALL") == 0) { 1183 devcrypto_select_all_digests(selected_digests); 1184 } else if (OPENSSL_strcasecmp((const char*)p, "NONE") == 0) { 1185 memset(selected_digests, 0, sizeof(selected_digests)); 1186 } else { 1187 new_list=OPENSSL_zalloc(sizeof(selected_digests)); 1188 if (!CONF_parse_list(p, ',', 1, cryptodev_select_digest_cb, new_list)) { 1189 OPENSSL_free(new_list); 1190 return 0; 1191 } 1192 memcpy(selected_digests, new_list, sizeof(selected_digests)); 1193 OPENSSL_free(new_list); 1194 } 1195 rebuild_known_digest_nids(e); 1196 return 1; 1197 #endif /* IMPLEMENT_DIGEST */ 1198 1199 case DEVCRYPTO_CMD_DUMP_INFO: 1200 dump_cipher_info(); 1201 #ifdef IMPLEMENT_DIGEST 1202 dump_digest_info(); 1203 #endif 1204 return 1; 1205 1206 default: 1207 break; 1208 } 1209 return 0; 1210 } 1211 1212 /****************************************************************************** 1213 * 1214 * LOAD / UNLOAD 1215 * 1216 *****/ 1217 1218 /* 1219 * Opens /dev/crypto 1220 */ 1221 static int open_devcrypto(void) 1222 { 1223 int fd; 1224 1225 if (cfd >= 0) 1226 return 1; 1227 1228 if ((fd = open("/dev/crypto", O_RDWR, 0)) < 0) { 1229 #ifndef ENGINE_DEVCRYPTO_DEBUG 1230 if (errno != ENOENT) 1231 #endif 1232 fprintf(stderr, "Could not open /dev/crypto: %s\n", strerror(errno)); 1233 return 0; 1234 } 1235 1236 #ifdef CRIOGET 1237 if (ioctl(fd, CRIOGET, &cfd) < 0) { 1238 fprintf(stderr, "Could not create crypto fd: %s\n", strerror(errno)); 1239 close(fd); 1240 cfd = -1; 1241 return 0; 1242 } 1243 close(fd); 1244 #else 1245 cfd = fd; 1246 #endif 1247 1248 return 1; 1249 } 1250 1251 static int close_devcrypto(void) 1252 { 1253 int ret; 1254 1255 if (cfd < 0) 1256 return 1; 1257 ret = close(cfd); 1258 cfd = -1; 1259 if (ret != 0) { 1260 fprintf(stderr, "Error closing /dev/crypto: %s\n", strerror(errno)); 1261 return 0; 1262 } 1263 return 1; 1264 } 1265 1266 static int devcrypto_unload(ENGINE *e) 1267 { 1268 destroy_all_cipher_methods(); 1269 #ifdef IMPLEMENT_DIGEST 1270 destroy_all_digest_methods(); 1271 #endif 1272 1273 close_devcrypto(); 1274 1275 return 1; 1276 } 1277 1278 static int bind_devcrypto(ENGINE *e) { 1279 1280 if (!ENGINE_set_id(e, engine_devcrypto_id) 1281 || !ENGINE_set_name(e, "/dev/crypto engine") 1282 || !ENGINE_set_destroy_function(e, devcrypto_unload) 1283 || !ENGINE_set_cmd_defns(e, devcrypto_cmds) 1284 || !ENGINE_set_ctrl_function(e, devcrypto_ctrl)) 1285 return 0; 1286 1287 prepare_cipher_methods(); 1288 #ifdef IMPLEMENT_DIGEST 1289 prepare_digest_methods(); 1290 #endif 1291 1292 return (ENGINE_set_ciphers(e, devcrypto_ciphers) 1293 #ifdef IMPLEMENT_DIGEST 1294 && ENGINE_set_digests(e, devcrypto_digests) 1295 #endif 1296 /* 1297 * Asymmetric ciphers aren't well supported with /dev/crypto. Among the BSD 1298 * implementations, it seems to only exist in FreeBSD, and regarding the 1299 * parameters in its crypt_kop, the manual crypto(4) has this to say: 1300 * 1301 * The semantics of these arguments are currently undocumented. 1302 * 1303 * Reading through the FreeBSD source code doesn't give much more than 1304 * their CRK_MOD_EXP implementation for ubsec. 1305 * 1306 * It doesn't look much better with cryptodev-linux. They have the crypt_kop 1307 * structure as well as the command (CRK_*) in cryptodev.h, but no support 1308 * seems to be implemented at all for the moment. 1309 * 1310 * At the time of writing, it seems impossible to write proper support for 1311 * FreeBSD's asym features without some very deep knowledge and access to 1312 * specific kernel modules. 1313 * 1314 * /Richard Levitte, 2017-05-11 1315 */ 1316 #if 0 1317 && ENGINE_set_RSA(e, devcrypto_rsa) 1318 # ifndef OPENSSL_NO_DSA 1319 && ENGINE_set_DSA(e, devcrypto_dsa) 1320 # endif 1321 # ifndef OPENSSL_NO_DH 1322 && ENGINE_set_DH(e, devcrypto_dh) 1323 # endif 1324 # ifndef OPENSSL_NO_EC 1325 && ENGINE_set_EC(e, devcrypto_ec) 1326 # endif 1327 #endif 1328 ); 1329 } 1330 1331 #ifdef OPENSSL_NO_DYNAMIC_ENGINE 1332 /* 1333 * In case this engine is built into libcrypto, then it doesn't offer any 1334 * ability to be dynamically loadable. 1335 */ 1336 void engine_load_devcrypto_int(void) 1337 { 1338 ENGINE *e = NULL; 1339 1340 if (!open_devcrypto()) 1341 return; 1342 1343 if ((e = ENGINE_new()) == NULL 1344 || !bind_devcrypto(e)) { 1345 close_devcrypto(); 1346 ENGINE_free(e); 1347 return; 1348 } 1349 1350 ERR_set_mark(); 1351 ENGINE_add(e); 1352 /* 1353 * If the "add" worked, it gets a structural reference. So either way, we 1354 * release our just-created reference. 1355 */ 1356 ENGINE_free(e); /* Loose our local reference */ 1357 /* 1358 * If the "add" didn't work, it was probably a conflict because it was 1359 * already added (eg. someone calling ENGINE_load_blah then calling 1360 * ENGINE_load_builtin_engines() perhaps). 1361 */ 1362 ERR_pop_to_mark(); 1363 } 1364 1365 #else 1366 1367 static int bind_helper(ENGINE *e, const char *id) 1368 { 1369 if ((id && (strcmp(id, engine_devcrypto_id) != 0)) 1370 || !open_devcrypto()) 1371 return 0; 1372 if (!bind_devcrypto(e)) { 1373 close_devcrypto(); 1374 return 0; 1375 } 1376 return 1; 1377 } 1378 1379 IMPLEMENT_DYNAMIC_CHECK_FN() 1380 IMPLEMENT_DYNAMIC_BIND_FN(bind_helper) 1381 1382 #endif 1383