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