/src/openssl/providers/implementations/ciphers/cipher_aes_hw.c
Line | Count | Source |
1 | | /* |
2 | | * Copyright 2001-2026 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 <openssl/proverr.h> |
17 | | #include "cipher_aes.h" |
18 | | |
19 | | int ossl_cipher_set_aes_initkey(PROV_CIPHER_CTX *ctx, |
20 | | const unsigned char *key, size_t keylen, |
21 | | aes_set_encrypt_key_fn fn_set_key, aes_block128_f fn_block, |
22 | | ecb128_f fn_ecb, cbc128_f fn_cbc, ctr128_f fn_ctr) |
23 | 0 | { |
24 | 0 | PROV_AES_CTX *actx = (PROV_AES_CTX *)ctx; |
25 | 0 | AES_KEY *ks = &actx->ks.ks; |
26 | |
|
27 | 0 | int ret = fn_set_key(key, (int)(keylen * 8), ks); |
28 | 0 | if (ret < 0) { |
29 | 0 | ERR_raise(ERR_LIB_PROV, PROV_R_KEY_SETUP_FAILED); |
30 | 0 | return 0; |
31 | 0 | } |
32 | 0 | ctx->ks = ks; |
33 | |
|
34 | 0 | ctx->block = (block128_f)fn_block; |
35 | |
|
36 | 0 | switch (ctx->mode) { |
37 | 0 | case EVP_CIPH_ECB_MODE: |
38 | 0 | ctx->stream.ecb = fn_ecb; |
39 | 0 | break; |
40 | 0 | case EVP_CIPH_CBC_MODE: |
41 | 0 | ctx->stream.cbc = fn_cbc; |
42 | 0 | break; |
43 | 0 | case EVP_CIPH_CTR_MODE: |
44 | 0 | ctx->stream.ctr = fn_ctr; |
45 | 0 | break; |
46 | 0 | default: |
47 | 0 | memset(&ctx->stream, 0, sizeof(ctx->stream)); |
48 | 0 | break; |
49 | 0 | } |
50 | | |
51 | 0 | return 1; |
52 | 0 | } |
53 | | |
54 | | #ifdef HWAES_CAPABLE |
55 | | static int hwaes_initkey(PROV_CIPHER_CTX *ctx, |
56 | | const unsigned char *key, size_t keylen) |
57 | | { |
58 | | if (HWAES_CAPABLE) { |
59 | | ecb128_f fn_ecb = NULL; |
60 | | cbc128_f fn_cbc = NULL; |
61 | | ctr128_f fn_ctr = NULL; |
62 | | #ifdef HWAES_ecb_encrypt |
63 | | fn_ecb = (ecb128_f)HWAES_ecb_encrypt; |
64 | | #endif |
65 | | #ifdef HWAES_cbc_encrypt |
66 | | fn_cbc = (cbc128_f)HWAES_cbc_encrypt; |
67 | | #endif |
68 | | #ifdef HWAES_ctr32_encrypt_blocks |
69 | | fn_ctr = (ctr128_f)HWAES_ctr32_encrypt_blocks; |
70 | | #endif |
71 | | if ((ctx->mode == EVP_CIPH_ECB_MODE || ctx->mode == EVP_CIPH_CBC_MODE) |
72 | | && !ctx->enc) |
73 | | return ossl_cipher_set_aes_initkey(ctx, key, keylen, |
74 | | HWAES_set_decrypt_key, HWAES_decrypt, fn_ecb, fn_cbc, fn_ctr); |
75 | | else |
76 | | return ossl_cipher_set_aes_initkey(ctx, key, keylen, |
77 | | HWAES_set_encrypt_key, HWAES_encrypt, fn_ecb, fn_cbc, fn_ctr); |
78 | | } |
79 | | return -1; |
80 | | } |
81 | | #endif /* HWAES_CAPABLE */ |
82 | | |
83 | | #ifdef BSAES_CAPABLE |
84 | | static int bsaes_initkey(PROV_CIPHER_CTX *ctx, |
85 | | const unsigned char *key, size_t keylen) |
86 | | { |
87 | | if (BSAES_CAPABLE) { |
88 | | if (ctx->mode == EVP_CIPH_CBC_MODE && !ctx->enc) |
89 | | return ossl_cipher_set_aes_initkey(ctx, key, keylen, |
90 | | AES_set_decrypt_key, AES_decrypt, NULL, |
91 | | (cbc128_f)ossl_bsaes_cbc_encrypt, NULL); |
92 | | else if (ctx->mode == EVP_CIPH_CTR_MODE) |
93 | | return ossl_cipher_set_aes_initkey(ctx, key, keylen, |
94 | | AES_set_encrypt_key, AES_encrypt, NULL, NULL, |
95 | | (ctr128_f)ossl_bsaes_ctr32_encrypt_blocks); |
96 | | } |
97 | | return -1; |
98 | | } |
99 | | #endif /* BSAES_CAPABLE */ |
100 | | |
101 | | #ifdef VPAES_CAPABLE |
102 | | static int vpaes_initkey(PROV_CIPHER_CTX *ctx, |
103 | | const unsigned char *key, size_t keylen) |
104 | | { |
105 | | if (VPAES_CAPABLE) { |
106 | | if ((ctx->mode == EVP_CIPH_ECB_MODE || ctx->mode == EVP_CIPH_CBC_MODE) |
107 | | && !ctx->enc) { |
108 | | return ossl_cipher_set_aes_initkey(ctx, key, keylen, |
109 | | vpaes_set_decrypt_key, vpaes_decrypt, NULL, |
110 | | (cbc128_f)vpaes_cbc_encrypt, NULL); |
111 | | } else { |
112 | | return ossl_cipher_set_aes_initkey(ctx, key, keylen, |
113 | | vpaes_set_encrypt_key, vpaes_encrypt, NULL, |
114 | | (cbc128_f)vpaes_cbc_encrypt, NULL); |
115 | | } |
116 | | } |
117 | | return -1; |
118 | | } |
119 | | #endif /* VPAES_CAPABLE */ |
120 | | |
121 | | int ossl_cipher_hw_aes_initkey(PROV_CIPHER_CTX *ctx, |
122 | | const unsigned char *key, size_t keylen) |
123 | 0 | { |
124 | 0 | int ret = 0; |
125 | |
|
126 | | #ifdef HWAES_CAPABLE |
127 | | ret = hwaes_initkey(ctx, key, keylen); |
128 | | if (ret >= 0) |
129 | | return ret; |
130 | | #endif |
131 | |
|
132 | | #ifdef BSAES_CAPABLE |
133 | | ret = bsaes_initkey(ctx, key, keylen); |
134 | | if (ret >= 0) |
135 | | return ret; |
136 | | #endif |
137 | |
|
138 | | #ifdef VPAES_CAPABLE |
139 | | ret = vpaes_initkey(ctx, key, keylen); |
140 | | if (ret >= 0) |
141 | | return ret; |
142 | | #endif |
143 | |
|
144 | 0 | if ((ctx->mode == EVP_CIPH_ECB_MODE || ctx->mode == EVP_CIPH_CBC_MODE) |
145 | 0 | && !ctx->enc) { |
146 | 0 | ret = ossl_cipher_set_aes_initkey(ctx, key, keylen, |
147 | 0 | AES_set_decrypt_key, AES_decrypt, NULL, (cbc128_f)AES_cbc_encrypt, |
148 | 0 | NULL); |
149 | 0 | } else { |
150 | 0 | ctr128_f fn_ctr = NULL; |
151 | | #ifdef AES_CTR_ASM |
152 | | fn_ctr = (ctr128_f)AES_ctr32_encrypt; |
153 | | #endif |
154 | 0 | ret = ossl_cipher_set_aes_initkey(ctx, key, keylen, |
155 | 0 | AES_set_encrypt_key, AES_encrypt, NULL, (cbc128_f)AES_cbc_encrypt, |
156 | 0 | fn_ctr); |
157 | 0 | } |
158 | |
|
159 | 0 | return ret; |
160 | 0 | } |
161 | | |
162 | | void ossl_cipher_aes_copyctx(PROV_CIPHER_CTX *dst, |
163 | | const PROV_CIPHER_CTX *src) |
164 | 0 | { |
165 | 0 | PROV_AES_CTX *sctx = (PROV_AES_CTX *)src; |
166 | 0 | PROV_AES_CTX *dctx = (PROV_AES_CTX *)dst; |
167 | |
|
168 | 0 | *dctx = *sctx; |
169 | 0 | dst->ks = &dctx->ks.ks; |
170 | 0 | } |
171 | | |
172 | | static const PROV_CIPHER_HW aes_ecb = { |
173 | | ossl_cipher_hw_aes_initkey, |
174 | | ossl_cipher_hw_generic_ecb, |
175 | | ossl_cipher_aes_copyctx |
176 | | }; |
177 | | |
178 | | static const PROV_CIPHER_HW aes_cbc = { |
179 | | ossl_cipher_hw_aes_initkey, |
180 | | ossl_cipher_hw_generic_cbc, |
181 | | ossl_cipher_aes_copyctx |
182 | | }; |
183 | | |
184 | | static const PROV_CIPHER_HW aes_cfb128 = { |
185 | | ossl_cipher_hw_aes_initkey, |
186 | | ossl_cipher_hw_generic_cfb128, |
187 | | ossl_cipher_aes_copyctx |
188 | | }; |
189 | | |
190 | | static const PROV_CIPHER_HW aes_cfb8 = { |
191 | | ossl_cipher_hw_aes_initkey, |
192 | | ossl_cipher_hw_generic_cfb8, |
193 | | ossl_cipher_aes_copyctx |
194 | | }; |
195 | | |
196 | | static const PROV_CIPHER_HW aes_cfb1 = { |
197 | | ossl_cipher_hw_aes_initkey, |
198 | | ossl_cipher_hw_generic_cfb1, |
199 | | ossl_cipher_aes_copyctx |
200 | | }; |
201 | | |
202 | | static const PROV_CIPHER_HW aes_ofb128 = { |
203 | | ossl_cipher_hw_aes_initkey, |
204 | | ossl_cipher_hw_generic_ofb128, |
205 | | ossl_cipher_aes_copyctx |
206 | | }; |
207 | | |
208 | | static const PROV_CIPHER_HW aes_ctr = { |
209 | | ossl_cipher_hw_aes_initkey, |
210 | | ossl_cipher_hw_generic_ctr, |
211 | | ossl_cipher_aes_copyctx |
212 | | }; |
213 | | |
214 | | static const PROV_CIPHER_HW *ossl_prov_cipher_hw_aes_mode(enum aes_modes mode, |
215 | | size_t keybits) |
216 | 0 | { |
217 | 0 | const PROV_CIPHER_HW *aes_hw_mode = NULL; |
218 | |
|
219 | | #if defined(AESNI_CAPABLE) |
220 | | aes_hw_mode = ossl_prov_cipher_hw_aesni(mode); |
221 | | #elif defined(ARMv8_HWAES_CAPABLE) |
222 | | aes_hw_mode = ossl_prov_cipher_hw_arm(mode); |
223 | | #elif defined(OPENSSL_CPUID_OBJ) && defined(__riscv) && __riscv_xlen == 32 |
224 | | aes_hw_mode = ossl_prov_cipher_hw_rv32i(mode); |
225 | | #elif defined(OPENSSL_CPUID_OBJ) && defined(__riscv) && __riscv_xlen == 64 |
226 | | aes_hw_mode = ossl_prov_cipher_hw_rv64i(mode); |
227 | | #elif defined(S390X_aes_128_CAPABLE) |
228 | | aes_hw_mode = ossl_prov_cipher_hw_s390x(mode, keybits); |
229 | | #elif defined(SPARC_AES_CAPABLE) |
230 | | aes_hw_mode = ossl_prov_cipher_hw_t4(mode); |
231 | | #endif |
232 | |
|
233 | 0 | if (aes_hw_mode == NULL) { |
234 | 0 | switch (mode) { |
235 | 0 | case AES_MODE_ECB: |
236 | 0 | return &aes_ecb; |
237 | 0 | case AES_MODE_CBC: |
238 | 0 | return &aes_cbc; |
239 | 0 | case AES_MODE_CFB128: |
240 | 0 | return &aes_cfb128; |
241 | 0 | case AES_MODE_CFB8: |
242 | 0 | return &aes_cfb8; |
243 | 0 | case AES_MODE_CFB1: |
244 | 0 | return &aes_cfb1; |
245 | 0 | case AES_MODE_OFB128: |
246 | 0 | return &aes_ofb128; |
247 | 0 | case AES_MODE_CTR: |
248 | 0 | return &aes_ctr; |
249 | 0 | } |
250 | 0 | } |
251 | | |
252 | 0 | return aes_hw_mode; |
253 | 0 | } |
254 | | |
255 | | const PROV_CIPHER_HW *ossl_prov_cipher_hw_aes_ecb(size_t keybits) |
256 | 0 | { |
257 | 0 | return ossl_prov_cipher_hw_aes_mode(AES_MODE_ECB, keybits); |
258 | 0 | } |
259 | | |
260 | | const PROV_CIPHER_HW *ossl_prov_cipher_hw_aes_cbc(size_t keybits) |
261 | 0 | { |
262 | 0 | return ossl_prov_cipher_hw_aes_mode(AES_MODE_CBC, keybits); |
263 | 0 | } |
264 | | |
265 | | const PROV_CIPHER_HW *ossl_prov_cipher_hw_aes_cfb128(size_t keybits) |
266 | 0 | { |
267 | 0 | return ossl_prov_cipher_hw_aes_mode(AES_MODE_CFB128, keybits); |
268 | 0 | } |
269 | | |
270 | | const PROV_CIPHER_HW *ossl_prov_cipher_hw_aes_cfb8(size_t keybits) |
271 | 0 | { |
272 | 0 | return ossl_prov_cipher_hw_aes_mode(AES_MODE_CFB8, keybits); |
273 | 0 | } |
274 | | |
275 | | const PROV_CIPHER_HW *ossl_prov_cipher_hw_aes_cfb1(size_t keybits) |
276 | 0 | { |
277 | 0 | return ossl_prov_cipher_hw_aes_mode(AES_MODE_CFB1, keybits); |
278 | 0 | } |
279 | | |
280 | | const PROV_CIPHER_HW *ossl_prov_cipher_hw_aes_ofb128(size_t keybits) |
281 | 0 | { |
282 | 0 | return ossl_prov_cipher_hw_aes_mode(AES_MODE_OFB128, keybits); |
283 | 0 | } |
284 | | |
285 | | const PROV_CIPHER_HW *ossl_prov_cipher_hw_aes_ctr(size_t keybits) |
286 | 0 | { |
287 | 0 | return ossl_prov_cipher_hw_aes_mode(AES_MODE_CTR, keybits); |
288 | 0 | } |