static int bind_afalg(ENGINE *e) { /* Ensure the afalg error handling is set up */ unsigned short i; ERR_load_AFALG_strings(); if (!ENGINE_set_id(e, engine_afalg_id) || !ENGINE_set_name(e, engine_afalg_name) || !ENGINE_set_destroy_function(e, afalg_destroy) || !ENGINE_set_init_function(e, afalg_init) || !ENGINE_set_finish_function(e, afalg_finish)) { AFALGerr(AFALG_F_BIND_AFALG, AFALG_R_INIT_FAILED); return 0; } /* * Create _hidden_aes_xxx_cbc by calling afalg_aes_xxx_cbc * now, as bind_aflag can only be called by one thread at a * time. */ for(i = 0; i < OSSL_NELEM(afalg_cipher_nids); i++) { if (afalg_aes_cbc(afalg_cipher_nids[i]) == NULL) { AFALGerr(AFALG_F_BIND_AFALG, AFALG_R_INIT_FAILED); return 0; } } if (!ENGINE_set_ciphers(e, afalg_ciphers)) { AFALGerr(AFALG_F_BIND_AFALG, AFALG_R_INIT_FAILED); return 0; } return 1; }
static int bind_afalg(ENGINE *e) { /* Ensure the afalg error handling is set up */ ERR_load_AFALG_strings(); if (!ENGINE_set_id(e, engine_afalg_id) || !ENGINE_set_name(e, engine_afalg_name) || !ENGINE_set_destroy_function(e, afalg_destroy) || !ENGINE_set_init_function(e, afalg_init) || !ENGINE_set_finish_function(e, afalg_finish)) { AFALGerr(AFALG_F_BIND_AFALG, AFALG_R_INIT_FAILED); return 0; } /* * Create _hidden_aes_128_cbc by calling afalg_aes_128_cbc * now, as bind_aflag can only be called by one thread at a * time. */ if (afalg_aes_128_cbc() == NULL) { AFALGerr(AFALG_F_BIND_AFALG, AFALG_R_INIT_FAILED); return 0; } if (!ENGINE_set_ciphers(e, afalg_ciphers)) { AFALGerr(AFALG_F_BIND_AFALG, AFALG_R_INIT_FAILED); return 0; } return 1; }
static int afalg_chk_platform(void) { int ret; int i; int kver[3] = { -1, -1, -1 }; char *str; struct utsname ut; ret = uname(&ut); if (ret != 0) { AFALGerr(AFALG_F_AFALG_CHK_PLATFORM, AFALG_R_FAILED_TO_GET_PLATFORM_INFO); return 0; } str = strtok(ut.release, "."); for (i = 0; i < 3 && str != NULL; i++) { kver[i] = atoi(str); str = strtok(NULL, "."); } if (KERNEL_VERSION(kver[0], kver[1], kver[2]) < KERNEL_VERSION(K_MAJ, K_MIN1, K_MIN2)) { ALG_ERR("ASYNC AFALG not supported this kernel(%d.%d.%d)\n", kver[0], kver[1], kver[2]); ALG_ERR("ASYNC AFALG requires kernel version %d.%d.%d or later\n", K_MAJ, K_MIN1, K_MIN2); AFALGerr(AFALG_F_AFALG_CHK_PLATFORM, AFALG_R_KERNEL_DOES_NOT_SUPPORT_ASYNC_AFALG); return 0; } return 1; }
static int afalg_setup_async_event_notification(afalg_aio *aio) { ASYNC_JOB *job; ASYNC_WAIT_CTX *waitctx; void *custom = NULL; int ret; if ((job = ASYNC_get_current_job()) != NULL) { /* Async mode */ waitctx = ASYNC_get_wait_ctx(job); if (waitctx == NULL) { ALG_WARN("%s(%d): ASYNC_get_wait_ctx error", __FILE__, __LINE__); return 0; } /* Get waitfd from ASYNC_WAIT_CTX if it is already set */ ret = ASYNC_WAIT_CTX_get_fd(waitctx, engine_afalg_id, &aio->efd, &custom); if (ret == 0) { /* * waitfd is not set in ASYNC_WAIT_CTX, create a new one * and set it. efd will be signaled when AIO operation completes */ aio->efd = eventfd(0); if (aio->efd == -1) { ALG_PERR("%s(%d): Failed to get eventfd : ", __FILE__, __LINE__); AFALGerr(AFALG_F_AFALG_SETUP_ASYNC_EVENT_NOTIFICATION, AFALG_R_EVENTFD_FAILED); return 0; } ret = ASYNC_WAIT_CTX_set_wait_fd(waitctx, engine_afalg_id, aio->efd, custom, afalg_waitfd_cleanup); if (ret == 0) { ALG_WARN("%s(%d): Failed to set wait fd", __FILE__, __LINE__); close(aio->efd); return 0; } /* make fd non-blocking in async mode */ if (fcntl(aio->efd, F_SETFL, O_NONBLOCK) != 0) { ALG_WARN("%s(%d): Failed to set event fd as NONBLOCKING", __FILE__, __LINE__); } } aio->mode = MODE_ASYNC; } else { /* Sync mode */ aio->efd = eventfd(0); if (aio->efd == -1) { ALG_PERR("%s(%d): Failed to get eventfd : ", __FILE__, __LINE__); AFALGerr(AFALG_F_AFALG_SETUP_ASYNC_EVENT_NOTIFICATION, AFALG_R_EVENTFD_FAILED); return 0; } aio->mode = MODE_SYNC; } return 1; }
static int afalg_create_sk(afalg_ctx *actx, const char *ciphertype, const char *ciphername) { struct sockaddr_alg sa; int r = -1; actx->bfd = actx->sfd = -1; memset(&sa, 0, sizeof(sa)); sa.salg_family = AF_ALG; strncpy((char *) sa.salg_type, ciphertype, ALG_MAX_SALG_TYPE); sa.salg_type[ALG_MAX_SALG_TYPE-1] = '\0'; strncpy((char *) sa.salg_name, ciphername, ALG_MAX_SALG_NAME); sa.salg_name[ALG_MAX_SALG_NAME-1] = '\0'; actx->bfd = socket(AF_ALG, SOCK_SEQPACKET, 0); if (actx->bfd == -1) { ALG_PERR("%s: Failed to open socket : ", __func__); AFALGerr(AFALG_F_AFALG_CREATE_SK, AFALG_R_SOCKET_CREATE_FAILED); goto err; } r = bind(actx->bfd, (struct sockaddr *)&sa, sizeof(sa)); if (r < 0) { ALG_PERR("%s: Failed to bind socket : ", __func__); AFALGerr(AFALG_F_AFALG_CREATE_SK, AFALG_R_SOCKET_BIND_FAILED); goto err; } actx->sfd = accept(actx->bfd, NULL, 0); if (actx->sfd < 0) { ALG_PERR("%s: Socket Accept Failed : ", __func__); AFALGerr(AFALG_F_AFALG_CREATE_SK, AFALG_R_SOCKET_ACCEPT_FAILED); goto err; } return 1; err: if (actx->bfd >= 0) close(actx->bfd); if (actx->sfd >= 0) close(actx->sfd); actx->bfd = actx->sfd = -1; return 0; }
static int afalg_chk_platform(void) { int ret; int i; int kver[3] = { -1, -1, -1 }; int sock; char *str; struct utsname ut; ret = uname(&ut); if (ret != 0) { AFALGerr(AFALG_F_AFALG_CHK_PLATFORM, AFALG_R_FAILED_TO_GET_PLATFORM_INFO); return 0; } str = strtok(ut.release, "."); for (i = 0; i < 3 && str != NULL; i++) { kver[i] = atoi(str); str = strtok(NULL, "."); } if (KERNEL_VERSION(kver[0], kver[1], kver[2]) < KERNEL_VERSION(K_MAJ, K_MIN1, K_MIN2)) { ALG_ERR("ASYNC AFALG not supported this kernel(%d.%d.%d)\n", kver[0], kver[1], kver[2]); ALG_ERR("ASYNC AFALG requires kernel version %d.%d.%d or later\n", K_MAJ, K_MIN1, K_MIN2); AFALGerr(AFALG_F_AFALG_CHK_PLATFORM, AFALG_R_KERNEL_DOES_NOT_SUPPORT_ASYNC_AFALG); return 0; } /* Test if we can actually create an AF_ALG socket */ sock = socket(AF_ALG, SOCK_SEQPACKET, 0); if (sock == -1) { AFALGerr(AFALG_F_AFALG_CHK_PLATFORM, AFALG_R_SOCKET_CREATE_FAILED); return 0; } close(sock); return 1; }
static ossl_inline int afalg_set_key(afalg_ctx *actx, const unsigned char *key, const int klen) { int ret; ret = setsockopt(actx->bfd, SOL_ALG, ALG_SET_KEY, key, klen); if (ret < 0) { ALG_PERR("%s(%d): Failed to set socket option : ", __FILE__, __LINE__); AFALGerr(AFALG_F_AFALG_SET_KEY, AFALG_R_SOCKET_SET_KEY_FAILED); return 0; } return 1; }
static int afalg_init_aio(afalg_aio *aio) { int r = -1; /* Initialise for AIO */ aio->aio_ctx = 0; r = io_setup(MAX_INFLIGHTS, &aio->aio_ctx); if (r < 0) { ALG_PERR("%s: io_setup error : ", __func__); AFALGerr(AFALG_F_AFALG_INIT_AIO, AFALG_R_IO_SETUP_FAILED); return 0; } memset(aio->cbt, 0, sizeof(aio->cbt)); aio->efd = -1; aio->mode = MODE_UNINIT; return 1; }