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