• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * AES-based functions
3  *
4  * - AES Key Wrap Algorithm (128-bit KEK) (RFC3394)
5  * - One-Key CBC MAC (OMAC1, i.e., CMAC) hash with AES-128
6  * - AES-128 CTR mode encryption
7  * - AES-128 EAX mode encryption/decryption
8  * - AES-128 CBC
9  *
10  * Copyright (c) 2003-2007, Jouni Malinen <j@w1.fi>
11  *
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.
15  *
16  * Alternatively, this software may be distributed under the terms of BSD
17  * license.
18  *
19  * See README and COPYING for more details.
20  */
21 
22 #include "includes.h"
23 
24 #include "common.h"
25 #include "aes_wrap.h"
26 #include "crypto.h"
27 
28 #ifndef CONFIG_NO_AES_WRAP
29 
30 /**
31  * aes_wrap - Wrap keys with AES Key Wrap Algorithm (128-bit KEK) (RFC3394)
32  * @kek: 16-octet Key encryption key (KEK)
33  * @n: Length of the plaintext key in 64-bit units; e.g., 2 = 128-bit = 16
34  * bytes
35  * @plain: Plaintext key to be wrapped, n * 64 bits
36  * @cipher: Wrapped key, (n + 1) * 64 bits
37  * Returns: 0 on success, -1 on failure
38  */
aes_wrap(const u8 * kek,int n,const u8 * plain,u8 * cipher)39 int aes_wrap(const u8 *kek, int n, const u8 *plain, u8 *cipher)
40 {
41 	u8 *a, *r, b[16];
42 	int i, j;
43 	void *ctx;
44 
45 	a = cipher;
46 	r = cipher + 8;
47 
48 	/* 1) Initialize variables. */
49 	os_memset(a, 0xa6, 8);
50 	os_memcpy(r, plain, 8 * n);
51 
52 	ctx = aes_encrypt_init(kek, 16);
53 	if (ctx == NULL)
54 		return -1;
55 
56 	/* 2) Calculate intermediate values.
57 	 * For j = 0 to 5
58 	 *     For i=1 to n
59 	 *         B = AES(K, A | R[i])
60 	 *         A = MSB(64, B) ^ t where t = (n*j)+i
61 	 *         R[i] = LSB(64, B)
62 	 */
63 	for (j = 0; j <= 5; j++) {
64 		r = cipher + 8;
65 		for (i = 1; i <= n; i++) {
66 			os_memcpy(b, a, 8);
67 			os_memcpy(b + 8, r, 8);
68 			aes_encrypt(ctx, b, b);
69 			os_memcpy(a, b, 8);
70 			a[7] ^= n * j + i;
71 			os_memcpy(r, b + 8, 8);
72 			r += 8;
73 		}
74 	}
75 	aes_encrypt_deinit(ctx);
76 
77 	/* 3) Output the results.
78 	 *
79 	 * These are already in @cipher due to the location of temporary
80 	 * variables.
81 	 */
82 
83 	return 0;
84 }
85 
86 #endif /* CONFIG_NO_AES_WRAP */
87 
88 
89 #ifndef CONFIG_NO_AES_UNWRAP
90 
91 /**
92  * aes_unwrap - Unwrap key with AES Key Wrap Algorithm (128-bit KEK) (RFC3394)
93  * @kek: Key encryption key (KEK)
94  * @n: Length of the plaintext key in 64-bit units; e.g., 2 = 128-bit = 16
95  * bytes
96  * @cipher: Wrapped key to be unwrapped, (n + 1) * 64 bits
97  * @plain: Plaintext key, n * 64 bits
98  * Returns: 0 on success, -1 on failure (e.g., integrity verification failed)
99  */
aes_unwrap(const u8 * kek,int n,const u8 * cipher,u8 * plain)100 int aes_unwrap(const u8 *kek, int n, const u8 *cipher, u8 *plain)
101 {
102 	u8 a[8], *r, b[16];
103 	int i, j;
104 	void *ctx;
105 
106 	/* 1) Initialize variables. */
107 	os_memcpy(a, cipher, 8);
108 	r = plain;
109 	os_memcpy(r, cipher + 8, 8 * n);
110 
111 	ctx = aes_decrypt_init(kek, 16);
112 	if (ctx == NULL)
113 		return -1;
114 
115 	/* 2) Compute intermediate values.
116 	 * For j = 5 to 0
117 	 *     For i = n to 1
118 	 *         B = AES-1(K, (A ^ t) | R[i]) where t = n*j+i
119 	 *         A = MSB(64, B)
120 	 *         R[i] = LSB(64, B)
121 	 */
122 	for (j = 5; j >= 0; j--) {
123 		r = plain + (n - 1) * 8;
124 		for (i = n; i >= 1; i--) {
125 			os_memcpy(b, a, 8);
126 			b[7] ^= n * j + i;
127 
128 			os_memcpy(b + 8, r, 8);
129 			aes_decrypt(ctx, b, b);
130 			os_memcpy(a, b, 8);
131 			os_memcpy(r, b + 8, 8);
132 			r -= 8;
133 		}
134 	}
135 	aes_decrypt_deinit(ctx);
136 
137 	/* 3) Output results.
138 	 *
139 	 * These are already in @plain due to the location of temporary
140 	 * variables. Just verify that the IV matches with the expected value.
141 	 */
142 	for (i = 0; i < 8; i++) {
143 		if (a[i] != 0xa6)
144 			return -1;
145 	}
146 
147 	return 0;
148 }
149 
150 #endif /* CONFIG_NO_AES_UNWRAP */
151 
152 
153 #define BLOCK_SIZE 16
154 
155 #ifndef CONFIG_NO_AES_OMAC1
156 
gf_mulx(u8 * pad)157 static void gf_mulx(u8 *pad)
158 {
159 	int i, carry;
160 
161 	carry = pad[0] & 0x80;
162 	for (i = 0; i < BLOCK_SIZE - 1; i++)
163 		pad[i] = (pad[i] << 1) | (pad[i + 1] >> 7);
164 	pad[BLOCK_SIZE - 1] <<= 1;
165 	if (carry)
166 		pad[BLOCK_SIZE - 1] ^= 0x87;
167 }
168 
169 
170 /**
171  * omac1_aes_128_vector - One-Key CBC MAC (OMAC1) hash with AES-128
172  * @key: 128-bit key for the hash operation
173  * @num_elem: Number of elements in the data vector
174  * @addr: Pointers to the data areas
175  * @len: Lengths of the data blocks
176  * @mac: Buffer for MAC (128 bits, i.e., 16 bytes)
177  * Returns: 0 on success, -1 on failure
178  *
179  * This is a mode for using block cipher (AES in this case) for authentication.
180  * OMAC1 was standardized with the name CMAC by NIST in a Special Publication
181  * (SP) 800-38B.
182  */
omac1_aes_128_vector(const u8 * key,size_t num_elem,const u8 * addr[],const size_t * len,u8 * mac)183 int omac1_aes_128_vector(const u8 *key, size_t num_elem,
184 			 const u8 *addr[], const size_t *len, u8 *mac)
185 {
186 	void *ctx;
187 	u8 cbc[BLOCK_SIZE], pad[BLOCK_SIZE];
188 	const u8 *pos, *end;
189 	size_t i, e, left, total_len;
190 
191 	ctx = aes_encrypt_init(key, 16);
192 	if (ctx == NULL)
193 		return -1;
194 	os_memset(cbc, 0, BLOCK_SIZE);
195 
196 	total_len = 0;
197 	for (e = 0; e < num_elem; e++)
198 		total_len += len[e];
199 	left = total_len;
200 
201 	e = 0;
202 	pos = addr[0];
203 	end = pos + len[0];
204 
205 	while (left >= BLOCK_SIZE) {
206 		for (i = 0; i < BLOCK_SIZE; i++) {
207 			cbc[i] ^= *pos++;
208 			if (pos >= end) {
209 				e++;
210 				pos = addr[e];
211 				end = pos + len[e];
212 			}
213 		}
214 		if (left > BLOCK_SIZE)
215 			aes_encrypt(ctx, cbc, cbc);
216 		left -= BLOCK_SIZE;
217 	}
218 
219 	os_memset(pad, 0, BLOCK_SIZE);
220 	aes_encrypt(ctx, pad, pad);
221 	gf_mulx(pad);
222 
223 	if (left || total_len == 0) {
224 		for (i = 0; i < left; i++) {
225 			cbc[i] ^= *pos++;
226 			if (pos >= end) {
227 				e++;
228 				pos = addr[e];
229 				end = pos + len[e];
230 			}
231 		}
232 		cbc[left] ^= 0x80;
233 		gf_mulx(pad);
234 	}
235 
236 	for (i = 0; i < BLOCK_SIZE; i++)
237 		pad[i] ^= cbc[i];
238 	aes_encrypt(ctx, pad, mac);
239 	aes_encrypt_deinit(ctx);
240 	return 0;
241 }
242 
243 
244 /**
245  * omac1_aes_128 - One-Key CBC MAC (OMAC1) hash with AES-128 (aka AES-CMAC)
246  * @key: 128-bit key for the hash operation
247  * @data: Data buffer for which a MAC is determined
248  * @data_len: Length of data buffer in bytes
249  * @mac: Buffer for MAC (128 bits, i.e., 16 bytes)
250  * Returns: 0 on success, -1 on failure
251  *
252  * This is a mode for using block cipher (AES in this case) for authentication.
253  * OMAC1 was standardized with the name CMAC by NIST in a Special Publication
254  * (SP) 800-38B.
255  */
omac1_aes_128(const u8 * key,const u8 * data,size_t data_len,u8 * mac)256 int omac1_aes_128(const u8 *key, const u8 *data, size_t data_len, u8 *mac)
257 {
258 	return omac1_aes_128_vector(key, 1, &data, &data_len, mac);
259 }
260 
261 #endif /* CONFIG_NO_AES_OMAC1 */
262 
263 
264 #ifndef CONFIG_NO_AES_ENCRYPT_BLOCK
265 /**
266  * aes_128_encrypt_block - Perform one AES 128-bit block operation
267  * @key: Key for AES
268  * @in: Input data (16 bytes)
269  * @out: Output of the AES block operation (16 bytes)
270  * Returns: 0 on success, -1 on failure
271  */
aes_128_encrypt_block(const u8 * key,const u8 * in,u8 * out)272 int aes_128_encrypt_block(const u8 *key, const u8 *in, u8 *out)
273 {
274 	void *ctx;
275 	ctx = aes_encrypt_init(key, 16);
276 	if (ctx == NULL)
277 		return -1;
278 	aes_encrypt(ctx, in, out);
279 	aes_encrypt_deinit(ctx);
280 	return 0;
281 }
282 #endif /* CONFIG_NO_AES_ENCRYPT_BLOCK */
283 
284 
285 #ifndef CONFIG_NO_AES_CTR
286 
287 /**
288  * aes_128_ctr_encrypt - AES-128 CTR mode encryption
289  * @key: Key for encryption (16 bytes)
290  * @nonce: Nonce for counter mode (16 bytes)
291  * @data: Data to encrypt in-place
292  * @data_len: Length of data in bytes
293  * Returns: 0 on success, -1 on failure
294  */
aes_128_ctr_encrypt(const u8 * key,const u8 * nonce,u8 * data,size_t data_len)295 int aes_128_ctr_encrypt(const u8 *key, const u8 *nonce,
296 			u8 *data, size_t data_len)
297 {
298 	void *ctx;
299 	size_t j, len, left = data_len;
300 	int i;
301 	u8 *pos = data;
302 	u8 counter[BLOCK_SIZE], buf[BLOCK_SIZE];
303 
304 	ctx = aes_encrypt_init(key, 16);
305 	if (ctx == NULL)
306 		return -1;
307 	os_memcpy(counter, nonce, BLOCK_SIZE);
308 
309 	while (left > 0) {
310 		aes_encrypt(ctx, counter, buf);
311 
312 		len = (left < BLOCK_SIZE) ? left : BLOCK_SIZE;
313 		for (j = 0; j < len; j++)
314 			pos[j] ^= buf[j];
315 		pos += len;
316 		left -= len;
317 
318 		for (i = BLOCK_SIZE - 1; i >= 0; i--) {
319 			counter[i]++;
320 			if (counter[i])
321 				break;
322 		}
323 	}
324 	aes_encrypt_deinit(ctx);
325 	return 0;
326 }
327 
328 #endif /* CONFIG_NO_AES_CTR */
329 
330 
331 #ifndef CONFIG_NO_AES_EAX
332 
333 /**
334  * aes_128_eax_encrypt - AES-128 EAX mode encryption
335  * @key: Key for encryption (16 bytes)
336  * @nonce: Nonce for counter mode
337  * @nonce_len: Nonce length in bytes
338  * @hdr: Header data to be authenticity protected
339  * @hdr_len: Length of the header data bytes
340  * @data: Data to encrypt in-place
341  * @data_len: Length of data in bytes
342  * @tag: 16-byte tag value
343  * Returns: 0 on success, -1 on failure
344  */
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)345 int aes_128_eax_encrypt(const u8 *key, const u8 *nonce, size_t nonce_len,
346 			const u8 *hdr, size_t hdr_len,
347 			u8 *data, size_t data_len, u8 *tag)
348 {
349 	u8 *buf;
350 	size_t buf_len;
351 	u8 nonce_mac[BLOCK_SIZE], hdr_mac[BLOCK_SIZE], data_mac[BLOCK_SIZE];
352 	int i, ret = -1;
353 
354 	if (nonce_len > data_len)
355 		buf_len = nonce_len;
356 	else
357 		buf_len = data_len;
358 	if (hdr_len > buf_len)
359 		buf_len = hdr_len;
360 	buf_len += 16;
361 
362 	buf = os_malloc(buf_len);
363 	if (buf == NULL)
364 		return -1;
365 
366 	os_memset(buf, 0, 15);
367 
368 	buf[15] = 0;
369 	os_memcpy(buf + 16, nonce, nonce_len);
370 	if (omac1_aes_128(key, buf, 16 + nonce_len, nonce_mac))
371 		goto fail;
372 
373 	buf[15] = 1;
374 	os_memcpy(buf + 16, hdr, hdr_len);
375 	if (omac1_aes_128(key, buf, 16 + hdr_len, hdr_mac))
376 		goto fail;
377 
378 	if (aes_128_ctr_encrypt(key, nonce_mac, data, data_len))
379 		goto fail;
380 	buf[15] = 2;
381 	os_memcpy(buf + 16, data, data_len);
382 	if (omac1_aes_128(key, buf, 16 + data_len, data_mac))
383 		goto fail;
384 
385 	for (i = 0; i < BLOCK_SIZE; i++)
386 		tag[i] = nonce_mac[i] ^ data_mac[i] ^ hdr_mac[i];
387 
388 	ret = 0;
389 fail:
390 	os_free(buf);
391 
392 	return ret;
393 }
394 
395 
396 /**
397  * aes_128_eax_decrypt - AES-128 EAX mode decryption
398  * @key: Key for decryption (16 bytes)
399  * @nonce: Nonce for counter mode
400  * @nonce_len: Nonce length in bytes
401  * @hdr: Header data to be authenticity protected
402  * @hdr_len: Length of the header data bytes
403  * @data: Data to encrypt in-place
404  * @data_len: Length of data in bytes
405  * @tag: 16-byte tag value
406  * Returns: 0 on success, -1 on failure, -2 if tag does not match
407  */
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)408 int aes_128_eax_decrypt(const u8 *key, const u8 *nonce, size_t nonce_len,
409 			const u8 *hdr, size_t hdr_len,
410 			u8 *data, size_t data_len, const u8 *tag)
411 {
412 	u8 *buf;
413 	size_t buf_len;
414 	u8 nonce_mac[BLOCK_SIZE], hdr_mac[BLOCK_SIZE], data_mac[BLOCK_SIZE];
415 	int i;
416 
417 	if (nonce_len > data_len)
418 		buf_len = nonce_len;
419 	else
420 		buf_len = data_len;
421 	if (hdr_len > buf_len)
422 		buf_len = hdr_len;
423 	buf_len += 16;
424 
425 	buf = os_malloc(buf_len);
426 	if (buf == NULL)
427 		return -1;
428 
429 	os_memset(buf, 0, 15);
430 
431 	buf[15] = 0;
432 	os_memcpy(buf + 16, nonce, nonce_len);
433 	if (omac1_aes_128(key, buf, 16 + nonce_len, nonce_mac)) {
434 		os_free(buf);
435 		return -1;
436 	}
437 
438 	buf[15] = 1;
439 	os_memcpy(buf + 16, hdr, hdr_len);
440 	if (omac1_aes_128(key, buf, 16 + hdr_len, hdr_mac)) {
441 		os_free(buf);
442 		return -1;
443 	}
444 
445 	buf[15] = 2;
446 	os_memcpy(buf + 16, data, data_len);
447 	if (omac1_aes_128(key, buf, 16 + data_len, data_mac)) {
448 		os_free(buf);
449 		return -1;
450 	}
451 
452 	os_free(buf);
453 
454 	for (i = 0; i < BLOCK_SIZE; i++) {
455 		if (tag[i] != (nonce_mac[i] ^ data_mac[i] ^ hdr_mac[i]))
456 			return -2;
457 	}
458 
459 	return aes_128_ctr_encrypt(key, nonce_mac, data, data_len);
460 }
461 
462 #endif /* CONFIG_NO_AES_EAX */
463 
464 
465 #ifndef CONFIG_NO_AES_CBC
466 
467 /**
468  * aes_128_cbc_encrypt - AES-128 CBC encryption
469  * @key: Encryption key
470  * @iv: Encryption IV for CBC mode (16 bytes)
471  * @data: Data to encrypt in-place
472  * @data_len: Length of data in bytes (must be divisible by 16)
473  * Returns: 0 on success, -1 on failure
474  */
aes_128_cbc_encrypt(const u8 * key,const u8 * iv,u8 * data,size_t data_len)475 int aes_128_cbc_encrypt(const u8 *key, const u8 *iv, u8 *data, size_t data_len)
476 {
477 	void *ctx;
478 	u8 cbc[BLOCK_SIZE];
479 	u8 *pos = data;
480 	int i, j, blocks;
481 
482 	ctx = aes_encrypt_init(key, 16);
483 	if (ctx == NULL)
484 		return -1;
485 	os_memcpy(cbc, iv, BLOCK_SIZE);
486 
487 	blocks = data_len / BLOCK_SIZE;
488 	for (i = 0; i < blocks; i++) {
489 		for (j = 0; j < BLOCK_SIZE; j++)
490 			cbc[j] ^= pos[j];
491 		aes_encrypt(ctx, cbc, cbc);
492 		os_memcpy(pos, cbc, BLOCK_SIZE);
493 		pos += BLOCK_SIZE;
494 	}
495 	aes_encrypt_deinit(ctx);
496 	return 0;
497 }
498 
499 
500 /**
501  * aes_128_cbc_decrypt - AES-128 CBC decryption
502  * @key: Decryption key
503  * @iv: Decryption IV for CBC mode (16 bytes)
504  * @data: Data to decrypt in-place
505  * @data_len: Length of data in bytes (must be divisible by 16)
506  * Returns: 0 on success, -1 on failure
507  */
aes_128_cbc_decrypt(const u8 * key,const u8 * iv,u8 * data,size_t data_len)508 int aes_128_cbc_decrypt(const u8 *key, const u8 *iv, u8 *data, size_t data_len)
509 {
510 	void *ctx;
511 	u8 cbc[BLOCK_SIZE], tmp[BLOCK_SIZE];
512 	u8 *pos = data;
513 	int i, j, blocks;
514 
515 	ctx = aes_decrypt_init(key, 16);
516 	if (ctx == NULL)
517 		return -1;
518 	os_memcpy(cbc, iv, BLOCK_SIZE);
519 
520 	blocks = data_len / BLOCK_SIZE;
521 	for (i = 0; i < blocks; i++) {
522 		os_memcpy(tmp, pos, BLOCK_SIZE);
523 		aes_decrypt(ctx, pos, pos);
524 		for (j = 0; j < BLOCK_SIZE; j++)
525 			pos[j] ^= cbc[j];
526 		os_memcpy(cbc, tmp, BLOCK_SIZE);
527 		pos += BLOCK_SIZE;
528 	}
529 	aes_decrypt_deinit(ctx);
530 	return 0;
531 }
532 
533 #endif /* CONFIG_NO_AES_CBC */
534