Path: blob/main/crypto/openssl/providers/implementations/ciphers/cipher_aes_xts_hw.c
107833 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) \20{ \21size_t bytes = keylen / 2; \22size_t bits = bytes * 8; \23\24if (ctx->enc) { \25fn_set_enc_key(key, bits, &xctx->ks1.ks); \26xctx->xts.block1 = (block128_f)fn_block_enc; \27} else { \28fn_set_dec_key(key, bits, &xctx->ks1.ks); \29xctx->xts.block1 = (block128_f)fn_block_dec; \30} \31fn_set_enc_key(key + bytes, bits, &xctx->ks2.ks); \32xctx->xts.block2 = (block128_f)fn_block_enc; \33xctx->xts.key1 = &xctx->ks1; \34xctx->xts.key2 = &xctx->ks2; \35xctx->stream = ctx->enc ? fn_stream_enc : fn_stream_dec; \36}3738static int cipher_hw_aes_xts_generic_initkey(PROV_CIPHER_CTX *ctx,39const unsigned char *key,40size_t keylen)41{42PROV_AES_XTS_CTX *xctx = (PROV_AES_XTS_CTX *)ctx;43OSSL_xts_stream_fn stream_enc = NULL;44OSSL_xts_stream_fn stream_dec = NULL;4546#ifdef AES_XTS_ASM47stream_enc = AES_xts_encrypt;48stream_dec = AES_xts_decrypt;49#endif /* AES_XTS_ASM */5051#ifdef HWAES_CAPABLE52if (HWAES_CAPABLE) {53#ifdef HWAES_xts_encrypt54stream_enc = HWAES_xts_encrypt;55#endif /* HWAES_xts_encrypt */56#ifdef HWAES_xts_decrypt57stream_dec = HWAES_xts_decrypt;58#endif /* HWAES_xts_decrypt */59XTS_SET_KEY_FN(HWAES_set_encrypt_key, HWAES_set_decrypt_key,60HWAES_encrypt, HWAES_decrypt,61stream_enc, stream_dec);62return 1;63} else64#endif /* HWAES_CAPABLE */6566#ifdef BSAES_CAPABLE67if (BSAES_CAPABLE) {68stream_enc = ossl_bsaes_xts_encrypt;69stream_dec = ossl_bsaes_xts_decrypt;70} else71#endif /* BSAES_CAPABLE */72#ifdef VPAES_CAPABLE73if (VPAES_CAPABLE) {74XTS_SET_KEY_FN(vpaes_set_encrypt_key, vpaes_set_decrypt_key,75vpaes_encrypt, vpaes_decrypt, stream_enc, stream_dec);76return 1;77} else78#endif /* VPAES_CAPABLE */79{80(void)0;81}82{83XTS_SET_KEY_FN(AES_set_encrypt_key, AES_set_decrypt_key,84AES_encrypt, AES_decrypt, stream_enc, stream_dec);85}86return 1;87}8889static void cipher_hw_aes_xts_copyctx(PROV_CIPHER_CTX *dst,90const PROV_CIPHER_CTX *src)91{92PROV_AES_XTS_CTX *sctx = (PROV_AES_XTS_CTX *)src;93PROV_AES_XTS_CTX *dctx = (PROV_AES_XTS_CTX *)dst;9495*dctx = *sctx;96dctx->xts.key1 = &dctx->ks1.ks;97dctx->xts.key2 = &dctx->ks2.ks;98}99100#if defined(AESNI_CAPABLE)101102static int cipher_hw_aesni_xts_initkey(PROV_CIPHER_CTX *ctx,103const unsigned char *key, size_t keylen)104{105PROV_AES_XTS_CTX *xctx = (PROV_AES_XTS_CTX *)ctx;106107void (*aesni_xts_enc)(const unsigned char *in,108unsigned char *out,109size_t length,110const AES_KEY *key1, const AES_KEY *key2,111const unsigned char iv[16]);112void (*aesni_xts_dec)(const unsigned char *in,113unsigned char *out,114size_t length,115const AES_KEY *key1, const AES_KEY *key2,116const unsigned char iv[16]);117118aesni_xts_enc = aesni_xts_encrypt;119aesni_xts_dec = aesni_xts_decrypt;120121#if (defined(__x86_64) || defined(__x86_64__) || defined(_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() && riscv_vlen() >= 128) \267return &aes_xts_rv64i_zvbb_zvkg_zvkned; \268if (RISCV_HAS_ZVKNED() && riscv_vlen() >= 128) \269return &aes_xts_rv64i_zvkned; \270else if (RISCV_HAS_ZKND_AND_ZKNE()) \271return &aes_xts_rv64i_zknd_zkne;272273#elif defined(OPENSSL_CPUID_OBJ) && defined(__riscv) && __riscv_xlen == 32274275static int cipher_hw_aes_xts_rv32i_zknd_zkne_initkey(PROV_CIPHER_CTX *ctx,276const unsigned char *key,277size_t keylen)278{279PROV_AES_XTS_CTX *xctx = (PROV_AES_XTS_CTX *)ctx;280281XTS_SET_KEY_FN(rv32i_zkne_set_encrypt_key, rv32i_zknd_zkne_set_decrypt_key,282rv32i_zkne_encrypt, rv32i_zknd_decrypt,283NULL, NULL);284return 1;285}286287static int cipher_hw_aes_xts_rv32i_zbkb_zknd_zkne_initkey(PROV_CIPHER_CTX *ctx,288const unsigned char *key,289size_t keylen)290{291PROV_AES_XTS_CTX *xctx = (PROV_AES_XTS_CTX *)ctx;292293XTS_SET_KEY_FN(rv32i_zbkb_zkne_set_encrypt_key, rv32i_zbkb_zknd_zkne_set_decrypt_key,294rv32i_zkne_encrypt, rv32i_zknd_decrypt,295NULL, NULL);296return 1;297}298299#define PROV_CIPHER_HW_declare_xts() \300static const PROV_CIPHER_HW aes_xts_rv32i_zknd_zkne = { \301cipher_hw_aes_xts_rv32i_zknd_zkne_initkey, \302NULL, \303cipher_hw_aes_xts_copyctx \304}; \305static const PROV_CIPHER_HW aes_xts_rv32i_zbkb_zknd_zkne = { \306cipher_hw_aes_xts_rv32i_zbkb_zknd_zkne_initkey, \307NULL, \308cipher_hw_aes_xts_copyctx \309};310#define PROV_CIPHER_HW_select_xts() \311if (RISCV_HAS_ZBKB_AND_ZKND_AND_ZKNE()) \312return &aes_xts_rv32i_zbkb_zknd_zkne; \313if (RISCV_HAS_ZKND_AND_ZKNE()) \314return &aes_xts_rv32i_zknd_zkne;315#else316/* The generic case */317#define PROV_CIPHER_HW_declare_xts()318#define PROV_CIPHER_HW_select_xts()319#endif320321static const PROV_CIPHER_HW aes_generic_xts = {322cipher_hw_aes_xts_generic_initkey,323NULL,324cipher_hw_aes_xts_copyctx325};326PROV_CIPHER_HW_declare_xts()327const PROV_CIPHER_HW *ossl_prov_cipher_hw_aes_xts(size_t keybits)328{329PROV_CIPHER_HW_select_xts() return &aes_generic_xts;330}331332333