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