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