4 * - AES Key Wrap Algorithm (128-bit KEK) (RFC3394)
5 * - One-Key CBC MAC (OMAC1) hash with AES-128
6 * - AES-128 CTR mode encryption
7 * - AES-128 EAX mode encryption/decryption
10 * Copyright (c) 2003-2005, Jouni Malinen <j@w1.fi>
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License version 2 as
14 * published by the Free Software Foundation.
16 * Alternatively, this software may be distributed under the terms of BSD
19 * See README and COPYING for more details.
30 #endif /* INTERNAL_AES */
33 #ifndef CONFIG_NO_AES_WRAP
36 * aes_wrap - Wrap keys with AES Key Wrap Algorithm (128-bit KEK) (RFC3394)
37 * @kek: Key encryption key (KEK)
38 * @n: Length of the wrapped key in 64-bit units; e.g., 2 = 128-bit = 16 bytes
39 * @plain: Plaintext key to be wrapped, n * 64 bit
40 * @cipher: Wrapped key, (n + 1) * 64 bit
41 * Returns: 0 on success, -1 on failure
43 int aes_wrap(const u8
*kek
, int n
, const u8
*plain
, u8
*cipher
)
52 /* 1) Initialize variables. */
53 os_memset(a
, 0xa6, 8);
54 os_memcpy(r
, plain
, 8 * n
);
56 ctx
= aes_encrypt_init(kek
, 16);
60 /* 2) Calculate intermediate values.
63 * B = AES(K, A | R[i])
64 * A = MSB(64, B) ^ t where t = (n*j)+i
67 for (j
= 0; j
<= 5; j
++) {
69 for (i
= 1; i
<= n
; i
++) {
71 os_memcpy(b
+ 8, r
, 8);
72 aes_encrypt(ctx
, b
, b
);
75 os_memcpy(r
, b
+ 8, 8);
79 aes_encrypt_deinit(ctx
);
81 /* 3) Output the results.
83 * These are already in @cipher due to the location of temporary
90 #endif /* CONFIG_NO_AES_WRAP */
94 * aes_unwrap - Unwrap key with AES Key Wrap Algorithm (128-bit KEK) (RFC3394)
95 * @kek: Key encryption key (KEK)
96 * @n: Length of the wrapped key in 64-bit units; e.g., 2 = 128-bit = 16 bytes
97 * @cipher: Wrapped key to be unwrapped, (n + 1) * 64 bit
98 * @plain: Plaintext key, n * 64 bit
99 * Returns: 0 on success, -1 on failure (e.g., integrity verification failed)
101 int aes_unwrap(const u8
*kek
, int n
, const u8
*cipher
, u8
*plain
)
107 /* 1) Initialize variables. */
108 os_memcpy(a
, cipher
, 8);
110 os_memcpy(r
, cipher
+ 8, 8 * n
);
112 ctx
= aes_decrypt_init(kek
, 16);
116 /* 2) Compute intermediate values.
119 * B = AES-1(K, (A ^ t) | R[i]) where t = n*j+i
123 for (j
= 5; j
>= 0; j
--) {
124 r
= plain
+ (n
- 1) * 8;
125 for (i
= n
; i
>= 1; i
--) {
129 os_memcpy(b
+ 8, r
, 8);
130 aes_decrypt(ctx
, b
, b
);
132 os_memcpy(r
, b
+ 8, 8);
136 aes_decrypt_deinit(ctx
);
138 /* 3) Output results.
140 * These are already in @plain due to the location of temporary
141 * variables. Just verify that the IV matches with the expected value.
143 for (i
= 0; i
< 8; i
++) {
152 #define BLOCK_SIZE 16
154 #ifndef CONFIG_NO_AES_OMAC1
156 static void gf_mulx(u8
*pad
)
160 carry
= pad
[0] & 0x80;
161 for (i
= 0; i
< BLOCK_SIZE
- 1; i
++)
162 pad
[i
] = (pad
[i
] << 1) | (pad
[i
+ 1] >> 7);
163 pad
[BLOCK_SIZE
- 1] <<= 1;
165 pad
[BLOCK_SIZE
- 1] ^= 0x87;
170 * omac1_aes_128 - One-Key CBC MAC (OMAC1) hash with AES-128 (aka AES-CMAC)
171 * @key: 128-bit key for the hash operation
172 * @data: Data buffer for which a MAC is determined
173 * @data: Length of data buffer in bytes
174 * @mac: Buffer for MAC (128 bits, i.e., 16 bytes)
175 * Returns: 0 on success, -1 on failure
177 int omac1_aes_128(const u8
*key
, const u8
*data
, size_t data_len
, u8
*mac
)
180 u8 cbc
[BLOCK_SIZE
], pad
[BLOCK_SIZE
];
181 const u8
*pos
= data
;
182 size_t i
, left
= data_len
;
184 ctx
= aes_encrypt_init(key
, 16);
187 os_memset(cbc
, 0, BLOCK_SIZE
);
189 while (left
>= BLOCK_SIZE
) {
190 for (i
= 0; i
< BLOCK_SIZE
; i
++)
192 if (left
> BLOCK_SIZE
)
193 aes_encrypt(ctx
, cbc
, cbc
);
197 os_memset(pad
, 0, BLOCK_SIZE
);
198 aes_encrypt(ctx
, pad
, pad
);
201 if (left
|| data_len
== 0) {
202 for (i
= 0; i
< left
; i
++)
208 for (i
= 0; i
< BLOCK_SIZE
; i
++)
210 aes_encrypt(ctx
, pad
, mac
);
211 aes_encrypt_deinit(ctx
);
215 #endif /* CONFIG_NO_AES_OMAC1 */
219 * aes_128_encrypt_block - Perform one AES 128-bit block operation
221 * @in: Input data (16 bytes)
222 * @out: Output of the AES block operation (16 bytes)
223 * Returns: 0 on success, -1 on failure
225 int aes_128_encrypt_block(const u8
*key
, const u8
*in
, u8
*out
)
228 ctx
= aes_encrypt_init(key
, 16);
231 aes_encrypt(ctx
, in
, out
);
232 aes_encrypt_deinit(ctx
);
237 #ifndef CONFIG_NO_AES_CTR
240 * aes_128_ctr_encrypt - AES-128 CTR mode encryption
241 * @key: Key for encryption (16 bytes)
242 * @nonce: Nonce for counter mode (16 bytes)
243 * @data: Data to encrypt in-place
244 * @data_len: Length of data in bytes
245 * Returns: 0 on success, -1 on failure
247 int aes_128_ctr_encrypt(const u8
*key
, const u8
*nonce
,
248 u8
*data
, size_t data_len
)
251 size_t j
, len
, left
= data_len
;
254 u8 counter
[BLOCK_SIZE
], buf
[BLOCK_SIZE
];
256 ctx
= aes_encrypt_init(key
, 16);
259 os_memcpy(counter
, nonce
, BLOCK_SIZE
);
262 aes_encrypt(ctx
, counter
, buf
);
264 len
= (left
< BLOCK_SIZE
) ? left
: BLOCK_SIZE
;
265 for (j
= 0; j
< len
; j
++)
270 for (i
= BLOCK_SIZE
- 1; i
>= 0; i
--) {
276 aes_encrypt_deinit(ctx
);
280 #endif /* CONFIG_NO_AES_CTR */
283 #ifndef CONFIG_NO_AES_EAX
286 * aes_128_eax_encrypt - AES-128 EAX mode encryption
287 * @key: Key for encryption (16 bytes)
288 * @nonce: Nonce for counter mode
289 * @nonce_len: Nonce length in bytes
290 * @hdr: Header data to be authenticity protected
291 * @hdr_len: Length of the header data bytes
292 * @data: Data to encrypt in-place
293 * @data_len: Length of data in bytes
294 * @tag: 16-byte tag value
295 * Returns: 0 on success, -1 on failure
297 int aes_128_eax_encrypt(const u8
*key
, const u8
*nonce
, size_t nonce_len
,
298 const u8
*hdr
, size_t hdr_len
,
299 u8
*data
, size_t data_len
, u8
*tag
)
303 u8 nonce_mac
[BLOCK_SIZE
], hdr_mac
[BLOCK_SIZE
], data_mac
[BLOCK_SIZE
];
306 if (nonce_len
> data_len
)
310 if (hdr_len
> buf_len
)
314 buf
= os_malloc(buf_len
);
318 os_memset(buf
, 0, 15);
321 os_memcpy(buf
+ 16, nonce
, nonce_len
);
322 omac1_aes_128(key
, buf
, 16 + nonce_len
, nonce_mac
);
325 os_memcpy(buf
+ 16, hdr
, hdr_len
);
326 omac1_aes_128(key
, buf
, 16 + hdr_len
, hdr_mac
);
328 aes_128_ctr_encrypt(key
, nonce_mac
, data
, data_len
);
330 os_memcpy(buf
+ 16, data
, data_len
);
331 omac1_aes_128(key
, buf
, 16 + data_len
, data_mac
);
335 for (i
= 0; i
< BLOCK_SIZE
; i
++)
336 tag
[i
] = nonce_mac
[i
] ^ data_mac
[i
] ^ hdr_mac
[i
];
343 * aes_128_eax_decrypt - AES-128 EAX mode decryption
344 * @key: Key for decryption (16 bytes)
345 * @nonce: Nonce for counter mode
346 * @nonce_len: Nonce length in bytes
347 * @hdr: Header data to be authenticity protected
348 * @hdr_len: Length of the header data bytes
349 * @data: Data to encrypt in-place
350 * @data_len: Length of data in bytes
351 * @tag: 16-byte tag value
352 * Returns: 0 on success, -1 on failure, -2 if tag does not match
354 int aes_128_eax_decrypt(const u8
*key
, const u8
*nonce
, size_t nonce_len
,
355 const u8
*hdr
, size_t hdr_len
,
356 u8
*data
, size_t data_len
, const u8
*tag
)
360 u8 nonce_mac
[BLOCK_SIZE
], hdr_mac
[BLOCK_SIZE
], data_mac
[BLOCK_SIZE
];
363 if (nonce_len
> data_len
)
367 if (hdr_len
> buf_len
)
371 buf
= os_malloc(buf_len
);
375 os_memset(buf
, 0, 15);
378 os_memcpy(buf
+ 16, nonce
, nonce_len
);
379 omac1_aes_128(key
, buf
, 16 + nonce_len
, nonce_mac
);
382 os_memcpy(buf
+ 16, hdr
, hdr_len
);
383 omac1_aes_128(key
, buf
, 16 + hdr_len
, hdr_mac
);
386 os_memcpy(buf
+ 16, data
, data_len
);
387 omac1_aes_128(key
, buf
, 16 + data_len
, data_mac
);
391 for (i
= 0; i
< BLOCK_SIZE
; i
++) {
392 if (tag
[i
] != (nonce_mac
[i
] ^ data_mac
[i
] ^ hdr_mac
[i
]))
396 aes_128_ctr_encrypt(key
, nonce_mac
, data
, data_len
);
401 #endif /* CONFIG_NO_AES_EAX */
404 #ifndef CONFIG_NO_AES_CBC
407 * aes_128_cbc_encrypt - AES-128 CBC encryption
408 * @key: Encryption key
409 * @iv: Encryption IV for CBC mode (16 bytes)
410 * @data: Data to encrypt in-place
411 * @data_len: Length of data in bytes (must be divisible by 16)
412 * Returns: 0 on success, -1 on failure
414 int aes_128_cbc_encrypt(const u8
*key
, const u8
*iv
, u8
*data
, size_t data_len
)
421 ctx
= aes_encrypt_init(key
, 16);
424 os_memcpy(cbc
, iv
, BLOCK_SIZE
);
426 blocks
= data_len
/ BLOCK_SIZE
;
427 for (i
= 0; i
< blocks
; i
++) {
428 for (j
= 0; j
< BLOCK_SIZE
; j
++)
430 aes_encrypt(ctx
, cbc
, cbc
);
431 os_memcpy(pos
, cbc
, BLOCK_SIZE
);
434 aes_encrypt_deinit(ctx
);
440 * aes_128_cbc_decrypt - AES-128 CBC decryption
441 * @key: Decryption key
442 * @iv: Decryption IV for CBC mode (16 bytes)
443 * @data: Data to decrypt in-place
444 * @data_len: Length of data in bytes (must be divisible by 16)
445 * Returns: 0 on success, -1 on failure
447 int aes_128_cbc_decrypt(const u8
*key
, const u8
*iv
, u8
*data
, size_t data_len
)
450 u8 cbc
[BLOCK_SIZE
], tmp
[BLOCK_SIZE
];
454 ctx
= aes_decrypt_init(key
, 16);
457 os_memcpy(cbc
, iv
, BLOCK_SIZE
);
459 blocks
= data_len
/ BLOCK_SIZE
;
460 for (i
= 0; i
< blocks
; i
++) {
461 os_memcpy(tmp
, pos
, BLOCK_SIZE
);
462 aes_decrypt(ctx
, pos
, pos
);
463 for (j
= 0; j
< BLOCK_SIZE
; j
++)
465 os_memcpy(cbc
, tmp
, BLOCK_SIZE
);
468 aes_decrypt_deinit(ctx
);
472 #endif /* CONFIG_NO_AES_CBC */