1e1051a39Sopenharmony_ci/* 2e1051a39Sopenharmony_ci * Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved. 3e1051a39Sopenharmony_ci * 4e1051a39Sopenharmony_ci * Licensed under the Apache License 2.0 (the "License"). You may not use 5e1051a39Sopenharmony_ci * this file except in compliance with the License. You can obtain a copy 6e1051a39Sopenharmony_ci * in the file LICENSE in the source distribution or at 7e1051a39Sopenharmony_ci * https://www.openssl.org/source/license.html 8e1051a39Sopenharmony_ci */ 9e1051a39Sopenharmony_ci 10e1051a39Sopenharmony_ci/* 11e1051a39Sopenharmony_ci * This file uses the low level AES functions (which are deprecated for 12e1051a39Sopenharmony_ci * non-internal use) in order to implement provider AES ciphers. 13e1051a39Sopenharmony_ci */ 14e1051a39Sopenharmony_ci#include "internal/deprecated.h" 15e1051a39Sopenharmony_ci 16e1051a39Sopenharmony_ci#include "cipher_aes_siv.h" 17e1051a39Sopenharmony_ci 18e1051a39Sopenharmony_cistatic void aes_siv_cleanup(void *vctx); 19e1051a39Sopenharmony_ci 20e1051a39Sopenharmony_cistatic int aes_siv_initkey(void *vctx, const unsigned char *key, size_t keylen) 21e1051a39Sopenharmony_ci{ 22e1051a39Sopenharmony_ci PROV_AES_SIV_CTX *ctx = (PROV_AES_SIV_CTX *)vctx; 23e1051a39Sopenharmony_ci SIV128_CONTEXT *sctx = &ctx->siv; 24e1051a39Sopenharmony_ci size_t klen = keylen / 2; 25e1051a39Sopenharmony_ci OSSL_LIB_CTX *libctx = ctx->libctx; 26e1051a39Sopenharmony_ci const char *propq = NULL; 27e1051a39Sopenharmony_ci 28e1051a39Sopenharmony_ci EVP_CIPHER_free(ctx->cbc); 29e1051a39Sopenharmony_ci EVP_CIPHER_free(ctx->ctr); 30e1051a39Sopenharmony_ci ctx->cbc = NULL; 31e1051a39Sopenharmony_ci ctx->ctr = NULL; 32e1051a39Sopenharmony_ci 33e1051a39Sopenharmony_ci switch (klen) { 34e1051a39Sopenharmony_ci case 16: 35e1051a39Sopenharmony_ci ctx->cbc = EVP_CIPHER_fetch(libctx, "AES-128-CBC", propq); 36e1051a39Sopenharmony_ci ctx->ctr = EVP_CIPHER_fetch(libctx, "AES-128-CTR", propq); 37e1051a39Sopenharmony_ci break; 38e1051a39Sopenharmony_ci case 24: 39e1051a39Sopenharmony_ci ctx->cbc = EVP_CIPHER_fetch(libctx, "AES-192-CBC", propq); 40e1051a39Sopenharmony_ci ctx->ctr = EVP_CIPHER_fetch(libctx, "AES-192-CTR", propq); 41e1051a39Sopenharmony_ci break; 42e1051a39Sopenharmony_ci case 32: 43e1051a39Sopenharmony_ci ctx->cbc = EVP_CIPHER_fetch(libctx, "AES-256-CBC", propq); 44e1051a39Sopenharmony_ci ctx->ctr = EVP_CIPHER_fetch(libctx, "AES-256-CTR", propq); 45e1051a39Sopenharmony_ci break; 46e1051a39Sopenharmony_ci default: 47e1051a39Sopenharmony_ci break; 48e1051a39Sopenharmony_ci } 49e1051a39Sopenharmony_ci if (ctx->cbc == NULL || ctx->ctr == NULL) 50e1051a39Sopenharmony_ci return 0; 51e1051a39Sopenharmony_ci /* 52e1051a39Sopenharmony_ci * klen is the length of the underlying cipher, not the input key, 53e1051a39Sopenharmony_ci * which should be twice as long 54e1051a39Sopenharmony_ci */ 55e1051a39Sopenharmony_ci return ossl_siv128_init(sctx, key, klen, ctx->cbc, ctx->ctr, libctx, 56e1051a39Sopenharmony_ci propq); 57e1051a39Sopenharmony_ci} 58e1051a39Sopenharmony_ci 59e1051a39Sopenharmony_cistatic int aes_siv_dupctx(void *in_vctx, void *out_vctx) 60e1051a39Sopenharmony_ci{ 61e1051a39Sopenharmony_ci PROV_AES_SIV_CTX *in = (PROV_AES_SIV_CTX *)in_vctx; 62e1051a39Sopenharmony_ci PROV_AES_SIV_CTX *out = (PROV_AES_SIV_CTX *)out_vctx; 63e1051a39Sopenharmony_ci 64e1051a39Sopenharmony_ci *out = *in; 65e1051a39Sopenharmony_ci out->siv.cipher_ctx = NULL; 66e1051a39Sopenharmony_ci out->siv.mac_ctx_init = NULL; 67e1051a39Sopenharmony_ci out->siv.mac = NULL; 68e1051a39Sopenharmony_ci if (!ossl_siv128_copy_ctx(&out->siv, &in->siv)) 69e1051a39Sopenharmony_ci return 0; 70e1051a39Sopenharmony_ci if (out->cbc != NULL) 71e1051a39Sopenharmony_ci EVP_CIPHER_up_ref(out->cbc); 72e1051a39Sopenharmony_ci if (out->ctr != NULL) 73e1051a39Sopenharmony_ci EVP_CIPHER_up_ref(out->ctr); 74e1051a39Sopenharmony_ci return 1; 75e1051a39Sopenharmony_ci} 76e1051a39Sopenharmony_ci 77e1051a39Sopenharmony_cistatic int aes_siv_settag(void *vctx, const unsigned char *tag, size_t tagl) 78e1051a39Sopenharmony_ci{ 79e1051a39Sopenharmony_ci PROV_AES_SIV_CTX *ctx = (PROV_AES_SIV_CTX *)vctx; 80e1051a39Sopenharmony_ci SIV128_CONTEXT *sctx = &ctx->siv; 81e1051a39Sopenharmony_ci 82e1051a39Sopenharmony_ci return ossl_siv128_set_tag(sctx, tag, tagl); 83e1051a39Sopenharmony_ci} 84e1051a39Sopenharmony_ci 85e1051a39Sopenharmony_cistatic void aes_siv_setspeed(void *vctx, int speed) 86e1051a39Sopenharmony_ci{ 87e1051a39Sopenharmony_ci PROV_AES_SIV_CTX *ctx = (PROV_AES_SIV_CTX *)vctx; 88e1051a39Sopenharmony_ci SIV128_CONTEXT *sctx = &ctx->siv; 89e1051a39Sopenharmony_ci 90e1051a39Sopenharmony_ci ossl_siv128_speed(sctx, (int)speed); 91e1051a39Sopenharmony_ci} 92e1051a39Sopenharmony_ci 93e1051a39Sopenharmony_cistatic void aes_siv_cleanup(void *vctx) 94e1051a39Sopenharmony_ci{ 95e1051a39Sopenharmony_ci PROV_AES_SIV_CTX *ctx = (PROV_AES_SIV_CTX *)vctx; 96e1051a39Sopenharmony_ci SIV128_CONTEXT *sctx = &ctx->siv; 97e1051a39Sopenharmony_ci 98e1051a39Sopenharmony_ci ossl_siv128_cleanup(sctx); 99e1051a39Sopenharmony_ci EVP_CIPHER_free(ctx->cbc); 100e1051a39Sopenharmony_ci EVP_CIPHER_free(ctx->ctr); 101e1051a39Sopenharmony_ci} 102e1051a39Sopenharmony_ci 103e1051a39Sopenharmony_cistatic int aes_siv_cipher(void *vctx, unsigned char *out, 104e1051a39Sopenharmony_ci const unsigned char *in, size_t len) 105e1051a39Sopenharmony_ci{ 106e1051a39Sopenharmony_ci PROV_AES_SIV_CTX *ctx = (PROV_AES_SIV_CTX *)vctx; 107e1051a39Sopenharmony_ci SIV128_CONTEXT *sctx = &ctx->siv; 108e1051a39Sopenharmony_ci 109e1051a39Sopenharmony_ci /* EncryptFinal or DecryptFinal */ 110e1051a39Sopenharmony_ci if (in == NULL) 111e1051a39Sopenharmony_ci return ossl_siv128_finish(sctx) == 0; 112e1051a39Sopenharmony_ci 113e1051a39Sopenharmony_ci /* Deal with associated data */ 114e1051a39Sopenharmony_ci if (out == NULL) 115e1051a39Sopenharmony_ci return (ossl_siv128_aad(sctx, in, len) == 1); 116e1051a39Sopenharmony_ci 117e1051a39Sopenharmony_ci if (ctx->enc) 118e1051a39Sopenharmony_ci return ossl_siv128_encrypt(sctx, in, out, len) > 0; 119e1051a39Sopenharmony_ci 120e1051a39Sopenharmony_ci return ossl_siv128_decrypt(sctx, in, out, len) > 0; 121e1051a39Sopenharmony_ci} 122e1051a39Sopenharmony_ci 123e1051a39Sopenharmony_cistatic const PROV_CIPHER_HW_AES_SIV aes_siv_hw = 124e1051a39Sopenharmony_ci{ 125e1051a39Sopenharmony_ci aes_siv_initkey, 126e1051a39Sopenharmony_ci aes_siv_cipher, 127e1051a39Sopenharmony_ci aes_siv_setspeed, 128e1051a39Sopenharmony_ci aes_siv_settag, 129e1051a39Sopenharmony_ci aes_siv_cleanup, 130e1051a39Sopenharmony_ci aes_siv_dupctx, 131e1051a39Sopenharmony_ci}; 132e1051a39Sopenharmony_ci 133e1051a39Sopenharmony_ciconst PROV_CIPHER_HW_AES_SIV *ossl_prov_cipher_hw_aes_siv(size_t keybits) 134e1051a39Sopenharmony_ci{ 135e1051a39Sopenharmony_ci return &aes_siv_hw; 136e1051a39Sopenharmony_ci} 137