1 /* 2 * Copyright 2016-2021 The OpenSSL Project Authors. All Rights Reserved. 3 * 4 * Licensed under the OpenSSL license (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 /* Required for vmsplice */ 11 #ifndef _GNU_SOURCE 12 # define _GNU_SOURCE 13 #endif 14 #include <stdio.h> 15 #include <string.h> 16 #include <unistd.h> 17 18 #include <openssl/engine.h> 19 #include <openssl/async.h> 20 #include <openssl/err.h> 21 #include "internal/nelem.h" 22 23 #include <sys/socket.h> 24 #include <linux/version.h> 25 #define K_MAJ 4 26 #define K_MIN1 1 27 #define K_MIN2 0 28 #if LINUX_VERSION_CODE < KERNEL_VERSION(K_MAJ, K_MIN1, K_MIN2) || \ 29 !defined(AF_ALG) 30 # ifndef PEDANTIC 31 # warning "AFALG ENGINE requires Kernel Headers >= 4.1.0" 32 # warning "Skipping Compilation of AFALG engine" 33 # endif 34 void engine_load_afalg_int(void); 35 void engine_load_afalg_int(void) 36 { 37 } 38 #else 39 40 # include <linux/if_alg.h> 41 # include <fcntl.h> 42 # include <sys/utsname.h> 43 44 # include <linux/aio_abi.h> 45 # include <sys/syscall.h> 46 # include <errno.h> 47 48 # include "e_afalg.h" 49 # include "e_afalg_err.c" 50 51 # ifndef SOL_ALG 52 # define SOL_ALG 279 53 # endif 54 55 # ifdef ALG_ZERO_COPY 56 # ifndef SPLICE_F_GIFT 57 # define SPLICE_F_GIFT (0x08) 58 # endif 59 # endif 60 61 # define ALG_AES_IV_LEN 16 62 # define ALG_IV_LEN(len) (sizeof(struct af_alg_iv) + (len)) 63 # define ALG_OP_TYPE unsigned int 64 # define ALG_OP_LEN (sizeof(ALG_OP_TYPE)) 65 66 # ifdef OPENSSL_NO_DYNAMIC_ENGINE 67 void engine_load_afalg_int(void); 68 # endif 69 70 /* Local Linkage Functions */ 71 static int afalg_init_aio(afalg_aio *aio); 72 static int afalg_fin_cipher_aio(afalg_aio *ptr, int sfd, 73 unsigned char *buf, size_t len); 74 static int afalg_create_sk(afalg_ctx *actx, const char *ciphertype, 75 const char *ciphername); 76 static int afalg_destroy(ENGINE *e); 77 static int afalg_init(ENGINE *e); 78 static int afalg_finish(ENGINE *e); 79 static const EVP_CIPHER *afalg_aes_cbc(int nid); 80 static cbc_handles *get_cipher_handle(int nid); 81 static int afalg_ciphers(ENGINE *e, const EVP_CIPHER **cipher, 82 const int **nids, int nid); 83 static int afalg_cipher_init(EVP_CIPHER_CTX *ctx, const unsigned char *key, 84 const unsigned char *iv, int enc); 85 static int afalg_do_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, 86 const unsigned char *in, size_t inl); 87 static int afalg_cipher_cleanup(EVP_CIPHER_CTX *ctx); 88 static int afalg_chk_platform(void); 89 90 /* Engine Id and Name */ 91 static const char *engine_afalg_id = "afalg"; 92 static const char *engine_afalg_name = "AFALG engine support"; 93 94 static int afalg_cipher_nids[] = { 95 NID_aes_128_cbc, 96 NID_aes_192_cbc, 97 NID_aes_256_cbc, 98 }; 99 100 static cbc_handles cbc_handle[] = {{AES_KEY_SIZE_128, NULL}, 101 {AES_KEY_SIZE_192, NULL}, 102 {AES_KEY_SIZE_256, NULL}}; 103 104 static ossl_inline int io_setup(unsigned n, aio_context_t *ctx) 105 { 106 return syscall(__NR_io_setup, n, ctx); 107 } 108 109 static ossl_inline int eventfd(int n) 110 { 111 return syscall(__NR_eventfd2, n, 0); 112 } 113 114 static ossl_inline int io_destroy(aio_context_t ctx) 115 { 116 return syscall(__NR_io_destroy, ctx); 117 } 118 119 static ossl_inline int io_read(aio_context_t ctx, long n, struct iocb **iocb) 120 { 121 return syscall(__NR_io_submit, ctx, n, iocb); 122 } 123 124 static ossl_inline int io_getevents(aio_context_t ctx, long min, long max, 125 struct io_event *events, 126 struct timespec *timeout) 127 { 128 return syscall(__NR_io_getevents, ctx, min, max, events, timeout); 129 } 130 131 static void afalg_waitfd_cleanup(ASYNC_WAIT_CTX *ctx, const void *key, 132 OSSL_ASYNC_FD waitfd, void *custom) 133 { 134 close(waitfd); 135 } 136 137 static int afalg_setup_async_event_notification(afalg_aio *aio) 138 { 139 ASYNC_JOB *job; 140 ASYNC_WAIT_CTX *waitctx; 141 void *custom = NULL; 142 int ret; 143 144 if ((job = ASYNC_get_current_job()) != NULL) { 145 /* Async mode */ 146 waitctx = ASYNC_get_wait_ctx(job); 147 if (waitctx == NULL) { 148 ALG_WARN("%s(%d): ASYNC_get_wait_ctx error", __FILE__, __LINE__); 149 return 0; 150 } 151 /* Get waitfd from ASYNC_WAIT_CTX if it is already set */ 152 ret = ASYNC_WAIT_CTX_get_fd(waitctx, engine_afalg_id, 153 &aio->efd, &custom); 154 if (ret == 0) { 155 /* 156 * waitfd is not set in ASYNC_WAIT_CTX, create a new one 157 * and set it. efd will be signaled when AIO operation completes 158 */ 159 aio->efd = eventfd(0); 160 if (aio->efd == -1) { 161 ALG_PERR("%s(%d): Failed to get eventfd : ", __FILE__, 162 __LINE__); 163 AFALGerr(AFALG_F_AFALG_SETUP_ASYNC_EVENT_NOTIFICATION, 164 AFALG_R_EVENTFD_FAILED); 165 return 0; 166 } 167 ret = ASYNC_WAIT_CTX_set_wait_fd(waitctx, engine_afalg_id, 168 aio->efd, custom, 169 afalg_waitfd_cleanup); 170 if (ret == 0) { 171 ALG_WARN("%s(%d): Failed to set wait fd", __FILE__, __LINE__); 172 close(aio->efd); 173 return 0; 174 } 175 /* make fd non-blocking in async mode */ 176 if (fcntl(aio->efd, F_SETFL, O_NONBLOCK) != 0) { 177 ALG_WARN("%s(%d): Failed to set event fd as NONBLOCKING", 178 __FILE__, __LINE__); 179 } 180 } 181 aio->mode = MODE_ASYNC; 182 } else { 183 /* Sync mode */ 184 aio->efd = eventfd(0); 185 if (aio->efd == -1) { 186 ALG_PERR("%s(%d): Failed to get eventfd : ", __FILE__, __LINE__); 187 AFALGerr(AFALG_F_AFALG_SETUP_ASYNC_EVENT_NOTIFICATION, 188 AFALG_R_EVENTFD_FAILED); 189 return 0; 190 } 191 aio->mode = MODE_SYNC; 192 } 193 return 1; 194 } 195 196 static int afalg_init_aio(afalg_aio *aio) 197 { 198 int r = -1; 199 200 /* Initialise for AIO */ 201 aio->aio_ctx = 0; 202 r = io_setup(MAX_INFLIGHTS, &aio->aio_ctx); 203 if (r < 0) { 204 ALG_PERR("%s(%d): io_setup error : ", __FILE__, __LINE__); 205 AFALGerr(AFALG_F_AFALG_INIT_AIO, AFALG_R_IO_SETUP_FAILED); 206 return 0; 207 } 208 209 memset(aio->cbt, 0, sizeof(aio->cbt)); 210 aio->efd = -1; 211 aio->mode = MODE_UNINIT; 212 213 return 1; 214 } 215 216 static int afalg_fin_cipher_aio(afalg_aio *aio, int sfd, unsigned char *buf, 217 size_t len) 218 { 219 int r; 220 int retry = 0; 221 unsigned int done = 0; 222 struct iocb *cb; 223 struct timespec timeout; 224 struct io_event events[MAX_INFLIGHTS]; 225 u_int64_t eval = 0; 226 227 timeout.tv_sec = 0; 228 timeout.tv_nsec = 0; 229 230 /* if efd has not been initialised yet do it here */ 231 if (aio->mode == MODE_UNINIT) { 232 r = afalg_setup_async_event_notification(aio); 233 if (r == 0) 234 return 0; 235 } 236 237 cb = &(aio->cbt[0 % MAX_INFLIGHTS]); 238 memset(cb, '\0', sizeof(*cb)); 239 cb->aio_fildes = sfd; 240 cb->aio_lio_opcode = IOCB_CMD_PREAD; 241 /* 242 * The pointer has to be converted to unsigned value first to avoid 243 * sign extension on cast to 64 bit value in 32-bit builds 244 */ 245 cb->aio_buf = (size_t)buf; 246 cb->aio_offset = 0; 247 cb->aio_data = 0; 248 cb->aio_nbytes = len; 249 cb->aio_flags = IOCB_FLAG_RESFD; 250 cb->aio_resfd = aio->efd; 251 252 /* 253 * Perform AIO read on AFALG socket, this in turn performs an async 254 * crypto operation in kernel space 255 */ 256 r = io_read(aio->aio_ctx, 1, &cb); 257 if (r < 0) { 258 ALG_PWARN("%s(%d): io_read failed : ", __FILE__, __LINE__); 259 return 0; 260 } 261 262 do { 263 /* While AIO read is being performed pause job */ 264 ASYNC_pause_job(); 265 266 /* Check for completion of AIO read */ 267 r = read(aio->efd, &eval, sizeof(eval)); 268 if (r < 0) { 269 if (errno == EAGAIN || errno == EWOULDBLOCK) 270 continue; 271 ALG_PERR("%s(%d): read failed for event fd : ", __FILE__, __LINE__); 272 return 0; 273 } else if (r == 0 || eval <= 0) { 274 ALG_WARN("%s(%d): eventfd read %d bytes, eval = %lu\n", __FILE__, 275 __LINE__, r, eval); 276 } 277 if (eval > 0) { 278 279 /* Get results of AIO read */ 280 r = io_getevents(aio->aio_ctx, 1, MAX_INFLIGHTS, 281 events, &timeout); 282 if (r > 0) { 283 /* 284 * events.res indicates the actual status of the operation. 285 * Handle the error condition first. 286 */ 287 if (events[0].res < 0) { 288 /* 289 * Underlying operation cannot be completed at the time 290 * of previous submission. Resubmit for the operation. 291 */ 292 if (events[0].res == -EBUSY && retry++ < 3) { 293 r = io_read(aio->aio_ctx, 1, &cb); 294 if (r < 0) { 295 ALG_PERR("%s(%d): retry %d for io_read failed : ", 296 __FILE__, __LINE__, retry); 297 return 0; 298 } 299 continue; 300 } else { 301 /* 302 * Retries exceed for -EBUSY or unrecoverable error 303 * condition for this instance of operation. 304 */ 305 ALG_WARN 306 ("%s(%d): Crypto Operation failed with code %lld\n", 307 __FILE__, __LINE__, events[0].res); 308 return 0; 309 } 310 } 311 /* Operation successful. */ 312 done = 1; 313 } else if (r < 0) { 314 ALG_PERR("%s(%d): io_getevents failed : ", __FILE__, __LINE__); 315 return 0; 316 } else { 317 ALG_WARN("%s(%d): io_geteventd read 0 bytes\n", __FILE__, 318 __LINE__); 319 } 320 } 321 } while (!done); 322 323 return 1; 324 } 325 326 static ossl_inline void afalg_set_op_sk(struct cmsghdr *cmsg, 327 const ALG_OP_TYPE op) 328 { 329 cmsg->cmsg_level = SOL_ALG; 330 cmsg->cmsg_type = ALG_SET_OP; 331 cmsg->cmsg_len = CMSG_LEN(ALG_OP_LEN); 332 memcpy(CMSG_DATA(cmsg), &op, ALG_OP_LEN); 333 } 334 335 static void afalg_set_iv_sk(struct cmsghdr *cmsg, const unsigned char *iv, 336 const unsigned int len) 337 { 338 struct af_alg_iv *aiv; 339 340 cmsg->cmsg_level = SOL_ALG; 341 cmsg->cmsg_type = ALG_SET_IV; 342 cmsg->cmsg_len = CMSG_LEN(ALG_IV_LEN(len)); 343 aiv = (struct af_alg_iv *)CMSG_DATA(cmsg); 344 aiv->ivlen = len; 345 memcpy(aiv->iv, iv, len); 346 } 347 348 static ossl_inline int afalg_set_key(afalg_ctx *actx, const unsigned char *key, 349 const int klen) 350 { 351 int ret; 352 ret = setsockopt(actx->bfd, SOL_ALG, ALG_SET_KEY, key, klen); 353 if (ret < 0) { 354 ALG_PERR("%s(%d): Failed to set socket option : ", __FILE__, __LINE__); 355 AFALGerr(AFALG_F_AFALG_SET_KEY, AFALG_R_SOCKET_SET_KEY_FAILED); 356 return 0; 357 } 358 return 1; 359 } 360 361 static int afalg_create_sk(afalg_ctx *actx, const char *ciphertype, 362 const char *ciphername) 363 { 364 struct sockaddr_alg sa; 365 int r = -1; 366 367 actx->bfd = actx->sfd = -1; 368 369 memset(&sa, 0, sizeof(sa)); 370 sa.salg_family = AF_ALG; 371 OPENSSL_strlcpy((char *) sa.salg_type, ciphertype, sizeof(sa.salg_type)); 372 OPENSSL_strlcpy((char *) sa.salg_name, ciphername, sizeof(sa.salg_name)); 373 374 actx->bfd = socket(AF_ALG, SOCK_SEQPACKET, 0); 375 if (actx->bfd == -1) { 376 ALG_PERR("%s(%d): Failed to open socket : ", __FILE__, __LINE__); 377 AFALGerr(AFALG_F_AFALG_CREATE_SK, AFALG_R_SOCKET_CREATE_FAILED); 378 goto err; 379 } 380 381 r = bind(actx->bfd, (struct sockaddr *)&sa, sizeof(sa)); 382 if (r < 0) { 383 ALG_PERR("%s(%d): Failed to bind socket : ", __FILE__, __LINE__); 384 AFALGerr(AFALG_F_AFALG_CREATE_SK, AFALG_R_SOCKET_BIND_FAILED); 385 goto err; 386 } 387 388 actx->sfd = accept(actx->bfd, NULL, 0); 389 if (actx->sfd < 0) { 390 ALG_PERR("%s(%d): Socket Accept Failed : ", __FILE__, __LINE__); 391 AFALGerr(AFALG_F_AFALG_CREATE_SK, AFALG_R_SOCKET_ACCEPT_FAILED); 392 goto err; 393 } 394 395 return 1; 396 397 err: 398 if (actx->bfd >= 0) 399 close(actx->bfd); 400 if (actx->sfd >= 0) 401 close(actx->sfd); 402 actx->bfd = actx->sfd = -1; 403 return 0; 404 } 405 406 static int afalg_start_cipher_sk(afalg_ctx *actx, const unsigned char *in, 407 size_t inl, const unsigned char *iv, 408 unsigned int enc) 409 { 410 struct msghdr msg; 411 struct cmsghdr *cmsg; 412 struct iovec iov; 413 ssize_t sbytes; 414 # ifdef ALG_ZERO_COPY 415 int ret; 416 # endif 417 char cbuf[CMSG_SPACE(ALG_IV_LEN(ALG_AES_IV_LEN)) + CMSG_SPACE(ALG_OP_LEN)]; 418 419 memset(&msg, 0, sizeof(msg)); 420 memset(cbuf, 0, sizeof(cbuf)); 421 msg.msg_control = cbuf; 422 msg.msg_controllen = sizeof(cbuf); 423 424 /* 425 * cipher direction (i.e. encrypt or decrypt) and iv are sent to the 426 * kernel as part of sendmsg()'s ancillary data 427 */ 428 cmsg = CMSG_FIRSTHDR(&msg); 429 afalg_set_op_sk(cmsg, enc); 430 cmsg = CMSG_NXTHDR(&msg, cmsg); 431 afalg_set_iv_sk(cmsg, iv, ALG_AES_IV_LEN); 432 433 /* iov that describes input data */ 434 iov.iov_base = (unsigned char *)in; 435 iov.iov_len = inl; 436 437 msg.msg_flags = MSG_MORE; 438 439 # ifdef ALG_ZERO_COPY 440 /* 441 * ZERO_COPY mode 442 * Works best when buffer is 4k aligned 443 * OPENS: out of place processing (i.e. out != in) 444 */ 445 446 /* Input data is not sent as part of call to sendmsg() */ 447 msg.msg_iovlen = 0; 448 msg.msg_iov = NULL; 449 450 /* Sendmsg() sends iv and cipher direction to the kernel */ 451 sbytes = sendmsg(actx->sfd, &msg, 0); 452 if (sbytes < 0) { 453 ALG_PERR("%s(%d): sendmsg failed for zero copy cipher operation : ", 454 __FILE__, __LINE__); 455 return 0; 456 } 457 458 /* 459 * vmsplice and splice are used to pin the user space input buffer for 460 * kernel space processing avoiding copies from user to kernel space 461 */ 462 ret = vmsplice(actx->zc_pipe[1], &iov, 1, SPLICE_F_GIFT); 463 if (ret < 0) { 464 ALG_PERR("%s(%d): vmsplice failed : ", __FILE__, __LINE__); 465 return 0; 466 } 467 468 ret = splice(actx->zc_pipe[0], NULL, actx->sfd, NULL, inl, 0); 469 if (ret < 0) { 470 ALG_PERR("%s(%d): splice failed : ", __FILE__, __LINE__); 471 return 0; 472 } 473 # else 474 msg.msg_iovlen = 1; 475 msg.msg_iov = &iov; 476 477 /* Sendmsg() sends iv, cipher direction and input data to the kernel */ 478 sbytes = sendmsg(actx->sfd, &msg, 0); 479 if (sbytes < 0) { 480 ALG_PERR("%s(%d): sendmsg failed for cipher operation : ", __FILE__, 481 __LINE__); 482 return 0; 483 } 484 485 if (sbytes != (ssize_t) inl) { 486 ALG_WARN("Cipher operation send bytes %zd != inlen %zd\n", sbytes, 487 inl); 488 return 0; 489 } 490 # endif 491 492 return 1; 493 } 494 495 static int afalg_cipher_init(EVP_CIPHER_CTX *ctx, const unsigned char *key, 496 const unsigned char *iv, int enc) 497 { 498 int ciphertype; 499 int ret; 500 afalg_ctx *actx; 501 const char *ciphername; 502 503 if (ctx == NULL || key == NULL) { 504 ALG_WARN("%s(%d): Null Parameter\n", __FILE__, __LINE__); 505 return 0; 506 } 507 508 if (EVP_CIPHER_CTX_cipher(ctx) == NULL) { 509 ALG_WARN("%s(%d): Cipher object NULL\n", __FILE__, __LINE__); 510 return 0; 511 } 512 513 actx = EVP_CIPHER_CTX_get_cipher_data(ctx); 514 if (actx == NULL) { 515 ALG_WARN("%s(%d): Cipher data NULL\n", __FILE__, __LINE__); 516 return 0; 517 } 518 519 ciphertype = EVP_CIPHER_CTX_nid(ctx); 520 switch (ciphertype) { 521 case NID_aes_128_cbc: 522 case NID_aes_192_cbc: 523 case NID_aes_256_cbc: 524 ciphername = "cbc(aes)"; 525 break; 526 default: 527 ALG_WARN("%s(%d): Unsupported Cipher type %d\n", __FILE__, __LINE__, 528 ciphertype); 529 return 0; 530 } 531 532 if (ALG_AES_IV_LEN != EVP_CIPHER_CTX_iv_length(ctx)) { 533 ALG_WARN("%s(%d): Unsupported IV length :%d\n", __FILE__, __LINE__, 534 EVP_CIPHER_CTX_iv_length(ctx)); 535 return 0; 536 } 537 538 /* Setup AFALG socket for crypto processing */ 539 ret = afalg_create_sk(actx, "skcipher", ciphername); 540 if (ret < 1) 541 return 0; 542 543 544 ret = afalg_set_key(actx, key, EVP_CIPHER_CTX_key_length(ctx)); 545 if (ret < 1) 546 goto err; 547 548 /* Setup AIO ctx to allow async AFALG crypto processing */ 549 if (afalg_init_aio(&actx->aio) == 0) 550 goto err; 551 552 # ifdef ALG_ZERO_COPY 553 pipe(actx->zc_pipe); 554 # endif 555 556 actx->init_done = MAGIC_INIT_NUM; 557 558 return 1; 559 560 err: 561 close(actx->sfd); 562 close(actx->bfd); 563 return 0; 564 } 565 566 static int afalg_do_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, 567 const unsigned char *in, size_t inl) 568 { 569 afalg_ctx *actx; 570 int ret; 571 char nxtiv[ALG_AES_IV_LEN] = { 0 }; 572 573 if (ctx == NULL || out == NULL || in == NULL) { 574 ALG_WARN("NULL parameter passed to function %s(%d)\n", __FILE__, 575 __LINE__); 576 return 0; 577 } 578 579 actx = (afalg_ctx *) EVP_CIPHER_CTX_get_cipher_data(ctx); 580 if (actx == NULL || actx->init_done != MAGIC_INIT_NUM) { 581 ALG_WARN("%s afalg ctx passed\n", 582 ctx == NULL ? "NULL" : "Uninitialised"); 583 return 0; 584 } 585 586 /* 587 * set iv now for decrypt operation as the input buffer can be 588 * overwritten for inplace operation where in = out. 589 */ 590 if (EVP_CIPHER_CTX_encrypting(ctx) == 0) { 591 memcpy(nxtiv, in + (inl - ALG_AES_IV_LEN), ALG_AES_IV_LEN); 592 } 593 594 /* Send input data to kernel space */ 595 ret = afalg_start_cipher_sk(actx, (unsigned char *)in, inl, 596 EVP_CIPHER_CTX_iv(ctx), 597 EVP_CIPHER_CTX_encrypting(ctx)); 598 if (ret < 1) { 599 return 0; 600 } 601 602 /* Perform async crypto operation in kernel space */ 603 ret = afalg_fin_cipher_aio(&actx->aio, actx->sfd, out, inl); 604 if (ret < 1) 605 return 0; 606 607 if (EVP_CIPHER_CTX_encrypting(ctx)) { 608 memcpy(EVP_CIPHER_CTX_iv_noconst(ctx), out + (inl - ALG_AES_IV_LEN), 609 ALG_AES_IV_LEN); 610 } else { 611 memcpy(EVP_CIPHER_CTX_iv_noconst(ctx), nxtiv, ALG_AES_IV_LEN); 612 } 613 614 return 1; 615 } 616 617 static int afalg_cipher_cleanup(EVP_CIPHER_CTX *ctx) 618 { 619 afalg_ctx *actx; 620 621 if (ctx == NULL) { 622 ALG_WARN("NULL parameter passed to function %s(%d)\n", __FILE__, 623 __LINE__); 624 return 0; 625 } 626 627 actx = (afalg_ctx *) EVP_CIPHER_CTX_get_cipher_data(ctx); 628 if (actx == NULL || actx->init_done != MAGIC_INIT_NUM) 629 return 1; 630 631 close(actx->sfd); 632 close(actx->bfd); 633 # ifdef ALG_ZERO_COPY 634 close(actx->zc_pipe[0]); 635 close(actx->zc_pipe[1]); 636 # endif 637 /* close efd in sync mode, async mode is closed in afalg_waitfd_cleanup() */ 638 if (actx->aio.mode == MODE_SYNC) 639 close(actx->aio.efd); 640 io_destroy(actx->aio.aio_ctx); 641 642 return 1; 643 } 644 645 static cbc_handles *get_cipher_handle(int nid) 646 { 647 switch (nid) { 648 case NID_aes_128_cbc: 649 return &cbc_handle[AES_CBC_128]; 650 case NID_aes_192_cbc: 651 return &cbc_handle[AES_CBC_192]; 652 case NID_aes_256_cbc: 653 return &cbc_handle[AES_CBC_256]; 654 default: 655 return NULL; 656 } 657 } 658 659 static const EVP_CIPHER *afalg_aes_cbc(int nid) 660 { 661 cbc_handles *cipher_handle = get_cipher_handle(nid); 662 if (cipher_handle->_hidden == NULL 663 && ((cipher_handle->_hidden = 664 EVP_CIPHER_meth_new(nid, 665 AES_BLOCK_SIZE, 666 cipher_handle->key_size)) == NULL 667 || !EVP_CIPHER_meth_set_iv_length(cipher_handle->_hidden, 668 AES_IV_LEN) 669 || !EVP_CIPHER_meth_set_flags(cipher_handle->_hidden, 670 EVP_CIPH_CBC_MODE | 671 EVP_CIPH_FLAG_DEFAULT_ASN1) 672 || !EVP_CIPHER_meth_set_init(cipher_handle->_hidden, 673 afalg_cipher_init) 674 || !EVP_CIPHER_meth_set_do_cipher(cipher_handle->_hidden, 675 afalg_do_cipher) 676 || !EVP_CIPHER_meth_set_cleanup(cipher_handle->_hidden, 677 afalg_cipher_cleanup) 678 || !EVP_CIPHER_meth_set_impl_ctx_size(cipher_handle->_hidden, 679 sizeof(afalg_ctx)))) { 680 EVP_CIPHER_meth_free(cipher_handle->_hidden); 681 cipher_handle->_hidden= NULL; 682 } 683 return cipher_handle->_hidden; 684 } 685 686 static int afalg_ciphers(ENGINE *e, const EVP_CIPHER **cipher, 687 const int **nids, int nid) 688 { 689 int r = 1; 690 691 if (cipher == NULL) { 692 *nids = afalg_cipher_nids; 693 return (sizeof(afalg_cipher_nids) / sizeof(afalg_cipher_nids[0])); 694 } 695 696 switch (nid) { 697 case NID_aes_128_cbc: 698 case NID_aes_192_cbc: 699 case NID_aes_256_cbc: 700 *cipher = afalg_aes_cbc(nid); 701 break; 702 default: 703 *cipher = NULL; 704 r = 0; 705 } 706 return r; 707 } 708 709 static int bind_afalg(ENGINE *e) 710 { 711 /* Ensure the afalg error handling is set up */ 712 unsigned short i; 713 ERR_load_AFALG_strings(); 714 715 if (!ENGINE_set_id(e, engine_afalg_id) 716 || !ENGINE_set_name(e, engine_afalg_name) 717 || !ENGINE_set_destroy_function(e, afalg_destroy) 718 || !ENGINE_set_init_function(e, afalg_init) 719 || !ENGINE_set_finish_function(e, afalg_finish)) { 720 AFALGerr(AFALG_F_BIND_AFALG, AFALG_R_INIT_FAILED); 721 return 0; 722 } 723 724 /* 725 * Create _hidden_aes_xxx_cbc by calling afalg_aes_xxx_cbc 726 * now, as bind_aflag can only be called by one thread at a 727 * time. 728 */ 729 for(i = 0; i < OSSL_NELEM(afalg_cipher_nids); i++) { 730 if (afalg_aes_cbc(afalg_cipher_nids[i]) == NULL) { 731 AFALGerr(AFALG_F_BIND_AFALG, AFALG_R_INIT_FAILED); 732 return 0; 733 } 734 } 735 736 if (!ENGINE_set_ciphers(e, afalg_ciphers)) { 737 AFALGerr(AFALG_F_BIND_AFALG, AFALG_R_INIT_FAILED); 738 return 0; 739 } 740 741 return 1; 742 } 743 744 # ifndef OPENSSL_NO_DYNAMIC_ENGINE 745 static int bind_helper(ENGINE *e, const char *id) 746 { 747 if (id && (strcmp(id, engine_afalg_id) != 0)) 748 return 0; 749 750 if (!afalg_chk_platform()) 751 return 0; 752 753 if (!bind_afalg(e)) 754 return 0; 755 return 1; 756 } 757 758 IMPLEMENT_DYNAMIC_CHECK_FN() 759 IMPLEMENT_DYNAMIC_BIND_FN(bind_helper) 760 # endif 761 762 static int afalg_chk_platform(void) 763 { 764 int ret; 765 int i; 766 int kver[3] = { -1, -1, -1 }; 767 int sock; 768 char *str; 769 struct utsname ut; 770 771 ret = uname(&ut); 772 if (ret != 0) { 773 AFALGerr(AFALG_F_AFALG_CHK_PLATFORM, 774 AFALG_R_FAILED_TO_GET_PLATFORM_INFO); 775 return 0; 776 } 777 778 str = strtok(ut.release, "."); 779 for (i = 0; i < 3 && str != NULL; i++) { 780 kver[i] = atoi(str); 781 str = strtok(NULL, "."); 782 } 783 784 if (KERNEL_VERSION(kver[0], kver[1], kver[2]) 785 < KERNEL_VERSION(K_MAJ, K_MIN1, K_MIN2)) { 786 ALG_ERR("ASYNC AFALG not supported this kernel(%d.%d.%d)\n", 787 kver[0], kver[1], kver[2]); 788 ALG_ERR("ASYNC AFALG requires kernel version %d.%d.%d or later\n", 789 K_MAJ, K_MIN1, K_MIN2); 790 AFALGerr(AFALG_F_AFALG_CHK_PLATFORM, 791 AFALG_R_KERNEL_DOES_NOT_SUPPORT_ASYNC_AFALG); 792 return 0; 793 } 794 795 /* Test if we can actually create an AF_ALG socket */ 796 sock = socket(AF_ALG, SOCK_SEQPACKET, 0); 797 if (sock == -1) { 798 AFALGerr(AFALG_F_AFALG_CHK_PLATFORM, AFALG_R_SOCKET_CREATE_FAILED); 799 return 0; 800 } 801 close(sock); 802 803 return 1; 804 } 805 806 # ifdef OPENSSL_NO_DYNAMIC_ENGINE 807 static ENGINE *engine_afalg(void) 808 { 809 ENGINE *ret = ENGINE_new(); 810 if (ret == NULL) 811 return NULL; 812 if (!bind_afalg(ret)) { 813 ENGINE_free(ret); 814 return NULL; 815 } 816 return ret; 817 } 818 819 void engine_load_afalg_int(void) 820 { 821 ENGINE *toadd; 822 823 if (!afalg_chk_platform()) 824 return; 825 826 toadd = engine_afalg(); 827 if (toadd == NULL) 828 return; 829 ENGINE_add(toadd); 830 ENGINE_free(toadd); 831 ERR_clear_error(); 832 } 833 # endif 834 835 static int afalg_init(ENGINE *e) 836 { 837 return 1; 838 } 839 840 static int afalg_finish(ENGINE *e) 841 { 842 return 1; 843 } 844 845 static int free_cbc(void) 846 { 847 short unsigned int i; 848 for(i = 0; i < OSSL_NELEM(afalg_cipher_nids); i++) { 849 EVP_CIPHER_meth_free(cbc_handle[i]._hidden); 850 cbc_handle[i]._hidden = NULL; 851 } 852 return 1; 853 } 854 855 static int afalg_destroy(ENGINE *e) 856 { 857 ERR_unload_AFALG_strings(); 858 free_cbc(); 859 return 1; 860 } 861 862 #endif /* KERNEL VERSION */ 863