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