~ubuntu-branches/ubuntu/lucid/openssl/lucid-proposed

« back to all changes in this revision

Viewing changes to crypto/aes/aes_wrap.c

  • Committer: Bazaar Package Importer
  • Author(s): Kurt Roeckx
  • Date: 2009-06-13 18:15:46 UTC
  • mto: (11.1.5 squeeze)
  • mto: This revision was merged to the branch mainline in revision 34.
  • Revision ID: james.westby@ubuntu.com-20090613181546-vbfntai3b009dl1u
Tags: upstream-0.9.8k
ImportĀ upstreamĀ versionĀ 0.9.8k

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
static const unsigned char default_iv[] = {
 
59
  0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6,
 
60
};
 
61
 
 
62
int AES_wrap_key(AES_KEY *key, const unsigned char *iv,
 
63
                unsigned char *out,
 
64
                const unsigned char *in, unsigned int inlen)
 
65
        {
 
66
        unsigned char *A, B[16], *R;
 
67
        unsigned int i, j, t;
 
68
        if ((inlen & 0x7) || (inlen < 8))
 
69
                return -1;
 
70
        A = B;
 
71
        t = 1;
 
72
        memcpy(out + 8, in, inlen);
 
73
        if (!iv)
 
74
                iv = default_iv;
 
75
 
 
76
        memcpy(A, iv, 8);
 
77
 
 
78
        for (j = 0; j < 6; j++)
 
79
                {
 
80
                R = out + 8;
 
81
                for (i = 0; i < inlen; i += 8, t++, R += 8)
 
82
                        {
 
83
                        memcpy(B + 8, R, 8);
 
84
                        AES_encrypt(B, B, key);
 
85
                        A[7] ^= (unsigned char)(t & 0xff);
 
86
                        if (t > 0xff)   
 
87
                                {
 
88
                                A[6] ^= (unsigned char)((t & 0xff) >> 8);
 
89
                                A[5] ^= (unsigned char)((t & 0xff) >> 16);
 
90
                                A[4] ^= (unsigned char)((t & 0xff) >> 24);
 
91
                                }
 
92
                        memcpy(R, B + 8, 8);
 
93
                        }
 
94
                }
 
95
        memcpy(out, A, 8);
 
96
        return inlen + 8;
 
97
        }
 
98
 
 
99
int AES_unwrap_key(AES_KEY *key, const unsigned char *iv,
 
100
                unsigned char *out,
 
101
                const unsigned char *in, unsigned int inlen)
 
102
        {
 
103
        unsigned char *A, B[16], *R;
 
104
        unsigned int i, j, t;
 
105
        inlen -= 8;
 
106
        if (inlen & 0x7)
 
107
                return -1;
 
108
        if (inlen < 8)
 
109
                return -1;
 
110
        A = B;
 
111
        t =  6 * (inlen >> 3);
 
112
        memcpy(A, in, 8);
 
113
        memcpy(out, in + 8, inlen);
 
114
        for (j = 0; j < 6; j++)
 
115
                {
 
116
                R = out + inlen - 8;
 
117
                for (i = 0; i < inlen; i += 8, t--, R -= 8)
 
118
                        {
 
119
                        A[7] ^= (unsigned char)(t & 0xff);
 
120
                        if (t > 0xff)   
 
121
                                {
 
122
                                A[6] ^= (unsigned char)((t & 0xff) >> 8);
 
123
                                A[5] ^= (unsigned char)((t & 0xff) >> 16);
 
124
                                A[4] ^= (unsigned char)((t & 0xff) >> 24);
 
125
                                }
 
126
                        memcpy(B + 8, R, 8);
 
127
                        AES_decrypt(B, B, key);
 
128
                        memcpy(R, B + 8, 8);
 
129
                        }
 
130
                }
 
131
        if (!iv)
 
132
                iv = default_iv;
 
133
        if (memcmp(A, iv, 8))
 
134
                {
 
135
                OPENSSL_cleanse(out, inlen);
 
136
                return 0;
 
137
                }
 
138
        return inlen;
 
139
        }
 
140
 
 
141
#ifdef AES_WRAP_TEST
 
142
 
 
143
int AES_wrap_unwrap_test(const unsigned char *kek, int keybits,
 
144
                         const unsigned char *iv,
 
145
                         const unsigned char *eout,
 
146
                         const unsigned char *key, int keylen)
 
147
        {
 
148
        unsigned char *otmp = NULL, *ptmp = NULL;
 
149
        int r, ret = 0;
 
150
        AES_KEY wctx;
 
151
        otmp = OPENSSL_malloc(keylen + 8);
 
152
        ptmp = OPENSSL_malloc(keylen);
 
153
        if (!otmp || !ptmp)
 
154
                return 0;
 
155
        if (AES_set_encrypt_key(kek, keybits, &wctx))
 
156
                goto err;
 
157
        r = AES_wrap_key(&wctx, iv, otmp, key, keylen);
 
158
        if (r <= 0)
 
159
                goto err;
 
160
 
 
161
        if (eout && memcmp(eout, otmp, keylen))
 
162
                goto err;
 
163
                
 
164
        if (AES_set_decrypt_key(kek, keybits, &wctx))
 
165
                goto err;
 
166
        r = AES_unwrap_key(&wctx, iv, ptmp, otmp, r);
 
167
 
 
168
        if (memcmp(key, ptmp, keylen))
 
169
                goto err;
 
170
 
 
171
        ret = 1;
 
172
 
 
173
        err:
 
174
        if (otmp)
 
175
                OPENSSL_free(otmp);
 
176
        if (ptmp)
 
177
                OPENSSL_free(ptmp);
 
178
 
 
179
        return ret;
 
180
 
 
181
        }
 
182
 
 
183
 
 
184
 
 
185
int main(int argc, char **argv)
 
186
{
 
187
 
 
188
static const unsigned char kek[] = {
 
189
  0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
 
190
  0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
 
191
  0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
 
192
  0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f
 
193
};
 
194
 
 
195
static const unsigned char key[] = {
 
196
  0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
 
197
  0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff,
 
198
  0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
 
199
  0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f
 
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