1 | /* |
2 | * Copyright 2001-2019 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 | #include "cipher_aes.h" |
11 | #include "prov/providercommonerr.h" |
12 | |
13 | static int cipher_hw_aes_initkey(PROV_CIPHER_CTX *dat, |
14 | const unsigned char *key, size_t keylen) |
15 | { |
16 | int ret; |
17 | PROV_AES_CTX *adat = (PROV_AES_CTX *)dat; |
18 | AES_KEY *ks = &adat->ks.ks; |
19 | |
20 | dat->ks = ks; |
21 | |
22 | if ((dat->mode == EVP_CIPH_ECB_MODE || dat->mode == EVP_CIPH_CBC_MODE) |
23 | && !dat->enc) { |
24 | #ifdef HWAES_CAPABLE |
25 | if (HWAES_CAPABLE) { |
26 | ret = HWAES_set_decrypt_key(key, keylen * 8, ks); |
27 | dat->block = (block128_f)HWAES_decrypt; |
28 | dat->stream.cbc = NULL; |
29 | # ifdef HWAES_cbc_encrypt |
30 | if (dat->mode == EVP_CIPH_CBC_MODE) |
31 | dat->stream.cbc = (cbc128_f)HWAES_cbc_encrypt; |
32 | # endif |
33 | # ifdef HWAES_ecb_encrypt |
34 | if (dat->mode == EVP_CIPH_ECB_MODE) |
35 | dat->stream.ecb = (ecb128_f)HWAES_ecb_encrypt; |
36 | # endif |
37 | } else |
38 | #endif |
39 | #ifdef BSAES_CAPABLE |
40 | if (BSAES_CAPABLE && dat->mode == EVP_CIPH_CBC_MODE) { |
41 | ret = AES_set_decrypt_key(key, keylen * 8, ks); |
42 | dat->block = (block128_f)AES_decrypt; |
43 | dat->stream.cbc = (cbc128_f)bsaes_cbc_encrypt; |
44 | } else |
45 | #endif |
46 | #ifdef VPAES_CAPABLE |
47 | if (VPAES_CAPABLE) { |
48 | ret = vpaes_set_decrypt_key(key, keylen * 8, ks); |
49 | dat->block = (block128_f)vpaes_decrypt; |
50 | dat->stream.cbc = (dat->mode == EVP_CIPH_CBC_MODE) |
51 | ?(cbc128_f)vpaes_cbc_encrypt : NULL; |
52 | } else |
53 | #endif |
54 | { |
55 | ret = AES_set_decrypt_key(key, keylen * 8, ks); |
56 | dat->block = (block128_f)AES_decrypt; |
57 | dat->stream.cbc = (dat->mode == EVP_CIPH_CBC_MODE) |
58 | ? (cbc128_f)AES_cbc_encrypt : NULL; |
59 | } |
60 | } else |
61 | #ifdef HWAES_CAPABLE |
62 | if (HWAES_CAPABLE) { |
63 | ret = HWAES_set_encrypt_key(key, keylen * 8, ks); |
64 | dat->block = (block128_f)HWAES_encrypt; |
65 | dat->stream.cbc = NULL; |
66 | # ifdef HWAES_cbc_encrypt |
67 | if (dat->mode == EVP_CIPH_CBC_MODE) |
68 | dat->stream.cbc = (cbc128_f)HWAES_cbc_encrypt; |
69 | else |
70 | # endif |
71 | # ifdef HWAES_ecb_encrypt |
72 | if (dat->mode == EVP_CIPH_ECB_MODE) |
73 | dat->stream.ecb = (ecb128_f)HWAES_ecb_encrypt; |
74 | else |
75 | # endif |
76 | # ifdef HWAES_ctr32_encrypt_blocks |
77 | if (dat->mode == EVP_CIPH_CTR_MODE) |
78 | dat->stream.ctr = (ctr128_f)HWAES_ctr32_encrypt_blocks; |
79 | else |
80 | # endif |
81 | (void)0; /* terminate potentially open 'else' */ |
82 | } else |
83 | #endif |
84 | #ifdef BSAES_CAPABLE |
85 | if (BSAES_CAPABLE && dat->mode == EVP_CIPH_CTR_MODE) { |
86 | ret = AES_set_encrypt_key(key, keylen * 8, ks); |
87 | dat->block = (block128_f)AES_encrypt; |
88 | dat->stream.ctr = (ctr128_f)bsaes_ctr32_encrypt_blocks; |
89 | } else |
90 | #endif |
91 | #ifdef VPAES_CAPABLE |
92 | if (VPAES_CAPABLE) { |
93 | ret = vpaes_set_encrypt_key(key, keylen * 8, ks); |
94 | dat->block = (block128_f)vpaes_encrypt; |
95 | dat->stream.cbc = (dat->mode == EVP_CIPH_CBC_MODE) |
96 | ? (cbc128_f)vpaes_cbc_encrypt : NULL; |
97 | } else |
98 | #endif |
99 | { |
100 | ret = AES_set_encrypt_key(key, keylen * 8, ks); |
101 | dat->block = (block128_f)AES_encrypt; |
102 | dat->stream.cbc = (dat->mode == EVP_CIPH_CBC_MODE) |
103 | ? (cbc128_f)AES_cbc_encrypt : NULL; |
104 | #ifdef AES_CTR_ASM |
105 | if (dat->mode == EVP_CIPH_CTR_MODE) |
106 | dat->stream.ctr = (ctr128_f)AES_ctr32_encrypt; |
107 | #endif |
108 | } |
109 | |
110 | if (ret < 0) { |
111 | ERR_raise(ERR_LIB_PROV, PROV_R_AES_KEY_SETUP_FAILED); |
112 | return 0; |
113 | } |
114 | |
115 | return 1; |
116 | } |
117 | |
118 | IMPLEMENT_CIPHER_HW_COPYCTX(cipher_hw_aes_copyctx, PROV_AES_CTX) |
119 | |
120 | #define PROV_CIPHER_HW_aes_mode(mode) \ |
121 | static const PROV_CIPHER_HW aes_##mode = { \ |
122 | cipher_hw_aes_initkey, \ |
123 | cipher_hw_generic_##mode, \ |
124 | cipher_hw_aes_copyctx \ |
125 | }; \ |
126 | PROV_CIPHER_HW_declare(mode) \ |
127 | const PROV_CIPHER_HW *PROV_CIPHER_HW_aes_##mode(size_t keybits) \ |
128 | { \ |
129 | PROV_CIPHER_HW_select(mode) \ |
130 | return &aes_##mode; \ |
131 | } |
132 | |
133 | #if defined(AESNI_CAPABLE) |
134 | # include "cipher_aes_hw_aesni.inc" |
135 | #elif defined(SPARC_AES_CAPABLE) |
136 | # include "cipher_aes_hw_t4.inc" |
137 | #elif defined(S390X_aes_128_CAPABLE) |
138 | # include "cipher_aes_hw_s390x.inc" |
139 | #else |
140 | /* The generic case */ |
141 | # define PROV_CIPHER_HW_declare(mode) |
142 | # define PROV_CIPHER_HW_select(mode) |
143 | #endif |
144 | |
145 | PROV_CIPHER_HW_aes_mode(cbc) |
146 | PROV_CIPHER_HW_aes_mode(ecb) |
147 | PROV_CIPHER_HW_aes_mode(ofb128) |
148 | PROV_CIPHER_HW_aes_mode(cfb128) |
149 | PROV_CIPHER_HW_aes_mode(cfb1) |
150 | PROV_CIPHER_HW_aes_mode(cfb8) |
151 | PROV_CIPHER_HW_aes_mode(ctr) |
152 | |