And so it begins...
[openssl.git] / crypto / aes / aes_wrap.c
1 /* crypto/aes/aes_wrap.c */
2 /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
3  * project.
4  */
5 /* ====================================================================
6  * Copyright (c) 2008 The OpenSSL Project.  All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer. 
14  *
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in
17  *    the documentation and/or other materials provided with the
18  *    distribution.
19  *
20  * 3. All advertising materials mentioning features or use of this
21  *    software must display the following acknowledgment:
22  *    "This product includes software developed by the OpenSSL Project
23  *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
24  *
25  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26  *    endorse or promote products derived from this software without
27  *    prior written permission. For written permission, please contact
28  *    licensing@OpenSSL.org.
29  *
30  * 5. Products derived from this software may not be called "OpenSSL"
31  *    nor may "OpenSSL" appear in their names without prior written
32  *    permission of the OpenSSL Project.
33  *
34  * 6. Redistributions of any form whatsoever must retain the following
35  *    acknowledgment:
36  *    "This product includes software developed by the OpenSSL Project
37  *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
38  *
39  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
43  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50  * OF THE POSSIBILITY OF SUCH DAMAGE.
51  * ====================================================================
52  */
53
54 #include "cryptlib.h"
55 #include <openssl/aes.h>
56 #include <openssl/bio.h>
57
58 int AES_wrap_key(AES_KEY *key, const unsigned char *iv,
59                 unsigned char *out,
60                 const unsigned char *in, unsigned int inlen)
61         {
62         unsigned char *A, B[16], *R;
63         unsigned int i, j, t;
64         if ((inlen & 0x7) || (inlen < 8))
65                 return -1;
66         A = B;
67         t = 1;
68         memcpy(out + 8, in, inlen);
69         if (!iv)
70                 iv = default_iv;
71
72         memcpy(A, iv, 8);
73
74         for (j = 0; j < 6; j++)
75                 {
76                 R = out + 8;
77                 for (i = 0; i < inlen; i += 8, t++, R += 8)
78                         {
79                         memcpy(B + 8, R, 8);
80                         AES_encrypt(B, B, key);
81                         A[7] ^= (unsigned char)(t & 0xff);
82                         if (t > 0xff)   
83                                 {
84                                 A[6] ^= (unsigned char)((t & 0xff) >> 8);
85                                 A[5] ^= (unsigned char)((t & 0xff) >> 16);
86                                 A[4] ^= (unsigned char)((t & 0xff) >> 24);
87                                 }
88                         memcpy(R, B + 8, 8);
89                         }
90                 }
91         memcpy(out, A, 8);
92         return inlen + 8;
93         }
94
95 int AES_unwrap_key(AES_KEY *key, const unsigned char *iv,
96                 unsigned char *out,
97                 const unsigned char *in, unsigned int inlen)
98         {
99         unsigned char *A, B[16], *R;
100         unsigned int i, j, t;
101         inlen -= 8;
102         if (inlen & 0x7)
103                 return -1;
104         if (inlen < 8)
105                 return -1;
106         A = B;
107         t =  6 * (inlen >> 3);
108         memcpy(A, in, 8);
109         memcpy(out, in + 8, inlen);
110         for (j = 0; j < 6; j++)
111                 {
112                 R = out + inlen - 8;
113                 for (i = 0; i < inlen; i += 8, t--, R -= 8)
114                         {
115                         A[7] ^= (unsigned char)(t & 0xff);
116                         if (t > 0xff)   
117                                 {
118                                 A[6] ^= (unsigned char)((t & 0xff) >> 8);
119                                 A[5] ^= (unsigned char)((t & 0xff) >> 16);
120                                 A[4] ^= (unsigned char)((t & 0xff) >> 24);
121                                 }
122                         memcpy(B + 8, R, 8);
123                         AES_decrypt(B, B, key);
124                         memcpy(R, B + 8, 8);
125                         }
126                 }
127         if (!iv)
128                 iv = default_iv;
129         if (memcmp(A, iv, 8))
130                 {
131                 OPENSSL_cleanse(out, inlen);
132                 return 0;
133                 }
134         return inlen;
135         }
136
137 #ifdef AES_WRAP_TEST
138
139 int AES_wrap_unwrap_test(const unsigned char *kek, int keybits,
140                          const unsigned char *iv,
141                          const unsigned char *eout,
142                          const unsigned char *key, int keylen)
143         {
144         unsigned char *otmp = NULL, *ptmp = NULL;
145         int r, ret = 0;
146         AES_KEY wctx;
147         otmp = OPENSSL_malloc(keylen + 8);
148         ptmp = OPENSSL_malloc(keylen);
149         if (!otmp || !ptmp)
150                 return 0;
151         if (AES_set_encrypt_key(kek, keybits, &wctx))
152                 goto err;
153         r = AES_wrap_key(&wctx, iv, otmp, key, keylen);
154         if (r <= 0)
155                 goto err;
156
157         if (eout && memcmp(eout, otmp, keylen))
158                 goto err;
159                 
160         if (AES_set_decrypt_key(kek, keybits, &wctx))
161                 goto err;
162         r = AES_unwrap_key(&wctx, iv, ptmp, otmp, r);
163
164         if (memcmp(key, ptmp, keylen))
165                 goto err;
166
167         ret = 1;
168
169         err:
170         if (otmp)
171                 OPENSSL_free(otmp);
172         if (ptmp)
173                 OPENSSL_free(ptmp);
174
175         return ret;
176
177         }
178
179
180
181 int main(int argc, char **argv)
182 {
183
184 static const unsigned char kek[] = {
185   0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
186   0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
187   0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
188   0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f
189 };
190
191 static const unsigned char key[] = {
192   0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
193   0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff,
194   0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
195   0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f
196 };
197
198 static const unsigned char default_iv[] = {
199   0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6,
200 };
201
202 static const unsigned char e1[] = {
203   0x1f, 0xa6, 0x8b, 0x0a, 0x81, 0x12, 0xb4, 0x47,
204   0xae, 0xf3, 0x4b, 0xd8, 0xfb, 0x5a, 0x7b, 0x82,
205   0x9d, 0x3e, 0x86, 0x23, 0x71, 0xd2, 0xcf, 0xe5
206 };
207
208 static const unsigned char e2[] = {
209   0x96, 0x77, 0x8b, 0x25, 0xae, 0x6c, 0xa4, 0x35,
210   0xf9, 0x2b, 0x5b, 0x97, 0xc0, 0x50, 0xae, 0xd2,
211   0x46, 0x8a, 0xb8, 0xa1, 0x7a, 0xd8, 0x4e, 0x5d
212 };
213
214 static const unsigned char e3[] = {
215   0x64, 0xe8, 0xc3, 0xf9, 0xce, 0x0f, 0x5b, 0xa2,
216   0x63, 0xe9, 0x77, 0x79, 0x05, 0x81, 0x8a, 0x2a,
217   0x93, 0xc8, 0x19, 0x1e, 0x7d, 0x6e, 0x8a, 0xe7
218 };
219
220 static const unsigned char e4[] = {
221   0x03, 0x1d, 0x33, 0x26, 0x4e, 0x15, 0xd3, 0x32,
222   0x68, 0xf2, 0x4e, 0xc2, 0x60, 0x74, 0x3e, 0xdc,
223   0xe1, 0xc6, 0xc7, 0xdd, 0xee, 0x72, 0x5a, 0x93,
224   0x6b, 0xa8, 0x14, 0x91, 0x5c, 0x67, 0x62, 0xd2
225 };
226
227 static const unsigned char e5[] = {
228   0xa8, 0xf9, 0xbc, 0x16, 0x12, 0xc6, 0x8b, 0x3f,
229   0xf6, 0xe6, 0xf4, 0xfb, 0xe3, 0x0e, 0x71, 0xe4,
230   0x76, 0x9c, 0x8b, 0x80, 0xa3, 0x2c, 0xb8, 0x95,
231   0x8c, 0xd5, 0xd1, 0x7d, 0x6b, 0x25, 0x4d, 0xa1
232 };
233
234 static const unsigned char e6[] = {
235   0x28, 0xc9, 0xf4, 0x04, 0xc4, 0xb8, 0x10, 0xf4,
236   0xcb, 0xcc, 0xb3, 0x5c, 0xfb, 0x87, 0xf8, 0x26,
237   0x3f, 0x57, 0x86, 0xe2, 0xd8, 0x0e, 0xd3, 0x26,
238   0xcb, 0xc7, 0xf0, 0xe7, 0x1a, 0x99, 0xf4, 0x3b,
239   0xfb, 0x98, 0x8b, 0x9b, 0x7a, 0x02, 0xdd, 0x21
240 };
241
242         AES_KEY wctx, xctx;
243         int ret;
244         ret = AES_wrap_unwrap_test(kek, 128, NULL, e1, key, 16);
245         fprintf(stderr, "Key test result %d\n", ret);
246         ret = AES_wrap_unwrap_test(kek, 192, NULL, e2, key, 16);
247         fprintf(stderr, "Key test result %d\n", ret);
248         ret = AES_wrap_unwrap_test(kek, 256, NULL, e3, key, 16);
249         fprintf(stderr, "Key test result %d\n", ret);
250         ret = AES_wrap_unwrap_test(kek, 192, NULL, e4, key, 24);
251         fprintf(stderr, "Key test result %d\n", ret);
252         ret = AES_wrap_unwrap_test(kek, 256, NULL, e5, key, 24);
253         fprintf(stderr, "Key test result %d\n", ret);
254         ret = AES_wrap_unwrap_test(kek, 256, NULL, e6, key, 32);
255         fprintf(stderr, "Key test result %d\n", ret);
256 }
257         
258         
259 #endif