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