aboutsummaryrefslogtreecommitdiffstats
path: root/crypto/aes_generic.c
diff options
context:
space:
mode:
authorSebastian Siewior <sebastian@breakpoint.cc>2007-10-05 04:52:01 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2007-10-10 19:55:49 -0400
commitf8246af005d56b73f4f04304fc5b6fd9878af4ef (patch)
treed935971920749a7e99b7224e413b110a3ba07b10 /crypto/aes_generic.c
parentc5a511f1cd6f90a98ad11dd97e2313c7c787deb2 (diff)
[CRYPTO] aes: Rename aes to aes-generic
Loading the crypto algorithm by the alias instead of by module directly has the advantage that all possible implementations of this algorithm are loaded automatically and the crypto API can choose the best one depending on its priority. Additionally it ensures that the generic implementation as well as the HW driver (if available) is loaded in case the HW driver needs the generic version as fallback in corner cases. Signed-off-by: Sebastian Siewior <sebastian@breakpoint.cc> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Diffstat (limited to 'crypto/aes_generic.c')
-rw-r--r--crypto/aes_generic.c456
1 files changed, 456 insertions, 0 deletions
diff --git a/crypto/aes_generic.c b/crypto/aes_generic.c
new file mode 100644
index 000000000000..9401dca85e87
--- /dev/null
+++ b/crypto/aes_generic.c
@@ -0,0 +1,456 @@
1/*
2 * Cryptographic API.
3 *
4 * AES Cipher Algorithm.
5 *
6 * Based on Brian Gladman's code.
7 *
8 * Linux developers:
9 * Alexander Kjeldaas <astor@fast.no>
10 * Herbert Valerio Riedel <hvr@hvrlab.org>
11 * Kyle McMartin <kyle@debian.org>
12 * Adam J. Richter <adam@yggdrasil.com> (conversion to 2.5 API).
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
18 *
19 * ---------------------------------------------------------------------------
20 * Copyright (c) 2002, Dr Brian Gladman <brg@gladman.me.uk>, Worcester, UK.
21 * All rights reserved.
22 *
23 * LICENSE TERMS
24 *
25 * The free distribution and use of this software in both source and binary
26 * form is allowed (with or without changes) provided that:
27 *
28 * 1. distributions of this source code include the above copyright
29 * notice, this list of conditions and the following disclaimer;
30 *
31 * 2. distributions in binary form include the above copyright
32 * notice, this list of conditions and the following disclaimer
33 * in the documentation and/or other associated materials;
34 *
35 * 3. the copyright holder's name is not used to endorse products
36 * built using this software without specific written permission.
37 *
38 * ALTERNATIVELY, provided that this notice is retained in full, this product
39 * may be distributed under the terms of the GNU General Public License (GPL),
40 * in which case the provisions of the GPL apply INSTEAD OF those given above.
41 *
42 * DISCLAIMER
43 *
44 * This software is provided 'as is' with no explicit or implied warranties
45 * in respect of its properties, including, but not limited to, correctness
46 * and/or fitness for purpose.
47 * ---------------------------------------------------------------------------
48 */
49
50/* Some changes from the Gladman version:
51 s/RIJNDAEL(e_key)/E_KEY/g
52 s/RIJNDAEL(d_key)/D_KEY/g
53*/
54
55#include <linux/module.h>
56#include <linux/init.h>
57#include <linux/types.h>
58#include <linux/errno.h>
59#include <linux/crypto.h>
60#include <asm/byteorder.h>
61
62#define AES_MIN_KEY_SIZE 16
63#define AES_MAX_KEY_SIZE 32
64
65#define AES_BLOCK_SIZE 16
66
67/*
68 * #define byte(x, nr) ((unsigned char)((x) >> (nr*8)))
69 */
70static inline u8
71byte(const u32 x, const unsigned n)
72{
73 return x >> (n << 3);
74}
75
76struct aes_ctx {
77 int key_length;
78 u32 buf[120];
79};
80
81#define E_KEY (&ctx->buf[0])
82#define D_KEY (&ctx->buf[60])
83
84static u8 pow_tab[256] __initdata;
85static u8 log_tab[256] __initdata;
86static u8 sbx_tab[256] __initdata;
87static u8 isb_tab[256] __initdata;
88static u32 rco_tab[10];
89static u32 ft_tab[4][256];
90static u32 it_tab[4][256];
91
92static u32 fl_tab[4][256];
93static u32 il_tab[4][256];
94
95static inline u8 __init
96f_mult (u8 a, u8 b)
97{
98 u8 aa = log_tab[a], cc = aa + log_tab[b];
99
100 return pow_tab[cc + (cc < aa ? 1 : 0)];
101}
102
103#define ff_mult(a,b) (a && b ? f_mult(a, b) : 0)
104
105#define f_rn(bo, bi, n, k) \
106 bo[n] = ft_tab[0][byte(bi[n],0)] ^ \
107 ft_tab[1][byte(bi[(n + 1) & 3],1)] ^ \
108 ft_tab[2][byte(bi[(n + 2) & 3],2)] ^ \
109 ft_tab[3][byte(bi[(n + 3) & 3],3)] ^ *(k + n)
110
111#define i_rn(bo, bi, n, k) \
112 bo[n] = it_tab[0][byte(bi[n],0)] ^ \
113 it_tab[1][byte(bi[(n + 3) & 3],1)] ^ \
114 it_tab[2][byte(bi[(n + 2) & 3],2)] ^ \
115 it_tab[3][byte(bi[(n + 1) & 3],3)] ^ *(k + n)
116
117#define ls_box(x) \
118 ( fl_tab[0][byte(x, 0)] ^ \
119 fl_tab[1][byte(x, 1)] ^ \
120 fl_tab[2][byte(x, 2)] ^ \
121 fl_tab[3][byte(x, 3)] )
122
123#define f_rl(bo, bi, n, k) \
124 bo[n] = fl_tab[0][byte(bi[n],0)] ^ \
125 fl_tab[1][byte(bi[(n + 1) & 3],1)] ^ \
126 fl_tab[2][byte(bi[(n + 2) & 3],2)] ^ \
127 fl_tab[3][byte(bi[(n + 3) & 3],3)] ^ *(k + n)
128
129#define i_rl(bo, bi, n, k) \
130 bo[n] = il_tab[0][byte(bi[n],0)] ^ \
131 il_tab[1][byte(bi[(n + 3) & 3],1)] ^ \
132 il_tab[2][byte(bi[(n + 2) & 3],2)] ^ \
133 il_tab[3][byte(bi[(n + 1) & 3],3)] ^ *(k + n)
134
135static void __init
136gen_tabs (void)
137{
138 u32 i, t;
139 u8 p, q;
140
141 /* log and power tables for GF(2**8) finite field with
142 0x011b as modular polynomial - the simplest primitive
143 root is 0x03, used here to generate the tables */
144
145 for (i = 0, p = 1; i < 256; ++i) {
146 pow_tab[i] = (u8) p;
147 log_tab[p] = (u8) i;
148
149 p ^= (p << 1) ^ (p & 0x80 ? 0x01b : 0);
150 }
151
152 log_tab[1] = 0;
153
154 for (i = 0, p = 1; i < 10; ++i) {
155 rco_tab[i] = p;
156
157 p = (p << 1) ^ (p & 0x80 ? 0x01b : 0);
158 }
159
160 for (i = 0; i < 256; ++i) {
161 p = (i ? pow_tab[255 - log_tab[i]] : 0);
162 q = ((p >> 7) | (p << 1)) ^ ((p >> 6) | (p << 2));
163 p ^= 0x63 ^ q ^ ((q >> 6) | (q << 2));
164 sbx_tab[i] = p;
165 isb_tab[p] = (u8) i;
166 }
167
168 for (i = 0; i < 256; ++i) {
169 p = sbx_tab[i];
170
171 t = p;
172 fl_tab[0][i] = t;
173 fl_tab[1][i] = rol32(t, 8);
174 fl_tab[2][i] = rol32(t, 16);
175 fl_tab[3][i] = rol32(t, 24);
176
177 t = ((u32) ff_mult (2, p)) |
178 ((u32) p << 8) |
179 ((u32) p << 16) | ((u32) ff_mult (3, p) << 24);
180
181 ft_tab[0][i] = t;
182 ft_tab[1][i] = rol32(t, 8);
183 ft_tab[2][i] = rol32(t, 16);
184 ft_tab[3][i] = rol32(t, 24);
185
186 p = isb_tab[i];
187
188 t = p;
189 il_tab[0][i] = t;
190 il_tab[1][i] = rol32(t, 8);
191 il_tab[2][i] = rol32(t, 16);
192 il_tab[3][i] = rol32(t, 24);
193
194 t = ((u32) ff_mult (14, p)) |
195 ((u32) ff_mult (9, p) << 8) |
196 ((u32) ff_mult (13, p) << 16) |
197 ((u32) ff_mult (11, p) << 24);
198
199 it_tab[0][i] = t;
200 it_tab[1][i] = rol32(t, 8);
201 it_tab[2][i] = rol32(t, 16);
202 it_tab[3][i] = rol32(t, 24);
203 }
204}
205
206#define star_x(x) (((x) & 0x7f7f7f7f) << 1) ^ ((((x) & 0x80808080) >> 7) * 0x1b)
207
208#define imix_col(y,x) \
209 u = star_x(x); \
210 v = star_x(u); \
211 w = star_x(v); \
212 t = w ^ (x); \
213 (y) = u ^ v ^ w; \
214 (y) ^= ror32(u ^ t, 8) ^ \
215 ror32(v ^ t, 16) ^ \
216 ror32(t,24)
217
218/* initialise the key schedule from the user supplied key */
219
220#define loop4(i) \
221{ t = ror32(t, 8); t = ls_box(t) ^ rco_tab[i]; \
222 t ^= E_KEY[4 * i]; E_KEY[4 * i + 4] = t; \
223 t ^= E_KEY[4 * i + 1]; E_KEY[4 * i + 5] = t; \
224 t ^= E_KEY[4 * i + 2]; E_KEY[4 * i + 6] = t; \
225 t ^= E_KEY[4 * i + 3]; E_KEY[4 * i + 7] = t; \
226}
227
228#define loop6(i) \
229{ t = ror32(t, 8); t = ls_box(t) ^ rco_tab[i]; \
230 t ^= E_KEY[6 * i]; E_KEY[6 * i + 6] = t; \
231 t ^= E_KEY[6 * i + 1]; E_KEY[6 * i + 7] = t; \
232 t ^= E_KEY[6 * i + 2]; E_KEY[6 * i + 8] = t; \
233 t ^= E_KEY[6 * i + 3]; E_KEY[6 * i + 9] = t; \
234 t ^= E_KEY[6 * i + 4]; E_KEY[6 * i + 10] = t; \
235 t ^= E_KEY[6 * i + 5]; E_KEY[6 * i + 11] = t; \
236}
237
238#define loop8(i) \
239{ t = ror32(t, 8); ; t = ls_box(t) ^ rco_tab[i]; \
240 t ^= E_KEY[8 * i]; E_KEY[8 * i + 8] = t; \
241 t ^= E_KEY[8 * i + 1]; E_KEY[8 * i + 9] = t; \
242 t ^= E_KEY[8 * i + 2]; E_KEY[8 * i + 10] = t; \
243 t ^= E_KEY[8 * i + 3]; E_KEY[8 * i + 11] = t; \
244 t = E_KEY[8 * i + 4] ^ ls_box(t); \
245 E_KEY[8 * i + 12] = t; \
246 t ^= E_KEY[8 * i + 5]; E_KEY[8 * i + 13] = t; \
247 t ^= E_KEY[8 * i + 6]; E_KEY[8 * i + 14] = t; \
248 t ^= E_KEY[8 * i + 7]; E_KEY[8 * i + 15] = t; \
249}
250
251static int aes_set_key(struct crypto_tfm *tfm, const u8 *in_key,
252 unsigned int key_len)
253{
254 struct aes_ctx *ctx = crypto_tfm_ctx(tfm);
255 const __le32 *key = (const __le32 *)in_key;
256 u32 *flags = &tfm->crt_flags;
257 u32 i, t, u, v, w;
258
259 if (key_len % 8) {
260 *flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
261 return -EINVAL;
262 }
263
264 ctx->key_length = key_len;
265
266 E_KEY[0] = le32_to_cpu(key[0]);
267 E_KEY[1] = le32_to_cpu(key[1]);
268 E_KEY[2] = le32_to_cpu(key[2]);
269 E_KEY[3] = le32_to_cpu(key[3]);
270
271 switch (key_len) {
272 case 16:
273 t = E_KEY[3];
274 for (i = 0; i < 10; ++i)
275 loop4 (i);
276 break;
277
278 case 24:
279 E_KEY[4] = le32_to_cpu(key[4]);
280 t = E_KEY[5] = le32_to_cpu(key[5]);
281 for (i = 0; i < 8; ++i)
282 loop6 (i);
283 break;
284
285 case 32:
286 E_KEY[4] = le32_to_cpu(key[4]);
287 E_KEY[5] = le32_to_cpu(key[5]);
288 E_KEY[6] = le32_to_cpu(key[6]);
289 t = E_KEY[7] = le32_to_cpu(key[7]);
290 for (i = 0; i < 7; ++i)
291 loop8 (i);
292 break;
293 }
294
295 D_KEY[0] = E_KEY[0];
296 D_KEY[1] = E_KEY[1];
297 D_KEY[2] = E_KEY[2];
298 D_KEY[3] = E_KEY[3];
299
300 for (i = 4; i < key_len + 24; ++i) {
301 imix_col (D_KEY[i], E_KEY[i]);
302 }
303
304 return 0;
305}
306
307/* encrypt a block of text */
308
309#define f_nround(bo, bi, k) \
310 f_rn(bo, bi, 0, k); \
311 f_rn(bo, bi, 1, k); \
312 f_rn(bo, bi, 2, k); \
313 f_rn(bo, bi, 3, k); \
314 k += 4
315
316#define f_lround(bo, bi, k) \
317 f_rl(bo, bi, 0, k); \
318 f_rl(bo, bi, 1, k); \
319 f_rl(bo, bi, 2, k); \
320 f_rl(bo, bi, 3, k)
321
322static void aes_encrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in)
323{
324 const struct aes_ctx *ctx = crypto_tfm_ctx(tfm);
325 const __le32 *src = (const __le32 *)in;
326 __le32 *dst = (__le32 *)out;
327 u32 b0[4], b1[4];
328 const u32 *kp = E_KEY + 4;
329
330 b0[0] = le32_to_cpu(src[0]) ^ E_KEY[0];
331 b0[1] = le32_to_cpu(src[1]) ^ E_KEY[1];
332 b0[2] = le32_to_cpu(src[2]) ^ E_KEY[2];
333 b0[3] = le32_to_cpu(src[3]) ^ E_KEY[3];
334
335 if (ctx->key_length > 24) {
336 f_nround (b1, b0, kp);
337 f_nround (b0, b1, kp);
338 }
339
340 if (ctx->key_length > 16) {
341 f_nround (b1, b0, kp);
342 f_nround (b0, b1, kp);
343 }
344
345 f_nround (b1, b0, kp);
346 f_nround (b0, b1, kp);
347 f_nround (b1, b0, kp);
348 f_nround (b0, b1, kp);
349 f_nround (b1, b0, kp);
350 f_nround (b0, b1, kp);
351 f_nround (b1, b0, kp);
352 f_nround (b0, b1, kp);
353 f_nround (b1, b0, kp);
354 f_lround (b0, b1, kp);
355
356 dst[0] = cpu_to_le32(b0[0]);
357 dst[1] = cpu_to_le32(b0[1]);
358 dst[2] = cpu_to_le32(b0[2]);
359 dst[3] = cpu_to_le32(b0[3]);
360}
361
362/* decrypt a block of text */
363
364#define i_nround(bo, bi, k) \
365 i_rn(bo, bi, 0, k); \
366 i_rn(bo, bi, 1, k); \
367 i_rn(bo, bi, 2, k); \
368 i_rn(bo, bi, 3, k); \
369 k -= 4
370
371#define i_lround(bo, bi, k) \
372 i_rl(bo, bi, 0, k); \
373 i_rl(bo, bi, 1, k); \
374 i_rl(bo, bi, 2, k); \
375 i_rl(bo, bi, 3, k)
376
377static void aes_decrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in)
378{
379 const struct aes_ctx *ctx = crypto_tfm_ctx(tfm);
380 const __le32 *src = (const __le32 *)in;
381 __le32 *dst = (__le32 *)out;
382 u32 b0[4], b1[4];
383 const int key_len = ctx->key_length;
384 const u32 *kp = D_KEY + key_len + 20;
385
386 b0[0] = le32_to_cpu(src[0]) ^ E_KEY[key_len + 24];
387 b0[1] = le32_to_cpu(src[1]) ^ E_KEY[key_len + 25];
388 b0[2] = le32_to_cpu(src[2]) ^ E_KEY[key_len + 26];
389 b0[3] = le32_to_cpu(src[3]) ^ E_KEY[key_len + 27];
390
391 if (key_len > 24) {
392 i_nround (b1, b0, kp);
393 i_nround (b0, b1, kp);
394 }
395
396 if (key_len > 16) {
397 i_nround (b1, b0, kp);
398 i_nround (b0, b1, kp);
399 }
400
401 i_nround (b1, b0, kp);
402 i_nround (b0, b1, kp);
403 i_nround (b1, b0, kp);
404 i_nround (b0, b1, kp);
405 i_nround (b1, b0, kp);
406 i_nround (b0, b1, kp);
407 i_nround (b1, b0, kp);
408 i_nround (b0, b1, kp);
409 i_nround (b1, b0, kp);
410 i_lround (b0, b1, kp);
411
412 dst[0] = cpu_to_le32(b0[0]);
413 dst[1] = cpu_to_le32(b0[1]);
414 dst[2] = cpu_to_le32(b0[2]);
415 dst[3] = cpu_to_le32(b0[3]);
416}
417
418
419static struct crypto_alg aes_alg = {
420 .cra_name = "aes",
421 .cra_driver_name = "aes-generic",
422 .cra_priority = 100,
423 .cra_flags = CRYPTO_ALG_TYPE_CIPHER,
424 .cra_blocksize = AES_BLOCK_SIZE,
425 .cra_ctxsize = sizeof(struct aes_ctx),
426 .cra_alignmask = 3,
427 .cra_module = THIS_MODULE,
428 .cra_list = LIST_HEAD_INIT(aes_alg.cra_list),
429 .cra_u = {
430 .cipher = {
431 .cia_min_keysize = AES_MIN_KEY_SIZE,
432 .cia_max_keysize = AES_MAX_KEY_SIZE,
433 .cia_setkey = aes_set_key,
434 .cia_encrypt = aes_encrypt,
435 .cia_decrypt = aes_decrypt
436 }
437 }
438};
439
440static int __init aes_init(void)
441{
442 gen_tabs();
443 return crypto_register_alg(&aes_alg);
444}
445
446static void __exit aes_fini(void)
447{
448 crypto_unregister_alg(&aes_alg);
449}
450
451module_init(aes_init);
452module_exit(aes_fini);
453
454MODULE_DESCRIPTION("Rijndael (AES) Cipher Algorithm");
455MODULE_LICENSE("Dual BSD/GPL");
456MODULE_ALIAS("aes");