Line data Source code
1 : /*
2 : * Copyright (c) 2003 Kungliga Tekniska Högskolan
3 : * (Royal Institute of Technology, Stockholm, Sweden).
4 : * All rights reserved.
5 : *
6 : * Redistribution and use in source and binary forms, with or without
7 : * modification, are permitted provided that the following conditions
8 : * are met:
9 : *
10 : * 1. Redistributions of source code must retain the above copyright
11 : * notice, this list of conditions and the following disclaimer.
12 : *
13 : * 2. Redistributions in binary form must reproduce the above copyright
14 : * notice, this list of conditions and the following disclaimer in the
15 : * documentation and/or other materials provided with the distribution.
16 : *
17 : * 3. Neither the name of the Institute nor the names of its contributors
18 : * may be used to endorse or promote products derived from this software
19 : * without specific prior written permission.
20 : *
21 : * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
22 : * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 : * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 : * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
25 : * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 : * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 : * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 : * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 : * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 : * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 : * SUCH DAMAGE.
32 : */
33 :
34 : #include "replace.h"
35 : #include "aes.h"
36 :
37 : #ifdef SAMBA_RIJNDAEL
38 : #include "rijndael-alg-fst.h"
39 :
40 : #if defined(HAVE_AESNI_INTEL)
41 :
42 : /*
43 : * NB. HAVE_AESNI_INTEL is only defined if -lang-asm is
44 : * available.
45 : */
46 :
47 : static inline void __cpuid(unsigned int where[4], unsigned int leaf)
48 : {
49 : asm volatile("cpuid" :
50 : "=a" (where[0]),
51 : "=b" (where[1]),
52 : "=c" (where[2]),
53 : "=d" (where[3]): "a" (leaf));
54 : }
55 :
56 : /*
57 : * has_intel_aes_instructions()
58 : * return true if supports AES-NI and false if doesn't
59 : */
60 : static bool has_intel_aes_instructions(void)
61 : {
62 : static int has_aes_instructions = -1;
63 : unsigned int cpuid_results[4];
64 :
65 : if (has_aes_instructions != -1) {
66 : return (bool)has_aes_instructions;
67 : }
68 :
69 : __cpuid(cpuid_results, 1);
70 : has_aes_instructions = !!(cpuid_results[2] & (1 << 25));
71 : return (bool)has_aes_instructions;
72 : }
73 :
74 : /*
75 : * Macro to ensure the AES key schedule starts on a 16 byte boundary.
76 : */
77 :
78 : #define SET_ACC_CTX(k) \
79 : do { \
80 : (k)->u.aes_ni.acc_ctx = \
81 : (struct crypto_aes_ctx *)(((unsigned long)(k)->u.aes_ni._acc_ctx + 15) & ~0xfUL); \
82 : } while (0)
83 :
84 : /*
85 : * The next 4 functions call the Intel AES hardware implementations
86 : * of:
87 : *
88 : * AES_set_encrypt_key()
89 : * AES_set_decrypt_key()
90 : * AES_encrypt()
91 : * AES_decrypt()
92 : */
93 :
94 : static int AES_set_encrypt_key_aesni(const unsigned char *userkey,
95 : const int bits,
96 : AES_KEY *key)
97 : {
98 : SET_ACC_CTX(key);
99 : return aesni_set_key(key->u.aes_ni.acc_ctx, userkey, bits/8);
100 : }
101 :
102 : static int AES_set_decrypt_key_aesni(const unsigned char *userkey,
103 : const int bits,
104 : AES_KEY *key)
105 : {
106 : SET_ACC_CTX(key);
107 : return aesni_set_key(key->u.aes_ni.acc_ctx, userkey, bits/8);
108 : }
109 :
110 : static void AES_encrypt_aesni(const unsigned char *in,
111 : unsigned char *out,
112 : const AES_KEY *key)
113 : {
114 : aesni_enc(key->u.aes_ni.acc_ctx, out, in);
115 : }
116 :
117 : static void AES_decrypt_aesni(const unsigned char *in,
118 : unsigned char *out,
119 : const AES_KEY *key)
120 : {
121 : aesni_dec(key->u.aes_ni.acc_ctx, out, in);
122 : }
123 : #else /* defined(HAVE_AESNI_INTEL) */
124 :
125 : /*
126 : * Dummy implementations if no Intel AES instructions present.
127 : * Only has_intel_aes_instructions() will ever be called.
128 : */
129 :
130 5493048 : static bool has_intel_aes_instructions(void)
131 : {
132 5493048 : return false;
133 : }
134 :
135 0 : static int AES_set_encrypt_key_aesni(const unsigned char *userkey,
136 : const int bits,
137 : AES_KEY *key)
138 : {
139 0 : return -1;
140 : }
141 :
142 0 : static int AES_set_decrypt_key_aesni(const unsigned char *userkey,
143 : const int bits,
144 : AES_KEY *key)
145 : {
146 0 : return -1;
147 : }
148 :
149 0 : static void AES_encrypt_aesni(const unsigned char *in,
150 : unsigned char *out,
151 : const AES_KEY *key)
152 : {
153 0 : abort();
154 : }
155 :
156 0 : static void AES_decrypt_aesni(const unsigned char *in,
157 : unsigned char *out,
158 : const AES_KEY *key)
159 : {
160 0 : abort();
161 : }
162 : #endif /* defined(HAVE_AENI_INTEL) */
163 :
164 : /*
165 : * The next 4 functions are the pure software implementations
166 : * of:
167 : *
168 : * AES_set_encrypt_key()
169 : * AES_set_decrypt_key()
170 : * AES_encrypt()
171 : * AES_decrypt()
172 : */
173 :
174 : static int
175 63654 : AES_set_encrypt_key_rj(const unsigned char *userkey, const int bits, AES_KEY *key)
176 : {
177 63654 : key->u.aes_rj.rounds = rijndaelKeySetupEnc(key->u.aes_rj.key, userkey, bits);
178 63654 : if (key->u.aes_rj.rounds == 0)
179 0 : return -1;
180 63654 : return 0;
181 : }
182 :
183 : static int
184 0 : AES_set_decrypt_key_rj(const unsigned char *userkey, const int bits, AES_KEY *key)
185 : {
186 0 : key->u.aes_rj.rounds = rijndaelKeySetupDec(key->u.aes_rj.key, userkey, bits);
187 0 : if (key->u.aes_rj.rounds == 0)
188 0 : return -1;
189 0 : return 0;
190 : }
191 :
192 : static void
193 5429394 : AES_encrypt_rj(const unsigned char *in, unsigned char *out, const AES_KEY *key)
194 : {
195 5429394 : rijndaelEncrypt(key->u.aes_rj.key, key->u.aes_rj.rounds, in, out);
196 5429394 : }
197 :
198 : static void
199 0 : AES_decrypt_rj(const unsigned char *in, unsigned char *out, const AES_KEY *key)
200 : {
201 0 : rijndaelDecrypt(key->u.aes_rj.key, key->u.aes_rj.rounds, in, out);
202 0 : }
203 :
204 : /*
205 : * The next 4 functions are the runtime switch for Intel AES hardware
206 : * implementations of:
207 : *
208 : * AES_set_encrypt_key()
209 : * AES_set_decrypt_key()
210 : * AES_encrypt()
211 : * AES_decrypt()
212 : *
213 : * If the hardware instructions don't exist, fall back to the software
214 : * versions.
215 : */
216 :
217 : int
218 63654 : AES_set_encrypt_key(const unsigned char *userkey, const int bits, AES_KEY *key)
219 : {
220 63654 : if (has_intel_aes_instructions()) {
221 0 : return AES_set_encrypt_key_aesni(userkey, bits, key);
222 : }
223 63654 : return AES_set_encrypt_key_rj(userkey, bits, key);
224 : }
225 :
226 : int
227 0 : AES_set_decrypt_key(const unsigned char *userkey, const int bits, AES_KEY *key)
228 : {
229 0 : if (has_intel_aes_instructions()) {
230 0 : return AES_set_decrypt_key_aesni(userkey, bits, key);
231 : }
232 0 : return AES_set_decrypt_key_rj(userkey, bits, key);
233 : }
234 :
235 : void
236 5429394 : AES_encrypt(const unsigned char *in, unsigned char *out, const AES_KEY *key)
237 : {
238 5429394 : if (has_intel_aes_instructions()) {
239 0 : AES_encrypt_aesni(in, out, key);
240 0 : return;
241 : }
242 5429394 : AES_encrypt_rj(in, out, key);
243 : }
244 :
245 : void
246 0 : AES_decrypt(const unsigned char *in, unsigned char *out, const AES_KEY *key)
247 : {
248 0 : if (has_intel_aes_instructions()) {
249 0 : AES_decrypt_aesni(in, out, key);
250 0 : return;
251 : }
252 0 : AES_decrypt_rj(in, out, key);
253 : }
254 :
255 : #endif /* SAMBA_RIJNDAEL */
256 :
257 : #ifdef SAMBA_AES_CBC_ENCRYPT
258 : void
259 0 : AES_cbc_encrypt(const unsigned char *in, unsigned char *out,
260 : unsigned long size, const AES_KEY *key,
261 : unsigned char *iv, int forward_encrypt)
262 : {
263 : unsigned char tmp[AES_BLOCK_SIZE];
264 : int i;
265 :
266 0 : if (forward_encrypt) {
267 0 : while (size >= AES_BLOCK_SIZE) {
268 0 : for (i = 0; i < AES_BLOCK_SIZE; i++)
269 0 : tmp[i] = in[i] ^ iv[i];
270 0 : AES_encrypt(tmp, out, key);
271 0 : memcpy(iv, out, AES_BLOCK_SIZE);
272 0 : size -= AES_BLOCK_SIZE;
273 0 : in += AES_BLOCK_SIZE;
274 0 : out += AES_BLOCK_SIZE;
275 : }
276 0 : if (size) {
277 0 : for (i = 0; i < size; i++)
278 0 : tmp[i] = in[i] ^ iv[i];
279 0 : for (i = size; i < AES_BLOCK_SIZE; i++)
280 0 : tmp[i] = iv[i];
281 0 : AES_encrypt(tmp, out, key);
282 0 : memcpy(iv, out, AES_BLOCK_SIZE);
283 : }
284 : } else {
285 0 : while (size >= AES_BLOCK_SIZE) {
286 0 : memcpy(tmp, in, AES_BLOCK_SIZE);
287 0 : AES_decrypt(tmp, out, key);
288 0 : for (i = 0; i < AES_BLOCK_SIZE; i++)
289 0 : out[i] ^= iv[i];
290 0 : memcpy(iv, tmp, AES_BLOCK_SIZE);
291 0 : size -= AES_BLOCK_SIZE;
292 0 : in += AES_BLOCK_SIZE;
293 0 : out += AES_BLOCK_SIZE;
294 : }
295 0 : if (size) {
296 0 : memcpy(tmp, in, AES_BLOCK_SIZE);
297 0 : AES_decrypt(tmp, out, key);
298 0 : for (i = 0; i < size; i++)
299 0 : out[i] ^= iv[i];
300 0 : memcpy(iv, tmp, AES_BLOCK_SIZE);
301 : }
302 : }
303 0 : }
304 : #endif /* SAMBA_AES_CBC_ENCRYPT */
305 :
306 : #ifdef SAMBA_AES_CFB8_ENCRYPT
307 : void
308 78259 : AES_cfb8_encrypt(const unsigned char *in, unsigned char *out,
309 : unsigned long size, const AES_KEY *key,
310 : unsigned char *iv, int forward_encrypt)
311 : {
312 : int i;
313 :
314 5497255 : for (i = 0; i < size; i++) {
315 : unsigned char tmp[AES_BLOCK_SIZE + 1];
316 :
317 5418996 : memcpy(tmp, iv, AES_BLOCK_SIZE);
318 5418996 : AES_encrypt(iv, iv, key);
319 5418996 : if (!forward_encrypt) {
320 2505396 : tmp[AES_BLOCK_SIZE] = in[i];
321 : }
322 5418996 : out[i] = in[i] ^ iv[0];
323 5418996 : if (forward_encrypt) {
324 2913600 : tmp[AES_BLOCK_SIZE] = out[i];
325 : }
326 5418996 : memcpy(iv, &tmp[1], AES_BLOCK_SIZE);
327 : }
328 78259 : }
329 : #endif /* SAMBA_AES_CFB8_ENCRYPT */
|