OpenCores
URL https://opencores.org/ocsvn/test_project/test_project/trunk

Subversion Repositories test_project

[/] [test_project/] [trunk/] [linux_sd_driver/] [crypto/] [aes_generic.c] - Blame information for rev 62

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 62 marcus.erl
/*
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
 */
70
static inline u8
71
byte(const u32 x, const unsigned n)
72
{
73
        return x >> (n << 3);
74
}
75
 
76
struct 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
 
84
static u8 pow_tab[256] __initdata;
85
static u8 log_tab[256] __initdata;
86
static u8 sbx_tab[256] __initdata;
87
static u8 isb_tab[256] __initdata;
88
static u32 rco_tab[10];
89
static u32 ft_tab[4][256];
90
static u32 it_tab[4][256];
91
 
92
static u32 fl_tab[4][256];
93
static u32 il_tab[4][256];
94
 
95
static inline u8 __init
96
f_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
 
135
static void __init
136
gen_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
 
251
static 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
 
322
static 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
 
377
static 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
 
419
static 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
 
440
static int __init aes_init(void)
441
{
442
        gen_tabs();
443
        return crypto_register_alg(&aes_alg);
444
}
445
 
446
static void __exit aes_fini(void)
447
{
448
        crypto_unregister_alg(&aes_alg);
449
}
450
 
451
module_init(aes_init);
452
module_exit(aes_fini);
453
 
454
MODULE_DESCRIPTION("Rijndael (AES) Cipher Algorithm");
455
MODULE_LICENSE("Dual BSD/GPL");
456
MODULE_ALIAS("aes");

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.