lib:replace: Add getprogname()
[samba.git] / lib / crypto / aes.c
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 static bool has_intel_aes_instructions(void)
131 {
132         return false;
133 }
134
135 static int AES_set_encrypt_key_aesni(const unsigned char *userkey,
136                                 const int bits,
137                                 AES_KEY *key)
138 {
139         return -1;
140 }
141
142 static int AES_set_decrypt_key_aesni(const unsigned char *userkey,
143                                 const int bits,
144                                 AES_KEY *key)
145 {
146         return -1;
147 }
148
149 static void AES_encrypt_aesni(const unsigned char *in,
150                                 unsigned char *out,
151                                 const AES_KEY *key)
152 {
153         abort();
154 }
155
156 static void AES_decrypt_aesni(const unsigned char *in,
157                                 unsigned char *out,
158                                 const AES_KEY *key)
159 {
160         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 AES_set_encrypt_key_rj(const unsigned char *userkey, const int bits, AES_KEY *key)
176 {
177     key->u.aes_rj.rounds = rijndaelKeySetupEnc(key->u.aes_rj.key, userkey, bits);
178     if (key->u.aes_rj.rounds == 0)
179         return -1;
180     return 0;
181 }
182
183 static int
184 AES_set_decrypt_key_rj(const unsigned char *userkey, const int bits, AES_KEY *key)
185 {
186     key->u.aes_rj.rounds = rijndaelKeySetupDec(key->u.aes_rj.key, userkey, bits);
187     if (key->u.aes_rj.rounds == 0)
188         return -1;
189     return 0;
190 }
191
192 static void
193 AES_encrypt_rj(const unsigned char *in, unsigned char *out, const AES_KEY *key)
194 {
195     rijndaelEncrypt(key->u.aes_rj.key, key->u.aes_rj.rounds, in, out);
196 }
197
198 static void
199 AES_decrypt_rj(const unsigned char *in, unsigned char *out, const AES_KEY *key)
200 {
201     rijndaelDecrypt(key->u.aes_rj.key, key->u.aes_rj.rounds, in, out);
202 }
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 AES_set_encrypt_key(const unsigned char *userkey, const int bits, AES_KEY *key)
219 {
220         if (has_intel_aes_instructions()) {
221                 return AES_set_encrypt_key_aesni(userkey, bits, key);
222         }
223         return AES_set_encrypt_key_rj(userkey, bits, key);
224 }
225
226 int
227 AES_set_decrypt_key(const unsigned char *userkey, const int bits, AES_KEY *key)
228 {
229         if (has_intel_aes_instructions()) {
230                 return AES_set_decrypt_key_aesni(userkey, bits, key);
231         }
232         return AES_set_decrypt_key_rj(userkey, bits, key);
233 }
234
235 void
236 AES_encrypt(const unsigned char *in, unsigned char *out, const AES_KEY *key)
237 {
238         if (has_intel_aes_instructions()) {
239                 AES_encrypt_aesni(in, out, key);
240                 return;
241         }
242         AES_encrypt_rj(in, out, key);
243 }
244
245 void
246 AES_decrypt(const unsigned char *in, unsigned char *out, const AES_KEY *key)
247 {
248         if (has_intel_aes_instructions()) {
249                 AES_decrypt_aesni(in, out, key);
250                 return;
251         }
252         AES_decrypt_rj(in, out, key);
253 }
254
255 #endif /* SAMBA_RIJNDAEL */
256
257 #ifdef SAMBA_AES_CBC_ENCRYPT
258 void
259 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     if (forward_encrypt) {
267         while (size >= AES_BLOCK_SIZE) {
268             for (i = 0; i < AES_BLOCK_SIZE; i++)
269                 tmp[i] = in[i] ^ iv[i];
270             AES_encrypt(tmp, out, key);
271             memcpy(iv, out, AES_BLOCK_SIZE);
272             size -= AES_BLOCK_SIZE;
273             in += AES_BLOCK_SIZE;
274             out += AES_BLOCK_SIZE;
275         }
276         if (size) {
277             for (i = 0; i < size; i++)
278                 tmp[i] = in[i] ^ iv[i];
279             for (i = size; i < AES_BLOCK_SIZE; i++)
280                 tmp[i] = iv[i];
281             AES_encrypt(tmp, out, key);
282             memcpy(iv, out, AES_BLOCK_SIZE);
283         }
284     } else {
285         while (size >= AES_BLOCK_SIZE) {
286             memcpy(tmp, in, AES_BLOCK_SIZE);
287             AES_decrypt(tmp, out, key);
288             for (i = 0; i < AES_BLOCK_SIZE; i++)
289                 out[i] ^= iv[i];
290             memcpy(iv, tmp, AES_BLOCK_SIZE);
291             size -= AES_BLOCK_SIZE;
292             in += AES_BLOCK_SIZE;
293             out += AES_BLOCK_SIZE;
294         }
295         if (size) {
296             memcpy(tmp, in, AES_BLOCK_SIZE);
297             AES_decrypt(tmp, out, key);
298             for (i = 0; i < size; i++)
299                 out[i] ^= iv[i];
300             memcpy(iv, tmp, AES_BLOCK_SIZE);
301         }
302     }
303 }
304 #endif /* SAMBA_AES_CBC_ENCRYPT */
305
306 #ifdef SAMBA_AES_CFB8_ENCRYPT
307 void
308 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     for (i = 0; i < size; i++) {
315         unsigned char tmp[AES_BLOCK_SIZE + 1];
316
317         memcpy(tmp, iv, AES_BLOCK_SIZE);
318         AES_encrypt(iv, iv, key);
319         if (!forward_encrypt) {
320             tmp[AES_BLOCK_SIZE] = in[i];
321         }
322         out[i] = in[i] ^ iv[0];
323         if (forward_encrypt) {
324             tmp[AES_BLOCK_SIZE] = out[i];
325         }
326         memcpy(iv, &tmp[1], AES_BLOCK_SIZE);
327     }
328 }
329 #endif /* SAMBA_AES_CFB8_ENCRYPT */