xref: /aosp_15_r20/external/wpa_supplicant_8/src/crypto/aes-eax.c (revision 03f9172ca588f91df233974f4258bab95191f931)
1*03f9172cSAndroid Build Coastguard Worker /*
2*03f9172cSAndroid Build Coastguard Worker  * AES-128 EAX
3*03f9172cSAndroid Build Coastguard Worker  *
4*03f9172cSAndroid Build Coastguard Worker  * Copyright (c) 2003-2007, Jouni Malinen <[email protected]>
5*03f9172cSAndroid Build Coastguard Worker  *
6*03f9172cSAndroid Build Coastguard Worker  * This software may be distributed under the terms of the BSD license.
7*03f9172cSAndroid Build Coastguard Worker  * See README for more details.
8*03f9172cSAndroid Build Coastguard Worker  */
9*03f9172cSAndroid Build Coastguard Worker 
10*03f9172cSAndroid Build Coastguard Worker #include "includes.h"
11*03f9172cSAndroid Build Coastguard Worker 
12*03f9172cSAndroid Build Coastguard Worker #include "common.h"
13*03f9172cSAndroid Build Coastguard Worker #include "aes.h"
14*03f9172cSAndroid Build Coastguard Worker #include "aes_wrap.h"
15*03f9172cSAndroid Build Coastguard Worker 
16*03f9172cSAndroid Build Coastguard Worker /**
17*03f9172cSAndroid Build Coastguard Worker  * aes_128_eax_encrypt - AES-128 EAX mode encryption
18*03f9172cSAndroid Build Coastguard Worker  * @key: Key for encryption (16 bytes)
19*03f9172cSAndroid Build Coastguard Worker  * @nonce: Nonce for counter mode
20*03f9172cSAndroid Build Coastguard Worker  * @nonce_len: Nonce length in bytes
21*03f9172cSAndroid Build Coastguard Worker  * @hdr: Header data to be authenticity protected
22*03f9172cSAndroid Build Coastguard Worker  * @hdr_len: Length of the header data bytes
23*03f9172cSAndroid Build Coastguard Worker  * @data: Data to encrypt in-place
24*03f9172cSAndroid Build Coastguard Worker  * @data_len: Length of data in bytes
25*03f9172cSAndroid Build Coastguard Worker  * @tag: 16-byte tag value
26*03f9172cSAndroid Build Coastguard Worker  * Returns: 0 on success, -1 on failure
27*03f9172cSAndroid Build Coastguard Worker  */
aes_128_eax_encrypt(const u8 * key,const u8 * nonce,size_t nonce_len,const u8 * hdr,size_t hdr_len,u8 * data,size_t data_len,u8 * tag)28*03f9172cSAndroid Build Coastguard Worker int aes_128_eax_encrypt(const u8 *key, const u8 *nonce, size_t nonce_len,
29*03f9172cSAndroid Build Coastguard Worker 			const u8 *hdr, size_t hdr_len,
30*03f9172cSAndroid Build Coastguard Worker 			u8 *data, size_t data_len, u8 *tag)
31*03f9172cSAndroid Build Coastguard Worker {
32*03f9172cSAndroid Build Coastguard Worker 	u8 *buf;
33*03f9172cSAndroid Build Coastguard Worker 	size_t buf_len;
34*03f9172cSAndroid Build Coastguard Worker 	u8 nonce_mac[AES_BLOCK_SIZE], hdr_mac[AES_BLOCK_SIZE],
35*03f9172cSAndroid Build Coastguard Worker 		data_mac[AES_BLOCK_SIZE];
36*03f9172cSAndroid Build Coastguard Worker 	int i, ret = -1;
37*03f9172cSAndroid Build Coastguard Worker 
38*03f9172cSAndroid Build Coastguard Worker 	if (nonce_len > data_len)
39*03f9172cSAndroid Build Coastguard Worker 		buf_len = nonce_len;
40*03f9172cSAndroid Build Coastguard Worker 	else
41*03f9172cSAndroid Build Coastguard Worker 		buf_len = data_len;
42*03f9172cSAndroid Build Coastguard Worker 	if (hdr_len > buf_len)
43*03f9172cSAndroid Build Coastguard Worker 		buf_len = hdr_len;
44*03f9172cSAndroid Build Coastguard Worker 	buf_len += 16;
45*03f9172cSAndroid Build Coastguard Worker 
46*03f9172cSAndroid Build Coastguard Worker 	buf = os_malloc(buf_len);
47*03f9172cSAndroid Build Coastguard Worker 	if (buf == NULL)
48*03f9172cSAndroid Build Coastguard Worker 		return -1;
49*03f9172cSAndroid Build Coastguard Worker 
50*03f9172cSAndroid Build Coastguard Worker 	os_memset(buf, 0, 15);
51*03f9172cSAndroid Build Coastguard Worker 
52*03f9172cSAndroid Build Coastguard Worker 	buf[15] = 0;
53*03f9172cSAndroid Build Coastguard Worker 	os_memcpy(buf + 16, nonce, nonce_len);
54*03f9172cSAndroid Build Coastguard Worker 	if (omac1_aes_128(key, buf, 16 + nonce_len, nonce_mac))
55*03f9172cSAndroid Build Coastguard Worker 		goto fail;
56*03f9172cSAndroid Build Coastguard Worker 
57*03f9172cSAndroid Build Coastguard Worker 	buf[15] = 1;
58*03f9172cSAndroid Build Coastguard Worker 	os_memcpy(buf + 16, hdr, hdr_len);
59*03f9172cSAndroid Build Coastguard Worker 	if (omac1_aes_128(key, buf, 16 + hdr_len, hdr_mac))
60*03f9172cSAndroid Build Coastguard Worker 		goto fail;
61*03f9172cSAndroid Build Coastguard Worker 
62*03f9172cSAndroid Build Coastguard Worker 	if (aes_128_ctr_encrypt(key, nonce_mac, data, data_len))
63*03f9172cSAndroid Build Coastguard Worker 		goto fail;
64*03f9172cSAndroid Build Coastguard Worker 	buf[15] = 2;
65*03f9172cSAndroid Build Coastguard Worker 	os_memcpy(buf + 16, data, data_len);
66*03f9172cSAndroid Build Coastguard Worker 	if (omac1_aes_128(key, buf, 16 + data_len, data_mac))
67*03f9172cSAndroid Build Coastguard Worker 		goto fail;
68*03f9172cSAndroid Build Coastguard Worker 
69*03f9172cSAndroid Build Coastguard Worker 	for (i = 0; i < AES_BLOCK_SIZE; i++)
70*03f9172cSAndroid Build Coastguard Worker 		tag[i] = nonce_mac[i] ^ data_mac[i] ^ hdr_mac[i];
71*03f9172cSAndroid Build Coastguard Worker 
72*03f9172cSAndroid Build Coastguard Worker 	ret = 0;
73*03f9172cSAndroid Build Coastguard Worker fail:
74*03f9172cSAndroid Build Coastguard Worker 	bin_clear_free(buf, buf_len);
75*03f9172cSAndroid Build Coastguard Worker 
76*03f9172cSAndroid Build Coastguard Worker 	return ret;
77*03f9172cSAndroid Build Coastguard Worker }
78*03f9172cSAndroid Build Coastguard Worker 
79*03f9172cSAndroid Build Coastguard Worker 
80*03f9172cSAndroid Build Coastguard Worker /**
81*03f9172cSAndroid Build Coastguard Worker  * aes_128_eax_decrypt - AES-128 EAX mode decryption
82*03f9172cSAndroid Build Coastguard Worker  * @key: Key for decryption (16 bytes)
83*03f9172cSAndroid Build Coastguard Worker  * @nonce: Nonce for counter mode
84*03f9172cSAndroid Build Coastguard Worker  * @nonce_len: Nonce length in bytes
85*03f9172cSAndroid Build Coastguard Worker  * @hdr: Header data to be authenticity protected
86*03f9172cSAndroid Build Coastguard Worker  * @hdr_len: Length of the header data bytes
87*03f9172cSAndroid Build Coastguard Worker  * @data: Data to encrypt in-place
88*03f9172cSAndroid Build Coastguard Worker  * @data_len: Length of data in bytes
89*03f9172cSAndroid Build Coastguard Worker  * @tag: 16-byte tag value
90*03f9172cSAndroid Build Coastguard Worker  * Returns: 0 on success, -1 on failure, -2 if tag does not match
91*03f9172cSAndroid Build Coastguard Worker  */
aes_128_eax_decrypt(const u8 * key,const u8 * nonce,size_t nonce_len,const u8 * hdr,size_t hdr_len,u8 * data,size_t data_len,const u8 * tag)92*03f9172cSAndroid Build Coastguard Worker int aes_128_eax_decrypt(const u8 *key, const u8 *nonce, size_t nonce_len,
93*03f9172cSAndroid Build Coastguard Worker 			const u8 *hdr, size_t hdr_len,
94*03f9172cSAndroid Build Coastguard Worker 			u8 *data, size_t data_len, const u8 *tag)
95*03f9172cSAndroid Build Coastguard Worker {
96*03f9172cSAndroid Build Coastguard Worker 	u8 *buf;
97*03f9172cSAndroid Build Coastguard Worker 	size_t buf_len;
98*03f9172cSAndroid Build Coastguard Worker 	u8 nonce_mac[AES_BLOCK_SIZE], hdr_mac[AES_BLOCK_SIZE],
99*03f9172cSAndroid Build Coastguard Worker 		data_mac[AES_BLOCK_SIZE];
100*03f9172cSAndroid Build Coastguard Worker 	int i;
101*03f9172cSAndroid Build Coastguard Worker 
102*03f9172cSAndroid Build Coastguard Worker 	if (nonce_len > data_len)
103*03f9172cSAndroid Build Coastguard Worker 		buf_len = nonce_len;
104*03f9172cSAndroid Build Coastguard Worker 	else
105*03f9172cSAndroid Build Coastguard Worker 		buf_len = data_len;
106*03f9172cSAndroid Build Coastguard Worker 	if (hdr_len > buf_len)
107*03f9172cSAndroid Build Coastguard Worker 		buf_len = hdr_len;
108*03f9172cSAndroid Build Coastguard Worker 	buf_len += 16;
109*03f9172cSAndroid Build Coastguard Worker 
110*03f9172cSAndroid Build Coastguard Worker 	buf = os_malloc(buf_len);
111*03f9172cSAndroid Build Coastguard Worker 	if (buf == NULL)
112*03f9172cSAndroid Build Coastguard Worker 		return -1;
113*03f9172cSAndroid Build Coastguard Worker 
114*03f9172cSAndroid Build Coastguard Worker 	os_memset(buf, 0, 15);
115*03f9172cSAndroid Build Coastguard Worker 
116*03f9172cSAndroid Build Coastguard Worker 	buf[15] = 0;
117*03f9172cSAndroid Build Coastguard Worker 	os_memcpy(buf + 16, nonce, nonce_len);
118*03f9172cSAndroid Build Coastguard Worker 	if (omac1_aes_128(key, buf, 16 + nonce_len, nonce_mac)) {
119*03f9172cSAndroid Build Coastguard Worker 		os_free(buf);
120*03f9172cSAndroid Build Coastguard Worker 		return -1;
121*03f9172cSAndroid Build Coastguard Worker 	}
122*03f9172cSAndroid Build Coastguard Worker 
123*03f9172cSAndroid Build Coastguard Worker 	buf[15] = 1;
124*03f9172cSAndroid Build Coastguard Worker 	os_memcpy(buf + 16, hdr, hdr_len);
125*03f9172cSAndroid Build Coastguard Worker 	if (omac1_aes_128(key, buf, 16 + hdr_len, hdr_mac)) {
126*03f9172cSAndroid Build Coastguard Worker 		os_free(buf);
127*03f9172cSAndroid Build Coastguard Worker 		return -1;
128*03f9172cSAndroid Build Coastguard Worker 	}
129*03f9172cSAndroid Build Coastguard Worker 
130*03f9172cSAndroid Build Coastguard Worker 	buf[15] = 2;
131*03f9172cSAndroid Build Coastguard Worker 	os_memcpy(buf + 16, data, data_len);
132*03f9172cSAndroid Build Coastguard Worker 	if (omac1_aes_128(key, buf, 16 + data_len, data_mac)) {
133*03f9172cSAndroid Build Coastguard Worker 		os_free(buf);
134*03f9172cSAndroid Build Coastguard Worker 		return -1;
135*03f9172cSAndroid Build Coastguard Worker 	}
136*03f9172cSAndroid Build Coastguard Worker 
137*03f9172cSAndroid Build Coastguard Worker 	os_free(buf);
138*03f9172cSAndroid Build Coastguard Worker 
139*03f9172cSAndroid Build Coastguard Worker 	for (i = 0; i < AES_BLOCK_SIZE; i++) {
140*03f9172cSAndroid Build Coastguard Worker 		if (tag[i] != (nonce_mac[i] ^ data_mac[i] ^ hdr_mac[i]))
141*03f9172cSAndroid Build Coastguard Worker 			return -2;
142*03f9172cSAndroid Build Coastguard Worker 	}
143*03f9172cSAndroid Build Coastguard Worker 
144*03f9172cSAndroid Build Coastguard Worker 	return aes_128_ctr_encrypt(key, nonce_mac, data, data_len);
145*03f9172cSAndroid Build Coastguard Worker }
146