Path: blob/main/crypto/openssl/providers/implementations/ciphers/cipher_aes_xts_hw.c
48383 views
/*1* Copyright 2019-2025 The OpenSSL Project Authors. All Rights Reserved.2*3* Licensed under the Apache License 2.0 (the "License"). You may not use4* this file except in compliance with the License. You can obtain a copy5* in the file LICENSE in the source distribution or at6* https://www.openssl.org/source/license.html7*/89/*10* This file uses the low level AES functions (which are deprecated for11* non-internal use) in order to implement provider AES ciphers.12*/13#include "internal/deprecated.h"1415#include "cipher_aes_xts.h"1617#define XTS_SET_KEY_FN(fn_set_enc_key, fn_set_dec_key, \18fn_block_enc, fn_block_dec, \19fn_stream_enc, fn_stream_dec) { \20size_t bytes = keylen / 2; \21size_t bits = bytes * 8; \22\23if (ctx->enc) { \24fn_set_enc_key(key, bits, &xctx->ks1.ks); \25xctx->xts.block1 = (block128_f)fn_block_enc; \26} else { \27fn_set_dec_key(key, bits, &xctx->ks1.ks); \28xctx->xts.block1 = (block128_f)fn_block_dec; \29} \30fn_set_enc_key(key + bytes, bits, &xctx->ks2.ks); \31xctx->xts.block2 = (block128_f)fn_block_enc; \32xctx->xts.key1 = &xctx->ks1; \33xctx->xts.key2 = &xctx->ks2; \34xctx->stream = ctx->enc ? fn_stream_enc : fn_stream_dec; \35}3637static int cipher_hw_aes_xts_generic_initkey(PROV_CIPHER_CTX *ctx,38const unsigned char *key,39size_t keylen)40{41PROV_AES_XTS_CTX *xctx = (PROV_AES_XTS_CTX *)ctx;42OSSL_xts_stream_fn stream_enc = NULL;43OSSL_xts_stream_fn stream_dec = NULL;4445#ifdef AES_XTS_ASM46stream_enc = AES_xts_encrypt;47stream_dec = AES_xts_decrypt;48#endif /* AES_XTS_ASM */4950#ifdef HWAES_CAPABLE51if (HWAES_CAPABLE) {52# ifdef HWAES_xts_encrypt53stream_enc = HWAES_xts_encrypt;54# endif /* HWAES_xts_encrypt */55# ifdef HWAES_xts_decrypt56stream_dec = HWAES_xts_decrypt;57# endif /* HWAES_xts_decrypt */58XTS_SET_KEY_FN(HWAES_set_encrypt_key, HWAES_set_decrypt_key,59HWAES_encrypt, HWAES_decrypt,60stream_enc, stream_dec);61return 1;62} else63#endif /* HWAES_CAPABLE */6465#ifdef BSAES_CAPABLE66if (BSAES_CAPABLE) {67stream_enc = ossl_bsaes_xts_encrypt;68stream_dec = ossl_bsaes_xts_decrypt;69} else70#endif /* BSAES_CAPABLE */71#ifdef VPAES_CAPABLE72if (VPAES_CAPABLE) {73XTS_SET_KEY_FN(vpaes_set_encrypt_key, vpaes_set_decrypt_key,74vpaes_encrypt, vpaes_decrypt, stream_enc, stream_dec);75return 1;76} else77#endif /* VPAES_CAPABLE */78{79(void)0;80}81{82XTS_SET_KEY_FN(AES_set_encrypt_key, AES_set_decrypt_key,83AES_encrypt, AES_decrypt, stream_enc, stream_dec);84}85return 1;86}8788static void cipher_hw_aes_xts_copyctx(PROV_CIPHER_CTX *dst,89const PROV_CIPHER_CTX *src)90{91PROV_AES_XTS_CTX *sctx = (PROV_AES_XTS_CTX *)src;92PROV_AES_XTS_CTX *dctx = (PROV_AES_XTS_CTX *)dst;9394*dctx = *sctx;95dctx->xts.key1 = &dctx->ks1.ks;96dctx->xts.key2 = &dctx->ks2.ks;97}9899#if defined(AESNI_CAPABLE)100101static int cipher_hw_aesni_xts_initkey(PROV_CIPHER_CTX *ctx,102const unsigned char *key, size_t keylen)103{104PROV_AES_XTS_CTX *xctx = (PROV_AES_XTS_CTX *)ctx;105106void (*aesni_xts_enc)(const unsigned char *in,107unsigned char *out,108size_t length,109const AES_KEY *key1, const AES_KEY *key2,110const unsigned char iv[16]);111void (*aesni_xts_dec)(const unsigned char *in,112unsigned char *out,113size_t length,114const AES_KEY *key1, const AES_KEY *key2,115const unsigned char iv[16]);116117aesni_xts_enc = aesni_xts_encrypt;118aesni_xts_dec = aesni_xts_decrypt;119120# if (defined(__x86_64) || defined(__x86_64__) || \121defined(_M_AMD64) || defined(_M_X64))122if (aesni_xts_avx512_eligible()) {123if (keylen == 64) {124aesni_xts_enc = aesni_xts_256_encrypt_avx512;125aesni_xts_dec = aesni_xts_256_decrypt_avx512;126} else if (keylen == 32) {127aesni_xts_enc = aesni_xts_128_encrypt_avx512;128aesni_xts_dec = aesni_xts_128_decrypt_avx512;129}130}131# endif132133XTS_SET_KEY_FN(aesni_set_encrypt_key, aesni_set_decrypt_key,134aesni_encrypt, aesni_decrypt,135aesni_xts_enc, aesni_xts_dec);136return 1;137}138139# define PROV_CIPHER_HW_declare_xts() \140static const PROV_CIPHER_HW aesni_xts = { \141cipher_hw_aesni_xts_initkey, \142NULL, \143cipher_hw_aes_xts_copyctx \144};145# define PROV_CIPHER_HW_select_xts() \146if (AESNI_CAPABLE) \147return &aesni_xts;148149# elif defined(SPARC_AES_CAPABLE)150151static int cipher_hw_aes_xts_t4_initkey(PROV_CIPHER_CTX *ctx,152const unsigned char *key, size_t keylen)153{154PROV_AES_XTS_CTX *xctx = (PROV_AES_XTS_CTX *)ctx;155OSSL_xts_stream_fn stream_enc = NULL;156OSSL_xts_stream_fn stream_dec = NULL;157158/* Note: keylen is the size of 2 keys */159switch (keylen) {160case 32:161stream_enc = aes128_t4_xts_encrypt;162stream_dec = aes128_t4_xts_decrypt;163break;164case 64:165stream_enc = aes256_t4_xts_encrypt;166stream_dec = aes256_t4_xts_decrypt;167break;168default:169return 0;170}171172XTS_SET_KEY_FN(aes_t4_set_encrypt_key, aes_t4_set_decrypt_key,173aes_t4_encrypt, aes_t4_decrypt,174stream_enc, stream_dec);175return 1;176}177178# define PROV_CIPHER_HW_declare_xts() \179static const PROV_CIPHER_HW aes_xts_t4 = { \180cipher_hw_aes_xts_t4_initkey, \181NULL, \182cipher_hw_aes_xts_copyctx \183};184# define PROV_CIPHER_HW_select_xts() \185if (SPARC_AES_CAPABLE) \186return &aes_xts_t4;187188#elif defined(OPENSSL_CPUID_OBJ) && defined(__riscv) && __riscv_xlen == 64189190static int cipher_hw_aes_xts_rv64i_zknd_zkne_initkey(PROV_CIPHER_CTX *ctx,191const unsigned char *key,192size_t keylen)193{194PROV_AES_XTS_CTX *xctx = (PROV_AES_XTS_CTX *)ctx;195OSSL_xts_stream_fn stream_enc = NULL;196OSSL_xts_stream_fn stream_dec = NULL;197198XTS_SET_KEY_FN(rv64i_zkne_set_encrypt_key, rv64i_zknd_set_decrypt_key,199rv64i_zkne_encrypt, rv64i_zknd_decrypt,200stream_enc, stream_dec);201return 1;202}203204static int cipher_hw_aes_xts_rv64i_zvbb_zvkg_zvkned_initkey(205PROV_CIPHER_CTX *ctx, const unsigned char *key, size_t keylen)206{207PROV_AES_XTS_CTX *xctx = (PROV_AES_XTS_CTX *)ctx;208OSSL_xts_stream_fn stream_enc = NULL;209OSSL_xts_stream_fn stream_dec = NULL;210211/* Zvkned only supports 128 and 256 bit keys. */212if (keylen * 8 == 128 * 2 || keylen * 8 == 256 * 2) {213XTS_SET_KEY_FN(rv64i_zvkned_set_encrypt_key,214rv64i_zvkned_set_decrypt_key, rv64i_zvkned_encrypt,215rv64i_zvkned_decrypt,216rv64i_zvbb_zvkg_zvkned_aes_xts_encrypt,217rv64i_zvbb_zvkg_zvkned_aes_xts_decrypt);218} else {219XTS_SET_KEY_FN(AES_set_encrypt_key, AES_set_encrypt_key,220rv64i_zvkned_encrypt, rv64i_zvkned_decrypt,221stream_enc, stream_dec);222}223return 1;224}225226static int cipher_hw_aes_xts_rv64i_zvkned_initkey(PROV_CIPHER_CTX *ctx,227const unsigned char *key,228size_t keylen)229{230PROV_AES_XTS_CTX *xctx = (PROV_AES_XTS_CTX *)ctx;231OSSL_xts_stream_fn stream_enc = NULL;232OSSL_xts_stream_fn stream_dec = NULL;233234/* Zvkned only supports 128 and 256 bit keys. */235if (keylen * 8 == 128 * 2 || keylen * 8 == 256 * 2) {236XTS_SET_KEY_FN(rv64i_zvkned_set_encrypt_key,237rv64i_zvkned_set_decrypt_key,238rv64i_zvkned_encrypt, rv64i_zvkned_decrypt,239stream_enc, stream_dec);240} else {241XTS_SET_KEY_FN(AES_set_encrypt_key, AES_set_encrypt_key,242rv64i_zvkned_encrypt, rv64i_zvkned_decrypt,243stream_enc, stream_dec);244}245return 1;246}247248# define PROV_CIPHER_HW_declare_xts() \249static const PROV_CIPHER_HW aes_xts_rv64i_zknd_zkne = { \250cipher_hw_aes_xts_rv64i_zknd_zkne_initkey, \251NULL, \252cipher_hw_aes_xts_copyctx \253}; \254static const PROV_CIPHER_HW aes_xts_rv64i_zvkned = { \255cipher_hw_aes_xts_rv64i_zvkned_initkey, \256NULL, \257cipher_hw_aes_xts_copyctx \258}; \259static const PROV_CIPHER_HW aes_xts_rv64i_zvbb_zvkg_zvkned = { \260cipher_hw_aes_xts_rv64i_zvbb_zvkg_zvkned_initkey, \261NULL, \262cipher_hw_aes_xts_copyctx \263};264265# define PROV_CIPHER_HW_select_xts() \266if (RISCV_HAS_ZVBB() && RISCV_HAS_ZVKG() && RISCV_HAS_ZVKNED() && \267riscv_vlen() >= 128) \268return &aes_xts_rv64i_zvbb_zvkg_zvkned; \269if (RISCV_HAS_ZVKNED() && riscv_vlen() >= 128) \270return &aes_xts_rv64i_zvkned; \271else if (RISCV_HAS_ZKND_AND_ZKNE()) \272return &aes_xts_rv64i_zknd_zkne;273274#elif defined(OPENSSL_CPUID_OBJ) && defined(__riscv) && __riscv_xlen == 32275276static int cipher_hw_aes_xts_rv32i_zknd_zkne_initkey(PROV_CIPHER_CTX *ctx,277const unsigned char *key,278size_t keylen)279{280PROV_AES_XTS_CTX *xctx = (PROV_AES_XTS_CTX *)ctx;281282XTS_SET_KEY_FN(rv32i_zkne_set_encrypt_key, rv32i_zknd_zkne_set_decrypt_key,283rv32i_zkne_encrypt, rv32i_zknd_decrypt,284NULL, NULL);285return 1;286}287288static int cipher_hw_aes_xts_rv32i_zbkb_zknd_zkne_initkey(PROV_CIPHER_CTX *ctx,289const unsigned char *key,290size_t keylen)291{292PROV_AES_XTS_CTX *xctx = (PROV_AES_XTS_CTX *)ctx;293294XTS_SET_KEY_FN(rv32i_zbkb_zkne_set_encrypt_key, rv32i_zbkb_zknd_zkne_set_decrypt_key,295rv32i_zkne_encrypt, rv32i_zknd_decrypt,296NULL, NULL);297return 1;298}299300# define PROV_CIPHER_HW_declare_xts() \301static const PROV_CIPHER_HW aes_xts_rv32i_zknd_zkne = { \302cipher_hw_aes_xts_rv32i_zknd_zkne_initkey, \303NULL, \304cipher_hw_aes_xts_copyctx \305}; \306static const PROV_CIPHER_HW aes_xts_rv32i_zbkb_zknd_zkne = { \307cipher_hw_aes_xts_rv32i_zbkb_zknd_zkne_initkey, \308NULL, \309cipher_hw_aes_xts_copyctx \310};311# define PROV_CIPHER_HW_select_xts() \312if (RISCV_HAS_ZBKB_AND_ZKND_AND_ZKNE()) \313return &aes_xts_rv32i_zbkb_zknd_zkne; \314if (RISCV_HAS_ZKND_AND_ZKNE()) \315return &aes_xts_rv32i_zknd_zkne;316# else317/* The generic case */318# define PROV_CIPHER_HW_declare_xts()319# define PROV_CIPHER_HW_select_xts()320#endif321322static const PROV_CIPHER_HW aes_generic_xts = {323cipher_hw_aes_xts_generic_initkey,324NULL,325cipher_hw_aes_xts_copyctx326};327PROV_CIPHER_HW_declare_xts()328const PROV_CIPHER_HW *ossl_prov_cipher_hw_aes_xts(size_t keybits)329{330PROV_CIPHER_HW_select_xts()331return &aes_generic_xts;332}333334335