xref: /aosp_15_r20/external/wpa_supplicant_8/src/crypto/aes-internal-enc.c (revision 03f9172ca588f91df233974f4258bab95191f931)
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