1123870Sume/* crypto/aes/aes_wrap.c */ 2121748Sume/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL 3121748Sume * project. 4121748Sume */ 5121748Sume/* ==================================================================== 6121748Sume * Copyright (c) 2008 The OpenSSL Project. All rights reserved. 7121748Sume * 8121748Sume * Redistribution and use in source and binary forms, with or without 9121748Sume * modification, are permitted provided that the following conditions 10121748Sume * are met: 11121748Sume * 12121748Sume * 1. Redistributions of source code must retain the above copyright 13121748Sume * notice, this list of conditions and the following disclaimer. 14121748Sume * 15121748Sume * 2. Redistributions in binary form must reproduce the above copyright 16121748Sume * notice, this list of conditions and the following disclaimer in 17121748Sume * the documentation and/or other materials provided with the 18121748Sume * distribution. 19121748Sume * 20121748Sume * 3. All advertising materials mentioning features or use of this 21121748Sume * software must display the following acknowledgment: 22121748Sume * "This product includes software developed by the OpenSSL Project 23121748Sume * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" 24121748Sume * 25121748Sume * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 26121748Sume * endorse or promote products derived from this software without 27121748Sume * prior written permission. For written permission, please contact 28121748Sume * licensing@OpenSSL.org. 29121748Sume * 30121748Sume * 5. Products derived from this software may not be called "OpenSSL" 31121748Sume * nor may "OpenSSL" appear in their names without prior written 32121748Sume * permission of the OpenSSL Project. 33121748Sume * 34121748Sume * 6. Redistributions of any form whatsoever must retain the following 35121748Sume * acknowledgment: 36121748Sume * "This product includes software developed by the OpenSSL Project 37121748Sume * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" 38121748Sume * 39121748Sume * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 40121748Sume * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 41121748Sume * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 42121748Sume * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 43121748Sume * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 44121748Sume * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 45121748Sume * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 46121748Sume * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 47121748Sume * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 48121748Sume * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 49121748Sume * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 50121748Sume * OF THE POSSIBILITY OF SUCH DAMAGE. 51121748Sume * ==================================================================== 52121748Sume */ 53121748Sume 54121748Sume#include <openssl/local/cryptlib.h> 55121748Sume#include <openssl/aes.h> 56121748Sume#include <openssl/bio.h> 57121748Sume 58121748Sumestatic const unsigned char default_iv[] = { 59121748Sume 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 60121748Sume}; 61121748Sume 62241737Sedint AES_wrap_key(AES_KEY *key, const unsigned char *iv, 63121748Sume unsigned char *out, 64173412Skevlo const unsigned char *in, unsigned int inlen) 65173412Skevlo { 66173412Skevlo unsigned char *A, B[16], *R; 67173412Skevlo unsigned int i, j, t; 68173412Skevlo if ((inlen & 0x7) || (inlen < 8)) 69173412Skevlo return -1; 70173412Skevlo A = B; 71173412Skevlo t = 1; 72173412Skevlo memcpy(out + 8, in, inlen); 73173412Skevlo if (!iv) 74241134Seadler iv = default_iv; 75121748Sume 76121748Sume memcpy(A, iv, 8); 77241134Seadler 78121748Sume for (j = 0; j < 6; j++) 79121748Sume { 80121748Sume R = out + 8; 81121748Sume for (i = 0; i < inlen; i += 8, t++, R += 8) 82121748Sume { 83121748Sume memcpy(B + 8, R, 8); 84121748Sume AES_encrypt(B, B, key); 85121748Sume A[7] ^= (unsigned char)(t & 0xff); 86121748Sume if (t > 0xff) 87121748Sume { 88123714Ssuz A[6] ^= (unsigned char)((t >> 8) & 0xff); 89121748Sume A[5] ^= (unsigned char)((t >> 16) & 0xff); 90121748Sume A[4] ^= (unsigned char)((t >> 24) & 0xff); 91121748Sume } 92121748Sume memcpy(R, B + 8, 8); 93121748Sume } 94121748Sume } 95121748Sume memcpy(out, A, 8); 96121748Sume return inlen + 8; 97121748Sume } 98121748Sume 99121748Sumeint AES_unwrap_key(AES_KEY *key, const unsigned char *iv, 100121748Sume unsigned char *out, 101121748Sume const unsigned char *in, unsigned int inlen) 102121748Sume { 103121748Sume unsigned char *A, B[16], *R; 104121748Sume unsigned int i, j, t; 105121748Sume inlen -= 8; 106121748Sume if (inlen & 0x7) 107121748Sume return -1; 108241134Seadler if (inlen < 8) 109121748Sume return -1; 110121748Sume A = B; 111121748Sume t = 6 * (inlen >> 3); 112241134Seadler memcpy(A, in, 8); 113121748Sume memcpy(out, in + 8, inlen); 114121748Sume for (j = 0; j < 6; j++) 115121748Sume { 116121748Sume R = out + inlen - 8; 117121748Sume for (i = 0; i < inlen; i += 8, t--, R -= 8) 118121748Sume { 119123870Sume A[7] ^= (unsigned char)(t & 0xff); 120123870Sume if (t > 0xff) 121123870Sume { 122123870Sume A[6] ^= (unsigned char)((t >> 8) & 0xff); 123121748Sume A[5] ^= (unsigned char)((t >> 16) & 0xff); 124121748Sume A[4] ^= (unsigned char)((t >> 24) & 0xff); 125121748Sume } 126121748Sume memcpy(B + 8, R, 8); 127121748Sume AES_decrypt(B, B, key); 128121748Sume memcpy(R, B + 8, 8); 129121748Sume } 130121748Sume } 131121748Sume if (!iv) 132241134Seadler iv = default_iv; 133241134Seadler if (memcmp(A, iv, 8)) 134121748Sume { 135121748Sume OPENSSL_cleanse(out, inlen); 136121748Sume return 0; 137121748Sume } 138121748Sume return inlen; 139121748Sume } 140121748Sume 141121748Sume#ifdef AES_WRAP_TEST 142121748Sume 143121748Sumeint AES_wrap_unwrap_test(const unsigned char *kek, int keybits, 144121748Sume const unsigned char *iv, 145121748Sume const unsigned char *eout, 146241134Seadler const unsigned char *key, int keylen) 147121748Sume { 148121748Sume unsigned char *otmp = NULL, *ptmp = NULL; 149121748Sume int r, ret = 0; 150121748Sume AES_KEY wctx; 151121748Sume otmp = OPENSSL_malloc(keylen + 8); 152121748Sume ptmp = OPENSSL_malloc(keylen); 153121748Sume if (!otmp || !ptmp) 154121748Sume return 0; 155121748Sume if (AES_set_encrypt_key(kek, keybits, &wctx)) 156121748Sume goto err; 157121748Sume r = AES_wrap_key(&wctx, iv, otmp, key, keylen); 158121748Sume if (r <= 0) 159121748Sume goto err; 160121748Sume 161121748Sume if (eout && memcmp(eout, otmp, keylen)) 162121748Sume goto err; 163121748Sume 164121748Sume if (AES_set_decrypt_key(kek, keybits, &wctx)) 165121748Sume goto err; 166121748Sume r = AES_unwrap_key(&wctx, iv, ptmp, otmp, r); 167121748Sume 168121748Sume if (memcmp(key, ptmp, keylen)) 169121748Sume goto err; 170121748Sume 171121748Sume ret = 1; 172121748Sume 173121748Sume err: 174121748Sume if (otmp) 175121748Sume OPENSSL_free(otmp); 176121748Sume if (ptmp) 177121748Sume OPENSSL_free(ptmp); 178121748Sume 179121748Sume return ret; 180121748Sume 181121748Sume } 182121748Sume 183121748Sume 184121748Sume 185121748Sumeint main(int argc, char **argv) 186121748Sume{ 187121748Sume 188121748Sumestatic const unsigned char kek[] = { 189121748Sume 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 190121748Sume 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 191121748Sume 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 192121748Sume 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f 193121748Sume}; 194121748Sume 195121748Sumestatic const unsigned char key[] = { 196121748Sume 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 197121748Sume 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, 198121748Sume 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 199121748Sume 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f 200121748Sume}; 201121748Sume 202241134Seadlerstatic const unsigned char e1[] = { 203121748Sume 0x1f, 0xa6, 0x8b, 0x0a, 0x81, 0x12, 0xb4, 0x47, 204121748Sume 0xae, 0xf3, 0x4b, 0xd8, 0xfb, 0x5a, 0x7b, 0x82, 205121748Sume 0x9d, 0x3e, 0x86, 0x23, 0x71, 0xd2, 0xcf, 0xe5 206121748Sume}; 207121748Sume 208121748Sumestatic const unsigned char e2[] = { 209121748Sume 0x96, 0x77, 0x8b, 0x25, 0xae, 0x6c, 0xa4, 0x35, 210121748Sume 0xf9, 0x2b, 0x5b, 0x97, 0xc0, 0x50, 0xae, 0xd2, 211121748Sume 0x46, 0x8a, 0xb8, 0xa1, 0x7a, 0xd8, 0x4e, 0x5d 212121748Sume}; 213121748Sume 214121748Sumestatic const unsigned char e3[] = { 215121748Sume 0x64, 0xe8, 0xc3, 0xf9, 0xce, 0x0f, 0x5b, 0xa2, 216121748Sume 0x63, 0xe9, 0x77, 0x79, 0x05, 0x81, 0x8a, 0x2a, 217121748Sume 0x93, 0xc8, 0x19, 0x1e, 0x7d, 0x6e, 0x8a, 0xe7 218121748Sume}; 219121748Sume 220121748Sumestatic const unsigned char e4[] = { 221121748Sume 0x03, 0x1d, 0x33, 0x26, 0x4e, 0x15, 0xd3, 0x32, 222121748Sume 0x68, 0xf2, 0x4e, 0xc2, 0x60, 0x74, 0x3e, 0xdc, 223121748Sume 0xe1, 0xc6, 0xc7, 0xdd, 0xee, 0x72, 0x5a, 0x93, 224121748Sume 0x6b, 0xa8, 0x14, 0x91, 0x5c, 0x67, 0x62, 0xd2 225121748Sume}; 226121748Sume 227121748Sumestatic const unsigned char e5[] = { 228121748Sume 0xa8, 0xf9, 0xbc, 0x16, 0x12, 0xc6, 0x8b, 0x3f, 229121748Sume 0xf6, 0xe6, 0xf4, 0xfb, 0xe3, 0x0e, 0x71, 0xe4, 230121748Sume 0x76, 0x9c, 0x8b, 0x80, 0xa3, 0x2c, 0xb8, 0x95, 231121748Sume 0x8c, 0xd5, 0xd1, 0x7d, 0x6b, 0x25, 0x4d, 0xa1 232121748Sume}; 233121748Sume 234121748Sumestatic const unsigned char e6[] = { 235121748Sume 0x28, 0xc9, 0xf4, 0x04, 0xc4, 0xb8, 0x10, 0xf4, 236121748Sume 0xcb, 0xcc, 0xb3, 0x5c, 0xfb, 0x87, 0xf8, 0x26, 237121748Sume 0x3f, 0x57, 0x86, 0xe2, 0xd8, 0x0e, 0xd3, 0x26, 238121748Sume 0xcb, 0xc7, 0xf0, 0xe7, 0x1a, 0x99, 0xf4, 0x3b, 239121748Sume 0xfb, 0x98, 0x8b, 0x9b, 0x7a, 0x02, 0xdd, 0x21 240121748Sume}; 241121748Sume 242121748Sume AES_KEY wctx, xctx; 243121748Sume int ret; 244121748Sume ret = AES_wrap_unwrap_test(kek, 128, NULL, e1, key, 16); 245121748Sume fprintf(stderr, "Key test result %d\n", ret); 246121748Sume ret = AES_wrap_unwrap_test(kek, 192, NULL, e2, key, 16); 247121748Sume fprintf(stderr, "Key test result %d\n", ret); 248121748Sume ret = AES_wrap_unwrap_test(kek, 256, NULL, e3, key, 16); 249121748Sume fprintf(stderr, "Key test result %d\n", ret); 250121748Sume ret = AES_wrap_unwrap_test(kek, 192, NULL, e4, key, 24); 251121748Sume fprintf(stderr, "Key test result %d\n", ret); 252121748Sume ret = AES_wrap_unwrap_test(kek, 256, NULL, e5, key, 24); 253121748Sume fprintf(stderr, "Key test result %d\n", ret); 254121748Sume ret = AES_wrap_unwrap_test(kek, 256, NULL, e6, key, 32); 255121748Sume fprintf(stderr, "Key test result %d\n", ret); 256121748Sume} 257241134Seadler 258121748Sume 259121748Sume#endif 260121748Sume