1305549Sjhb/* crypto/aes/aes_wrap.c */ 2305549Sjhb/* 3305549Sjhb * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL 4305549Sjhb * project. 5305549Sjhb */ 6305549Sjhb/* ==================================================================== 7305549Sjhb * Copyright (c) 2008 The OpenSSL Project. All rights reserved. 8305549Sjhb * 9305549Sjhb * Redistribution and use in source and binary forms, with or without 10305549Sjhb * modification, are permitted provided that the following conditions 11305549Sjhb * are met: 12305549Sjhb * 13305549Sjhb * 1. Redistributions of source code must retain the above copyright 14305549Sjhb * notice, this list of conditions and the following disclaimer. 15305549Sjhb * 16305549Sjhb * 2. Redistributions in binary form must reproduce the above copyright 17305549Sjhb * notice, this list of conditions and the following disclaimer in 18305549Sjhb * the documentation and/or other materials provided with the 19305549Sjhb * distribution. 20305549Sjhb * 21305549Sjhb * 3. All advertising materials mentioning features or use of this 22305549Sjhb * software must display the following acknowledgment: 23305549Sjhb * "This product includes software developed by the OpenSSL Project 24305549Sjhb * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" 25305549Sjhb * 26305549Sjhb * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 27305549Sjhb * endorse or promote products derived from this software without 28305549Sjhb * prior written permission. For written permission, please contact 29305549Sjhb * licensing@OpenSSL.org. 30305549Sjhb * 31305549Sjhb * 5. Products derived from this software may not be called "OpenSSL" 32305549Sjhb * nor may "OpenSSL" appear in their names without prior written 33305549Sjhb * permission of the OpenSSL Project. 34305549Sjhb * 35309529Skib * 6. Redistributions of any form whatsoever must retain the following 36305549Sjhb * acknowledgment: 37305549Sjhb * "This product includes software developed by the OpenSSL Project 38309447Sjhb * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" 39305549Sjhb * 40305549Sjhb * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 41305549Sjhb * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 42305549Sjhb * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 43305549Sjhb * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 44305549Sjhb * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 45305549Sjhb * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 46305549Sjhb * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 47305549Sjhb * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 48305549Sjhb * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 49305549Sjhb * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 50305549Sjhb * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 51305549Sjhb * OF THE POSSIBILITY OF SUCH DAMAGE. 52305549Sjhb * ==================================================================== 53305549Sjhb */ 54305549Sjhb 55305549Sjhb#include "cryptlib.h" 56305549Sjhb#include <openssl/aes.h> 57305549Sjhb#include <openssl/bio.h> 58305549Sjhb 59305549Sjhbstatic const unsigned char default_iv[] = { 60305549Sjhb 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 61305549Sjhb}; 62305549Sjhb 63305549Sjhbint AES_wrap_key(AES_KEY *key, const unsigned char *iv, 64305549Sjhb unsigned char *out, 65305549Sjhb const unsigned char *in, unsigned int inlen) 66305549Sjhb{ 67305549Sjhb unsigned char *A, B[16], *R; 68305549Sjhb unsigned int i, j, t; 69305549Sjhb if ((inlen & 0x7) || (inlen < 8)) 70305549Sjhb return -1; 71305549Sjhb A = B; 72305549Sjhb t = 1; 73305549Sjhb memcpy(out + 8, in, inlen); 74305549Sjhb if (!iv) 75305549Sjhb iv = default_iv; 76305549Sjhb 77305549Sjhb memcpy(A, iv, 8); 78305549Sjhb 79305549Sjhb for (j = 0; j < 6; j++) { 80305549Sjhb R = out + 8; 81305549Sjhb for (i = 0; i < inlen; i += 8, t++, R += 8) { 82305549Sjhb memcpy(B + 8, R, 8); 83305549Sjhb AES_encrypt(B, B, key); 84305549Sjhb A[7] ^= (unsigned char)(t & 0xff); 85305549Sjhb if (t > 0xff) { 86305549Sjhb A[6] ^= (unsigned char)((t >> 8) & 0xff); 87305549Sjhb A[5] ^= (unsigned char)((t >> 16) & 0xff); 88305549Sjhb A[4] ^= (unsigned char)((t >> 24) & 0xff); 89305549Sjhb } 90305549Sjhb memcpy(R, B + 8, 8); 91305549Sjhb } 92305549Sjhb } 93305549Sjhb memcpy(out, A, 8); 94305549Sjhb return inlen + 8; 95305549Sjhb} 96305549Sjhb 97305549Sjhbint AES_unwrap_key(AES_KEY *key, const unsigned char *iv, 98305549Sjhb unsigned char *out, 99305549Sjhb const unsigned char *in, unsigned int inlen) 100305549Sjhb{ 101305549Sjhb unsigned char *A, B[16], *R; 102305549Sjhb unsigned int i, j, t; 103305549Sjhb inlen -= 8; 104305549Sjhb if (inlen & 0x7) 105305549Sjhb return -1; 106305549Sjhb if (inlen < 8) 107305549Sjhb return -1; 108305549Sjhb A = B; 109305549Sjhb t = 6 * (inlen >> 3); 110305549Sjhb memcpy(A, in, 8); 111305549Sjhb memcpy(out, in + 8, inlen); 112305549Sjhb for (j = 0; j < 6; j++) { 113305549Sjhb R = out + inlen - 8; 114305549Sjhb for (i = 0; i < inlen; i += 8, t--, R -= 8) { 115305549Sjhb A[7] ^= (unsigned char)(t & 0xff); 116309560Sjhb if (t > 0xff) { 117318844Snp A[6] ^= (unsigned char)((t >> 8) & 0xff); 118309560Sjhb A[5] ^= (unsigned char)((t >> 16) & 0xff); 119309560Sjhb A[4] ^= (unsigned char)((t >> 24) & 0xff); 120318844Snp } 121318844Snp memcpy(B + 8, R, 8); 122318844Snp AES_decrypt(B, B, key); 123318844Snp memcpy(R, B + 8, 8); 124309560Sjhb } 125309560Sjhb } 126318844Snp if (!iv) 127309560Sjhb iv = default_iv; 128318844Snp if (memcmp(A, iv, 8)) { 129318844Snp OPENSSL_cleanse(out, inlen); 130318844Snp return 0; 131318844Snp } 132318844Snp return inlen; 133318844Snp} 134318844Snp 135318844Snp#ifdef AES_WRAP_TEST 136305549Sjhb 137305549Sjhbint AES_wrap_unwrap_test(const unsigned char *kek, int keybits, 138305549Sjhb const unsigned char *iv, 139305549Sjhb const unsigned char *eout, 140305549Sjhb const unsigned char *key, int keylen) 141305549Sjhb{ 142305549Sjhb unsigned char *otmp = NULL, *ptmp = NULL; 143305549Sjhb int r, ret = 0; 144305549Sjhb AES_KEY wctx; 145305549Sjhb otmp = OPENSSL_malloc(keylen + 8); 146305549Sjhb ptmp = OPENSSL_malloc(keylen); 147305549Sjhb if (!otmp || !ptmp) 148305549Sjhb return 0; 149309449Sjhb if (AES_set_encrypt_key(kek, keybits, &wctx)) 150305549Sjhb goto err; 151305549Sjhb r = AES_wrap_key(&wctx, iv, otmp, key, keylen); 152305549Sjhb if (r <= 0) 153305549Sjhb goto err; 154305549Sjhb 155305549Sjhb if (eout && memcmp(eout, otmp, keylen)) 156305549Sjhb goto err; 157305549Sjhb 158305549Sjhb if (AES_set_decrypt_key(kek, keybits, &wctx)) 159305549Sjhb goto err; 160305549Sjhb r = AES_unwrap_key(&wctx, iv, ptmp, otmp, r); 161305549Sjhb 162305549Sjhb if (memcmp(key, ptmp, keylen)) 163305549Sjhb goto err; 164305549Sjhb 165309449Sjhb ret = 1; 166305549Sjhb 167305549Sjhb err: 168305549Sjhb if (otmp) 169305549Sjhb OPENSSL_free(otmp); 170305549Sjhb if (ptmp) 171305549Sjhb OPENSSL_free(ptmp); 172305549Sjhb 173305549Sjhb return ret; 174305549Sjhb 175305549Sjhb} 176305549Sjhb 177305549Sjhbint main(int argc, char **argv) 178309560Sjhb{ 179309560Sjhb 180309560Sjhb static const unsigned char kek[] = { 181309560Sjhb 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 182309560Sjhb 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 183309560Sjhb 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 184309560Sjhb 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f 185309560Sjhb }; 186309560Sjhb 187309560Sjhb static const unsigned char key[] = { 188309560Sjhb 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 189309560Sjhb 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, 190309560Sjhb 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 191309560Sjhb 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f 192309560Sjhb }; 193309560Sjhb 194305549Sjhb static const unsigned char e1[] = { 195305549Sjhb 0x1f, 0xa6, 0x8b, 0x0a, 0x81, 0x12, 0xb4, 0x47, 196305549Sjhb 0xae, 0xf3, 0x4b, 0xd8, 0xfb, 0x5a, 0x7b, 0x82, 197305549Sjhb 0x9d, 0x3e, 0x86, 0x23, 0x71, 0xd2, 0xcf, 0xe5 198305549Sjhb }; 199305549Sjhb 200305549Sjhb static const unsigned char e2[] = { 201305549Sjhb 0x96, 0x77, 0x8b, 0x25, 0xae, 0x6c, 0xa4, 0x35, 202305549Sjhb 0xf9, 0x2b, 0x5b, 0x97, 0xc0, 0x50, 0xae, 0xd2, 203305549Sjhb 0x46, 0x8a, 0xb8, 0xa1, 0x7a, 0xd8, 0x4e, 0x5d 204305549Sjhb }; 205305549Sjhb 206305549Sjhb static const unsigned char e3[] = { 207305549Sjhb 0x64, 0xe8, 0xc3, 0xf9, 0xce, 0x0f, 0x5b, 0xa2, 208305549Sjhb 0x63, 0xe9, 0x77, 0x79, 0x05, 0x81, 0x8a, 0x2a, 209305549Sjhb 0x93, 0xc8, 0x19, 0x1e, 0x7d, 0x6e, 0x8a, 0xe7 210305549Sjhb }; 211305549Sjhb 212305549Sjhb static const unsigned char e4[] = { 213305549Sjhb 0x03, 0x1d, 0x33, 0x26, 0x4e, 0x15, 0xd3, 0x32, 214305549Sjhb 0x68, 0xf2, 0x4e, 0xc2, 0x60, 0x74, 0x3e, 0xdc, 215305549Sjhb 0xe1, 0xc6, 0xc7, 0xdd, 0xee, 0x72, 0x5a, 0x93, 216305549Sjhb 0x6b, 0xa8, 0x14, 0x91, 0x5c, 0x67, 0x62, 0xd2 217305549Sjhb }; 218305549Sjhb 219305549Sjhb static const unsigned char e5[] = { 220305549Sjhb 0xa8, 0xf9, 0xbc, 0x16, 0x12, 0xc6, 0x8b, 0x3f, 221305549Sjhb 0xf6, 0xe6, 0xf4, 0xfb, 0xe3, 0x0e, 0x71, 0xe4, 222305549Sjhb 0x76, 0x9c, 0x8b, 0x80, 0xa3, 0x2c, 0xb8, 0x95, 223305549Sjhb 0x8c, 0xd5, 0xd1, 0x7d, 0x6b, 0x25, 0x4d, 0xa1 224305549Sjhb }; 225305549Sjhb 226305549Sjhb static const unsigned char e6[] = { 227305549Sjhb 0x28, 0xc9, 0xf4, 0x04, 0xc4, 0xb8, 0x10, 0xf4, 228305549Sjhb 0xcb, 0xcc, 0xb3, 0x5c, 0xfb, 0x87, 0xf8, 0x26, 229305549Sjhb 0x3f, 0x57, 0x86, 0xe2, 0xd8, 0x0e, 0xd3, 0x26, 230305549Sjhb 0xcb, 0xc7, 0xf0, 0xe7, 0x1a, 0x99, 0xf4, 0x3b, 231305549Sjhb 0xfb, 0x98, 0x8b, 0x9b, 0x7a, 0x02, 0xdd, 0x21 232305549Sjhb }; 233305549Sjhb 234305549Sjhb AES_KEY wctx, xctx; 235305549Sjhb int ret; 236305549Sjhb ret = AES_wrap_unwrap_test(kek, 128, NULL, e1, key, 16); 237305549Sjhb fprintf(stderr, "Key test result %d\n", ret); 238305549Sjhb ret = AES_wrap_unwrap_test(kek, 192, NULL, e2, key, 16); 239305549Sjhb fprintf(stderr, "Key test result %d\n", ret); 240305549Sjhb ret = AES_wrap_unwrap_test(kek, 256, NULL, e3, key, 16); 241305549Sjhb fprintf(stderr, "Key test result %d\n", ret); 242305549Sjhb ret = AES_wrap_unwrap_test(kek, 192, NULL, e4, key, 24); 243305549Sjhb fprintf(stderr, "Key test result %d\n", ret); 244305549Sjhb ret = AES_wrap_unwrap_test(kek, 256, NULL, e5, key, 24); 245305549Sjhb fprintf(stderr, "Key test result %d\n", ret); 246305549Sjhb ret = AES_wrap_unwrap_test(kek, 256, NULL, e6, key, 32); 247305549Sjhb fprintf(stderr, "Key test result %d\n", ret); 248305549Sjhb} 249305549Sjhb 250305549Sjhb#endif 251305549Sjhb