18d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* 28d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * AES key unwrap (128-bit KEK, RFC3394) 38d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 48d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Copyright (c) 2003-2007, Jouni Malinen <j@w1.fi> 58d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 6c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * This software may be distributed under the terms of the BSD license. 7c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * See README for more details. 88d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 98d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "includes.h" 118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "common.h" 138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "aes.h" 148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "aes_wrap.h" 158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * aes_unwrap - Unwrap key with AES Key Wrap Algorithm (128-bit KEK) (RFC3394) 188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @kek: Key encryption key (KEK) 198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @n: Length of the plaintext key in 64-bit units; e.g., 2 = 128-bit = 16 208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * bytes 218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @cipher: Wrapped key to be unwrapped, (n + 1) * 64 bits 228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @plain: Plaintext key, n * 64 bits 238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 0 on success, -1 on failure (e.g., integrity verification failed) 248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint aes_unwrap(const u8 *kek, int n, const u8 *cipher, u8 *plain) 268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 a[8], *r, b[16]; 288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int i, j; 298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt void *ctx; 308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 1) Initialize variables. */ 328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(a, cipher, 8); 338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt r = plain; 348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(r, cipher + 8, 8 * n); 358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ctx = aes_decrypt_init(kek, 16); 378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ctx == NULL) 388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 2) Compute intermediate values. 418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * For j = 5 to 0 428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * For i = n to 1 438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * B = AES-1(K, (A ^ t) | R[i]) where t = n*j+i 448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * A = MSB(64, B) 458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * R[i] = LSB(64, B) 468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (j = 5; j >= 0; j--) { 488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt r = plain + (n - 1) * 8; 498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = n; i >= 1; i--) { 508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(b, a, 8); 518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt b[7] ^= n * j + i; 528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(b + 8, r, 8); 548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt aes_decrypt(ctx, b, b); 558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(a, b, 8); 568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(r, b + 8, 8); 578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt r -= 8; 588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt aes_decrypt_deinit(ctx); 618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 3) Output results. 638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * These are already in @plain due to the location of temporary 658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * variables. Just verify that the IV matches with the expected value. 668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < 8; i++) { 688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (a[i] != 0xa6) 698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 74