]>
Commit | Line | Data |
---|---|---|
4c9e03e0 JB |
1 | /* |
2 | * AES-128 EAX | |
3 | * | |
4 | * Copyright (c) 2003-2007, Jouni Malinen <j@w1.fi> | |
5 | * | |
0f3d578e JM |
6 | * This software may be distributed under the terms of the BSD license. |
7 | * See README for more details. | |
4c9e03e0 JB |
8 | */ |
9 | ||
10 | #include "includes.h" | |
11 | ||
12 | #include "common.h" | |
1ba787b9 | 13 | #include "aes.h" |
4c9e03e0 JB |
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 | */ | |
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; | |
1ba787b9 JM |
34 | u8 nonce_mac[AES_BLOCK_SIZE], hdr_mac[AES_BLOCK_SIZE], |
35 | data_mac[AES_BLOCK_SIZE]; | |
4c9e03e0 JB |
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 | ||
1ba787b9 | 69 | for (i = 0; i < AES_BLOCK_SIZE; i++) |
4c9e03e0 JB |
70 | tag[i] = nonce_mac[i] ^ data_mac[i] ^ hdr_mac[i]; |
71 | ||
72 | ret = 0; | |
73 | fail: | |
74 | os_free(buf); | |
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 | */ | |
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; | |
1ba787b9 JM |
98 | u8 nonce_mac[AES_BLOCK_SIZE], hdr_mac[AES_BLOCK_SIZE], |
99 | data_mac[AES_BLOCK_SIZE]; | |
4c9e03e0 JB |
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 | ||
1ba787b9 | 139 | for (i = 0; i < AES_BLOCK_SIZE; i++) { |
4c9e03e0 JB |
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 | } |