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