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