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