nbt_server: Factor out packet generation for netlogon reply
[Samba.git] / lib / crypto / aes.c
blobc226ac1b3df26677e0ec3621103bcfaae737f450
1 /*
2 * Copyright (c) 2003 Kungliga Tekniska Högskolan
3 * (Royal Institute of Technology, Stockholm, Sweden).
4 * All rights reserved.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
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.
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.
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.
34 #include "replace.h"
35 #include "aes.h"
37 #ifdef SAMBA_RIJNDAEL
38 #include "rijndael-alg-fst.h"
40 #if defined(HAVE_AESNI_INTEL)
43 * NB. HAVE_AESNI_INTEL is only defined if -lang-asm is
44 * available.
47 static inline void __cpuid(unsigned int where[4], unsigned int leaf)
49 asm volatile("cpuid" :
50 "=a" (where[0]),
51 "=b" (where[1]),
52 "=c" (where[2]),
53 "=d" (where[3]): "a" (leaf));
57 * has_intel_aes_instructions()
58 * return true if supports AES-NI and false if doesn't
60 static bool has_intel_aes_instructions(void)
62 static int has_aes_instructions = -1;
63 unsigned int cpuid_results[4];
65 if (has_aes_instructions != -1) {
66 return (bool)has_aes_instructions;
69 __cpuid(cpuid_results, 0);
71 * MSB LSB
72 * EBX = 'u' 'n' 'e' 'G'
73 * EDX = 'I' 'e' 'n' 'i'
74 * ECX = 'l' 'e' 't' 'n'
76 if (memcmp((unsigned char *)&cpuid_results[1], "Genu", 4) != 0 ||
77 memcmp((unsigned char *)&cpuid_results[3],
78 "ineI", 4) != 0 ||
79 memcmp((unsigned char *)&cpuid_results[2],
80 "ntel", 4) != 0) {
81 has_aes_instructions = 0;
82 return (bool)has_aes_instructions;
85 __cpuid(cpuid_results, 1);
86 has_aes_instructions = !!(cpuid_results[2] & (1 << 25));
87 return (bool)has_aes_instructions;
91 * Macro to ensure the AES key schedule starts on a 16 byte boundary.
94 #define SET_ACC_CTX(k) \
95 do { \
96 (k)->u.aes_ni.acc_ctx = \
97 (struct crypto_aes_ctx *)(((unsigned long)(k)->u.aes_ni._acc_ctx + 15) & ~0xfUL); \
98 } while (0)
101 * The next 4 functions call the Intel AES hardware implementations
102 * of:
104 * AES_set_encrypt_key()
105 * AES_set_decrypt_key()
106 * AES_encrypt()
107 * AES_decrypt()
110 static int AES_set_encrypt_key_aesni(const unsigned char *userkey,
111 const int bits,
112 AES_KEY *key)
114 SET_ACC_CTX(key);
115 return aesni_set_key(key->u.aes_ni.acc_ctx, userkey, bits/8);
118 static int AES_set_decrypt_key_aesni(const unsigned char *userkey,
119 const int bits,
120 AES_KEY *key)
122 SET_ACC_CTX(key);
123 return aesni_set_key(key->u.aes_ni.acc_ctx, userkey, bits/8);
126 static void AES_encrypt_aesni(const unsigned char *in,
127 unsigned char *out,
128 const AES_KEY *key)
130 aesni_enc(key->u.aes_ni.acc_ctx, out, in);
133 static void AES_decrypt_aesni(const unsigned char *in,
134 unsigned char *out,
135 const AES_KEY *key)
137 aesni_dec(key->u.aes_ni.acc_ctx, out, in);
139 #else /* defined(HAVE_AESNI_INTEL) */
142 * Dummy implementations if no Intel AES instructions present.
143 * Only has_intel_aes_instructions() will ever be called.
146 static bool has_intel_aes_instructions(void)
148 return false;
151 static int AES_set_encrypt_key_aesni(const unsigned char *userkey,
152 const int bits,
153 AES_KEY *key)
155 return -1;
158 static int AES_set_decrypt_key_aesni(const unsigned char *userkey,
159 const int bits,
160 AES_KEY *key)
162 return -1;
165 static void AES_encrypt_aesni(const unsigned char *in,
166 unsigned char *out,
167 const AES_KEY *key)
169 abort();
172 static void AES_decrypt_aesni(const unsigned char *in,
173 unsigned char *out,
174 const AES_KEY *key)
176 abort();
178 #endif /* defined(HAVE_AENI_INTEL) */
181 * The next 4 functions are the pure software implementations
182 * of:
184 * AES_set_encrypt_key()
185 * AES_set_decrypt_key()
186 * AES_encrypt()
187 * AES_decrypt()
190 static int
191 AES_set_encrypt_key_rj(const unsigned char *userkey, const int bits, AES_KEY *key)
193 key->u.aes_rj.rounds = rijndaelKeySetupEnc(key->u.aes_rj.key, userkey, bits);
194 if (key->u.aes_rj.rounds == 0)
195 return -1;
196 return 0;
199 static int
200 AES_set_decrypt_key_rj(const unsigned char *userkey, const int bits, AES_KEY *key)
202 key->u.aes_rj.rounds = rijndaelKeySetupDec(key->u.aes_rj.key, userkey, bits);
203 if (key->u.aes_rj.rounds == 0)
204 return -1;
205 return 0;
208 static void
209 AES_encrypt_rj(const unsigned char *in, unsigned char *out, const AES_KEY *key)
211 rijndaelEncrypt(key->u.aes_rj.key, key->u.aes_rj.rounds, in, out);
214 static void
215 AES_decrypt_rj(const unsigned char *in, unsigned char *out, const AES_KEY *key)
217 rijndaelDecrypt(key->u.aes_rj.key, key->u.aes_rj.rounds, in, out);
221 * The next 4 functions are the runtime switch for Intel AES hardware
222 * implementations of:
224 * AES_set_encrypt_key()
225 * AES_set_decrypt_key()
226 * AES_encrypt()
227 * AES_decrypt()
229 * If the hardware instructions don't exist, fall back to the software
230 * versions.
234 AES_set_encrypt_key(const unsigned char *userkey, const int bits, AES_KEY *key)
236 if (has_intel_aes_instructions()) {
237 return AES_set_encrypt_key_aesni(userkey, bits, key);
239 return AES_set_encrypt_key_rj(userkey, bits, key);
243 AES_set_decrypt_key(const unsigned char *userkey, const int bits, AES_KEY *key)
245 if (has_intel_aes_instructions()) {
246 return AES_set_decrypt_key_aesni(userkey, bits, key);
248 return AES_set_decrypt_key_rj(userkey, bits, key);
251 void
252 AES_encrypt(const unsigned char *in, unsigned char *out, const AES_KEY *key)
254 if (has_intel_aes_instructions()) {
255 return AES_encrypt_aesni(in, out, key);
257 return AES_encrypt_rj(in, out, key);
260 void
261 AES_decrypt(const unsigned char *in, unsigned char *out, const AES_KEY *key)
263 if (has_intel_aes_instructions()) {
264 return AES_decrypt_aesni(in, out, key);
266 return AES_decrypt_rj(in, out, key);
269 #endif /* SAMBA_RIJNDAEL */
271 #ifdef SAMBA_AES_CBC_ENCRYPT
272 void
273 AES_cbc_encrypt(const unsigned char *in, unsigned char *out,
274 unsigned long size, const AES_KEY *key,
275 unsigned char *iv, int forward_encrypt)
277 unsigned char tmp[AES_BLOCK_SIZE];
278 int i;
280 if (forward_encrypt) {
281 while (size >= AES_BLOCK_SIZE) {
282 for (i = 0; i < AES_BLOCK_SIZE; i++)
283 tmp[i] = in[i] ^ iv[i];
284 AES_encrypt(tmp, out, key);
285 memcpy(iv, out, AES_BLOCK_SIZE);
286 size -= AES_BLOCK_SIZE;
287 in += AES_BLOCK_SIZE;
288 out += AES_BLOCK_SIZE;
290 if (size) {
291 for (i = 0; i < size; i++)
292 tmp[i] = in[i] ^ iv[i];
293 for (i = size; i < AES_BLOCK_SIZE; i++)
294 tmp[i] = iv[i];
295 AES_encrypt(tmp, out, key);
296 memcpy(iv, out, AES_BLOCK_SIZE);
298 } else {
299 while (size >= AES_BLOCK_SIZE) {
300 memcpy(tmp, in, AES_BLOCK_SIZE);
301 AES_decrypt(tmp, out, key);
302 for (i = 0; i < AES_BLOCK_SIZE; i++)
303 out[i] ^= iv[i];
304 memcpy(iv, tmp, AES_BLOCK_SIZE);
305 size -= AES_BLOCK_SIZE;
306 in += AES_BLOCK_SIZE;
307 out += AES_BLOCK_SIZE;
309 if (size) {
310 memcpy(tmp, in, AES_BLOCK_SIZE);
311 AES_decrypt(tmp, out, key);
312 for (i = 0; i < size; i++)
313 out[i] ^= iv[i];
314 memcpy(iv, tmp, AES_BLOCK_SIZE);
318 #endif /* SAMBA_AES_CBC_ENCRYPT */
320 #ifdef SAMBA_AES_CFB8_ENCRYPT
321 void
322 AES_cfb8_encrypt(const unsigned char *in, unsigned char *out,
323 unsigned long size, const AES_KEY *key,
324 unsigned char *iv, int forward_encrypt)
326 int i;
328 for (i = 0; i < size; i++) {
329 unsigned char tmp[AES_BLOCK_SIZE + 1];
331 memcpy(tmp, iv, AES_BLOCK_SIZE);
332 AES_encrypt(iv, iv, key);
333 if (!forward_encrypt) {
334 tmp[AES_BLOCK_SIZE] = in[i];
336 out[i] = in[i] ^ iv[0];
337 if (forward_encrypt) {
338 tmp[AES_BLOCK_SIZE] = out[i];
340 memcpy(iv, &tmp[1], AES_BLOCK_SIZE);
343 #endif /* SAMBA_AES_CFB8_ENCRYPT */