18d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* 29ead16e203b81d44a2d84eadc2901ceeb7daf805Dmitry Shmidt * AES Key Wrap Algorithm (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/** 179ead16e203b81d44a2d84eadc2901ceeb7daf805Dmitry Shmidt * aes_wrap - Wrap keys with AES Key Wrap Algorithm (RFC3394) 189ead16e203b81d44a2d84eadc2901ceeb7daf805Dmitry Shmidt * @kek: Key encryption key (KEK) 199ead16e203b81d44a2d84eadc2901ceeb7daf805Dmitry Shmidt * @kek_len: Length of KEK in octets 208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @n: Length of the plaintext key in 64-bit units; e.g., 2 = 128-bit = 16 218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * bytes 228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @plain: Plaintext key to be wrapped, n * 64 bits 238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @cipher: Wrapped key, (n + 1) * 64 bits 248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 0 on success, -1 on failure 258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 269ead16e203b81d44a2d84eadc2901ceeb7daf805Dmitry Shmidtint aes_wrap(const u8 *kek, size_t kek_len, int n, const u8 *plain, u8 *cipher) 278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 289ead16e203b81d44a2d84eadc2901ceeb7daf805Dmitry Shmidt u8 *a, *r, b[AES_BLOCK_SIZE]; 298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int i, j; 308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt void *ctx; 319ead16e203b81d44a2d84eadc2901ceeb7daf805Dmitry Shmidt unsigned int t; 328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt a = cipher; 348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt r = cipher + 8; 358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 1) Initialize variables. */ 378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(a, 0xa6, 8); 388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(r, plain, 8 * n); 398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 409ead16e203b81d44a2d84eadc2901ceeb7daf805Dmitry Shmidt ctx = aes_encrypt_init(kek, kek_len); 418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ctx == NULL) 428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 2) Calculate intermediate values. 458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * For j = 0 to 5 468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * For i=1 to n 478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * B = AES(K, A | R[i]) 488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * A = MSB(64, B) ^ t where t = (n*j)+i 498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * R[i] = LSB(64, B) 508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (j = 0; j <= 5; j++) { 528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt r = cipher + 8; 538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 1; i <= n; i++) { 548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(b, a, 8); 558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(b + 8, r, 8); 568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt aes_encrypt(ctx, b, b); 578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(a, b, 8); 589ead16e203b81d44a2d84eadc2901ceeb7daf805Dmitry Shmidt t = n * j + i; 599ead16e203b81d44a2d84eadc2901ceeb7daf805Dmitry Shmidt a[7] ^= t; 609ead16e203b81d44a2d84eadc2901ceeb7daf805Dmitry Shmidt a[6] ^= t >> 8; 619ead16e203b81d44a2d84eadc2901ceeb7daf805Dmitry Shmidt a[5] ^= t >> 16; 629ead16e203b81d44a2d84eadc2901ceeb7daf805Dmitry Shmidt a[4] ^= t >> 24; 638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(r, b + 8, 8); 648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt r += 8; 658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt aes_encrypt_deinit(ctx); 688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 3) Output the results. 708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * These are already in @cipher due to the location of temporary 728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * variables. 738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 77