1 /* 2 * Copyright 2019-2025 The OpenSSL Project Authors. All Rights Reserved. 3 * 4 * Licensed under the Apache License 2.0 (the "License"). You may not use 5 * this file except in compliance with the License. You can obtain a copy 6 * in the file LICENSE in the source distribution or at 7 * https://www.openssl.org/source/license.html 8 */ 9 10 /* 11 * This file uses the low level AES functions (which are deprecated for 12 * non-internal use) in order to implement provider AES ciphers. 13 */ 14 #include "internal/deprecated.h" 15 16 #include "cipher_aes_xts.h" 17 18 #define XTS_SET_KEY_FN(fn_set_enc_key, fn_set_dec_key, \ 19 fn_block_enc, fn_block_dec, \ 20 fn_stream_enc, fn_stream_dec) { \ 21 size_t bytes = keylen / 2; \ 22 size_t bits = bytes * 8; \ 23 \ 24 if (ctx->enc) { \ 25 fn_set_enc_key(key, bits, &xctx->ks1.ks); \ 26 xctx->xts.block1 = (block128_f)fn_block_enc; \ 27 } else { \ 28 fn_set_dec_key(key, bits, &xctx->ks1.ks); \ 29 xctx->xts.block1 = (block128_f)fn_block_dec; \ 30 } \ 31 fn_set_enc_key(key + bytes, bits, &xctx->ks2.ks); \ 32 xctx->xts.block2 = (block128_f)fn_block_enc; \ 33 xctx->xts.key1 = &xctx->ks1; \ 34 xctx->xts.key2 = &xctx->ks2; \ 35 xctx->stream = ctx->enc ? fn_stream_enc : fn_stream_dec; \ 36 } 37 38 static int cipher_hw_aes_xts_generic_initkey(PROV_CIPHER_CTX *ctx, 39 const unsigned char *key, 40 size_t keylen) 41 { 42 PROV_AES_XTS_CTX *xctx = (PROV_AES_XTS_CTX *)ctx; 43 OSSL_xts_stream_fn stream_enc = NULL; 44 OSSL_xts_stream_fn stream_dec = NULL; 45 46 #ifdef AES_XTS_ASM 47 stream_enc = AES_xts_encrypt; 48 stream_dec = AES_xts_decrypt; 49 #endif /* AES_XTS_ASM */ 50 51 #ifdef HWAES_CAPABLE 52 if (HWAES_CAPABLE) { 53 # ifdef HWAES_xts_encrypt 54 stream_enc = HWAES_xts_encrypt; 55 # endif /* HWAES_xts_encrypt */ 56 # ifdef HWAES_xts_decrypt 57 stream_dec = HWAES_xts_decrypt; 58 # endif /* HWAES_xts_decrypt */ 59 XTS_SET_KEY_FN(HWAES_set_encrypt_key, HWAES_set_decrypt_key, 60 HWAES_encrypt, HWAES_decrypt, 61 stream_enc, stream_dec); 62 return 1; 63 } else 64 #endif /* HWAES_CAPABLE */ 65 66 #ifdef BSAES_CAPABLE 67 if (BSAES_CAPABLE) { 68 stream_enc = ossl_bsaes_xts_encrypt; 69 stream_dec = ossl_bsaes_xts_decrypt; 70 } else 71 #endif /* BSAES_CAPABLE */ 72 #ifdef VPAES_CAPABLE 73 if (VPAES_CAPABLE) { 74 XTS_SET_KEY_FN(vpaes_set_encrypt_key, vpaes_set_decrypt_key, 75 vpaes_encrypt, vpaes_decrypt, stream_enc, stream_dec); 76 return 1; 77 } else 78 #endif /* VPAES_CAPABLE */ 79 { 80 (void)0; 81 } 82 { 83 XTS_SET_KEY_FN(AES_set_encrypt_key, AES_set_decrypt_key, 84 AES_encrypt, AES_decrypt, stream_enc, stream_dec); 85 } 86 return 1; 87 } 88 89 static void cipher_hw_aes_xts_copyctx(PROV_CIPHER_CTX *dst, 90 const PROV_CIPHER_CTX *src) 91 { 92 PROV_AES_XTS_CTX *sctx = (PROV_AES_XTS_CTX *)src; 93 PROV_AES_XTS_CTX *dctx = (PROV_AES_XTS_CTX *)dst; 94 95 *dctx = *sctx; 96 dctx->xts.key1 = &dctx->ks1.ks; 97 dctx->xts.key2 = &dctx->ks2.ks; 98 } 99 100 #if defined(AESNI_CAPABLE) 101 102 static int cipher_hw_aesni_xts_initkey(PROV_CIPHER_CTX *ctx, 103 const unsigned char *key, size_t keylen) 104 { 105 PROV_AES_XTS_CTX *xctx = (PROV_AES_XTS_CTX *)ctx; 106 107 void (*aesni_xts_enc)(const unsigned char *in, 108 unsigned char *out, 109 size_t length, 110 const AES_KEY *key1, const AES_KEY *key2, 111 const unsigned char iv[16]); 112 void (*aesni_xts_dec)(const unsigned char *in, 113 unsigned char *out, 114 size_t length, 115 const AES_KEY *key1, const AES_KEY *key2, 116 const unsigned char iv[16]); 117 118 aesni_xts_enc = aesni_xts_encrypt; 119 aesni_xts_dec = aesni_xts_decrypt; 120 121 # if (defined(__x86_64) || defined(__x86_64__) || \ 122 defined(_M_AMD64) || defined(_M_X64)) 123 if (aesni_xts_avx512_eligible()) { 124 if (keylen == 64) { 125 aesni_xts_enc = aesni_xts_256_encrypt_avx512; 126 aesni_xts_dec = aesni_xts_256_decrypt_avx512; 127 } else if (keylen == 32) { 128 aesni_xts_enc = aesni_xts_128_encrypt_avx512; 129 aesni_xts_dec = aesni_xts_128_decrypt_avx512; 130 } 131 } 132 # endif 133 134 XTS_SET_KEY_FN(aesni_set_encrypt_key, aesni_set_decrypt_key, 135 aesni_encrypt, aesni_decrypt, 136 aesni_xts_enc, aesni_xts_dec); 137 return 1; 138 } 139 140 # define PROV_CIPHER_HW_declare_xts() \ 141 static const PROV_CIPHER_HW aesni_xts = { \ 142 cipher_hw_aesni_xts_initkey, \ 143 NULL, \ 144 cipher_hw_aes_xts_copyctx \ 145 }; 146 # define PROV_CIPHER_HW_select_xts() \ 147 if (AESNI_CAPABLE) \ 148 return &aesni_xts; 149 150 # elif defined(SPARC_AES_CAPABLE) 151 152 static int cipher_hw_aes_xts_t4_initkey(PROV_CIPHER_CTX *ctx, 153 const unsigned char *key, size_t keylen) 154 { 155 PROV_AES_XTS_CTX *xctx = (PROV_AES_XTS_CTX *)ctx; 156 OSSL_xts_stream_fn stream_enc = NULL; 157 OSSL_xts_stream_fn stream_dec = NULL; 158 159 /* Note: keylen is the size of 2 keys */ 160 switch (keylen) { 161 case 32: 162 stream_enc = aes128_t4_xts_encrypt; 163 stream_dec = aes128_t4_xts_decrypt; 164 break; 165 case 64: 166 stream_enc = aes256_t4_xts_encrypt; 167 stream_dec = aes256_t4_xts_decrypt; 168 break; 169 default: 170 return 0; 171 } 172 173 XTS_SET_KEY_FN(aes_t4_set_encrypt_key, aes_t4_set_decrypt_key, 174 aes_t4_encrypt, aes_t4_decrypt, 175 stream_enc, stream_dec); 176 return 1; 177 } 178 179 # define PROV_CIPHER_HW_declare_xts() \ 180 static const PROV_CIPHER_HW aes_xts_t4 = { \ 181 cipher_hw_aes_xts_t4_initkey, \ 182 NULL, \ 183 cipher_hw_aes_xts_copyctx \ 184 }; 185 # define PROV_CIPHER_HW_select_xts() \ 186 if (SPARC_AES_CAPABLE) \ 187 return &aes_xts_t4; 188 189 #elif defined(OPENSSL_CPUID_OBJ) && defined(__riscv) && __riscv_xlen == 64 190 191 static int cipher_hw_aes_xts_rv64i_zknd_zkne_initkey(PROV_CIPHER_CTX *ctx, 192 const unsigned char *key, 193 size_t keylen) 194 { 195 PROV_AES_XTS_CTX *xctx = (PROV_AES_XTS_CTX *)ctx; 196 OSSL_xts_stream_fn stream_enc = NULL; 197 OSSL_xts_stream_fn stream_dec = NULL; 198 199 XTS_SET_KEY_FN(rv64i_zkne_set_encrypt_key, rv64i_zknd_set_decrypt_key, 200 rv64i_zkne_encrypt, rv64i_zknd_decrypt, 201 stream_enc, stream_dec); 202 return 1; 203 } 204 205 static int cipher_hw_aes_xts_rv64i_zvbb_zvkg_zvkned_initkey( 206 PROV_CIPHER_CTX *ctx, const unsigned char *key, size_t keylen) 207 { 208 PROV_AES_XTS_CTX *xctx = (PROV_AES_XTS_CTX *)ctx; 209 OSSL_xts_stream_fn stream_enc = NULL; 210 OSSL_xts_stream_fn stream_dec = NULL; 211 212 /* Zvkned only supports 128 and 256 bit keys. */ 213 if (keylen * 8 == 128 * 2 || keylen * 8 == 256 * 2) { 214 XTS_SET_KEY_FN(rv64i_zvkned_set_encrypt_key, 215 rv64i_zvkned_set_decrypt_key, rv64i_zvkned_encrypt, 216 rv64i_zvkned_decrypt, 217 rv64i_zvbb_zvkg_zvkned_aes_xts_encrypt, 218 rv64i_zvbb_zvkg_zvkned_aes_xts_decrypt); 219 } else { 220 XTS_SET_KEY_FN(AES_set_encrypt_key, AES_set_encrypt_key, 221 rv64i_zvkned_encrypt, rv64i_zvkned_decrypt, 222 stream_enc, stream_dec); 223 } 224 return 1; 225 } 226 227 static int cipher_hw_aes_xts_rv64i_zvkned_initkey(PROV_CIPHER_CTX *ctx, 228 const unsigned char *key, 229 size_t keylen) 230 { 231 PROV_AES_XTS_CTX *xctx = (PROV_AES_XTS_CTX *)ctx; 232 OSSL_xts_stream_fn stream_enc = NULL; 233 OSSL_xts_stream_fn stream_dec = NULL; 234 235 /* Zvkned only supports 128 and 256 bit keys. */ 236 if (keylen * 8 == 128 * 2 || keylen * 8 == 256 * 2) { 237 XTS_SET_KEY_FN(rv64i_zvkned_set_encrypt_key, 238 rv64i_zvkned_set_decrypt_key, 239 rv64i_zvkned_encrypt, rv64i_zvkned_decrypt, 240 stream_enc, stream_dec); 241 } else { 242 XTS_SET_KEY_FN(AES_set_encrypt_key, AES_set_encrypt_key, 243 rv64i_zvkned_encrypt, rv64i_zvkned_decrypt, 244 stream_enc, stream_dec); 245 } 246 return 1; 247 } 248 249 # define PROV_CIPHER_HW_declare_xts() \ 250 static const PROV_CIPHER_HW aes_xts_rv64i_zknd_zkne = { \ 251 cipher_hw_aes_xts_rv64i_zknd_zkne_initkey, \ 252 NULL, \ 253 cipher_hw_aes_xts_copyctx \ 254 }; \ 255 static const PROV_CIPHER_HW aes_xts_rv64i_zvkned = { \ 256 cipher_hw_aes_xts_rv64i_zvkned_initkey, \ 257 NULL, \ 258 cipher_hw_aes_xts_copyctx \ 259 }; \ 260 static const PROV_CIPHER_HW aes_xts_rv64i_zvbb_zvkg_zvkned = { \ 261 cipher_hw_aes_xts_rv64i_zvbb_zvkg_zvkned_initkey, \ 262 NULL, \ 263 cipher_hw_aes_xts_copyctx \ 264 }; 265 266 # define PROV_CIPHER_HW_select_xts() \ 267 if (RISCV_HAS_ZVBB() && RISCV_HAS_ZVKG() && RISCV_HAS_ZVKNED() && \ 268 riscv_vlen() >= 128) \ 269 return &aes_xts_rv64i_zvbb_zvkg_zvkned; \ 270 if (RISCV_HAS_ZVKNED() && riscv_vlen() >= 128) \ 271 return &aes_xts_rv64i_zvkned; \ 272 else if (RISCV_HAS_ZKND_AND_ZKNE()) \ 273 return &aes_xts_rv64i_zknd_zkne; 274 275 #elif defined(OPENSSL_CPUID_OBJ) && defined(__riscv) && __riscv_xlen == 32 276 277 static int cipher_hw_aes_xts_rv32i_zknd_zkne_initkey(PROV_CIPHER_CTX *ctx, 278 const unsigned char *key, 279 size_t keylen) 280 { 281 PROV_AES_XTS_CTX *xctx = (PROV_AES_XTS_CTX *)ctx; 282 283 XTS_SET_KEY_FN(rv32i_zkne_set_encrypt_key, rv32i_zknd_zkne_set_decrypt_key, 284 rv32i_zkne_encrypt, rv32i_zknd_decrypt, 285 NULL, NULL); 286 return 1; 287 } 288 289 static int cipher_hw_aes_xts_rv32i_zbkb_zknd_zkne_initkey(PROV_CIPHER_CTX *ctx, 290 const unsigned char *key, 291 size_t keylen) 292 { 293 PROV_AES_XTS_CTX *xctx = (PROV_AES_XTS_CTX *)ctx; 294 295 XTS_SET_KEY_FN(rv32i_zbkb_zkne_set_encrypt_key, rv32i_zbkb_zknd_zkne_set_decrypt_key, 296 rv32i_zkne_encrypt, rv32i_zknd_decrypt, 297 NULL, NULL); 298 return 1; 299 } 300 301 # define PROV_CIPHER_HW_declare_xts() \ 302 static const PROV_CIPHER_HW aes_xts_rv32i_zknd_zkne = { \ 303 cipher_hw_aes_xts_rv32i_zknd_zkne_initkey, \ 304 NULL, \ 305 cipher_hw_aes_xts_copyctx \ 306 }; \ 307 static const PROV_CIPHER_HW aes_xts_rv32i_zbkb_zknd_zkne = { \ 308 cipher_hw_aes_xts_rv32i_zbkb_zknd_zkne_initkey, \ 309 NULL, \ 310 cipher_hw_aes_xts_copyctx \ 311 }; 312 # define PROV_CIPHER_HW_select_xts() \ 313 if (RISCV_HAS_ZBKB_AND_ZKND_AND_ZKNE()) \ 314 return &aes_xts_rv32i_zbkb_zknd_zkne; \ 315 if (RISCV_HAS_ZKND_AND_ZKNE()) \ 316 return &aes_xts_rv32i_zknd_zkne; 317 # else 318 /* The generic case */ 319 # define PROV_CIPHER_HW_declare_xts() 320 # define PROV_CIPHER_HW_select_xts() 321 #endif 322 323 static const PROV_CIPHER_HW aes_generic_xts = { 324 cipher_hw_aes_xts_generic_initkey, 325 NULL, 326 cipher_hw_aes_xts_copyctx 327 }; 328 PROV_CIPHER_HW_declare_xts() 329 const PROV_CIPHER_HW *ossl_prov_cipher_hw_aes_xts(size_t keybits) 330 { 331 PROV_CIPHER_HW_select_xts() 332 return &aes_generic_xts; 333 } 334