1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
| /*
| * AES (Rijndael) cipher - encrypt
| *
| * Modifications to public domain implementation:
| * - cleanup
| * - use C pre-processor to make it easier to change S table access
| * - added option (AES_SMALL_TABLES) for reducing code size by about 8 kB at
| * cost of reduced throughput (quite small difference on Pentium 4,
| * 10-25% when using -O1 or -O2 optimization)
| *
| * Copyright (c) 2003-2012, Jouni Malinen <j@w1.fi>
| *
| * This software may be distributed under the terms of the BSD license.
| * See README for more details.
| */
|
| #include "rtw_crypto_wrap.h"
|
| #include "aes_i.h"
|
| static void rijndaelEncrypt(const u32 rk[], int Nr, const u8 pt[16], u8 ct[16])
| {
| u32 s0, s1, s2, s3, t0, t1, t2, t3;
| #ifndef FULL_UNROLL
| int r;
| #endif /* ?FULL_UNROLL */
|
| /*
| * map byte array block to cipher state
| * and add initial round key:
| */
| s0 = GETU32(pt ) ^ rk[0];
| s1 = GETU32(pt + 4) ^ rk[1];
| s2 = GETU32(pt + 8) ^ rk[2];
| s3 = GETU32(pt + 12) ^ rk[3];
|
| #define ROUND(i,d,s) \
| d##0 = TE0(s##0) ^ TE1(s##1) ^ TE2(s##2) ^ TE3(s##3) ^ rk[4 * i]; \
| d##1 = TE0(s##1) ^ TE1(s##2) ^ TE2(s##3) ^ TE3(s##0) ^ rk[4 * i + 1]; \
| d##2 = TE0(s##2) ^ TE1(s##3) ^ TE2(s##0) ^ TE3(s##1) ^ rk[4 * i + 2]; \
| d##3 = TE0(s##3) ^ TE1(s##0) ^ TE2(s##1) ^ TE3(s##2) ^ rk[4 * i + 3]
|
| #ifdef FULL_UNROLL
|
| ROUND(1,t,s);
| ROUND(2,s,t);
| ROUND(3,t,s);
| ROUND(4,s,t);
| ROUND(5,t,s);
| ROUND(6,s,t);
| ROUND(7,t,s);
| ROUND(8,s,t);
| ROUND(9,t,s);
| if (Nr > 10) {
| ROUND(10,s,t);
| ROUND(11,t,s);
| if (Nr > 12) {
| ROUND(12,s,t);
| ROUND(13,t,s);
| }
| }
|
| rk += Nr << 2;
|
| #else /* !FULL_UNROLL */
|
| /* Nr - 1 full rounds: */
| r = Nr >> 1;
| for (;;) {
| ROUND(1,t,s);
| rk += 8;
| if (--r == 0)
| break;
| ROUND(0,s,t);
| }
|
| #endif /* ?FULL_UNROLL */
|
| #undef ROUND
|
| /*
| * apply last round and
| * map cipher state to byte array block:
| */
| s0 = TE41(t0) ^ TE42(t1) ^ TE43(t2) ^ TE44(t3) ^ rk[0];
| PUTU32(ct , s0);
| s1 = TE41(t1) ^ TE42(t2) ^ TE43(t3) ^ TE44(t0) ^ rk[1];
| PUTU32(ct + 4, s1);
| s2 = TE41(t2) ^ TE42(t3) ^ TE43(t0) ^ TE44(t1) ^ rk[2];
| PUTU32(ct + 8, s2);
| s3 = TE41(t3) ^ TE42(t0) ^ TE43(t1) ^ TE44(t2) ^ rk[3];
| PUTU32(ct + 12, s3);
| }
|
|
| void * aes_encrypt_init(const u8 *key, size_t len)
| {
| u32 *rk;
| int res;
|
| if (TEST_FAIL())
| return NULL;
|
| rk = os_malloc(AES_PRIV_SIZE);
| if (rk == NULL)
| return NULL;
| res = rijndaelKeySetupEnc(rk, key, len * 8);
| if (res < 0) {
| rtw_mfree(rk, AES_PRIV_SIZE);
| return NULL;
| }
| rk[AES_PRIV_NR_POS] = res;
| return rk;
| }
|
|
| int _aes_encrypt(void *ctx, const u8 *plain, u8 *crypt)
| {
| u32 *rk = ctx;
| rijndaelEncrypt(ctx, rk[AES_PRIV_NR_POS], plain, crypt);
| return 0;
| }
|
|
| void aes_encrypt_deinit(void *ctx)
| {
| os_memset(ctx, 0, AES_PRIV_SIZE);
| rtw_mfree(ctx, AES_PRIV_SIZE);
| }
|
|