1e5b75505Sopenharmony_ci/* 2e5b75505Sopenharmony_ci * AES Key Wrap Algorithm (RFC3394) 3e5b75505Sopenharmony_ci * 4e5b75505Sopenharmony_ci * Copyright (c) 2003-2007, Jouni Malinen <j@w1.fi> 5e5b75505Sopenharmony_ci * 6e5b75505Sopenharmony_ci * This software may be distributed under the terms of the BSD license. 7e5b75505Sopenharmony_ci * See README for more details. 8e5b75505Sopenharmony_ci */ 9e5b75505Sopenharmony_ci 10e5b75505Sopenharmony_ci#include "includes.h" 11e5b75505Sopenharmony_ci 12e5b75505Sopenharmony_ci#include "common.h" 13e5b75505Sopenharmony_ci#include "aes.h" 14e5b75505Sopenharmony_ci#include "aes_wrap.h" 15e5b75505Sopenharmony_ci 16e5b75505Sopenharmony_ci/** 17e5b75505Sopenharmony_ci * aes_wrap - Wrap keys with AES Key Wrap Algorithm (RFC3394) 18e5b75505Sopenharmony_ci * @kek: Key encryption key (KEK) 19e5b75505Sopenharmony_ci * @kek_len: Length of KEK in octets 20e5b75505Sopenharmony_ci * @n: Length of the plaintext key in 64-bit units; e.g., 2 = 128-bit = 16 21e5b75505Sopenharmony_ci * bytes 22e5b75505Sopenharmony_ci * @plain: Plaintext key to be wrapped, n * 64 bits 23e5b75505Sopenharmony_ci * @cipher: Wrapped key, (n + 1) * 64 bits 24e5b75505Sopenharmony_ci * Returns: 0 on success, -1 on failure 25e5b75505Sopenharmony_ci */ 26e5b75505Sopenharmony_ciint aes_wrap(const u8 *kek, size_t kek_len, int n, const u8 *plain, u8 *cipher) 27e5b75505Sopenharmony_ci{ 28e5b75505Sopenharmony_ci u8 *a, *r, b[AES_BLOCK_SIZE]; 29e5b75505Sopenharmony_ci int i, j; 30e5b75505Sopenharmony_ci void *ctx; 31e5b75505Sopenharmony_ci unsigned int t; 32e5b75505Sopenharmony_ci 33e5b75505Sopenharmony_ci a = cipher; 34e5b75505Sopenharmony_ci r = cipher + 8; 35e5b75505Sopenharmony_ci 36e5b75505Sopenharmony_ci /* 1) Initialize variables. */ 37e5b75505Sopenharmony_ci os_memset(a, 0xa6, 8); 38e5b75505Sopenharmony_ci os_memcpy(r, plain, 8 * n); 39e5b75505Sopenharmony_ci 40e5b75505Sopenharmony_ci ctx = aes_encrypt_init(kek, kek_len); 41e5b75505Sopenharmony_ci if (ctx == NULL) 42e5b75505Sopenharmony_ci return -1; 43e5b75505Sopenharmony_ci 44e5b75505Sopenharmony_ci /* 2) Calculate intermediate values. 45e5b75505Sopenharmony_ci * For j = 0 to 5 46e5b75505Sopenharmony_ci * For i=1 to n 47e5b75505Sopenharmony_ci * B = AES(K, A | R[i]) 48e5b75505Sopenharmony_ci * A = MSB(64, B) ^ t where t = (n*j)+i 49e5b75505Sopenharmony_ci * R[i] = LSB(64, B) 50e5b75505Sopenharmony_ci */ 51e5b75505Sopenharmony_ci for (j = 0; j <= 5; j++) { 52e5b75505Sopenharmony_ci r = cipher + 8; 53e5b75505Sopenharmony_ci for (i = 1; i <= n; i++) { 54e5b75505Sopenharmony_ci os_memcpy(b, a, 8); 55e5b75505Sopenharmony_ci os_memcpy(b + 8, r, 8); 56e5b75505Sopenharmony_ci aes_encrypt(ctx, b, b); 57e5b75505Sopenharmony_ci os_memcpy(a, b, 8); 58e5b75505Sopenharmony_ci t = n * j + i; 59e5b75505Sopenharmony_ci a[7] ^= t; 60e5b75505Sopenharmony_ci a[6] ^= t >> 8; 61e5b75505Sopenharmony_ci a[5] ^= t >> 16; 62e5b75505Sopenharmony_ci a[4] ^= t >> 24; 63e5b75505Sopenharmony_ci os_memcpy(r, b + 8, 8); 64e5b75505Sopenharmony_ci r += 8; 65e5b75505Sopenharmony_ci } 66e5b75505Sopenharmony_ci } 67e5b75505Sopenharmony_ci aes_encrypt_deinit(ctx); 68e5b75505Sopenharmony_ci 69e5b75505Sopenharmony_ci /* 3) Output the results. 70e5b75505Sopenharmony_ci * 71e5b75505Sopenharmony_ci * These are already in @cipher due to the location of temporary 72e5b75505Sopenharmony_ci * variables. 73e5b75505Sopenharmony_ci */ 74e5b75505Sopenharmony_ci 75e5b75505Sopenharmony_ci return 0; 76e5b75505Sopenharmony_ci} 77