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