diff options
126 files changed, 42285 insertions, 494 deletions
diff --git a/src/lib/libcrypto/aes/aes_ige.c b/src/lib/libcrypto/aes/aes_ige.c new file mode 100644 index 0000000000..45d7096181 --- /dev/null +++ b/src/lib/libcrypto/aes/aes_ige.c | |||
@@ -0,0 +1,323 @@ | |||
1 | /* crypto/aes/aes_ige.c -*- mode:C; c-file-style: "eay" -*- */ | ||
2 | /* ==================================================================== | ||
3 | * Copyright (c) 2006 The OpenSSL Project. All rights reserved. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions | ||
7 | * are met: | ||
8 | * | ||
9 | * 1. Redistributions of source code must retain the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer. | ||
11 | * | ||
12 | * 2. Redistributions in binary form must reproduce the above copyright | ||
13 | * notice, this list of conditions and the following disclaimer in | ||
14 | * the documentation and/or other materials provided with the | ||
15 | * distribution. | ||
16 | * | ||
17 | * 3. All advertising materials mentioning features or use of this | ||
18 | * software must display the following acknowledgment: | ||
19 | * "This product includes software developed by the OpenSSL Project | ||
20 | * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" | ||
21 | * | ||
22 | * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to | ||
23 | * endorse or promote products derived from this software without | ||
24 | * prior written permission. For written permission, please contact | ||
25 | * openssl-core@openssl.org. | ||
26 | * | ||
27 | * 5. Products derived from this software may not be called "OpenSSL" | ||
28 | * nor may "OpenSSL" appear in their names without prior written | ||
29 | * permission of the OpenSSL Project. | ||
30 | * | ||
31 | * 6. Redistributions of any form whatsoever must retain the following | ||
32 | * acknowledgment: | ||
33 | * "This product includes software developed by the OpenSSL Project | ||
34 | * for use in the OpenSSL Toolkit (http://www.openssl.org/)" | ||
35 | * | ||
36 | * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY | ||
37 | * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
38 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | ||
39 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR | ||
40 | * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
41 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
42 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
43 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
44 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
45 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
46 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED | ||
47 | * OF THE POSSIBILITY OF SUCH DAMAGE. | ||
48 | * ==================================================================== | ||
49 | * | ||
50 | */ | ||
51 | |||
52 | #include "cryptlib.h" | ||
53 | |||
54 | #include <openssl/aes.h> | ||
55 | #include "aes_locl.h" | ||
56 | |||
57 | #define N_WORDS (AES_BLOCK_SIZE / sizeof(unsigned long)) | ||
58 | typedef struct { | ||
59 | unsigned long data[N_WORDS]; | ||
60 | } aes_block_t; | ||
61 | |||
62 | /* XXX: probably some better way to do this */ | ||
63 | #if defined(__i386__) || defined(__x86_64__) | ||
64 | #define UNALIGNED_MEMOPS_ARE_FAST 1 | ||
65 | #else | ||
66 | #define UNALIGNED_MEMOPS_ARE_FAST 0 | ||
67 | #endif | ||
68 | |||
69 | #if UNALIGNED_MEMOPS_ARE_FAST | ||
70 | #define load_block(d, s) (d) = *(const aes_block_t *)(s) | ||
71 | #define store_block(d, s) *(aes_block_t *)(d) = (s) | ||
72 | #else | ||
73 | #define load_block(d, s) memcpy((d).data, (s), AES_BLOCK_SIZE) | ||
74 | #define store_block(d, s) memcpy((d), (s).data, AES_BLOCK_SIZE) | ||
75 | #endif | ||
76 | |||
77 | /* N.B. The IV for this mode is _twice_ the block size */ | ||
78 | |||
79 | void AES_ige_encrypt(const unsigned char *in, unsigned char *out, | ||
80 | const unsigned long length, const AES_KEY *key, | ||
81 | unsigned char *ivec, const int enc) | ||
82 | { | ||
83 | unsigned long n; | ||
84 | unsigned long len; | ||
85 | |||
86 | OPENSSL_assert(in && out && key && ivec); | ||
87 | OPENSSL_assert((AES_ENCRYPT == enc)||(AES_DECRYPT == enc)); | ||
88 | OPENSSL_assert((length%AES_BLOCK_SIZE) == 0); | ||
89 | |||
90 | len = length / AES_BLOCK_SIZE; | ||
91 | |||
92 | if (AES_ENCRYPT == enc) | ||
93 | { | ||
94 | if (in != out && | ||
95 | (UNALIGNED_MEMOPS_ARE_FAST || ((size_t)in|(size_t)out|(size_t)ivec)%sizeof(long)==0)) | ||
96 | { | ||
97 | aes_block_t *ivp = (aes_block_t *)ivec; | ||
98 | aes_block_t *iv2p = (aes_block_t *)(ivec + AES_BLOCK_SIZE); | ||
99 | |||
100 | while (len) | ||
101 | { | ||
102 | aes_block_t *inp = (aes_block_t *)in; | ||
103 | aes_block_t *outp = (aes_block_t *)out; | ||
104 | |||
105 | for(n=0 ; n < N_WORDS; ++n) | ||
106 | outp->data[n] = inp->data[n] ^ ivp->data[n]; | ||
107 | AES_encrypt((unsigned char *)outp->data, (unsigned char *)outp->data, key); | ||
108 | for(n=0 ; n < N_WORDS; ++n) | ||
109 | outp->data[n] ^= iv2p->data[n]; | ||
110 | ivp = outp; | ||
111 | iv2p = inp; | ||
112 | --len; | ||
113 | in += AES_BLOCK_SIZE; | ||
114 | out += AES_BLOCK_SIZE; | ||
115 | } | ||
116 | memcpy(ivec, ivp->data, AES_BLOCK_SIZE); | ||
117 | memcpy(ivec + AES_BLOCK_SIZE, iv2p->data, AES_BLOCK_SIZE); | ||
118 | } | ||
119 | else | ||
120 | { | ||
121 | aes_block_t tmp, tmp2; | ||
122 | aes_block_t iv; | ||
123 | aes_block_t iv2; | ||
124 | |||
125 | load_block(iv, ivec); | ||
126 | load_block(iv2, ivec + AES_BLOCK_SIZE); | ||
127 | |||
128 | while (len) | ||
129 | { | ||
130 | load_block(tmp, in); | ||
131 | for(n=0 ; n < N_WORDS; ++n) | ||
132 | tmp2.data[n] = tmp.data[n] ^ iv.data[n]; | ||
133 | AES_encrypt((unsigned char *)tmp2.data, (unsigned char *)tmp2.data, key); | ||
134 | for(n=0 ; n < N_WORDS; ++n) | ||
135 | tmp2.data[n] ^= iv2.data[n]; | ||
136 | store_block(out, tmp2); | ||
137 | iv = tmp2; | ||
138 | iv2 = tmp; | ||
139 | --len; | ||
140 | in += AES_BLOCK_SIZE; | ||
141 | out += AES_BLOCK_SIZE; | ||
142 | } | ||
143 | memcpy(ivec, iv.data, AES_BLOCK_SIZE); | ||
144 | memcpy(ivec + AES_BLOCK_SIZE, iv2.data, AES_BLOCK_SIZE); | ||
145 | } | ||
146 | } | ||
147 | else | ||
148 | { | ||
149 | if (in != out && | ||
150 | (UNALIGNED_MEMOPS_ARE_FAST || ((size_t)in|(size_t)out|(size_t)ivec)%sizeof(long)==0)) | ||
151 | { | ||
152 | aes_block_t *ivp = (aes_block_t *)ivec; | ||
153 | aes_block_t *iv2p = (aes_block_t *)(ivec + AES_BLOCK_SIZE); | ||
154 | |||
155 | while (len) | ||
156 | { | ||
157 | aes_block_t tmp; | ||
158 | aes_block_t *inp = (aes_block_t *)in; | ||
159 | aes_block_t *outp = (aes_block_t *)out; | ||
160 | |||
161 | for(n=0 ; n < N_WORDS; ++n) | ||
162 | tmp.data[n] = inp->data[n] ^ iv2p->data[n]; | ||
163 | AES_decrypt((unsigned char *)tmp.data, (unsigned char *)outp->data, key); | ||
164 | for(n=0 ; n < N_WORDS; ++n) | ||
165 | outp->data[n] ^= ivp->data[n]; | ||
166 | ivp = inp; | ||
167 | iv2p = outp; | ||
168 | --len; | ||
169 | in += AES_BLOCK_SIZE; | ||
170 | out += AES_BLOCK_SIZE; | ||
171 | } | ||
172 | memcpy(ivec, ivp->data, AES_BLOCK_SIZE); | ||
173 | memcpy(ivec + AES_BLOCK_SIZE, iv2p->data, AES_BLOCK_SIZE); | ||
174 | } | ||
175 | else | ||
176 | { | ||
177 | aes_block_t tmp, tmp2; | ||
178 | aes_block_t iv; | ||
179 | aes_block_t iv2; | ||
180 | |||
181 | load_block(iv, ivec); | ||
182 | load_block(iv2, ivec + AES_BLOCK_SIZE); | ||
183 | |||
184 | while (len) | ||
185 | { | ||
186 | load_block(tmp, in); | ||
187 | tmp2 = tmp; | ||
188 | for(n=0 ; n < N_WORDS; ++n) | ||
189 | tmp.data[n] ^= iv2.data[n]; | ||
190 | AES_decrypt((unsigned char *)tmp.data, (unsigned char *)tmp.data, key); | ||
191 | for(n=0 ; n < N_WORDS; ++n) | ||
192 | tmp.data[n] ^= iv.data[n]; | ||
193 | store_block(out, tmp); | ||
194 | iv = tmp2; | ||
195 | iv2 = tmp; | ||
196 | --len; | ||
197 | in += AES_BLOCK_SIZE; | ||
198 | out += AES_BLOCK_SIZE; | ||
199 | } | ||
200 | memcpy(ivec, iv.data, AES_BLOCK_SIZE); | ||
201 | memcpy(ivec + AES_BLOCK_SIZE, iv2.data, AES_BLOCK_SIZE); | ||
202 | } | ||
203 | } | ||
204 | } | ||
205 | |||
206 | /* | ||
207 | * Note that its effectively impossible to do biIGE in anything other | ||
208 | * than a single pass, so no provision is made for chaining. | ||
209 | */ | ||
210 | |||
211 | /* N.B. The IV for this mode is _four times_ the block size */ | ||
212 | |||
213 | void AES_bi_ige_encrypt(const unsigned char *in, unsigned char *out, | ||
214 | const unsigned long length, const AES_KEY *key, | ||
215 | const AES_KEY *key2, const unsigned char *ivec, | ||
216 | const int enc) | ||
217 | { | ||
218 | unsigned long n; | ||
219 | unsigned long len = length; | ||
220 | unsigned char tmp[AES_BLOCK_SIZE]; | ||
221 | unsigned char tmp2[AES_BLOCK_SIZE]; | ||
222 | unsigned char tmp3[AES_BLOCK_SIZE]; | ||
223 | unsigned char prev[AES_BLOCK_SIZE]; | ||
224 | const unsigned char *iv; | ||
225 | const unsigned char *iv2; | ||
226 | |||
227 | OPENSSL_assert(in && out && key && ivec); | ||
228 | OPENSSL_assert((AES_ENCRYPT == enc)||(AES_DECRYPT == enc)); | ||
229 | OPENSSL_assert((length%AES_BLOCK_SIZE) == 0); | ||
230 | |||
231 | if (AES_ENCRYPT == enc) | ||
232 | { | ||
233 | /* XXX: Do a separate case for when in != out (strictly should | ||
234 | check for overlap, too) */ | ||
235 | |||
236 | /* First the forward pass */ | ||
237 | iv = ivec; | ||
238 | iv2 = ivec + AES_BLOCK_SIZE; | ||
239 | while (len >= AES_BLOCK_SIZE) | ||
240 | { | ||
241 | for(n=0 ; n < AES_BLOCK_SIZE ; ++n) | ||
242 | out[n] = in[n] ^ iv[n]; | ||
243 | AES_encrypt(out, out, key); | ||
244 | for(n=0 ; n < AES_BLOCK_SIZE ; ++n) | ||
245 | out[n] ^= iv2[n]; | ||
246 | iv = out; | ||
247 | memcpy(prev, in, AES_BLOCK_SIZE); | ||
248 | iv2 = prev; | ||
249 | len -= AES_BLOCK_SIZE; | ||
250 | in += AES_BLOCK_SIZE; | ||
251 | out += AES_BLOCK_SIZE; | ||
252 | } | ||
253 | |||
254 | /* And now backwards */ | ||
255 | iv = ivec + AES_BLOCK_SIZE*2; | ||
256 | iv2 = ivec + AES_BLOCK_SIZE*3; | ||
257 | len = length; | ||
258 | while(len >= AES_BLOCK_SIZE) | ||
259 | { | ||
260 | out -= AES_BLOCK_SIZE; | ||
261 | /* XXX: reduce copies by alternating between buffers */ | ||
262 | memcpy(tmp, out, AES_BLOCK_SIZE); | ||
263 | for(n=0 ; n < AES_BLOCK_SIZE ; ++n) | ||
264 | out[n] ^= iv[n]; | ||
265 | /* hexdump(stdout, "out ^ iv", out, AES_BLOCK_SIZE); */ | ||
266 | AES_encrypt(out, out, key); | ||
267 | /* hexdump(stdout,"enc", out, AES_BLOCK_SIZE); */ | ||
268 | /* hexdump(stdout,"iv2", iv2, AES_BLOCK_SIZE); */ | ||
269 | for(n=0 ; n < AES_BLOCK_SIZE ; ++n) | ||
270 | out[n] ^= iv2[n]; | ||
271 | /* hexdump(stdout,"out", out, AES_BLOCK_SIZE); */ | ||
272 | iv = out; | ||
273 | memcpy(prev, tmp, AES_BLOCK_SIZE); | ||
274 | iv2 = prev; | ||
275 | len -= AES_BLOCK_SIZE; | ||
276 | } | ||
277 | } | ||
278 | else | ||
279 | { | ||
280 | /* First backwards */ | ||
281 | iv = ivec + AES_BLOCK_SIZE*2; | ||
282 | iv2 = ivec + AES_BLOCK_SIZE*3; | ||
283 | in += length; | ||
284 | out += length; | ||
285 | while (len >= AES_BLOCK_SIZE) | ||
286 | { | ||
287 | in -= AES_BLOCK_SIZE; | ||
288 | out -= AES_BLOCK_SIZE; | ||
289 | memcpy(tmp, in, AES_BLOCK_SIZE); | ||
290 | memcpy(tmp2, in, AES_BLOCK_SIZE); | ||
291 | for(n=0 ; n < AES_BLOCK_SIZE ; ++n) | ||
292 | tmp[n] ^= iv2[n]; | ||
293 | AES_decrypt(tmp, out, key); | ||
294 | for(n=0 ; n < AES_BLOCK_SIZE ; ++n) | ||
295 | out[n] ^= iv[n]; | ||
296 | memcpy(tmp3, tmp2, AES_BLOCK_SIZE); | ||
297 | iv = tmp3; | ||
298 | iv2 = out; | ||
299 | len -= AES_BLOCK_SIZE; | ||
300 | } | ||
301 | |||
302 | /* And now forwards */ | ||
303 | iv = ivec; | ||
304 | iv2 = ivec + AES_BLOCK_SIZE; | ||
305 | len = length; | ||
306 | while (len >= AES_BLOCK_SIZE) | ||
307 | { | ||
308 | memcpy(tmp, out, AES_BLOCK_SIZE); | ||
309 | memcpy(tmp2, out, AES_BLOCK_SIZE); | ||
310 | for(n=0 ; n < AES_BLOCK_SIZE ; ++n) | ||
311 | tmp[n] ^= iv2[n]; | ||
312 | AES_decrypt(tmp, out, key); | ||
313 | for(n=0 ; n < AES_BLOCK_SIZE ; ++n) | ||
314 | out[n] ^= iv[n]; | ||
315 | memcpy(tmp3, tmp2, AES_BLOCK_SIZE); | ||
316 | iv = tmp3; | ||
317 | iv2 = out; | ||
318 | len -= AES_BLOCK_SIZE; | ||
319 | in += AES_BLOCK_SIZE; | ||
320 | out += AES_BLOCK_SIZE; | ||
321 | } | ||
322 | } | ||
323 | } | ||
diff --git a/src/lib/libcrypto/aes/aes_wrap.c b/src/lib/libcrypto/aes/aes_wrap.c new file mode 100644 index 0000000000..9feacd65d8 --- /dev/null +++ b/src/lib/libcrypto/aes/aes_wrap.c | |||
@@ -0,0 +1,259 @@ | |||
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 | ||
diff --git a/src/lib/libcrypto/aes/asm/aes-ia64.S b/src/lib/libcrypto/aes/asm/aes-ia64.S new file mode 100644 index 0000000000..7f6c4c3662 --- /dev/null +++ b/src/lib/libcrypto/aes/asm/aes-ia64.S | |||
@@ -0,0 +1,1123 @@ | |||
1 | // ==================================================================== | ||
2 | // Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL | ||
3 | // project. Rights for redistribution and usage in source and binary | ||
4 | // forms are granted according to the OpenSSL license. | ||
5 | // ==================================================================== | ||
6 | // | ||
7 | // What's wrong with compiler generated code? Compiler never uses | ||
8 | // variable 'shr' which is pairable with 'extr'/'dep' instructions. | ||
9 | // Then it uses 'zxt' which is an I-type, but can be replaced with | ||
10 | // 'and' which in turn can be assigned to M-port [there're double as | ||
11 | // much M-ports as there're I-ports on Itanium 2]. By sacrificing few | ||
12 | // registers for small constants (255, 24 and 16) to be used with | ||
13 | // 'shr' and 'and' instructions I can achieve better ILP, Intruction | ||
14 | // Level Parallelism, and performance. This code outperforms GCC 3.3 | ||
15 | // generated code by over factor of 2 (two), GCC 3.4 - by 70% and | ||
16 | // HP C - by 40%. Measured best-case scenario, i.e. aligned | ||
17 | // big-endian input, ECB timing on Itanium 2 is (18 + 13*rounds) | ||
18 | // ticks per block, or 9.25 CPU cycles per byte for 128 bit key. | ||
19 | |||
20 | // Version 1.2 mitigates the hazard of cache-timing attacks by | ||
21 | // a) compressing S-boxes from 8KB to 2KB+256B, b) scheduling | ||
22 | // references to S-boxes for L2 cache latency, c) prefetching T[ed]4 | ||
23 | // prior last round. As result performance dropped to (26 + 15*rounds) | ||
24 | // ticks per block or 11 cycles per byte processed with 128-bit key. | ||
25 | // This is ~16% deterioration. For reference Itanium 2 L1 cache has | ||
26 | // 64 bytes line size and L2 - 128 bytes... | ||
27 | |||
28 | .ident "aes-ia64.S, version 1.2" | ||
29 | .ident "IA-64 ISA artwork by Andy Polyakov <appro@fy.chalmers.se>" | ||
30 | .explicit | ||
31 | .text | ||
32 | |||
33 | rk0=r8; rk1=r9; | ||
34 | |||
35 | pfssave=r2; | ||
36 | lcsave=r10; | ||
37 | prsave=r3; | ||
38 | maskff=r11; | ||
39 | twenty4=r14; | ||
40 | sixteen=r15; | ||
41 | |||
42 | te00=r16; te11=r17; te22=r18; te33=r19; | ||
43 | te01=r20; te12=r21; te23=r22; te30=r23; | ||
44 | te02=r24; te13=r25; te20=r26; te31=r27; | ||
45 | te03=r28; te10=r29; te21=r30; te32=r31; | ||
46 | |||
47 | // these are rotating... | ||
48 | t0=r32; s0=r33; | ||
49 | t1=r34; s1=r35; | ||
50 | t2=r36; s2=r37; | ||
51 | t3=r38; s3=r39; | ||
52 | |||
53 | te0=r40; te1=r41; te2=r42; te3=r43; | ||
54 | |||
55 | #if defined(_HPUX_SOURCE) && !defined(_LP64) | ||
56 | # define ADDP addp4 | ||
57 | #else | ||
58 | # define ADDP add | ||
59 | #endif | ||
60 | |||
61 | // Offsets from Te0 | ||
62 | #define TE0 0 | ||
63 | #define TE2 2 | ||
64 | #if defined(_HPUX_SOURCE) || defined(B_ENDIAN) | ||
65 | #define TE1 3 | ||
66 | #define TE3 1 | ||
67 | #else | ||
68 | #define TE1 1 | ||
69 | #define TE3 3 | ||
70 | #endif | ||
71 | |||
72 | // This implies that AES_KEY comprises 32-bit key schedule elements | ||
73 | // even on LP64 platforms. | ||
74 | #ifndef KSZ | ||
75 | # define KSZ 4 | ||
76 | # define LDKEY ld4 | ||
77 | #endif | ||
78 | |||
79 | .proc _ia64_AES_encrypt# | ||
80 | // Input: rk0-rk1 | ||
81 | // te0 | ||
82 | // te3 as AES_KEY->rounds!!! | ||
83 | // s0-s3 | ||
84 | // maskff,twenty4,sixteen | ||
85 | // Output: r16,r20,r24,r28 as s0-s3 | ||
86 | // Clobber: r16-r31,rk0-rk1,r32-r43 | ||
87 | .align 32 | ||
88 | _ia64_AES_encrypt: | ||
89 | .prologue | ||
90 | .altrp b6 | ||
91 | .body | ||
92 | { .mmi; alloc r16=ar.pfs,12,0,0,8 | ||
93 | LDKEY t0=[rk0],2*KSZ | ||
94 | mov pr.rot=1<<16 } | ||
95 | { .mmi; LDKEY t1=[rk1],2*KSZ | ||
96 | add te1=TE1,te0 | ||
97 | add te3=-3,te3 };; | ||
98 | { .mib; LDKEY t2=[rk0],2*KSZ | ||
99 | mov ar.ec=2 } | ||
100 | { .mib; LDKEY t3=[rk1],2*KSZ | ||
101 | add te2=TE2,te0 | ||
102 | brp.loop.imp .Le_top,.Le_end-16 };; | ||
103 | |||
104 | { .mmi; xor s0=s0,t0 | ||
105 | xor s1=s1,t1 | ||
106 | mov ar.lc=te3 } | ||
107 | { .mmi; xor s2=s2,t2 | ||
108 | xor s3=s3,t3 | ||
109 | add te3=TE3,te0 };; | ||
110 | |||
111 | .align 32 | ||
112 | .Le_top: | ||
113 | { .mmi; (p0) LDKEY t0=[rk0],2*KSZ // 0/0:rk[0] | ||
114 | (p0) and te33=s3,maskff // 0/0:s3&0xff | ||
115 | (p0) extr.u te22=s2,8,8 } // 0/0:s2>>8&0xff | ||
116 | { .mmi; (p0) LDKEY t1=[rk1],2*KSZ // 0/1:rk[1] | ||
117 | (p0) and te30=s0,maskff // 0/1:s0&0xff | ||
118 | (p0) shr.u te00=s0,twenty4 };; // 0/0:s0>>24 | ||
119 | { .mmi; (p0) LDKEY t2=[rk0],2*KSZ // 1/2:rk[2] | ||
120 | (p0) shladd te33=te33,3,te3 // 1/0:te0+s0>>24 | ||
121 | (p0) extr.u te23=s3,8,8 } // 1/1:s3>>8&0xff | ||
122 | { .mmi; (p0) LDKEY t3=[rk1],2*KSZ // 1/3:rk[3] | ||
123 | (p0) shladd te30=te30,3,te3 // 1/1:te3+s0 | ||
124 | (p0) shr.u te01=s1,twenty4 };; // 1/1:s1>>24 | ||
125 | { .mmi; (p0) ld4 te33=[te33] // 2/0:te3[s3&0xff] | ||
126 | (p0) shladd te22=te22,3,te2 // 2/0:te2+s2>>8&0xff | ||
127 | (p0) extr.u te20=s0,8,8 } // 2/2:s0>>8&0xff | ||
128 | { .mmi; (p0) ld4 te30=[te30] // 2/1:te3[s0] | ||
129 | (p0) shladd te23=te23,3,te2 // 2/1:te2+s3>>8 | ||
130 | (p0) shr.u te02=s2,twenty4 };; // 2/2:s2>>24 | ||
131 | { .mmi; (p0) ld4 te22=[te22] // 3/0:te2[s2>>8] | ||
132 | (p0) shladd te20=te20,3,te2 // 3/2:te2+s0>>8 | ||
133 | (p0) extr.u te21=s1,8,8 } // 3/3:s1>>8&0xff | ||
134 | { .mmi; (p0) ld4 te23=[te23] // 3/1:te2[s3>>8] | ||
135 | (p0) shladd te00=te00,3,te0 // 3/0:te0+s0>>24 | ||
136 | (p0) shr.u te03=s3,twenty4 };; // 3/3:s3>>24 | ||
137 | { .mmi; (p0) ld4 te20=[te20] // 4/2:te2[s0>>8] | ||
138 | (p0) shladd te21=te21,3,te2 // 4/3:te3+s2 | ||
139 | (p0) extr.u te11=s1,16,8 } // 4/0:s1>>16&0xff | ||
140 | { .mmi; (p0) ld4 te00=[te00] // 4/0:te0[s0>>24] | ||
141 | (p0) shladd te01=te01,3,te0 // 4/1:te0+s1>>24 | ||
142 | (p0) shr.u te13=s3,sixteen };; // 4/2:s3>>16 | ||
143 | { .mmi; (p0) ld4 te21=[te21] // 5/3:te2[s1>>8] | ||
144 | (p0) shladd te11=te11,3,te1 // 5/0:te1+s1>>16 | ||
145 | (p0) extr.u te12=s2,16,8 } // 5/1:s2>>16&0xff | ||
146 | { .mmi; (p0) ld4 te01=[te01] // 5/1:te0[s1>>24] | ||
147 | (p0) shladd te02=te02,3,te0 // 5/2:te0+s2>>24 | ||
148 | (p0) and te31=s1,maskff };; // 5/2:s1&0xff | ||
149 | { .mmi; (p0) ld4 te11=[te11] // 6/0:te1[s1>>16] | ||
150 | (p0) shladd te12=te12,3,te1 // 6/1:te1+s2>>16 | ||
151 | (p0) extr.u te10=s0,16,8 } // 6/3:s0>>16&0xff | ||
152 | { .mmi; (p0) ld4 te02=[te02] // 6/2:te0[s2>>24] | ||
153 | (p0) shladd te03=te03,3,te0 // 6/3:te1+s0>>16 | ||
154 | (p0) and te32=s2,maskff };; // 6/3:s2&0xff | ||
155 | |||
156 | { .mmi; (p0) ld4 te12=[te12] // 7/1:te1[s2>>16] | ||
157 | (p0) shladd te31=te31,3,te3 // 7/2:te3+s1&0xff | ||
158 | (p0) and te13=te13,maskff} // 7/2:s3>>16&0xff | ||
159 | { .mmi; (p0) ld4 te03=[te03] // 7/3:te0[s3>>24] | ||
160 | (p0) shladd te32=te32,3,te3 // 7/3:te3+s2 | ||
161 | (p0) xor t0=t0,te33 };; // 7/0: | ||
162 | { .mmi; (p0) ld4 te31=[te31] // 8/2:te3[s1] | ||
163 | (p0) shladd te13=te13,3,te1 // 8/2:te1+s3>>16 | ||
164 | (p0) xor t0=t0,te22 } // 8/0: | ||
165 | { .mmi; (p0) ld4 te32=[te32] // 8/3:te3[s2] | ||
166 | (p0) shladd te10=te10,3,te1 // 8/3:te1+s0>>16 | ||
167 | (p0) xor t1=t1,te30 };; // 8/1: | ||
168 | { .mmi; (p0) ld4 te13=[te13] // 9/2:te1[s3>>16] | ||
169 | (p0) ld4 te10=[te10] // 9/3:te1[s0>>16] | ||
170 | (p0) xor t0=t0,te00 };; // 9/0: !L2 scheduling | ||
171 | { .mmi; (p0) xor t1=t1,te23 // 10[9]/1: | ||
172 | (p0) xor t2=t2,te20 // 10[9]/2: | ||
173 | (p0) xor t3=t3,te21 };; // 10[9]/3: | ||
174 | { .mmi; (p0) xor t0=t0,te11 // 11[10]/0:done! | ||
175 | (p0) xor t1=t1,te01 // 11[10]/1: | ||
176 | (p0) xor t2=t2,te02 };; // 11[10]/2: !L2 scheduling | ||
177 | { .mmi; (p0) xor t3=t3,te03 // 12[10]/3: | ||
178 | (p16) cmp.eq p0,p17=r0,r0 };; // 12[10]/clear (p17) | ||
179 | { .mmi; (p0) xor t1=t1,te12 // 13[11]/1:done! | ||
180 | (p0) xor t2=t2,te31 // 13[11]/2: | ||
181 | (p0) xor t3=t3,te32 } // 13[11]/3: | ||
182 | { .mmi; (p17) add te0=2048,te0 // 13[11]/ | ||
183 | (p17) add te1=2048+64-TE1,te1};; // 13[11]/ | ||
184 | { .mib; (p0) xor t2=t2,te13 // 14[12]/2:done! | ||
185 | (p17) add te2=2048+128-TE2,te2} // 14[12]/ | ||
186 | { .mib; (p0) xor t3=t3,te10 // 14[12]/3:done! | ||
187 | (p17) add te3=2048+192-TE3,te3 // 14[12]/ | ||
188 | br.ctop.sptk .Le_top };; | ||
189 | .Le_end: | ||
190 | |||
191 | |||
192 | { .mmi; ld8 te12=[te0] // prefetch Te4 | ||
193 | ld8 te31=[te1] } | ||
194 | { .mmi; ld8 te10=[te2] | ||
195 | ld8 te32=[te3] } | ||
196 | |||
197 | { .mmi; LDKEY t0=[rk0],2*KSZ // 0/0:rk[0] | ||
198 | and te33=s3,maskff // 0/0:s3&0xff | ||
199 | extr.u te22=s2,8,8 } // 0/0:s2>>8&0xff | ||
200 | { .mmi; LDKEY t1=[rk1],2*KSZ // 0/1:rk[1] | ||
201 | and te30=s0,maskff // 0/1:s0&0xff | ||
202 | shr.u te00=s0,twenty4 };; // 0/0:s0>>24 | ||
203 | { .mmi; LDKEY t2=[rk0],2*KSZ // 1/2:rk[2] | ||
204 | add te33=te33,te0 // 1/0:te0+s0>>24 | ||
205 | extr.u te23=s3,8,8 } // 1/1:s3>>8&0xff | ||
206 | { .mmi; LDKEY t3=[rk1],2*KSZ // 1/3:rk[3] | ||
207 | add te30=te30,te0 // 1/1:te0+s0 | ||
208 | shr.u te01=s1,twenty4 };; // 1/1:s1>>24 | ||
209 | { .mmi; ld1 te33=[te33] // 2/0:te0[s3&0xff] | ||
210 | add te22=te22,te0 // 2/0:te0+s2>>8&0xff | ||
211 | extr.u te20=s0,8,8 } // 2/2:s0>>8&0xff | ||
212 | { .mmi; ld1 te30=[te30] // 2/1:te0[s0] | ||
213 | add te23=te23,te0 // 2/1:te0+s3>>8 | ||
214 | shr.u te02=s2,twenty4 };; // 2/2:s2>>24 | ||
215 | { .mmi; ld1 te22=[te22] // 3/0:te0[s2>>8] | ||
216 | add te20=te20,te0 // 3/2:te0+s0>>8 | ||
217 | extr.u te21=s1,8,8 } // 3/3:s1>>8&0xff | ||
218 | { .mmi; ld1 te23=[te23] // 3/1:te0[s3>>8] | ||
219 | add te00=te00,te0 // 3/0:te0+s0>>24 | ||
220 | shr.u te03=s3,twenty4 };; // 3/3:s3>>24 | ||
221 | { .mmi; ld1 te20=[te20] // 4/2:te0[s0>>8] | ||
222 | add te21=te21,te0 // 4/3:te0+s2 | ||
223 | extr.u te11=s1,16,8 } // 4/0:s1>>16&0xff | ||
224 | { .mmi; ld1 te00=[te00] // 4/0:te0[s0>>24] | ||
225 | add te01=te01,te0 // 4/1:te0+s1>>24 | ||
226 | shr.u te13=s3,sixteen };; // 4/2:s3>>16 | ||
227 | { .mmi; ld1 te21=[te21] // 5/3:te0[s1>>8] | ||
228 | add te11=te11,te0 // 5/0:te0+s1>>16 | ||
229 | extr.u te12=s2,16,8 } // 5/1:s2>>16&0xff | ||
230 | { .mmi; ld1 te01=[te01] // 5/1:te0[s1>>24] | ||
231 | add te02=te02,te0 // 5/2:te0+s2>>24 | ||
232 | and te31=s1,maskff };; // 5/2:s1&0xff | ||
233 | { .mmi; ld1 te11=[te11] // 6/0:te0[s1>>16] | ||
234 | add te12=te12,te0 // 6/1:te0+s2>>16 | ||
235 | extr.u te10=s0,16,8 } // 6/3:s0>>16&0xff | ||
236 | { .mmi; ld1 te02=[te02] // 6/2:te0[s2>>24] | ||
237 | add te03=te03,te0 // 6/3:te0+s0>>16 | ||
238 | and te32=s2,maskff };; // 6/3:s2&0xff | ||
239 | |||
240 | { .mmi; ld1 te12=[te12] // 7/1:te0[s2>>16] | ||
241 | add te31=te31,te0 // 7/2:te0+s1&0xff | ||
242 | dep te33=te22,te33,8,8} // 7/0: | ||
243 | { .mmi; ld1 te03=[te03] // 7/3:te0[s3>>24] | ||
244 | add te32=te32,te0 // 7/3:te0+s2 | ||
245 | and te13=te13,maskff};; // 7/2:s3>>16&0xff | ||
246 | { .mmi; ld1 te31=[te31] // 8/2:te0[s1] | ||
247 | add te13=te13,te0 // 8/2:te0+s3>>16 | ||
248 | dep te30=te23,te30,8,8} // 8/1: | ||
249 | { .mmi; ld1 te32=[te32] // 8/3:te0[s2] | ||
250 | add te10=te10,te0 // 8/3:te0+s0>>16 | ||
251 | shl te00=te00,twenty4};; // 8/0: | ||
252 | { .mii; ld1 te13=[te13] // 9/2:te0[s3>>16] | ||
253 | dep te33=te11,te33,16,8 // 9/0: | ||
254 | shl te01=te01,twenty4};; // 9/1: | ||
255 | { .mii; ld1 te10=[te10] // 10/3:te0[s0>>16] | ||
256 | dep te31=te20,te31,8,8 // 10/2: | ||
257 | shl te02=te02,twenty4};; // 10/2: | ||
258 | { .mii; xor t0=t0,te33 // 11/0: | ||
259 | dep te32=te21,te32,8,8 // 11/3: | ||
260 | shl te12=te12,sixteen};; // 11/1: | ||
261 | { .mii; xor r16=t0,te00 // 12/0:done! | ||
262 | dep te31=te13,te31,16,8 // 12/2: | ||
263 | shl te03=te03,twenty4};; // 12/3: | ||
264 | { .mmi; xor t1=t1,te01 // 13/1: | ||
265 | xor t2=t2,te02 // 13/2: | ||
266 | dep te32=te10,te32,16,8};; // 13/3: | ||
267 | { .mmi; xor t1=t1,te30 // 14/1: | ||
268 | xor r24=t2,te31 // 14/2:done! | ||
269 | xor t3=t3,te32 };; // 14/3: | ||
270 | { .mib; xor r20=t1,te12 // 15/1:done! | ||
271 | xor r28=t3,te03 // 15/3:done! | ||
272 | br.ret.sptk b6 };; | ||
273 | .endp _ia64_AES_encrypt# | ||
274 | |||
275 | // void AES_encrypt (const void *in,void *out,const AES_KEY *key); | ||
276 | .global AES_encrypt# | ||
277 | .proc AES_encrypt# | ||
278 | .align 32 | ||
279 | AES_encrypt: | ||
280 | .prologue | ||
281 | .save ar.pfs,pfssave | ||
282 | { .mmi; alloc pfssave=ar.pfs,3,1,12,0 | ||
283 | and out0=3,in0 | ||
284 | mov r3=ip } | ||
285 | { .mmi; ADDP in0=0,in0 | ||
286 | mov loc0=psr.um | ||
287 | ADDP out11=KSZ*60,in2 };; // &AES_KEY->rounds | ||
288 | |||
289 | { .mmi; ld4 out11=[out11] // AES_KEY->rounds | ||
290 | add out8=(AES_Te#-AES_encrypt#),r3 // Te0 | ||
291 | .save pr,prsave | ||
292 | mov prsave=pr } | ||
293 | { .mmi; rum 1<<3 // clear um.ac | ||
294 | .save ar.lc,lcsave | ||
295 | mov lcsave=ar.lc };; | ||
296 | |||
297 | .body | ||
298 | #if defined(_HPUX_SOURCE) // HPUX is big-endian, cut 15+15 cycles... | ||
299 | { .mib; cmp.ne p6,p0=out0,r0 | ||
300 | add out0=4,in0 | ||
301 | (p6) br.dpnt.many .Le_i_unaligned };; | ||
302 | |||
303 | { .mmi; ld4 out1=[in0],8 // s0 | ||
304 | and out9=3,in1 | ||
305 | mov twenty4=24 } | ||
306 | { .mmi; ld4 out3=[out0],8 // s1 | ||
307 | ADDP rk0=0,in2 | ||
308 | mov sixteen=16 };; | ||
309 | { .mmi; ld4 out5=[in0] // s2 | ||
310 | cmp.ne p6,p0=out9,r0 | ||
311 | mov maskff=0xff } | ||
312 | { .mmb; ld4 out7=[out0] // s3 | ||
313 | ADDP rk1=KSZ,in2 | ||
314 | br.call.sptk.many b6=_ia64_AES_encrypt };; | ||
315 | |||
316 | { .mib; ADDP in0=4,in1 | ||
317 | ADDP in1=0,in1 | ||
318 | (p6) br.spnt .Le_o_unaligned };; | ||
319 | |||
320 | { .mii; mov psr.um=loc0 | ||
321 | mov ar.pfs=pfssave | ||
322 | mov ar.lc=lcsave };; | ||
323 | { .mmi; st4 [in1]=r16,8 // s0 | ||
324 | st4 [in0]=r20,8 // s1 | ||
325 | mov pr=prsave,0x1ffff };; | ||
326 | { .mmb; st4 [in1]=r24 // s2 | ||
327 | st4 [in0]=r28 // s3 | ||
328 | br.ret.sptk.many b0 };; | ||
329 | #endif | ||
330 | |||
331 | .align 32 | ||
332 | .Le_i_unaligned: | ||
333 | { .mmi; add out0=1,in0 | ||
334 | add out2=2,in0 | ||
335 | add out4=3,in0 };; | ||
336 | { .mmi; ld1 r16=[in0],4 | ||
337 | ld1 r17=[out0],4 }//;; | ||
338 | { .mmi; ld1 r18=[out2],4 | ||
339 | ld1 out1=[out4],4 };; // s0 | ||
340 | { .mmi; ld1 r20=[in0],4 | ||
341 | ld1 r21=[out0],4 }//;; | ||
342 | { .mmi; ld1 r22=[out2],4 | ||
343 | ld1 out3=[out4],4 };; // s1 | ||
344 | { .mmi; ld1 r24=[in0],4 | ||
345 | ld1 r25=[out0],4 }//;; | ||
346 | { .mmi; ld1 r26=[out2],4 | ||
347 | ld1 out5=[out4],4 };; // s2 | ||
348 | { .mmi; ld1 r28=[in0] | ||
349 | ld1 r29=[out0] }//;; | ||
350 | { .mmi; ld1 r30=[out2] | ||
351 | ld1 out7=[out4] };; // s3 | ||
352 | |||
353 | { .mii; | ||
354 | dep out1=r16,out1,24,8 //;; | ||
355 | dep out3=r20,out3,24,8 }//;; | ||
356 | { .mii; ADDP rk0=0,in2 | ||
357 | dep out5=r24,out5,24,8 //;; | ||
358 | dep out7=r28,out7,24,8 };; | ||
359 | { .mii; ADDP rk1=KSZ,in2 | ||
360 | dep out1=r17,out1,16,8 //;; | ||
361 | dep out3=r21,out3,16,8 }//;; | ||
362 | { .mii; mov twenty4=24 | ||
363 | dep out5=r25,out5,16,8 //;; | ||
364 | dep out7=r29,out7,16,8 };; | ||
365 | { .mii; mov sixteen=16 | ||
366 | dep out1=r18,out1,8,8 //;; | ||
367 | dep out3=r22,out3,8,8 }//;; | ||
368 | { .mii; mov maskff=0xff | ||
369 | dep out5=r26,out5,8,8 //;; | ||
370 | dep out7=r30,out7,8,8 };; | ||
371 | |||
372 | { .mib; br.call.sptk.many b6=_ia64_AES_encrypt };; | ||
373 | |||
374 | .Le_o_unaligned: | ||
375 | { .mii; ADDP out0=0,in1 | ||
376 | extr.u r17=r16,8,8 // s0 | ||
377 | shr.u r19=r16,twenty4 }//;; | ||
378 | { .mii; ADDP out1=1,in1 | ||
379 | extr.u r18=r16,16,8 | ||
380 | shr.u r23=r20,twenty4 }//;; // s1 | ||
381 | { .mii; ADDP out2=2,in1 | ||
382 | extr.u r21=r20,8,8 | ||
383 | shr.u r22=r20,sixteen }//;; | ||
384 | { .mii; ADDP out3=3,in1 | ||
385 | extr.u r25=r24,8,8 // s2 | ||
386 | shr.u r27=r24,twenty4 };; | ||
387 | { .mii; st1 [out3]=r16,4 | ||
388 | extr.u r26=r24,16,8 | ||
389 | shr.u r31=r28,twenty4 }//;; // s3 | ||
390 | { .mii; st1 [out2]=r17,4 | ||
391 | extr.u r29=r28,8,8 | ||
392 | shr.u r30=r28,sixteen }//;; | ||
393 | |||
394 | { .mmi; st1 [out1]=r18,4 | ||
395 | st1 [out0]=r19,4 };; | ||
396 | { .mmi; st1 [out3]=r20,4 | ||
397 | st1 [out2]=r21,4 }//;; | ||
398 | { .mmi; st1 [out1]=r22,4 | ||
399 | st1 [out0]=r23,4 };; | ||
400 | { .mmi; st1 [out3]=r24,4 | ||
401 | st1 [out2]=r25,4 | ||
402 | mov pr=prsave,0x1ffff }//;; | ||
403 | { .mmi; st1 [out1]=r26,4 | ||
404 | st1 [out0]=r27,4 | ||
405 | mov ar.pfs=pfssave };; | ||
406 | { .mmi; st1 [out3]=r28 | ||
407 | st1 [out2]=r29 | ||
408 | mov ar.lc=lcsave }//;; | ||
409 | { .mmi; st1 [out1]=r30 | ||
410 | st1 [out0]=r31 } | ||
411 | { .mfb; mov psr.um=loc0 // restore user mask | ||
412 | br.ret.sptk.many b0 };; | ||
413 | .endp AES_encrypt# | ||
414 | |||
415 | // *AES_decrypt are autogenerated by the following script: | ||
416 | #if 0 | ||
417 | #!/usr/bin/env perl | ||
418 | print "// *AES_decrypt are autogenerated by the following script:\n#if 0\n"; | ||
419 | open(PROG,'<'.$0); while(<PROG>) { print; } close(PROG); | ||
420 | print "#endif\n"; | ||
421 | while(<>) { | ||
422 | $process=1 if (/\.proc\s+_ia64_AES_encrypt/); | ||
423 | next if (!$process); | ||
424 | |||
425 | #s/te00=s0/td00=s0/; s/te00/td00/g; | ||
426 | s/te11=s1/td13=s3/; s/te11/td13/g; | ||
427 | #s/te22=s2/td22=s2/; s/te22/td22/g; | ||
428 | s/te33=s3/td31=s1/; s/te33/td31/g; | ||
429 | |||
430 | #s/te01=s1/td01=s1/; s/te01/td01/g; | ||
431 | s/te12=s2/td10=s0/; s/te12/td10/g; | ||
432 | #s/te23=s3/td23=s3/; s/te23/td23/g; | ||
433 | s/te30=s0/td32=s2/; s/te30/td32/g; | ||
434 | |||
435 | #s/te02=s2/td02=s2/; s/te02/td02/g; | ||
436 | s/te13=s3/td11=s1/; s/te13/td11/g; | ||
437 | #s/te20=s0/td20=s0/; s/te20/td20/g; | ||
438 | s/te31=s1/td33=s3/; s/te31/td33/g; | ||
439 | |||
440 | #s/te03=s3/td03=s3/; s/te03/td03/g; | ||
441 | s/te10=s0/td12=s2/; s/te10/td12/g; | ||
442 | #s/te21=s1/td21=s1/; s/te21/td21/g; | ||
443 | s/te32=s2/td30=s0/; s/te32/td30/g; | ||
444 | |||
445 | s/td/te/g; | ||
446 | |||
447 | s/AES_encrypt/AES_decrypt/g; | ||
448 | s/\.Le_/.Ld_/g; | ||
449 | s/AES_Te#/AES_Td#/g; | ||
450 | |||
451 | print; | ||
452 | |||
453 | exit if (/\.endp\s+AES_decrypt/); | ||
454 | } | ||
455 | #endif | ||
456 | .proc _ia64_AES_decrypt# | ||
457 | // Input: rk0-rk1 | ||
458 | // te0 | ||
459 | // te3 as AES_KEY->rounds!!! | ||
460 | // s0-s3 | ||
461 | // maskff,twenty4,sixteen | ||
462 | // Output: r16,r20,r24,r28 as s0-s3 | ||
463 | // Clobber: r16-r31,rk0-rk1,r32-r43 | ||
464 | .align 32 | ||
465 | _ia64_AES_decrypt: | ||
466 | .prologue | ||
467 | .altrp b6 | ||
468 | .body | ||
469 | { .mmi; alloc r16=ar.pfs,12,0,0,8 | ||
470 | LDKEY t0=[rk0],2*KSZ | ||
471 | mov pr.rot=1<<16 } | ||
472 | { .mmi; LDKEY t1=[rk1],2*KSZ | ||
473 | add te1=TE1,te0 | ||
474 | add te3=-3,te3 };; | ||
475 | { .mib; LDKEY t2=[rk0],2*KSZ | ||
476 | mov ar.ec=2 } | ||
477 | { .mib; LDKEY t3=[rk1],2*KSZ | ||
478 | add te2=TE2,te0 | ||
479 | brp.loop.imp .Ld_top,.Ld_end-16 };; | ||
480 | |||
481 | { .mmi; xor s0=s0,t0 | ||
482 | xor s1=s1,t1 | ||
483 | mov ar.lc=te3 } | ||
484 | { .mmi; xor s2=s2,t2 | ||
485 | xor s3=s3,t3 | ||
486 | add te3=TE3,te0 };; | ||
487 | |||
488 | .align 32 | ||
489 | .Ld_top: | ||
490 | { .mmi; (p0) LDKEY t0=[rk0],2*KSZ // 0/0:rk[0] | ||
491 | (p0) and te31=s1,maskff // 0/0:s3&0xff | ||
492 | (p0) extr.u te22=s2,8,8 } // 0/0:s2>>8&0xff | ||
493 | { .mmi; (p0) LDKEY t1=[rk1],2*KSZ // 0/1:rk[1] | ||
494 | (p0) and te32=s2,maskff // 0/1:s0&0xff | ||
495 | (p0) shr.u te00=s0,twenty4 };; // 0/0:s0>>24 | ||
496 | { .mmi; (p0) LDKEY t2=[rk0],2*KSZ // 1/2:rk[2] | ||
497 | (p0) shladd te31=te31,3,te3 // 1/0:te0+s0>>24 | ||
498 | (p0) extr.u te23=s3,8,8 } // 1/1:s3>>8&0xff | ||
499 | { .mmi; (p0) LDKEY t3=[rk1],2*KSZ // 1/3:rk[3] | ||
500 | (p0) shladd te32=te32,3,te3 // 1/1:te3+s0 | ||
501 | (p0) shr.u te01=s1,twenty4 };; // 1/1:s1>>24 | ||
502 | { .mmi; (p0) ld4 te31=[te31] // 2/0:te3[s3&0xff] | ||
503 | (p0) shladd te22=te22,3,te2 // 2/0:te2+s2>>8&0xff | ||
504 | (p0) extr.u te20=s0,8,8 } // 2/2:s0>>8&0xff | ||
505 | { .mmi; (p0) ld4 te32=[te32] // 2/1:te3[s0] | ||
506 | (p0) shladd te23=te23,3,te2 // 2/1:te2+s3>>8 | ||
507 | (p0) shr.u te02=s2,twenty4 };; // 2/2:s2>>24 | ||
508 | { .mmi; (p0) ld4 te22=[te22] // 3/0:te2[s2>>8] | ||
509 | (p0) shladd te20=te20,3,te2 // 3/2:te2+s0>>8 | ||
510 | (p0) extr.u te21=s1,8,8 } // 3/3:s1>>8&0xff | ||
511 | { .mmi; (p0) ld4 te23=[te23] // 3/1:te2[s3>>8] | ||
512 | (p0) shladd te00=te00,3,te0 // 3/0:te0+s0>>24 | ||
513 | (p0) shr.u te03=s3,twenty4 };; // 3/3:s3>>24 | ||
514 | { .mmi; (p0) ld4 te20=[te20] // 4/2:te2[s0>>8] | ||
515 | (p0) shladd te21=te21,3,te2 // 4/3:te3+s2 | ||
516 | (p0) extr.u te13=s3,16,8 } // 4/0:s1>>16&0xff | ||
517 | { .mmi; (p0) ld4 te00=[te00] // 4/0:te0[s0>>24] | ||
518 | (p0) shladd te01=te01,3,te0 // 4/1:te0+s1>>24 | ||
519 | (p0) shr.u te11=s1,sixteen };; // 4/2:s3>>16 | ||
520 | { .mmi; (p0) ld4 te21=[te21] // 5/3:te2[s1>>8] | ||
521 | (p0) shladd te13=te13,3,te1 // 5/0:te1+s1>>16 | ||
522 | (p0) extr.u te10=s0,16,8 } // 5/1:s2>>16&0xff | ||
523 | { .mmi; (p0) ld4 te01=[te01] // 5/1:te0[s1>>24] | ||
524 | (p0) shladd te02=te02,3,te0 // 5/2:te0+s2>>24 | ||
525 | (p0) and te33=s3,maskff };; // 5/2:s1&0xff | ||
526 | { .mmi; (p0) ld4 te13=[te13] // 6/0:te1[s1>>16] | ||
527 | (p0) shladd te10=te10,3,te1 // 6/1:te1+s2>>16 | ||
528 | (p0) extr.u te12=s2,16,8 } // 6/3:s0>>16&0xff | ||
529 | { .mmi; (p0) ld4 te02=[te02] // 6/2:te0[s2>>24] | ||
530 | (p0) shladd te03=te03,3,te0 // 6/3:te1+s0>>16 | ||
531 | (p0) and te30=s0,maskff };; // 6/3:s2&0xff | ||
532 | |||
533 | { .mmi; (p0) ld4 te10=[te10] // 7/1:te1[s2>>16] | ||
534 | (p0) shladd te33=te33,3,te3 // 7/2:te3+s1&0xff | ||
535 | (p0) and te11=te11,maskff} // 7/2:s3>>16&0xff | ||
536 | { .mmi; (p0) ld4 te03=[te03] // 7/3:te0[s3>>24] | ||
537 | (p0) shladd te30=te30,3,te3 // 7/3:te3+s2 | ||
538 | (p0) xor t0=t0,te31 };; // 7/0: | ||
539 | { .mmi; (p0) ld4 te33=[te33] // 8/2:te3[s1] | ||
540 | (p0) shladd te11=te11,3,te1 // 8/2:te1+s3>>16 | ||
541 | (p0) xor t0=t0,te22 } // 8/0: | ||
542 | { .mmi; (p0) ld4 te30=[te30] // 8/3:te3[s2] | ||
543 | (p0) shladd te12=te12,3,te1 // 8/3:te1+s0>>16 | ||
544 | (p0) xor t1=t1,te32 };; // 8/1: | ||
545 | { .mmi; (p0) ld4 te11=[te11] // 9/2:te1[s3>>16] | ||
546 | (p0) ld4 te12=[te12] // 9/3:te1[s0>>16] | ||
547 | (p0) xor t0=t0,te00 };; // 9/0: !L2 scheduling | ||
548 | { .mmi; (p0) xor t1=t1,te23 // 10[9]/1: | ||
549 | (p0) xor t2=t2,te20 // 10[9]/2: | ||
550 | (p0) xor t3=t3,te21 };; // 10[9]/3: | ||
551 | { .mmi; (p0) xor t0=t0,te13 // 11[10]/0:done! | ||
552 | (p0) xor t1=t1,te01 // 11[10]/1: | ||
553 | (p0) xor t2=t2,te02 };; // 11[10]/2: !L2 scheduling | ||
554 | { .mmi; (p0) xor t3=t3,te03 // 12[10]/3: | ||
555 | (p16) cmp.eq p0,p17=r0,r0 };; // 12[10]/clear (p17) | ||
556 | { .mmi; (p0) xor t1=t1,te10 // 13[11]/1:done! | ||
557 | (p0) xor t2=t2,te33 // 13[11]/2: | ||
558 | (p0) xor t3=t3,te30 } // 13[11]/3: | ||
559 | { .mmi; (p17) add te0=2048,te0 // 13[11]/ | ||
560 | (p17) add te1=2048+64-TE1,te1};; // 13[11]/ | ||
561 | { .mib; (p0) xor t2=t2,te11 // 14[12]/2:done! | ||
562 | (p17) add te2=2048+128-TE2,te2} // 14[12]/ | ||
563 | { .mib; (p0) xor t3=t3,te12 // 14[12]/3:done! | ||
564 | (p17) add te3=2048+192-TE3,te3 // 14[12]/ | ||
565 | br.ctop.sptk .Ld_top };; | ||
566 | .Ld_end: | ||
567 | |||
568 | |||
569 | { .mmi; ld8 te10=[te0] // prefetch Td4 | ||
570 | ld8 te33=[te1] } | ||
571 | { .mmi; ld8 te12=[te2] | ||
572 | ld8 te30=[te3] } | ||
573 | |||
574 | { .mmi; LDKEY t0=[rk0],2*KSZ // 0/0:rk[0] | ||
575 | and te31=s1,maskff // 0/0:s3&0xff | ||
576 | extr.u te22=s2,8,8 } // 0/0:s2>>8&0xff | ||
577 | { .mmi; LDKEY t1=[rk1],2*KSZ // 0/1:rk[1] | ||
578 | and te32=s2,maskff // 0/1:s0&0xff | ||
579 | shr.u te00=s0,twenty4 };; // 0/0:s0>>24 | ||
580 | { .mmi; LDKEY t2=[rk0],2*KSZ // 1/2:rk[2] | ||
581 | add te31=te31,te0 // 1/0:te0+s0>>24 | ||
582 | extr.u te23=s3,8,8 } // 1/1:s3>>8&0xff | ||
583 | { .mmi; LDKEY t3=[rk1],2*KSZ // 1/3:rk[3] | ||
584 | add te32=te32,te0 // 1/1:te0+s0 | ||
585 | shr.u te01=s1,twenty4 };; // 1/1:s1>>24 | ||
586 | { .mmi; ld1 te31=[te31] // 2/0:te0[s3&0xff] | ||
587 | add te22=te22,te0 // 2/0:te0+s2>>8&0xff | ||
588 | extr.u te20=s0,8,8 } // 2/2:s0>>8&0xff | ||
589 | { .mmi; ld1 te32=[te32] // 2/1:te0[s0] | ||
590 | add te23=te23,te0 // 2/1:te0+s3>>8 | ||
591 | shr.u te02=s2,twenty4 };; // 2/2:s2>>24 | ||
592 | { .mmi; ld1 te22=[te22] // 3/0:te0[s2>>8] | ||
593 | add te20=te20,te0 // 3/2:te0+s0>>8 | ||
594 | extr.u te21=s1,8,8 } // 3/3:s1>>8&0xff | ||
595 | { .mmi; ld1 te23=[te23] // 3/1:te0[s3>>8] | ||
596 | add te00=te00,te0 // 3/0:te0+s0>>24 | ||
597 | shr.u te03=s3,twenty4 };; // 3/3:s3>>24 | ||
598 | { .mmi; ld1 te20=[te20] // 4/2:te0[s0>>8] | ||
599 | add te21=te21,te0 // 4/3:te0+s2 | ||
600 | extr.u te13=s3,16,8 } // 4/0:s1>>16&0xff | ||
601 | { .mmi; ld1 te00=[te00] // 4/0:te0[s0>>24] | ||
602 | add te01=te01,te0 // 4/1:te0+s1>>24 | ||
603 | shr.u te11=s1,sixteen };; // 4/2:s3>>16 | ||
604 | { .mmi; ld1 te21=[te21] // 5/3:te0[s1>>8] | ||
605 | add te13=te13,te0 // 5/0:te0+s1>>16 | ||
606 | extr.u te10=s0,16,8 } // 5/1:s2>>16&0xff | ||
607 | { .mmi; ld1 te01=[te01] // 5/1:te0[s1>>24] | ||
608 | add te02=te02,te0 // 5/2:te0+s2>>24 | ||
609 | and te33=s3,maskff };; // 5/2:s1&0xff | ||
610 | { .mmi; ld1 te13=[te13] // 6/0:te0[s1>>16] | ||
611 | add te10=te10,te0 // 6/1:te0+s2>>16 | ||
612 | extr.u te12=s2,16,8 } // 6/3:s0>>16&0xff | ||
613 | { .mmi; ld1 te02=[te02] // 6/2:te0[s2>>24] | ||
614 | add te03=te03,te0 // 6/3:te0+s0>>16 | ||
615 | and te30=s0,maskff };; // 6/3:s2&0xff | ||
616 | |||
617 | { .mmi; ld1 te10=[te10] // 7/1:te0[s2>>16] | ||
618 | add te33=te33,te0 // 7/2:te0+s1&0xff | ||
619 | dep te31=te22,te31,8,8} // 7/0: | ||
620 | { .mmi; ld1 te03=[te03] // 7/3:te0[s3>>24] | ||
621 | add te30=te30,te0 // 7/3:te0+s2 | ||
622 | and te11=te11,maskff};; // 7/2:s3>>16&0xff | ||
623 | { .mmi; ld1 te33=[te33] // 8/2:te0[s1] | ||
624 | add te11=te11,te0 // 8/2:te0+s3>>16 | ||
625 | dep te32=te23,te32,8,8} // 8/1: | ||
626 | { .mmi; ld1 te30=[te30] // 8/3:te0[s2] | ||
627 | add te12=te12,te0 // 8/3:te0+s0>>16 | ||
628 | shl te00=te00,twenty4};; // 8/0: | ||
629 | { .mii; ld1 te11=[te11] // 9/2:te0[s3>>16] | ||
630 | dep te31=te13,te31,16,8 // 9/0: | ||
631 | shl te01=te01,twenty4};; // 9/1: | ||
632 | { .mii; ld1 te12=[te12] // 10/3:te0[s0>>16] | ||
633 | dep te33=te20,te33,8,8 // 10/2: | ||
634 | shl te02=te02,twenty4};; // 10/2: | ||
635 | { .mii; xor t0=t0,te31 // 11/0: | ||
636 | dep te30=te21,te30,8,8 // 11/3: | ||
637 | shl te10=te10,sixteen};; // 11/1: | ||
638 | { .mii; xor r16=t0,te00 // 12/0:done! | ||
639 | dep te33=te11,te33,16,8 // 12/2: | ||
640 | shl te03=te03,twenty4};; // 12/3: | ||
641 | { .mmi; xor t1=t1,te01 // 13/1: | ||
642 | xor t2=t2,te02 // 13/2: | ||
643 | dep te30=te12,te30,16,8};; // 13/3: | ||
644 | { .mmi; xor t1=t1,te32 // 14/1: | ||
645 | xor r24=t2,te33 // 14/2:done! | ||
646 | xor t3=t3,te30 };; // 14/3: | ||
647 | { .mib; xor r20=t1,te10 // 15/1:done! | ||
648 | xor r28=t3,te03 // 15/3:done! | ||
649 | br.ret.sptk b6 };; | ||
650 | .endp _ia64_AES_decrypt# | ||
651 | |||
652 | // void AES_decrypt (const void *in,void *out,const AES_KEY *key); | ||
653 | .global AES_decrypt# | ||
654 | .proc AES_decrypt# | ||
655 | .align 32 | ||
656 | AES_decrypt: | ||
657 | .prologue | ||
658 | .save ar.pfs,pfssave | ||
659 | { .mmi; alloc pfssave=ar.pfs,3,1,12,0 | ||
660 | and out0=3,in0 | ||
661 | mov r3=ip } | ||
662 | { .mmi; ADDP in0=0,in0 | ||
663 | mov loc0=psr.um | ||
664 | ADDP out11=KSZ*60,in2 };; // &AES_KEY->rounds | ||
665 | |||
666 | { .mmi; ld4 out11=[out11] // AES_KEY->rounds | ||
667 | add out8=(AES_Td#-AES_decrypt#),r3 // Te0 | ||
668 | .save pr,prsave | ||
669 | mov prsave=pr } | ||
670 | { .mmi; rum 1<<3 // clear um.ac | ||
671 | .save ar.lc,lcsave | ||
672 | mov lcsave=ar.lc };; | ||
673 | |||
674 | .body | ||
675 | #if defined(_HPUX_SOURCE) // HPUX is big-endian, cut 15+15 cycles... | ||
676 | { .mib; cmp.ne p6,p0=out0,r0 | ||
677 | add out0=4,in0 | ||
678 | (p6) br.dpnt.many .Ld_i_unaligned };; | ||
679 | |||
680 | { .mmi; ld4 out1=[in0],8 // s0 | ||
681 | and out9=3,in1 | ||
682 | mov twenty4=24 } | ||
683 | { .mmi; ld4 out3=[out0],8 // s1 | ||
684 | ADDP rk0=0,in2 | ||
685 | mov sixteen=16 };; | ||
686 | { .mmi; ld4 out5=[in0] // s2 | ||
687 | cmp.ne p6,p0=out9,r0 | ||
688 | mov maskff=0xff } | ||
689 | { .mmb; ld4 out7=[out0] // s3 | ||
690 | ADDP rk1=KSZ,in2 | ||
691 | br.call.sptk.many b6=_ia64_AES_decrypt };; | ||
692 | |||
693 | { .mib; ADDP in0=4,in1 | ||
694 | ADDP in1=0,in1 | ||
695 | (p6) br.spnt .Ld_o_unaligned };; | ||
696 | |||
697 | { .mii; mov psr.um=loc0 | ||
698 | mov ar.pfs=pfssave | ||
699 | mov ar.lc=lcsave };; | ||
700 | { .mmi; st4 [in1]=r16,8 // s0 | ||
701 | st4 [in0]=r20,8 // s1 | ||
702 | mov pr=prsave,0x1ffff };; | ||
703 | { .mmb; st4 [in1]=r24 // s2 | ||
704 | st4 [in0]=r28 // s3 | ||
705 | br.ret.sptk.many b0 };; | ||
706 | #endif | ||
707 | |||
708 | .align 32 | ||
709 | .Ld_i_unaligned: | ||
710 | { .mmi; add out0=1,in0 | ||
711 | add out2=2,in0 | ||
712 | add out4=3,in0 };; | ||
713 | { .mmi; ld1 r16=[in0],4 | ||
714 | ld1 r17=[out0],4 }//;; | ||
715 | { .mmi; ld1 r18=[out2],4 | ||
716 | ld1 out1=[out4],4 };; // s0 | ||
717 | { .mmi; ld1 r20=[in0],4 | ||
718 | ld1 r21=[out0],4 }//;; | ||
719 | { .mmi; ld1 r22=[out2],4 | ||
720 | ld1 out3=[out4],4 };; // s1 | ||
721 | { .mmi; ld1 r24=[in0],4 | ||
722 | ld1 r25=[out0],4 }//;; | ||
723 | { .mmi; ld1 r26=[out2],4 | ||
724 | ld1 out5=[out4],4 };; // s2 | ||
725 | { .mmi; ld1 r28=[in0] | ||
726 | ld1 r29=[out0] }//;; | ||
727 | { .mmi; ld1 r30=[out2] | ||
728 | ld1 out7=[out4] };; // s3 | ||
729 | |||
730 | { .mii; | ||
731 | dep out1=r16,out1,24,8 //;; | ||
732 | dep out3=r20,out3,24,8 }//;; | ||
733 | { .mii; ADDP rk0=0,in2 | ||
734 | dep out5=r24,out5,24,8 //;; | ||
735 | dep out7=r28,out7,24,8 };; | ||
736 | { .mii; ADDP rk1=KSZ,in2 | ||
737 | dep out1=r17,out1,16,8 //;; | ||
738 | dep out3=r21,out3,16,8 }//;; | ||
739 | { .mii; mov twenty4=24 | ||
740 | dep out5=r25,out5,16,8 //;; | ||
741 | dep out7=r29,out7,16,8 };; | ||
742 | { .mii; mov sixteen=16 | ||
743 | dep out1=r18,out1,8,8 //;; | ||
744 | dep out3=r22,out3,8,8 }//;; | ||
745 | { .mii; mov maskff=0xff | ||
746 | dep out5=r26,out5,8,8 //;; | ||
747 | dep out7=r30,out7,8,8 };; | ||
748 | |||
749 | { .mib; br.call.sptk.many b6=_ia64_AES_decrypt };; | ||
750 | |||
751 | .Ld_o_unaligned: | ||
752 | { .mii; ADDP out0=0,in1 | ||
753 | extr.u r17=r16,8,8 // s0 | ||
754 | shr.u r19=r16,twenty4 }//;; | ||
755 | { .mii; ADDP out1=1,in1 | ||
756 | extr.u r18=r16,16,8 | ||
757 | shr.u r23=r20,twenty4 }//;; // s1 | ||
758 | { .mii; ADDP out2=2,in1 | ||
759 | extr.u r21=r20,8,8 | ||
760 | shr.u r22=r20,sixteen }//;; | ||
761 | { .mii; ADDP out3=3,in1 | ||
762 | extr.u r25=r24,8,8 // s2 | ||
763 | shr.u r27=r24,twenty4 };; | ||
764 | { .mii; st1 [out3]=r16,4 | ||
765 | extr.u r26=r24,16,8 | ||
766 | shr.u r31=r28,twenty4 }//;; // s3 | ||
767 | { .mii; st1 [out2]=r17,4 | ||
768 | extr.u r29=r28,8,8 | ||
769 | shr.u r30=r28,sixteen }//;; | ||
770 | |||
771 | { .mmi; st1 [out1]=r18,4 | ||
772 | st1 [out0]=r19,4 };; | ||
773 | { .mmi; st1 [out3]=r20,4 | ||
774 | st1 [out2]=r21,4 }//;; | ||
775 | { .mmi; st1 [out1]=r22,4 | ||
776 | st1 [out0]=r23,4 };; | ||
777 | { .mmi; st1 [out3]=r24,4 | ||
778 | st1 [out2]=r25,4 | ||
779 | mov pr=prsave,0x1ffff }//;; | ||
780 | { .mmi; st1 [out1]=r26,4 | ||
781 | st1 [out0]=r27,4 | ||
782 | mov ar.pfs=pfssave };; | ||
783 | { .mmi; st1 [out3]=r28 | ||
784 | st1 [out2]=r29 | ||
785 | mov ar.lc=lcsave }//;; | ||
786 | { .mmi; st1 [out1]=r30 | ||
787 | st1 [out0]=r31 } | ||
788 | { .mfb; mov psr.um=loc0 // restore user mask | ||
789 | br.ret.sptk.many b0 };; | ||
790 | .endp AES_decrypt# | ||
791 | |||
792 | // leave it in .text segment... | ||
793 | .align 64 | ||
794 | .global AES_Te# | ||
795 | .type AES_Te#,@object | ||
796 | AES_Te: data4 0xc66363a5,0xc66363a5, 0xf87c7c84,0xf87c7c84 | ||
797 | data4 0xee777799,0xee777799, 0xf67b7b8d,0xf67b7b8d | ||
798 | data4 0xfff2f20d,0xfff2f20d, 0xd66b6bbd,0xd66b6bbd | ||
799 | data4 0xde6f6fb1,0xde6f6fb1, 0x91c5c554,0x91c5c554 | ||
800 | data4 0x60303050,0x60303050, 0x02010103,0x02010103 | ||
801 | data4 0xce6767a9,0xce6767a9, 0x562b2b7d,0x562b2b7d | ||
802 | data4 0xe7fefe19,0xe7fefe19, 0xb5d7d762,0xb5d7d762 | ||
803 | data4 0x4dababe6,0x4dababe6, 0xec76769a,0xec76769a | ||
804 | data4 0x8fcaca45,0x8fcaca45, 0x1f82829d,0x1f82829d | ||
805 | data4 0x89c9c940,0x89c9c940, 0xfa7d7d87,0xfa7d7d87 | ||
806 | data4 0xeffafa15,0xeffafa15, 0xb25959eb,0xb25959eb | ||
807 | data4 0x8e4747c9,0x8e4747c9, 0xfbf0f00b,0xfbf0f00b | ||
808 | data4 0x41adadec,0x41adadec, 0xb3d4d467,0xb3d4d467 | ||
809 | data4 0x5fa2a2fd,0x5fa2a2fd, 0x45afafea,0x45afafea | ||
810 | data4 0x239c9cbf,0x239c9cbf, 0x53a4a4f7,0x53a4a4f7 | ||
811 | data4 0xe4727296,0xe4727296, 0x9bc0c05b,0x9bc0c05b | ||
812 | data4 0x75b7b7c2,0x75b7b7c2, 0xe1fdfd1c,0xe1fdfd1c | ||
813 | data4 0x3d9393ae,0x3d9393ae, 0x4c26266a,0x4c26266a | ||
814 | data4 0x6c36365a,0x6c36365a, 0x7e3f3f41,0x7e3f3f41 | ||
815 | data4 0xf5f7f702,0xf5f7f702, 0x83cccc4f,0x83cccc4f | ||
816 | data4 0x6834345c,0x6834345c, 0x51a5a5f4,0x51a5a5f4 | ||
817 | data4 0xd1e5e534,0xd1e5e534, 0xf9f1f108,0xf9f1f108 | ||
818 | data4 0xe2717193,0xe2717193, 0xabd8d873,0xabd8d873 | ||
819 | data4 0x62313153,0x62313153, 0x2a15153f,0x2a15153f | ||
820 | data4 0x0804040c,0x0804040c, 0x95c7c752,0x95c7c752 | ||
821 | data4 0x46232365,0x46232365, 0x9dc3c35e,0x9dc3c35e | ||
822 | data4 0x30181828,0x30181828, 0x379696a1,0x379696a1 | ||
823 | data4 0x0a05050f,0x0a05050f, 0x2f9a9ab5,0x2f9a9ab5 | ||
824 | data4 0x0e070709,0x0e070709, 0x24121236,0x24121236 | ||
825 | data4 0x1b80809b,0x1b80809b, 0xdfe2e23d,0xdfe2e23d | ||
826 | data4 0xcdebeb26,0xcdebeb26, 0x4e272769,0x4e272769 | ||
827 | data4 0x7fb2b2cd,0x7fb2b2cd, 0xea75759f,0xea75759f | ||
828 | data4 0x1209091b,0x1209091b, 0x1d83839e,0x1d83839e | ||
829 | data4 0x582c2c74,0x582c2c74, 0x341a1a2e,0x341a1a2e | ||
830 | data4 0x361b1b2d,0x361b1b2d, 0xdc6e6eb2,0xdc6e6eb2 | ||
831 | data4 0xb45a5aee,0xb45a5aee, 0x5ba0a0fb,0x5ba0a0fb | ||
832 | data4 0xa45252f6,0xa45252f6, 0x763b3b4d,0x763b3b4d | ||
833 | data4 0xb7d6d661,0xb7d6d661, 0x7db3b3ce,0x7db3b3ce | ||
834 | data4 0x5229297b,0x5229297b, 0xdde3e33e,0xdde3e33e | ||
835 | data4 0x5e2f2f71,0x5e2f2f71, 0x13848497,0x13848497 | ||
836 | data4 0xa65353f5,0xa65353f5, 0xb9d1d168,0xb9d1d168 | ||
837 | data4 0x00000000,0x00000000, 0xc1eded2c,0xc1eded2c | ||
838 | data4 0x40202060,0x40202060, 0xe3fcfc1f,0xe3fcfc1f | ||
839 | data4 0x79b1b1c8,0x79b1b1c8, 0xb65b5bed,0xb65b5bed | ||
840 | data4 0xd46a6abe,0xd46a6abe, 0x8dcbcb46,0x8dcbcb46 | ||
841 | data4 0x67bebed9,0x67bebed9, 0x7239394b,0x7239394b | ||
842 | data4 0x944a4ade,0x944a4ade, 0x984c4cd4,0x984c4cd4 | ||
843 | data4 0xb05858e8,0xb05858e8, 0x85cfcf4a,0x85cfcf4a | ||
844 | data4 0xbbd0d06b,0xbbd0d06b, 0xc5efef2a,0xc5efef2a | ||
845 | data4 0x4faaaae5,0x4faaaae5, 0xedfbfb16,0xedfbfb16 | ||
846 | data4 0x864343c5,0x864343c5, 0x9a4d4dd7,0x9a4d4dd7 | ||
847 | data4 0x66333355,0x66333355, 0x11858594,0x11858594 | ||
848 | data4 0x8a4545cf,0x8a4545cf, 0xe9f9f910,0xe9f9f910 | ||
849 | data4 0x04020206,0x04020206, 0xfe7f7f81,0xfe7f7f81 | ||
850 | data4 0xa05050f0,0xa05050f0, 0x783c3c44,0x783c3c44 | ||
851 | data4 0x259f9fba,0x259f9fba, 0x4ba8a8e3,0x4ba8a8e3 | ||
852 | data4 0xa25151f3,0xa25151f3, 0x5da3a3fe,0x5da3a3fe | ||
853 | data4 0x804040c0,0x804040c0, 0x058f8f8a,0x058f8f8a | ||
854 | data4 0x3f9292ad,0x3f9292ad, 0x219d9dbc,0x219d9dbc | ||
855 | data4 0x70383848,0x70383848, 0xf1f5f504,0xf1f5f504 | ||
856 | data4 0x63bcbcdf,0x63bcbcdf, 0x77b6b6c1,0x77b6b6c1 | ||
857 | data4 0xafdada75,0xafdada75, 0x42212163,0x42212163 | ||
858 | data4 0x20101030,0x20101030, 0xe5ffff1a,0xe5ffff1a | ||
859 | data4 0xfdf3f30e,0xfdf3f30e, 0xbfd2d26d,0xbfd2d26d | ||
860 | data4 0x81cdcd4c,0x81cdcd4c, 0x180c0c14,0x180c0c14 | ||
861 | data4 0x26131335,0x26131335, 0xc3ecec2f,0xc3ecec2f | ||
862 | data4 0xbe5f5fe1,0xbe5f5fe1, 0x359797a2,0x359797a2 | ||
863 | data4 0x884444cc,0x884444cc, 0x2e171739,0x2e171739 | ||
864 | data4 0x93c4c457,0x93c4c457, 0x55a7a7f2,0x55a7a7f2 | ||
865 | data4 0xfc7e7e82,0xfc7e7e82, 0x7a3d3d47,0x7a3d3d47 | ||
866 | data4 0xc86464ac,0xc86464ac, 0xba5d5de7,0xba5d5de7 | ||
867 | data4 0x3219192b,0x3219192b, 0xe6737395,0xe6737395 | ||
868 | data4 0xc06060a0,0xc06060a0, 0x19818198,0x19818198 | ||
869 | data4 0x9e4f4fd1,0x9e4f4fd1, 0xa3dcdc7f,0xa3dcdc7f | ||
870 | data4 0x44222266,0x44222266, 0x542a2a7e,0x542a2a7e | ||
871 | data4 0x3b9090ab,0x3b9090ab, 0x0b888883,0x0b888883 | ||
872 | data4 0x8c4646ca,0x8c4646ca, 0xc7eeee29,0xc7eeee29 | ||
873 | data4 0x6bb8b8d3,0x6bb8b8d3, 0x2814143c,0x2814143c | ||
874 | data4 0xa7dede79,0xa7dede79, 0xbc5e5ee2,0xbc5e5ee2 | ||
875 | data4 0x160b0b1d,0x160b0b1d, 0xaddbdb76,0xaddbdb76 | ||
876 | data4 0xdbe0e03b,0xdbe0e03b, 0x64323256,0x64323256 | ||
877 | data4 0x743a3a4e,0x743a3a4e, 0x140a0a1e,0x140a0a1e | ||
878 | data4 0x924949db,0x924949db, 0x0c06060a,0x0c06060a | ||
879 | data4 0x4824246c,0x4824246c, 0xb85c5ce4,0xb85c5ce4 | ||
880 | data4 0x9fc2c25d,0x9fc2c25d, 0xbdd3d36e,0xbdd3d36e | ||
881 | data4 0x43acacef,0x43acacef, 0xc46262a6,0xc46262a6 | ||
882 | data4 0x399191a8,0x399191a8, 0x319595a4,0x319595a4 | ||
883 | data4 0xd3e4e437,0xd3e4e437, 0xf279798b,0xf279798b | ||
884 | data4 0xd5e7e732,0xd5e7e732, 0x8bc8c843,0x8bc8c843 | ||
885 | data4 0x6e373759,0x6e373759, 0xda6d6db7,0xda6d6db7 | ||
886 | data4 0x018d8d8c,0x018d8d8c, 0xb1d5d564,0xb1d5d564 | ||
887 | data4 0x9c4e4ed2,0x9c4e4ed2, 0x49a9a9e0,0x49a9a9e0 | ||
888 | data4 0xd86c6cb4,0xd86c6cb4, 0xac5656fa,0xac5656fa | ||
889 | data4 0xf3f4f407,0xf3f4f407, 0xcfeaea25,0xcfeaea25 | ||
890 | data4 0xca6565af,0xca6565af, 0xf47a7a8e,0xf47a7a8e | ||
891 | data4 0x47aeaee9,0x47aeaee9, 0x10080818,0x10080818 | ||
892 | data4 0x6fbabad5,0x6fbabad5, 0xf0787888,0xf0787888 | ||
893 | data4 0x4a25256f,0x4a25256f, 0x5c2e2e72,0x5c2e2e72 | ||
894 | data4 0x381c1c24,0x381c1c24, 0x57a6a6f1,0x57a6a6f1 | ||
895 | data4 0x73b4b4c7,0x73b4b4c7, 0x97c6c651,0x97c6c651 | ||
896 | data4 0xcbe8e823,0xcbe8e823, 0xa1dddd7c,0xa1dddd7c | ||
897 | data4 0xe874749c,0xe874749c, 0x3e1f1f21,0x3e1f1f21 | ||
898 | data4 0x964b4bdd,0x964b4bdd, 0x61bdbddc,0x61bdbddc | ||
899 | data4 0x0d8b8b86,0x0d8b8b86, 0x0f8a8a85,0x0f8a8a85 | ||
900 | data4 0xe0707090,0xe0707090, 0x7c3e3e42,0x7c3e3e42 | ||
901 | data4 0x71b5b5c4,0x71b5b5c4, 0xcc6666aa,0xcc6666aa | ||
902 | data4 0x904848d8,0x904848d8, 0x06030305,0x06030305 | ||
903 | data4 0xf7f6f601,0xf7f6f601, 0x1c0e0e12,0x1c0e0e12 | ||
904 | data4 0xc26161a3,0xc26161a3, 0x6a35355f,0x6a35355f | ||
905 | data4 0xae5757f9,0xae5757f9, 0x69b9b9d0,0x69b9b9d0 | ||
906 | data4 0x17868691,0x17868691, 0x99c1c158,0x99c1c158 | ||
907 | data4 0x3a1d1d27,0x3a1d1d27, 0x279e9eb9,0x279e9eb9 | ||
908 | data4 0xd9e1e138,0xd9e1e138, 0xebf8f813,0xebf8f813 | ||
909 | data4 0x2b9898b3,0x2b9898b3, 0x22111133,0x22111133 | ||
910 | data4 0xd26969bb,0xd26969bb, 0xa9d9d970,0xa9d9d970 | ||
911 | data4 0x078e8e89,0x078e8e89, 0x339494a7,0x339494a7 | ||
912 | data4 0x2d9b9bb6,0x2d9b9bb6, 0x3c1e1e22,0x3c1e1e22 | ||
913 | data4 0x15878792,0x15878792, 0xc9e9e920,0xc9e9e920 | ||
914 | data4 0x87cece49,0x87cece49, 0xaa5555ff,0xaa5555ff | ||
915 | data4 0x50282878,0x50282878, 0xa5dfdf7a,0xa5dfdf7a | ||
916 | data4 0x038c8c8f,0x038c8c8f, 0x59a1a1f8,0x59a1a1f8 | ||
917 | data4 0x09898980,0x09898980, 0x1a0d0d17,0x1a0d0d17 | ||
918 | data4 0x65bfbfda,0x65bfbfda, 0xd7e6e631,0xd7e6e631 | ||
919 | data4 0x844242c6,0x844242c6, 0xd06868b8,0xd06868b8 | ||
920 | data4 0x824141c3,0x824141c3, 0x299999b0,0x299999b0 | ||
921 | data4 0x5a2d2d77,0x5a2d2d77, 0x1e0f0f11,0x1e0f0f11 | ||
922 | data4 0x7bb0b0cb,0x7bb0b0cb, 0xa85454fc,0xa85454fc | ||
923 | data4 0x6dbbbbd6,0x6dbbbbd6, 0x2c16163a,0x2c16163a | ||
924 | // Te4: | ||
925 | data1 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5 | ||
926 | data1 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76 | ||
927 | data1 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0 | ||
928 | data1 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0 | ||
929 | data1 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc | ||
930 | data1 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15 | ||
931 | data1 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a | ||
932 | data1 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75 | ||
933 | data1 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0 | ||
934 | data1 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84 | ||
935 | data1 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b | ||
936 | data1 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf | ||
937 | data1 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85 | ||
938 | data1 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8 | ||
939 | data1 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5 | ||
940 | data1 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2 | ||
941 | data1 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17 | ||
942 | data1 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73 | ||
943 | data1 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88 | ||
944 | data1 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb | ||
945 | data1 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c | ||
946 | data1 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79 | ||
947 | data1 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9 | ||
948 | data1 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08 | ||
949 | data1 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6 | ||
950 | data1 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a | ||
951 | data1 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e | ||
952 | data1 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e | ||
953 | data1 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94 | ||
954 | data1 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf | ||
955 | data1 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68 | ||
956 | data1 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16 | ||
957 | .size AES_Te#,2048+256 // HP-UX assembler fails to ".-AES_Te#" | ||
958 | |||
959 | .align 64 | ||
960 | .global AES_Td# | ||
961 | .type AES_Td#,@object | ||
962 | AES_Td: data4 0x51f4a750,0x51f4a750, 0x7e416553,0x7e416553 | ||
963 | data4 0x1a17a4c3,0x1a17a4c3, 0x3a275e96,0x3a275e96 | ||
964 | data4 0x3bab6bcb,0x3bab6bcb, 0x1f9d45f1,0x1f9d45f1 | ||
965 | data4 0xacfa58ab,0xacfa58ab, 0x4be30393,0x4be30393 | ||
966 | data4 0x2030fa55,0x2030fa55, 0xad766df6,0xad766df6 | ||
967 | data4 0x88cc7691,0x88cc7691, 0xf5024c25,0xf5024c25 | ||
968 | data4 0x4fe5d7fc,0x4fe5d7fc, 0xc52acbd7,0xc52acbd7 | ||
969 | data4 0x26354480,0x26354480, 0xb562a38f,0xb562a38f | ||
970 | data4 0xdeb15a49,0xdeb15a49, 0x25ba1b67,0x25ba1b67 | ||
971 | data4 0x45ea0e98,0x45ea0e98, 0x5dfec0e1,0x5dfec0e1 | ||
972 | data4 0xc32f7502,0xc32f7502, 0x814cf012,0x814cf012 | ||
973 | data4 0x8d4697a3,0x8d4697a3, 0x6bd3f9c6,0x6bd3f9c6 | ||
974 | data4 0x038f5fe7,0x038f5fe7, 0x15929c95,0x15929c95 | ||
975 | data4 0xbf6d7aeb,0xbf6d7aeb, 0x955259da,0x955259da | ||
976 | data4 0xd4be832d,0xd4be832d, 0x587421d3,0x587421d3 | ||
977 | data4 0x49e06929,0x49e06929, 0x8ec9c844,0x8ec9c844 | ||
978 | data4 0x75c2896a,0x75c2896a, 0xf48e7978,0xf48e7978 | ||
979 | data4 0x99583e6b,0x99583e6b, 0x27b971dd,0x27b971dd | ||
980 | data4 0xbee14fb6,0xbee14fb6, 0xf088ad17,0xf088ad17 | ||
981 | data4 0xc920ac66,0xc920ac66, 0x7dce3ab4,0x7dce3ab4 | ||
982 | data4 0x63df4a18,0x63df4a18, 0xe51a3182,0xe51a3182 | ||
983 | data4 0x97513360,0x97513360, 0x62537f45,0x62537f45 | ||
984 | data4 0xb16477e0,0xb16477e0, 0xbb6bae84,0xbb6bae84 | ||
985 | data4 0xfe81a01c,0xfe81a01c, 0xf9082b94,0xf9082b94 | ||
986 | data4 0x70486858,0x70486858, 0x8f45fd19,0x8f45fd19 | ||
987 | data4 0x94de6c87,0x94de6c87, 0x527bf8b7,0x527bf8b7 | ||
988 | data4 0xab73d323,0xab73d323, 0x724b02e2,0x724b02e2 | ||
989 | data4 0xe31f8f57,0xe31f8f57, 0x6655ab2a,0x6655ab2a | ||
990 | data4 0xb2eb2807,0xb2eb2807, 0x2fb5c203,0x2fb5c203 | ||
991 | data4 0x86c57b9a,0x86c57b9a, 0xd33708a5,0xd33708a5 | ||
992 | data4 0x302887f2,0x302887f2, 0x23bfa5b2,0x23bfa5b2 | ||
993 | data4 0x02036aba,0x02036aba, 0xed16825c,0xed16825c | ||
994 | data4 0x8acf1c2b,0x8acf1c2b, 0xa779b492,0xa779b492 | ||
995 | data4 0xf307f2f0,0xf307f2f0, 0x4e69e2a1,0x4e69e2a1 | ||
996 | data4 0x65daf4cd,0x65daf4cd, 0x0605bed5,0x0605bed5 | ||
997 | data4 0xd134621f,0xd134621f, 0xc4a6fe8a,0xc4a6fe8a | ||
998 | data4 0x342e539d,0x342e539d, 0xa2f355a0,0xa2f355a0 | ||
999 | data4 0x058ae132,0x058ae132, 0xa4f6eb75,0xa4f6eb75 | ||
1000 | data4 0x0b83ec39,0x0b83ec39, 0x4060efaa,0x4060efaa | ||
1001 | data4 0x5e719f06,0x5e719f06, 0xbd6e1051,0xbd6e1051 | ||
1002 | data4 0x3e218af9,0x3e218af9, 0x96dd063d,0x96dd063d | ||
1003 | data4 0xdd3e05ae,0xdd3e05ae, 0x4de6bd46,0x4de6bd46 | ||
1004 | data4 0x91548db5,0x91548db5, 0x71c45d05,0x71c45d05 | ||
1005 | data4 0x0406d46f,0x0406d46f, 0x605015ff,0x605015ff | ||
1006 | data4 0x1998fb24,0x1998fb24, 0xd6bde997,0xd6bde997 | ||
1007 | data4 0x894043cc,0x894043cc, 0x67d99e77,0x67d99e77 | ||
1008 | data4 0xb0e842bd,0xb0e842bd, 0x07898b88,0x07898b88 | ||
1009 | data4 0xe7195b38,0xe7195b38, 0x79c8eedb,0x79c8eedb | ||
1010 | data4 0xa17c0a47,0xa17c0a47, 0x7c420fe9,0x7c420fe9 | ||
1011 | data4 0xf8841ec9,0xf8841ec9, 0x00000000,0x00000000 | ||
1012 | data4 0x09808683,0x09808683, 0x322bed48,0x322bed48 | ||
1013 | data4 0x1e1170ac,0x1e1170ac, 0x6c5a724e,0x6c5a724e | ||
1014 | data4 0xfd0efffb,0xfd0efffb, 0x0f853856,0x0f853856 | ||
1015 | data4 0x3daed51e,0x3daed51e, 0x362d3927,0x362d3927 | ||
1016 | data4 0x0a0fd964,0x0a0fd964, 0x685ca621,0x685ca621 | ||
1017 | data4 0x9b5b54d1,0x9b5b54d1, 0x24362e3a,0x24362e3a | ||
1018 | data4 0x0c0a67b1,0x0c0a67b1, 0x9357e70f,0x9357e70f | ||
1019 | data4 0xb4ee96d2,0xb4ee96d2, 0x1b9b919e,0x1b9b919e | ||
1020 | data4 0x80c0c54f,0x80c0c54f, 0x61dc20a2,0x61dc20a2 | ||
1021 | data4 0x5a774b69,0x5a774b69, 0x1c121a16,0x1c121a16 | ||
1022 | data4 0xe293ba0a,0xe293ba0a, 0xc0a02ae5,0xc0a02ae5 | ||
1023 | data4 0x3c22e043,0x3c22e043, 0x121b171d,0x121b171d | ||
1024 | data4 0x0e090d0b,0x0e090d0b, 0xf28bc7ad,0xf28bc7ad | ||
1025 | data4 0x2db6a8b9,0x2db6a8b9, 0x141ea9c8,0x141ea9c8 | ||
1026 | data4 0x57f11985,0x57f11985, 0xaf75074c,0xaf75074c | ||
1027 | data4 0xee99ddbb,0xee99ddbb, 0xa37f60fd,0xa37f60fd | ||
1028 | data4 0xf701269f,0xf701269f, 0x5c72f5bc,0x5c72f5bc | ||
1029 | data4 0x44663bc5,0x44663bc5, 0x5bfb7e34,0x5bfb7e34 | ||
1030 | data4 0x8b432976,0x8b432976, 0xcb23c6dc,0xcb23c6dc | ||
1031 | data4 0xb6edfc68,0xb6edfc68, 0xb8e4f163,0xb8e4f163 | ||
1032 | data4 0xd731dcca,0xd731dcca, 0x42638510,0x42638510 | ||
1033 | data4 0x13972240,0x13972240, 0x84c61120,0x84c61120 | ||
1034 | data4 0x854a247d,0x854a247d, 0xd2bb3df8,0xd2bb3df8 | ||
1035 | data4 0xaef93211,0xaef93211, 0xc729a16d,0xc729a16d | ||
1036 | data4 0x1d9e2f4b,0x1d9e2f4b, 0xdcb230f3,0xdcb230f3 | ||
1037 | data4 0x0d8652ec,0x0d8652ec, 0x77c1e3d0,0x77c1e3d0 | ||
1038 | data4 0x2bb3166c,0x2bb3166c, 0xa970b999,0xa970b999 | ||
1039 | data4 0x119448fa,0x119448fa, 0x47e96422,0x47e96422 | ||
1040 | data4 0xa8fc8cc4,0xa8fc8cc4, 0xa0f03f1a,0xa0f03f1a | ||
1041 | data4 0x567d2cd8,0x567d2cd8, 0x223390ef,0x223390ef | ||
1042 | data4 0x87494ec7,0x87494ec7, 0xd938d1c1,0xd938d1c1 | ||
1043 | data4 0x8ccaa2fe,0x8ccaa2fe, 0x98d40b36,0x98d40b36 | ||
1044 | data4 0xa6f581cf,0xa6f581cf, 0xa57ade28,0xa57ade28 | ||
1045 | data4 0xdab78e26,0xdab78e26, 0x3fadbfa4,0x3fadbfa4 | ||
1046 | data4 0x2c3a9de4,0x2c3a9de4, 0x5078920d,0x5078920d | ||
1047 | data4 0x6a5fcc9b,0x6a5fcc9b, 0x547e4662,0x547e4662 | ||
1048 | data4 0xf68d13c2,0xf68d13c2, 0x90d8b8e8,0x90d8b8e8 | ||
1049 | data4 0x2e39f75e,0x2e39f75e, 0x82c3aff5,0x82c3aff5 | ||
1050 | data4 0x9f5d80be,0x9f5d80be, 0x69d0937c,0x69d0937c | ||
1051 | data4 0x6fd52da9,0x6fd52da9, 0xcf2512b3,0xcf2512b3 | ||
1052 | data4 0xc8ac993b,0xc8ac993b, 0x10187da7,0x10187da7 | ||
1053 | data4 0xe89c636e,0xe89c636e, 0xdb3bbb7b,0xdb3bbb7b | ||
1054 | data4 0xcd267809,0xcd267809, 0x6e5918f4,0x6e5918f4 | ||
1055 | data4 0xec9ab701,0xec9ab701, 0x834f9aa8,0x834f9aa8 | ||
1056 | data4 0xe6956e65,0xe6956e65, 0xaaffe67e,0xaaffe67e | ||
1057 | data4 0x21bccf08,0x21bccf08, 0xef15e8e6,0xef15e8e6 | ||
1058 | data4 0xbae79bd9,0xbae79bd9, 0x4a6f36ce,0x4a6f36ce | ||
1059 | data4 0xea9f09d4,0xea9f09d4, 0x29b07cd6,0x29b07cd6 | ||
1060 | data4 0x31a4b2af,0x31a4b2af, 0x2a3f2331,0x2a3f2331 | ||
1061 | data4 0xc6a59430,0xc6a59430, 0x35a266c0,0x35a266c0 | ||
1062 | data4 0x744ebc37,0x744ebc37, 0xfc82caa6,0xfc82caa6 | ||
1063 | data4 0xe090d0b0,0xe090d0b0, 0x33a7d815,0x33a7d815 | ||
1064 | data4 0xf104984a,0xf104984a, 0x41ecdaf7,0x41ecdaf7 | ||
1065 | data4 0x7fcd500e,0x7fcd500e, 0x1791f62f,0x1791f62f | ||
1066 | data4 0x764dd68d,0x764dd68d, 0x43efb04d,0x43efb04d | ||
1067 | data4 0xccaa4d54,0xccaa4d54, 0xe49604df,0xe49604df | ||
1068 | data4 0x9ed1b5e3,0x9ed1b5e3, 0x4c6a881b,0x4c6a881b | ||
1069 | data4 0xc12c1fb8,0xc12c1fb8, 0x4665517f,0x4665517f | ||
1070 | data4 0x9d5eea04,0x9d5eea04, 0x018c355d,0x018c355d | ||
1071 | data4 0xfa877473,0xfa877473, 0xfb0b412e,0xfb0b412e | ||
1072 | data4 0xb3671d5a,0xb3671d5a, 0x92dbd252,0x92dbd252 | ||
1073 | data4 0xe9105633,0xe9105633, 0x6dd64713,0x6dd64713 | ||
1074 | data4 0x9ad7618c,0x9ad7618c, 0x37a10c7a,0x37a10c7a | ||
1075 | data4 0x59f8148e,0x59f8148e, 0xeb133c89,0xeb133c89 | ||
1076 | data4 0xcea927ee,0xcea927ee, 0xb761c935,0xb761c935 | ||
1077 | data4 0xe11ce5ed,0xe11ce5ed, 0x7a47b13c,0x7a47b13c | ||
1078 | data4 0x9cd2df59,0x9cd2df59, 0x55f2733f,0x55f2733f | ||
1079 | data4 0x1814ce79,0x1814ce79, 0x73c737bf,0x73c737bf | ||
1080 | data4 0x53f7cdea,0x53f7cdea, 0x5ffdaa5b,0x5ffdaa5b | ||
1081 | data4 0xdf3d6f14,0xdf3d6f14, 0x7844db86,0x7844db86 | ||
1082 | data4 0xcaaff381,0xcaaff381, 0xb968c43e,0xb968c43e | ||
1083 | data4 0x3824342c,0x3824342c, 0xc2a3405f,0xc2a3405f | ||
1084 | data4 0x161dc372,0x161dc372, 0xbce2250c,0xbce2250c | ||
1085 | data4 0x283c498b,0x283c498b, 0xff0d9541,0xff0d9541 | ||
1086 | data4 0x39a80171,0x39a80171, 0x080cb3de,0x080cb3de | ||
1087 | data4 0xd8b4e49c,0xd8b4e49c, 0x6456c190,0x6456c190 | ||
1088 | data4 0x7bcb8461,0x7bcb8461, 0xd532b670,0xd532b670 | ||
1089 | data4 0x486c5c74,0x486c5c74, 0xd0b85742,0xd0b85742 | ||
1090 | // Td4: | ||
1091 | data1 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38 | ||
1092 | data1 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb | ||
1093 | data1 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87 | ||
1094 | data1 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb | ||
1095 | data1 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d | ||
1096 | data1 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e | ||
1097 | data1 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2 | ||
1098 | data1 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25 | ||
1099 | data1 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16 | ||
1100 | data1 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92 | ||
1101 | data1 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda | ||
1102 | data1 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84 | ||
1103 | data1 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a | ||
1104 | data1 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06 | ||
1105 | data1 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02 | ||
1106 | data1 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b | ||
1107 | data1 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea | ||
1108 | data1 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73 | ||
1109 | data1 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85 | ||
1110 | data1 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e | ||
1111 | data1 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89 | ||
1112 | data1 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b | ||
1113 | data1 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20 | ||
1114 | data1 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4 | ||
1115 | data1 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31 | ||
1116 | data1 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f | ||
1117 | data1 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d | ||
1118 | data1 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef | ||
1119 | data1 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0 | ||
1120 | data1 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61 | ||
1121 | data1 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26 | ||
1122 | data1 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d | ||
1123 | .size AES_Td#,2048+256 // HP-UX assembler fails to ".-AES_Td#" | ||
diff --git a/src/lib/libcrypto/aes/asm/aes-x86_64.pl b/src/lib/libcrypto/aes/asm/aes-x86_64.pl new file mode 100755 index 0000000000..44e0bf8cae --- /dev/null +++ b/src/lib/libcrypto/aes/asm/aes-x86_64.pl | |||
@@ -0,0 +1,1578 @@ | |||
1 | #!/usr/bin/env perl | ||
2 | # | ||
3 | # ==================================================================== | ||
4 | # Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL | ||
5 | # project. Rights for redistribution and usage in source and binary | ||
6 | # forms are granted according to the OpenSSL license. | ||
7 | # ==================================================================== | ||
8 | # | ||
9 | # Version 1.2. | ||
10 | # | ||
11 | # aes-*-cbc benchmarks are improved by >70% [compared to gcc 3.3.2 on | ||
12 | # Opteron 240 CPU] plus all the bells-n-whistles from 32-bit version | ||
13 | # [you'll notice a lot of resemblance], such as compressed S-boxes | ||
14 | # in little-endian byte order, prefetch of these tables in CBC mode, | ||
15 | # as well as avoiding L1 cache aliasing between stack frame and key | ||
16 | # schedule and already mentioned tables, compressed Td4... | ||
17 | # | ||
18 | # Performance in number of cycles per processed byte for 128-bit key: | ||
19 | # | ||
20 | # ECB CBC encrypt | ||
21 | # AMD64 13.7 13.0(*) | ||
22 | # EM64T 20.2 18.6(*) | ||
23 | # | ||
24 | # (*) CBC benchmarks are better than ECB thanks to custom ABI used | ||
25 | # by the private block encryption function. | ||
26 | |||
27 | $verticalspin=1; # unlike 32-bit version $verticalspin performs | ||
28 | # ~15% better on both AMD and Intel cores | ||
29 | $output=shift; | ||
30 | open STDOUT,"| $^X ../perlasm/x86_64-xlate.pl $output"; | ||
31 | |||
32 | $code=".text\n"; | ||
33 | |||
34 | $s0="%eax"; | ||
35 | $s1="%ebx"; | ||
36 | $s2="%ecx"; | ||
37 | $s3="%edx"; | ||
38 | $acc0="%esi"; | ||
39 | $acc1="%edi"; | ||
40 | $acc2="%ebp"; | ||
41 | $inp="%r8"; | ||
42 | $out="%r9"; | ||
43 | $t0="%r10d"; | ||
44 | $t1="%r11d"; | ||
45 | $t2="%r12d"; | ||
46 | $rnds="%r13d"; | ||
47 | $sbox="%r14"; | ||
48 | $key="%r15"; | ||
49 | |||
50 | sub hi() { my $r=shift; $r =~ s/%[er]([a-d])x/%\1h/; $r; } | ||
51 | sub lo() { my $r=shift; $r =~ s/%[er]([a-d])x/%\1l/; | ||
52 | $r =~ s/%[er]([sd]i)/%\1l/; | ||
53 | $r =~ s/%(r[0-9]+)[d]?/%\1b/; $r; } | ||
54 | sub _data_word() | ||
55 | { my $i; | ||
56 | while(defined($i=shift)) { $code.=sprintf".long\t0x%08x,0x%08x\n",$i,$i; } | ||
57 | } | ||
58 | sub data_word() | ||
59 | { my $i; | ||
60 | my $last=pop(@_); | ||
61 | $code.=".long\t"; | ||
62 | while(defined($i=shift)) { $code.=sprintf"0x%08x,",$i; } | ||
63 | $code.=sprintf"0x%08x\n",$last; | ||
64 | } | ||
65 | |||
66 | sub data_byte() | ||
67 | { my $i; | ||
68 | my $last=pop(@_); | ||
69 | $code.=".byte\t"; | ||
70 | while(defined($i=shift)) { $code.=sprintf"0x%02x,",$i&0xff; } | ||
71 | $code.=sprintf"0x%02x\n",$last&0xff; | ||
72 | } | ||
73 | |||
74 | sub encvert() | ||
75 | { my $t3="%r8d"; # zaps $inp! | ||
76 | |||
77 | $code.=<<___; | ||
78 | # favor 3-way issue Opteron pipeline... | ||
79 | movzb `&lo("$s0")`,$acc0 | ||
80 | movzb `&lo("$s1")`,$acc1 | ||
81 | movzb `&lo("$s2")`,$acc2 | ||
82 | mov 0($sbox,$acc0,8),$t0 | ||
83 | mov 0($sbox,$acc1,8),$t1 | ||
84 | mov 0($sbox,$acc2,8),$t2 | ||
85 | |||
86 | movzb `&hi("$s1")`,$acc0 | ||
87 | movzb `&hi("$s2")`,$acc1 | ||
88 | movzb `&lo("$s3")`,$acc2 | ||
89 | xor 3($sbox,$acc0,8),$t0 | ||
90 | xor 3($sbox,$acc1,8),$t1 | ||
91 | mov 0($sbox,$acc2,8),$t3 | ||
92 | |||
93 | movzb `&hi("$s3")`,$acc0 | ||
94 | shr \$16,$s2 | ||
95 | movzb `&hi("$s0")`,$acc2 | ||
96 | xor 3($sbox,$acc0,8),$t2 | ||
97 | shr \$16,$s3 | ||
98 | xor 3($sbox,$acc2,8),$t3 | ||
99 | |||
100 | shr \$16,$s1 | ||
101 | lea 16($key),$key | ||
102 | shr \$16,$s0 | ||
103 | |||
104 | movzb `&lo("$s2")`,$acc0 | ||
105 | movzb `&lo("$s3")`,$acc1 | ||
106 | movzb `&lo("$s0")`,$acc2 | ||
107 | xor 2($sbox,$acc0,8),$t0 | ||
108 | xor 2($sbox,$acc1,8),$t1 | ||
109 | xor 2($sbox,$acc2,8),$t2 | ||
110 | |||
111 | movzb `&hi("$s3")`,$acc0 | ||
112 | movzb `&hi("$s0")`,$acc1 | ||
113 | movzb `&lo("$s1")`,$acc2 | ||
114 | xor 1($sbox,$acc0,8),$t0 | ||
115 | xor 1($sbox,$acc1,8),$t1 | ||
116 | xor 2($sbox,$acc2,8),$t3 | ||
117 | |||
118 | mov 12($key),$s3 | ||
119 | movzb `&hi("$s1")`,$acc1 | ||
120 | movzb `&hi("$s2")`,$acc2 | ||
121 | mov 0($key),$s0 | ||
122 | xor 1($sbox,$acc1,8),$t2 | ||
123 | xor 1($sbox,$acc2,8),$t3 | ||
124 | |||
125 | mov 4($key),$s1 | ||
126 | mov 8($key),$s2 | ||
127 | xor $t0,$s0 | ||
128 | xor $t1,$s1 | ||
129 | xor $t2,$s2 | ||
130 | xor $t3,$s3 | ||
131 | ___ | ||
132 | } | ||
133 | |||
134 | sub enclastvert() | ||
135 | { my $t3="%r8d"; # zaps $inp! | ||
136 | |||
137 | $code.=<<___; | ||
138 | movzb `&lo("$s0")`,$acc0 | ||
139 | movzb `&lo("$s1")`,$acc1 | ||
140 | movzb `&lo("$s2")`,$acc2 | ||
141 | mov 2($sbox,$acc0,8),$t0 | ||
142 | mov 2($sbox,$acc1,8),$t1 | ||
143 | mov 2($sbox,$acc2,8),$t2 | ||
144 | |||
145 | and \$0x000000ff,$t0 | ||
146 | and \$0x000000ff,$t1 | ||
147 | and \$0x000000ff,$t2 | ||
148 | |||
149 | movzb `&lo("$s3")`,$acc0 | ||
150 | movzb `&hi("$s1")`,$acc1 | ||
151 | movzb `&hi("$s2")`,$acc2 | ||
152 | mov 2($sbox,$acc0,8),$t3 | ||
153 | mov 0($sbox,$acc1,8),$acc1 #$t0 | ||
154 | mov 0($sbox,$acc2,8),$acc2 #$t1 | ||
155 | |||
156 | and \$0x000000ff,$t3 | ||
157 | and \$0x0000ff00,$acc1 | ||
158 | and \$0x0000ff00,$acc2 | ||
159 | |||
160 | xor $acc1,$t0 | ||
161 | xor $acc2,$t1 | ||
162 | shr \$16,$s2 | ||
163 | |||
164 | movzb `&hi("$s3")`,$acc0 | ||
165 | movzb `&hi("$s0")`,$acc1 | ||
166 | shr \$16,$s3 | ||
167 | mov 0($sbox,$acc0,8),$acc0 #$t2 | ||
168 | mov 0($sbox,$acc1,8),$acc1 #$t3 | ||
169 | |||
170 | and \$0x0000ff00,$acc0 | ||
171 | and \$0x0000ff00,$acc1 | ||
172 | shr \$16,$s1 | ||
173 | xor $acc0,$t2 | ||
174 | xor $acc1,$t3 | ||
175 | shr \$16,$s0 | ||
176 | |||
177 | movzb `&lo("$s2")`,$acc0 | ||
178 | movzb `&lo("$s3")`,$acc1 | ||
179 | movzb `&lo("$s0")`,$acc2 | ||
180 | mov 0($sbox,$acc0,8),$acc0 #$t0 | ||
181 | mov 0($sbox,$acc1,8),$acc1 #$t1 | ||
182 | mov 0($sbox,$acc2,8),$acc2 #$t2 | ||
183 | |||
184 | and \$0x00ff0000,$acc0 | ||
185 | and \$0x00ff0000,$acc1 | ||
186 | and \$0x00ff0000,$acc2 | ||
187 | |||
188 | xor $acc0,$t0 | ||
189 | xor $acc1,$t1 | ||
190 | xor $acc2,$t2 | ||
191 | |||
192 | movzb `&lo("$s1")`,$acc0 | ||
193 | movzb `&hi("$s3")`,$acc1 | ||
194 | movzb `&hi("$s0")`,$acc2 | ||
195 | mov 0($sbox,$acc0,8),$acc0 #$t3 | ||
196 | mov 2($sbox,$acc1,8),$acc1 #$t0 | ||
197 | mov 2($sbox,$acc2,8),$acc2 #$t1 | ||
198 | |||
199 | and \$0x00ff0000,$acc0 | ||
200 | and \$0xff000000,$acc1 | ||
201 | and \$0xff000000,$acc2 | ||
202 | |||
203 | xor $acc0,$t3 | ||
204 | xor $acc1,$t0 | ||
205 | xor $acc2,$t1 | ||
206 | |||
207 | movzb `&hi("$s1")`,$acc0 | ||
208 | movzb `&hi("$s2")`,$acc1 | ||
209 | mov 16+12($key),$s3 | ||
210 | mov 2($sbox,$acc0,8),$acc0 #$t2 | ||
211 | mov 2($sbox,$acc1,8),$acc1 #$t3 | ||
212 | mov 16+0($key),$s0 | ||
213 | |||
214 | and \$0xff000000,$acc0 | ||
215 | and \$0xff000000,$acc1 | ||
216 | |||
217 | xor $acc0,$t2 | ||
218 | xor $acc1,$t3 | ||
219 | |||
220 | mov 16+4($key),$s1 | ||
221 | mov 16+8($key),$s2 | ||
222 | xor $t0,$s0 | ||
223 | xor $t1,$s1 | ||
224 | xor $t2,$s2 | ||
225 | xor $t3,$s3 | ||
226 | ___ | ||
227 | } | ||
228 | |||
229 | sub encstep() | ||
230 | { my ($i,@s) = @_; | ||
231 | my $tmp0=$acc0; | ||
232 | my $tmp1=$acc1; | ||
233 | my $tmp2=$acc2; | ||
234 | my $out=($t0,$t1,$t2,$s[0])[$i]; | ||
235 | |||
236 | if ($i==3) { | ||
237 | $tmp0=$s[1]; | ||
238 | $tmp1=$s[2]; | ||
239 | $tmp2=$s[3]; | ||
240 | } | ||
241 | $code.=" movzb ".&lo($s[0]).",$out\n"; | ||
242 | $code.=" mov $s[2],$tmp1\n" if ($i!=3); | ||
243 | $code.=" lea 16($key),$key\n" if ($i==0); | ||
244 | |||
245 | $code.=" movzb ".&hi($s[1]).",$tmp0\n"; | ||
246 | $code.=" mov 0($sbox,$out,8),$out\n"; | ||
247 | |||
248 | $code.=" shr \$16,$tmp1\n"; | ||
249 | $code.=" mov $s[3],$tmp2\n" if ($i!=3); | ||
250 | $code.=" xor 3($sbox,$tmp0,8),$out\n"; | ||
251 | |||
252 | $code.=" movzb ".&lo($tmp1).",$tmp1\n"; | ||
253 | $code.=" shr \$24,$tmp2\n"; | ||
254 | $code.=" xor 4*$i($key),$out\n"; | ||
255 | |||
256 | $code.=" xor 2($sbox,$tmp1,8),$out\n"; | ||
257 | $code.=" xor 1($sbox,$tmp2,8),$out\n"; | ||
258 | |||
259 | $code.=" mov $t0,$s[1]\n" if ($i==3); | ||
260 | $code.=" mov $t1,$s[2]\n" if ($i==3); | ||
261 | $code.=" mov $t2,$s[3]\n" if ($i==3); | ||
262 | $code.="\n"; | ||
263 | } | ||
264 | |||
265 | sub enclast() | ||
266 | { my ($i,@s)=@_; | ||
267 | my $tmp0=$acc0; | ||
268 | my $tmp1=$acc1; | ||
269 | my $tmp2=$acc2; | ||
270 | my $out=($t0,$t1,$t2,$s[0])[$i]; | ||
271 | |||
272 | if ($i==3) { | ||
273 | $tmp0=$s[1]; | ||
274 | $tmp1=$s[2]; | ||
275 | $tmp2=$s[3]; | ||
276 | } | ||
277 | $code.=" movzb ".&lo($s[0]).",$out\n"; | ||
278 | $code.=" mov $s[2],$tmp1\n" if ($i!=3); | ||
279 | |||
280 | $code.=" mov 2($sbox,$out,8),$out\n"; | ||
281 | $code.=" shr \$16,$tmp1\n"; | ||
282 | $code.=" mov $s[3],$tmp2\n" if ($i!=3); | ||
283 | |||
284 | $code.=" and \$0x000000ff,$out\n"; | ||
285 | $code.=" movzb ".&hi($s[1]).",$tmp0\n"; | ||
286 | $code.=" movzb ".&lo($tmp1).",$tmp1\n"; | ||
287 | $code.=" shr \$24,$tmp2\n"; | ||
288 | |||
289 | $code.=" mov 0($sbox,$tmp0,8),$tmp0\n"; | ||
290 | $code.=" mov 0($sbox,$tmp1,8),$tmp1\n"; | ||
291 | $code.=" mov 2($sbox,$tmp2,8),$tmp2\n"; | ||
292 | |||
293 | $code.=" and \$0x0000ff00,$tmp0\n"; | ||
294 | $code.=" and \$0x00ff0000,$tmp1\n"; | ||
295 | $code.=" and \$0xff000000,$tmp2\n"; | ||
296 | |||
297 | $code.=" xor $tmp0,$out\n"; | ||
298 | $code.=" mov $t0,$s[1]\n" if ($i==3); | ||
299 | $code.=" xor $tmp1,$out\n"; | ||
300 | $code.=" mov $t1,$s[2]\n" if ($i==3); | ||
301 | $code.=" xor $tmp2,$out\n"; | ||
302 | $code.=" mov $t2,$s[3]\n" if ($i==3); | ||
303 | $code.="\n"; | ||
304 | } | ||
305 | |||
306 | $code.=<<___; | ||
307 | .type _x86_64_AES_encrypt,\@abi-omnipotent | ||
308 | .align 16 | ||
309 | _x86_64_AES_encrypt: | ||
310 | xor 0($key),$s0 # xor with key | ||
311 | xor 4($key),$s1 | ||
312 | xor 8($key),$s2 | ||
313 | xor 12($key),$s3 | ||
314 | |||
315 | mov 240($key),$rnds # load key->rounds | ||
316 | sub \$1,$rnds | ||
317 | jmp .Lenc_loop | ||
318 | .align 16 | ||
319 | .Lenc_loop: | ||
320 | ___ | ||
321 | if ($verticalspin) { &encvert(); } | ||
322 | else { &encstep(0,$s0,$s1,$s2,$s3); | ||
323 | &encstep(1,$s1,$s2,$s3,$s0); | ||
324 | &encstep(2,$s2,$s3,$s0,$s1); | ||
325 | &encstep(3,$s3,$s0,$s1,$s2); | ||
326 | } | ||
327 | $code.=<<___; | ||
328 | sub \$1,$rnds | ||
329 | jnz .Lenc_loop | ||
330 | ___ | ||
331 | if ($verticalspin) { &enclastvert(); } | ||
332 | else { &enclast(0,$s0,$s1,$s2,$s3); | ||
333 | &enclast(1,$s1,$s2,$s3,$s0); | ||
334 | &enclast(2,$s2,$s3,$s0,$s1); | ||
335 | &enclast(3,$s3,$s0,$s1,$s2); | ||
336 | $code.=<<___; | ||
337 | xor 16+0($key),$s0 # xor with key | ||
338 | xor 16+4($key),$s1 | ||
339 | xor 16+8($key),$s2 | ||
340 | xor 16+12($key),$s3 | ||
341 | ___ | ||
342 | } | ||
343 | $code.=<<___; | ||
344 | .byte 0xf3,0xc3 # rep ret | ||
345 | .size _x86_64_AES_encrypt,.-_x86_64_AES_encrypt | ||
346 | ___ | ||
347 | |||
348 | # void AES_encrypt (const void *inp,void *out,const AES_KEY *key); | ||
349 | $code.=<<___; | ||
350 | .globl AES_encrypt | ||
351 | .type AES_encrypt,\@function,3 | ||
352 | .align 16 | ||
353 | AES_encrypt: | ||
354 | push %rbx | ||
355 | push %rbp | ||
356 | push %r12 | ||
357 | push %r13 | ||
358 | push %r14 | ||
359 | push %r15 | ||
360 | |||
361 | mov %rdx,$key | ||
362 | mov %rdi,$inp | ||
363 | mov %rsi,$out | ||
364 | |||
365 | .picmeup $sbox | ||
366 | lea AES_Te-.($sbox),$sbox | ||
367 | |||
368 | mov 0($inp),$s0 | ||
369 | mov 4($inp),$s1 | ||
370 | mov 8($inp),$s2 | ||
371 | mov 12($inp),$s3 | ||
372 | |||
373 | call _x86_64_AES_encrypt | ||
374 | |||
375 | mov $s0,0($out) | ||
376 | mov $s1,4($out) | ||
377 | mov $s2,8($out) | ||
378 | mov $s3,12($out) | ||
379 | |||
380 | pop %r15 | ||
381 | pop %r14 | ||
382 | pop %r13 | ||
383 | pop %r12 | ||
384 | pop %rbp | ||
385 | pop %rbx | ||
386 | ret | ||
387 | .size AES_encrypt,.-AES_encrypt | ||
388 | ___ | ||
389 | |||
390 | #------------------------------------------------------------------# | ||
391 | |||
392 | sub decvert() | ||
393 | { my $t3="%r8d"; # zaps $inp! | ||
394 | |||
395 | $code.=<<___; | ||
396 | # favor 3-way issue Opteron pipeline... | ||
397 | movzb `&lo("$s0")`,$acc0 | ||
398 | movzb `&lo("$s1")`,$acc1 | ||
399 | movzb `&lo("$s2")`,$acc2 | ||
400 | mov 0($sbox,$acc0,8),$t0 | ||
401 | mov 0($sbox,$acc1,8),$t1 | ||
402 | mov 0($sbox,$acc2,8),$t2 | ||
403 | |||
404 | movzb `&hi("$s3")`,$acc0 | ||
405 | movzb `&hi("$s0")`,$acc1 | ||
406 | movzb `&lo("$s3")`,$acc2 | ||
407 | xor 3($sbox,$acc0,8),$t0 | ||
408 | xor 3($sbox,$acc1,8),$t1 | ||
409 | mov 0($sbox,$acc2,8),$t3 | ||
410 | |||
411 | movzb `&hi("$s1")`,$acc0 | ||
412 | shr \$16,$s0 | ||
413 | movzb `&hi("$s2")`,$acc2 | ||
414 | xor 3($sbox,$acc0,8),$t2 | ||
415 | shr \$16,$s3 | ||
416 | xor 3($sbox,$acc2,8),$t3 | ||
417 | |||
418 | shr \$16,$s1 | ||
419 | lea 16($key),$key | ||
420 | shr \$16,$s2 | ||
421 | |||
422 | movzb `&lo("$s2")`,$acc0 | ||
423 | movzb `&lo("$s3")`,$acc1 | ||
424 | movzb `&lo("$s0")`,$acc2 | ||
425 | xor 2($sbox,$acc0,8),$t0 | ||
426 | xor 2($sbox,$acc1,8),$t1 | ||
427 | xor 2($sbox,$acc2,8),$t2 | ||
428 | |||
429 | movzb `&hi("$s1")`,$acc0 | ||
430 | movzb `&hi("$s2")`,$acc1 | ||
431 | movzb `&lo("$s1")`,$acc2 | ||
432 | xor 1($sbox,$acc0,8),$t0 | ||
433 | xor 1($sbox,$acc1,8),$t1 | ||
434 | xor 2($sbox,$acc2,8),$t3 | ||
435 | |||
436 | movzb `&hi("$s3")`,$acc0 | ||
437 | mov 12($key),$s3 | ||
438 | movzb `&hi("$s0")`,$acc2 | ||
439 | xor 1($sbox,$acc0,8),$t2 | ||
440 | mov 0($key),$s0 | ||
441 | xor 1($sbox,$acc2,8),$t3 | ||
442 | |||
443 | xor $t0,$s0 | ||
444 | mov 4($key),$s1 | ||
445 | mov 8($key),$s2 | ||
446 | xor $t2,$s2 | ||
447 | xor $t1,$s1 | ||
448 | xor $t3,$s3 | ||
449 | ___ | ||
450 | } | ||
451 | |||
452 | sub declastvert() | ||
453 | { my $t3="%r8d"; # zaps $inp! | ||
454 | |||
455 | $code.=<<___; | ||
456 | movzb `&lo("$s0")`,$acc0 | ||
457 | movzb `&lo("$s1")`,$acc1 | ||
458 | movzb `&lo("$s2")`,$acc2 | ||
459 | movzb 2048($sbox,$acc0,1),$t0 | ||
460 | movzb 2048($sbox,$acc1,1),$t1 | ||
461 | movzb 2048($sbox,$acc2,1),$t2 | ||
462 | |||
463 | movzb `&lo("$s3")`,$acc0 | ||
464 | movzb `&hi("$s3")`,$acc1 | ||
465 | movzb `&hi("$s0")`,$acc2 | ||
466 | movzb 2048($sbox,$acc0,1),$t3 | ||
467 | movzb 2048($sbox,$acc1,1),$acc1 #$t0 | ||
468 | movzb 2048($sbox,$acc2,1),$acc2 #$t1 | ||
469 | |||
470 | shl \$8,$acc1 | ||
471 | shl \$8,$acc2 | ||
472 | |||
473 | xor $acc1,$t0 | ||
474 | xor $acc2,$t1 | ||
475 | shr \$16,$s3 | ||
476 | |||
477 | movzb `&hi("$s1")`,$acc0 | ||
478 | movzb `&hi("$s2")`,$acc1 | ||
479 | shr \$16,$s0 | ||
480 | movzb 2048($sbox,$acc0,1),$acc0 #$t2 | ||
481 | movzb 2048($sbox,$acc1,1),$acc1 #$t3 | ||
482 | |||
483 | shl \$8,$acc0 | ||
484 | shl \$8,$acc1 | ||
485 | shr \$16,$s1 | ||
486 | xor $acc0,$t2 | ||
487 | xor $acc1,$t3 | ||
488 | shr \$16,$s2 | ||
489 | |||
490 | movzb `&lo("$s2")`,$acc0 | ||
491 | movzb `&lo("$s3")`,$acc1 | ||
492 | movzb `&lo("$s0")`,$acc2 | ||
493 | movzb 2048($sbox,$acc0,1),$acc0 #$t0 | ||
494 | movzb 2048($sbox,$acc1,1),$acc1 #$t1 | ||
495 | movzb 2048($sbox,$acc2,1),$acc2 #$t2 | ||
496 | |||
497 | shl \$16,$acc0 | ||
498 | shl \$16,$acc1 | ||
499 | shl \$16,$acc2 | ||
500 | |||
501 | xor $acc0,$t0 | ||
502 | xor $acc1,$t1 | ||
503 | xor $acc2,$t2 | ||
504 | |||
505 | movzb `&lo("$s1")`,$acc0 | ||
506 | movzb `&hi("$s1")`,$acc1 | ||
507 | movzb `&hi("$s2")`,$acc2 | ||
508 | movzb 2048($sbox,$acc0,1),$acc0 #$t3 | ||
509 | movzb 2048($sbox,$acc1,1),$acc1 #$t0 | ||
510 | movzb 2048($sbox,$acc2,1),$acc2 #$t1 | ||
511 | |||
512 | shl \$16,$acc0 | ||
513 | shl \$24,$acc1 | ||
514 | shl \$24,$acc2 | ||
515 | |||
516 | xor $acc0,$t3 | ||
517 | xor $acc1,$t0 | ||
518 | xor $acc2,$t1 | ||
519 | |||
520 | movzb `&hi("$s3")`,$acc0 | ||
521 | movzb `&hi("$s0")`,$acc1 | ||
522 | mov 16+12($key),$s3 | ||
523 | movzb 2048($sbox,$acc0,1),$acc0 #$t2 | ||
524 | movzb 2048($sbox,$acc1,1),$acc1 #$t3 | ||
525 | mov 16+0($key),$s0 | ||
526 | |||
527 | shl \$24,$acc0 | ||
528 | shl \$24,$acc1 | ||
529 | |||
530 | xor $acc0,$t2 | ||
531 | xor $acc1,$t3 | ||
532 | |||
533 | mov 16+4($key),$s1 | ||
534 | mov 16+8($key),$s2 | ||
535 | xor $t0,$s0 | ||
536 | xor $t1,$s1 | ||
537 | xor $t2,$s2 | ||
538 | xor $t3,$s3 | ||
539 | ___ | ||
540 | } | ||
541 | |||
542 | sub decstep() | ||
543 | { my ($i,@s) = @_; | ||
544 | my $tmp0=$acc0; | ||
545 | my $tmp1=$acc1; | ||
546 | my $tmp2=$acc2; | ||
547 | my $out=($t0,$t1,$t2,$s[0])[$i]; | ||
548 | |||
549 | $code.=" mov $s[0],$out\n" if ($i!=3); | ||
550 | $tmp1=$s[2] if ($i==3); | ||
551 | $code.=" mov $s[2],$tmp1\n" if ($i!=3); | ||
552 | $code.=" and \$0xFF,$out\n"; | ||
553 | |||
554 | $code.=" mov 0($sbox,$out,8),$out\n"; | ||
555 | $code.=" shr \$16,$tmp1\n"; | ||
556 | $tmp2=$s[3] if ($i==3); | ||
557 | $code.=" mov $s[3],$tmp2\n" if ($i!=3); | ||
558 | |||
559 | $tmp0=$s[1] if ($i==3); | ||
560 | $code.=" movzb ".&hi($s[1]).",$tmp0\n"; | ||
561 | $code.=" and \$0xFF,$tmp1\n"; | ||
562 | $code.=" shr \$24,$tmp2\n"; | ||
563 | |||
564 | $code.=" xor 3($sbox,$tmp0,8),$out\n"; | ||
565 | $code.=" xor 2($sbox,$tmp1,8),$out\n"; | ||
566 | $code.=" xor 1($sbox,$tmp2,8),$out\n"; | ||
567 | |||
568 | $code.=" mov $t2,$s[1]\n" if ($i==3); | ||
569 | $code.=" mov $t1,$s[2]\n" if ($i==3); | ||
570 | $code.=" mov $t0,$s[3]\n" if ($i==3); | ||
571 | $code.="\n"; | ||
572 | } | ||
573 | |||
574 | sub declast() | ||
575 | { my ($i,@s)=@_; | ||
576 | my $tmp0=$acc0; | ||
577 | my $tmp1=$acc1; | ||
578 | my $tmp2=$acc2; | ||
579 | my $out=($t0,$t1,$t2,$s[0])[$i]; | ||
580 | |||
581 | $code.=" mov $s[0],$out\n" if ($i!=3); | ||
582 | $tmp1=$s[2] if ($i==3); | ||
583 | $code.=" mov $s[2],$tmp1\n" if ($i!=3); | ||
584 | $code.=" and \$0xFF,$out\n"; | ||
585 | |||
586 | $code.=" movzb 2048($sbox,$out,1),$out\n"; | ||
587 | $code.=" shr \$16,$tmp1\n"; | ||
588 | $tmp2=$s[3] if ($i==3); | ||
589 | $code.=" mov $s[3],$tmp2\n" if ($i!=3); | ||
590 | |||
591 | $tmp0=$s[1] if ($i==3); | ||
592 | $code.=" movzb ".&hi($s[1]).",$tmp0\n"; | ||
593 | $code.=" and \$0xFF,$tmp1\n"; | ||
594 | $code.=" shr \$24,$tmp2\n"; | ||
595 | |||
596 | $code.=" movzb 2048($sbox,$tmp0,1),$tmp0\n"; | ||
597 | $code.=" movzb 2048($sbox,$tmp1,1),$tmp1\n"; | ||
598 | $code.=" movzb 2048($sbox,$tmp2,1),$tmp2\n"; | ||
599 | |||
600 | $code.=" shl \$8,$tmp0\n"; | ||
601 | $code.=" shl \$16,$tmp1\n"; | ||
602 | $code.=" shl \$24,$tmp2\n"; | ||
603 | |||
604 | $code.=" xor $tmp0,$out\n"; | ||
605 | $code.=" mov $t2,$s[1]\n" if ($i==3); | ||
606 | $code.=" xor $tmp1,$out\n"; | ||
607 | $code.=" mov $t1,$s[2]\n" if ($i==3); | ||
608 | $code.=" xor $tmp2,$out\n"; | ||
609 | $code.=" mov $t0,$s[3]\n" if ($i==3); | ||
610 | $code.="\n"; | ||
611 | } | ||
612 | |||
613 | $code.=<<___; | ||
614 | .type _x86_64_AES_decrypt,\@abi-omnipotent | ||
615 | .align 16 | ||
616 | _x86_64_AES_decrypt: | ||
617 | xor 0($key),$s0 # xor with key | ||
618 | xor 4($key),$s1 | ||
619 | xor 8($key),$s2 | ||
620 | xor 12($key),$s3 | ||
621 | |||
622 | mov 240($key),$rnds # load key->rounds | ||
623 | sub \$1,$rnds | ||
624 | jmp .Ldec_loop | ||
625 | .align 16 | ||
626 | .Ldec_loop: | ||
627 | ___ | ||
628 | if ($verticalspin) { &decvert(); } | ||
629 | else { &decstep(0,$s0,$s3,$s2,$s1); | ||
630 | &decstep(1,$s1,$s0,$s3,$s2); | ||
631 | &decstep(2,$s2,$s1,$s0,$s3); | ||
632 | &decstep(3,$s3,$s2,$s1,$s0); | ||
633 | $code.=<<___; | ||
634 | lea 16($key),$key | ||
635 | xor 0($key),$s0 # xor with key | ||
636 | xor 4($key),$s1 | ||
637 | xor 8($key),$s2 | ||
638 | xor 12($key),$s3 | ||
639 | ___ | ||
640 | } | ||
641 | $code.=<<___; | ||
642 | sub \$1,$rnds | ||
643 | jnz .Ldec_loop | ||
644 | ___ | ||
645 | if ($verticalspin) { &declastvert(); } | ||
646 | else { &declast(0,$s0,$s3,$s2,$s1); | ||
647 | &declast(1,$s1,$s0,$s3,$s2); | ||
648 | &declast(2,$s2,$s1,$s0,$s3); | ||
649 | &declast(3,$s3,$s2,$s1,$s0); | ||
650 | $code.=<<___; | ||
651 | xor 16+0($key),$s0 # xor with key | ||
652 | xor 16+4($key),$s1 | ||
653 | xor 16+8($key),$s2 | ||
654 | xor 16+12($key),$s3 | ||
655 | ___ | ||
656 | } | ||
657 | $code.=<<___; | ||
658 | .byte 0xf3,0xc3 # rep ret | ||
659 | .size _x86_64_AES_decrypt,.-_x86_64_AES_decrypt | ||
660 | ___ | ||
661 | |||
662 | # void AES_decrypt (const void *inp,void *out,const AES_KEY *key); | ||
663 | $code.=<<___; | ||
664 | .globl AES_decrypt | ||
665 | .type AES_decrypt,\@function,3 | ||
666 | .align 16 | ||
667 | AES_decrypt: | ||
668 | push %rbx | ||
669 | push %rbp | ||
670 | push %r12 | ||
671 | push %r13 | ||
672 | push %r14 | ||
673 | push %r15 | ||
674 | |||
675 | mov %rdx,$key | ||
676 | mov %rdi,$inp | ||
677 | mov %rsi,$out | ||
678 | |||
679 | .picmeup $sbox | ||
680 | lea AES_Td-.($sbox),$sbox | ||
681 | |||
682 | # prefetch Td4 | ||
683 | lea 2048+128($sbox),$sbox; | ||
684 | mov 0-128($sbox),$s0 | ||
685 | mov 32-128($sbox),$s1 | ||
686 | mov 64-128($sbox),$s2 | ||
687 | mov 96-128($sbox),$s3 | ||
688 | mov 128-128($sbox),$s0 | ||
689 | mov 160-128($sbox),$s1 | ||
690 | mov 192-128($sbox),$s2 | ||
691 | mov 224-128($sbox),$s3 | ||
692 | lea -2048-128($sbox),$sbox; | ||
693 | |||
694 | mov 0($inp),$s0 | ||
695 | mov 4($inp),$s1 | ||
696 | mov 8($inp),$s2 | ||
697 | mov 12($inp),$s3 | ||
698 | |||
699 | call _x86_64_AES_decrypt | ||
700 | |||
701 | mov $s0,0($out) | ||
702 | mov $s1,4($out) | ||
703 | mov $s2,8($out) | ||
704 | mov $s3,12($out) | ||
705 | |||
706 | pop %r15 | ||
707 | pop %r14 | ||
708 | pop %r13 | ||
709 | pop %r12 | ||
710 | pop %rbp | ||
711 | pop %rbx | ||
712 | ret | ||
713 | .size AES_decrypt,.-AES_decrypt | ||
714 | ___ | ||
715 | #------------------------------------------------------------------# | ||
716 | |||
717 | sub enckey() | ||
718 | { | ||
719 | $code.=<<___; | ||
720 | movz %dl,%esi # rk[i]>>0 | ||
721 | mov 2(%rbp,%rsi,8),%ebx | ||
722 | movz %dh,%esi # rk[i]>>8 | ||
723 | and \$0xFF000000,%ebx | ||
724 | xor %ebx,%eax | ||
725 | |||
726 | mov 2(%rbp,%rsi,8),%ebx | ||
727 | shr \$16,%edx | ||
728 | and \$0x000000FF,%ebx | ||
729 | movz %dl,%esi # rk[i]>>16 | ||
730 | xor %ebx,%eax | ||
731 | |||
732 | mov 0(%rbp,%rsi,8),%ebx | ||
733 | movz %dh,%esi # rk[i]>>24 | ||
734 | and \$0x0000FF00,%ebx | ||
735 | xor %ebx,%eax | ||
736 | |||
737 | mov 0(%rbp,%rsi,8),%ebx | ||
738 | and \$0x00FF0000,%ebx | ||
739 | xor %ebx,%eax | ||
740 | |||
741 | xor 2048(%rbp,%rcx,4),%eax # rcon | ||
742 | ___ | ||
743 | } | ||
744 | |||
745 | # int AES_set_encrypt_key(const unsigned char *userKey, const int bits, | ||
746 | # AES_KEY *key) | ||
747 | $code.=<<___; | ||
748 | .globl AES_set_encrypt_key | ||
749 | .type AES_set_encrypt_key,\@function,3 | ||
750 | .align 16 | ||
751 | AES_set_encrypt_key: | ||
752 | push %rbx | ||
753 | push %rbp | ||
754 | |||
755 | mov %esi,%ecx # %ecx=bits | ||
756 | mov %rdi,%rsi # %rsi=userKey | ||
757 | mov %rdx,%rdi # %rdi=key | ||
758 | |||
759 | test \$-1,%rsi | ||
760 | jz .Lbadpointer | ||
761 | test \$-1,%rdi | ||
762 | jz .Lbadpointer | ||
763 | |||
764 | .picmeup %rbp | ||
765 | lea AES_Te-.(%rbp),%rbp | ||
766 | |||
767 | cmp \$128,%ecx | ||
768 | je .L10rounds | ||
769 | cmp \$192,%ecx | ||
770 | je .L12rounds | ||
771 | cmp \$256,%ecx | ||
772 | je .L14rounds | ||
773 | mov \$-2,%rax # invalid number of bits | ||
774 | jmp .Lexit | ||
775 | |||
776 | .L10rounds: | ||
777 | mov 0(%rsi),%eax # copy first 4 dwords | ||
778 | mov 4(%rsi),%ebx | ||
779 | mov 8(%rsi),%ecx | ||
780 | mov 12(%rsi),%edx | ||
781 | mov %eax,0(%rdi) | ||
782 | mov %ebx,4(%rdi) | ||
783 | mov %ecx,8(%rdi) | ||
784 | mov %edx,12(%rdi) | ||
785 | |||
786 | xor %ecx,%ecx | ||
787 | jmp .L10shortcut | ||
788 | .align 4 | ||
789 | .L10loop: | ||
790 | mov 0(%rdi),%eax # rk[0] | ||
791 | mov 12(%rdi),%edx # rk[3] | ||
792 | .L10shortcut: | ||
793 | ___ | ||
794 | &enckey (); | ||
795 | $code.=<<___; | ||
796 | mov %eax,16(%rdi) # rk[4] | ||
797 | xor 4(%rdi),%eax | ||
798 | mov %eax,20(%rdi) # rk[5] | ||
799 | xor 8(%rdi),%eax | ||
800 | mov %eax,24(%rdi) # rk[6] | ||
801 | xor 12(%rdi),%eax | ||
802 | mov %eax,28(%rdi) # rk[7] | ||
803 | add \$1,%ecx | ||
804 | lea 16(%rdi),%rdi | ||
805 | cmp \$10,%ecx | ||
806 | jl .L10loop | ||
807 | |||
808 | movl \$10,80(%rdi) # setup number of rounds | ||
809 | xor %rax,%rax | ||
810 | jmp .Lexit | ||
811 | |||
812 | .L12rounds: | ||
813 | mov 0(%rsi),%eax # copy first 6 dwords | ||
814 | mov 4(%rsi),%ebx | ||
815 | mov 8(%rsi),%ecx | ||
816 | mov 12(%rsi),%edx | ||
817 | mov %eax,0(%rdi) | ||
818 | mov %ebx,4(%rdi) | ||
819 | mov %ecx,8(%rdi) | ||
820 | mov %edx,12(%rdi) | ||
821 | mov 16(%rsi),%ecx | ||
822 | mov 20(%rsi),%edx | ||
823 | mov %ecx,16(%rdi) | ||
824 | mov %edx,20(%rdi) | ||
825 | |||
826 | xor %ecx,%ecx | ||
827 | jmp .L12shortcut | ||
828 | .align 4 | ||
829 | .L12loop: | ||
830 | mov 0(%rdi),%eax # rk[0] | ||
831 | mov 20(%rdi),%edx # rk[5] | ||
832 | .L12shortcut: | ||
833 | ___ | ||
834 | &enckey (); | ||
835 | $code.=<<___; | ||
836 | mov %eax,24(%rdi) # rk[6] | ||
837 | xor 4(%rdi),%eax | ||
838 | mov %eax,28(%rdi) # rk[7] | ||
839 | xor 8(%rdi),%eax | ||
840 | mov %eax,32(%rdi) # rk[8] | ||
841 | xor 12(%rdi),%eax | ||
842 | mov %eax,36(%rdi) # rk[9] | ||
843 | |||
844 | cmp \$7,%ecx | ||
845 | je .L12break | ||
846 | add \$1,%ecx | ||
847 | |||
848 | xor 16(%rdi),%eax | ||
849 | mov %eax,40(%rdi) # rk[10] | ||
850 | xor 20(%rdi),%eax | ||
851 | mov %eax,44(%rdi) # rk[11] | ||
852 | |||
853 | lea 24(%rdi),%rdi | ||
854 | jmp .L12loop | ||
855 | .L12break: | ||
856 | movl \$12,72(%rdi) # setup number of rounds | ||
857 | xor %rax,%rax | ||
858 | jmp .Lexit | ||
859 | |||
860 | .L14rounds: | ||
861 | mov 0(%rsi),%eax # copy first 8 dwords | ||
862 | mov 4(%rsi),%ebx | ||
863 | mov 8(%rsi),%ecx | ||
864 | mov 12(%rsi),%edx | ||
865 | mov %eax,0(%rdi) | ||
866 | mov %ebx,4(%rdi) | ||
867 | mov %ecx,8(%rdi) | ||
868 | mov %edx,12(%rdi) | ||
869 | mov 16(%rsi),%eax | ||
870 | mov 20(%rsi),%ebx | ||
871 | mov 24(%rsi),%ecx | ||
872 | mov 28(%rsi),%edx | ||
873 | mov %eax,16(%rdi) | ||
874 | mov %ebx,20(%rdi) | ||
875 | mov %ecx,24(%rdi) | ||
876 | mov %edx,28(%rdi) | ||
877 | |||
878 | xor %ecx,%ecx | ||
879 | jmp .L14shortcut | ||
880 | .align 4 | ||
881 | .L14loop: | ||
882 | mov 28(%rdi),%edx # rk[4] | ||
883 | .L14shortcut: | ||
884 | mov 0(%rdi),%eax # rk[0] | ||
885 | ___ | ||
886 | &enckey (); | ||
887 | $code.=<<___; | ||
888 | mov %eax,32(%rdi) # rk[8] | ||
889 | xor 4(%rdi),%eax | ||
890 | mov %eax,36(%rdi) # rk[9] | ||
891 | xor 8(%rdi),%eax | ||
892 | mov %eax,40(%rdi) # rk[10] | ||
893 | xor 12(%rdi),%eax | ||
894 | mov %eax,44(%rdi) # rk[11] | ||
895 | |||
896 | cmp \$6,%ecx | ||
897 | je .L14break | ||
898 | add \$1,%ecx | ||
899 | |||
900 | mov %eax,%edx | ||
901 | mov 16(%rdi),%eax # rk[4] | ||
902 | movz %dl,%esi # rk[11]>>0 | ||
903 | mov 2(%rbp,%rsi,8),%ebx | ||
904 | movz %dh,%esi # rk[11]>>8 | ||
905 | and \$0x000000FF,%ebx | ||
906 | xor %ebx,%eax | ||
907 | |||
908 | mov 0(%rbp,%rsi,8),%ebx | ||
909 | shr \$16,%edx | ||
910 | and \$0x0000FF00,%ebx | ||
911 | movz %dl,%esi # rk[11]>>16 | ||
912 | xor %ebx,%eax | ||
913 | |||
914 | mov 0(%rbp,%rsi,8),%ebx | ||
915 | movz %dh,%esi # rk[11]>>24 | ||
916 | and \$0x00FF0000,%ebx | ||
917 | xor %ebx,%eax | ||
918 | |||
919 | mov 2(%rbp,%rsi,8),%ebx | ||
920 | and \$0xFF000000,%ebx | ||
921 | xor %ebx,%eax | ||
922 | |||
923 | mov %eax,48(%rdi) # rk[12] | ||
924 | xor 20(%rdi),%eax | ||
925 | mov %eax,52(%rdi) # rk[13] | ||
926 | xor 24(%rdi),%eax | ||
927 | mov %eax,56(%rdi) # rk[14] | ||
928 | xor 28(%rdi),%eax | ||
929 | mov %eax,60(%rdi) # rk[15] | ||
930 | |||
931 | lea 32(%rdi),%rdi | ||
932 | jmp .L14loop | ||
933 | .L14break: | ||
934 | movl \$14,48(%rdi) # setup number of rounds | ||
935 | xor %rax,%rax | ||
936 | jmp .Lexit | ||
937 | |||
938 | .Lbadpointer: | ||
939 | mov \$-1,%rax | ||
940 | .Lexit: | ||
941 | pop %rbp | ||
942 | pop %rbx | ||
943 | ret | ||
944 | .size AES_set_encrypt_key,.-AES_set_encrypt_key | ||
945 | ___ | ||
946 | |||
947 | sub deckey() | ||
948 | { my ($i,$ptr,$te,$td) = @_; | ||
949 | $code.=<<___; | ||
950 | mov $i($ptr),%eax | ||
951 | mov %eax,%edx | ||
952 | movz %ah,%ebx | ||
953 | shr \$16,%edx | ||
954 | and \$0xFF,%eax | ||
955 | movzb 2($te,%rax,8),%rax | ||
956 | movzb 2($te,%rbx,8),%rbx | ||
957 | mov 0($td,%rax,8),%eax | ||
958 | xor 3($td,%rbx,8),%eax | ||
959 | movzb %dh,%ebx | ||
960 | and \$0xFF,%edx | ||
961 | movzb 2($te,%rdx,8),%rdx | ||
962 | movzb 2($te,%rbx,8),%rbx | ||
963 | xor 2($td,%rdx,8),%eax | ||
964 | xor 1($td,%rbx,8),%eax | ||
965 | mov %eax,$i($ptr) | ||
966 | ___ | ||
967 | } | ||
968 | |||
969 | # int AES_set_decrypt_key(const unsigned char *userKey, const int bits, | ||
970 | # AES_KEY *key) | ||
971 | $code.=<<___; | ||
972 | .globl AES_set_decrypt_key | ||
973 | .type AES_set_decrypt_key,\@function,3 | ||
974 | .align 16 | ||
975 | AES_set_decrypt_key: | ||
976 | push %rdx | ||
977 | call AES_set_encrypt_key | ||
978 | cmp \$0,%eax | ||
979 | je .Lproceed | ||
980 | lea 24(%rsp),%rsp | ||
981 | ret | ||
982 | .Lproceed: | ||
983 | mov (%rsp),%r8 # restore key schedule | ||
984 | mov %rbx,(%rsp) | ||
985 | |||
986 | mov 240(%r8),%ecx # pull number of rounds | ||
987 | xor %rdi,%rdi | ||
988 | lea (%rdi,%rcx,4),%rcx | ||
989 | mov %r8,%rsi | ||
990 | lea (%r8,%rcx,4),%rdi # pointer to last chunk | ||
991 | .align 4 | ||
992 | .Linvert: | ||
993 | mov 0(%rsi),%rax | ||
994 | mov 8(%rsi),%rbx | ||
995 | mov 0(%rdi),%rcx | ||
996 | mov 8(%rdi),%rdx | ||
997 | mov %rax,0(%rdi) | ||
998 | mov %rbx,8(%rdi) | ||
999 | mov %rcx,0(%rsi) | ||
1000 | mov %rdx,8(%rsi) | ||
1001 | lea 16(%rsi),%rsi | ||
1002 | lea -16(%rdi),%rdi | ||
1003 | cmp %rsi,%rdi | ||
1004 | jne .Linvert | ||
1005 | |||
1006 | .picmeup %r9 | ||
1007 | lea AES_Td-.(%r9),%rdi | ||
1008 | lea AES_Te-AES_Td(%rdi),%r9 | ||
1009 | |||
1010 | mov %r8,%rsi | ||
1011 | mov 240(%r8),%ecx # pull number of rounds | ||
1012 | sub \$1,%ecx | ||
1013 | .align 4 | ||
1014 | .Lpermute: | ||
1015 | lea 16(%rsi),%rsi | ||
1016 | ___ | ||
1017 | &deckey (0,"%rsi","%r9","%rdi"); | ||
1018 | &deckey (4,"%rsi","%r9","%rdi"); | ||
1019 | &deckey (8,"%rsi","%r9","%rdi"); | ||
1020 | &deckey (12,"%rsi","%r9","%rdi"); | ||
1021 | $code.=<<___; | ||
1022 | sub \$1,%ecx | ||
1023 | jnz .Lpermute | ||
1024 | |||
1025 | xor %rax,%rax | ||
1026 | pop %rbx | ||
1027 | ret | ||
1028 | .size AES_set_decrypt_key,.-AES_set_decrypt_key | ||
1029 | ___ | ||
1030 | |||
1031 | # void AES_cbc_encrypt (const void char *inp, unsigned char *out, | ||
1032 | # size_t length, const AES_KEY *key, | ||
1033 | # unsigned char *ivp,const int enc); | ||
1034 | { | ||
1035 | # stack frame layout | ||
1036 | # -8(%rsp) return address | ||
1037 | my $_rsp="0(%rsp)"; # saved %rsp | ||
1038 | my $_len="8(%rsp)"; # copy of 3rd parameter, length | ||
1039 | my $_key="16(%rsp)"; # copy of 4th parameter, key | ||
1040 | my $_ivp="24(%rsp)"; # copy of 5th parameter, ivp | ||
1041 | my $keyp="32(%rsp)"; # one to pass as $key | ||
1042 | my $ivec="40(%rsp)"; # ivec[16] | ||
1043 | my $aes_key="56(%rsp)"; # copy of aes_key | ||
1044 | my $mark="56+240(%rsp)"; # copy of aes_key->rounds | ||
1045 | |||
1046 | $code.=<<___; | ||
1047 | .globl AES_cbc_encrypt | ||
1048 | .type AES_cbc_encrypt,\@function,6 | ||
1049 | .align 16 | ||
1050 | AES_cbc_encrypt: | ||
1051 | cmp \$0,%rdx # check length | ||
1052 | je .Lcbc_just_ret | ||
1053 | push %rbx | ||
1054 | push %rbp | ||
1055 | push %r12 | ||
1056 | push %r13 | ||
1057 | push %r14 | ||
1058 | push %r15 | ||
1059 | pushfq | ||
1060 | cld | ||
1061 | mov %r9d,%r9d # clear upper half of enc | ||
1062 | |||
1063 | .picmeup $sbox | ||
1064 | .Lcbc_pic_point: | ||
1065 | |||
1066 | cmp \$0,%r9 | ||
1067 | je .LDECRYPT | ||
1068 | |||
1069 | lea AES_Te-.Lcbc_pic_point($sbox),$sbox | ||
1070 | |||
1071 | # allocate aligned stack frame... | ||
1072 | lea -64-248(%rsp),$key | ||
1073 | and \$-64,$key | ||
1074 | |||
1075 | # ... and make it doesn't alias with AES_Te modulo 4096 | ||
1076 | mov $sbox,%r10 | ||
1077 | lea 2048($sbox),%r11 | ||
1078 | mov $key,%r12 | ||
1079 | and \$0xFFF,%r10 # s = $sbox&0xfff | ||
1080 | and \$0xFFF,%r11 # e = ($sbox+2048)&0xfff | ||
1081 | and \$0xFFF,%r12 # p = %rsp&0xfff | ||
1082 | |||
1083 | cmp %r11,%r12 # if (p=>e) %rsp =- (p-e); | ||
1084 | jb .Lcbc_te_break_out | ||
1085 | sub %r11,%r12 | ||
1086 | sub %r12,$key | ||
1087 | jmp .Lcbc_te_ok | ||
1088 | .Lcbc_te_break_out: # else %rsp -= (p-s)&0xfff + framesz | ||
1089 | sub %r10,%r12 | ||
1090 | and \$0xFFF,%r12 | ||
1091 | add \$320,%r12 | ||
1092 | sub %r12,$key | ||
1093 | .align 4 | ||
1094 | .Lcbc_te_ok: | ||
1095 | |||
1096 | xchg %rsp,$key | ||
1097 | add \$8,%rsp # reserve for return address! | ||
1098 | mov $key,$_rsp # save %rsp | ||
1099 | mov %rdx,$_len # save copy of len | ||
1100 | mov %rcx,$_key # save copy of key | ||
1101 | mov %r8,$_ivp # save copy of ivp | ||
1102 | movl \$0,$mark # copy of aes_key->rounds = 0; | ||
1103 | mov %r8,%rbp # rearrange input arguments | ||
1104 | mov %rsi,$out | ||
1105 | mov %rdi,$inp | ||
1106 | mov %rcx,$key | ||
1107 | |||
1108 | # do we copy key schedule to stack? | ||
1109 | mov $key,%r10 | ||
1110 | sub $sbox,%r10 | ||
1111 | and \$0xfff,%r10 | ||
1112 | cmp \$2048,%r10 | ||
1113 | jb .Lcbc_do_ecopy | ||
1114 | cmp \$4096-248,%r10 | ||
1115 | jb .Lcbc_skip_ecopy | ||
1116 | .align 4 | ||
1117 | .Lcbc_do_ecopy: | ||
1118 | mov $key,%rsi | ||
1119 | lea $aes_key,%rdi | ||
1120 | lea $aes_key,$key | ||
1121 | mov \$240/8,%ecx | ||
1122 | .long 0x90A548F3 # rep movsq | ||
1123 | mov (%rsi),%eax # copy aes_key->rounds | ||
1124 | mov %eax,(%rdi) | ||
1125 | .Lcbc_skip_ecopy: | ||
1126 | mov $key,$keyp # save key pointer | ||
1127 | |||
1128 | mov \$16,%ecx | ||
1129 | .align 4 | ||
1130 | .Lcbc_prefetch_te: | ||
1131 | mov 0($sbox),%r10 | ||
1132 | mov 32($sbox),%r11 | ||
1133 | mov 64($sbox),%r12 | ||
1134 | mov 96($sbox),%r13 | ||
1135 | lea 128($sbox),$sbox | ||
1136 | sub \$1,%ecx | ||
1137 | jnz .Lcbc_prefetch_te | ||
1138 | sub \$2048,$sbox | ||
1139 | |||
1140 | test \$-16,%rdx # check upon length | ||
1141 | mov %rdx,%r10 | ||
1142 | mov 0(%rbp),$s0 # load iv | ||
1143 | mov 4(%rbp),$s1 | ||
1144 | mov 8(%rbp),$s2 | ||
1145 | mov 12(%rbp),$s3 | ||
1146 | jz .Lcbc_enc_tail # short input... | ||
1147 | |||
1148 | .align 4 | ||
1149 | .Lcbc_enc_loop: | ||
1150 | xor 0($inp),$s0 | ||
1151 | xor 4($inp),$s1 | ||
1152 | xor 8($inp),$s2 | ||
1153 | xor 12($inp),$s3 | ||
1154 | mov $inp,$ivec # if ($verticalspin) save inp | ||
1155 | |||
1156 | mov $keyp,$key # restore key | ||
1157 | call _x86_64_AES_encrypt | ||
1158 | |||
1159 | mov $ivec,$inp # if ($verticalspin) restore inp | ||
1160 | mov $s0,0($out) | ||
1161 | mov $s1,4($out) | ||
1162 | mov $s2,8($out) | ||
1163 | mov $s3,12($out) | ||
1164 | |||
1165 | mov $_len,%r10 | ||
1166 | lea 16($inp),$inp | ||
1167 | lea 16($out),$out | ||
1168 | sub \$16,%r10 | ||
1169 | test \$-16,%r10 | ||
1170 | mov %r10,$_len | ||
1171 | jnz .Lcbc_enc_loop | ||
1172 | test \$15,%r10 | ||
1173 | jnz .Lcbc_enc_tail | ||
1174 | mov $_ivp,%rbp # restore ivp | ||
1175 | mov $s0,0(%rbp) # save ivec | ||
1176 | mov $s1,4(%rbp) | ||
1177 | mov $s2,8(%rbp) | ||
1178 | mov $s3,12(%rbp) | ||
1179 | |||
1180 | .align 4 | ||
1181 | .Lcbc_cleanup: | ||
1182 | cmpl \$0,$mark # was the key schedule copied? | ||
1183 | lea $aes_key,%rdi | ||
1184 | mov $_rsp,%rsp | ||
1185 | je .Lcbc_exit | ||
1186 | mov \$240/8,%ecx | ||
1187 | xor %rax,%rax | ||
1188 | .long 0x90AB48F3 # rep stosq | ||
1189 | .Lcbc_exit: | ||
1190 | popfq | ||
1191 | pop %r15 | ||
1192 | pop %r14 | ||
1193 | pop %r13 | ||
1194 | pop %r12 | ||
1195 | pop %rbp | ||
1196 | pop %rbx | ||
1197 | .Lcbc_just_ret: | ||
1198 | ret | ||
1199 | .align 4 | ||
1200 | .Lcbc_enc_tail: | ||
1201 | cmp $inp,$out | ||
1202 | je .Lcbc_enc_in_place | ||
1203 | mov %r10,%rcx | ||
1204 | mov $inp,%rsi | ||
1205 | mov $out,%rdi | ||
1206 | .long 0xF689A4F3 # rep movsb | ||
1207 | .Lcbc_enc_in_place: | ||
1208 | mov \$16,%rcx # zero tail | ||
1209 | sub %r10,%rcx | ||
1210 | xor %rax,%rax | ||
1211 | .long 0xF689AAF3 # rep stosb | ||
1212 | mov $out,$inp # this is not a mistake! | ||
1213 | movq \$16,$_len # len=16 | ||
1214 | jmp .Lcbc_enc_loop # one more spin... | ||
1215 | #----------------------------- DECRYPT -----------------------------# | ||
1216 | .align 16 | ||
1217 | .LDECRYPT: | ||
1218 | lea AES_Td-.Lcbc_pic_point($sbox),$sbox | ||
1219 | |||
1220 | # allocate aligned stack frame... | ||
1221 | lea -64-248(%rsp),$key | ||
1222 | and \$-64,$key | ||
1223 | |||
1224 | # ... and make it doesn't alias with AES_Td modulo 4096 | ||
1225 | mov $sbox,%r10 | ||
1226 | lea 2304($sbox),%r11 | ||
1227 | mov $key,%r12 | ||
1228 | and \$0xFFF,%r10 # s = $sbox&0xfff | ||
1229 | and \$0xFFF,%r11 # e = ($sbox+2048+256)&0xfff | ||
1230 | and \$0xFFF,%r12 # p = %rsp&0xfff | ||
1231 | |||
1232 | cmp %r11,%r12 # if (p=>e) %rsp =- (p-e); | ||
1233 | jb .Lcbc_td_break_out | ||
1234 | sub %r11,%r12 | ||
1235 | sub %r12,$key | ||
1236 | jmp .Lcbc_td_ok | ||
1237 | .Lcbc_td_break_out: # else %rsp -= (p-s)&0xfff + framesz | ||
1238 | sub %r10,%r12 | ||
1239 | and \$0xFFF,%r12 | ||
1240 | add \$320,%r12 | ||
1241 | sub %r12,$key | ||
1242 | .align 4 | ||
1243 | .Lcbc_td_ok: | ||
1244 | |||
1245 | xchg %rsp,$key | ||
1246 | add \$8,%rsp # reserve for return address! | ||
1247 | mov $key,$_rsp # save %rsp | ||
1248 | mov %rdx,$_len # save copy of len | ||
1249 | mov %rcx,$_key # save copy of key | ||
1250 | mov %r8,$_ivp # save copy of ivp | ||
1251 | movl \$0,$mark # copy of aes_key->rounds = 0; | ||
1252 | mov %r8,%rbp # rearrange input arguments | ||
1253 | mov %rsi,$out | ||
1254 | mov %rdi,$inp | ||
1255 | mov %rcx,$key | ||
1256 | |||
1257 | # do we copy key schedule to stack? | ||
1258 | mov $key,%r10 | ||
1259 | sub $sbox,%r10 | ||
1260 | and \$0xfff,%r10 | ||
1261 | cmp \$2304,%r10 | ||
1262 | jb .Lcbc_do_dcopy | ||
1263 | cmp \$4096-248,%r10 | ||
1264 | jb .Lcbc_skip_dcopy | ||
1265 | .align 4 | ||
1266 | .Lcbc_do_dcopy: | ||
1267 | mov $key,%rsi | ||
1268 | lea $aes_key,%rdi | ||
1269 | lea $aes_key,$key | ||
1270 | mov \$240/8,%ecx | ||
1271 | .long 0x90A548F3 # rep movsq | ||
1272 | mov (%rsi),%eax # copy aes_key->rounds | ||
1273 | mov %eax,(%rdi) | ||
1274 | .Lcbc_skip_dcopy: | ||
1275 | mov $key,$keyp # save key pointer | ||
1276 | |||
1277 | mov \$18,%ecx | ||
1278 | .align 4 | ||
1279 | .Lcbc_prefetch_td: | ||
1280 | mov 0($sbox),%r10 | ||
1281 | mov 32($sbox),%r11 | ||
1282 | mov 64($sbox),%r12 | ||
1283 | mov 96($sbox),%r13 | ||
1284 | lea 128($sbox),$sbox | ||
1285 | sub \$1,%ecx | ||
1286 | jnz .Lcbc_prefetch_td | ||
1287 | sub \$2304,$sbox | ||
1288 | |||
1289 | cmp $inp,$out | ||
1290 | je .Lcbc_dec_in_place | ||
1291 | |||
1292 | mov %rbp,$ivec | ||
1293 | .align 4 | ||
1294 | .Lcbc_dec_loop: | ||
1295 | mov 0($inp),$s0 # read input | ||
1296 | mov 4($inp),$s1 | ||
1297 | mov 8($inp),$s2 | ||
1298 | mov 12($inp),$s3 | ||
1299 | mov $inp,8+$ivec # if ($verticalspin) save inp | ||
1300 | |||
1301 | mov $keyp,$key # restore key | ||
1302 | call _x86_64_AES_decrypt | ||
1303 | |||
1304 | mov $ivec,%rbp # load ivp | ||
1305 | mov 8+$ivec,$inp # if ($verticalspin) restore inp | ||
1306 | xor 0(%rbp),$s0 # xor iv | ||
1307 | xor 4(%rbp),$s1 | ||
1308 | xor 8(%rbp),$s2 | ||
1309 | xor 12(%rbp),$s3 | ||
1310 | mov $inp,%rbp # current input, next iv | ||
1311 | |||
1312 | mov $_len,%r10 # load len | ||
1313 | sub \$16,%r10 | ||
1314 | jc .Lcbc_dec_partial | ||
1315 | mov %r10,$_len # update len | ||
1316 | mov %rbp,$ivec # update ivp | ||
1317 | |||
1318 | mov $s0,0($out) # write output | ||
1319 | mov $s1,4($out) | ||
1320 | mov $s2,8($out) | ||
1321 | mov $s3,12($out) | ||
1322 | |||
1323 | lea 16($inp),$inp | ||
1324 | lea 16($out),$out | ||
1325 | jnz .Lcbc_dec_loop | ||
1326 | .Lcbc_dec_end: | ||
1327 | mov $_ivp,%r12 # load user ivp | ||
1328 | mov 0(%rbp),%r10 # load iv | ||
1329 | mov 8(%rbp),%r11 | ||
1330 | mov %r10,0(%r12) # copy back to user | ||
1331 | mov %r11,8(%r12) | ||
1332 | jmp .Lcbc_cleanup | ||
1333 | |||
1334 | .align 4 | ||
1335 | .Lcbc_dec_partial: | ||
1336 | mov $s0,0+$ivec # dump output to stack | ||
1337 | mov $s1,4+$ivec | ||
1338 | mov $s2,8+$ivec | ||
1339 | mov $s3,12+$ivec | ||
1340 | mov $out,%rdi | ||
1341 | lea $ivec,%rsi | ||
1342 | mov \$16,%rcx | ||
1343 | add %r10,%rcx # number of bytes to copy | ||
1344 | .long 0xF689A4F3 # rep movsb | ||
1345 | jmp .Lcbc_dec_end | ||
1346 | |||
1347 | .align 16 | ||
1348 | .Lcbc_dec_in_place: | ||
1349 | mov 0($inp),$s0 # load input | ||
1350 | mov 4($inp),$s1 | ||
1351 | mov 8($inp),$s2 | ||
1352 | mov 12($inp),$s3 | ||
1353 | |||
1354 | mov $inp,$ivec # if ($verticalspin) save inp | ||
1355 | mov $keyp,$key | ||
1356 | call _x86_64_AES_decrypt | ||
1357 | |||
1358 | mov $ivec,$inp # if ($verticalspin) restore inp | ||
1359 | mov $_ivp,%rbp | ||
1360 | xor 0(%rbp),$s0 | ||
1361 | xor 4(%rbp),$s1 | ||
1362 | xor 8(%rbp),$s2 | ||
1363 | xor 12(%rbp),$s3 | ||
1364 | |||
1365 | mov 0($inp),%r10 # copy input to iv | ||
1366 | mov 8($inp),%r11 | ||
1367 | mov %r10,0(%rbp) | ||
1368 | mov %r11,8(%rbp) | ||
1369 | |||
1370 | mov $s0,0($out) # save output [zaps input] | ||
1371 | mov $s1,4($out) | ||
1372 | mov $s2,8($out) | ||
1373 | mov $s3,12($out) | ||
1374 | |||
1375 | mov $_len,%rcx | ||
1376 | lea 16($inp),$inp | ||
1377 | lea 16($out),$out | ||
1378 | sub \$16,%rcx | ||
1379 | jc .Lcbc_dec_in_place_partial | ||
1380 | mov %rcx,$_len | ||
1381 | jnz .Lcbc_dec_in_place | ||
1382 | jmp .Lcbc_cleanup | ||
1383 | |||
1384 | .align 4 | ||
1385 | .Lcbc_dec_in_place_partial: | ||
1386 | # one can argue if this is actually required | ||
1387 | lea ($out,%rcx),%rdi | ||
1388 | lea (%rbp,%rcx),%rsi | ||
1389 | neg %rcx | ||
1390 | .long 0xF689A4F3 # rep movsb # restore tail | ||
1391 | jmp .Lcbc_cleanup | ||
1392 | .size AES_cbc_encrypt,.-AES_cbc_encrypt | ||
1393 | ___ | ||
1394 | } | ||
1395 | |||
1396 | $code.=<<___; | ||
1397 | .globl AES_Te | ||
1398 | .align 64 | ||
1399 | AES_Te: | ||
1400 | ___ | ||
1401 | &_data_word(0xa56363c6, 0x847c7cf8, 0x997777ee, 0x8d7b7bf6); | ||
1402 | &_data_word(0x0df2f2ff, 0xbd6b6bd6, 0xb16f6fde, 0x54c5c591); | ||
1403 | &_data_word(0x50303060, 0x03010102, 0xa96767ce, 0x7d2b2b56); | ||
1404 | &_data_word(0x19fefee7, 0x62d7d7b5, 0xe6abab4d, 0x9a7676ec); | ||
1405 | &_data_word(0x45caca8f, 0x9d82821f, 0x40c9c989, 0x877d7dfa); | ||
1406 | &_data_word(0x15fafaef, 0xeb5959b2, 0xc947478e, 0x0bf0f0fb); | ||
1407 | &_data_word(0xecadad41, 0x67d4d4b3, 0xfda2a25f, 0xeaafaf45); | ||
1408 | &_data_word(0xbf9c9c23, 0xf7a4a453, 0x967272e4, 0x5bc0c09b); | ||
1409 | &_data_word(0xc2b7b775, 0x1cfdfde1, 0xae93933d, 0x6a26264c); | ||
1410 | &_data_word(0x5a36366c, 0x413f3f7e, 0x02f7f7f5, 0x4fcccc83); | ||
1411 | &_data_word(0x5c343468, 0xf4a5a551, 0x34e5e5d1, 0x08f1f1f9); | ||
1412 | &_data_word(0x937171e2, 0x73d8d8ab, 0x53313162, 0x3f15152a); | ||
1413 | &_data_word(0x0c040408, 0x52c7c795, 0x65232346, 0x5ec3c39d); | ||
1414 | &_data_word(0x28181830, 0xa1969637, 0x0f05050a, 0xb59a9a2f); | ||
1415 | &_data_word(0x0907070e, 0x36121224, 0x9b80801b, 0x3de2e2df); | ||
1416 | &_data_word(0x26ebebcd, 0x6927274e, 0xcdb2b27f, 0x9f7575ea); | ||
1417 | &_data_word(0x1b090912, 0x9e83831d, 0x742c2c58, 0x2e1a1a34); | ||
1418 | &_data_word(0x2d1b1b36, 0xb26e6edc, 0xee5a5ab4, 0xfba0a05b); | ||
1419 | &_data_word(0xf65252a4, 0x4d3b3b76, 0x61d6d6b7, 0xceb3b37d); | ||
1420 | &_data_word(0x7b292952, 0x3ee3e3dd, 0x712f2f5e, 0x97848413); | ||
1421 | &_data_word(0xf55353a6, 0x68d1d1b9, 0x00000000, 0x2cededc1); | ||
1422 | &_data_word(0x60202040, 0x1ffcfce3, 0xc8b1b179, 0xed5b5bb6); | ||
1423 | &_data_word(0xbe6a6ad4, 0x46cbcb8d, 0xd9bebe67, 0x4b393972); | ||
1424 | &_data_word(0xde4a4a94, 0xd44c4c98, 0xe85858b0, 0x4acfcf85); | ||
1425 | &_data_word(0x6bd0d0bb, 0x2aefefc5, 0xe5aaaa4f, 0x16fbfbed); | ||
1426 | &_data_word(0xc5434386, 0xd74d4d9a, 0x55333366, 0x94858511); | ||
1427 | &_data_word(0xcf45458a, 0x10f9f9e9, 0x06020204, 0x817f7ffe); | ||
1428 | &_data_word(0xf05050a0, 0x443c3c78, 0xba9f9f25, 0xe3a8a84b); | ||
1429 | &_data_word(0xf35151a2, 0xfea3a35d, 0xc0404080, 0x8a8f8f05); | ||
1430 | &_data_word(0xad92923f, 0xbc9d9d21, 0x48383870, 0x04f5f5f1); | ||
1431 | &_data_word(0xdfbcbc63, 0xc1b6b677, 0x75dadaaf, 0x63212142); | ||
1432 | &_data_word(0x30101020, 0x1affffe5, 0x0ef3f3fd, 0x6dd2d2bf); | ||
1433 | &_data_word(0x4ccdcd81, 0x140c0c18, 0x35131326, 0x2fececc3); | ||
1434 | &_data_word(0xe15f5fbe, 0xa2979735, 0xcc444488, 0x3917172e); | ||
1435 | &_data_word(0x57c4c493, 0xf2a7a755, 0x827e7efc, 0x473d3d7a); | ||
1436 | &_data_word(0xac6464c8, 0xe75d5dba, 0x2b191932, 0x957373e6); | ||
1437 | &_data_word(0xa06060c0, 0x98818119, 0xd14f4f9e, 0x7fdcdca3); | ||
1438 | &_data_word(0x66222244, 0x7e2a2a54, 0xab90903b, 0x8388880b); | ||
1439 | &_data_word(0xca46468c, 0x29eeeec7, 0xd3b8b86b, 0x3c141428); | ||
1440 | &_data_word(0x79dedea7, 0xe25e5ebc, 0x1d0b0b16, 0x76dbdbad); | ||
1441 | &_data_word(0x3be0e0db, 0x56323264, 0x4e3a3a74, 0x1e0a0a14); | ||
1442 | &_data_word(0xdb494992, 0x0a06060c, 0x6c242448, 0xe45c5cb8); | ||
1443 | &_data_word(0x5dc2c29f, 0x6ed3d3bd, 0xefacac43, 0xa66262c4); | ||
1444 | &_data_word(0xa8919139, 0xa4959531, 0x37e4e4d3, 0x8b7979f2); | ||
1445 | &_data_word(0x32e7e7d5, 0x43c8c88b, 0x5937376e, 0xb76d6dda); | ||
1446 | &_data_word(0x8c8d8d01, 0x64d5d5b1, 0xd24e4e9c, 0xe0a9a949); | ||
1447 | &_data_word(0xb46c6cd8, 0xfa5656ac, 0x07f4f4f3, 0x25eaeacf); | ||
1448 | &_data_word(0xaf6565ca, 0x8e7a7af4, 0xe9aeae47, 0x18080810); | ||
1449 | &_data_word(0xd5baba6f, 0x887878f0, 0x6f25254a, 0x722e2e5c); | ||
1450 | &_data_word(0x241c1c38, 0xf1a6a657, 0xc7b4b473, 0x51c6c697); | ||
1451 | &_data_word(0x23e8e8cb, 0x7cdddda1, 0x9c7474e8, 0x211f1f3e); | ||
1452 | &_data_word(0xdd4b4b96, 0xdcbdbd61, 0x868b8b0d, 0x858a8a0f); | ||
1453 | &_data_word(0x907070e0, 0x423e3e7c, 0xc4b5b571, 0xaa6666cc); | ||
1454 | &_data_word(0xd8484890, 0x05030306, 0x01f6f6f7, 0x120e0e1c); | ||
1455 | &_data_word(0xa36161c2, 0x5f35356a, 0xf95757ae, 0xd0b9b969); | ||
1456 | &_data_word(0x91868617, 0x58c1c199, 0x271d1d3a, 0xb99e9e27); | ||
1457 | &_data_word(0x38e1e1d9, 0x13f8f8eb, 0xb398982b, 0x33111122); | ||
1458 | &_data_word(0xbb6969d2, 0x70d9d9a9, 0x898e8e07, 0xa7949433); | ||
1459 | &_data_word(0xb69b9b2d, 0x221e1e3c, 0x92878715, 0x20e9e9c9); | ||
1460 | &_data_word(0x49cece87, 0xff5555aa, 0x78282850, 0x7adfdfa5); | ||
1461 | &_data_word(0x8f8c8c03, 0xf8a1a159, 0x80898909, 0x170d0d1a); | ||
1462 | &_data_word(0xdabfbf65, 0x31e6e6d7, 0xc6424284, 0xb86868d0); | ||
1463 | &_data_word(0xc3414182, 0xb0999929, 0x772d2d5a, 0x110f0f1e); | ||
1464 | &_data_word(0xcbb0b07b, 0xfc5454a8, 0xd6bbbb6d, 0x3a16162c); | ||
1465 | #rcon: | ||
1466 | $code.=<<___; | ||
1467 | .long 0x00000001, 0x00000002, 0x00000004, 0x00000008 | ||
1468 | .long 0x00000010, 0x00000020, 0x00000040, 0x00000080 | ||
1469 | .long 0x0000001b, 0x00000036, 0, 0, 0, 0, 0, 0 | ||
1470 | ___ | ||
1471 | $code.=<<___; | ||
1472 | .globl AES_Td | ||
1473 | .align 64 | ||
1474 | AES_Td: | ||
1475 | ___ | ||
1476 | &_data_word(0x50a7f451, 0x5365417e, 0xc3a4171a, 0x965e273a); | ||
1477 | &_data_word(0xcb6bab3b, 0xf1459d1f, 0xab58faac, 0x9303e34b); | ||
1478 | &_data_word(0x55fa3020, 0xf66d76ad, 0x9176cc88, 0x254c02f5); | ||
1479 | &_data_word(0xfcd7e54f, 0xd7cb2ac5, 0x80443526, 0x8fa362b5); | ||
1480 | &_data_word(0x495ab1de, 0x671bba25, 0x980eea45, 0xe1c0fe5d); | ||
1481 | &_data_word(0x02752fc3, 0x12f04c81, 0xa397468d, 0xc6f9d36b); | ||
1482 | &_data_word(0xe75f8f03, 0x959c9215, 0xeb7a6dbf, 0xda595295); | ||
1483 | &_data_word(0x2d83bed4, 0xd3217458, 0x2969e049, 0x44c8c98e); | ||
1484 | &_data_word(0x6a89c275, 0x78798ef4, 0x6b3e5899, 0xdd71b927); | ||
1485 | &_data_word(0xb64fe1be, 0x17ad88f0, 0x66ac20c9, 0xb43ace7d); | ||
1486 | &_data_word(0x184adf63, 0x82311ae5, 0x60335197, 0x457f5362); | ||
1487 | &_data_word(0xe07764b1, 0x84ae6bbb, 0x1ca081fe, 0x942b08f9); | ||
1488 | &_data_word(0x58684870, 0x19fd458f, 0x876cde94, 0xb7f87b52); | ||
1489 | &_data_word(0x23d373ab, 0xe2024b72, 0x578f1fe3, 0x2aab5566); | ||
1490 | &_data_word(0x0728ebb2, 0x03c2b52f, 0x9a7bc586, 0xa50837d3); | ||
1491 | &_data_word(0xf2872830, 0xb2a5bf23, 0xba6a0302, 0x5c8216ed); | ||
1492 | &_data_word(0x2b1ccf8a, 0x92b479a7, 0xf0f207f3, 0xa1e2694e); | ||
1493 | &_data_word(0xcdf4da65, 0xd5be0506, 0x1f6234d1, 0x8afea6c4); | ||
1494 | &_data_word(0x9d532e34, 0xa055f3a2, 0x32e18a05, 0x75ebf6a4); | ||
1495 | &_data_word(0x39ec830b, 0xaaef6040, 0x069f715e, 0x51106ebd); | ||
1496 | &_data_word(0xf98a213e, 0x3d06dd96, 0xae053edd, 0x46bde64d); | ||
1497 | &_data_word(0xb58d5491, 0x055dc471, 0x6fd40604, 0xff155060); | ||
1498 | &_data_word(0x24fb9819, 0x97e9bdd6, 0xcc434089, 0x779ed967); | ||
1499 | &_data_word(0xbd42e8b0, 0x888b8907, 0x385b19e7, 0xdbeec879); | ||
1500 | &_data_word(0x470a7ca1, 0xe90f427c, 0xc91e84f8, 0x00000000); | ||
1501 | &_data_word(0x83868009, 0x48ed2b32, 0xac70111e, 0x4e725a6c); | ||
1502 | &_data_word(0xfbff0efd, 0x5638850f, 0x1ed5ae3d, 0x27392d36); | ||
1503 | &_data_word(0x64d90f0a, 0x21a65c68, 0xd1545b9b, 0x3a2e3624); | ||
1504 | &_data_word(0xb1670a0c, 0x0fe75793, 0xd296eeb4, 0x9e919b1b); | ||
1505 | &_data_word(0x4fc5c080, 0xa220dc61, 0x694b775a, 0x161a121c); | ||
1506 | &_data_word(0x0aba93e2, 0xe52aa0c0, 0x43e0223c, 0x1d171b12); | ||
1507 | &_data_word(0x0b0d090e, 0xadc78bf2, 0xb9a8b62d, 0xc8a91e14); | ||
1508 | &_data_word(0x8519f157, 0x4c0775af, 0xbbdd99ee, 0xfd607fa3); | ||
1509 | &_data_word(0x9f2601f7, 0xbcf5725c, 0xc53b6644, 0x347efb5b); | ||
1510 | &_data_word(0x7629438b, 0xdcc623cb, 0x68fcedb6, 0x63f1e4b8); | ||
1511 | &_data_word(0xcadc31d7, 0x10856342, 0x40229713, 0x2011c684); | ||
1512 | &_data_word(0x7d244a85, 0xf83dbbd2, 0x1132f9ae, 0x6da129c7); | ||
1513 | &_data_word(0x4b2f9e1d, 0xf330b2dc, 0xec52860d, 0xd0e3c177); | ||
1514 | &_data_word(0x6c16b32b, 0x99b970a9, 0xfa489411, 0x2264e947); | ||
1515 | &_data_word(0xc48cfca8, 0x1a3ff0a0, 0xd82c7d56, 0xef903322); | ||
1516 | &_data_word(0xc74e4987, 0xc1d138d9, 0xfea2ca8c, 0x360bd498); | ||
1517 | &_data_word(0xcf81f5a6, 0x28de7aa5, 0x268eb7da, 0xa4bfad3f); | ||
1518 | &_data_word(0xe49d3a2c, 0x0d927850, 0x9bcc5f6a, 0x62467e54); | ||
1519 | &_data_word(0xc2138df6, 0xe8b8d890, 0x5ef7392e, 0xf5afc382); | ||
1520 | &_data_word(0xbe805d9f, 0x7c93d069, 0xa92dd56f, 0xb31225cf); | ||
1521 | &_data_word(0x3b99acc8, 0xa77d1810, 0x6e639ce8, 0x7bbb3bdb); | ||
1522 | &_data_word(0x097826cd, 0xf418596e, 0x01b79aec, 0xa89a4f83); | ||
1523 | &_data_word(0x656e95e6, 0x7ee6ffaa, 0x08cfbc21, 0xe6e815ef); | ||
1524 | &_data_word(0xd99be7ba, 0xce366f4a, 0xd4099fea, 0xd67cb029); | ||
1525 | &_data_word(0xafb2a431, 0x31233f2a, 0x3094a5c6, 0xc066a235); | ||
1526 | &_data_word(0x37bc4e74, 0xa6ca82fc, 0xb0d090e0, 0x15d8a733); | ||
1527 | &_data_word(0x4a9804f1, 0xf7daec41, 0x0e50cd7f, 0x2ff69117); | ||
1528 | &_data_word(0x8dd64d76, 0x4db0ef43, 0x544daacc, 0xdf0496e4); | ||
1529 | &_data_word(0xe3b5d19e, 0x1b886a4c, 0xb81f2cc1, 0x7f516546); | ||
1530 | &_data_word(0x04ea5e9d, 0x5d358c01, 0x737487fa, 0x2e410bfb); | ||
1531 | &_data_word(0x5a1d67b3, 0x52d2db92, 0x335610e9, 0x1347d66d); | ||
1532 | &_data_word(0x8c61d79a, 0x7a0ca137, 0x8e14f859, 0x893c13eb); | ||
1533 | &_data_word(0xee27a9ce, 0x35c961b7, 0xede51ce1, 0x3cb1477a); | ||
1534 | &_data_word(0x59dfd29c, 0x3f73f255, 0x79ce1418, 0xbf37c773); | ||
1535 | &_data_word(0xeacdf753, 0x5baafd5f, 0x146f3ddf, 0x86db4478); | ||
1536 | &_data_word(0x81f3afca, 0x3ec468b9, 0x2c342438, 0x5f40a3c2); | ||
1537 | &_data_word(0x72c31d16, 0x0c25e2bc, 0x8b493c28, 0x41950dff); | ||
1538 | &_data_word(0x7101a839, 0xdeb30c08, 0x9ce4b4d8, 0x90c15664); | ||
1539 | &_data_word(0x6184cb7b, 0x70b632d5, 0x745c6c48, 0x4257b8d0); | ||
1540 | #Td4: | ||
1541 | &data_byte(0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38); | ||
1542 | &data_byte(0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb); | ||
1543 | &data_byte(0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87); | ||
1544 | &data_byte(0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb); | ||
1545 | &data_byte(0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d); | ||
1546 | &data_byte(0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e); | ||
1547 | &data_byte(0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2); | ||
1548 | &data_byte(0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25); | ||
1549 | &data_byte(0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16); | ||
1550 | &data_byte(0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92); | ||
1551 | &data_byte(0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda); | ||
1552 | &data_byte(0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84); | ||
1553 | &data_byte(0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a); | ||
1554 | &data_byte(0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06); | ||
1555 | &data_byte(0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02); | ||
1556 | &data_byte(0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b); | ||
1557 | &data_byte(0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea); | ||
1558 | &data_byte(0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73); | ||
1559 | &data_byte(0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85); | ||
1560 | &data_byte(0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e); | ||
1561 | &data_byte(0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89); | ||
1562 | &data_byte(0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b); | ||
1563 | &data_byte(0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20); | ||
1564 | &data_byte(0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4); | ||
1565 | &data_byte(0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31); | ||
1566 | &data_byte(0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f); | ||
1567 | &data_byte(0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d); | ||
1568 | &data_byte(0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef); | ||
1569 | &data_byte(0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0); | ||
1570 | &data_byte(0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61); | ||
1571 | &data_byte(0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26); | ||
1572 | &data_byte(0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d); | ||
1573 | |||
1574 | $code =~ s/\`([^\`]*)\`/eval($1)/gem; | ||
1575 | |||
1576 | print $code; | ||
1577 | |||
1578 | close STDOUT; | ||
diff --git a/src/lib/libcrypto/asn1/asn1_gen.c b/src/lib/libcrypto/asn1/asn1_gen.c new file mode 100644 index 0000000000..26c832781e --- /dev/null +++ b/src/lib/libcrypto/asn1/asn1_gen.c | |||
@@ -0,0 +1,848 @@ | |||
1 | /* asn1_gen.c */ | ||
2 | /* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL | ||
3 | * project 2002. | ||
4 | */ | ||
5 | /* ==================================================================== | ||
6 | * Copyright (c) 2002 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 | * This product includes cryptographic software written by Eric Young | ||
54 | * (eay@cryptsoft.com). This product includes software written by Tim | ||
55 | * Hudson (tjh@cryptsoft.com). | ||
56 | * | ||
57 | */ | ||
58 | |||
59 | #include "cryptlib.h" | ||
60 | #include <openssl/asn1.h> | ||
61 | #include <openssl/x509v3.h> | ||
62 | |||
63 | #define ASN1_GEN_FLAG 0x10000 | ||
64 | #define ASN1_GEN_FLAG_IMP (ASN1_GEN_FLAG|1) | ||
65 | #define ASN1_GEN_FLAG_EXP (ASN1_GEN_FLAG|2) | ||
66 | #define ASN1_GEN_FLAG_TAG (ASN1_GEN_FLAG|3) | ||
67 | #define ASN1_GEN_FLAG_BITWRAP (ASN1_GEN_FLAG|4) | ||
68 | #define ASN1_GEN_FLAG_OCTWRAP (ASN1_GEN_FLAG|5) | ||
69 | #define ASN1_GEN_FLAG_SEQWRAP (ASN1_GEN_FLAG|6) | ||
70 | #define ASN1_GEN_FLAG_SETWRAP (ASN1_GEN_FLAG|7) | ||
71 | #define ASN1_GEN_FLAG_FORMAT (ASN1_GEN_FLAG|8) | ||
72 | |||
73 | #define ASN1_GEN_STR(str,val) {str, sizeof(str) - 1, val} | ||
74 | |||
75 | #define ASN1_FLAG_EXP_MAX 20 | ||
76 | |||
77 | /* Input formats */ | ||
78 | |||
79 | /* ASCII: default */ | ||
80 | #define ASN1_GEN_FORMAT_ASCII 1 | ||
81 | /* UTF8 */ | ||
82 | #define ASN1_GEN_FORMAT_UTF8 2 | ||
83 | /* Hex */ | ||
84 | #define ASN1_GEN_FORMAT_HEX 3 | ||
85 | /* List of bits */ | ||
86 | #define ASN1_GEN_FORMAT_BITLIST 4 | ||
87 | |||
88 | |||
89 | struct tag_name_st | ||
90 | { | ||
91 | const char *strnam; | ||
92 | int len; | ||
93 | int tag; | ||
94 | }; | ||
95 | |||
96 | typedef struct | ||
97 | { | ||
98 | int exp_tag; | ||
99 | int exp_class; | ||
100 | int exp_constructed; | ||
101 | int exp_pad; | ||
102 | long exp_len; | ||
103 | } tag_exp_type; | ||
104 | |||
105 | typedef struct | ||
106 | { | ||
107 | int imp_tag; | ||
108 | int imp_class; | ||
109 | int utype; | ||
110 | int format; | ||
111 | const char *str; | ||
112 | tag_exp_type exp_list[ASN1_FLAG_EXP_MAX]; | ||
113 | int exp_count; | ||
114 | } tag_exp_arg; | ||
115 | |||
116 | static int bitstr_cb(const char *elem, int len, void *bitstr); | ||
117 | static int asn1_cb(const char *elem, int len, void *bitstr); | ||
118 | static int append_exp(tag_exp_arg *arg, int exp_tag, int exp_class, int exp_constructed, int exp_pad, int imp_ok); | ||
119 | static int parse_tagging(const char *vstart, int vlen, int *ptag, int *pclass); | ||
120 | static ASN1_TYPE *asn1_multi(int utype, const char *section, X509V3_CTX *cnf); | ||
121 | static ASN1_TYPE *asn1_str2type(const char *str, int format, int utype); | ||
122 | static int asn1_str2tag(const char *tagstr, int len); | ||
123 | |||
124 | ASN1_TYPE *ASN1_generate_nconf(char *str, CONF *nconf) | ||
125 | { | ||
126 | X509V3_CTX cnf; | ||
127 | |||
128 | if (!nconf) | ||
129 | return ASN1_generate_v3(str, NULL); | ||
130 | |||
131 | X509V3_set_nconf(&cnf, nconf); | ||
132 | return ASN1_generate_v3(str, &cnf); | ||
133 | } | ||
134 | |||
135 | ASN1_TYPE *ASN1_generate_v3(char *str, X509V3_CTX *cnf) | ||
136 | { | ||
137 | ASN1_TYPE *ret; | ||
138 | tag_exp_arg asn1_tags; | ||
139 | tag_exp_type *etmp; | ||
140 | |||
141 | int i, len; | ||
142 | |||
143 | unsigned char *orig_der = NULL, *new_der = NULL; | ||
144 | const unsigned char *cpy_start; | ||
145 | unsigned char *p; | ||
146 | const unsigned char *cp; | ||
147 | int cpy_len; | ||
148 | long hdr_len; | ||
149 | int hdr_constructed = 0, hdr_tag, hdr_class; | ||
150 | int r; | ||
151 | |||
152 | asn1_tags.imp_tag = -1; | ||
153 | asn1_tags.imp_class = -1; | ||
154 | asn1_tags.format = ASN1_GEN_FORMAT_ASCII; | ||
155 | asn1_tags.exp_count = 0; | ||
156 | if (CONF_parse_list(str, ',', 1, asn1_cb, &asn1_tags) != 0) | ||
157 | return NULL; | ||
158 | |||
159 | if ((asn1_tags.utype == V_ASN1_SEQUENCE) || (asn1_tags.utype == V_ASN1_SET)) | ||
160 | { | ||
161 | if (!cnf) | ||
162 | { | ||
163 | ASN1err(ASN1_F_ASN1_GENERATE_V3, ASN1_R_SEQUENCE_OR_SET_NEEDS_CONFIG); | ||
164 | return NULL; | ||
165 | } | ||
166 | ret = asn1_multi(asn1_tags.utype, asn1_tags.str, cnf); | ||
167 | } | ||
168 | else | ||
169 | ret = asn1_str2type(asn1_tags.str, asn1_tags.format, asn1_tags.utype); | ||
170 | |||
171 | if (!ret) | ||
172 | return NULL; | ||
173 | |||
174 | /* If no tagging return base type */ | ||
175 | if ((asn1_tags.imp_tag == -1) && (asn1_tags.exp_count == 0)) | ||
176 | return ret; | ||
177 | |||
178 | /* Generate the encoding */ | ||
179 | cpy_len = i2d_ASN1_TYPE(ret, &orig_der); | ||
180 | ASN1_TYPE_free(ret); | ||
181 | ret = NULL; | ||
182 | /* Set point to start copying for modified encoding */ | ||
183 | cpy_start = orig_der; | ||
184 | |||
185 | /* Do we need IMPLICIT tagging? */ | ||
186 | if (asn1_tags.imp_tag != -1) | ||
187 | { | ||
188 | /* If IMPLICIT we will replace the underlying tag */ | ||
189 | /* Skip existing tag+len */ | ||
190 | r = ASN1_get_object(&cpy_start, &hdr_len, &hdr_tag, &hdr_class, cpy_len); | ||
191 | if (r & 0x80) | ||
192 | goto err; | ||
193 | /* Update copy length */ | ||
194 | cpy_len -= cpy_start - orig_der; | ||
195 | /* For IMPLICIT tagging the length should match the | ||
196 | * original length and constructed flag should be | ||
197 | * consistent. | ||
198 | */ | ||
199 | if (r & 0x1) | ||
200 | { | ||
201 | /* Indefinite length constructed */ | ||
202 | hdr_constructed = 2; | ||
203 | hdr_len = 0; | ||
204 | } | ||
205 | else | ||
206 | /* Just retain constructed flag */ | ||
207 | hdr_constructed = r & V_ASN1_CONSTRUCTED; | ||
208 | /* Work out new length with IMPLICIT tag: ignore constructed | ||
209 | * because it will mess up if indefinite length | ||
210 | */ | ||
211 | len = ASN1_object_size(0, hdr_len, asn1_tags.imp_tag); | ||
212 | } | ||
213 | else | ||
214 | len = cpy_len; | ||
215 | |||
216 | /* Work out length in any EXPLICIT, starting from end */ | ||
217 | |||
218 | for(i = 0, etmp = asn1_tags.exp_list + asn1_tags.exp_count - 1; i < asn1_tags.exp_count; i++, etmp--) | ||
219 | { | ||
220 | /* Content length: number of content octets + any padding */ | ||
221 | len += etmp->exp_pad; | ||
222 | etmp->exp_len = len; | ||
223 | /* Total object length: length including new header */ | ||
224 | len = ASN1_object_size(0, len, etmp->exp_tag); | ||
225 | } | ||
226 | |||
227 | /* Allocate buffer for new encoding */ | ||
228 | |||
229 | new_der = OPENSSL_malloc(len); | ||
230 | |||
231 | /* Generate tagged encoding */ | ||
232 | |||
233 | p = new_der; | ||
234 | |||
235 | /* Output explicit tags first */ | ||
236 | |||
237 | for (i = 0, etmp = asn1_tags.exp_list; i < asn1_tags.exp_count; i++, etmp++) | ||
238 | { | ||
239 | ASN1_put_object(&p, etmp->exp_constructed, etmp->exp_len, | ||
240 | etmp->exp_tag, etmp->exp_class); | ||
241 | if (etmp->exp_pad) | ||
242 | *p++ = 0; | ||
243 | } | ||
244 | |||
245 | /* If IMPLICIT, output tag */ | ||
246 | |||
247 | if (asn1_tags.imp_tag != -1) | ||
248 | ASN1_put_object(&p, hdr_constructed, hdr_len, | ||
249 | asn1_tags.imp_tag, asn1_tags.imp_class); | ||
250 | |||
251 | /* Copy across original encoding */ | ||
252 | memcpy(p, cpy_start, cpy_len); | ||
253 | |||
254 | cp = new_der; | ||
255 | |||
256 | /* Obtain new ASN1_TYPE structure */ | ||
257 | ret = d2i_ASN1_TYPE(NULL, &cp, len); | ||
258 | |||
259 | err: | ||
260 | if (orig_der) | ||
261 | OPENSSL_free(orig_der); | ||
262 | if (new_der) | ||
263 | OPENSSL_free(new_der); | ||
264 | |||
265 | return ret; | ||
266 | |||
267 | } | ||
268 | |||
269 | static int asn1_cb(const char *elem, int len, void *bitstr) | ||
270 | { | ||
271 | tag_exp_arg *arg = bitstr; | ||
272 | int i; | ||
273 | int utype; | ||
274 | int vlen = 0; | ||
275 | const char *p, *vstart = NULL; | ||
276 | |||
277 | int tmp_tag, tmp_class; | ||
278 | |||
279 | for(i = 0, p = elem; i < len; p++, i++) | ||
280 | { | ||
281 | /* Look for the ':' in name value pairs */ | ||
282 | if (*p == ':') | ||
283 | { | ||
284 | vstart = p + 1; | ||
285 | vlen = len - (vstart - elem); | ||
286 | len = p - elem; | ||
287 | break; | ||
288 | } | ||
289 | } | ||
290 | |||
291 | utype = asn1_str2tag(elem, len); | ||
292 | |||
293 | if (utype == -1) | ||
294 | { | ||
295 | ASN1err(ASN1_F_ASN1_CB, ASN1_R_UNKNOWN_TAG); | ||
296 | ERR_add_error_data(2, "tag=", elem); | ||
297 | return -1; | ||
298 | } | ||
299 | |||
300 | /* If this is not a modifier mark end of string and exit */ | ||
301 | if (!(utype & ASN1_GEN_FLAG)) | ||
302 | { | ||
303 | arg->utype = utype; | ||
304 | arg->str = vstart; | ||
305 | /* If no value and not end of string, error */ | ||
306 | if (!vstart && elem[len]) | ||
307 | { | ||
308 | ASN1err(ASN1_F_ASN1_CB, ASN1_R_MISSING_VALUE); | ||
309 | return -1; | ||
310 | } | ||
311 | return 0; | ||
312 | } | ||
313 | |||
314 | switch(utype) | ||
315 | { | ||
316 | |||
317 | case ASN1_GEN_FLAG_IMP: | ||
318 | /* Check for illegal multiple IMPLICIT tagging */ | ||
319 | if (arg->imp_tag != -1) | ||
320 | { | ||
321 | ASN1err(ASN1_F_ASN1_CB, ASN1_R_ILLEGAL_NESTED_TAGGING); | ||
322 | return -1; | ||
323 | } | ||
324 | if (!parse_tagging(vstart, vlen, &arg->imp_tag, &arg->imp_class)) | ||
325 | return -1; | ||
326 | break; | ||
327 | |||
328 | case ASN1_GEN_FLAG_EXP: | ||
329 | |||
330 | if (!parse_tagging(vstart, vlen, &tmp_tag, &tmp_class)) | ||
331 | return -1; | ||
332 | if (!append_exp(arg, tmp_tag, tmp_class, 1, 0, 0)) | ||
333 | return -1; | ||
334 | break; | ||
335 | |||
336 | case ASN1_GEN_FLAG_SEQWRAP: | ||
337 | if (!append_exp(arg, V_ASN1_SEQUENCE, V_ASN1_UNIVERSAL, 1, 0, 1)) | ||
338 | return -1; | ||
339 | break; | ||
340 | |||
341 | case ASN1_GEN_FLAG_SETWRAP: | ||
342 | if (!append_exp(arg, V_ASN1_SET, V_ASN1_UNIVERSAL, 1, 0, 1)) | ||
343 | return -1; | ||
344 | break; | ||
345 | |||
346 | case ASN1_GEN_FLAG_BITWRAP: | ||
347 | if (!append_exp(arg, V_ASN1_BIT_STRING, V_ASN1_UNIVERSAL, 0, 1, 1)) | ||
348 | return -1; | ||
349 | break; | ||
350 | |||
351 | case ASN1_GEN_FLAG_OCTWRAP: | ||
352 | if (!append_exp(arg, V_ASN1_OCTET_STRING, V_ASN1_UNIVERSAL, 0, 0, 1)) | ||
353 | return -1; | ||
354 | break; | ||
355 | |||
356 | case ASN1_GEN_FLAG_FORMAT: | ||
357 | if (!strncmp(vstart, "ASCII", 5)) | ||
358 | arg->format = ASN1_GEN_FORMAT_ASCII; | ||
359 | else if (!strncmp(vstart, "UTF8", 4)) | ||
360 | arg->format = ASN1_GEN_FORMAT_UTF8; | ||
361 | else if (!strncmp(vstart, "HEX", 3)) | ||
362 | arg->format = ASN1_GEN_FORMAT_HEX; | ||
363 | else if (!strncmp(vstart, "BITLIST", 3)) | ||
364 | arg->format = ASN1_GEN_FORMAT_BITLIST; | ||
365 | else | ||
366 | { | ||
367 | ASN1err(ASN1_F_ASN1_CB, ASN1_R_UNKOWN_FORMAT); | ||
368 | return -1; | ||
369 | } | ||
370 | break; | ||
371 | |||
372 | } | ||
373 | |||
374 | return 1; | ||
375 | |||
376 | } | ||
377 | |||
378 | static int parse_tagging(const char *vstart, int vlen, int *ptag, int *pclass) | ||
379 | { | ||
380 | char erch[2]; | ||
381 | long tag_num; | ||
382 | char *eptr; | ||
383 | if (!vstart) | ||
384 | return 0; | ||
385 | tag_num = strtoul(vstart, &eptr, 10); | ||
386 | /* Check we haven't gone past max length: should be impossible */ | ||
387 | if (eptr && *eptr && (eptr > vstart + vlen)) | ||
388 | return 0; | ||
389 | if (tag_num < 0) | ||
390 | { | ||
391 | ASN1err(ASN1_F_PARSE_TAGGING, ASN1_R_INVALID_NUMBER); | ||
392 | return 0; | ||
393 | } | ||
394 | *ptag = tag_num; | ||
395 | /* If we have non numeric characters, parse them */ | ||
396 | if (eptr) | ||
397 | vlen -= eptr - vstart; | ||
398 | else | ||
399 | vlen = 0; | ||
400 | if (vlen) | ||
401 | { | ||
402 | switch (*eptr) | ||
403 | { | ||
404 | |||
405 | case 'U': | ||
406 | *pclass = V_ASN1_UNIVERSAL; | ||
407 | break; | ||
408 | |||
409 | case 'A': | ||
410 | *pclass = V_ASN1_APPLICATION; | ||
411 | break; | ||
412 | |||
413 | case 'P': | ||
414 | *pclass = V_ASN1_PRIVATE; | ||
415 | break; | ||
416 | |||
417 | case 'C': | ||
418 | *pclass = V_ASN1_CONTEXT_SPECIFIC; | ||
419 | break; | ||
420 | |||
421 | default: | ||
422 | erch[0] = *eptr; | ||
423 | erch[1] = 0; | ||
424 | ASN1err(ASN1_F_PARSE_TAGGING, ASN1_R_INVALID_MODIFIER); | ||
425 | ERR_add_error_data(2, "Char=", erch); | ||
426 | return 0; | ||
427 | break; | ||
428 | |||
429 | } | ||
430 | } | ||
431 | else | ||
432 | *pclass = V_ASN1_CONTEXT_SPECIFIC; | ||
433 | |||
434 | return 1; | ||
435 | |||
436 | } | ||
437 | |||
438 | /* Handle multiple types: SET and SEQUENCE */ | ||
439 | |||
440 | static ASN1_TYPE *asn1_multi(int utype, const char *section, X509V3_CTX *cnf) | ||
441 | { | ||
442 | ASN1_TYPE *ret = NULL, *typ = NULL; | ||
443 | STACK_OF(ASN1_TYPE) *sk = NULL; | ||
444 | STACK_OF(CONF_VALUE) *sect = NULL; | ||
445 | unsigned char *der = NULL, *p; | ||
446 | int derlen; | ||
447 | int i, is_set; | ||
448 | sk = sk_ASN1_TYPE_new_null(); | ||
449 | if (section) | ||
450 | { | ||
451 | if (!cnf) | ||
452 | goto bad; | ||
453 | sect = X509V3_get_section(cnf, (char *)section); | ||
454 | if (!sect) | ||
455 | goto bad; | ||
456 | for (i = 0; i < sk_CONF_VALUE_num(sect); i++) | ||
457 | { | ||
458 | typ = ASN1_generate_v3(sk_CONF_VALUE_value(sect, i)->value, cnf); | ||
459 | if (!typ) | ||
460 | goto bad; | ||
461 | sk_ASN1_TYPE_push(sk, typ); | ||
462 | typ = NULL; | ||
463 | } | ||
464 | } | ||
465 | |||
466 | /* Now we has a STACK of the components, convert to the correct form */ | ||
467 | |||
468 | if (utype == V_ASN1_SET) | ||
469 | is_set = 1; | ||
470 | else | ||
471 | is_set = 0; | ||
472 | |||
473 | |||
474 | derlen = i2d_ASN1_SET_OF_ASN1_TYPE(sk, NULL, i2d_ASN1_TYPE, utype, | ||
475 | V_ASN1_UNIVERSAL, is_set); | ||
476 | der = OPENSSL_malloc(derlen); | ||
477 | p = der; | ||
478 | i2d_ASN1_SET_OF_ASN1_TYPE(sk, &p, i2d_ASN1_TYPE, utype, | ||
479 | V_ASN1_UNIVERSAL, is_set); | ||
480 | |||
481 | if (!(ret = ASN1_TYPE_new())) | ||
482 | goto bad; | ||
483 | |||
484 | if (!(ret->value.asn1_string = ASN1_STRING_type_new(utype))) | ||
485 | goto bad; | ||
486 | |||
487 | ret->type = utype; | ||
488 | |||
489 | ret->value.asn1_string->data = der; | ||
490 | ret->value.asn1_string->length = derlen; | ||
491 | |||
492 | der = NULL; | ||
493 | |||
494 | bad: | ||
495 | |||
496 | if (der) | ||
497 | OPENSSL_free(der); | ||
498 | |||
499 | if (sk) | ||
500 | sk_ASN1_TYPE_pop_free(sk, ASN1_TYPE_free); | ||
501 | if (typ) | ||
502 | ASN1_TYPE_free(typ); | ||
503 | if (sect) | ||
504 | X509V3_section_free(cnf, sect); | ||
505 | |||
506 | return ret; | ||
507 | } | ||
508 | |||
509 | static int append_exp(tag_exp_arg *arg, int exp_tag, int exp_class, int exp_constructed, int exp_pad, int imp_ok) | ||
510 | { | ||
511 | tag_exp_type *exp_tmp; | ||
512 | /* Can only have IMPLICIT if permitted */ | ||
513 | if ((arg->imp_tag != -1) && !imp_ok) | ||
514 | { | ||
515 | ASN1err(ASN1_F_APPEND_EXP, ASN1_R_ILLEGAL_IMPLICIT_TAG); | ||
516 | return 0; | ||
517 | } | ||
518 | |||
519 | if (arg->exp_count == ASN1_FLAG_EXP_MAX) | ||
520 | { | ||
521 | ASN1err(ASN1_F_APPEND_EXP, ASN1_R_DEPTH_EXCEEDED); | ||
522 | return 0; | ||
523 | } | ||
524 | |||
525 | exp_tmp = &arg->exp_list[arg->exp_count++]; | ||
526 | |||
527 | /* If IMPLICIT set tag to implicit value then | ||
528 | * reset implicit tag since it has been used. | ||
529 | */ | ||
530 | if (arg->imp_tag != -1) | ||
531 | { | ||
532 | exp_tmp->exp_tag = arg->imp_tag; | ||
533 | exp_tmp->exp_class = arg->imp_class; | ||
534 | arg->imp_tag = -1; | ||
535 | arg->imp_class = -1; | ||
536 | } | ||
537 | else | ||
538 | { | ||
539 | exp_tmp->exp_tag = exp_tag; | ||
540 | exp_tmp->exp_class = exp_class; | ||
541 | } | ||
542 | exp_tmp->exp_constructed = exp_constructed; | ||
543 | exp_tmp->exp_pad = exp_pad; | ||
544 | |||
545 | return 1; | ||
546 | } | ||
547 | |||
548 | |||
549 | static int asn1_str2tag(const char *tagstr, int len) | ||
550 | { | ||
551 | unsigned int i; | ||
552 | static struct tag_name_st *tntmp, tnst [] = { | ||
553 | ASN1_GEN_STR("BOOL", V_ASN1_BOOLEAN), | ||
554 | ASN1_GEN_STR("BOOLEAN", V_ASN1_BOOLEAN), | ||
555 | ASN1_GEN_STR("NULL", V_ASN1_NULL), | ||
556 | ASN1_GEN_STR("INT", V_ASN1_INTEGER), | ||
557 | ASN1_GEN_STR("INTEGER", V_ASN1_INTEGER), | ||
558 | ASN1_GEN_STR("ENUM", V_ASN1_ENUMERATED), | ||
559 | ASN1_GEN_STR("ENUMERATED", V_ASN1_ENUMERATED), | ||
560 | ASN1_GEN_STR("OID", V_ASN1_OBJECT), | ||
561 | ASN1_GEN_STR("OBJECT", V_ASN1_OBJECT), | ||
562 | ASN1_GEN_STR("UTCTIME", V_ASN1_UTCTIME), | ||
563 | ASN1_GEN_STR("UTC", V_ASN1_UTCTIME), | ||
564 | ASN1_GEN_STR("GENERALIZEDTIME", V_ASN1_GENERALIZEDTIME), | ||
565 | ASN1_GEN_STR("GENTIME", V_ASN1_GENERALIZEDTIME), | ||
566 | ASN1_GEN_STR("OCT", V_ASN1_OCTET_STRING), | ||
567 | ASN1_GEN_STR("OCTETSTRING", V_ASN1_OCTET_STRING), | ||
568 | ASN1_GEN_STR("BITSTR", V_ASN1_BIT_STRING), | ||
569 | ASN1_GEN_STR("BITSTRING", V_ASN1_BIT_STRING), | ||
570 | ASN1_GEN_STR("UNIVERSALSTRING", V_ASN1_UNIVERSALSTRING), | ||
571 | ASN1_GEN_STR("UNIV", V_ASN1_UNIVERSALSTRING), | ||
572 | ASN1_GEN_STR("IA5", V_ASN1_IA5STRING), | ||
573 | ASN1_GEN_STR("IA5STRING", V_ASN1_IA5STRING), | ||
574 | ASN1_GEN_STR("UTF8", V_ASN1_UTF8STRING), | ||
575 | ASN1_GEN_STR("UTF8String", V_ASN1_UTF8STRING), | ||
576 | ASN1_GEN_STR("BMP", V_ASN1_BMPSTRING), | ||
577 | ASN1_GEN_STR("BMPSTRING", V_ASN1_BMPSTRING), | ||
578 | ASN1_GEN_STR("VISIBLESTRING", V_ASN1_VISIBLESTRING), | ||
579 | ASN1_GEN_STR("VISIBLE", V_ASN1_VISIBLESTRING), | ||
580 | ASN1_GEN_STR("PRINTABLESTRING", V_ASN1_PRINTABLESTRING), | ||
581 | ASN1_GEN_STR("PRINTABLE", V_ASN1_PRINTABLESTRING), | ||
582 | ASN1_GEN_STR("T61", V_ASN1_T61STRING), | ||
583 | ASN1_GEN_STR("T61STRING", V_ASN1_T61STRING), | ||
584 | ASN1_GEN_STR("TELETEXSTRING", V_ASN1_T61STRING), | ||
585 | ASN1_GEN_STR("GeneralString", V_ASN1_GENERALSTRING), | ||
586 | ASN1_GEN_STR("GENSTR", V_ASN1_GENERALSTRING), | ||
587 | |||
588 | /* Special cases */ | ||
589 | ASN1_GEN_STR("SEQUENCE", V_ASN1_SEQUENCE), | ||
590 | ASN1_GEN_STR("SEQ", V_ASN1_SEQUENCE), | ||
591 | ASN1_GEN_STR("SET", V_ASN1_SET), | ||
592 | /* type modifiers */ | ||
593 | /* Explicit tag */ | ||
594 | ASN1_GEN_STR("EXP", ASN1_GEN_FLAG_EXP), | ||
595 | ASN1_GEN_STR("EXPLICIT", ASN1_GEN_FLAG_EXP), | ||
596 | /* Implicit tag */ | ||
597 | ASN1_GEN_STR("IMP", ASN1_GEN_FLAG_IMP), | ||
598 | ASN1_GEN_STR("IMPLICIT", ASN1_GEN_FLAG_IMP), | ||
599 | /* OCTET STRING wrapper */ | ||
600 | ASN1_GEN_STR("OCTWRAP", ASN1_GEN_FLAG_OCTWRAP), | ||
601 | /* SEQUENCE wrapper */ | ||
602 | ASN1_GEN_STR("SEQWRAP", ASN1_GEN_FLAG_SEQWRAP), | ||
603 | /* SET wrapper */ | ||
604 | ASN1_GEN_STR("SETWRAP", ASN1_GEN_FLAG_SETWRAP), | ||
605 | /* BIT STRING wrapper */ | ||
606 | ASN1_GEN_STR("BITWRAP", ASN1_GEN_FLAG_BITWRAP), | ||
607 | ASN1_GEN_STR("FORM", ASN1_GEN_FLAG_FORMAT), | ||
608 | ASN1_GEN_STR("FORMAT", ASN1_GEN_FLAG_FORMAT), | ||
609 | }; | ||
610 | |||
611 | if (len == -1) | ||
612 | len = strlen(tagstr); | ||
613 | |||
614 | tntmp = tnst; | ||
615 | for (i = 0; i < sizeof(tnst) / sizeof(struct tag_name_st); i++, tntmp++) | ||
616 | { | ||
617 | if ((len == tntmp->len) && !strncmp(tntmp->strnam, tagstr, len)) | ||
618 | return tntmp->tag; | ||
619 | } | ||
620 | |||
621 | return -1; | ||
622 | } | ||
623 | |||
624 | static ASN1_TYPE *asn1_str2type(const char *str, int format, int utype) | ||
625 | { | ||
626 | ASN1_TYPE *atmp = NULL; | ||
627 | |||
628 | CONF_VALUE vtmp; | ||
629 | |||
630 | unsigned char *rdata; | ||
631 | long rdlen; | ||
632 | |||
633 | int no_unused = 1; | ||
634 | |||
635 | if (!(atmp = ASN1_TYPE_new())) | ||
636 | { | ||
637 | ASN1err(ASN1_F_ASN1_STR2TYPE, ERR_R_MALLOC_FAILURE); | ||
638 | return NULL; | ||
639 | } | ||
640 | |||
641 | if (!str) | ||
642 | str = ""; | ||
643 | |||
644 | switch(utype) | ||
645 | { | ||
646 | |||
647 | case V_ASN1_NULL: | ||
648 | if (str && *str) | ||
649 | { | ||
650 | ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_NULL_VALUE); | ||
651 | goto bad_form; | ||
652 | } | ||
653 | break; | ||
654 | |||
655 | case V_ASN1_BOOLEAN: | ||
656 | if (format != ASN1_GEN_FORMAT_ASCII) | ||
657 | { | ||
658 | ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_NOT_ASCII_FORMAT); | ||
659 | goto bad_form; | ||
660 | } | ||
661 | vtmp.name = NULL; | ||
662 | vtmp.section = NULL; | ||
663 | vtmp.value = (char *)str; | ||
664 | if (!X509V3_get_value_bool(&vtmp, &atmp->value.boolean)) | ||
665 | { | ||
666 | ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_BOOLEAN); | ||
667 | goto bad_str; | ||
668 | } | ||
669 | break; | ||
670 | |||
671 | case V_ASN1_INTEGER: | ||
672 | case V_ASN1_ENUMERATED: | ||
673 | if (format != ASN1_GEN_FORMAT_ASCII) | ||
674 | { | ||
675 | ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_INTEGER_NOT_ASCII_FORMAT); | ||
676 | goto bad_form; | ||
677 | } | ||
678 | if (!(atmp->value.integer = s2i_ASN1_INTEGER(NULL, (char *)str))) | ||
679 | { | ||
680 | ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_INTEGER); | ||
681 | goto bad_str; | ||
682 | } | ||
683 | break; | ||
684 | |||
685 | case V_ASN1_OBJECT: | ||
686 | if (format != ASN1_GEN_FORMAT_ASCII) | ||
687 | { | ||
688 | ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_OBJECT_NOT_ASCII_FORMAT); | ||
689 | goto bad_form; | ||
690 | } | ||
691 | if (!(atmp->value.object = OBJ_txt2obj(str, 0))) | ||
692 | { | ||
693 | ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_OBJECT); | ||
694 | goto bad_str; | ||
695 | } | ||
696 | break; | ||
697 | |||
698 | case V_ASN1_UTCTIME: | ||
699 | case V_ASN1_GENERALIZEDTIME: | ||
700 | if (format != ASN1_GEN_FORMAT_ASCII) | ||
701 | { | ||
702 | ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_TIME_NOT_ASCII_FORMAT); | ||
703 | goto bad_form; | ||
704 | } | ||
705 | if (!(atmp->value.asn1_string = ASN1_STRING_new())) | ||
706 | { | ||
707 | ASN1err(ASN1_F_ASN1_STR2TYPE, ERR_R_MALLOC_FAILURE); | ||
708 | goto bad_str; | ||
709 | } | ||
710 | if (!ASN1_STRING_set(atmp->value.asn1_string, str, -1)) | ||
711 | { | ||
712 | ASN1err(ASN1_F_ASN1_STR2TYPE, ERR_R_MALLOC_FAILURE); | ||
713 | goto bad_str; | ||
714 | } | ||
715 | atmp->value.asn1_string->type = utype; | ||
716 | if (!ASN1_TIME_check(atmp->value.asn1_string)) | ||
717 | { | ||
718 | ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_TIME_VALUE); | ||
719 | goto bad_str; | ||
720 | } | ||
721 | |||
722 | break; | ||
723 | |||
724 | case V_ASN1_BMPSTRING: | ||
725 | case V_ASN1_PRINTABLESTRING: | ||
726 | case V_ASN1_IA5STRING: | ||
727 | case V_ASN1_T61STRING: | ||
728 | case V_ASN1_UTF8STRING: | ||
729 | case V_ASN1_VISIBLESTRING: | ||
730 | case V_ASN1_UNIVERSALSTRING: | ||
731 | case V_ASN1_GENERALSTRING: | ||
732 | |||
733 | if (format == ASN1_GEN_FORMAT_ASCII) | ||
734 | format = MBSTRING_ASC; | ||
735 | else if (format == ASN1_GEN_FORMAT_UTF8) | ||
736 | format = MBSTRING_UTF8; | ||
737 | else | ||
738 | { | ||
739 | ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_FORMAT); | ||
740 | goto bad_form; | ||
741 | } | ||
742 | |||
743 | |||
744 | if (ASN1_mbstring_copy(&atmp->value.asn1_string, (unsigned char *)str, | ||
745 | -1, format, ASN1_tag2bit(utype)) <= 0) | ||
746 | { | ||
747 | ASN1err(ASN1_F_ASN1_STR2TYPE, ERR_R_MALLOC_FAILURE); | ||
748 | goto bad_str; | ||
749 | } | ||
750 | |||
751 | |||
752 | break; | ||
753 | |||
754 | case V_ASN1_BIT_STRING: | ||
755 | |||
756 | case V_ASN1_OCTET_STRING: | ||
757 | |||
758 | if (!(atmp->value.asn1_string = ASN1_STRING_new())) | ||
759 | { | ||
760 | ASN1err(ASN1_F_ASN1_STR2TYPE, ERR_R_MALLOC_FAILURE); | ||
761 | goto bad_form; | ||
762 | } | ||
763 | |||
764 | if (format == ASN1_GEN_FORMAT_HEX) | ||
765 | { | ||
766 | |||
767 | if (!(rdata = string_to_hex((char *)str, &rdlen))) | ||
768 | { | ||
769 | ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_HEX); | ||
770 | goto bad_str; | ||
771 | } | ||
772 | |||
773 | atmp->value.asn1_string->data = rdata; | ||
774 | atmp->value.asn1_string->length = rdlen; | ||
775 | atmp->value.asn1_string->type = utype; | ||
776 | |||
777 | } | ||
778 | else if (format == ASN1_GEN_FORMAT_ASCII) | ||
779 | ASN1_STRING_set(atmp->value.asn1_string, str, -1); | ||
780 | else if ((format == ASN1_GEN_FORMAT_BITLIST) && (utype == V_ASN1_BIT_STRING)) | ||
781 | { | ||
782 | if (!CONF_parse_list(str, ',', 1, bitstr_cb, atmp->value.bit_string)) | ||
783 | { | ||
784 | ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_LIST_ERROR); | ||
785 | goto bad_str; | ||
786 | } | ||
787 | no_unused = 0; | ||
788 | |||
789 | } | ||
790 | else | ||
791 | { | ||
792 | ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_BITSTRING_FORMAT); | ||
793 | goto bad_form; | ||
794 | } | ||
795 | |||
796 | if ((utype == V_ASN1_BIT_STRING) && no_unused) | ||
797 | { | ||
798 | atmp->value.asn1_string->flags | ||
799 | &= ~(ASN1_STRING_FLAG_BITS_LEFT|0x07); | ||
800 | atmp->value.asn1_string->flags | ||
801 | |= ASN1_STRING_FLAG_BITS_LEFT; | ||
802 | } | ||
803 | |||
804 | |||
805 | break; | ||
806 | |||
807 | default: | ||
808 | ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_UNSUPPORTED_TYPE); | ||
809 | goto bad_str; | ||
810 | break; | ||
811 | } | ||
812 | |||
813 | |||
814 | atmp->type = utype; | ||
815 | return atmp; | ||
816 | |||
817 | |||
818 | bad_str: | ||
819 | ERR_add_error_data(2, "string=", str); | ||
820 | bad_form: | ||
821 | |||
822 | ASN1_TYPE_free(atmp); | ||
823 | return NULL; | ||
824 | |||
825 | } | ||
826 | |||
827 | static int bitstr_cb(const char *elem, int len, void *bitstr) | ||
828 | { | ||
829 | long bitnum; | ||
830 | char *eptr; | ||
831 | if (!elem) | ||
832 | return 0; | ||
833 | bitnum = strtoul(elem, &eptr, 10); | ||
834 | if (eptr && *eptr && (eptr != elem + len)) | ||
835 | return 0; | ||
836 | if (bitnum < 0) | ||
837 | { | ||
838 | ASN1err(ASN1_F_BITSTR_CB, ASN1_R_INVALID_NUMBER); | ||
839 | return 0; | ||
840 | } | ||
841 | if (!ASN1_BIT_STRING_set_bit(bitstr, bitnum, 1)) | ||
842 | { | ||
843 | ASN1err(ASN1_F_BITSTR_CB, ERR_R_MALLOC_FAILURE); | ||
844 | return 0; | ||
845 | } | ||
846 | return 1; | ||
847 | } | ||
848 | |||
diff --git a/src/lib/libcrypto/asn1/asn_mime.c b/src/lib/libcrypto/asn1/asn_mime.c new file mode 100644 index 0000000000..fe7c4ec7ab --- /dev/null +++ b/src/lib/libcrypto/asn1/asn_mime.c | |||
@@ -0,0 +1,874 @@ | |||
1 | /* asn_mime.c */ | ||
2 | /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL | ||
3 | * project. | ||
4 | */ | ||
5 | /* ==================================================================== | ||
6 | * Copyright (c) 1999-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 | |||
55 | #include <stdio.h> | ||
56 | #include <ctype.h> | ||
57 | #include "cryptlib.h" | ||
58 | #include <openssl/rand.h> | ||
59 | #include <openssl/x509.h> | ||
60 | #include <openssl/asn1.h> | ||
61 | #include <openssl/asn1t.h> | ||
62 | |||
63 | /* Generalised MIME like utilities for streaming ASN1. Although many | ||
64 | * have a PKCS7/CMS like flavour others are more general purpose. | ||
65 | */ | ||
66 | |||
67 | /* MIME format structures | ||
68 | * Note that all are translated to lower case apart from | ||
69 | * parameter values. Quotes are stripped off | ||
70 | */ | ||
71 | |||
72 | typedef struct { | ||
73 | char *param_name; /* Param name e.g. "micalg" */ | ||
74 | char *param_value; /* Param value e.g. "sha1" */ | ||
75 | } MIME_PARAM; | ||
76 | |||
77 | DECLARE_STACK_OF(MIME_PARAM) | ||
78 | IMPLEMENT_STACK_OF(MIME_PARAM) | ||
79 | |||
80 | typedef struct { | ||
81 | char *name; /* Name of line e.g. "content-type" */ | ||
82 | char *value; /* Value of line e.g. "text/plain" */ | ||
83 | STACK_OF(MIME_PARAM) *params; /* Zero or more parameters */ | ||
84 | } MIME_HEADER; | ||
85 | |||
86 | DECLARE_STACK_OF(MIME_HEADER) | ||
87 | IMPLEMENT_STACK_OF(MIME_HEADER) | ||
88 | |||
89 | static char * strip_ends(char *name); | ||
90 | static char * strip_start(char *name); | ||
91 | static char * strip_end(char *name); | ||
92 | static MIME_HEADER *mime_hdr_new(char *name, char *value); | ||
93 | static int mime_hdr_addparam(MIME_HEADER *mhdr, char *name, char *value); | ||
94 | static STACK_OF(MIME_HEADER) *mime_parse_hdr(BIO *bio); | ||
95 | static int mime_hdr_cmp(const MIME_HEADER * const *a, | ||
96 | const MIME_HEADER * const *b); | ||
97 | static int mime_param_cmp(const MIME_PARAM * const *a, | ||
98 | const MIME_PARAM * const *b); | ||
99 | static void mime_param_free(MIME_PARAM *param); | ||
100 | static int mime_bound_check(char *line, int linelen, char *bound, int blen); | ||
101 | static int multi_split(BIO *bio, char *bound, STACK_OF(BIO) **ret); | ||
102 | static int strip_eol(char *linebuf, int *plen); | ||
103 | static MIME_HEADER *mime_hdr_find(STACK_OF(MIME_HEADER) *hdrs, char *name); | ||
104 | static MIME_PARAM *mime_param_find(MIME_HEADER *hdr, char *name); | ||
105 | static void mime_hdr_free(MIME_HEADER *hdr); | ||
106 | |||
107 | #define MAX_SMLEN 1024 | ||
108 | #define mime_debug(x) /* x */ | ||
109 | |||
110 | /* Base 64 read and write of ASN1 structure */ | ||
111 | |||
112 | static int B64_write_ASN1(BIO *out, ASN1_VALUE *val, BIO *in, int flags, | ||
113 | const ASN1_ITEM *it) | ||
114 | { | ||
115 | BIO *b64; | ||
116 | int r; | ||
117 | b64 = BIO_new(BIO_f_base64()); | ||
118 | if(!b64) | ||
119 | { | ||
120 | ASN1err(ASN1_F_B64_WRITE_ASN1,ERR_R_MALLOC_FAILURE); | ||
121 | return 0; | ||
122 | } | ||
123 | /* prepend the b64 BIO so all data is base64 encoded. | ||
124 | */ | ||
125 | out = BIO_push(b64, out); | ||
126 | r = ASN1_item_i2d_bio(it, out, val); | ||
127 | (void)BIO_flush(out); | ||
128 | BIO_pop(out); | ||
129 | BIO_free(b64); | ||
130 | return r; | ||
131 | } | ||
132 | |||
133 | static ASN1_VALUE *b64_read_asn1(BIO *bio, const ASN1_ITEM *it) | ||
134 | { | ||
135 | BIO *b64; | ||
136 | ASN1_VALUE *val; | ||
137 | if(!(b64 = BIO_new(BIO_f_base64()))) { | ||
138 | ASN1err(ASN1_F_B64_READ_ASN1,ERR_R_MALLOC_FAILURE); | ||
139 | return 0; | ||
140 | } | ||
141 | bio = BIO_push(b64, bio); | ||
142 | val = ASN1_item_d2i_bio(it, bio, NULL); | ||
143 | if(!val) | ||
144 | ASN1err(ASN1_F_B64_READ_ASN1,ASN1_R_DECODE_ERROR); | ||
145 | (void)BIO_flush(bio); | ||
146 | bio = BIO_pop(bio); | ||
147 | BIO_free(b64); | ||
148 | return val; | ||
149 | } | ||
150 | |||
151 | /* Generate the MIME "micalg" parameter from RFC3851, RFC4490 */ | ||
152 | |||
153 | static int asn1_write_micalg(BIO *out, STACK_OF(X509_ALGOR) *mdalgs) | ||
154 | { | ||
155 | const EVP_MD *md; | ||
156 | int i, have_unknown = 0, write_comma, md_nid; | ||
157 | have_unknown = 0; | ||
158 | write_comma = 0; | ||
159 | for (i = 0; i < sk_X509_ALGOR_num(mdalgs); i++) | ||
160 | { | ||
161 | if (write_comma) | ||
162 | BIO_write(out, ",", 1); | ||
163 | write_comma = 1; | ||
164 | md_nid = OBJ_obj2nid(sk_X509_ALGOR_value(mdalgs, i)->algorithm); | ||
165 | md = EVP_get_digestbynid(md_nid); | ||
166 | switch(md_nid) | ||
167 | { | ||
168 | case NID_sha1: | ||
169 | BIO_puts(out, "sha1"); | ||
170 | break; | ||
171 | |||
172 | case NID_md5: | ||
173 | BIO_puts(out, "md5"); | ||
174 | break; | ||
175 | |||
176 | case NID_sha256: | ||
177 | BIO_puts(out, "sha-256"); | ||
178 | break; | ||
179 | |||
180 | case NID_sha384: | ||
181 | BIO_puts(out, "sha-384"); | ||
182 | break; | ||
183 | |||
184 | case NID_sha512: | ||
185 | BIO_puts(out, "sha-512"); | ||
186 | break; | ||
187 | |||
188 | default: | ||
189 | if (have_unknown) | ||
190 | write_comma = 0; | ||
191 | else | ||
192 | { | ||
193 | BIO_puts(out, "unknown"); | ||
194 | have_unknown = 1; | ||
195 | } | ||
196 | break; | ||
197 | |||
198 | } | ||
199 | } | ||
200 | |||
201 | return 1; | ||
202 | |||
203 | } | ||
204 | |||
205 | /* SMIME sender */ | ||
206 | |||
207 | int int_smime_write_ASN1(BIO *bio, ASN1_VALUE *val, BIO *data, int flags, | ||
208 | int ctype_nid, int econt_nid, | ||
209 | STACK_OF(X509_ALGOR) *mdalgs, | ||
210 | asn1_output_data_fn *data_fn, | ||
211 | const ASN1_ITEM *it) | ||
212 | { | ||
213 | char bound[33], c; | ||
214 | int i; | ||
215 | const char *mime_prefix, *mime_eol, *cname = "smime.p7m"; | ||
216 | const char *msg_type=NULL; | ||
217 | if (flags & SMIME_OLDMIME) | ||
218 | mime_prefix = "application/x-pkcs7-"; | ||
219 | else | ||
220 | mime_prefix = "application/pkcs7-"; | ||
221 | |||
222 | if (flags & SMIME_CRLFEOL) | ||
223 | mime_eol = "\r\n"; | ||
224 | else | ||
225 | mime_eol = "\n"; | ||
226 | if((flags & SMIME_DETACHED) && data) { | ||
227 | /* We want multipart/signed */ | ||
228 | /* Generate a random boundary */ | ||
229 | RAND_pseudo_bytes((unsigned char *)bound, 32); | ||
230 | for(i = 0; i < 32; i++) { | ||
231 | c = bound[i] & 0xf; | ||
232 | if(c < 10) c += '0'; | ||
233 | else c += 'A' - 10; | ||
234 | bound[i] = c; | ||
235 | } | ||
236 | bound[32] = 0; | ||
237 | BIO_printf(bio, "MIME-Version: 1.0%s", mime_eol); | ||
238 | BIO_printf(bio, "Content-Type: multipart/signed;"); | ||
239 | BIO_printf(bio, " protocol=\"%ssignature\";", mime_prefix); | ||
240 | BIO_puts(bio, " micalg=\""); | ||
241 | asn1_write_micalg(bio, mdalgs); | ||
242 | BIO_printf(bio, "\"; boundary=\"----%s\"%s%s", | ||
243 | bound, mime_eol, mime_eol); | ||
244 | BIO_printf(bio, "This is an S/MIME signed message%s%s", | ||
245 | mime_eol, mime_eol); | ||
246 | /* Now write out the first part */ | ||
247 | BIO_printf(bio, "------%s%s", bound, mime_eol); | ||
248 | if (!data_fn(bio, data, val, flags, it)) | ||
249 | return 0; | ||
250 | BIO_printf(bio, "%s------%s%s", mime_eol, bound, mime_eol); | ||
251 | |||
252 | /* Headers for signature */ | ||
253 | |||
254 | BIO_printf(bio, "Content-Type: %ssignature;", mime_prefix); | ||
255 | BIO_printf(bio, " name=\"smime.p7s\"%s", mime_eol); | ||
256 | BIO_printf(bio, "Content-Transfer-Encoding: base64%s", | ||
257 | mime_eol); | ||
258 | BIO_printf(bio, "Content-Disposition: attachment;"); | ||
259 | BIO_printf(bio, " filename=\"smime.p7s\"%s%s", | ||
260 | mime_eol, mime_eol); | ||
261 | B64_write_ASN1(bio, val, NULL, 0, it); | ||
262 | BIO_printf(bio,"%s------%s--%s%s", mime_eol, bound, | ||
263 | mime_eol, mime_eol); | ||
264 | return 1; | ||
265 | } | ||
266 | |||
267 | /* Determine smime-type header */ | ||
268 | |||
269 | if (ctype_nid == NID_pkcs7_enveloped) | ||
270 | msg_type = "enveloped-data"; | ||
271 | else if (ctype_nid == NID_pkcs7_signed) | ||
272 | { | ||
273 | if (econt_nid == NID_id_smime_ct_receipt) | ||
274 | msg_type = "signed-receipt"; | ||
275 | else if (sk_X509_ALGOR_num(mdalgs) >= 0) | ||
276 | msg_type = "signed-data"; | ||
277 | else | ||
278 | msg_type = "certs-only"; | ||
279 | } | ||
280 | else if (ctype_nid == NID_id_smime_ct_compressedData) | ||
281 | { | ||
282 | msg_type = "compressed-data"; | ||
283 | cname = "smime.p7z"; | ||
284 | } | ||
285 | /* MIME headers */ | ||
286 | BIO_printf(bio, "MIME-Version: 1.0%s", mime_eol); | ||
287 | BIO_printf(bio, "Content-Disposition: attachment;"); | ||
288 | BIO_printf(bio, " filename=\"%s\"%s", cname, mime_eol); | ||
289 | BIO_printf(bio, "Content-Type: %smime;", mime_prefix); | ||
290 | if (msg_type) | ||
291 | BIO_printf(bio, " smime-type=%s;", msg_type); | ||
292 | BIO_printf(bio, " name=\"%s\"%s", cname, mime_eol); | ||
293 | BIO_printf(bio, "Content-Transfer-Encoding: base64%s%s", | ||
294 | mime_eol, mime_eol); | ||
295 | if (!B64_write_ASN1(bio, val, data, flags, it)) | ||
296 | return 0; | ||
297 | BIO_printf(bio, "%s", mime_eol); | ||
298 | return 1; | ||
299 | } | ||
300 | |||
301 | #if 0 | ||
302 | |||
303 | /* Handle output of ASN1 data */ | ||
304 | |||
305 | |||
306 | static int asn1_output_data(BIO *out, BIO *data, ASN1_VALUE *val, int flags, | ||
307 | const ASN1_ITEM *it) | ||
308 | { | ||
309 | BIO *tmpbio; | ||
310 | const ASN1_AUX *aux = it->funcs; | ||
311 | ASN1_STREAM_ARG sarg; | ||
312 | |||
313 | if (!(flags & SMIME_DETACHED)) | ||
314 | { | ||
315 | SMIME_crlf_copy(data, out, flags); | ||
316 | return 1; | ||
317 | } | ||
318 | |||
319 | if (!aux || !aux->asn1_cb) | ||
320 | { | ||
321 | ASN1err(ASN1_F_ASN1_OUTPUT_DATA, | ||
322 | ASN1_R_STREAMING_NOT_SUPPORTED); | ||
323 | return 0; | ||
324 | } | ||
325 | |||
326 | sarg.out = out; | ||
327 | sarg.ndef_bio = NULL; | ||
328 | sarg.boundary = NULL; | ||
329 | |||
330 | /* Let ASN1 code prepend any needed BIOs */ | ||
331 | |||
332 | if (aux->asn1_cb(ASN1_OP_DETACHED_PRE, &val, it, &sarg) <= 0) | ||
333 | return 0; | ||
334 | |||
335 | /* Copy data across, passing through filter BIOs for processing */ | ||
336 | SMIME_crlf_copy(data, sarg.ndef_bio, flags); | ||
337 | |||
338 | /* Finalize structure */ | ||
339 | if (aux->asn1_cb(ASN1_OP_DETACHED_POST, &val, it, &sarg) <= 0) | ||
340 | return 0; | ||
341 | |||
342 | /* Now remove any digests prepended to the BIO */ | ||
343 | |||
344 | while (sarg.ndef_bio != out) | ||
345 | { | ||
346 | tmpbio = BIO_pop(sarg.ndef_bio); | ||
347 | BIO_free(sarg.ndef_bio); | ||
348 | sarg.ndef_bio = tmpbio; | ||
349 | } | ||
350 | |||
351 | return 1; | ||
352 | |||
353 | } | ||
354 | |||
355 | #endif | ||
356 | |||
357 | /* SMIME reader: handle multipart/signed and opaque signing. | ||
358 | * in multipart case the content is placed in a memory BIO | ||
359 | * pointed to by "bcont". In opaque this is set to NULL | ||
360 | */ | ||
361 | |||
362 | ASN1_VALUE *SMIME_read_ASN1(BIO *bio, BIO **bcont, const ASN1_ITEM *it) | ||
363 | { | ||
364 | BIO *asnin; | ||
365 | STACK_OF(MIME_HEADER) *headers = NULL; | ||
366 | STACK_OF(BIO) *parts = NULL; | ||
367 | MIME_HEADER *hdr; | ||
368 | MIME_PARAM *prm; | ||
369 | ASN1_VALUE *val; | ||
370 | int ret; | ||
371 | |||
372 | if(bcont) *bcont = NULL; | ||
373 | |||
374 | if (!(headers = mime_parse_hdr(bio))) { | ||
375 | ASN1err(ASN1_F_SMIME_READ_ASN1,ASN1_R_MIME_PARSE_ERROR); | ||
376 | return NULL; | ||
377 | } | ||
378 | |||
379 | if(!(hdr = mime_hdr_find(headers, "content-type")) || !hdr->value) { | ||
380 | sk_MIME_HEADER_pop_free(headers, mime_hdr_free); | ||
381 | ASN1err(ASN1_F_SMIME_READ_ASN1, ASN1_R_NO_CONTENT_TYPE); | ||
382 | return NULL; | ||
383 | } | ||
384 | |||
385 | /* Handle multipart/signed */ | ||
386 | |||
387 | if(!strcmp(hdr->value, "multipart/signed")) { | ||
388 | /* Split into two parts */ | ||
389 | prm = mime_param_find(hdr, "boundary"); | ||
390 | if(!prm || !prm->param_value) { | ||
391 | sk_MIME_HEADER_pop_free(headers, mime_hdr_free); | ||
392 | ASN1err(ASN1_F_SMIME_READ_ASN1, ASN1_R_NO_MULTIPART_BOUNDARY); | ||
393 | return NULL; | ||
394 | } | ||
395 | ret = multi_split(bio, prm->param_value, &parts); | ||
396 | sk_MIME_HEADER_pop_free(headers, mime_hdr_free); | ||
397 | if(!ret || (sk_BIO_num(parts) != 2) ) { | ||
398 | ASN1err(ASN1_F_SMIME_READ_ASN1, ASN1_R_NO_MULTIPART_BODY_FAILURE); | ||
399 | sk_BIO_pop_free(parts, BIO_vfree); | ||
400 | return NULL; | ||
401 | } | ||
402 | |||
403 | /* Parse the signature piece */ | ||
404 | asnin = sk_BIO_value(parts, 1); | ||
405 | |||
406 | if (!(headers = mime_parse_hdr(asnin))) { | ||
407 | ASN1err(ASN1_F_SMIME_READ_ASN1,ASN1_R_MIME_SIG_PARSE_ERROR); | ||
408 | sk_BIO_pop_free(parts, BIO_vfree); | ||
409 | return NULL; | ||
410 | } | ||
411 | |||
412 | /* Get content type */ | ||
413 | |||
414 | if(!(hdr = mime_hdr_find(headers, "content-type")) || | ||
415 | !hdr->value) { | ||
416 | sk_MIME_HEADER_pop_free(headers, mime_hdr_free); | ||
417 | ASN1err(ASN1_F_SMIME_READ_ASN1, ASN1_R_NO_SIG_CONTENT_TYPE); | ||
418 | return NULL; | ||
419 | } | ||
420 | |||
421 | if(strcmp(hdr->value, "application/x-pkcs7-signature") && | ||
422 | strcmp(hdr->value, "application/pkcs7-signature")) { | ||
423 | sk_MIME_HEADER_pop_free(headers, mime_hdr_free); | ||
424 | ASN1err(ASN1_F_SMIME_READ_ASN1,ASN1_R_SIG_INVALID_MIME_TYPE); | ||
425 | ERR_add_error_data(2, "type: ", hdr->value); | ||
426 | sk_BIO_pop_free(parts, BIO_vfree); | ||
427 | return NULL; | ||
428 | } | ||
429 | sk_MIME_HEADER_pop_free(headers, mime_hdr_free); | ||
430 | /* Read in ASN1 */ | ||
431 | if(!(val = b64_read_asn1(asnin, it))) { | ||
432 | ASN1err(ASN1_F_SMIME_READ_ASN1,ASN1_R_ASN1_SIG_PARSE_ERROR); | ||
433 | sk_BIO_pop_free(parts, BIO_vfree); | ||
434 | return NULL; | ||
435 | } | ||
436 | |||
437 | if(bcont) { | ||
438 | *bcont = sk_BIO_value(parts, 0); | ||
439 | BIO_free(asnin); | ||
440 | sk_BIO_free(parts); | ||
441 | } else sk_BIO_pop_free(parts, BIO_vfree); | ||
442 | return val; | ||
443 | } | ||
444 | |||
445 | /* OK, if not multipart/signed try opaque signature */ | ||
446 | |||
447 | if (strcmp (hdr->value, "application/x-pkcs7-mime") && | ||
448 | strcmp (hdr->value, "application/pkcs7-mime")) { | ||
449 | ASN1err(ASN1_F_SMIME_READ_ASN1,ASN1_R_INVALID_MIME_TYPE); | ||
450 | ERR_add_error_data(2, "type: ", hdr->value); | ||
451 | sk_MIME_HEADER_pop_free(headers, mime_hdr_free); | ||
452 | return NULL; | ||
453 | } | ||
454 | |||
455 | sk_MIME_HEADER_pop_free(headers, mime_hdr_free); | ||
456 | |||
457 | if(!(val = b64_read_asn1(bio, it))) { | ||
458 | ASN1err(ASN1_F_SMIME_READ_ASN1, ASN1_R_ASN1_PARSE_ERROR); | ||
459 | return NULL; | ||
460 | } | ||
461 | return val; | ||
462 | |||
463 | } | ||
464 | |||
465 | /* Copy text from one BIO to another making the output CRLF at EOL */ | ||
466 | int SMIME_crlf_copy(BIO *in, BIO *out, int flags) | ||
467 | { | ||
468 | BIO *bf; | ||
469 | char eol; | ||
470 | int len; | ||
471 | char linebuf[MAX_SMLEN]; | ||
472 | /* Buffer output so we don't write one line at a time. This is | ||
473 | * useful when streaming as we don't end up with one OCTET STRING | ||
474 | * per line. | ||
475 | */ | ||
476 | bf = BIO_new(BIO_f_buffer()); | ||
477 | if (!bf) | ||
478 | return 0; | ||
479 | out = BIO_push(bf, out); | ||
480 | if(flags & SMIME_BINARY) | ||
481 | { | ||
482 | while((len = BIO_read(in, linebuf, MAX_SMLEN)) > 0) | ||
483 | BIO_write(out, linebuf, len); | ||
484 | } | ||
485 | else | ||
486 | { | ||
487 | if(flags & SMIME_TEXT) | ||
488 | BIO_printf(out, "Content-Type: text/plain\r\n\r\n"); | ||
489 | while ((len = BIO_gets(in, linebuf, MAX_SMLEN)) > 0) | ||
490 | { | ||
491 | eol = strip_eol(linebuf, &len); | ||
492 | if (len) | ||
493 | BIO_write(out, linebuf, len); | ||
494 | if(eol) BIO_write(out, "\r\n", 2); | ||
495 | } | ||
496 | } | ||
497 | (void)BIO_flush(out); | ||
498 | BIO_pop(out); | ||
499 | BIO_free(bf); | ||
500 | return 1; | ||
501 | } | ||
502 | |||
503 | /* Strip off headers if they are text/plain */ | ||
504 | int SMIME_text(BIO *in, BIO *out) | ||
505 | { | ||
506 | char iobuf[4096]; | ||
507 | int len; | ||
508 | STACK_OF(MIME_HEADER) *headers; | ||
509 | MIME_HEADER *hdr; | ||
510 | |||
511 | if (!(headers = mime_parse_hdr(in))) { | ||
512 | ASN1err(ASN1_F_SMIME_TEXT,ASN1_R_MIME_PARSE_ERROR); | ||
513 | return 0; | ||
514 | } | ||
515 | if(!(hdr = mime_hdr_find(headers, "content-type")) || !hdr->value) { | ||
516 | ASN1err(ASN1_F_SMIME_TEXT,ASN1_R_MIME_NO_CONTENT_TYPE); | ||
517 | sk_MIME_HEADER_pop_free(headers, mime_hdr_free); | ||
518 | return 0; | ||
519 | } | ||
520 | if (strcmp (hdr->value, "text/plain")) { | ||
521 | ASN1err(ASN1_F_SMIME_TEXT,ASN1_R_INVALID_MIME_TYPE); | ||
522 | ERR_add_error_data(2, "type: ", hdr->value); | ||
523 | sk_MIME_HEADER_pop_free(headers, mime_hdr_free); | ||
524 | return 0; | ||
525 | } | ||
526 | sk_MIME_HEADER_pop_free(headers, mime_hdr_free); | ||
527 | while ((len = BIO_read(in, iobuf, sizeof(iobuf))) > 0) | ||
528 | BIO_write(out, iobuf, len); | ||
529 | return 1; | ||
530 | } | ||
531 | |||
532 | /* Split a multipart/XXX message body into component parts: result is | ||
533 | * canonical parts in a STACK of bios | ||
534 | */ | ||
535 | |||
536 | static int multi_split(BIO *bio, char *bound, STACK_OF(BIO) **ret) | ||
537 | { | ||
538 | char linebuf[MAX_SMLEN]; | ||
539 | int len, blen; | ||
540 | int eol = 0, next_eol = 0; | ||
541 | BIO *bpart = NULL; | ||
542 | STACK_OF(BIO) *parts; | ||
543 | char state, part, first; | ||
544 | |||
545 | blen = strlen(bound); | ||
546 | part = 0; | ||
547 | state = 0; | ||
548 | first = 1; | ||
549 | parts = sk_BIO_new_null(); | ||
550 | *ret = parts; | ||
551 | while ((len = BIO_gets(bio, linebuf, MAX_SMLEN)) > 0) { | ||
552 | state = mime_bound_check(linebuf, len, bound, blen); | ||
553 | if(state == 1) { | ||
554 | first = 1; | ||
555 | part++; | ||
556 | } else if(state == 2) { | ||
557 | sk_BIO_push(parts, bpart); | ||
558 | return 1; | ||
559 | } else if(part) { | ||
560 | /* Strip CR+LF from linebuf */ | ||
561 | next_eol = strip_eol(linebuf, &len); | ||
562 | if(first) { | ||
563 | first = 0; | ||
564 | if(bpart) sk_BIO_push(parts, bpart); | ||
565 | bpart = BIO_new(BIO_s_mem()); | ||
566 | BIO_set_mem_eof_return(bpart, 0); | ||
567 | } else if (eol) | ||
568 | BIO_write(bpart, "\r\n", 2); | ||
569 | eol = next_eol; | ||
570 | if (len) | ||
571 | BIO_write(bpart, linebuf, len); | ||
572 | } | ||
573 | } | ||
574 | return 0; | ||
575 | } | ||
576 | |||
577 | /* This is the big one: parse MIME header lines up to message body */ | ||
578 | |||
579 | #define MIME_INVALID 0 | ||
580 | #define MIME_START 1 | ||
581 | #define MIME_TYPE 2 | ||
582 | #define MIME_NAME 3 | ||
583 | #define MIME_VALUE 4 | ||
584 | #define MIME_QUOTE 5 | ||
585 | #define MIME_COMMENT 6 | ||
586 | |||
587 | |||
588 | static STACK_OF(MIME_HEADER) *mime_parse_hdr(BIO *bio) | ||
589 | { | ||
590 | char *p, *q, c; | ||
591 | char *ntmp; | ||
592 | char linebuf[MAX_SMLEN]; | ||
593 | MIME_HEADER *mhdr = NULL; | ||
594 | STACK_OF(MIME_HEADER) *headers; | ||
595 | int len, state, save_state = 0; | ||
596 | |||
597 | headers = sk_MIME_HEADER_new(mime_hdr_cmp); | ||
598 | while ((len = BIO_gets(bio, linebuf, MAX_SMLEN)) > 0) { | ||
599 | /* If whitespace at line start then continuation line */ | ||
600 | if(mhdr && isspace((unsigned char)linebuf[0])) state = MIME_NAME; | ||
601 | else state = MIME_START; | ||
602 | ntmp = NULL; | ||
603 | /* Go through all characters */ | ||
604 | for(p = linebuf, q = linebuf; (c = *p) && (c!='\r') && (c!='\n'); p++) { | ||
605 | |||
606 | /* State machine to handle MIME headers | ||
607 | * if this looks horrible that's because it *is* | ||
608 | */ | ||
609 | |||
610 | switch(state) { | ||
611 | case MIME_START: | ||
612 | if(c == ':') { | ||
613 | state = MIME_TYPE; | ||
614 | *p = 0; | ||
615 | ntmp = strip_ends(q); | ||
616 | q = p + 1; | ||
617 | } | ||
618 | break; | ||
619 | |||
620 | case MIME_TYPE: | ||
621 | if(c == ';') { | ||
622 | mime_debug("Found End Value\n"); | ||
623 | *p = 0; | ||
624 | mhdr = mime_hdr_new(ntmp, strip_ends(q)); | ||
625 | sk_MIME_HEADER_push(headers, mhdr); | ||
626 | ntmp = NULL; | ||
627 | q = p + 1; | ||
628 | state = MIME_NAME; | ||
629 | } else if(c == '(') { | ||
630 | save_state = state; | ||
631 | state = MIME_COMMENT; | ||
632 | } | ||
633 | break; | ||
634 | |||
635 | case MIME_COMMENT: | ||
636 | if(c == ')') { | ||
637 | state = save_state; | ||
638 | } | ||
639 | break; | ||
640 | |||
641 | case MIME_NAME: | ||
642 | if(c == '=') { | ||
643 | state = MIME_VALUE; | ||
644 | *p = 0; | ||
645 | ntmp = strip_ends(q); | ||
646 | q = p + 1; | ||
647 | } | ||
648 | break ; | ||
649 | |||
650 | case MIME_VALUE: | ||
651 | if(c == ';') { | ||
652 | state = MIME_NAME; | ||
653 | *p = 0; | ||
654 | mime_hdr_addparam(mhdr, ntmp, strip_ends(q)); | ||
655 | ntmp = NULL; | ||
656 | q = p + 1; | ||
657 | } else if (c == '"') { | ||
658 | mime_debug("Found Quote\n"); | ||
659 | state = MIME_QUOTE; | ||
660 | } else if(c == '(') { | ||
661 | save_state = state; | ||
662 | state = MIME_COMMENT; | ||
663 | } | ||
664 | break; | ||
665 | |||
666 | case MIME_QUOTE: | ||
667 | if(c == '"') { | ||
668 | mime_debug("Found Match Quote\n"); | ||
669 | state = MIME_VALUE; | ||
670 | } | ||
671 | break; | ||
672 | } | ||
673 | } | ||
674 | |||
675 | if(state == MIME_TYPE) { | ||
676 | mhdr = mime_hdr_new(ntmp, strip_ends(q)); | ||
677 | sk_MIME_HEADER_push(headers, mhdr); | ||
678 | } else if(state == MIME_VALUE) | ||
679 | mime_hdr_addparam(mhdr, ntmp, strip_ends(q)); | ||
680 | if(p == linebuf) break; /* Blank line means end of headers */ | ||
681 | } | ||
682 | |||
683 | return headers; | ||
684 | |||
685 | } | ||
686 | |||
687 | static char *strip_ends(char *name) | ||
688 | { | ||
689 | return strip_end(strip_start(name)); | ||
690 | } | ||
691 | |||
692 | /* Strip a parameter of whitespace from start of param */ | ||
693 | static char *strip_start(char *name) | ||
694 | { | ||
695 | char *p, c; | ||
696 | /* Look for first non white space or quote */ | ||
697 | for(p = name; (c = *p) ;p++) { | ||
698 | if(c == '"') { | ||
699 | /* Next char is start of string if non null */ | ||
700 | if(p[1]) return p + 1; | ||
701 | /* Else null string */ | ||
702 | return NULL; | ||
703 | } | ||
704 | if(!isspace((unsigned char)c)) return p; | ||
705 | } | ||
706 | return NULL; | ||
707 | } | ||
708 | |||
709 | /* As above but strip from end of string : maybe should handle brackets? */ | ||
710 | static char *strip_end(char *name) | ||
711 | { | ||
712 | char *p, c; | ||
713 | if(!name) return NULL; | ||
714 | /* Look for first non white space or quote */ | ||
715 | for(p = name + strlen(name) - 1; p >= name ;p--) { | ||
716 | c = *p; | ||
717 | if(c == '"') { | ||
718 | if(p - 1 == name) return NULL; | ||
719 | *p = 0; | ||
720 | return name; | ||
721 | } | ||
722 | if(isspace((unsigned char)c)) *p = 0; | ||
723 | else return name; | ||
724 | } | ||
725 | return NULL; | ||
726 | } | ||
727 | |||
728 | static MIME_HEADER *mime_hdr_new(char *name, char *value) | ||
729 | { | ||
730 | MIME_HEADER *mhdr; | ||
731 | char *tmpname, *tmpval, *p; | ||
732 | int c; | ||
733 | if(name) { | ||
734 | if(!(tmpname = BUF_strdup(name))) return NULL; | ||
735 | for(p = tmpname ; *p; p++) { | ||
736 | c = *p; | ||
737 | if(isupper(c)) { | ||
738 | c = tolower(c); | ||
739 | *p = c; | ||
740 | } | ||
741 | } | ||
742 | } else tmpname = NULL; | ||
743 | if(value) { | ||
744 | if(!(tmpval = BUF_strdup(value))) return NULL; | ||
745 | for(p = tmpval ; *p; p++) { | ||
746 | c = *p; | ||
747 | if(isupper(c)) { | ||
748 | c = tolower(c); | ||
749 | *p = c; | ||
750 | } | ||
751 | } | ||
752 | } else tmpval = NULL; | ||
753 | mhdr = (MIME_HEADER *) OPENSSL_malloc(sizeof(MIME_HEADER)); | ||
754 | if(!mhdr) return NULL; | ||
755 | mhdr->name = tmpname; | ||
756 | mhdr->value = tmpval; | ||
757 | if(!(mhdr->params = sk_MIME_PARAM_new(mime_param_cmp))) return NULL; | ||
758 | return mhdr; | ||
759 | } | ||
760 | |||
761 | static int mime_hdr_addparam(MIME_HEADER *mhdr, char *name, char *value) | ||
762 | { | ||
763 | char *tmpname, *tmpval, *p; | ||
764 | int c; | ||
765 | MIME_PARAM *mparam; | ||
766 | if(name) { | ||
767 | tmpname = BUF_strdup(name); | ||
768 | if(!tmpname) return 0; | ||
769 | for(p = tmpname ; *p; p++) { | ||
770 | c = *p; | ||
771 | if(isupper(c)) { | ||
772 | c = tolower(c); | ||
773 | *p = c; | ||
774 | } | ||
775 | } | ||
776 | } else tmpname = NULL; | ||
777 | if(value) { | ||
778 | tmpval = BUF_strdup(value); | ||
779 | if(!tmpval) return 0; | ||
780 | } else tmpval = NULL; | ||
781 | /* Parameter values are case sensitive so leave as is */ | ||
782 | mparam = (MIME_PARAM *) OPENSSL_malloc(sizeof(MIME_PARAM)); | ||
783 | if(!mparam) return 0; | ||
784 | mparam->param_name = tmpname; | ||
785 | mparam->param_value = tmpval; | ||
786 | sk_MIME_PARAM_push(mhdr->params, mparam); | ||
787 | return 1; | ||
788 | } | ||
789 | |||
790 | static int mime_hdr_cmp(const MIME_HEADER * const *a, | ||
791 | const MIME_HEADER * const *b) | ||
792 | { | ||
793 | return(strcmp((*a)->name, (*b)->name)); | ||
794 | } | ||
795 | |||
796 | static int mime_param_cmp(const MIME_PARAM * const *a, | ||
797 | const MIME_PARAM * const *b) | ||
798 | { | ||
799 | return(strcmp((*a)->param_name, (*b)->param_name)); | ||
800 | } | ||
801 | |||
802 | /* Find a header with a given name (if possible) */ | ||
803 | |||
804 | static MIME_HEADER *mime_hdr_find(STACK_OF(MIME_HEADER) *hdrs, char *name) | ||
805 | { | ||
806 | MIME_HEADER htmp; | ||
807 | int idx; | ||
808 | htmp.name = name; | ||
809 | idx = sk_MIME_HEADER_find(hdrs, &htmp); | ||
810 | if(idx < 0) return NULL; | ||
811 | return sk_MIME_HEADER_value(hdrs, idx); | ||
812 | } | ||
813 | |||
814 | static MIME_PARAM *mime_param_find(MIME_HEADER *hdr, char *name) | ||
815 | { | ||
816 | MIME_PARAM param; | ||
817 | int idx; | ||
818 | param.param_name = name; | ||
819 | idx = sk_MIME_PARAM_find(hdr->params, ¶m); | ||
820 | if(idx < 0) return NULL; | ||
821 | return sk_MIME_PARAM_value(hdr->params, idx); | ||
822 | } | ||
823 | |||
824 | static void mime_hdr_free(MIME_HEADER *hdr) | ||
825 | { | ||
826 | if(hdr->name) OPENSSL_free(hdr->name); | ||
827 | if(hdr->value) OPENSSL_free(hdr->value); | ||
828 | if(hdr->params) sk_MIME_PARAM_pop_free(hdr->params, mime_param_free); | ||
829 | OPENSSL_free(hdr); | ||
830 | } | ||
831 | |||
832 | static void mime_param_free(MIME_PARAM *param) | ||
833 | { | ||
834 | if(param->param_name) OPENSSL_free(param->param_name); | ||
835 | if(param->param_value) OPENSSL_free(param->param_value); | ||
836 | OPENSSL_free(param); | ||
837 | } | ||
838 | |||
839 | /* Check for a multipart boundary. Returns: | ||
840 | * 0 : no boundary | ||
841 | * 1 : part boundary | ||
842 | * 2 : final boundary | ||
843 | */ | ||
844 | static int mime_bound_check(char *line, int linelen, char *bound, int blen) | ||
845 | { | ||
846 | if(linelen == -1) linelen = strlen(line); | ||
847 | if(blen == -1) blen = strlen(bound); | ||
848 | /* Quickly eliminate if line length too short */ | ||
849 | if(blen + 2 > linelen) return 0; | ||
850 | /* Check for part boundary */ | ||
851 | if(!strncmp(line, "--", 2) && !strncmp(line + 2, bound, blen)) { | ||
852 | if(!strncmp(line + blen + 2, "--", 2)) return 2; | ||
853 | else return 1; | ||
854 | } | ||
855 | return 0; | ||
856 | } | ||
857 | |||
858 | static int strip_eol(char *linebuf, int *plen) | ||
859 | { | ||
860 | int len = *plen; | ||
861 | char *p, c; | ||
862 | int is_eol = 0; | ||
863 | p = linebuf + len - 1; | ||
864 | for (p = linebuf + len - 1; len > 0; len--, p--) | ||
865 | { | ||
866 | c = *p; | ||
867 | if (c == '\n') | ||
868 | is_eol = 1; | ||
869 | else if (c != '\r') | ||
870 | break; | ||
871 | } | ||
872 | *plen = len; | ||
873 | return is_eol; | ||
874 | } | ||
diff --git a/src/lib/libcrypto/bio/bss_dgram.c b/src/lib/libcrypto/bio/bss_dgram.c new file mode 100644 index 0000000000..ea2c3fff63 --- /dev/null +++ b/src/lib/libcrypto/bio/bss_dgram.c | |||
@@ -0,0 +1,488 @@ | |||
1 | /* crypto/bio/bio_dgram.c */ | ||
2 | /* | ||
3 | * DTLS implementation written by Nagendra Modadugu | ||
4 | * (nagendra@cs.stanford.edu) for the OpenSSL project 2005. | ||
5 | */ | ||
6 | /* ==================================================================== | ||
7 | * Copyright (c) 1999-2005 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 | * openssl-core@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 | * This product includes cryptographic software written by Eric Young | ||
55 | * (eay@cryptsoft.com). This product includes software written by Tim | ||
56 | * Hudson (tjh@cryptsoft.com). | ||
57 | * | ||
58 | */ | ||
59 | |||
60 | #ifndef OPENSSL_NO_DGRAM | ||
61 | |||
62 | #include <stdio.h> | ||
63 | #include <errno.h> | ||
64 | #define USE_SOCKETS | ||
65 | #include "cryptlib.h" | ||
66 | |||
67 | #include <openssl/bio.h> | ||
68 | |||
69 | #define IP_MTU 14 /* linux is lame */ | ||
70 | |||
71 | #ifdef WATT32 | ||
72 | #define sock_write SockWrite /* Watt-32 uses same names */ | ||
73 | #define sock_read SockRead | ||
74 | #define sock_puts SockPuts | ||
75 | #endif | ||
76 | |||
77 | static int dgram_write(BIO *h, const char *buf, int num); | ||
78 | static int dgram_read(BIO *h, char *buf, int size); | ||
79 | static int dgram_puts(BIO *h, const char *str); | ||
80 | static long dgram_ctrl(BIO *h, int cmd, long arg1, void *arg2); | ||
81 | static int dgram_new(BIO *h); | ||
82 | static int dgram_free(BIO *data); | ||
83 | static int dgram_clear(BIO *bio); | ||
84 | |||
85 | int BIO_dgram_should_retry(int s); | ||
86 | |||
87 | static BIO_METHOD methods_dgramp= | ||
88 | { | ||
89 | BIO_TYPE_DGRAM, | ||
90 | "datagram socket", | ||
91 | dgram_write, | ||
92 | dgram_read, | ||
93 | dgram_puts, | ||
94 | NULL, /* dgram_gets, */ | ||
95 | dgram_ctrl, | ||
96 | dgram_new, | ||
97 | dgram_free, | ||
98 | NULL, | ||
99 | }; | ||
100 | |||
101 | typedef struct bio_dgram_data_st | ||
102 | { | ||
103 | struct sockaddr peer; | ||
104 | unsigned int connected; | ||
105 | unsigned int _errno; | ||
106 | unsigned int mtu; | ||
107 | } bio_dgram_data; | ||
108 | |||
109 | BIO_METHOD *BIO_s_datagram(void) | ||
110 | { | ||
111 | return(&methods_dgramp); | ||
112 | } | ||
113 | |||
114 | BIO *BIO_new_dgram(int fd, int close_flag) | ||
115 | { | ||
116 | BIO *ret; | ||
117 | |||
118 | ret=BIO_new(BIO_s_datagram()); | ||
119 | if (ret == NULL) return(NULL); | ||
120 | BIO_set_fd(ret,fd,close_flag); | ||
121 | return(ret); | ||
122 | } | ||
123 | |||
124 | static int dgram_new(BIO *bi) | ||
125 | { | ||
126 | bio_dgram_data *data = NULL; | ||
127 | |||
128 | bi->init=0; | ||
129 | bi->num=0; | ||
130 | data = OPENSSL_malloc(sizeof(bio_dgram_data)); | ||
131 | if (data == NULL) | ||
132 | return 0; | ||
133 | memset(data, 0x00, sizeof(bio_dgram_data)); | ||
134 | bi->ptr = data; | ||
135 | |||
136 | bi->flags=0; | ||
137 | return(1); | ||
138 | } | ||
139 | |||
140 | static int dgram_free(BIO *a) | ||
141 | { | ||
142 | bio_dgram_data *data; | ||
143 | |||
144 | if (a == NULL) return(0); | ||
145 | if ( ! dgram_clear(a)) | ||
146 | return 0; | ||
147 | |||
148 | data = (bio_dgram_data *)a->ptr; | ||
149 | if(data != NULL) OPENSSL_free(data); | ||
150 | |||
151 | return(1); | ||
152 | } | ||
153 | |||
154 | static int dgram_clear(BIO *a) | ||
155 | { | ||
156 | if (a == NULL) return(0); | ||
157 | if (a->shutdown) | ||
158 | { | ||
159 | if (a->init) | ||
160 | { | ||
161 | SHUTDOWN2(a->num); | ||
162 | } | ||
163 | a->init=0; | ||
164 | a->flags=0; | ||
165 | } | ||
166 | return(1); | ||
167 | } | ||
168 | |||
169 | static int dgram_read(BIO *b, char *out, int outl) | ||
170 | { | ||
171 | int ret=0; | ||
172 | bio_dgram_data *data = (bio_dgram_data *)b->ptr; | ||
173 | |||
174 | struct sockaddr peer; | ||
175 | int peerlen = sizeof(peer); | ||
176 | |||
177 | if (out != NULL) | ||
178 | { | ||
179 | clear_socket_error(); | ||
180 | memset(&peer, 0x00, peerlen); | ||
181 | /* Last arg in recvfrom is signed on some platforms and | ||
182 | * unsigned on others. It is of type socklen_t on some | ||
183 | * but this is not universal. Cast to (void *) to avoid | ||
184 | * compiler warnings. | ||
185 | */ | ||
186 | ret=recvfrom(b->num,out,outl,0,&peer,(void *)&peerlen); | ||
187 | |||
188 | if ( ! data->connected && ret > 0) | ||
189 | BIO_ctrl(b, BIO_CTRL_DGRAM_CONNECT, 0, &peer); | ||
190 | |||
191 | BIO_clear_retry_flags(b); | ||
192 | if (ret <= 0) | ||
193 | { | ||
194 | if (BIO_dgram_should_retry(ret)) | ||
195 | { | ||
196 | BIO_set_retry_read(b); | ||
197 | data->_errno = get_last_socket_error(); | ||
198 | } | ||
199 | } | ||
200 | } | ||
201 | return(ret); | ||
202 | } | ||
203 | |||
204 | static int dgram_write(BIO *b, const char *in, int inl) | ||
205 | { | ||
206 | int ret; | ||
207 | bio_dgram_data *data = (bio_dgram_data *)b->ptr; | ||
208 | clear_socket_error(); | ||
209 | |||
210 | if ( data->connected ) | ||
211 | ret=writesocket(b->num,in,inl); | ||
212 | else | ||
213 | #if defined(NETWARE_CLIB) && defined(NETWARE_BSDSOCK) | ||
214 | ret=sendto(b->num, (char *)in, inl, 0, &data->peer, sizeof(data->peer)); | ||
215 | #else | ||
216 | ret=sendto(b->num, in, inl, 0, &data->peer, sizeof(data->peer)); | ||
217 | #endif | ||
218 | |||
219 | BIO_clear_retry_flags(b); | ||
220 | if (ret <= 0) | ||
221 | { | ||
222 | if (BIO_sock_should_retry(ret)) | ||
223 | { | ||
224 | BIO_set_retry_write(b); | ||
225 | data->_errno = get_last_socket_error(); | ||
226 | |||
227 | #if 0 /* higher layers are responsible for querying MTU, if necessary */ | ||
228 | if ( data->_errno == EMSGSIZE) | ||
229 | /* retrieve the new MTU */ | ||
230 | BIO_ctrl(b, BIO_CTRL_DGRAM_QUERY_MTU, 0, NULL); | ||
231 | #endif | ||
232 | } | ||
233 | } | ||
234 | return(ret); | ||
235 | } | ||
236 | |||
237 | static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr) | ||
238 | { | ||
239 | long ret=1; | ||
240 | int *ip; | ||
241 | struct sockaddr *to = NULL; | ||
242 | bio_dgram_data *data = NULL; | ||
243 | long sockopt_val = 0; | ||
244 | unsigned int sockopt_len = 0; | ||
245 | |||
246 | data = (bio_dgram_data *)b->ptr; | ||
247 | |||
248 | switch (cmd) | ||
249 | { | ||
250 | case BIO_CTRL_RESET: | ||
251 | num=0; | ||
252 | case BIO_C_FILE_SEEK: | ||
253 | ret=0; | ||
254 | break; | ||
255 | case BIO_C_FILE_TELL: | ||
256 | case BIO_CTRL_INFO: | ||
257 | ret=0; | ||
258 | break; | ||
259 | case BIO_C_SET_FD: | ||
260 | dgram_clear(b); | ||
261 | b->num= *((int *)ptr); | ||
262 | b->shutdown=(int)num; | ||
263 | b->init=1; | ||
264 | break; | ||
265 | case BIO_C_GET_FD: | ||
266 | if (b->init) | ||
267 | { | ||
268 | ip=(int *)ptr; | ||
269 | if (ip != NULL) *ip=b->num; | ||
270 | ret=b->num; | ||
271 | } | ||
272 | else | ||
273 | ret= -1; | ||
274 | break; | ||
275 | case BIO_CTRL_GET_CLOSE: | ||
276 | ret=b->shutdown; | ||
277 | break; | ||
278 | case BIO_CTRL_SET_CLOSE: | ||
279 | b->shutdown=(int)num; | ||
280 | break; | ||
281 | case BIO_CTRL_PENDING: | ||
282 | case BIO_CTRL_WPENDING: | ||
283 | ret=0; | ||
284 | break; | ||
285 | case BIO_CTRL_DUP: | ||
286 | case BIO_CTRL_FLUSH: | ||
287 | ret=1; | ||
288 | break; | ||
289 | case BIO_CTRL_DGRAM_CONNECT: | ||
290 | to = (struct sockaddr *)ptr; | ||
291 | #if 0 | ||
292 | if (connect(b->num, to, sizeof(struct sockaddr)) < 0) | ||
293 | { perror("connect"); ret = 0; } | ||
294 | else | ||
295 | { | ||
296 | #endif | ||
297 | memcpy(&(data->peer),to, sizeof(struct sockaddr)); | ||
298 | #if 0 | ||
299 | } | ||
300 | #endif | ||
301 | break; | ||
302 | /* (Linux)kernel sets DF bit on outgoing IP packets */ | ||
303 | #ifdef IP_MTU_DISCOVER | ||
304 | case BIO_CTRL_DGRAM_MTU_DISCOVER: | ||
305 | sockopt_val = IP_PMTUDISC_DO; | ||
306 | if ((ret = setsockopt(b->num, IPPROTO_IP, IP_MTU_DISCOVER, | ||
307 | &sockopt_val, sizeof(sockopt_val))) < 0) | ||
308 | perror("setsockopt"); | ||
309 | break; | ||
310 | #endif | ||
311 | case BIO_CTRL_DGRAM_QUERY_MTU: | ||
312 | sockopt_len = sizeof(sockopt_val); | ||
313 | if ((ret = getsockopt(b->num, IPPROTO_IP, IP_MTU, (void *)&sockopt_val, | ||
314 | &sockopt_len)) < 0 || sockopt_val < 0) | ||
315 | { ret = 0; } | ||
316 | else | ||
317 | { | ||
318 | data->mtu = sockopt_val; | ||
319 | ret = data->mtu; | ||
320 | } | ||
321 | break; | ||
322 | case BIO_CTRL_DGRAM_GET_MTU: | ||
323 | return data->mtu; | ||
324 | break; | ||
325 | case BIO_CTRL_DGRAM_SET_MTU: | ||
326 | data->mtu = num; | ||
327 | ret = num; | ||
328 | break; | ||
329 | case BIO_CTRL_DGRAM_SET_CONNECTED: | ||
330 | to = (struct sockaddr *)ptr; | ||
331 | |||
332 | if ( to != NULL) | ||
333 | { | ||
334 | data->connected = 1; | ||
335 | memcpy(&(data->peer),to, sizeof(struct sockaddr)); | ||
336 | } | ||
337 | else | ||
338 | { | ||
339 | data->connected = 0; | ||
340 | memset(&(data->peer), 0x00, sizeof(struct sockaddr)); | ||
341 | } | ||
342 | break; | ||
343 | case BIO_CTRL_DGRAM_SET_PEER: | ||
344 | to = (struct sockaddr *) ptr; | ||
345 | |||
346 | memcpy(&(data->peer), to, sizeof(struct sockaddr)); | ||
347 | break; | ||
348 | case BIO_CTRL_DGRAM_SET_RECV_TIMEOUT: | ||
349 | if ( setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, ptr, | ||
350 | sizeof(struct timeval)) < 0) | ||
351 | { perror("setsockopt"); ret = -1; } | ||
352 | break; | ||
353 | case BIO_CTRL_DGRAM_GET_RECV_TIMEOUT: | ||
354 | if ( getsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, | ||
355 | ptr, (void *)&ret) < 0) | ||
356 | { perror("getsockopt"); ret = -1; } | ||
357 | break; | ||
358 | case BIO_CTRL_DGRAM_SET_SEND_TIMEOUT: | ||
359 | if ( setsockopt(b->num, SOL_SOCKET, SO_SNDTIMEO, ptr, | ||
360 | sizeof(struct timeval)) < 0) | ||
361 | { perror("setsockopt"); ret = -1; } | ||
362 | break; | ||
363 | case BIO_CTRL_DGRAM_GET_SEND_TIMEOUT: | ||
364 | if ( getsockopt(b->num, SOL_SOCKET, SO_SNDTIMEO, | ||
365 | ptr, (void *)&ret) < 0) | ||
366 | { perror("getsockopt"); ret = -1; } | ||
367 | break; | ||
368 | case BIO_CTRL_DGRAM_GET_SEND_TIMER_EXP: | ||
369 | /* fall-through */ | ||
370 | case BIO_CTRL_DGRAM_GET_RECV_TIMER_EXP: | ||
371 | if ( data->_errno == EAGAIN) | ||
372 | { | ||
373 | ret = 1; | ||
374 | data->_errno = 0; | ||
375 | } | ||
376 | else | ||
377 | ret = 0; | ||
378 | break; | ||
379 | #ifdef EMSGSIZE | ||
380 | case BIO_CTRL_DGRAM_MTU_EXCEEDED: | ||
381 | if ( data->_errno == EMSGSIZE) | ||
382 | { | ||
383 | ret = 1; | ||
384 | data->_errno = 0; | ||
385 | } | ||
386 | else | ||
387 | ret = 0; | ||
388 | break; | ||
389 | #endif | ||
390 | default: | ||
391 | ret=0; | ||
392 | break; | ||
393 | } | ||
394 | return(ret); | ||
395 | } | ||
396 | |||
397 | static int dgram_puts(BIO *bp, const char *str) | ||
398 | { | ||
399 | int n,ret; | ||
400 | |||
401 | n=strlen(str); | ||
402 | ret=dgram_write(bp,str,n); | ||
403 | return(ret); | ||
404 | } | ||
405 | |||
406 | int BIO_dgram_should_retry(int i) | ||
407 | { | ||
408 | int err; | ||
409 | |||
410 | if ((i == 0) || (i == -1)) | ||
411 | { | ||
412 | err=get_last_socket_error(); | ||
413 | |||
414 | #if defined(OPENSSL_SYS_WINDOWS) && 0 /* more microsoft stupidity? perhaps not? Ben 4/1/99 */ | ||
415 | if ((i == -1) && (err == 0)) | ||
416 | return(1); | ||
417 | #endif | ||
418 | |||
419 | return(BIO_dgram_non_fatal_error(err)); | ||
420 | } | ||
421 | return(0); | ||
422 | } | ||
423 | |||
424 | int BIO_dgram_non_fatal_error(int err) | ||
425 | { | ||
426 | switch (err) | ||
427 | { | ||
428 | #if defined(OPENSSL_SYS_WINDOWS) | ||
429 | # if defined(WSAEWOULDBLOCK) | ||
430 | case WSAEWOULDBLOCK: | ||
431 | # endif | ||
432 | |||
433 | # if 0 /* This appears to always be an error */ | ||
434 | # if defined(WSAENOTCONN) | ||
435 | case WSAENOTCONN: | ||
436 | # endif | ||
437 | # endif | ||
438 | #endif | ||
439 | |||
440 | #ifdef EWOULDBLOCK | ||
441 | # ifdef WSAEWOULDBLOCK | ||
442 | # if WSAEWOULDBLOCK != EWOULDBLOCK | ||
443 | case EWOULDBLOCK: | ||
444 | # endif | ||
445 | # else | ||
446 | case EWOULDBLOCK: | ||
447 | # endif | ||
448 | #endif | ||
449 | |||
450 | #if defined(ENOTCONN) | ||
451 | case ENOTCONN: | ||
452 | #endif | ||
453 | |||
454 | #ifdef EINTR | ||
455 | case EINTR: | ||
456 | #endif | ||
457 | |||
458 | #ifdef EAGAIN | ||
459 | #if EWOULDBLOCK != EAGAIN | ||
460 | case EAGAIN: | ||
461 | # endif | ||
462 | #endif | ||
463 | |||
464 | #ifdef EPROTO | ||
465 | case EPROTO: | ||
466 | #endif | ||
467 | |||
468 | #ifdef EINPROGRESS | ||
469 | case EINPROGRESS: | ||
470 | #endif | ||
471 | |||
472 | #ifdef EALREADY | ||
473 | case EALREADY: | ||
474 | #endif | ||
475 | |||
476 | /* DF bit set, and packet larger than MTU */ | ||
477 | #ifdef EMSGSIZE | ||
478 | case EMSGSIZE: | ||
479 | #endif | ||
480 | |||
481 | return(1); | ||
482 | /* break; */ | ||
483 | default: | ||
484 | break; | ||
485 | } | ||
486 | return(0); | ||
487 | } | ||
488 | #endif | ||
diff --git a/src/lib/libcrypto/bn/asm/x86_64-gcc.c b/src/lib/libcrypto/bn/asm/x86_64-gcc.c index 7378344251..f13f52dd85 100644 --- a/src/lib/libcrypto/bn/asm/x86_64-gcc.c +++ b/src/lib/libcrypto/bn/asm/x86_64-gcc.c | |||
@@ -1,3 +1,6 @@ | |||
1 | #ifdef __SUNPRO_C | ||
2 | # include "../bn_asm.c" /* kind of dirty hack for Sun Studio */ | ||
3 | #else | ||
1 | /* | 4 | /* |
2 | * x86_64 BIGNUM accelerator version 0.1, December 2002. | 5 | * x86_64 BIGNUM accelerator version 0.1, December 2002. |
3 | * | 6 | * |
@@ -591,3 +594,4 @@ void bn_sqr_comba4(BN_ULONG *r, BN_ULONG *a) | |||
591 | r[6]=c1; | 594 | r[6]=c1; |
592 | r[7]=c2; | 595 | r[7]=c2; |
593 | } | 596 | } |
597 | #endif | ||
diff --git a/src/lib/libcrypto/bn/asm/x86_64-mont.pl b/src/lib/libcrypto/bn/asm/x86_64-mont.pl new file mode 100755 index 0000000000..c43b69592a --- /dev/null +++ b/src/lib/libcrypto/bn/asm/x86_64-mont.pl | |||
@@ -0,0 +1,214 @@ | |||
1 | #!/usr/bin/env perl | ||
2 | |||
3 | # ==================================================================== | ||
4 | # Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL | ||
5 | # project. The module is, however, dual licensed under OpenSSL and | ||
6 | # CRYPTOGAMS licenses depending on where you obtain it. For further | ||
7 | # details see http://www.openssl.org/~appro/cryptogams/. | ||
8 | # ==================================================================== | ||
9 | |||
10 | # October 2005. | ||
11 | # | ||
12 | # Montgomery multiplication routine for x86_64. While it gives modest | ||
13 | # 9% improvement of rsa4096 sign on Opteron, rsa512 sign runs more | ||
14 | # than twice, >2x, as fast. Most common rsa1024 sign is improved by | ||
15 | # respectful 50%. It remains to be seen if loop unrolling and | ||
16 | # dedicated squaring routine can provide further improvement... | ||
17 | |||
18 | $output=shift; | ||
19 | |||
20 | $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; | ||
21 | ( $xlate="${dir}x86_64-xlate.pl" and -f $xlate ) or | ||
22 | ( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or | ||
23 | die "can't locate x86_64-xlate.pl"; | ||
24 | |||
25 | open STDOUT,"| $^X $xlate $output"; | ||
26 | |||
27 | # int bn_mul_mont( | ||
28 | $rp="%rdi"; # BN_ULONG *rp, | ||
29 | $ap="%rsi"; # const BN_ULONG *ap, | ||
30 | $bp="%rdx"; # const BN_ULONG *bp, | ||
31 | $np="%rcx"; # const BN_ULONG *np, | ||
32 | $n0="%r8"; # const BN_ULONG *n0, | ||
33 | $num="%r9"; # int num); | ||
34 | $lo0="%r10"; | ||
35 | $hi0="%r11"; | ||
36 | $bp="%r12"; # reassign $bp | ||
37 | $hi1="%r13"; | ||
38 | $i="%r14"; | ||
39 | $j="%r15"; | ||
40 | $m0="%rbx"; | ||
41 | $m1="%rbp"; | ||
42 | |||
43 | $code=<<___; | ||
44 | .text | ||
45 | |||
46 | .globl bn_mul_mont | ||
47 | .type bn_mul_mont,\@function,6 | ||
48 | .align 16 | ||
49 | bn_mul_mont: | ||
50 | push %rbx | ||
51 | push %rbp | ||
52 | push %r12 | ||
53 | push %r13 | ||
54 | push %r14 | ||
55 | push %r15 | ||
56 | |||
57 | mov ${num}d,${num}d | ||
58 | lea 2($num),%rax | ||
59 | mov %rsp,%rbp | ||
60 | neg %rax | ||
61 | lea (%rsp,%rax,8),%rsp # tp=alloca(8*(num+2)) | ||
62 | and \$-1024,%rsp # minimize TLB usage | ||
63 | |||
64 | mov %rbp,8(%rsp,$num,8) # tp[num+1]=%rsp | ||
65 | mov %rdx,$bp # $bp reassigned, remember? | ||
66 | |||
67 | mov ($n0),$n0 # pull n0[0] value | ||
68 | |||
69 | xor $i,$i # i=0 | ||
70 | xor $j,$j # j=0 | ||
71 | |||
72 | mov ($bp),$m0 # m0=bp[0] | ||
73 | mov ($ap),%rax | ||
74 | mulq $m0 # ap[0]*bp[0] | ||
75 | mov %rax,$lo0 | ||
76 | mov %rdx,$hi0 | ||
77 | |||
78 | imulq $n0,%rax # "tp[0]"*n0 | ||
79 | mov %rax,$m1 | ||
80 | |||
81 | mulq ($np) # np[0]*m1 | ||
82 | add $lo0,%rax # discarded | ||
83 | adc \$0,%rdx | ||
84 | mov %rdx,$hi1 | ||
85 | |||
86 | lea 1($j),$j # j++ | ||
87 | .L1st: | ||
88 | mov ($ap,$j,8),%rax | ||
89 | mulq $m0 # ap[j]*bp[0] | ||
90 | add $hi0,%rax | ||
91 | adc \$0,%rdx | ||
92 | mov %rax,$lo0 | ||
93 | mov ($np,$j,8),%rax | ||
94 | mov %rdx,$hi0 | ||
95 | |||
96 | mulq $m1 # np[j]*m1 | ||
97 | add $hi1,%rax | ||
98 | lea 1($j),$j # j++ | ||
99 | adc \$0,%rdx | ||
100 | add $lo0,%rax # np[j]*m1+ap[j]*bp[0] | ||
101 | adc \$0,%rdx | ||
102 | mov %rax,-16(%rsp,$j,8) # tp[j-1] | ||
103 | cmp $num,$j | ||
104 | mov %rdx,$hi1 | ||
105 | jl .L1st | ||
106 | |||
107 | xor %rdx,%rdx | ||
108 | add $hi0,$hi1 | ||
109 | adc \$0,%rdx | ||
110 | mov $hi1,-8(%rsp,$num,8) | ||
111 | mov %rdx,(%rsp,$num,8) # store upmost overflow bit | ||
112 | |||
113 | lea 1($i),$i # i++ | ||
114 | .align 4 | ||
115 | .Louter: | ||
116 | xor $j,$j # j=0 | ||
117 | |||
118 | mov ($bp,$i,8),$m0 # m0=bp[i] | ||
119 | mov ($ap),%rax # ap[0] | ||
120 | mulq $m0 # ap[0]*bp[i] | ||
121 | add (%rsp),%rax # ap[0]*bp[i]+tp[0] | ||
122 | adc \$0,%rdx | ||
123 | mov %rax,$lo0 | ||
124 | mov %rdx,$hi0 | ||
125 | |||
126 | imulq $n0,%rax # tp[0]*n0 | ||
127 | mov %rax,$m1 | ||
128 | |||
129 | mulq ($np,$j,8) # np[0]*m1 | ||
130 | add $lo0,%rax # discarded | ||
131 | mov 8(%rsp),$lo0 # tp[1] | ||
132 | adc \$0,%rdx | ||
133 | mov %rdx,$hi1 | ||
134 | |||
135 | lea 1($j),$j # j++ | ||
136 | .align 4 | ||
137 | .Linner: | ||
138 | mov ($ap,$j,8),%rax | ||
139 | mulq $m0 # ap[j]*bp[i] | ||
140 | add $hi0,%rax | ||
141 | adc \$0,%rdx | ||
142 | add %rax,$lo0 # ap[j]*bp[i]+tp[j] | ||
143 | mov ($np,$j,8),%rax | ||
144 | adc \$0,%rdx | ||
145 | mov %rdx,$hi0 | ||
146 | |||
147 | mulq $m1 # np[j]*m1 | ||
148 | add $hi1,%rax | ||
149 | lea 1($j),$j # j++ | ||
150 | adc \$0,%rdx | ||
151 | add $lo0,%rax # np[j]*m1+ap[j]*bp[i]+tp[j] | ||
152 | adc \$0,%rdx | ||
153 | mov (%rsp,$j,8),$lo0 | ||
154 | cmp $num,$j | ||
155 | mov %rax,-16(%rsp,$j,8) # tp[j-1] | ||
156 | mov %rdx,$hi1 | ||
157 | jl .Linner | ||
158 | |||
159 | xor %rdx,%rdx | ||
160 | add $hi0,$hi1 | ||
161 | adc \$0,%rdx | ||
162 | add $lo0,$hi1 # pull upmost overflow bit | ||
163 | adc \$0,%rdx | ||
164 | mov $hi1,-8(%rsp,$num,8) | ||
165 | mov %rdx,(%rsp,$num,8) # store upmost overflow bit | ||
166 | |||
167 | lea 1($i),$i # i++ | ||
168 | cmp $num,$i | ||
169 | jl .Louter | ||
170 | |||
171 | lea (%rsp),$ap # borrow ap for tp | ||
172 | lea -1($num),$j # j=num-1 | ||
173 | |||
174 | mov ($ap),%rax # tp[0] | ||
175 | xor $i,$i # i=0 and clear CF! | ||
176 | jmp .Lsub | ||
177 | .align 16 | ||
178 | .Lsub: sbb ($np,$i,8),%rax | ||
179 | mov %rax,($rp,$i,8) # rp[i]=tp[i]-np[i] | ||
180 | dec $j # doesn't affect CF! | ||
181 | mov 8($ap,$i,8),%rax # tp[i+1] | ||
182 | lea 1($i),$i # i++ | ||
183 | jge .Lsub | ||
184 | |||
185 | sbb \$0,%rax # handle upmost overflow bit | ||
186 | and %rax,$ap | ||
187 | not %rax | ||
188 | mov $rp,$np | ||
189 | and %rax,$np | ||
190 | lea -1($num),$j | ||
191 | or $np,$ap # ap=borrow?tp:rp | ||
192 | .align 16 | ||
193 | .Lcopy: # copy or in-place refresh | ||
194 | mov ($ap,$j,8),%rax | ||
195 | mov %rax,($rp,$j,8) # rp[i]=tp[i] | ||
196 | mov $i,(%rsp,$j,8) # zap temporary vector | ||
197 | dec $j | ||
198 | jge .Lcopy | ||
199 | |||
200 | mov 8(%rsp,$num,8),%rsp # restore %rsp | ||
201 | mov \$1,%rax | ||
202 | pop %r15 | ||
203 | pop %r14 | ||
204 | pop %r13 | ||
205 | pop %r12 | ||
206 | pop %rbp | ||
207 | pop %rbx | ||
208 | ret | ||
209 | .size bn_mul_mont,.-bn_mul_mont | ||
210 | .asciz "Montgomery Multiplication for x86_64, CRYPTOGAMS by <appro\@openssl.org>" | ||
211 | ___ | ||
212 | |||
213 | print $code; | ||
214 | close STDOUT; | ||
diff --git a/src/lib/libcrypto/bn/bn_const.c b/src/lib/libcrypto/bn/bn_const.c new file mode 100644 index 0000000000..eb60a25b3c --- /dev/null +++ b/src/lib/libcrypto/bn/bn_const.c | |||
@@ -0,0 +1,402 @@ | |||
1 | /* crypto/bn/knownprimes.c */ | ||
2 | /* Insert boilerplate */ | ||
3 | |||
4 | #include "bn.h" | ||
5 | |||
6 | /* "First Oakley Default Group" from RFC2409, section 6.1. | ||
7 | * | ||
8 | * The prime is: 2^768 - 2 ^704 - 1 + 2^64 * { [2^638 pi] + 149686 } | ||
9 | * | ||
10 | * RFC2409 specifies a generator of 2. | ||
11 | * RFC2412 specifies a generator of of 22. | ||
12 | */ | ||
13 | |||
14 | BIGNUM *get_rfc2409_prime_768(BIGNUM *bn) | ||
15 | { | ||
16 | static const unsigned char RFC2409_PRIME_768[]={ | ||
17 | 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC9,0x0F,0xDA,0xA2, | ||
18 | 0x21,0x68,0xC2,0x34,0xC4,0xC6,0x62,0x8B,0x80,0xDC,0x1C,0xD1, | ||
19 | 0x29,0x02,0x4E,0x08,0x8A,0x67,0xCC,0x74,0x02,0x0B,0xBE,0xA6, | ||
20 | 0x3B,0x13,0x9B,0x22,0x51,0x4A,0x08,0x79,0x8E,0x34,0x04,0xDD, | ||
21 | 0xEF,0x95,0x19,0xB3,0xCD,0x3A,0x43,0x1B,0x30,0x2B,0x0A,0x6D, | ||
22 | 0xF2,0x5F,0x14,0x37,0x4F,0xE1,0x35,0x6D,0x6D,0x51,0xC2,0x45, | ||
23 | 0xE4,0x85,0xB5,0x76,0x62,0x5E,0x7E,0xC6,0xF4,0x4C,0x42,0xE9, | ||
24 | 0xA6,0x3A,0x36,0x20,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, | ||
25 | }; | ||
26 | return BN_bin2bn(RFC2409_PRIME_768,sizeof(RFC2409_PRIME_768),bn); | ||
27 | } | ||
28 | |||
29 | /* "Second Oakley Default Group" from RFC2409, section 6.2. | ||
30 | * | ||
31 | * The prime is: 2^1024 - 2^960 - 1 + 2^64 * { [2^894 pi] + 129093 }. | ||
32 | * | ||
33 | * RFC2409 specifies a generator of 2. | ||
34 | * RFC2412 specifies a generator of 22. | ||
35 | */ | ||
36 | |||
37 | BIGNUM *get_rfc2409_prime_1024(BIGNUM *bn) | ||
38 | { | ||
39 | static const unsigned char RFC2409_PRIME_1024[]={ | ||
40 | 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC9,0x0F,0xDA,0xA2, | ||
41 | 0x21,0x68,0xC2,0x34,0xC4,0xC6,0x62,0x8B,0x80,0xDC,0x1C,0xD1, | ||
42 | 0x29,0x02,0x4E,0x08,0x8A,0x67,0xCC,0x74,0x02,0x0B,0xBE,0xA6, | ||
43 | 0x3B,0x13,0x9B,0x22,0x51,0x4A,0x08,0x79,0x8E,0x34,0x04,0xDD, | ||
44 | 0xEF,0x95,0x19,0xB3,0xCD,0x3A,0x43,0x1B,0x30,0x2B,0x0A,0x6D, | ||
45 | 0xF2,0x5F,0x14,0x37,0x4F,0xE1,0x35,0x6D,0x6D,0x51,0xC2,0x45, | ||
46 | 0xE4,0x85,0xB5,0x76,0x62,0x5E,0x7E,0xC6,0xF4,0x4C,0x42,0xE9, | ||
47 | 0xA6,0x37,0xED,0x6B,0x0B,0xFF,0x5C,0xB6,0xF4,0x06,0xB7,0xED, | ||
48 | 0xEE,0x38,0x6B,0xFB,0x5A,0x89,0x9F,0xA5,0xAE,0x9F,0x24,0x11, | ||
49 | 0x7C,0x4B,0x1F,0xE6,0x49,0x28,0x66,0x51,0xEC,0xE6,0x53,0x81, | ||
50 | 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, | ||
51 | }; | ||
52 | return BN_bin2bn(RFC2409_PRIME_1024,sizeof(RFC2409_PRIME_1024),bn); | ||
53 | } | ||
54 | |||
55 | /* "1536-bit MODP Group" from RFC3526, Section 2. | ||
56 | * | ||
57 | * The prime is: 2^1536 - 2^1472 - 1 + 2^64 * { [2^1406 pi] + 741804 } | ||
58 | * | ||
59 | * RFC3526 specifies a generator of 2. | ||
60 | * RFC2312 specifies a generator of 22. | ||
61 | */ | ||
62 | |||
63 | BIGNUM *get_rfc3526_prime_1536(BIGNUM *bn) | ||
64 | { | ||
65 | static const unsigned char RFC3526_PRIME_1536[]={ | ||
66 | 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC9,0x0F,0xDA,0xA2, | ||
67 | 0x21,0x68,0xC2,0x34,0xC4,0xC6,0x62,0x8B,0x80,0xDC,0x1C,0xD1, | ||
68 | 0x29,0x02,0x4E,0x08,0x8A,0x67,0xCC,0x74,0x02,0x0B,0xBE,0xA6, | ||
69 | 0x3B,0x13,0x9B,0x22,0x51,0x4A,0x08,0x79,0x8E,0x34,0x04,0xDD, | ||
70 | 0xEF,0x95,0x19,0xB3,0xCD,0x3A,0x43,0x1B,0x30,0x2B,0x0A,0x6D, | ||
71 | 0xF2,0x5F,0x14,0x37,0x4F,0xE1,0x35,0x6D,0x6D,0x51,0xC2,0x45, | ||
72 | 0xE4,0x85,0xB5,0x76,0x62,0x5E,0x7E,0xC6,0xF4,0x4C,0x42,0xE9, | ||
73 | 0xA6,0x37,0xED,0x6B,0x0B,0xFF,0x5C,0xB6,0xF4,0x06,0xB7,0xED, | ||
74 | 0xEE,0x38,0x6B,0xFB,0x5A,0x89,0x9F,0xA5,0xAE,0x9F,0x24,0x11, | ||
75 | 0x7C,0x4B,0x1F,0xE6,0x49,0x28,0x66,0x51,0xEC,0xE4,0x5B,0x3D, | ||
76 | 0xC2,0x00,0x7C,0xB8,0xA1,0x63,0xBF,0x05,0x98,0xDA,0x48,0x36, | ||
77 | 0x1C,0x55,0xD3,0x9A,0x69,0x16,0x3F,0xA8,0xFD,0x24,0xCF,0x5F, | ||
78 | 0x83,0x65,0x5D,0x23,0xDC,0xA3,0xAD,0x96,0x1C,0x62,0xF3,0x56, | ||
79 | 0x20,0x85,0x52,0xBB,0x9E,0xD5,0x29,0x07,0x70,0x96,0x96,0x6D, | ||
80 | 0x67,0x0C,0x35,0x4E,0x4A,0xBC,0x98,0x04,0xF1,0x74,0x6C,0x08, | ||
81 | 0xCA,0x23,0x73,0x27,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, | ||
82 | }; | ||
83 | return BN_bin2bn(RFC3526_PRIME_1536,sizeof(RFC3526_PRIME_1536),bn); | ||
84 | } | ||
85 | |||
86 | /* "2048-bit MODP Group" from RFC3526, Section 3. | ||
87 | * | ||
88 | * The prime is: 2^2048 - 2^1984 - 1 + 2^64 * { [2^1918 pi] + 124476 } | ||
89 | * | ||
90 | * RFC3526 specifies a generator of 2. | ||
91 | */ | ||
92 | |||
93 | BIGNUM *get_rfc3526_prime_2048(BIGNUM *bn) | ||
94 | { | ||
95 | static const unsigned char RFC3526_PRIME_2048[]={ | ||
96 | 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC9,0x0F,0xDA,0xA2, | ||
97 | 0x21,0x68,0xC2,0x34,0xC4,0xC6,0x62,0x8B,0x80,0xDC,0x1C,0xD1, | ||
98 | 0x29,0x02,0x4E,0x08,0x8A,0x67,0xCC,0x74,0x02,0x0B,0xBE,0xA6, | ||
99 | 0x3B,0x13,0x9B,0x22,0x51,0x4A,0x08,0x79,0x8E,0x34,0x04,0xDD, | ||
100 | 0xEF,0x95,0x19,0xB3,0xCD,0x3A,0x43,0x1B,0x30,0x2B,0x0A,0x6D, | ||
101 | 0xF2,0x5F,0x14,0x37,0x4F,0xE1,0x35,0x6D,0x6D,0x51,0xC2,0x45, | ||
102 | 0xE4,0x85,0xB5,0x76,0x62,0x5E,0x7E,0xC6,0xF4,0x4C,0x42,0xE9, | ||
103 | 0xA6,0x37,0xED,0x6B,0x0B,0xFF,0x5C,0xB6,0xF4,0x06,0xB7,0xED, | ||
104 | 0xEE,0x38,0x6B,0xFB,0x5A,0x89,0x9F,0xA5,0xAE,0x9F,0x24,0x11, | ||
105 | 0x7C,0x4B,0x1F,0xE6,0x49,0x28,0x66,0x51,0xEC,0xE4,0x5B,0x3D, | ||
106 | 0xC2,0x00,0x7C,0xB8,0xA1,0x63,0xBF,0x05,0x98,0xDA,0x48,0x36, | ||
107 | 0x1C,0x55,0xD3,0x9A,0x69,0x16,0x3F,0xA8,0xFD,0x24,0xCF,0x5F, | ||
108 | 0x83,0x65,0x5D,0x23,0xDC,0xA3,0xAD,0x96,0x1C,0x62,0xF3,0x56, | ||
109 | 0x20,0x85,0x52,0xBB,0x9E,0xD5,0x29,0x07,0x70,0x96,0x96,0x6D, | ||
110 | 0x67,0x0C,0x35,0x4E,0x4A,0xBC,0x98,0x04,0xF1,0x74,0x6C,0x08, | ||
111 | 0xCA,0x18,0x21,0x7C,0x32,0x90,0x5E,0x46,0x2E,0x36,0xCE,0x3B, | ||
112 | 0xE3,0x9E,0x77,0x2C,0x18,0x0E,0x86,0x03,0x9B,0x27,0x83,0xA2, | ||
113 | 0xEC,0x07,0xA2,0x8F,0xB5,0xC5,0x5D,0xF0,0x6F,0x4C,0x52,0xC9, | ||
114 | 0xDE,0x2B,0xCB,0xF6,0x95,0x58,0x17,0x18,0x39,0x95,0x49,0x7C, | ||
115 | 0xEA,0x95,0x6A,0xE5,0x15,0xD2,0x26,0x18,0x98,0xFA,0x05,0x10, | ||
116 | 0x15,0x72,0x8E,0x5A,0x8A,0xAC,0xAA,0x68,0xFF,0xFF,0xFF,0xFF, | ||
117 | 0xFF,0xFF,0xFF,0xFF, | ||
118 | }; | ||
119 | return BN_bin2bn(RFC3526_PRIME_2048,sizeof(RFC3526_PRIME_2048),bn); | ||
120 | } | ||
121 | |||
122 | /* "3072-bit MODP Group" from RFC3526, Section 4. | ||
123 | * | ||
124 | * The prime is: 2^3072 - 2^3008 - 1 + 2^64 * { [2^2942 pi] + 1690314 } | ||
125 | * | ||
126 | * RFC3526 specifies a generator of 2. | ||
127 | */ | ||
128 | |||
129 | BIGNUM *get_rfc3526_prime_3072(BIGNUM *bn) | ||
130 | { | ||
131 | static const unsigned char RFC3526_PRIME_3072[]={ | ||
132 | 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC9,0x0F,0xDA,0xA2, | ||
133 | 0x21,0x68,0xC2,0x34,0xC4,0xC6,0x62,0x8B,0x80,0xDC,0x1C,0xD1, | ||
134 | 0x29,0x02,0x4E,0x08,0x8A,0x67,0xCC,0x74,0x02,0x0B,0xBE,0xA6, | ||
135 | 0x3B,0x13,0x9B,0x22,0x51,0x4A,0x08,0x79,0x8E,0x34,0x04,0xDD, | ||
136 | 0xEF,0x95,0x19,0xB3,0xCD,0x3A,0x43,0x1B,0x30,0x2B,0x0A,0x6D, | ||
137 | 0xF2,0x5F,0x14,0x37,0x4F,0xE1,0x35,0x6D,0x6D,0x51,0xC2,0x45, | ||
138 | 0xE4,0x85,0xB5,0x76,0x62,0x5E,0x7E,0xC6,0xF4,0x4C,0x42,0xE9, | ||
139 | 0xA6,0x37,0xED,0x6B,0x0B,0xFF,0x5C,0xB6,0xF4,0x06,0xB7,0xED, | ||
140 | 0xEE,0x38,0x6B,0xFB,0x5A,0x89,0x9F,0xA5,0xAE,0x9F,0x24,0x11, | ||
141 | 0x7C,0x4B,0x1F,0xE6,0x49,0x28,0x66,0x51,0xEC,0xE4,0x5B,0x3D, | ||
142 | 0xC2,0x00,0x7C,0xB8,0xA1,0x63,0xBF,0x05,0x98,0xDA,0x48,0x36, | ||
143 | 0x1C,0x55,0xD3,0x9A,0x69,0x16,0x3F,0xA8,0xFD,0x24,0xCF,0x5F, | ||
144 | 0x83,0x65,0x5D,0x23,0xDC,0xA3,0xAD,0x96,0x1C,0x62,0xF3,0x56, | ||
145 | 0x20,0x85,0x52,0xBB,0x9E,0xD5,0x29,0x07,0x70,0x96,0x96,0x6D, | ||
146 | 0x67,0x0C,0x35,0x4E,0x4A,0xBC,0x98,0x04,0xF1,0x74,0x6C,0x08, | ||
147 | 0xCA,0x18,0x21,0x7C,0x32,0x90,0x5E,0x46,0x2E,0x36,0xCE,0x3B, | ||
148 | 0xE3,0x9E,0x77,0x2C,0x18,0x0E,0x86,0x03,0x9B,0x27,0x83,0xA2, | ||
149 | 0xEC,0x07,0xA2,0x8F,0xB5,0xC5,0x5D,0xF0,0x6F,0x4C,0x52,0xC9, | ||
150 | 0xDE,0x2B,0xCB,0xF6,0x95,0x58,0x17,0x18,0x39,0x95,0x49,0x7C, | ||
151 | 0xEA,0x95,0x6A,0xE5,0x15,0xD2,0x26,0x18,0x98,0xFA,0x05,0x10, | ||
152 | 0x15,0x72,0x8E,0x5A,0x8A,0xAA,0xC4,0x2D,0xAD,0x33,0x17,0x0D, | ||
153 | 0x04,0x50,0x7A,0x33,0xA8,0x55,0x21,0xAB,0xDF,0x1C,0xBA,0x64, | ||
154 | 0xEC,0xFB,0x85,0x04,0x58,0xDB,0xEF,0x0A,0x8A,0xEA,0x71,0x57, | ||
155 | 0x5D,0x06,0x0C,0x7D,0xB3,0x97,0x0F,0x85,0xA6,0xE1,0xE4,0xC7, | ||
156 | 0xAB,0xF5,0xAE,0x8C,0xDB,0x09,0x33,0xD7,0x1E,0x8C,0x94,0xE0, | ||
157 | 0x4A,0x25,0x61,0x9D,0xCE,0xE3,0xD2,0x26,0x1A,0xD2,0xEE,0x6B, | ||
158 | 0xF1,0x2F,0xFA,0x06,0xD9,0x8A,0x08,0x64,0xD8,0x76,0x02,0x73, | ||
159 | 0x3E,0xC8,0x6A,0x64,0x52,0x1F,0x2B,0x18,0x17,0x7B,0x20,0x0C, | ||
160 | 0xBB,0xE1,0x17,0x57,0x7A,0x61,0x5D,0x6C,0x77,0x09,0x88,0xC0, | ||
161 | 0xBA,0xD9,0x46,0xE2,0x08,0xE2,0x4F,0xA0,0x74,0xE5,0xAB,0x31, | ||
162 | 0x43,0xDB,0x5B,0xFC,0xE0,0xFD,0x10,0x8E,0x4B,0x82,0xD1,0x20, | ||
163 | 0xA9,0x3A,0xD2,0xCA,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, | ||
164 | }; | ||
165 | return BN_bin2bn(RFC3526_PRIME_3072,sizeof(RFC3526_PRIME_3072),bn); | ||
166 | } | ||
167 | |||
168 | /* "4096-bit MODP Group" from RFC3526, Section 5. | ||
169 | * | ||
170 | * The prime is: 2^4096 - 2^4032 - 1 + 2^64 * { [2^3966 pi] + 240904 } | ||
171 | * | ||
172 | * RFC3526 specifies a generator of 2. | ||
173 | */ | ||
174 | |||
175 | BIGNUM *get_rfc3526_prime_4096(BIGNUM *bn) | ||
176 | { | ||
177 | static const unsigned char RFC3526_PRIME_4096[]={ | ||
178 | 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC9,0x0F,0xDA,0xA2, | ||
179 | 0x21,0x68,0xC2,0x34,0xC4,0xC6,0x62,0x8B,0x80,0xDC,0x1C,0xD1, | ||
180 | 0x29,0x02,0x4E,0x08,0x8A,0x67,0xCC,0x74,0x02,0x0B,0xBE,0xA6, | ||
181 | 0x3B,0x13,0x9B,0x22,0x51,0x4A,0x08,0x79,0x8E,0x34,0x04,0xDD, | ||
182 | 0xEF,0x95,0x19,0xB3,0xCD,0x3A,0x43,0x1B,0x30,0x2B,0x0A,0x6D, | ||
183 | 0xF2,0x5F,0x14,0x37,0x4F,0xE1,0x35,0x6D,0x6D,0x51,0xC2,0x45, | ||
184 | 0xE4,0x85,0xB5,0x76,0x62,0x5E,0x7E,0xC6,0xF4,0x4C,0x42,0xE9, | ||
185 | 0xA6,0x37,0xED,0x6B,0x0B,0xFF,0x5C,0xB6,0xF4,0x06,0xB7,0xED, | ||
186 | 0xEE,0x38,0x6B,0xFB,0x5A,0x89,0x9F,0xA5,0xAE,0x9F,0x24,0x11, | ||
187 | 0x7C,0x4B,0x1F,0xE6,0x49,0x28,0x66,0x51,0xEC,0xE4,0x5B,0x3D, | ||
188 | 0xC2,0x00,0x7C,0xB8,0xA1,0x63,0xBF,0x05,0x98,0xDA,0x48,0x36, | ||
189 | 0x1C,0x55,0xD3,0x9A,0x69,0x16,0x3F,0xA8,0xFD,0x24,0xCF,0x5F, | ||
190 | 0x83,0x65,0x5D,0x23,0xDC,0xA3,0xAD,0x96,0x1C,0x62,0xF3,0x56, | ||
191 | 0x20,0x85,0x52,0xBB,0x9E,0xD5,0x29,0x07,0x70,0x96,0x96,0x6D, | ||
192 | 0x67,0x0C,0x35,0x4E,0x4A,0xBC,0x98,0x04,0xF1,0x74,0x6C,0x08, | ||
193 | 0xCA,0x18,0x21,0x7C,0x32,0x90,0x5E,0x46,0x2E,0x36,0xCE,0x3B, | ||
194 | 0xE3,0x9E,0x77,0x2C,0x18,0x0E,0x86,0x03,0x9B,0x27,0x83,0xA2, | ||
195 | 0xEC,0x07,0xA2,0x8F,0xB5,0xC5,0x5D,0xF0,0x6F,0x4C,0x52,0xC9, | ||
196 | 0xDE,0x2B,0xCB,0xF6,0x95,0x58,0x17,0x18,0x39,0x95,0x49,0x7C, | ||
197 | 0xEA,0x95,0x6A,0xE5,0x15,0xD2,0x26,0x18,0x98,0xFA,0x05,0x10, | ||
198 | 0x15,0x72,0x8E,0x5A,0x8A,0xAA,0xC4,0x2D,0xAD,0x33,0x17,0x0D, | ||
199 | 0x04,0x50,0x7A,0x33,0xA8,0x55,0x21,0xAB,0xDF,0x1C,0xBA,0x64, | ||
200 | 0xEC,0xFB,0x85,0x04,0x58,0xDB,0xEF,0x0A,0x8A,0xEA,0x71,0x57, | ||
201 | 0x5D,0x06,0x0C,0x7D,0xB3,0x97,0x0F,0x85,0xA6,0xE1,0xE4,0xC7, | ||
202 | 0xAB,0xF5,0xAE,0x8C,0xDB,0x09,0x33,0xD7,0x1E,0x8C,0x94,0xE0, | ||
203 | 0x4A,0x25,0x61,0x9D,0xCE,0xE3,0xD2,0x26,0x1A,0xD2,0xEE,0x6B, | ||
204 | 0xF1,0x2F,0xFA,0x06,0xD9,0x8A,0x08,0x64,0xD8,0x76,0x02,0x73, | ||
205 | 0x3E,0xC8,0x6A,0x64,0x52,0x1F,0x2B,0x18,0x17,0x7B,0x20,0x0C, | ||
206 | 0xBB,0xE1,0x17,0x57,0x7A,0x61,0x5D,0x6C,0x77,0x09,0x88,0xC0, | ||
207 | 0xBA,0xD9,0x46,0xE2,0x08,0xE2,0x4F,0xA0,0x74,0xE5,0xAB,0x31, | ||
208 | 0x43,0xDB,0x5B,0xFC,0xE0,0xFD,0x10,0x8E,0x4B,0x82,0xD1,0x20, | ||
209 | 0xA9,0x21,0x08,0x01,0x1A,0x72,0x3C,0x12,0xA7,0x87,0xE6,0xD7, | ||
210 | 0x88,0x71,0x9A,0x10,0xBD,0xBA,0x5B,0x26,0x99,0xC3,0x27,0x18, | ||
211 | 0x6A,0xF4,0xE2,0x3C,0x1A,0x94,0x68,0x34,0xB6,0x15,0x0B,0xDA, | ||
212 | 0x25,0x83,0xE9,0xCA,0x2A,0xD4,0x4C,0xE8,0xDB,0xBB,0xC2,0xDB, | ||
213 | 0x04,0xDE,0x8E,0xF9,0x2E,0x8E,0xFC,0x14,0x1F,0xBE,0xCA,0xA6, | ||
214 | 0x28,0x7C,0x59,0x47,0x4E,0x6B,0xC0,0x5D,0x99,0xB2,0x96,0x4F, | ||
215 | 0xA0,0x90,0xC3,0xA2,0x23,0x3B,0xA1,0x86,0x51,0x5B,0xE7,0xED, | ||
216 | 0x1F,0x61,0x29,0x70,0xCE,0xE2,0xD7,0xAF,0xB8,0x1B,0xDD,0x76, | ||
217 | 0x21,0x70,0x48,0x1C,0xD0,0x06,0x91,0x27,0xD5,0xB0,0x5A,0xA9, | ||
218 | 0x93,0xB4,0xEA,0x98,0x8D,0x8F,0xDD,0xC1,0x86,0xFF,0xB7,0xDC, | ||
219 | 0x90,0xA6,0xC0,0x8F,0x4D,0xF4,0x35,0xC9,0x34,0x06,0x31,0x99, | ||
220 | 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, | ||
221 | }; | ||
222 | return BN_bin2bn(RFC3526_PRIME_4096,sizeof(RFC3526_PRIME_4096),bn); | ||
223 | } | ||
224 | |||
225 | /* "6144-bit MODP Group" from RFC3526, Section 6. | ||
226 | * | ||
227 | * The prime is: 2^6144 - 2^6080 - 1 + 2^64 * { [2^6014 pi] + 929484 } | ||
228 | * | ||
229 | * RFC3526 specifies a generator of 2. | ||
230 | */ | ||
231 | |||
232 | BIGNUM *get_rfc3526_prime_6144(BIGNUM *bn) | ||
233 | { | ||
234 | static const unsigned char RFC3526_PRIME_6144[]={ | ||
235 | 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC9,0x0F,0xDA,0xA2, | ||
236 | 0x21,0x68,0xC2,0x34,0xC4,0xC6,0x62,0x8B,0x80,0xDC,0x1C,0xD1, | ||
237 | 0x29,0x02,0x4E,0x08,0x8A,0x67,0xCC,0x74,0x02,0x0B,0xBE,0xA6, | ||
238 | 0x3B,0x13,0x9B,0x22,0x51,0x4A,0x08,0x79,0x8E,0x34,0x04,0xDD, | ||
239 | 0xEF,0x95,0x19,0xB3,0xCD,0x3A,0x43,0x1B,0x30,0x2B,0x0A,0x6D, | ||
240 | 0xF2,0x5F,0x14,0x37,0x4F,0xE1,0x35,0x6D,0x6D,0x51,0xC2,0x45, | ||
241 | 0xE4,0x85,0xB5,0x76,0x62,0x5E,0x7E,0xC6,0xF4,0x4C,0x42,0xE9, | ||
242 | 0xA6,0x37,0xED,0x6B,0x0B,0xFF,0x5C,0xB6,0xF4,0x06,0xB7,0xED, | ||
243 | 0xEE,0x38,0x6B,0xFB,0x5A,0x89,0x9F,0xA5,0xAE,0x9F,0x24,0x11, | ||
244 | 0x7C,0x4B,0x1F,0xE6,0x49,0x28,0x66,0x51,0xEC,0xE4,0x5B,0x3D, | ||
245 | 0xC2,0x00,0x7C,0xB8,0xA1,0x63,0xBF,0x05,0x98,0xDA,0x48,0x36, | ||
246 | 0x1C,0x55,0xD3,0x9A,0x69,0x16,0x3F,0xA8,0xFD,0x24,0xCF,0x5F, | ||
247 | 0x83,0x65,0x5D,0x23,0xDC,0xA3,0xAD,0x96,0x1C,0x62,0xF3,0x56, | ||
248 | 0x20,0x85,0x52,0xBB,0x9E,0xD5,0x29,0x07,0x70,0x96,0x96,0x6D, | ||
249 | 0x67,0x0C,0x35,0x4E,0x4A,0xBC,0x98,0x04,0xF1,0x74,0x6C,0x08, | ||
250 | 0xCA,0x18,0x21,0x7C,0x32,0x90,0x5E,0x46,0x2E,0x36,0xCE,0x3B, | ||
251 | 0xE3,0x9E,0x77,0x2C,0x18,0x0E,0x86,0x03,0x9B,0x27,0x83,0xA2, | ||
252 | 0xEC,0x07,0xA2,0x8F,0xB5,0xC5,0x5D,0xF0,0x6F,0x4C,0x52,0xC9, | ||
253 | 0xDE,0x2B,0xCB,0xF6,0x95,0x58,0x17,0x18,0x39,0x95,0x49,0x7C, | ||
254 | 0xEA,0x95,0x6A,0xE5,0x15,0xD2,0x26,0x18,0x98,0xFA,0x05,0x10, | ||
255 | 0x15,0x72,0x8E,0x5A,0x8A,0xAA,0xC4,0x2D,0xAD,0x33,0x17,0x0D, | ||
256 | 0x04,0x50,0x7A,0x33,0xA8,0x55,0x21,0xAB,0xDF,0x1C,0xBA,0x64, | ||
257 | 0xEC,0xFB,0x85,0x04,0x58,0xDB,0xEF,0x0A,0x8A,0xEA,0x71,0x57, | ||
258 | 0x5D,0x06,0x0C,0x7D,0xB3,0x97,0x0F,0x85,0xA6,0xE1,0xE4,0xC7, | ||
259 | 0xAB,0xF5,0xAE,0x8C,0xDB,0x09,0x33,0xD7,0x1E,0x8C,0x94,0xE0, | ||
260 | 0x4A,0x25,0x61,0x9D,0xCE,0xE3,0xD2,0x26,0x1A,0xD2,0xEE,0x6B, | ||
261 | 0xF1,0x2F,0xFA,0x06,0xD9,0x8A,0x08,0x64,0xD8,0x76,0x02,0x73, | ||
262 | 0x3E,0xC8,0x6A,0x64,0x52,0x1F,0x2B,0x18,0x17,0x7B,0x20,0x0C, | ||
263 | 0xBB,0xE1,0x17,0x57,0x7A,0x61,0x5D,0x6C,0x77,0x09,0x88,0xC0, | ||
264 | 0xBA,0xD9,0x46,0xE2,0x08,0xE2,0x4F,0xA0,0x74,0xE5,0xAB,0x31, | ||
265 | 0x43,0xDB,0x5B,0xFC,0xE0,0xFD,0x10,0x8E,0x4B,0x82,0xD1,0x20, | ||
266 | 0xA9,0x21,0x08,0x01,0x1A,0x72,0x3C,0x12,0xA7,0x87,0xE6,0xD7, | ||
267 | 0x88,0x71,0x9A,0x10,0xBD,0xBA,0x5B,0x26,0x99,0xC3,0x27,0x18, | ||
268 | 0x6A,0xF4,0xE2,0x3C,0x1A,0x94,0x68,0x34,0xB6,0x15,0x0B,0xDA, | ||
269 | 0x25,0x83,0xE9,0xCA,0x2A,0xD4,0x4C,0xE8,0xDB,0xBB,0xC2,0xDB, | ||
270 | 0x04,0xDE,0x8E,0xF9,0x2E,0x8E,0xFC,0x14,0x1F,0xBE,0xCA,0xA6, | ||
271 | 0x28,0x7C,0x59,0x47,0x4E,0x6B,0xC0,0x5D,0x99,0xB2,0x96,0x4F, | ||
272 | 0xA0,0x90,0xC3,0xA2,0x23,0x3B,0xA1,0x86,0x51,0x5B,0xE7,0xED, | ||
273 | 0x1F,0x61,0x29,0x70,0xCE,0xE2,0xD7,0xAF,0xB8,0x1B,0xDD,0x76, | ||
274 | 0x21,0x70,0x48,0x1C,0xD0,0x06,0x91,0x27,0xD5,0xB0,0x5A,0xA9, | ||
275 | 0x93,0xB4,0xEA,0x98,0x8D,0x8F,0xDD,0xC1,0x86,0xFF,0xB7,0xDC, | ||
276 | 0x90,0xA6,0xC0,0x8F,0x4D,0xF4,0x35,0xC9,0x34,0x02,0x84,0x92, | ||
277 | 0x36,0xC3,0xFA,0xB4,0xD2,0x7C,0x70,0x26,0xC1,0xD4,0xDC,0xB2, | ||
278 | 0x60,0x26,0x46,0xDE,0xC9,0x75,0x1E,0x76,0x3D,0xBA,0x37,0xBD, | ||
279 | 0xF8,0xFF,0x94,0x06,0xAD,0x9E,0x53,0x0E,0xE5,0xDB,0x38,0x2F, | ||
280 | 0x41,0x30,0x01,0xAE,0xB0,0x6A,0x53,0xED,0x90,0x27,0xD8,0x31, | ||
281 | 0x17,0x97,0x27,0xB0,0x86,0x5A,0x89,0x18,0xDA,0x3E,0xDB,0xEB, | ||
282 | 0xCF,0x9B,0x14,0xED,0x44,0xCE,0x6C,0xBA,0xCE,0xD4,0xBB,0x1B, | ||
283 | 0xDB,0x7F,0x14,0x47,0xE6,0xCC,0x25,0x4B,0x33,0x20,0x51,0x51, | ||
284 | 0x2B,0xD7,0xAF,0x42,0x6F,0xB8,0xF4,0x01,0x37,0x8C,0xD2,0xBF, | ||
285 | 0x59,0x83,0xCA,0x01,0xC6,0x4B,0x92,0xEC,0xF0,0x32,0xEA,0x15, | ||
286 | 0xD1,0x72,0x1D,0x03,0xF4,0x82,0xD7,0xCE,0x6E,0x74,0xFE,0xF6, | ||
287 | 0xD5,0x5E,0x70,0x2F,0x46,0x98,0x0C,0x82,0xB5,0xA8,0x40,0x31, | ||
288 | 0x90,0x0B,0x1C,0x9E,0x59,0xE7,0xC9,0x7F,0xBE,0xC7,0xE8,0xF3, | ||
289 | 0x23,0xA9,0x7A,0x7E,0x36,0xCC,0x88,0xBE,0x0F,0x1D,0x45,0xB7, | ||
290 | 0xFF,0x58,0x5A,0xC5,0x4B,0xD4,0x07,0xB2,0x2B,0x41,0x54,0xAA, | ||
291 | 0xCC,0x8F,0x6D,0x7E,0xBF,0x48,0xE1,0xD8,0x14,0xCC,0x5E,0xD2, | ||
292 | 0x0F,0x80,0x37,0xE0,0xA7,0x97,0x15,0xEE,0xF2,0x9B,0xE3,0x28, | ||
293 | 0x06,0xA1,0xD5,0x8B,0xB7,0xC5,0xDA,0x76,0xF5,0x50,0xAA,0x3D, | ||
294 | 0x8A,0x1F,0xBF,0xF0,0xEB,0x19,0xCC,0xB1,0xA3,0x13,0xD5,0x5C, | ||
295 | 0xDA,0x56,0xC9,0xEC,0x2E,0xF2,0x96,0x32,0x38,0x7F,0xE8,0xD7, | ||
296 | 0x6E,0x3C,0x04,0x68,0x04,0x3E,0x8F,0x66,0x3F,0x48,0x60,0xEE, | ||
297 | 0x12,0xBF,0x2D,0x5B,0x0B,0x74,0x74,0xD6,0xE6,0x94,0xF9,0x1E, | ||
298 | 0x6D,0xCC,0x40,0x24,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, | ||
299 | }; | ||
300 | return BN_bin2bn(RFC3526_PRIME_6144,sizeof(RFC3526_PRIME_6144),bn); | ||
301 | } | ||
302 | |||
303 | /* "8192-bit MODP Group" from RFC3526, Section 7. | ||
304 | * | ||
305 | * The prime is: 2^8192 - 2^8128 - 1 + 2^64 * { [2^8062 pi] + 4743158 } | ||
306 | * | ||
307 | * RFC3526 specifies a generator of 2. | ||
308 | */ | ||
309 | |||
310 | BIGNUM *get_rfc3526_prime_8192(BIGNUM *bn) | ||
311 | { | ||
312 | static const unsigned char RFC3526_PRIME_8192[]={ | ||
313 | 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC9,0x0F,0xDA,0xA2, | ||
314 | 0x21,0x68,0xC2,0x34,0xC4,0xC6,0x62,0x8B,0x80,0xDC,0x1C,0xD1, | ||
315 | 0x29,0x02,0x4E,0x08,0x8A,0x67,0xCC,0x74,0x02,0x0B,0xBE,0xA6, | ||
316 | 0x3B,0x13,0x9B,0x22,0x51,0x4A,0x08,0x79,0x8E,0x34,0x04,0xDD, | ||
317 | 0xEF,0x95,0x19,0xB3,0xCD,0x3A,0x43,0x1B,0x30,0x2B,0x0A,0x6D, | ||
318 | 0xF2,0x5F,0x14,0x37,0x4F,0xE1,0x35,0x6D,0x6D,0x51,0xC2,0x45, | ||
319 | 0xE4,0x85,0xB5,0x76,0x62,0x5E,0x7E,0xC6,0xF4,0x4C,0x42,0xE9, | ||
320 | 0xA6,0x37,0xED,0x6B,0x0B,0xFF,0x5C,0xB6,0xF4,0x06,0xB7,0xED, | ||
321 | 0xEE,0x38,0x6B,0xFB,0x5A,0x89,0x9F,0xA5,0xAE,0x9F,0x24,0x11, | ||
322 | 0x7C,0x4B,0x1F,0xE6,0x49,0x28,0x66,0x51,0xEC,0xE4,0x5B,0x3D, | ||
323 | 0xC2,0x00,0x7C,0xB8,0xA1,0x63,0xBF,0x05,0x98,0xDA,0x48,0x36, | ||
324 | 0x1C,0x55,0xD3,0x9A,0x69,0x16,0x3F,0xA8,0xFD,0x24,0xCF,0x5F, | ||
325 | 0x83,0x65,0x5D,0x23,0xDC,0xA3,0xAD,0x96,0x1C,0x62,0xF3,0x56, | ||
326 | 0x20,0x85,0x52,0xBB,0x9E,0xD5,0x29,0x07,0x70,0x96,0x96,0x6D, | ||
327 | 0x67,0x0C,0x35,0x4E,0x4A,0xBC,0x98,0x04,0xF1,0x74,0x6C,0x08, | ||
328 | 0xCA,0x18,0x21,0x7C,0x32,0x90,0x5E,0x46,0x2E,0x36,0xCE,0x3B, | ||
329 | 0xE3,0x9E,0x77,0x2C,0x18,0x0E,0x86,0x03,0x9B,0x27,0x83,0xA2, | ||
330 | 0xEC,0x07,0xA2,0x8F,0xB5,0xC5,0x5D,0xF0,0x6F,0x4C,0x52,0xC9, | ||
331 | 0xDE,0x2B,0xCB,0xF6,0x95,0x58,0x17,0x18,0x39,0x95,0x49,0x7C, | ||
332 | 0xEA,0x95,0x6A,0xE5,0x15,0xD2,0x26,0x18,0x98,0xFA,0x05,0x10, | ||
333 | 0x15,0x72,0x8E,0x5A,0x8A,0xAA,0xC4,0x2D,0xAD,0x33,0x17,0x0D, | ||
334 | 0x04,0x50,0x7A,0x33,0xA8,0x55,0x21,0xAB,0xDF,0x1C,0xBA,0x64, | ||
335 | 0xEC,0xFB,0x85,0x04,0x58,0xDB,0xEF,0x0A,0x8A,0xEA,0x71,0x57, | ||
336 | 0x5D,0x06,0x0C,0x7D,0xB3,0x97,0x0F,0x85,0xA6,0xE1,0xE4,0xC7, | ||
337 | 0xAB,0xF5,0xAE,0x8C,0xDB,0x09,0x33,0xD7,0x1E,0x8C,0x94,0xE0, | ||
338 | 0x4A,0x25,0x61,0x9D,0xCE,0xE3,0xD2,0x26,0x1A,0xD2,0xEE,0x6B, | ||
339 | 0xF1,0x2F,0xFA,0x06,0xD9,0x8A,0x08,0x64,0xD8,0x76,0x02,0x73, | ||
340 | 0x3E,0xC8,0x6A,0x64,0x52,0x1F,0x2B,0x18,0x17,0x7B,0x20,0x0C, | ||
341 | 0xBB,0xE1,0x17,0x57,0x7A,0x61,0x5D,0x6C,0x77,0x09,0x88,0xC0, | ||
342 | 0xBA,0xD9,0x46,0xE2,0x08,0xE2,0x4F,0xA0,0x74,0xE5,0xAB,0x31, | ||
343 | 0x43,0xDB,0x5B,0xFC,0xE0,0xFD,0x10,0x8E,0x4B,0x82,0xD1,0x20, | ||
344 | 0xA9,0x21,0x08,0x01,0x1A,0x72,0x3C,0x12,0xA7,0x87,0xE6,0xD7, | ||
345 | 0x88,0x71,0x9A,0x10,0xBD,0xBA,0x5B,0x26,0x99,0xC3,0x27,0x18, | ||
346 | 0x6A,0xF4,0xE2,0x3C,0x1A,0x94,0x68,0x34,0xB6,0x15,0x0B,0xDA, | ||
347 | 0x25,0x83,0xE9,0xCA,0x2A,0xD4,0x4C,0xE8,0xDB,0xBB,0xC2,0xDB, | ||
348 | 0x04,0xDE,0x8E,0xF9,0x2E,0x8E,0xFC,0x14,0x1F,0xBE,0xCA,0xA6, | ||
349 | 0x28,0x7C,0x59,0x47,0x4E,0x6B,0xC0,0x5D,0x99,0xB2,0x96,0x4F, | ||
350 | 0xA0,0x90,0xC3,0xA2,0x23,0x3B,0xA1,0x86,0x51,0x5B,0xE7,0xED, | ||
351 | 0x1F,0x61,0x29,0x70,0xCE,0xE2,0xD7,0xAF,0xB8,0x1B,0xDD,0x76, | ||
352 | 0x21,0x70,0x48,0x1C,0xD0,0x06,0x91,0x27,0xD5,0xB0,0x5A,0xA9, | ||
353 | 0x93,0xB4,0xEA,0x98,0x8D,0x8F,0xDD,0xC1,0x86,0xFF,0xB7,0xDC, | ||
354 | 0x90,0xA6,0xC0,0x8F,0x4D,0xF4,0x35,0xC9,0x34,0x02,0x84,0x92, | ||
355 | 0x36,0xC3,0xFA,0xB4,0xD2,0x7C,0x70,0x26,0xC1,0xD4,0xDC,0xB2, | ||
356 | 0x60,0x26,0x46,0xDE,0xC9,0x75,0x1E,0x76,0x3D,0xBA,0x37,0xBD, | ||
357 | 0xF8,0xFF,0x94,0x06,0xAD,0x9E,0x53,0x0E,0xE5,0xDB,0x38,0x2F, | ||
358 | 0x41,0x30,0x01,0xAE,0xB0,0x6A,0x53,0xED,0x90,0x27,0xD8,0x31, | ||
359 | 0x17,0x97,0x27,0xB0,0x86,0x5A,0x89,0x18,0xDA,0x3E,0xDB,0xEB, | ||
360 | 0xCF,0x9B,0x14,0xED,0x44,0xCE,0x6C,0xBA,0xCE,0xD4,0xBB,0x1B, | ||
361 | 0xDB,0x7F,0x14,0x47,0xE6,0xCC,0x25,0x4B,0x33,0x20,0x51,0x51, | ||
362 | 0x2B,0xD7,0xAF,0x42,0x6F,0xB8,0xF4,0x01,0x37,0x8C,0xD2,0xBF, | ||
363 | 0x59,0x83,0xCA,0x01,0xC6,0x4B,0x92,0xEC,0xF0,0x32,0xEA,0x15, | ||
364 | 0xD1,0x72,0x1D,0x03,0xF4,0x82,0xD7,0xCE,0x6E,0x74,0xFE,0xF6, | ||
365 | 0xD5,0x5E,0x70,0x2F,0x46,0x98,0x0C,0x82,0xB5,0xA8,0x40,0x31, | ||
366 | 0x90,0x0B,0x1C,0x9E,0x59,0xE7,0xC9,0x7F,0xBE,0xC7,0xE8,0xF3, | ||
367 | 0x23,0xA9,0x7A,0x7E,0x36,0xCC,0x88,0xBE,0x0F,0x1D,0x45,0xB7, | ||
368 | 0xFF,0x58,0x5A,0xC5,0x4B,0xD4,0x07,0xB2,0x2B,0x41,0x54,0xAA, | ||
369 | 0xCC,0x8F,0x6D,0x7E,0xBF,0x48,0xE1,0xD8,0x14,0xCC,0x5E,0xD2, | ||
370 | 0x0F,0x80,0x37,0xE0,0xA7,0x97,0x15,0xEE,0xF2,0x9B,0xE3,0x28, | ||
371 | 0x06,0xA1,0xD5,0x8B,0xB7,0xC5,0xDA,0x76,0xF5,0x50,0xAA,0x3D, | ||
372 | 0x8A,0x1F,0xBF,0xF0,0xEB,0x19,0xCC,0xB1,0xA3,0x13,0xD5,0x5C, | ||
373 | 0xDA,0x56,0xC9,0xEC,0x2E,0xF2,0x96,0x32,0x38,0x7F,0xE8,0xD7, | ||
374 | 0x6E,0x3C,0x04,0x68,0x04,0x3E,0x8F,0x66,0x3F,0x48,0x60,0xEE, | ||
375 | 0x12,0xBF,0x2D,0x5B,0x0B,0x74,0x74,0xD6,0xE6,0x94,0xF9,0x1E, | ||
376 | 0x6D,0xBE,0x11,0x59,0x74,0xA3,0x92,0x6F,0x12,0xFE,0xE5,0xE4, | ||
377 | 0x38,0x77,0x7C,0xB6,0xA9,0x32,0xDF,0x8C,0xD8,0xBE,0xC4,0xD0, | ||
378 | 0x73,0xB9,0x31,0xBA,0x3B,0xC8,0x32,0xB6,0x8D,0x9D,0xD3,0x00, | ||
379 | 0x74,0x1F,0xA7,0xBF,0x8A,0xFC,0x47,0xED,0x25,0x76,0xF6,0x93, | ||
380 | 0x6B,0xA4,0x24,0x66,0x3A,0xAB,0x63,0x9C,0x5A,0xE4,0xF5,0x68, | ||
381 | 0x34,0x23,0xB4,0x74,0x2B,0xF1,0xC9,0x78,0x23,0x8F,0x16,0xCB, | ||
382 | 0xE3,0x9D,0x65,0x2D,0xE3,0xFD,0xB8,0xBE,0xFC,0x84,0x8A,0xD9, | ||
383 | 0x22,0x22,0x2E,0x04,0xA4,0x03,0x7C,0x07,0x13,0xEB,0x57,0xA8, | ||
384 | 0x1A,0x23,0xF0,0xC7,0x34,0x73,0xFC,0x64,0x6C,0xEA,0x30,0x6B, | ||
385 | 0x4B,0xCB,0xC8,0x86,0x2F,0x83,0x85,0xDD,0xFA,0x9D,0x4B,0x7F, | ||
386 | 0xA2,0xC0,0x87,0xE8,0x79,0x68,0x33,0x03,0xED,0x5B,0xDD,0x3A, | ||
387 | 0x06,0x2B,0x3C,0xF5,0xB3,0xA2,0x78,0xA6,0x6D,0x2A,0x13,0xF8, | ||
388 | 0x3F,0x44,0xF8,0x2D,0xDF,0x31,0x0E,0xE0,0x74,0xAB,0x6A,0x36, | ||
389 | 0x45,0x97,0xE8,0x99,0xA0,0x25,0x5D,0xC1,0x64,0xF3,0x1C,0xC5, | ||
390 | 0x08,0x46,0x85,0x1D,0xF9,0xAB,0x48,0x19,0x5D,0xED,0x7E,0xA1, | ||
391 | 0xB1,0xD5,0x10,0xBD,0x7E,0xE7,0x4D,0x73,0xFA,0xF3,0x6B,0xC3, | ||
392 | 0x1E,0xCF,0xA2,0x68,0x35,0x90,0x46,0xF4,0xEB,0x87,0x9F,0x92, | ||
393 | 0x40,0x09,0x43,0x8B,0x48,0x1C,0x6C,0xD7,0x88,0x9A,0x00,0x2E, | ||
394 | 0xD5,0xEE,0x38,0x2B,0xC9,0x19,0x0D,0xA6,0xFC,0x02,0x6E,0x47, | ||
395 | 0x95,0x58,0xE4,0x47,0x56,0x77,0xE9,0xAA,0x9E,0x30,0x50,0xE2, | ||
396 | 0x76,0x56,0x94,0xDF,0xC8,0x1F,0x56,0xE8,0x80,0xB9,0x6E,0x71, | ||
397 | 0x60,0xC9,0x80,0xDD,0x98,0xED,0xD3,0xDF,0xFF,0xFF,0xFF,0xFF, | ||
398 | 0xFF,0xFF,0xFF,0xFF, | ||
399 | }; | ||
400 | return BN_bin2bn(RFC3526_PRIME_8192,sizeof(RFC3526_PRIME_8192),bn); | ||
401 | } | ||
402 | |||
diff --git a/src/lib/libcrypto/bn/bn_depr.c b/src/lib/libcrypto/bn/bn_depr.c new file mode 100644 index 0000000000..27535e4fca --- /dev/null +++ b/src/lib/libcrypto/bn/bn_depr.c | |||
@@ -0,0 +1,112 @@ | |||
1 | /* crypto/bn/bn_depr.c */ | ||
2 | /* ==================================================================== | ||
3 | * Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions | ||
7 | * are met: | ||
8 | * | ||
9 | * 1. Redistributions of source code must retain the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer. | ||
11 | * | ||
12 | * 2. Redistributions in binary form must reproduce the above copyright | ||
13 | * notice, this list of conditions and the following disclaimer in | ||
14 | * the documentation and/or other materials provided with the | ||
15 | * distribution. | ||
16 | * | ||
17 | * 3. All advertising materials mentioning features or use of this | ||
18 | * software must display the following acknowledgment: | ||
19 | * "This product includes software developed by the OpenSSL Project | ||
20 | * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" | ||
21 | * | ||
22 | * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to | ||
23 | * endorse or promote products derived from this software without | ||
24 | * prior written permission. For written permission, please contact | ||
25 | * openssl-core@openssl.org. | ||
26 | * | ||
27 | * 5. Products derived from this software may not be called "OpenSSL" | ||
28 | * nor may "OpenSSL" appear in their names without prior written | ||
29 | * permission of the OpenSSL Project. | ||
30 | * | ||
31 | * 6. Redistributions of any form whatsoever must retain the following | ||
32 | * acknowledgment: | ||
33 | * "This product includes software developed by the OpenSSL Project | ||
34 | * for use in the OpenSSL Toolkit (http://www.openssl.org/)" | ||
35 | * | ||
36 | * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY | ||
37 | * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
38 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | ||
39 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR | ||
40 | * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
41 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
42 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
43 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
44 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
45 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
46 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED | ||
47 | * OF THE POSSIBILITY OF SUCH DAMAGE. | ||
48 | * ==================================================================== | ||
49 | * | ||
50 | * This product includes cryptographic software written by Eric Young | ||
51 | * (eay@cryptsoft.com). This product includes software written by Tim | ||
52 | * Hudson (tjh@cryptsoft.com). | ||
53 | * | ||
54 | */ | ||
55 | |||
56 | /* Support for deprecated functions goes here - static linkage will only slurp | ||
57 | * this code if applications are using them directly. */ | ||
58 | |||
59 | #include <stdio.h> | ||
60 | #include <time.h> | ||
61 | #include "cryptlib.h" | ||
62 | #include "bn_lcl.h" | ||
63 | #include <openssl/rand.h> | ||
64 | |||
65 | static void *dummy=&dummy; | ||
66 | |||
67 | #ifndef OPENSSL_NO_DEPRECATED | ||
68 | BIGNUM *BN_generate_prime(BIGNUM *ret, int bits, int safe, | ||
69 | const BIGNUM *add, const BIGNUM *rem, | ||
70 | void (*callback)(int,int,void *), void *cb_arg) | ||
71 | { | ||
72 | BN_GENCB cb; | ||
73 | BIGNUM *rnd=NULL; | ||
74 | int found = 0; | ||
75 | |||
76 | BN_GENCB_set_old(&cb, callback, cb_arg); | ||
77 | |||
78 | if (ret == NULL) | ||
79 | { | ||
80 | if ((rnd=BN_new()) == NULL) goto err; | ||
81 | } | ||
82 | else | ||
83 | rnd=ret; | ||
84 | if(!BN_generate_prime_ex(rnd, bits, safe, add, rem, &cb)) | ||
85 | goto err; | ||
86 | |||
87 | /* we have a prime :-) */ | ||
88 | found = 1; | ||
89 | err: | ||
90 | if (!found && (ret == NULL) && (rnd != NULL)) BN_free(rnd); | ||
91 | return(found ? rnd : NULL); | ||
92 | } | ||
93 | |||
94 | int BN_is_prime(const BIGNUM *a, int checks, void (*callback)(int,int,void *), | ||
95 | BN_CTX *ctx_passed, void *cb_arg) | ||
96 | { | ||
97 | BN_GENCB cb; | ||
98 | BN_GENCB_set_old(&cb, callback, cb_arg); | ||
99 | return BN_is_prime_ex(a, checks, ctx_passed, &cb); | ||
100 | } | ||
101 | |||
102 | int BN_is_prime_fasttest(const BIGNUM *a, int checks, | ||
103 | void (*callback)(int,int,void *), | ||
104 | BN_CTX *ctx_passed, void *cb_arg, | ||
105 | int do_trial_division) | ||
106 | { | ||
107 | BN_GENCB cb; | ||
108 | BN_GENCB_set_old(&cb, callback, cb_arg); | ||
109 | return BN_is_prime_fasttest_ex(a, checks, ctx_passed, | ||
110 | do_trial_division, &cb); | ||
111 | } | ||
112 | #endif | ||
diff --git a/src/lib/libcrypto/bn/bn_gf2m.c b/src/lib/libcrypto/bn/bn_gf2m.c new file mode 100644 index 0000000000..6a793857e1 --- /dev/null +++ b/src/lib/libcrypto/bn/bn_gf2m.c | |||
@@ -0,0 +1,1091 @@ | |||
1 | /* crypto/bn/bn_gf2m.c */ | ||
2 | /* ==================================================================== | ||
3 | * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. | ||
4 | * | ||
5 | * The Elliptic Curve Public-Key Crypto Library (ECC Code) included | ||
6 | * herein is developed by SUN MICROSYSTEMS, INC., and is contributed | ||
7 | * to the OpenSSL project. | ||
8 | * | ||
9 | * The ECC Code is licensed pursuant to the OpenSSL open source | ||
10 | * license provided below. | ||
11 | * | ||
12 | * In addition, Sun covenants to all licensees who provide a reciprocal | ||
13 | * covenant with respect to their own patents if any, not to sue under | ||
14 | * current and future patent claims necessarily infringed by the making, | ||
15 | * using, practicing, selling, offering for sale and/or otherwise | ||
16 | * disposing of the ECC Code as delivered hereunder (or portions thereof), | ||
17 | * provided that such covenant shall not apply: | ||
18 | * 1) for code that a licensee deletes from the ECC Code; | ||
19 | * 2) separates from the ECC Code; or | ||
20 | * 3) for infringements caused by: | ||
21 | * i) the modification of the ECC Code or | ||
22 | * ii) the combination of the ECC Code with other software or | ||
23 | * devices where such combination causes the infringement. | ||
24 | * | ||
25 | * The software is originally written by Sheueling Chang Shantz and | ||
26 | * Douglas Stebila of Sun Microsystems Laboratories. | ||
27 | * | ||
28 | */ | ||
29 | |||
30 | /* NOTE: This file is licensed pursuant to the OpenSSL license below | ||
31 | * and may be modified; but after modifications, the above covenant | ||
32 | * may no longer apply! In such cases, the corresponding paragraph | ||
33 | * ["In addition, Sun covenants ... causes the infringement."] and | ||
34 | * this note can be edited out; but please keep the Sun copyright | ||
35 | * notice and attribution. */ | ||
36 | |||
37 | /* ==================================================================== | ||
38 | * Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved. | ||
39 | * | ||
40 | * Redistribution and use in source and binary forms, with or without | ||
41 | * modification, are permitted provided that the following conditions | ||
42 | * are met: | ||
43 | * | ||
44 | * 1. Redistributions of source code must retain the above copyright | ||
45 | * notice, this list of conditions and the following disclaimer. | ||
46 | * | ||
47 | * 2. Redistributions in binary form must reproduce the above copyright | ||
48 | * notice, this list of conditions and the following disclaimer in | ||
49 | * the documentation and/or other materials provided with the | ||
50 | * distribution. | ||
51 | * | ||
52 | * 3. All advertising materials mentioning features or use of this | ||
53 | * software must display the following acknowledgment: | ||
54 | * "This product includes software developed by the OpenSSL Project | ||
55 | * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" | ||
56 | * | ||
57 | * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to | ||
58 | * endorse or promote products derived from this software without | ||
59 | * prior written permission. For written permission, please contact | ||
60 | * openssl-core@openssl.org. | ||
61 | * | ||
62 | * 5. Products derived from this software may not be called "OpenSSL" | ||
63 | * nor may "OpenSSL" appear in their names without prior written | ||
64 | * permission of the OpenSSL Project. | ||
65 | * | ||
66 | * 6. Redistributions of any form whatsoever must retain the following | ||
67 | * acknowledgment: | ||
68 | * "This product includes software developed by the OpenSSL Project | ||
69 | * for use in the OpenSSL Toolkit (http://www.openssl.org/)" | ||
70 | * | ||
71 | * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY | ||
72 | * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
73 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | ||
74 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR | ||
75 | * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
76 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
77 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
78 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
79 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
80 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
81 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED | ||
82 | * OF THE POSSIBILITY OF SUCH DAMAGE. | ||
83 | * ==================================================================== | ||
84 | * | ||
85 | * This product includes cryptographic software written by Eric Young | ||
86 | * (eay@cryptsoft.com). This product includes software written by Tim | ||
87 | * Hudson (tjh@cryptsoft.com). | ||
88 | * | ||
89 | */ | ||
90 | |||
91 | #include <assert.h> | ||
92 | #include <limits.h> | ||
93 | #include <stdio.h> | ||
94 | #include "cryptlib.h" | ||
95 | #include "bn_lcl.h" | ||
96 | |||
97 | /* Maximum number of iterations before BN_GF2m_mod_solve_quad_arr should fail. */ | ||
98 | #define MAX_ITERATIONS 50 | ||
99 | |||
100 | static const BN_ULONG SQR_tb[16] = | ||
101 | { 0, 1, 4, 5, 16, 17, 20, 21, | ||
102 | 64, 65, 68, 69, 80, 81, 84, 85 }; | ||
103 | /* Platform-specific macros to accelerate squaring. */ | ||
104 | #if defined(SIXTY_FOUR_BIT) || defined(SIXTY_FOUR_BIT_LONG) | ||
105 | #define SQR1(w) \ | ||
106 | SQR_tb[(w) >> 60 & 0xF] << 56 | SQR_tb[(w) >> 56 & 0xF] << 48 | \ | ||
107 | SQR_tb[(w) >> 52 & 0xF] << 40 | SQR_tb[(w) >> 48 & 0xF] << 32 | \ | ||
108 | SQR_tb[(w) >> 44 & 0xF] << 24 | SQR_tb[(w) >> 40 & 0xF] << 16 | \ | ||
109 | SQR_tb[(w) >> 36 & 0xF] << 8 | SQR_tb[(w) >> 32 & 0xF] | ||
110 | #define SQR0(w) \ | ||
111 | SQR_tb[(w) >> 28 & 0xF] << 56 | SQR_tb[(w) >> 24 & 0xF] << 48 | \ | ||
112 | SQR_tb[(w) >> 20 & 0xF] << 40 | SQR_tb[(w) >> 16 & 0xF] << 32 | \ | ||
113 | SQR_tb[(w) >> 12 & 0xF] << 24 | SQR_tb[(w) >> 8 & 0xF] << 16 | \ | ||
114 | SQR_tb[(w) >> 4 & 0xF] << 8 | SQR_tb[(w) & 0xF] | ||
115 | #endif | ||
116 | #ifdef THIRTY_TWO_BIT | ||
117 | #define SQR1(w) \ | ||
118 | SQR_tb[(w) >> 28 & 0xF] << 24 | SQR_tb[(w) >> 24 & 0xF] << 16 | \ | ||
119 | SQR_tb[(w) >> 20 & 0xF] << 8 | SQR_tb[(w) >> 16 & 0xF] | ||
120 | #define SQR0(w) \ | ||
121 | SQR_tb[(w) >> 12 & 0xF] << 24 | SQR_tb[(w) >> 8 & 0xF] << 16 | \ | ||
122 | SQR_tb[(w) >> 4 & 0xF] << 8 | SQR_tb[(w) & 0xF] | ||
123 | #endif | ||
124 | #ifdef SIXTEEN_BIT | ||
125 | #define SQR1(w) \ | ||
126 | SQR_tb[(w) >> 12 & 0xF] << 8 | SQR_tb[(w) >> 8 & 0xF] | ||
127 | #define SQR0(w) \ | ||
128 | SQR_tb[(w) >> 4 & 0xF] << 8 | SQR_tb[(w) & 0xF] | ||
129 | #endif | ||
130 | #ifdef EIGHT_BIT | ||
131 | #define SQR1(w) \ | ||
132 | SQR_tb[(w) >> 4 & 0xF] | ||
133 | #define SQR0(w) \ | ||
134 | SQR_tb[(w) & 15] | ||
135 | #endif | ||
136 | |||
137 | /* Product of two polynomials a, b each with degree < BN_BITS2 - 1, | ||
138 | * result is a polynomial r with degree < 2 * BN_BITS - 1 | ||
139 | * The caller MUST ensure that the variables have the right amount | ||
140 | * of space allocated. | ||
141 | */ | ||
142 | #ifdef EIGHT_BIT | ||
143 | static void bn_GF2m_mul_1x1(BN_ULONG *r1, BN_ULONG *r0, const BN_ULONG a, const BN_ULONG b) | ||
144 | { | ||
145 | register BN_ULONG h, l, s; | ||
146 | BN_ULONG tab[4], top1b = a >> 7; | ||
147 | register BN_ULONG a1, a2; | ||
148 | |||
149 | a1 = a & (0x7F); a2 = a1 << 1; | ||
150 | |||
151 | tab[0] = 0; tab[1] = a1; tab[2] = a2; tab[3] = a1^a2; | ||
152 | |||
153 | s = tab[b & 0x3]; l = s; | ||
154 | s = tab[b >> 2 & 0x3]; l ^= s << 2; h = s >> 6; | ||
155 | s = tab[b >> 4 & 0x3]; l ^= s << 4; h ^= s >> 4; | ||
156 | s = tab[b >> 6 ]; l ^= s << 6; h ^= s >> 2; | ||
157 | |||
158 | /* compensate for the top bit of a */ | ||
159 | |||
160 | if (top1b & 01) { l ^= b << 7; h ^= b >> 1; } | ||
161 | |||
162 | *r1 = h; *r0 = l; | ||
163 | } | ||
164 | #endif | ||
165 | #ifdef SIXTEEN_BIT | ||
166 | static void bn_GF2m_mul_1x1(BN_ULONG *r1, BN_ULONG *r0, const BN_ULONG a, const BN_ULONG b) | ||
167 | { | ||
168 | register BN_ULONG h, l, s; | ||
169 | BN_ULONG tab[4], top1b = a >> 15; | ||
170 | register BN_ULONG a1, a2; | ||
171 | |||
172 | a1 = a & (0x7FFF); a2 = a1 << 1; | ||
173 | |||
174 | tab[0] = 0; tab[1] = a1; tab[2] = a2; tab[3] = a1^a2; | ||
175 | |||
176 | s = tab[b & 0x3]; l = s; | ||
177 | s = tab[b >> 2 & 0x3]; l ^= s << 2; h = s >> 14; | ||
178 | s = tab[b >> 4 & 0x3]; l ^= s << 4; h ^= s >> 12; | ||
179 | s = tab[b >> 6 & 0x3]; l ^= s << 6; h ^= s >> 10; | ||
180 | s = tab[b >> 8 & 0x3]; l ^= s << 8; h ^= s >> 8; | ||
181 | s = tab[b >>10 & 0x3]; l ^= s << 10; h ^= s >> 6; | ||
182 | s = tab[b >>12 & 0x3]; l ^= s << 12; h ^= s >> 4; | ||
183 | s = tab[b >>14 ]; l ^= s << 14; h ^= s >> 2; | ||
184 | |||
185 | /* compensate for the top bit of a */ | ||
186 | |||
187 | if (top1b & 01) { l ^= b << 15; h ^= b >> 1; } | ||
188 | |||
189 | *r1 = h; *r0 = l; | ||
190 | } | ||
191 | #endif | ||
192 | #ifdef THIRTY_TWO_BIT | ||
193 | static void bn_GF2m_mul_1x1(BN_ULONG *r1, BN_ULONG *r0, const BN_ULONG a, const BN_ULONG b) | ||
194 | { | ||
195 | register BN_ULONG h, l, s; | ||
196 | BN_ULONG tab[8], top2b = a >> 30; | ||
197 | register BN_ULONG a1, a2, a4; | ||
198 | |||
199 | a1 = a & (0x3FFFFFFF); a2 = a1 << 1; a4 = a2 << 1; | ||
200 | |||
201 | tab[0] = 0; tab[1] = a1; tab[2] = a2; tab[3] = a1^a2; | ||
202 | tab[4] = a4; tab[5] = a1^a4; tab[6] = a2^a4; tab[7] = a1^a2^a4; | ||
203 | |||
204 | s = tab[b & 0x7]; l = s; | ||
205 | s = tab[b >> 3 & 0x7]; l ^= s << 3; h = s >> 29; | ||
206 | s = tab[b >> 6 & 0x7]; l ^= s << 6; h ^= s >> 26; | ||
207 | s = tab[b >> 9 & 0x7]; l ^= s << 9; h ^= s >> 23; | ||
208 | s = tab[b >> 12 & 0x7]; l ^= s << 12; h ^= s >> 20; | ||
209 | s = tab[b >> 15 & 0x7]; l ^= s << 15; h ^= s >> 17; | ||
210 | s = tab[b >> 18 & 0x7]; l ^= s << 18; h ^= s >> 14; | ||
211 | s = tab[b >> 21 & 0x7]; l ^= s << 21; h ^= s >> 11; | ||
212 | s = tab[b >> 24 & 0x7]; l ^= s << 24; h ^= s >> 8; | ||
213 | s = tab[b >> 27 & 0x7]; l ^= s << 27; h ^= s >> 5; | ||
214 | s = tab[b >> 30 ]; l ^= s << 30; h ^= s >> 2; | ||
215 | |||
216 | /* compensate for the top two bits of a */ | ||
217 | |||
218 | if (top2b & 01) { l ^= b << 30; h ^= b >> 2; } | ||
219 | if (top2b & 02) { l ^= b << 31; h ^= b >> 1; } | ||
220 | |||
221 | *r1 = h; *r0 = l; | ||
222 | } | ||
223 | #endif | ||
224 | #if defined(SIXTY_FOUR_BIT) || defined(SIXTY_FOUR_BIT_LONG) | ||
225 | static void bn_GF2m_mul_1x1(BN_ULONG *r1, BN_ULONG *r0, const BN_ULONG a, const BN_ULONG b) | ||
226 | { | ||
227 | register BN_ULONG h, l, s; | ||
228 | BN_ULONG tab[16], top3b = a >> 61; | ||
229 | register BN_ULONG a1, a2, a4, a8; | ||
230 | |||
231 | a1 = a & (0x1FFFFFFFFFFFFFFFULL); a2 = a1 << 1; a4 = a2 << 1; a8 = a4 << 1; | ||
232 | |||
233 | tab[ 0] = 0; tab[ 1] = a1; tab[ 2] = a2; tab[ 3] = a1^a2; | ||
234 | tab[ 4] = a4; tab[ 5] = a1^a4; tab[ 6] = a2^a4; tab[ 7] = a1^a2^a4; | ||
235 | tab[ 8] = a8; tab[ 9] = a1^a8; tab[10] = a2^a8; tab[11] = a1^a2^a8; | ||
236 | tab[12] = a4^a8; tab[13] = a1^a4^a8; tab[14] = a2^a4^a8; tab[15] = a1^a2^a4^a8; | ||
237 | |||
238 | s = tab[b & 0xF]; l = s; | ||
239 | s = tab[b >> 4 & 0xF]; l ^= s << 4; h = s >> 60; | ||
240 | s = tab[b >> 8 & 0xF]; l ^= s << 8; h ^= s >> 56; | ||
241 | s = tab[b >> 12 & 0xF]; l ^= s << 12; h ^= s >> 52; | ||
242 | s = tab[b >> 16 & 0xF]; l ^= s << 16; h ^= s >> 48; | ||
243 | s = tab[b >> 20 & 0xF]; l ^= s << 20; h ^= s >> 44; | ||
244 | s = tab[b >> 24 & 0xF]; l ^= s << 24; h ^= s >> 40; | ||
245 | s = tab[b >> 28 & 0xF]; l ^= s << 28; h ^= s >> 36; | ||
246 | s = tab[b >> 32 & 0xF]; l ^= s << 32; h ^= s >> 32; | ||
247 | s = tab[b >> 36 & 0xF]; l ^= s << 36; h ^= s >> 28; | ||
248 | s = tab[b >> 40 & 0xF]; l ^= s << 40; h ^= s >> 24; | ||
249 | s = tab[b >> 44 & 0xF]; l ^= s << 44; h ^= s >> 20; | ||
250 | s = tab[b >> 48 & 0xF]; l ^= s << 48; h ^= s >> 16; | ||
251 | s = tab[b >> 52 & 0xF]; l ^= s << 52; h ^= s >> 12; | ||
252 | s = tab[b >> 56 & 0xF]; l ^= s << 56; h ^= s >> 8; | ||
253 | s = tab[b >> 60 ]; l ^= s << 60; h ^= s >> 4; | ||
254 | |||
255 | /* compensate for the top three bits of a */ | ||
256 | |||
257 | if (top3b & 01) { l ^= b << 61; h ^= b >> 3; } | ||
258 | if (top3b & 02) { l ^= b << 62; h ^= b >> 2; } | ||
259 | if (top3b & 04) { l ^= b << 63; h ^= b >> 1; } | ||
260 | |||
261 | *r1 = h; *r0 = l; | ||
262 | } | ||
263 | #endif | ||
264 | |||
265 | /* Product of two polynomials a, b each with degree < 2 * BN_BITS2 - 1, | ||
266 | * result is a polynomial r with degree < 4 * BN_BITS2 - 1 | ||
267 | * The caller MUST ensure that the variables have the right amount | ||
268 | * of space allocated. | ||
269 | */ | ||
270 | static void bn_GF2m_mul_2x2(BN_ULONG *r, const BN_ULONG a1, const BN_ULONG a0, const BN_ULONG b1, const BN_ULONG b0) | ||
271 | { | ||
272 | BN_ULONG m1, m0; | ||
273 | /* r[3] = h1, r[2] = h0; r[1] = l1; r[0] = l0 */ | ||
274 | bn_GF2m_mul_1x1(r+3, r+2, a1, b1); | ||
275 | bn_GF2m_mul_1x1(r+1, r, a0, b0); | ||
276 | bn_GF2m_mul_1x1(&m1, &m0, a0 ^ a1, b0 ^ b1); | ||
277 | /* Correction on m1 ^= l1 ^ h1; m0 ^= l0 ^ h0; */ | ||
278 | r[2] ^= m1 ^ r[1] ^ r[3]; /* h0 ^= m1 ^ l1 ^ h1; */ | ||
279 | r[1] = r[3] ^ r[2] ^ r[0] ^ m1 ^ m0; /* l1 ^= l0 ^ h0 ^ m0; */ | ||
280 | } | ||
281 | |||
282 | |||
283 | /* Add polynomials a and b and store result in r; r could be a or b, a and b | ||
284 | * could be equal; r is the bitwise XOR of a and b. | ||
285 | */ | ||
286 | int BN_GF2m_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b) | ||
287 | { | ||
288 | int i; | ||
289 | const BIGNUM *at, *bt; | ||
290 | |||
291 | bn_check_top(a); | ||
292 | bn_check_top(b); | ||
293 | |||
294 | if (a->top < b->top) { at = b; bt = a; } | ||
295 | else { at = a; bt = b; } | ||
296 | |||
297 | bn_wexpand(r, at->top); | ||
298 | |||
299 | for (i = 0; i < bt->top; i++) | ||
300 | { | ||
301 | r->d[i] = at->d[i] ^ bt->d[i]; | ||
302 | } | ||
303 | for (; i < at->top; i++) | ||
304 | { | ||
305 | r->d[i] = at->d[i]; | ||
306 | } | ||
307 | |||
308 | r->top = at->top; | ||
309 | bn_correct_top(r); | ||
310 | |||
311 | return 1; | ||
312 | } | ||
313 | |||
314 | |||
315 | /* Some functions allow for representation of the irreducible polynomials | ||
316 | * as an int[], say p. The irreducible f(t) is then of the form: | ||
317 | * t^p[0] + t^p[1] + ... + t^p[k] | ||
318 | * where m = p[0] > p[1] > ... > p[k] = 0. | ||
319 | */ | ||
320 | |||
321 | |||
322 | /* Performs modular reduction of a and store result in r. r could be a. */ | ||
323 | int BN_GF2m_mod_arr(BIGNUM *r, const BIGNUM *a, const unsigned int p[]) | ||
324 | { | ||
325 | int j, k; | ||
326 | int n, dN, d0, d1; | ||
327 | BN_ULONG zz, *z; | ||
328 | |||
329 | bn_check_top(a); | ||
330 | |||
331 | if (!p[0]) | ||
332 | { | ||
333 | /* reduction mod 1 => return 0 */ | ||
334 | BN_zero(r); | ||
335 | return 1; | ||
336 | } | ||
337 | |||
338 | /* Since the algorithm does reduction in the r value, if a != r, copy | ||
339 | * the contents of a into r so we can do reduction in r. | ||
340 | */ | ||
341 | if (a != r) | ||
342 | { | ||
343 | if (!bn_wexpand(r, a->top)) return 0; | ||
344 | for (j = 0; j < a->top; j++) | ||
345 | { | ||
346 | r->d[j] = a->d[j]; | ||
347 | } | ||
348 | r->top = a->top; | ||
349 | } | ||
350 | z = r->d; | ||
351 | |||
352 | /* start reduction */ | ||
353 | dN = p[0] / BN_BITS2; | ||
354 | for (j = r->top - 1; j > dN;) | ||
355 | { | ||
356 | zz = z[j]; | ||
357 | if (z[j] == 0) { j--; continue; } | ||
358 | z[j] = 0; | ||
359 | |||
360 | for (k = 1; p[k] != 0; k++) | ||
361 | { | ||
362 | /* reducing component t^p[k] */ | ||
363 | n = p[0] - p[k]; | ||
364 | d0 = n % BN_BITS2; d1 = BN_BITS2 - d0; | ||
365 | n /= BN_BITS2; | ||
366 | z[j-n] ^= (zz>>d0); | ||
367 | if (d0) z[j-n-1] ^= (zz<<d1); | ||
368 | } | ||
369 | |||
370 | /* reducing component t^0 */ | ||
371 | n = dN; | ||
372 | d0 = p[0] % BN_BITS2; | ||
373 | d1 = BN_BITS2 - d0; | ||
374 | z[j-n] ^= (zz >> d0); | ||
375 | if (d0) z[j-n-1] ^= (zz << d1); | ||
376 | } | ||
377 | |||
378 | /* final round of reduction */ | ||
379 | while (j == dN) | ||
380 | { | ||
381 | |||
382 | d0 = p[0] % BN_BITS2; | ||
383 | zz = z[dN] >> d0; | ||
384 | if (zz == 0) break; | ||
385 | d1 = BN_BITS2 - d0; | ||
386 | |||
387 | if (d0) z[dN] = (z[dN] << d1) >> d1; /* clear up the top d1 bits */ | ||
388 | z[0] ^= zz; /* reduction t^0 component */ | ||
389 | |||
390 | for (k = 1; p[k] != 0; k++) | ||
391 | { | ||
392 | BN_ULONG tmp_ulong; | ||
393 | |||
394 | /* reducing component t^p[k]*/ | ||
395 | n = p[k] / BN_BITS2; | ||
396 | d0 = p[k] % BN_BITS2; | ||
397 | d1 = BN_BITS2 - d0; | ||
398 | z[n] ^= (zz << d0); | ||
399 | tmp_ulong = zz >> d1; | ||
400 | if (d0 && tmp_ulong) | ||
401 | z[n+1] ^= tmp_ulong; | ||
402 | } | ||
403 | |||
404 | |||
405 | } | ||
406 | |||
407 | bn_correct_top(r); | ||
408 | return 1; | ||
409 | } | ||
410 | |||
411 | /* Performs modular reduction of a by p and store result in r. r could be a. | ||
412 | * | ||
413 | * This function calls down to the BN_GF2m_mod_arr implementation; this wrapper | ||
414 | * function is only provided for convenience; for best performance, use the | ||
415 | * BN_GF2m_mod_arr function. | ||
416 | */ | ||
417 | int BN_GF2m_mod(BIGNUM *r, const BIGNUM *a, const BIGNUM *p) | ||
418 | { | ||
419 | int ret = 0; | ||
420 | const int max = BN_num_bits(p); | ||
421 | unsigned int *arr=NULL; | ||
422 | bn_check_top(a); | ||
423 | bn_check_top(p); | ||
424 | if ((arr = (unsigned int *)OPENSSL_malloc(sizeof(unsigned int) * max)) == NULL) goto err; | ||
425 | ret = BN_GF2m_poly2arr(p, arr, max); | ||
426 | if (!ret || ret > max) | ||
427 | { | ||
428 | BNerr(BN_F_BN_GF2M_MOD,BN_R_INVALID_LENGTH); | ||
429 | goto err; | ||
430 | } | ||
431 | ret = BN_GF2m_mod_arr(r, a, arr); | ||
432 | bn_check_top(r); | ||
433 | err: | ||
434 | if (arr) OPENSSL_free(arr); | ||
435 | return ret; | ||
436 | } | ||
437 | |||
438 | |||
439 | /* Compute the product of two polynomials a and b, reduce modulo p, and store | ||
440 | * the result in r. r could be a or b; a could be b. | ||
441 | */ | ||
442 | int BN_GF2m_mod_mul_arr(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const unsigned int p[], BN_CTX *ctx) | ||
443 | { | ||
444 | int zlen, i, j, k, ret = 0; | ||
445 | BIGNUM *s; | ||
446 | BN_ULONG x1, x0, y1, y0, zz[4]; | ||
447 | |||
448 | bn_check_top(a); | ||
449 | bn_check_top(b); | ||
450 | |||
451 | if (a == b) | ||
452 | { | ||
453 | return BN_GF2m_mod_sqr_arr(r, a, p, ctx); | ||
454 | } | ||
455 | |||
456 | BN_CTX_start(ctx); | ||
457 | if ((s = BN_CTX_get(ctx)) == NULL) goto err; | ||
458 | |||
459 | zlen = a->top + b->top + 4; | ||
460 | if (!bn_wexpand(s, zlen)) goto err; | ||
461 | s->top = zlen; | ||
462 | |||
463 | for (i = 0; i < zlen; i++) s->d[i] = 0; | ||
464 | |||
465 | for (j = 0; j < b->top; j += 2) | ||
466 | { | ||
467 | y0 = b->d[j]; | ||
468 | y1 = ((j+1) == b->top) ? 0 : b->d[j+1]; | ||
469 | for (i = 0; i < a->top; i += 2) | ||
470 | { | ||
471 | x0 = a->d[i]; | ||
472 | x1 = ((i+1) == a->top) ? 0 : a->d[i+1]; | ||
473 | bn_GF2m_mul_2x2(zz, x1, x0, y1, y0); | ||
474 | for (k = 0; k < 4; k++) s->d[i+j+k] ^= zz[k]; | ||
475 | } | ||
476 | } | ||
477 | |||
478 | bn_correct_top(s); | ||
479 | if (BN_GF2m_mod_arr(r, s, p)) | ||
480 | ret = 1; | ||
481 | bn_check_top(r); | ||
482 | |||
483 | err: | ||
484 | BN_CTX_end(ctx); | ||
485 | return ret; | ||
486 | } | ||
487 | |||
488 | /* Compute the product of two polynomials a and b, reduce modulo p, and store | ||
489 | * the result in r. r could be a or b; a could equal b. | ||
490 | * | ||
491 | * This function calls down to the BN_GF2m_mod_mul_arr implementation; this wrapper | ||
492 | * function is only provided for convenience; for best performance, use the | ||
493 | * BN_GF2m_mod_mul_arr function. | ||
494 | */ | ||
495 | int BN_GF2m_mod_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *p, BN_CTX *ctx) | ||
496 | { | ||
497 | int ret = 0; | ||
498 | const int max = BN_num_bits(p); | ||
499 | unsigned int *arr=NULL; | ||
500 | bn_check_top(a); | ||
501 | bn_check_top(b); | ||
502 | bn_check_top(p); | ||
503 | if ((arr = (unsigned int *)OPENSSL_malloc(sizeof(unsigned int) * max)) == NULL) goto err; | ||
504 | ret = BN_GF2m_poly2arr(p, arr, max); | ||
505 | if (!ret || ret > max) | ||
506 | { | ||
507 | BNerr(BN_F_BN_GF2M_MOD_MUL,BN_R_INVALID_LENGTH); | ||
508 | goto err; | ||
509 | } | ||
510 | ret = BN_GF2m_mod_mul_arr(r, a, b, arr, ctx); | ||
511 | bn_check_top(r); | ||
512 | err: | ||
513 | if (arr) OPENSSL_free(arr); | ||
514 | return ret; | ||
515 | } | ||
516 | |||
517 | |||
518 | /* Square a, reduce the result mod p, and store it in a. r could be a. */ | ||
519 | int BN_GF2m_mod_sqr_arr(BIGNUM *r, const BIGNUM *a, const unsigned int p[], BN_CTX *ctx) | ||
520 | { | ||
521 | int i, ret = 0; | ||
522 | BIGNUM *s; | ||
523 | |||
524 | bn_check_top(a); | ||
525 | BN_CTX_start(ctx); | ||
526 | if ((s = BN_CTX_get(ctx)) == NULL) return 0; | ||
527 | if (!bn_wexpand(s, 2 * a->top)) goto err; | ||
528 | |||
529 | for (i = a->top - 1; i >= 0; i--) | ||
530 | { | ||
531 | s->d[2*i+1] = SQR1(a->d[i]); | ||
532 | s->d[2*i ] = SQR0(a->d[i]); | ||
533 | } | ||
534 | |||
535 | s->top = 2 * a->top; | ||
536 | bn_correct_top(s); | ||
537 | if (!BN_GF2m_mod_arr(r, s, p)) goto err; | ||
538 | bn_check_top(r); | ||
539 | ret = 1; | ||
540 | err: | ||
541 | BN_CTX_end(ctx); | ||
542 | return ret; | ||
543 | } | ||
544 | |||
545 | /* Square a, reduce the result mod p, and store it in a. r could be a. | ||
546 | * | ||
547 | * This function calls down to the BN_GF2m_mod_sqr_arr implementation; this wrapper | ||
548 | * function is only provided for convenience; for best performance, use the | ||
549 | * BN_GF2m_mod_sqr_arr function. | ||
550 | */ | ||
551 | int BN_GF2m_mod_sqr(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx) | ||
552 | { | ||
553 | int ret = 0; | ||
554 | const int max = BN_num_bits(p); | ||
555 | unsigned int *arr=NULL; | ||
556 | |||
557 | bn_check_top(a); | ||
558 | bn_check_top(p); | ||
559 | if ((arr = (unsigned int *)OPENSSL_malloc(sizeof(unsigned int) * max)) == NULL) goto err; | ||
560 | ret = BN_GF2m_poly2arr(p, arr, max); | ||
561 | if (!ret || ret > max) | ||
562 | { | ||
563 | BNerr(BN_F_BN_GF2M_MOD_SQR,BN_R_INVALID_LENGTH); | ||
564 | goto err; | ||
565 | } | ||
566 | ret = BN_GF2m_mod_sqr_arr(r, a, arr, ctx); | ||
567 | bn_check_top(r); | ||
568 | err: | ||
569 | if (arr) OPENSSL_free(arr); | ||
570 | return ret; | ||
571 | } | ||
572 | |||
573 | |||
574 | /* Invert a, reduce modulo p, and store the result in r. r could be a. | ||
575 | * Uses Modified Almost Inverse Algorithm (Algorithm 10) from | ||
576 | * Hankerson, D., Hernandez, J.L., and Menezes, A. "Software Implementation | ||
577 | * of Elliptic Curve Cryptography Over Binary Fields". | ||
578 | */ | ||
579 | int BN_GF2m_mod_inv(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx) | ||
580 | { | ||
581 | BIGNUM *b, *c, *u, *v, *tmp; | ||
582 | int ret = 0; | ||
583 | |||
584 | bn_check_top(a); | ||
585 | bn_check_top(p); | ||
586 | |||
587 | BN_CTX_start(ctx); | ||
588 | |||
589 | b = BN_CTX_get(ctx); | ||
590 | c = BN_CTX_get(ctx); | ||
591 | u = BN_CTX_get(ctx); | ||
592 | v = BN_CTX_get(ctx); | ||
593 | if (v == NULL) goto err; | ||
594 | |||
595 | if (!BN_one(b)) goto err; | ||
596 | if (!BN_GF2m_mod(u, a, p)) goto err; | ||
597 | if (!BN_copy(v, p)) goto err; | ||
598 | |||
599 | if (BN_is_zero(u)) goto err; | ||
600 | |||
601 | while (1) | ||
602 | { | ||
603 | while (!BN_is_odd(u)) | ||
604 | { | ||
605 | if (!BN_rshift1(u, u)) goto err; | ||
606 | if (BN_is_odd(b)) | ||
607 | { | ||
608 | if (!BN_GF2m_add(b, b, p)) goto err; | ||
609 | } | ||
610 | if (!BN_rshift1(b, b)) goto err; | ||
611 | } | ||
612 | |||
613 | if (BN_abs_is_word(u, 1)) break; | ||
614 | |||
615 | if (BN_num_bits(u) < BN_num_bits(v)) | ||
616 | { | ||
617 | tmp = u; u = v; v = tmp; | ||
618 | tmp = b; b = c; c = tmp; | ||
619 | } | ||
620 | |||
621 | if (!BN_GF2m_add(u, u, v)) goto err; | ||
622 | if (!BN_GF2m_add(b, b, c)) goto err; | ||
623 | } | ||
624 | |||
625 | |||
626 | if (!BN_copy(r, b)) goto err; | ||
627 | bn_check_top(r); | ||
628 | ret = 1; | ||
629 | |||
630 | err: | ||
631 | BN_CTX_end(ctx); | ||
632 | return ret; | ||
633 | } | ||
634 | |||
635 | /* Invert xx, reduce modulo p, and store the result in r. r could be xx. | ||
636 | * | ||
637 | * This function calls down to the BN_GF2m_mod_inv implementation; this wrapper | ||
638 | * function is only provided for convenience; for best performance, use the | ||
639 | * BN_GF2m_mod_inv function. | ||
640 | */ | ||
641 | int BN_GF2m_mod_inv_arr(BIGNUM *r, const BIGNUM *xx, const unsigned int p[], BN_CTX *ctx) | ||
642 | { | ||
643 | BIGNUM *field; | ||
644 | int ret = 0; | ||
645 | |||
646 | bn_check_top(xx); | ||
647 | BN_CTX_start(ctx); | ||
648 | if ((field = BN_CTX_get(ctx)) == NULL) goto err; | ||
649 | if (!BN_GF2m_arr2poly(p, field)) goto err; | ||
650 | |||
651 | ret = BN_GF2m_mod_inv(r, xx, field, ctx); | ||
652 | bn_check_top(r); | ||
653 | |||
654 | err: | ||
655 | BN_CTX_end(ctx); | ||
656 | return ret; | ||
657 | } | ||
658 | |||
659 | |||
660 | #ifndef OPENSSL_SUN_GF2M_DIV | ||
661 | /* Divide y by x, reduce modulo p, and store the result in r. r could be x | ||
662 | * or y, x could equal y. | ||
663 | */ | ||
664 | int BN_GF2m_mod_div(BIGNUM *r, const BIGNUM *y, const BIGNUM *x, const BIGNUM *p, BN_CTX *ctx) | ||
665 | { | ||
666 | BIGNUM *xinv = NULL; | ||
667 | int ret = 0; | ||
668 | |||
669 | bn_check_top(y); | ||
670 | bn_check_top(x); | ||
671 | bn_check_top(p); | ||
672 | |||
673 | BN_CTX_start(ctx); | ||
674 | xinv = BN_CTX_get(ctx); | ||
675 | if (xinv == NULL) goto err; | ||
676 | |||
677 | if (!BN_GF2m_mod_inv(xinv, x, p, ctx)) goto err; | ||
678 | if (!BN_GF2m_mod_mul(r, y, xinv, p, ctx)) goto err; | ||
679 | bn_check_top(r); | ||
680 | ret = 1; | ||
681 | |||
682 | err: | ||
683 | BN_CTX_end(ctx); | ||
684 | return ret; | ||
685 | } | ||
686 | #else | ||
687 | /* Divide y by x, reduce modulo p, and store the result in r. r could be x | ||
688 | * or y, x could equal y. | ||
689 | * Uses algorithm Modular_Division_GF(2^m) from | ||
690 | * Chang-Shantz, S. "From Euclid's GCD to Montgomery Multiplication to | ||
691 | * the Great Divide". | ||
692 | */ | ||
693 | int BN_GF2m_mod_div(BIGNUM *r, const BIGNUM *y, const BIGNUM *x, const BIGNUM *p, BN_CTX *ctx) | ||
694 | { | ||
695 | BIGNUM *a, *b, *u, *v; | ||
696 | int ret = 0; | ||
697 | |||
698 | bn_check_top(y); | ||
699 | bn_check_top(x); | ||
700 | bn_check_top(p); | ||
701 | |||
702 | BN_CTX_start(ctx); | ||
703 | |||
704 | a = BN_CTX_get(ctx); | ||
705 | b = BN_CTX_get(ctx); | ||
706 | u = BN_CTX_get(ctx); | ||
707 | v = BN_CTX_get(ctx); | ||
708 | if (v == NULL) goto err; | ||
709 | |||
710 | /* reduce x and y mod p */ | ||
711 | if (!BN_GF2m_mod(u, y, p)) goto err; | ||
712 | if (!BN_GF2m_mod(a, x, p)) goto err; | ||
713 | if (!BN_copy(b, p)) goto err; | ||
714 | |||
715 | while (!BN_is_odd(a)) | ||
716 | { | ||
717 | if (!BN_rshift1(a, a)) goto err; | ||
718 | if (BN_is_odd(u)) if (!BN_GF2m_add(u, u, p)) goto err; | ||
719 | if (!BN_rshift1(u, u)) goto err; | ||
720 | } | ||
721 | |||
722 | do | ||
723 | { | ||
724 | if (BN_GF2m_cmp(b, a) > 0) | ||
725 | { | ||
726 | if (!BN_GF2m_add(b, b, a)) goto err; | ||
727 | if (!BN_GF2m_add(v, v, u)) goto err; | ||
728 | do | ||
729 | { | ||
730 | if (!BN_rshift1(b, b)) goto err; | ||
731 | if (BN_is_odd(v)) if (!BN_GF2m_add(v, v, p)) goto err; | ||
732 | if (!BN_rshift1(v, v)) goto err; | ||
733 | } while (!BN_is_odd(b)); | ||
734 | } | ||
735 | else if (BN_abs_is_word(a, 1)) | ||
736 | break; | ||
737 | else | ||
738 | { | ||
739 | if (!BN_GF2m_add(a, a, b)) goto err; | ||
740 | if (!BN_GF2m_add(u, u, v)) goto err; | ||
741 | do | ||
742 | { | ||
743 | if (!BN_rshift1(a, a)) goto err; | ||
744 | if (BN_is_odd(u)) if (!BN_GF2m_add(u, u, p)) goto err; | ||
745 | if (!BN_rshift1(u, u)) goto err; | ||
746 | } while (!BN_is_odd(a)); | ||
747 | } | ||
748 | } while (1); | ||
749 | |||
750 | if (!BN_copy(r, u)) goto err; | ||
751 | bn_check_top(r); | ||
752 | ret = 1; | ||
753 | |||
754 | err: | ||
755 | BN_CTX_end(ctx); | ||
756 | return ret; | ||
757 | } | ||
758 | #endif | ||
759 | |||
760 | /* Divide yy by xx, reduce modulo p, and store the result in r. r could be xx | ||
761 | * or yy, xx could equal yy. | ||
762 | * | ||
763 | * This function calls down to the BN_GF2m_mod_div implementation; this wrapper | ||
764 | * function is only provided for convenience; for best performance, use the | ||
765 | * BN_GF2m_mod_div function. | ||
766 | */ | ||
767 | int BN_GF2m_mod_div_arr(BIGNUM *r, const BIGNUM *yy, const BIGNUM *xx, const unsigned int p[], BN_CTX *ctx) | ||
768 | { | ||
769 | BIGNUM *field; | ||
770 | int ret = 0; | ||
771 | |||
772 | bn_check_top(yy); | ||
773 | bn_check_top(xx); | ||
774 | |||
775 | BN_CTX_start(ctx); | ||
776 | if ((field = BN_CTX_get(ctx)) == NULL) goto err; | ||
777 | if (!BN_GF2m_arr2poly(p, field)) goto err; | ||
778 | |||
779 | ret = BN_GF2m_mod_div(r, yy, xx, field, ctx); | ||
780 | bn_check_top(r); | ||
781 | |||
782 | err: | ||
783 | BN_CTX_end(ctx); | ||
784 | return ret; | ||
785 | } | ||
786 | |||
787 | |||
788 | /* Compute the bth power of a, reduce modulo p, and store | ||
789 | * the result in r. r could be a. | ||
790 | * Uses simple square-and-multiply algorithm A.5.1 from IEEE P1363. | ||
791 | */ | ||
792 | int BN_GF2m_mod_exp_arr(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const unsigned int p[], BN_CTX *ctx) | ||
793 | { | ||
794 | int ret = 0, i, n; | ||
795 | BIGNUM *u; | ||
796 | |||
797 | bn_check_top(a); | ||
798 | bn_check_top(b); | ||
799 | |||
800 | if (BN_is_zero(b)) | ||
801 | return(BN_one(r)); | ||
802 | |||
803 | if (BN_abs_is_word(b, 1)) | ||
804 | return (BN_copy(r, a) != NULL); | ||
805 | |||
806 | BN_CTX_start(ctx); | ||
807 | if ((u = BN_CTX_get(ctx)) == NULL) goto err; | ||
808 | |||
809 | if (!BN_GF2m_mod_arr(u, a, p)) goto err; | ||
810 | |||
811 | n = BN_num_bits(b) - 1; | ||
812 | for (i = n - 1; i >= 0; i--) | ||
813 | { | ||
814 | if (!BN_GF2m_mod_sqr_arr(u, u, p, ctx)) goto err; | ||
815 | if (BN_is_bit_set(b, i)) | ||
816 | { | ||
817 | if (!BN_GF2m_mod_mul_arr(u, u, a, p, ctx)) goto err; | ||
818 | } | ||
819 | } | ||
820 | if (!BN_copy(r, u)) goto err; | ||
821 | bn_check_top(r); | ||
822 | ret = 1; | ||
823 | err: | ||
824 | BN_CTX_end(ctx); | ||
825 | return ret; | ||
826 | } | ||
827 | |||
828 | /* Compute the bth power of a, reduce modulo p, and store | ||
829 | * the result in r. r could be a. | ||
830 | * | ||
831 | * This function calls down to the BN_GF2m_mod_exp_arr implementation; this wrapper | ||
832 | * function is only provided for convenience; for best performance, use the | ||
833 | * BN_GF2m_mod_exp_arr function. | ||
834 | */ | ||
835 | int BN_GF2m_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *p, BN_CTX *ctx) | ||
836 | { | ||
837 | int ret = 0; | ||
838 | const int max = BN_num_bits(p); | ||
839 | unsigned int *arr=NULL; | ||
840 | bn_check_top(a); | ||
841 | bn_check_top(b); | ||
842 | bn_check_top(p); | ||
843 | if ((arr = (unsigned int *)OPENSSL_malloc(sizeof(unsigned int) * max)) == NULL) goto err; | ||
844 | ret = BN_GF2m_poly2arr(p, arr, max); | ||
845 | if (!ret || ret > max) | ||
846 | { | ||
847 | BNerr(BN_F_BN_GF2M_MOD_EXP,BN_R_INVALID_LENGTH); | ||
848 | goto err; | ||
849 | } | ||
850 | ret = BN_GF2m_mod_exp_arr(r, a, b, arr, ctx); | ||
851 | bn_check_top(r); | ||
852 | err: | ||
853 | if (arr) OPENSSL_free(arr); | ||
854 | return ret; | ||
855 | } | ||
856 | |||
857 | /* Compute the square root of a, reduce modulo p, and store | ||
858 | * the result in r. r could be a. | ||
859 | * Uses exponentiation as in algorithm A.4.1 from IEEE P1363. | ||
860 | */ | ||
861 | int BN_GF2m_mod_sqrt_arr(BIGNUM *r, const BIGNUM *a, const unsigned int p[], BN_CTX *ctx) | ||
862 | { | ||
863 | int ret = 0; | ||
864 | BIGNUM *u; | ||
865 | |||
866 | bn_check_top(a); | ||
867 | |||
868 | if (!p[0]) | ||
869 | { | ||
870 | /* reduction mod 1 => return 0 */ | ||
871 | BN_zero(r); | ||
872 | return 1; | ||
873 | } | ||
874 | |||
875 | BN_CTX_start(ctx); | ||
876 | if ((u = BN_CTX_get(ctx)) == NULL) goto err; | ||
877 | |||
878 | if (!BN_set_bit(u, p[0] - 1)) goto err; | ||
879 | ret = BN_GF2m_mod_exp_arr(r, a, u, p, ctx); | ||
880 | bn_check_top(r); | ||
881 | |||
882 | err: | ||
883 | BN_CTX_end(ctx); | ||
884 | return ret; | ||
885 | } | ||
886 | |||
887 | /* Compute the square root of a, reduce modulo p, and store | ||
888 | * the result in r. r could be a. | ||
889 | * | ||
890 | * This function calls down to the BN_GF2m_mod_sqrt_arr implementation; this wrapper | ||
891 | * function is only provided for convenience; for best performance, use the | ||
892 | * BN_GF2m_mod_sqrt_arr function. | ||
893 | */ | ||
894 | int BN_GF2m_mod_sqrt(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx) | ||
895 | { | ||
896 | int ret = 0; | ||
897 | const int max = BN_num_bits(p); | ||
898 | unsigned int *arr=NULL; | ||
899 | bn_check_top(a); | ||
900 | bn_check_top(p); | ||
901 | if ((arr = (unsigned int *)OPENSSL_malloc(sizeof(unsigned int) * max)) == NULL) goto err; | ||
902 | ret = BN_GF2m_poly2arr(p, arr, max); | ||
903 | if (!ret || ret > max) | ||
904 | { | ||
905 | BNerr(BN_F_BN_GF2M_MOD_SQRT,BN_R_INVALID_LENGTH); | ||
906 | goto err; | ||
907 | } | ||
908 | ret = BN_GF2m_mod_sqrt_arr(r, a, arr, ctx); | ||
909 | bn_check_top(r); | ||
910 | err: | ||
911 | if (arr) OPENSSL_free(arr); | ||
912 | return ret; | ||
913 | } | ||
914 | |||
915 | /* Find r such that r^2 + r = a mod p. r could be a. If no r exists returns 0. | ||
916 | * Uses algorithms A.4.7 and A.4.6 from IEEE P1363. | ||
917 | */ | ||
918 | int BN_GF2m_mod_solve_quad_arr(BIGNUM *r, const BIGNUM *a_, const unsigned int p[], BN_CTX *ctx) | ||
919 | { | ||
920 | int ret = 0, count = 0; | ||
921 | unsigned int j; | ||
922 | BIGNUM *a, *z, *rho, *w, *w2, *tmp; | ||
923 | |||
924 | bn_check_top(a_); | ||
925 | |||
926 | if (!p[0]) | ||
927 | { | ||
928 | /* reduction mod 1 => return 0 */ | ||
929 | BN_zero(r); | ||
930 | return 1; | ||
931 | } | ||
932 | |||
933 | BN_CTX_start(ctx); | ||
934 | a = BN_CTX_get(ctx); | ||
935 | z = BN_CTX_get(ctx); | ||
936 | w = BN_CTX_get(ctx); | ||
937 | if (w == NULL) goto err; | ||
938 | |||
939 | if (!BN_GF2m_mod_arr(a, a_, p)) goto err; | ||
940 | |||
941 | if (BN_is_zero(a)) | ||
942 | { | ||
943 | BN_zero(r); | ||
944 | ret = 1; | ||
945 | goto err; | ||
946 | } | ||
947 | |||
948 | if (p[0] & 0x1) /* m is odd */ | ||
949 | { | ||
950 | /* compute half-trace of a */ | ||
951 | if (!BN_copy(z, a)) goto err; | ||
952 | for (j = 1; j <= (p[0] - 1) / 2; j++) | ||
953 | { | ||
954 | if (!BN_GF2m_mod_sqr_arr(z, z, p, ctx)) goto err; | ||
955 | if (!BN_GF2m_mod_sqr_arr(z, z, p, ctx)) goto err; | ||
956 | if (!BN_GF2m_add(z, z, a)) goto err; | ||
957 | } | ||
958 | |||
959 | } | ||
960 | else /* m is even */ | ||
961 | { | ||
962 | rho = BN_CTX_get(ctx); | ||
963 | w2 = BN_CTX_get(ctx); | ||
964 | tmp = BN_CTX_get(ctx); | ||
965 | if (tmp == NULL) goto err; | ||
966 | do | ||
967 | { | ||
968 | if (!BN_rand(rho, p[0], 0, 0)) goto err; | ||
969 | if (!BN_GF2m_mod_arr(rho, rho, p)) goto err; | ||
970 | BN_zero(z); | ||
971 | if (!BN_copy(w, rho)) goto err; | ||
972 | for (j = 1; j <= p[0] - 1; j++) | ||
973 | { | ||
974 | if (!BN_GF2m_mod_sqr_arr(z, z, p, ctx)) goto err; | ||
975 | if (!BN_GF2m_mod_sqr_arr(w2, w, p, ctx)) goto err; | ||
976 | if (!BN_GF2m_mod_mul_arr(tmp, w2, a, p, ctx)) goto err; | ||
977 | if (!BN_GF2m_add(z, z, tmp)) goto err; | ||
978 | if (!BN_GF2m_add(w, w2, rho)) goto err; | ||
979 | } | ||
980 | count++; | ||
981 | } while (BN_is_zero(w) && (count < MAX_ITERATIONS)); | ||
982 | if (BN_is_zero(w)) | ||
983 | { | ||
984 | BNerr(BN_F_BN_GF2M_MOD_SOLVE_QUAD_ARR,BN_R_TOO_MANY_ITERATIONS); | ||
985 | goto err; | ||
986 | } | ||
987 | } | ||
988 | |||
989 | if (!BN_GF2m_mod_sqr_arr(w, z, p, ctx)) goto err; | ||
990 | if (!BN_GF2m_add(w, z, w)) goto err; | ||
991 | if (BN_GF2m_cmp(w, a)) | ||
992 | { | ||
993 | BNerr(BN_F_BN_GF2M_MOD_SOLVE_QUAD_ARR, BN_R_NO_SOLUTION); | ||
994 | goto err; | ||
995 | } | ||
996 | |||
997 | if (!BN_copy(r, z)) goto err; | ||
998 | bn_check_top(r); | ||
999 | |||
1000 | ret = 1; | ||
1001 | |||
1002 | err: | ||
1003 | BN_CTX_end(ctx); | ||
1004 | return ret; | ||
1005 | } | ||
1006 | |||
1007 | /* Find r such that r^2 + r = a mod p. r could be a. If no r exists returns 0. | ||
1008 | * | ||
1009 | * This function calls down to the BN_GF2m_mod_solve_quad_arr implementation; this wrapper | ||
1010 | * function is only provided for convenience; for best performance, use the | ||
1011 | * BN_GF2m_mod_solve_quad_arr function. | ||
1012 | */ | ||
1013 | int BN_GF2m_mod_solve_quad(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx) | ||
1014 | { | ||
1015 | int ret = 0; | ||
1016 | const int max = BN_num_bits(p); | ||
1017 | unsigned int *arr=NULL; | ||
1018 | bn_check_top(a); | ||
1019 | bn_check_top(p); | ||
1020 | if ((arr = (unsigned int *)OPENSSL_malloc(sizeof(unsigned int) * | ||
1021 | max)) == NULL) goto err; | ||
1022 | ret = BN_GF2m_poly2arr(p, arr, max); | ||
1023 | if (!ret || ret > max) | ||
1024 | { | ||
1025 | BNerr(BN_F_BN_GF2M_MOD_SOLVE_QUAD,BN_R_INVALID_LENGTH); | ||
1026 | goto err; | ||
1027 | } | ||
1028 | ret = BN_GF2m_mod_solve_quad_arr(r, a, arr, ctx); | ||
1029 | bn_check_top(r); | ||
1030 | err: | ||
1031 | if (arr) OPENSSL_free(arr); | ||
1032 | return ret; | ||
1033 | } | ||
1034 | |||
1035 | /* Convert the bit-string representation of a polynomial | ||
1036 | * ( \sum_{i=0}^n a_i * x^i , where a_0 is *not* zero) into an array | ||
1037 | * of integers corresponding to the bits with non-zero coefficient. | ||
1038 | * Up to max elements of the array will be filled. Return value is total | ||
1039 | * number of coefficients that would be extracted if array was large enough. | ||
1040 | */ | ||
1041 | int BN_GF2m_poly2arr(const BIGNUM *a, unsigned int p[], int max) | ||
1042 | { | ||
1043 | int i, j, k = 0; | ||
1044 | BN_ULONG mask; | ||
1045 | |||
1046 | if (BN_is_zero(a) || !BN_is_bit_set(a, 0)) | ||
1047 | /* a_0 == 0 => return error (the unsigned int array | ||
1048 | * must be terminated by 0) | ||
1049 | */ | ||
1050 | return 0; | ||
1051 | |||
1052 | for (i = a->top - 1; i >= 0; i--) | ||
1053 | { | ||
1054 | if (!a->d[i]) | ||
1055 | /* skip word if a->d[i] == 0 */ | ||
1056 | continue; | ||
1057 | mask = BN_TBIT; | ||
1058 | for (j = BN_BITS2 - 1; j >= 0; j--) | ||
1059 | { | ||
1060 | if (a->d[i] & mask) | ||
1061 | { | ||
1062 | if (k < max) p[k] = BN_BITS2 * i + j; | ||
1063 | k++; | ||
1064 | } | ||
1065 | mask >>= 1; | ||
1066 | } | ||
1067 | } | ||
1068 | |||
1069 | return k; | ||
1070 | } | ||
1071 | |||
1072 | /* Convert the coefficient array representation of a polynomial to a | ||
1073 | * bit-string. The array must be terminated by 0. | ||
1074 | */ | ||
1075 | int BN_GF2m_arr2poly(const unsigned int p[], BIGNUM *a) | ||
1076 | { | ||
1077 | int i; | ||
1078 | |||
1079 | bn_check_top(a); | ||
1080 | BN_zero(a); | ||
1081 | for (i = 0; p[i] != 0; i++) | ||
1082 | { | ||
1083 | if (BN_set_bit(a, p[i]) == 0) | ||
1084 | return 0; | ||
1085 | } | ||
1086 | BN_set_bit(a, 0); | ||
1087 | bn_check_top(a); | ||
1088 | |||
1089 | return 1; | ||
1090 | } | ||
1091 | |||
diff --git a/src/lib/libcrypto/bn/bn_nist.c b/src/lib/libcrypto/bn/bn_nist.c new file mode 100644 index 0000000000..e14232fdbb --- /dev/null +++ b/src/lib/libcrypto/bn/bn_nist.c | |||
@@ -0,0 +1,692 @@ | |||
1 | /* crypto/bn/bn_nist.c */ | ||
2 | /* | ||
3 | * Written by Nils Larsch for the OpenSSL project | ||
4 | */ | ||
5 | /* ==================================================================== | ||
6 | * Copyright (c) 1998-2005 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 | * openssl-core@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 | * This product includes cryptographic software written by Eric Young | ||
54 | * (eay@cryptsoft.com). This product includes software written by Tim | ||
55 | * Hudson (tjh@cryptsoft.com). | ||
56 | * | ||
57 | */ | ||
58 | |||
59 | #include "bn_lcl.h" | ||
60 | #include "cryptlib.h" | ||
61 | |||
62 | #define BN_NIST_192_TOP (192+BN_BITS2-1)/BN_BITS2 | ||
63 | #define BN_NIST_224_TOP (224+BN_BITS2-1)/BN_BITS2 | ||
64 | #define BN_NIST_256_TOP (256+BN_BITS2-1)/BN_BITS2 | ||
65 | #define BN_NIST_384_TOP (384+BN_BITS2-1)/BN_BITS2 | ||
66 | #define BN_NIST_521_TOP (521+BN_BITS2-1)/BN_BITS2 | ||
67 | |||
68 | #if BN_BITS2 == 64 | ||
69 | static const BN_ULONG _nist_p_192[] = | ||
70 | {0xFFFFFFFFFFFFFFFFULL,0xFFFFFFFFFFFFFFFEULL, | ||
71 | 0xFFFFFFFFFFFFFFFFULL}; | ||
72 | static const BN_ULONG _nist_p_224[] = | ||
73 | {0x0000000000000001ULL,0xFFFFFFFF00000000ULL, | ||
74 | 0xFFFFFFFFFFFFFFFFULL,0x00000000FFFFFFFFULL}; | ||
75 | static const BN_ULONG _nist_p_256[] = | ||
76 | {0xFFFFFFFFFFFFFFFFULL,0x00000000FFFFFFFFULL, | ||
77 | 0x0000000000000000ULL,0xFFFFFFFF00000001ULL}; | ||
78 | static const BN_ULONG _nist_p_384[] = | ||
79 | {0x00000000FFFFFFFFULL,0xFFFFFFFF00000000ULL, | ||
80 | 0xFFFFFFFFFFFFFFFEULL,0xFFFFFFFFFFFFFFFFULL, | ||
81 | 0xFFFFFFFFFFFFFFFFULL,0xFFFFFFFFFFFFFFFFULL}; | ||
82 | static const BN_ULONG _nist_p_521[] = | ||
83 | {0xFFFFFFFFFFFFFFFFULL,0xFFFFFFFFFFFFFFFFULL, | ||
84 | 0xFFFFFFFFFFFFFFFFULL,0xFFFFFFFFFFFFFFFFULL, | ||
85 | 0xFFFFFFFFFFFFFFFFULL,0xFFFFFFFFFFFFFFFFULL, | ||
86 | 0xFFFFFFFFFFFFFFFFULL,0xFFFFFFFFFFFFFFFFULL, | ||
87 | 0x00000000000001FFULL}; | ||
88 | #elif BN_BITS2 == 32 | ||
89 | static const BN_ULONG _nist_p_192[] = {0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFE, | ||
90 | 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF}; | ||
91 | static const BN_ULONG _nist_p_224[] = {0x00000001,0x00000000,0x00000000, | ||
92 | 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF}; | ||
93 | static const BN_ULONG _nist_p_256[] = {0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, | ||
94 | 0x00000000,0x00000000,0x00000000,0x00000001,0xFFFFFFFF}; | ||
95 | static const BN_ULONG _nist_p_384[] = {0xFFFFFFFF,0x00000000,0x00000000, | ||
96 | 0xFFFFFFFF,0xFFFFFFFE,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, | ||
97 | 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF}; | ||
98 | static const BN_ULONG _nist_p_521[] = {0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, | ||
99 | 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, | ||
100 | 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, | ||
101 | 0xFFFFFFFF,0x000001FF}; | ||
102 | #endif | ||
103 | |||
104 | const BIGNUM *BN_get0_nist_prime_192(void) | ||
105 | { | ||
106 | static BIGNUM const_nist_192 = { (BN_ULONG *)_nist_p_192, | ||
107 | BN_NIST_192_TOP, BN_NIST_192_TOP, 0, BN_FLG_STATIC_DATA }; | ||
108 | return &const_nist_192; | ||
109 | } | ||
110 | |||
111 | const BIGNUM *BN_get0_nist_prime_224(void) | ||
112 | { | ||
113 | static BIGNUM const_nist_224 = { (BN_ULONG *)_nist_p_224, | ||
114 | BN_NIST_224_TOP, BN_NIST_224_TOP, 0, BN_FLG_STATIC_DATA }; | ||
115 | return &const_nist_224; | ||
116 | } | ||
117 | |||
118 | const BIGNUM *BN_get0_nist_prime_256(void) | ||
119 | { | ||
120 | static BIGNUM const_nist_256 = { (BN_ULONG *)_nist_p_256, | ||
121 | BN_NIST_256_TOP, BN_NIST_256_TOP, 0, BN_FLG_STATIC_DATA }; | ||
122 | return &const_nist_256; | ||
123 | } | ||
124 | |||
125 | const BIGNUM *BN_get0_nist_prime_384(void) | ||
126 | { | ||
127 | static BIGNUM const_nist_384 = { (BN_ULONG *)_nist_p_384, | ||
128 | BN_NIST_384_TOP, BN_NIST_384_TOP, 0, BN_FLG_STATIC_DATA }; | ||
129 | return &const_nist_384; | ||
130 | } | ||
131 | |||
132 | const BIGNUM *BN_get0_nist_prime_521(void) | ||
133 | { | ||
134 | static BIGNUM const_nist_521 = { (BN_ULONG *)_nist_p_521, | ||
135 | BN_NIST_521_TOP, BN_NIST_521_TOP, 0, BN_FLG_STATIC_DATA }; | ||
136 | return &const_nist_521; | ||
137 | } | ||
138 | |||
139 | #define BN_NIST_ADD_ONE(a) while (!(*(a)=(*(a)+1)&BN_MASK2)) ++(a); | ||
140 | |||
141 | static void nist_cp_bn_0(BN_ULONG *buf, BN_ULONG *a, int top, int max) | ||
142 | { | ||
143 | int i; | ||
144 | BN_ULONG *_tmp1 = (buf), *_tmp2 = (a); | ||
145 | for (i = (top); i != 0; i--) | ||
146 | *_tmp1++ = *_tmp2++; | ||
147 | for (i = (max) - (top); i != 0; i--) | ||
148 | *_tmp1++ = (BN_ULONG) 0; | ||
149 | } | ||
150 | |||
151 | static void nist_cp_bn(BN_ULONG *buf, BN_ULONG *a, int top) | ||
152 | { | ||
153 | int i; | ||
154 | BN_ULONG *_tmp1 = (buf), *_tmp2 = (a); | ||
155 | for (i = (top); i != 0; i--) | ||
156 | *_tmp1++ = *_tmp2++; | ||
157 | } | ||
158 | |||
159 | #if BN_BITS2 == 64 | ||
160 | #define bn_cp_64(to, n, from, m) (to)[n] = (m>=0)?((from)[m]):0; | ||
161 | #define bn_64_set_0(to, n) (to)[n] = (BN_ULONG)0; | ||
162 | /* TBD */ | ||
163 | #define bn_cp_32(to, n, from, m) (to)[n] = (m>=0)?((from)[m]):0; | ||
164 | #define bn_32_set_0(to, n) (to)[n] = (BN_ULONG)0; | ||
165 | #else | ||
166 | #define bn_cp_64(to, n, from, m) \ | ||
167 | { \ | ||
168 | bn_cp_32(to, (n)*2, from, (m)*2); \ | ||
169 | bn_cp_32(to, (n)*2+1, from, (m)*2+1); \ | ||
170 | } | ||
171 | #define bn_64_set_0(to, n) \ | ||
172 | { \ | ||
173 | bn_32_set_0(to, (n)*2); \ | ||
174 | bn_32_set_0(to, (n)*2+1); \ | ||
175 | } | ||
176 | #if BN_BITS2 == 32 | ||
177 | #define bn_cp_32(to, n, from, m) (to)[n] = (m>=0)?((from)[m]):0; | ||
178 | #define bn_32_set_0(to, n) (to)[n] = (BN_ULONG)0; | ||
179 | #endif | ||
180 | #endif /* BN_BITS2 != 64 */ | ||
181 | |||
182 | |||
183 | #define nist_set_192(to, from, a1, a2, a3) \ | ||
184 | { \ | ||
185 | if (a3 != 0) bn_cp_64(to, 0, from, (a3) - 3) else bn_64_set_0(to, 0)\ | ||
186 | bn_cp_64(to, 1, from, (a2) - 3) \ | ||
187 | if (a1 != 0) bn_cp_64(to, 2, from, (a1) - 3) else bn_64_set_0(to, 2)\ | ||
188 | } | ||
189 | |||
190 | int BN_nist_mod_192(BIGNUM *r, const BIGNUM *a, const BIGNUM *field, | ||
191 | BN_CTX *ctx) | ||
192 | { | ||
193 | int top = a->top, i; | ||
194 | int carry; | ||
195 | register BN_ULONG *r_d, *a_d = a->d; | ||
196 | BN_ULONG t_d[BN_NIST_192_TOP], | ||
197 | buf[BN_NIST_192_TOP], | ||
198 | c_d[BN_NIST_192_TOP], | ||
199 | *res; | ||
200 | size_t mask; | ||
201 | |||
202 | i = BN_ucmp(field, a); | ||
203 | if (i == 0) | ||
204 | { | ||
205 | BN_zero(r); | ||
206 | return 1; | ||
207 | } | ||
208 | else if (i > 0) | ||
209 | return (r == a) ? 1 : (BN_copy(r ,a) != NULL); | ||
210 | |||
211 | if (top == BN_NIST_192_TOP) | ||
212 | return BN_usub(r, a, field); | ||
213 | |||
214 | if (r != a) | ||
215 | { | ||
216 | if (!bn_wexpand(r, BN_NIST_192_TOP)) | ||
217 | return 0; | ||
218 | r_d = r->d; | ||
219 | nist_cp_bn(r_d, a_d, BN_NIST_192_TOP); | ||
220 | } | ||
221 | else | ||
222 | r_d = a_d; | ||
223 | |||
224 | nist_cp_bn_0(buf, a_d + BN_NIST_192_TOP, top - BN_NIST_192_TOP, BN_NIST_192_TOP); | ||
225 | |||
226 | nist_set_192(t_d, buf, 0, 3, 3); | ||
227 | carry = bn_add_words(r_d, r_d, t_d, BN_NIST_192_TOP); | ||
228 | mask = 0-(size_t)bn_sub_words(c_d,r_d,_nist_p_192,BN_NIST_192_TOP); | ||
229 | mask = ~mask | (0-(size_t)carry); | ||
230 | res = (BN_ULONG *)(((size_t)c_d&mask) | ((size_t)r_d&~mask)); | ||
231 | |||
232 | nist_set_192(t_d, buf, 4, 4, 0); | ||
233 | carry = bn_add_words(r_d, res, t_d, BN_NIST_192_TOP); | ||
234 | mask = 0-(size_t)bn_sub_words(c_d,r_d,_nist_p_192,BN_NIST_192_TOP); | ||
235 | mask = ~mask | (0-(size_t)carry); | ||
236 | res = (BN_ULONG *)(((size_t)c_d&mask) | ((size_t)r_d&~mask)); | ||
237 | |||
238 | nist_set_192(t_d, buf, 5, 5, 5) | ||
239 | carry = bn_add_words(r_d, res, t_d, BN_NIST_192_TOP); | ||
240 | mask = 0-(size_t)bn_sub_words(c_d,r_d,_nist_p_192,BN_NIST_192_TOP); | ||
241 | mask = ~mask | (0-(size_t)carry); | ||
242 | res = (BN_ULONG *)(((size_t)c_d&mask) | ((size_t)r_d&~mask)); | ||
243 | |||
244 | nist_cp_bn(r_d, res, BN_NIST_192_TOP); | ||
245 | r->top = BN_NIST_192_TOP; | ||
246 | bn_correct_top(r); | ||
247 | |||
248 | return 1; | ||
249 | } | ||
250 | |||
251 | #define nist_set_224(to, from, a1, a2, a3, a4, a5, a6, a7) \ | ||
252 | { \ | ||
253 | if (a7 != 0) bn_cp_32(to, 0, from, (a7) - 7) else bn_32_set_0(to, 0)\ | ||
254 | if (a6 != 0) bn_cp_32(to, 1, from, (a6) - 7) else bn_32_set_0(to, 1)\ | ||
255 | if (a5 != 0) bn_cp_32(to, 2, from, (a5) - 7) else bn_32_set_0(to, 2)\ | ||
256 | if (a4 != 0) bn_cp_32(to, 3, from, (a4) - 7) else bn_32_set_0(to, 3)\ | ||
257 | if (a3 != 0) bn_cp_32(to, 4, from, (a3) - 7) else bn_32_set_0(to, 4)\ | ||
258 | if (a2 != 0) bn_cp_32(to, 5, from, (a2) - 7) else bn_32_set_0(to, 5)\ | ||
259 | if (a1 != 0) bn_cp_32(to, 6, from, (a1) - 7) else bn_32_set_0(to, 6)\ | ||
260 | } | ||
261 | |||
262 | int BN_nist_mod_224(BIGNUM *r, const BIGNUM *a, const BIGNUM *field, | ||
263 | BN_CTX *ctx) | ||
264 | { | ||
265 | #if BN_BITS2 == 32 | ||
266 | int top = a->top, i; | ||
267 | int carry; | ||
268 | BN_ULONG *r_d, *a_d = a->d; | ||
269 | BN_ULONG t_d[BN_NIST_224_TOP], | ||
270 | buf[BN_NIST_224_TOP], | ||
271 | c_d[BN_NIST_224_TOP], | ||
272 | *res; | ||
273 | size_t mask; | ||
274 | |||
275 | i = BN_ucmp(field, a); | ||
276 | if (i == 0) | ||
277 | { | ||
278 | BN_zero(r); | ||
279 | return 1; | ||
280 | } | ||
281 | else if (i > 0) | ||
282 | return (r == a)? 1 : (BN_copy(r ,a) != NULL); | ||
283 | |||
284 | if (top == BN_NIST_224_TOP) | ||
285 | return BN_usub(r, a, field); | ||
286 | |||
287 | if (r != a) | ||
288 | { | ||
289 | if (!bn_wexpand(r, BN_NIST_224_TOP)) | ||
290 | return 0; | ||
291 | r_d = r->d; | ||
292 | nist_cp_bn(r_d, a_d, BN_NIST_224_TOP); | ||
293 | } | ||
294 | else | ||
295 | r_d = a_d; | ||
296 | |||
297 | nist_cp_bn_0(buf, a_d + BN_NIST_224_TOP, top - BN_NIST_224_TOP, BN_NIST_224_TOP); | ||
298 | |||
299 | nist_set_224(t_d, buf, 10, 9, 8, 7, 0, 0, 0); | ||
300 | carry = bn_add_words(r_d, r_d, t_d, BN_NIST_224_TOP); | ||
301 | mask = 0-(size_t)bn_sub_words(c_d,r_d,_nist_p_224,BN_NIST_224_TOP); | ||
302 | mask = ~mask | (0-(size_t)carry); | ||
303 | res = (BN_ULONG *)(((size_t)c_d&mask) | ((size_t)r_d&~mask)); | ||
304 | |||
305 | nist_set_224(t_d, buf, 0, 13, 12, 11, 0, 0, 0); | ||
306 | carry = bn_add_words(r_d, res, t_d, BN_NIST_224_TOP); | ||
307 | mask = 0-(size_t)bn_sub_words(c_d,r_d,_nist_p_224,BN_NIST_224_TOP); | ||
308 | mask = ~mask | (0-(size_t)carry); | ||
309 | res = (BN_ULONG *)(((size_t)c_d&mask) | ((size_t)r_d&~mask)); | ||
310 | |||
311 | nist_set_224(t_d, buf, 13, 12, 11, 10, 9, 8, 7); | ||
312 | #if BRANCH_FREE | ||
313 | carry = bn_sub_words(r_d, res, t_d, BN_NIST_224_TOP); | ||
314 | bn_add_words(c_d,r_d,_nist_p_224,BN_NIST_224_TOP); | ||
315 | mask = 0-(size_t)carry; | ||
316 | res = (BN_ULONG *)(((size_t)c_d&mask) | ((size_t)r_d&~mask)); | ||
317 | #else | ||
318 | if (bn_sub_words(r_d, res, t_d, BN_NIST_224_TOP)) | ||
319 | bn_add_words(r_d,r_d,_nist_p_224,BN_NIST_224_TOP); | ||
320 | #endif | ||
321 | nist_set_224(t_d, buf, 0, 0, 0, 0, 13, 12, 11); | ||
322 | #if BRANCH_FREE | ||
323 | carry = bn_sub_words(r_d, res, t_d, BN_NIST_224_TOP); | ||
324 | bn_add_words(c_d,r_d,_nist_p_224,BN_NIST_224_TOP); | ||
325 | mask = 0-(size_t)carry; | ||
326 | res = (BN_ULONG *)(((size_t)c_d&mask) | ((size_t)r_d&~mask)); | ||
327 | |||
328 | nist_cp_bn(r_d, res, BN_NIST_224_TOP); | ||
329 | #else | ||
330 | if (bn_sub_words(r_d, r_d, t_d, BN_NIST_224_TOP)) | ||
331 | bn_add_words(r_d,r_d,_nist_p_224,BN_NIST_224_TOP); | ||
332 | #endif | ||
333 | r->top = BN_NIST_224_TOP; | ||
334 | bn_correct_top(r); | ||
335 | |||
336 | return 1; | ||
337 | #else /* BN_BITS!=32 */ | ||
338 | return 0; | ||
339 | #endif | ||
340 | } | ||
341 | |||
342 | #define nist_set_256(to, from, a1, a2, a3, a4, a5, a6, a7, a8) \ | ||
343 | { \ | ||
344 | if (a8 != 0) bn_cp_32(to, 0, from, (a8) - 8) else bn_32_set_0(to, 0)\ | ||
345 | if (a7 != 0) bn_cp_32(to, 1, from, (a7) - 8) else bn_32_set_0(to, 1)\ | ||
346 | if (a6 != 0) bn_cp_32(to, 2, from, (a6) - 8) else bn_32_set_0(to, 2)\ | ||
347 | if (a5 != 0) bn_cp_32(to, 3, from, (a5) - 8) else bn_32_set_0(to, 3)\ | ||
348 | if (a4 != 0) bn_cp_32(to, 4, from, (a4) - 8) else bn_32_set_0(to, 4)\ | ||
349 | if (a3 != 0) bn_cp_32(to, 5, from, (a3) - 8) else bn_32_set_0(to, 5)\ | ||
350 | if (a2 != 0) bn_cp_32(to, 6, from, (a2) - 8) else bn_32_set_0(to, 6)\ | ||
351 | if (a1 != 0) bn_cp_32(to, 7, from, (a1) - 8) else bn_32_set_0(to, 7)\ | ||
352 | } | ||
353 | |||
354 | int BN_nist_mod_256(BIGNUM *r, const BIGNUM *a, const BIGNUM *field, | ||
355 | BN_CTX *ctx) | ||
356 | { | ||
357 | #if BN_BITS2 == 32 | ||
358 | int i, top = a->top; | ||
359 | int carry = 0; | ||
360 | register BN_ULONG *a_d = a->d, *r_d; | ||
361 | BN_ULONG t_d[BN_NIST_256_TOP], | ||
362 | buf[BN_NIST_256_TOP], | ||
363 | c_d[BN_NIST_256_TOP], | ||
364 | *res; | ||
365 | size_t mask; | ||
366 | |||
367 | i = BN_ucmp(field, a); | ||
368 | if (i == 0) | ||
369 | { | ||
370 | BN_zero(r); | ||
371 | return 1; | ||
372 | } | ||
373 | else if (i > 0) | ||
374 | return (r == a)? 1 : (BN_copy(r ,a) != NULL); | ||
375 | |||
376 | if (top == BN_NIST_256_TOP) | ||
377 | return BN_usub(r, a, field); | ||
378 | |||
379 | if (r != a) | ||
380 | { | ||
381 | if (!bn_wexpand(r, BN_NIST_256_TOP)) | ||
382 | return 0; | ||
383 | r_d = r->d; | ||
384 | nist_cp_bn(r_d, a_d, BN_NIST_256_TOP); | ||
385 | } | ||
386 | else | ||
387 | r_d = a_d; | ||
388 | |||
389 | nist_cp_bn_0(buf, a_d + BN_NIST_256_TOP, top - BN_NIST_256_TOP, BN_NIST_256_TOP); | ||
390 | |||
391 | /*S1*/ | ||
392 | nist_set_256(t_d, buf, 15, 14, 13, 12, 11, 0, 0, 0); | ||
393 | /*S2*/ | ||
394 | nist_set_256(c_d,buf, 0, 15, 14, 13, 12, 0, 0, 0); | ||
395 | carry = bn_add_words(t_d, t_d, c_d, BN_NIST_256_TOP); | ||
396 | mask = 0-(size_t)bn_sub_words(c_d,t_d,_nist_p_256,BN_NIST_256_TOP); | ||
397 | mask = ~mask | (0-(size_t)carry); | ||
398 | res = (BN_ULONG *)(((size_t)c_d&mask) | ((size_t)t_d&~mask)); | ||
399 | |||
400 | carry = bn_add_words(t_d, res, res, BN_NIST_256_TOP); | ||
401 | mask = 0-(size_t)bn_sub_words(c_d,t_d,_nist_p_256,BN_NIST_256_TOP); | ||
402 | mask = ~mask | (0-(size_t)carry); | ||
403 | res = (BN_ULONG *)(((size_t)c_d&mask) | ((size_t)t_d&~mask)); | ||
404 | |||
405 | carry = bn_add_words(r_d, r_d, res, BN_NIST_256_TOP); | ||
406 | mask = 0-(size_t)bn_sub_words(c_d,r_d,_nist_p_256,BN_NIST_256_TOP); | ||
407 | mask = ~mask | (0-(size_t)carry); | ||
408 | res = (BN_ULONG *)(((size_t)c_d&mask) | ((size_t)r_d&~mask)); | ||
409 | |||
410 | /*S3*/ | ||
411 | nist_set_256(t_d, buf, 15, 14, 0, 0, 0, 10, 9, 8); | ||
412 | carry = bn_add_words(r_d, res, t_d, BN_NIST_256_TOP); | ||
413 | mask = 0-(size_t)bn_sub_words(c_d,r_d,_nist_p_256,BN_NIST_256_TOP); | ||
414 | mask = ~mask | (0-(size_t)carry); | ||
415 | res = (BN_ULONG *)(((size_t)c_d&mask) | ((size_t)r_d&~mask)); | ||
416 | |||
417 | /*S4*/ | ||
418 | nist_set_256(t_d, buf, 8, 13, 15, 14, 13, 11, 10, 9); | ||
419 | carry = bn_add_words(r_d, res, t_d, BN_NIST_256_TOP); | ||
420 | mask = 0-(size_t)bn_sub_words(c_d,r_d,_nist_p_256,BN_NIST_256_TOP); | ||
421 | mask = ~mask | (0-(size_t)carry); | ||
422 | res = (BN_ULONG *)(((size_t)c_d&mask) | ((size_t)r_d&~mask)); | ||
423 | |||
424 | /*D1*/ | ||
425 | nist_set_256(t_d, buf, 10, 8, 0, 0, 0, 13, 12, 11); | ||
426 | #if BRANCH_FREE | ||
427 | carry = bn_sub_words(r_d, res, t_d, BN_NIST_256_TOP); | ||
428 | bn_add_words(c_d,r_d,_nist_p_256,BN_NIST_256_TOP); | ||
429 | mask = 0-(size_t)carry; | ||
430 | res = (BN_ULONG *)(((size_t)c_d&mask) | ((size_t)r_d&~mask)); | ||
431 | #else | ||
432 | if (bn_sub_words(r_d, res, t_d, BN_NIST_256_TOP)) | ||
433 | bn_add_words(r_d,r_d,_nist_p_256,BN_NIST_256_TOP); | ||
434 | #endif | ||
435 | /*D2*/ | ||
436 | nist_set_256(t_d, buf, 11, 9, 0, 0, 15, 14, 13, 12); | ||
437 | #if BRANCH_FREE | ||
438 | carry = bn_sub_words(r_d, res, t_d, BN_NIST_256_TOP); | ||
439 | bn_add_words(c_d,r_d,_nist_p_256,BN_NIST_256_TOP); | ||
440 | mask = 0-(size_t)carry; | ||
441 | res = (BN_ULONG *)(((size_t)c_d&mask) | ((size_t)r_d&~mask)); | ||
442 | #else | ||
443 | if (bn_sub_words(r_d, r_d, t_d, BN_NIST_256_TOP)) | ||
444 | bn_add_words(r_d,r_d,_nist_p_256,BN_NIST_256_TOP); | ||
445 | #endif | ||
446 | /*D3*/ | ||
447 | nist_set_256(t_d, buf, 12, 0, 10, 9, 8, 15, 14, 13); | ||
448 | #if BRANCH_FREE | ||
449 | carry = bn_sub_words(r_d, res, t_d, BN_NIST_256_TOP); | ||
450 | bn_add_words(c_d,r_d,_nist_p_256,BN_NIST_256_TOP); | ||
451 | mask = 0-(size_t)carry; | ||
452 | res = (BN_ULONG *)(((size_t)c_d&mask) | ((size_t)r_d&~mask)); | ||
453 | #else | ||
454 | if (bn_sub_words(r_d, r_d, t_d, BN_NIST_256_TOP)) | ||
455 | bn_add_words(r_d,r_d,_nist_p_256,BN_NIST_256_TOP); | ||
456 | #endif | ||
457 | /*D4*/ | ||
458 | nist_set_256(t_d, buf, 13, 0, 11, 10, 9, 0, 15, 14); | ||
459 | #if BRANCH_FREE | ||
460 | carry = bn_sub_words(r_d, res, t_d, BN_NIST_256_TOP); | ||
461 | bn_add_words(c_d,r_d,_nist_p_256,BN_NIST_256_TOP); | ||
462 | mask = 0-(size_t)carry; | ||
463 | res = (BN_ULONG *)(((size_t)c_d&mask) | ((size_t)r_d&~mask)); | ||
464 | |||
465 | nist_cp_bn(r_d, res, BN_NIST_384_TOP); | ||
466 | #else | ||
467 | if (bn_sub_words(r_d, r_d, t_d, BN_NIST_256_TOP)) | ||
468 | bn_add_words(r_d,r_d,_nist_p_256,BN_NIST_256_TOP); | ||
469 | #endif | ||
470 | r->top = BN_NIST_256_TOP; | ||
471 | bn_correct_top(r); | ||
472 | |||
473 | return 1; | ||
474 | #else /* BN_BITS!=32 */ | ||
475 | return 0; | ||
476 | #endif | ||
477 | } | ||
478 | |||
479 | #define nist_set_384(to,from,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12) \ | ||
480 | { \ | ||
481 | if (a12 != 0) bn_cp_32(to, 0, from, (a12) - 12) else bn_32_set_0(to, 0)\ | ||
482 | if (a11 != 0) bn_cp_32(to, 1, from, (a11) - 12) else bn_32_set_0(to, 1)\ | ||
483 | if (a10 != 0) bn_cp_32(to, 2, from, (a10) - 12) else bn_32_set_0(to, 2)\ | ||
484 | if (a9 != 0) bn_cp_32(to, 3, from, (a9) - 12) else bn_32_set_0(to, 3)\ | ||
485 | if (a8 != 0) bn_cp_32(to, 4, from, (a8) - 12) else bn_32_set_0(to, 4)\ | ||
486 | if (a7 != 0) bn_cp_32(to, 5, from, (a7) - 12) else bn_32_set_0(to, 5)\ | ||
487 | if (a6 != 0) bn_cp_32(to, 6, from, (a6) - 12) else bn_32_set_0(to, 6)\ | ||
488 | if (a5 != 0) bn_cp_32(to, 7, from, (a5) - 12) else bn_32_set_0(to, 7)\ | ||
489 | if (a4 != 0) bn_cp_32(to, 8, from, (a4) - 12) else bn_32_set_0(to, 8)\ | ||
490 | if (a3 != 0) bn_cp_32(to, 9, from, (a3) - 12) else bn_32_set_0(to, 9)\ | ||
491 | if (a2 != 0) bn_cp_32(to, 10, from, (a2) - 12) else bn_32_set_0(to, 10)\ | ||
492 | if (a1 != 0) bn_cp_32(to, 11, from, (a1) - 12) else bn_32_set_0(to, 11)\ | ||
493 | } | ||
494 | |||
495 | int BN_nist_mod_384(BIGNUM *r, const BIGNUM *a, const BIGNUM *field, | ||
496 | BN_CTX *ctx) | ||
497 | { | ||
498 | #if BN_BITS2 == 32 | ||
499 | int i, top = a->top; | ||
500 | int carry = 0; | ||
501 | register BN_ULONG *r_d, *a_d = a->d; | ||
502 | BN_ULONG t_d[BN_NIST_384_TOP], | ||
503 | buf[BN_NIST_384_TOP], | ||
504 | c_d[BN_NIST_384_TOP], | ||
505 | *res; | ||
506 | size_t mask; | ||
507 | |||
508 | i = BN_ucmp(field, a); | ||
509 | if (i == 0) | ||
510 | { | ||
511 | BN_zero(r); | ||
512 | return 1; | ||
513 | } | ||
514 | else if (i > 0) | ||
515 | return (r == a)? 1 : (BN_copy(r ,a) != NULL); | ||
516 | |||
517 | if (top == BN_NIST_384_TOP) | ||
518 | return BN_usub(r, a, field); | ||
519 | |||
520 | if (r != a) | ||
521 | { | ||
522 | if (!bn_wexpand(r, BN_NIST_384_TOP)) | ||
523 | return 0; | ||
524 | r_d = r->d; | ||
525 | nist_cp_bn(r_d, a_d, BN_NIST_384_TOP); | ||
526 | } | ||
527 | else | ||
528 | r_d = a_d; | ||
529 | |||
530 | nist_cp_bn_0(buf, a_d + BN_NIST_384_TOP, top - BN_NIST_384_TOP, BN_NIST_384_TOP); | ||
531 | |||
532 | /*S1*/ | ||
533 | nist_set_256(t_d, buf, 0, 0, 0, 0, 0, 23-4, 22-4, 21-4); | ||
534 | /* left shift */ | ||
535 | { | ||
536 | register BN_ULONG *ap,t,c; | ||
537 | ap = t_d; | ||
538 | c=0; | ||
539 | for (i = 3; i != 0; --i) | ||
540 | { | ||
541 | t= *ap; | ||
542 | *(ap++)=((t<<1)|c)&BN_MASK2; | ||
543 | c=(t & BN_TBIT)?1:0; | ||
544 | } | ||
545 | *ap=c; | ||
546 | } | ||
547 | carry = bn_add_words(r_d+(128/BN_BITS2), r_d+(128/BN_BITS2), | ||
548 | t_d, BN_NIST_256_TOP); | ||
549 | /* | ||
550 | * we need if (result>=modulus) subtract(result,modulus); | ||
551 | * in n-bit space this can be expressed as | ||
552 | * if (carry || result>=modulus) subtract(result,modulus); | ||
553 | * the catch is that comparison implies subtraction and | ||
554 | * therefore one can write tmp=subtract(result,modulus); | ||
555 | * and then if(carry || !borrow) result=tmp; this's what | ||
556 | * happens below, but without explicit if:-) a. | ||
557 | */ | ||
558 | mask = 0-(size_t)bn_sub_words(c_d,r_d,_nist_p_384,BN_NIST_384_TOP); | ||
559 | mask = ~mask | (0-(size_t)carry); | ||
560 | res = (BN_ULONG *)(((size_t)c_d&mask) | ((size_t)r_d&~mask)); | ||
561 | |||
562 | /*S2 */ | ||
563 | carry = bn_add_words(r_d, res, buf, BN_NIST_384_TOP); | ||
564 | mask = 0-(size_t)bn_sub_words(c_d,r_d,_nist_p_384,BN_NIST_384_TOP); | ||
565 | mask = ~mask | (0-(size_t)carry); | ||
566 | res = (BN_ULONG *)(((size_t)c_d&mask) | ((size_t)r_d&~mask)); | ||
567 | |||
568 | /*S3*/ | ||
569 | nist_set_384(t_d,buf,20,19,18,17,16,15,14,13,12,23,22,21); | ||
570 | carry = bn_add_words(r_d, res, t_d, BN_NIST_384_TOP); | ||
571 | mask = 0-(size_t)bn_sub_words(c_d,r_d,_nist_p_384,BN_NIST_384_TOP); | ||
572 | mask = ~mask | (0-(size_t)carry); | ||
573 | res = (BN_ULONG *)(((size_t)c_d&mask) | ((size_t)r_d&~mask)); | ||
574 | |||
575 | /*S4*/ | ||
576 | nist_set_384(t_d,buf,19,18,17,16,15,14,13,12,20,0,23,0); | ||
577 | carry = bn_add_words(r_d, res, t_d, BN_NIST_384_TOP); | ||
578 | mask = 0-(size_t)bn_sub_words(c_d,r_d,_nist_p_384,BN_NIST_384_TOP); | ||
579 | mask = ~mask | (0-(size_t)carry); | ||
580 | res = (BN_ULONG *)(((size_t)c_d&mask) | ((size_t)r_d&~mask)); | ||
581 | |||
582 | /*S5*/ | ||
583 | nist_set_384(t_d, buf,0,0,0,0,23,22,21,20,0,0,0,0); | ||
584 | carry = bn_add_words(r_d, res, t_d, BN_NIST_384_TOP); | ||
585 | mask = 0-(size_t)bn_sub_words(c_d,r_d,_nist_p_384,BN_NIST_384_TOP); | ||
586 | mask = ~mask | (0-(size_t)carry); | ||
587 | res = (BN_ULONG *)(((size_t)c_d&mask) | ((size_t)r_d&~mask)); | ||
588 | |||
589 | /*S6*/ | ||
590 | nist_set_384(t_d,buf,0,0,0,0,0,0,23,22,21,0,0,20); | ||
591 | carry = bn_add_words(r_d, res, t_d, BN_NIST_384_TOP); | ||
592 | mask = 0-(size_t)bn_sub_words(c_d,r_d,_nist_p_384,BN_NIST_384_TOP); | ||
593 | mask = ~mask | (0-(size_t)carry); | ||
594 | res = (BN_ULONG *)(((size_t)c_d&mask) | ((size_t)r_d&~mask)); | ||
595 | |||
596 | /*D1*/ | ||
597 | nist_set_384(t_d,buf,22,21,20,19,18,17,16,15,14,13,12,23); | ||
598 | #if BRANCH_FREE | ||
599 | carry = bn_sub_words(r_d, res, t_d, BN_NIST_384_TOP); | ||
600 | bn_add_words(c_d,r_d,_nist_p_384,BN_NIST_384_TOP); | ||
601 | mask = 0-(size_t)carry; | ||
602 | res = (BN_ULONG *)(((size_t)c_d&mask) | ((size_t)r_d&~mask)); | ||
603 | #else | ||
604 | if (bn_sub_words(r_d, res, t_d, BN_NIST_384_TOP)) | ||
605 | bn_add_words(r_d,r_d,_nist_p_384,BN_NIST_384_TOP); | ||
606 | #endif | ||
607 | /*D2*/ | ||
608 | nist_set_384(t_d,buf,0,0,0,0,0,0,0,23,22,21,20,0); | ||
609 | #if BRANCH_FREE | ||
610 | carry = bn_sub_words(r_d, res, t_d, BN_NIST_384_TOP); | ||
611 | bn_add_words(c_d,r_d,_nist_p_384,BN_NIST_384_TOP); | ||
612 | mask = 0-(size_t)carry; | ||
613 | res = (BN_ULONG *)(((size_t)c_d&mask) | ((size_t)r_d&~mask)); | ||
614 | #else | ||
615 | if (bn_sub_words(r_d, r_d, t_d, BN_NIST_384_TOP)) | ||
616 | bn_add_words(r_d,r_d,_nist_p_384,BN_NIST_384_TOP); | ||
617 | #endif | ||
618 | /*D3*/ | ||
619 | nist_set_384(t_d,buf,0,0,0,0,0,0,0,23,23,0,0,0); | ||
620 | #if BRANCH_FREE | ||
621 | carry = bn_sub_words(r_d, res, t_d, BN_NIST_384_TOP); | ||
622 | bn_add_words(c_d,r_d,_nist_p_384,BN_NIST_384_TOP); | ||
623 | mask = 0-(size_t)carry; | ||
624 | res = (BN_ULONG *)(((size_t)c_d&mask) | ((size_t)r_d&~mask)); | ||
625 | |||
626 | nist_cp_bn(r_d, res, BN_NIST_384_TOP); | ||
627 | #else | ||
628 | if (bn_sub_words(r_d, r_d, t_d, BN_NIST_384_TOP)) | ||
629 | bn_add_words(r_d,r_d,_nist_p_384,BN_NIST_384_TOP); | ||
630 | #endif | ||
631 | r->top = BN_NIST_384_TOP; | ||
632 | bn_correct_top(r); | ||
633 | |||
634 | return 1; | ||
635 | #else /* BN_BITS!=32 */ | ||
636 | return 0; | ||
637 | #endif | ||
638 | } | ||
639 | |||
640 | int BN_nist_mod_521(BIGNUM *r, const BIGNUM *a, const BIGNUM *field, | ||
641 | BN_CTX *ctx) | ||
642 | { | ||
643 | #if BN_BITS2 == 64 | ||
644 | #define BN_NIST_521_TOP_MASK (BN_ULONG)0x1FF | ||
645 | #elif BN_BITS2 == 32 | ||
646 | #define BN_NIST_521_TOP_MASK (BN_ULONG)0x1FF | ||
647 | #endif | ||
648 | int top, ret = 0; | ||
649 | BN_ULONG *r_d; | ||
650 | BIGNUM *tmp; | ||
651 | |||
652 | /* check whether a reduction is necessary */ | ||
653 | top = a->top; | ||
654 | if (top < BN_NIST_521_TOP || ( top == BN_NIST_521_TOP && | ||
655 | (!(a->d[BN_NIST_521_TOP-1] & ~(BN_NIST_521_TOP_MASK))))) | ||
656 | return (r == a)? 1 : (BN_copy(r ,a) != NULL); | ||
657 | |||
658 | BN_CTX_start(ctx); | ||
659 | tmp = BN_CTX_get(ctx); | ||
660 | if (!tmp) | ||
661 | goto err; | ||
662 | |||
663 | if (!bn_wexpand(tmp, BN_NIST_521_TOP)) | ||
664 | goto err; | ||
665 | nist_cp_bn(tmp->d, a->d, BN_NIST_521_TOP); | ||
666 | |||
667 | tmp->top = BN_NIST_521_TOP; | ||
668 | tmp->d[BN_NIST_521_TOP-1] &= BN_NIST_521_TOP_MASK; | ||
669 | bn_correct_top(tmp); | ||
670 | |||
671 | if (!BN_rshift(r, a, 521)) | ||
672 | goto err; | ||
673 | |||
674 | if (!BN_uadd(r, tmp, r)) | ||
675 | goto err; | ||
676 | top = r->top; | ||
677 | r_d = r->d; | ||
678 | if (top == BN_NIST_521_TOP && | ||
679 | (r_d[BN_NIST_521_TOP-1] & ~(BN_NIST_521_TOP_MASK))) | ||
680 | { | ||
681 | BN_NIST_ADD_ONE(r_d) | ||
682 | r->d[BN_NIST_521_TOP-1] &= BN_NIST_521_TOP_MASK; | ||
683 | } | ||
684 | bn_correct_top(r); | ||
685 | |||
686 | ret = 1; | ||
687 | err: | ||
688 | BN_CTX_end(ctx); | ||
689 | |||
690 | bn_check_top(r); | ||
691 | return ret; | ||
692 | } | ||
diff --git a/src/lib/libcrypto/camellia/camellia.c b/src/lib/libcrypto/camellia/camellia.c new file mode 100644 index 0000000000..491c26b39e --- /dev/null +++ b/src/lib/libcrypto/camellia/camellia.c | |||
@@ -0,0 +1,1624 @@ | |||
1 | /* crypto/camellia/camellia.c -*- mode:C; c-file-style: "eay" -*- */ | ||
2 | /* ==================================================================== | ||
3 | * Copyright 2006 NTT (Nippon Telegraph and Telephone Corporation) . | ||
4 | * ALL RIGHTS RESERVED. | ||
5 | * | ||
6 | * Intellectual Property information for Camellia: | ||
7 | * http://info.isl.ntt.co.jp/crypt/eng/info/chiteki.html | ||
8 | * | ||
9 | * News Release for Announcement of Camellia open source: | ||
10 | * http://www.ntt.co.jp/news/news06e/0604/060413a.html | ||
11 | * | ||
12 | * The Camellia Code included herein is developed by | ||
13 | * NTT (Nippon Telegraph and Telephone Corporation), and is contributed | ||
14 | * to the OpenSSL project. | ||
15 | * | ||
16 | * The Camellia Code is licensed pursuant to the OpenSSL open source | ||
17 | * license provided below. | ||
18 | */ | ||
19 | /* ==================================================================== | ||
20 | * Copyright (c) 2006 The OpenSSL Project. All rights reserved. | ||
21 | * | ||
22 | * Redistribution and use in source and binary forms, with or without | ||
23 | * modification, are permitted provided that the following conditions | ||
24 | * are met: | ||
25 | * | ||
26 | * 1. Redistributions of source code must retain the above copyright | ||
27 | * notice, this list of conditions and the following disclaimer. | ||
28 | * | ||
29 | * 2. Redistributions in binary form must reproduce the above copyright | ||
30 | * notice, this list of conditions and the following disclaimer in | ||
31 | * the documentation and/or other materials provided with the | ||
32 | * distribution. | ||
33 | * | ||
34 | * 3. All advertising materials mentioning features or use of this | ||
35 | * software must display the following acknowledgment: | ||
36 | * "This product includes software developed by the OpenSSL Project | ||
37 | * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" | ||
38 | * | ||
39 | * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to | ||
40 | * endorse or promote products derived from this software without | ||
41 | * prior written permission. For written permission, please contact | ||
42 | * openssl-core@openssl.org. | ||
43 | * | ||
44 | * 5. Products derived from this software may not be called "OpenSSL" | ||
45 | * nor may "OpenSSL" appear in their names without prior written | ||
46 | * permission of the OpenSSL Project. | ||
47 | * | ||
48 | * 6. Redistributions of any form whatsoever must retain the following | ||
49 | * acknowledgment: | ||
50 | * "This product includes software developed by the OpenSSL Project | ||
51 | * for use in the OpenSSL Toolkit (http://www.openssl.org/)" | ||
52 | * | ||
53 | * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY | ||
54 | * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
55 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | ||
56 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR | ||
57 | * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
58 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
59 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
60 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
61 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
62 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
63 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED | ||
64 | * OF THE POSSIBILITY OF SUCH DAMAGE. | ||
65 | * ==================================================================== | ||
66 | */ | ||
67 | |||
68 | /* Algorithm Specification | ||
69 | http://info.isl.ntt.co.jp/crypt/eng/camellia/specifications.html | ||
70 | */ | ||
71 | |||
72 | |||
73 | #include <string.h> | ||
74 | #include <stdlib.h> | ||
75 | |||
76 | #include "camellia.h" | ||
77 | #include "cmll_locl.h" | ||
78 | |||
79 | /* key constants */ | ||
80 | #define CAMELLIA_SIGMA1L (0xA09E667FL) | ||
81 | #define CAMELLIA_SIGMA1R (0x3BCC908BL) | ||
82 | #define CAMELLIA_SIGMA2L (0xB67AE858L) | ||
83 | #define CAMELLIA_SIGMA2R (0x4CAA73B2L) | ||
84 | #define CAMELLIA_SIGMA3L (0xC6EF372FL) | ||
85 | #define CAMELLIA_SIGMA3R (0xE94F82BEL) | ||
86 | #define CAMELLIA_SIGMA4L (0x54FF53A5L) | ||
87 | #define CAMELLIA_SIGMA4R (0xF1D36F1CL) | ||
88 | #define CAMELLIA_SIGMA5L (0x10E527FAL) | ||
89 | #define CAMELLIA_SIGMA5R (0xDE682D1DL) | ||
90 | #define CAMELLIA_SIGMA6L (0xB05688C2L) | ||
91 | #define CAMELLIA_SIGMA6R (0xB3E6C1FDL) | ||
92 | |||
93 | /* | ||
94 | * macros | ||
95 | */ | ||
96 | |||
97 | /* e is pointer of subkey */ | ||
98 | #define CamelliaSubkeyL(INDEX) (subkey[(INDEX)*2]) | ||
99 | #define CamelliaSubkeyR(INDEX) (subkey[(INDEX)*2 + 1]) | ||
100 | |||
101 | /* rotation right shift 1byte */ | ||
102 | #define CAMELLIA_RR8(x) (((x) >> 8) + ((x) << 24)) | ||
103 | /* rotation left shift 1bit */ | ||
104 | #define CAMELLIA_RL1(x) (((x) << 1) + ((x) >> 31)) | ||
105 | /* rotation left shift 1byte */ | ||
106 | #define CAMELLIA_RL8(x) (((x) << 8) + ((x) >> 24)) | ||
107 | |||
108 | #define CAMELLIA_ROLDQ(ll, lr, rl, rr, w0, w1, bits) \ | ||
109 | do \ | ||
110 | { \ | ||
111 | w0 = ll; \ | ||
112 | ll = (ll << bits) + (lr >> (32 - bits)); \ | ||
113 | lr = (lr << bits) + (rl >> (32 - bits)); \ | ||
114 | rl = (rl << bits) + (rr >> (32 - bits)); \ | ||
115 | rr = (rr << bits) + (w0 >> (32 - bits)); \ | ||
116 | } while(0) | ||
117 | |||
118 | #define CAMELLIA_ROLDQo32(ll, lr, rl, rr, w0, w1, bits) \ | ||
119 | do \ | ||
120 | { \ | ||
121 | w0 = ll; \ | ||
122 | w1 = lr; \ | ||
123 | ll = (lr << (bits - 32)) + (rl >> (64 - bits)); \ | ||
124 | lr = (rl << (bits - 32)) + (rr >> (64 - bits)); \ | ||
125 | rl = (rr << (bits - 32)) + (w0 >> (64 - bits)); \ | ||
126 | rr = (w0 << (bits - 32)) + (w1 >> (64 - bits)); \ | ||
127 | } while(0) | ||
128 | |||
129 | #define CAMELLIA_SP1110(INDEX) (camellia_sp1110[(INDEX)]) | ||
130 | #define CAMELLIA_SP0222(INDEX) (camellia_sp0222[(INDEX)]) | ||
131 | #define CAMELLIA_SP3033(INDEX) (camellia_sp3033[(INDEX)]) | ||
132 | #define CAMELLIA_SP4404(INDEX) (camellia_sp4404[(INDEX)]) | ||
133 | |||
134 | #define CAMELLIA_F(xl, xr, kl, kr, yl, yr, il, ir, t0, t1) \ | ||
135 | do \ | ||
136 | { \ | ||
137 | il = xl ^ kl; \ | ||
138 | ir = xr ^ kr; \ | ||
139 | t0 = il >> 16; \ | ||
140 | t1 = ir >> 16; \ | ||
141 | yl = CAMELLIA_SP1110(ir & 0xff) \ | ||
142 | ^ CAMELLIA_SP0222((t1 >> 8) & 0xff) \ | ||
143 | ^ CAMELLIA_SP3033(t1 & 0xff) \ | ||
144 | ^ CAMELLIA_SP4404((ir >> 8) & 0xff); \ | ||
145 | yr = CAMELLIA_SP1110((t0 >> 8) & 0xff) \ | ||
146 | ^ CAMELLIA_SP0222(t0 & 0xff) \ | ||
147 | ^ CAMELLIA_SP3033((il >> 8) & 0xff) \ | ||
148 | ^ CAMELLIA_SP4404(il & 0xff); \ | ||
149 | yl ^= yr; \ | ||
150 | yr = CAMELLIA_RR8(yr); \ | ||
151 | yr ^= yl; \ | ||
152 | } while(0) | ||
153 | |||
154 | |||
155 | /* | ||
156 | * for speed up | ||
157 | * | ||
158 | */ | ||
159 | #define CAMELLIA_FLS(ll, lr, rl, rr, kll, klr, krl, krr, t0, t1, t2, t3) \ | ||
160 | do \ | ||
161 | { \ | ||
162 | t0 = kll; \ | ||
163 | t0 &= ll; \ | ||
164 | lr ^= CAMELLIA_RL1(t0); \ | ||
165 | t1 = klr; \ | ||
166 | t1 |= lr; \ | ||
167 | ll ^= t1; \ | ||
168 | \ | ||
169 | t2 = krr; \ | ||
170 | t2 |= rr; \ | ||
171 | rl ^= t2; \ | ||
172 | t3 = krl; \ | ||
173 | t3 &= rl; \ | ||
174 | rr ^= CAMELLIA_RL1(t3); \ | ||
175 | } while(0) | ||
176 | |||
177 | #define CAMELLIA_ROUNDSM(xl, xr, kl, kr, yl, yr, il, ir, t0, t1) \ | ||
178 | do \ | ||
179 | { \ | ||
180 | il = xl; \ | ||
181 | ir = xr; \ | ||
182 | t0 = il >> 16; \ | ||
183 | t1 = ir >> 16; \ | ||
184 | ir = CAMELLIA_SP1110(ir & 0xff) \ | ||
185 | ^ CAMELLIA_SP0222((t1 >> 8) & 0xff) \ | ||
186 | ^ CAMELLIA_SP3033(t1 & 0xff) \ | ||
187 | ^ CAMELLIA_SP4404((ir >> 8) & 0xff); \ | ||
188 | il = CAMELLIA_SP1110((t0 >> 8) & 0xff) \ | ||
189 | ^ CAMELLIA_SP0222(t0 & 0xff) \ | ||
190 | ^ CAMELLIA_SP3033((il >> 8) & 0xff) \ | ||
191 | ^ CAMELLIA_SP4404(il & 0xff); \ | ||
192 | il ^= kl; \ | ||
193 | ir ^= kr; \ | ||
194 | ir ^= il; \ | ||
195 | il = CAMELLIA_RR8(il); \ | ||
196 | il ^= ir; \ | ||
197 | yl ^= ir; \ | ||
198 | yr ^= il; \ | ||
199 | } while(0) | ||
200 | |||
201 | static const u32 camellia_sp1110[256] = | ||
202 | { | ||
203 | 0x70707000,0x82828200,0x2c2c2c00,0xececec00, | ||
204 | 0xb3b3b300,0x27272700,0xc0c0c000,0xe5e5e500, | ||
205 | 0xe4e4e400,0x85858500,0x57575700,0x35353500, | ||
206 | 0xeaeaea00,0x0c0c0c00,0xaeaeae00,0x41414100, | ||
207 | 0x23232300,0xefefef00,0x6b6b6b00,0x93939300, | ||
208 | 0x45454500,0x19191900,0xa5a5a500,0x21212100, | ||
209 | 0xededed00,0x0e0e0e00,0x4f4f4f00,0x4e4e4e00, | ||
210 | 0x1d1d1d00,0x65656500,0x92929200,0xbdbdbd00, | ||
211 | 0x86868600,0xb8b8b800,0xafafaf00,0x8f8f8f00, | ||
212 | 0x7c7c7c00,0xebebeb00,0x1f1f1f00,0xcecece00, | ||
213 | 0x3e3e3e00,0x30303000,0xdcdcdc00,0x5f5f5f00, | ||
214 | 0x5e5e5e00,0xc5c5c500,0x0b0b0b00,0x1a1a1a00, | ||
215 | 0xa6a6a600,0xe1e1e100,0x39393900,0xcacaca00, | ||
216 | 0xd5d5d500,0x47474700,0x5d5d5d00,0x3d3d3d00, | ||
217 | 0xd9d9d900,0x01010100,0x5a5a5a00,0xd6d6d600, | ||
218 | 0x51515100,0x56565600,0x6c6c6c00,0x4d4d4d00, | ||
219 | 0x8b8b8b00,0x0d0d0d00,0x9a9a9a00,0x66666600, | ||
220 | 0xfbfbfb00,0xcccccc00,0xb0b0b000,0x2d2d2d00, | ||
221 | 0x74747400,0x12121200,0x2b2b2b00,0x20202000, | ||
222 | 0xf0f0f000,0xb1b1b100,0x84848400,0x99999900, | ||
223 | 0xdfdfdf00,0x4c4c4c00,0xcbcbcb00,0xc2c2c200, | ||
224 | 0x34343400,0x7e7e7e00,0x76767600,0x05050500, | ||
225 | 0x6d6d6d00,0xb7b7b700,0xa9a9a900,0x31313100, | ||
226 | 0xd1d1d100,0x17171700,0x04040400,0xd7d7d700, | ||
227 | 0x14141400,0x58585800,0x3a3a3a00,0x61616100, | ||
228 | 0xdedede00,0x1b1b1b00,0x11111100,0x1c1c1c00, | ||
229 | 0x32323200,0x0f0f0f00,0x9c9c9c00,0x16161600, | ||
230 | 0x53535300,0x18181800,0xf2f2f200,0x22222200, | ||
231 | 0xfefefe00,0x44444400,0xcfcfcf00,0xb2b2b200, | ||
232 | 0xc3c3c300,0xb5b5b500,0x7a7a7a00,0x91919100, | ||
233 | 0x24242400,0x08080800,0xe8e8e800,0xa8a8a800, | ||
234 | 0x60606000,0xfcfcfc00,0x69696900,0x50505000, | ||
235 | 0xaaaaaa00,0xd0d0d000,0xa0a0a000,0x7d7d7d00, | ||
236 | 0xa1a1a100,0x89898900,0x62626200,0x97979700, | ||
237 | 0x54545400,0x5b5b5b00,0x1e1e1e00,0x95959500, | ||
238 | 0xe0e0e000,0xffffff00,0x64646400,0xd2d2d200, | ||
239 | 0x10101000,0xc4c4c400,0x00000000,0x48484800, | ||
240 | 0xa3a3a300,0xf7f7f700,0x75757500,0xdbdbdb00, | ||
241 | 0x8a8a8a00,0x03030300,0xe6e6e600,0xdadada00, | ||
242 | 0x09090900,0x3f3f3f00,0xdddddd00,0x94949400, | ||
243 | 0x87878700,0x5c5c5c00,0x83838300,0x02020200, | ||
244 | 0xcdcdcd00,0x4a4a4a00,0x90909000,0x33333300, | ||
245 | 0x73737300,0x67676700,0xf6f6f600,0xf3f3f300, | ||
246 | 0x9d9d9d00,0x7f7f7f00,0xbfbfbf00,0xe2e2e200, | ||
247 | 0x52525200,0x9b9b9b00,0xd8d8d800,0x26262600, | ||
248 | 0xc8c8c800,0x37373700,0xc6c6c600,0x3b3b3b00, | ||
249 | 0x81818100,0x96969600,0x6f6f6f00,0x4b4b4b00, | ||
250 | 0x13131300,0xbebebe00,0x63636300,0x2e2e2e00, | ||
251 | 0xe9e9e900,0x79797900,0xa7a7a700,0x8c8c8c00, | ||
252 | 0x9f9f9f00,0x6e6e6e00,0xbcbcbc00,0x8e8e8e00, | ||
253 | 0x29292900,0xf5f5f500,0xf9f9f900,0xb6b6b600, | ||
254 | 0x2f2f2f00,0xfdfdfd00,0xb4b4b400,0x59595900, | ||
255 | 0x78787800,0x98989800,0x06060600,0x6a6a6a00, | ||
256 | 0xe7e7e700,0x46464600,0x71717100,0xbababa00, | ||
257 | 0xd4d4d400,0x25252500,0xababab00,0x42424200, | ||
258 | 0x88888800,0xa2a2a200,0x8d8d8d00,0xfafafa00, | ||
259 | 0x72727200,0x07070700,0xb9b9b900,0x55555500, | ||
260 | 0xf8f8f800,0xeeeeee00,0xacacac00,0x0a0a0a00, | ||
261 | 0x36363600,0x49494900,0x2a2a2a00,0x68686800, | ||
262 | 0x3c3c3c00,0x38383800,0xf1f1f100,0xa4a4a400, | ||
263 | 0x40404000,0x28282800,0xd3d3d300,0x7b7b7b00, | ||
264 | 0xbbbbbb00,0xc9c9c900,0x43434300,0xc1c1c100, | ||
265 | 0x15151500,0xe3e3e300,0xadadad00,0xf4f4f400, | ||
266 | 0x77777700,0xc7c7c700,0x80808000,0x9e9e9e00, | ||
267 | }; | ||
268 | |||
269 | static const u32 camellia_sp0222[256] = | ||
270 | { | ||
271 | 0x00e0e0e0,0x00050505,0x00585858,0x00d9d9d9, | ||
272 | 0x00676767,0x004e4e4e,0x00818181,0x00cbcbcb, | ||
273 | 0x00c9c9c9,0x000b0b0b,0x00aeaeae,0x006a6a6a, | ||
274 | 0x00d5d5d5,0x00181818,0x005d5d5d,0x00828282, | ||
275 | 0x00464646,0x00dfdfdf,0x00d6d6d6,0x00272727, | ||
276 | 0x008a8a8a,0x00323232,0x004b4b4b,0x00424242, | ||
277 | 0x00dbdbdb,0x001c1c1c,0x009e9e9e,0x009c9c9c, | ||
278 | 0x003a3a3a,0x00cacaca,0x00252525,0x007b7b7b, | ||
279 | 0x000d0d0d,0x00717171,0x005f5f5f,0x001f1f1f, | ||
280 | 0x00f8f8f8,0x00d7d7d7,0x003e3e3e,0x009d9d9d, | ||
281 | 0x007c7c7c,0x00606060,0x00b9b9b9,0x00bebebe, | ||
282 | 0x00bcbcbc,0x008b8b8b,0x00161616,0x00343434, | ||
283 | 0x004d4d4d,0x00c3c3c3,0x00727272,0x00959595, | ||
284 | 0x00ababab,0x008e8e8e,0x00bababa,0x007a7a7a, | ||
285 | 0x00b3b3b3,0x00020202,0x00b4b4b4,0x00adadad, | ||
286 | 0x00a2a2a2,0x00acacac,0x00d8d8d8,0x009a9a9a, | ||
287 | 0x00171717,0x001a1a1a,0x00353535,0x00cccccc, | ||
288 | 0x00f7f7f7,0x00999999,0x00616161,0x005a5a5a, | ||
289 | 0x00e8e8e8,0x00242424,0x00565656,0x00404040, | ||
290 | 0x00e1e1e1,0x00636363,0x00090909,0x00333333, | ||
291 | 0x00bfbfbf,0x00989898,0x00979797,0x00858585, | ||
292 | 0x00686868,0x00fcfcfc,0x00ececec,0x000a0a0a, | ||
293 | 0x00dadada,0x006f6f6f,0x00535353,0x00626262, | ||
294 | 0x00a3a3a3,0x002e2e2e,0x00080808,0x00afafaf, | ||
295 | 0x00282828,0x00b0b0b0,0x00747474,0x00c2c2c2, | ||
296 | 0x00bdbdbd,0x00363636,0x00222222,0x00383838, | ||
297 | 0x00646464,0x001e1e1e,0x00393939,0x002c2c2c, | ||
298 | 0x00a6a6a6,0x00303030,0x00e5e5e5,0x00444444, | ||
299 | 0x00fdfdfd,0x00888888,0x009f9f9f,0x00656565, | ||
300 | 0x00878787,0x006b6b6b,0x00f4f4f4,0x00232323, | ||
301 | 0x00484848,0x00101010,0x00d1d1d1,0x00515151, | ||
302 | 0x00c0c0c0,0x00f9f9f9,0x00d2d2d2,0x00a0a0a0, | ||
303 | 0x00555555,0x00a1a1a1,0x00414141,0x00fafafa, | ||
304 | 0x00434343,0x00131313,0x00c4c4c4,0x002f2f2f, | ||
305 | 0x00a8a8a8,0x00b6b6b6,0x003c3c3c,0x002b2b2b, | ||
306 | 0x00c1c1c1,0x00ffffff,0x00c8c8c8,0x00a5a5a5, | ||
307 | 0x00202020,0x00898989,0x00000000,0x00909090, | ||
308 | 0x00474747,0x00efefef,0x00eaeaea,0x00b7b7b7, | ||
309 | 0x00151515,0x00060606,0x00cdcdcd,0x00b5b5b5, | ||
310 | 0x00121212,0x007e7e7e,0x00bbbbbb,0x00292929, | ||
311 | 0x000f0f0f,0x00b8b8b8,0x00070707,0x00040404, | ||
312 | 0x009b9b9b,0x00949494,0x00212121,0x00666666, | ||
313 | 0x00e6e6e6,0x00cecece,0x00ededed,0x00e7e7e7, | ||
314 | 0x003b3b3b,0x00fefefe,0x007f7f7f,0x00c5c5c5, | ||
315 | 0x00a4a4a4,0x00373737,0x00b1b1b1,0x004c4c4c, | ||
316 | 0x00919191,0x006e6e6e,0x008d8d8d,0x00767676, | ||
317 | 0x00030303,0x002d2d2d,0x00dedede,0x00969696, | ||
318 | 0x00262626,0x007d7d7d,0x00c6c6c6,0x005c5c5c, | ||
319 | 0x00d3d3d3,0x00f2f2f2,0x004f4f4f,0x00191919, | ||
320 | 0x003f3f3f,0x00dcdcdc,0x00797979,0x001d1d1d, | ||
321 | 0x00525252,0x00ebebeb,0x00f3f3f3,0x006d6d6d, | ||
322 | 0x005e5e5e,0x00fbfbfb,0x00696969,0x00b2b2b2, | ||
323 | 0x00f0f0f0,0x00313131,0x000c0c0c,0x00d4d4d4, | ||
324 | 0x00cfcfcf,0x008c8c8c,0x00e2e2e2,0x00757575, | ||
325 | 0x00a9a9a9,0x004a4a4a,0x00575757,0x00848484, | ||
326 | 0x00111111,0x00454545,0x001b1b1b,0x00f5f5f5, | ||
327 | 0x00e4e4e4,0x000e0e0e,0x00737373,0x00aaaaaa, | ||
328 | 0x00f1f1f1,0x00dddddd,0x00595959,0x00141414, | ||
329 | 0x006c6c6c,0x00929292,0x00545454,0x00d0d0d0, | ||
330 | 0x00787878,0x00707070,0x00e3e3e3,0x00494949, | ||
331 | 0x00808080,0x00505050,0x00a7a7a7,0x00f6f6f6, | ||
332 | 0x00777777,0x00939393,0x00868686,0x00838383, | ||
333 | 0x002a2a2a,0x00c7c7c7,0x005b5b5b,0x00e9e9e9, | ||
334 | 0x00eeeeee,0x008f8f8f,0x00010101,0x003d3d3d, | ||
335 | }; | ||
336 | |||
337 | static const u32 camellia_sp3033[256] = | ||
338 | { | ||
339 | 0x38003838,0x41004141,0x16001616,0x76007676, | ||
340 | 0xd900d9d9,0x93009393,0x60006060,0xf200f2f2, | ||
341 | 0x72007272,0xc200c2c2,0xab00abab,0x9a009a9a, | ||
342 | 0x75007575,0x06000606,0x57005757,0xa000a0a0, | ||
343 | 0x91009191,0xf700f7f7,0xb500b5b5,0xc900c9c9, | ||
344 | 0xa200a2a2,0x8c008c8c,0xd200d2d2,0x90009090, | ||
345 | 0xf600f6f6,0x07000707,0xa700a7a7,0x27002727, | ||
346 | 0x8e008e8e,0xb200b2b2,0x49004949,0xde00dede, | ||
347 | 0x43004343,0x5c005c5c,0xd700d7d7,0xc700c7c7, | ||
348 | 0x3e003e3e,0xf500f5f5,0x8f008f8f,0x67006767, | ||
349 | 0x1f001f1f,0x18001818,0x6e006e6e,0xaf00afaf, | ||
350 | 0x2f002f2f,0xe200e2e2,0x85008585,0x0d000d0d, | ||
351 | 0x53005353,0xf000f0f0,0x9c009c9c,0x65006565, | ||
352 | 0xea00eaea,0xa300a3a3,0xae00aeae,0x9e009e9e, | ||
353 | 0xec00ecec,0x80008080,0x2d002d2d,0x6b006b6b, | ||
354 | 0xa800a8a8,0x2b002b2b,0x36003636,0xa600a6a6, | ||
355 | 0xc500c5c5,0x86008686,0x4d004d4d,0x33003333, | ||
356 | 0xfd00fdfd,0x66006666,0x58005858,0x96009696, | ||
357 | 0x3a003a3a,0x09000909,0x95009595,0x10001010, | ||
358 | 0x78007878,0xd800d8d8,0x42004242,0xcc00cccc, | ||
359 | 0xef00efef,0x26002626,0xe500e5e5,0x61006161, | ||
360 | 0x1a001a1a,0x3f003f3f,0x3b003b3b,0x82008282, | ||
361 | 0xb600b6b6,0xdb00dbdb,0xd400d4d4,0x98009898, | ||
362 | 0xe800e8e8,0x8b008b8b,0x02000202,0xeb00ebeb, | ||
363 | 0x0a000a0a,0x2c002c2c,0x1d001d1d,0xb000b0b0, | ||
364 | 0x6f006f6f,0x8d008d8d,0x88008888,0x0e000e0e, | ||
365 | 0x19001919,0x87008787,0x4e004e4e,0x0b000b0b, | ||
366 | 0xa900a9a9,0x0c000c0c,0x79007979,0x11001111, | ||
367 | 0x7f007f7f,0x22002222,0xe700e7e7,0x59005959, | ||
368 | 0xe100e1e1,0xda00dada,0x3d003d3d,0xc800c8c8, | ||
369 | 0x12001212,0x04000404,0x74007474,0x54005454, | ||
370 | 0x30003030,0x7e007e7e,0xb400b4b4,0x28002828, | ||
371 | 0x55005555,0x68006868,0x50005050,0xbe00bebe, | ||
372 | 0xd000d0d0,0xc400c4c4,0x31003131,0xcb00cbcb, | ||
373 | 0x2a002a2a,0xad00adad,0x0f000f0f,0xca00caca, | ||
374 | 0x70007070,0xff00ffff,0x32003232,0x69006969, | ||
375 | 0x08000808,0x62006262,0x00000000,0x24002424, | ||
376 | 0xd100d1d1,0xfb00fbfb,0xba00baba,0xed00eded, | ||
377 | 0x45004545,0x81008181,0x73007373,0x6d006d6d, | ||
378 | 0x84008484,0x9f009f9f,0xee00eeee,0x4a004a4a, | ||
379 | 0xc300c3c3,0x2e002e2e,0xc100c1c1,0x01000101, | ||
380 | 0xe600e6e6,0x25002525,0x48004848,0x99009999, | ||
381 | 0xb900b9b9,0xb300b3b3,0x7b007b7b,0xf900f9f9, | ||
382 | 0xce00cece,0xbf00bfbf,0xdf00dfdf,0x71007171, | ||
383 | 0x29002929,0xcd00cdcd,0x6c006c6c,0x13001313, | ||
384 | 0x64006464,0x9b009b9b,0x63006363,0x9d009d9d, | ||
385 | 0xc000c0c0,0x4b004b4b,0xb700b7b7,0xa500a5a5, | ||
386 | 0x89008989,0x5f005f5f,0xb100b1b1,0x17001717, | ||
387 | 0xf400f4f4,0xbc00bcbc,0xd300d3d3,0x46004646, | ||
388 | 0xcf00cfcf,0x37003737,0x5e005e5e,0x47004747, | ||
389 | 0x94009494,0xfa00fafa,0xfc00fcfc,0x5b005b5b, | ||
390 | 0x97009797,0xfe00fefe,0x5a005a5a,0xac00acac, | ||
391 | 0x3c003c3c,0x4c004c4c,0x03000303,0x35003535, | ||
392 | 0xf300f3f3,0x23002323,0xb800b8b8,0x5d005d5d, | ||
393 | 0x6a006a6a,0x92009292,0xd500d5d5,0x21002121, | ||
394 | 0x44004444,0x51005151,0xc600c6c6,0x7d007d7d, | ||
395 | 0x39003939,0x83008383,0xdc00dcdc,0xaa00aaaa, | ||
396 | 0x7c007c7c,0x77007777,0x56005656,0x05000505, | ||
397 | 0x1b001b1b,0xa400a4a4,0x15001515,0x34003434, | ||
398 | 0x1e001e1e,0x1c001c1c,0xf800f8f8,0x52005252, | ||
399 | 0x20002020,0x14001414,0xe900e9e9,0xbd00bdbd, | ||
400 | 0xdd00dddd,0xe400e4e4,0xa100a1a1,0xe000e0e0, | ||
401 | 0x8a008a8a,0xf100f1f1,0xd600d6d6,0x7a007a7a, | ||
402 | 0xbb00bbbb,0xe300e3e3,0x40004040,0x4f004f4f, | ||
403 | }; | ||
404 | |||
405 | static const u32 camellia_sp4404[256] = | ||
406 | { | ||
407 | 0x70700070,0x2c2c002c,0xb3b300b3,0xc0c000c0, | ||
408 | 0xe4e400e4,0x57570057,0xeaea00ea,0xaeae00ae, | ||
409 | 0x23230023,0x6b6b006b,0x45450045,0xa5a500a5, | ||
410 | 0xeded00ed,0x4f4f004f,0x1d1d001d,0x92920092, | ||
411 | 0x86860086,0xafaf00af,0x7c7c007c,0x1f1f001f, | ||
412 | 0x3e3e003e,0xdcdc00dc,0x5e5e005e,0x0b0b000b, | ||
413 | 0xa6a600a6,0x39390039,0xd5d500d5,0x5d5d005d, | ||
414 | 0xd9d900d9,0x5a5a005a,0x51510051,0x6c6c006c, | ||
415 | 0x8b8b008b,0x9a9a009a,0xfbfb00fb,0xb0b000b0, | ||
416 | 0x74740074,0x2b2b002b,0xf0f000f0,0x84840084, | ||
417 | 0xdfdf00df,0xcbcb00cb,0x34340034,0x76760076, | ||
418 | 0x6d6d006d,0xa9a900a9,0xd1d100d1,0x04040004, | ||
419 | 0x14140014,0x3a3a003a,0xdede00de,0x11110011, | ||
420 | 0x32320032,0x9c9c009c,0x53530053,0xf2f200f2, | ||
421 | 0xfefe00fe,0xcfcf00cf,0xc3c300c3,0x7a7a007a, | ||
422 | 0x24240024,0xe8e800e8,0x60600060,0x69690069, | ||
423 | 0xaaaa00aa,0xa0a000a0,0xa1a100a1,0x62620062, | ||
424 | 0x54540054,0x1e1e001e,0xe0e000e0,0x64640064, | ||
425 | 0x10100010,0x00000000,0xa3a300a3,0x75750075, | ||
426 | 0x8a8a008a,0xe6e600e6,0x09090009,0xdddd00dd, | ||
427 | 0x87870087,0x83830083,0xcdcd00cd,0x90900090, | ||
428 | 0x73730073,0xf6f600f6,0x9d9d009d,0xbfbf00bf, | ||
429 | 0x52520052,0xd8d800d8,0xc8c800c8,0xc6c600c6, | ||
430 | 0x81810081,0x6f6f006f,0x13130013,0x63630063, | ||
431 | 0xe9e900e9,0xa7a700a7,0x9f9f009f,0xbcbc00bc, | ||
432 | 0x29290029,0xf9f900f9,0x2f2f002f,0xb4b400b4, | ||
433 | 0x78780078,0x06060006,0xe7e700e7,0x71710071, | ||
434 | 0xd4d400d4,0xabab00ab,0x88880088,0x8d8d008d, | ||
435 | 0x72720072,0xb9b900b9,0xf8f800f8,0xacac00ac, | ||
436 | 0x36360036,0x2a2a002a,0x3c3c003c,0xf1f100f1, | ||
437 | 0x40400040,0xd3d300d3,0xbbbb00bb,0x43430043, | ||
438 | 0x15150015,0xadad00ad,0x77770077,0x80800080, | ||
439 | 0x82820082,0xecec00ec,0x27270027,0xe5e500e5, | ||
440 | 0x85850085,0x35350035,0x0c0c000c,0x41410041, | ||
441 | 0xefef00ef,0x93930093,0x19190019,0x21210021, | ||
442 | 0x0e0e000e,0x4e4e004e,0x65650065,0xbdbd00bd, | ||
443 | 0xb8b800b8,0x8f8f008f,0xebeb00eb,0xcece00ce, | ||
444 | 0x30300030,0x5f5f005f,0xc5c500c5,0x1a1a001a, | ||
445 | 0xe1e100e1,0xcaca00ca,0x47470047,0x3d3d003d, | ||
446 | 0x01010001,0xd6d600d6,0x56560056,0x4d4d004d, | ||
447 | 0x0d0d000d,0x66660066,0xcccc00cc,0x2d2d002d, | ||
448 | 0x12120012,0x20200020,0xb1b100b1,0x99990099, | ||
449 | 0x4c4c004c,0xc2c200c2,0x7e7e007e,0x05050005, | ||
450 | 0xb7b700b7,0x31310031,0x17170017,0xd7d700d7, | ||
451 | 0x58580058,0x61610061,0x1b1b001b,0x1c1c001c, | ||
452 | 0x0f0f000f,0x16160016,0x18180018,0x22220022, | ||
453 | 0x44440044,0xb2b200b2,0xb5b500b5,0x91910091, | ||
454 | 0x08080008,0xa8a800a8,0xfcfc00fc,0x50500050, | ||
455 | 0xd0d000d0,0x7d7d007d,0x89890089,0x97970097, | ||
456 | 0x5b5b005b,0x95950095,0xffff00ff,0xd2d200d2, | ||
457 | 0xc4c400c4,0x48480048,0xf7f700f7,0xdbdb00db, | ||
458 | 0x03030003,0xdada00da,0x3f3f003f,0x94940094, | ||
459 | 0x5c5c005c,0x02020002,0x4a4a004a,0x33330033, | ||
460 | 0x67670067,0xf3f300f3,0x7f7f007f,0xe2e200e2, | ||
461 | 0x9b9b009b,0x26260026,0x37370037,0x3b3b003b, | ||
462 | 0x96960096,0x4b4b004b,0xbebe00be,0x2e2e002e, | ||
463 | 0x79790079,0x8c8c008c,0x6e6e006e,0x8e8e008e, | ||
464 | 0xf5f500f5,0xb6b600b6,0xfdfd00fd,0x59590059, | ||
465 | 0x98980098,0x6a6a006a,0x46460046,0xbaba00ba, | ||
466 | 0x25250025,0x42420042,0xa2a200a2,0xfafa00fa, | ||
467 | 0x07070007,0x55550055,0xeeee00ee,0x0a0a000a, | ||
468 | 0x49490049,0x68680068,0x38380038,0xa4a400a4, | ||
469 | 0x28280028,0x7b7b007b,0xc9c900c9,0xc1c100c1, | ||
470 | 0xe3e300e3,0xf4f400f4,0xc7c700c7,0x9e9e009e, | ||
471 | }; | ||
472 | |||
473 | /** | ||
474 | * Stuff related to the Camellia key schedule | ||
475 | */ | ||
476 | #define subl(x) subL[(x)] | ||
477 | #define subr(x) subR[(x)] | ||
478 | |||
479 | void camellia_setup128(const u8 *key, u32 *subkey) | ||
480 | { | ||
481 | u32 kll, klr, krl, krr; | ||
482 | u32 il, ir, t0, t1, w0, w1; | ||
483 | u32 kw4l, kw4r, dw, tl, tr; | ||
484 | u32 subL[26]; | ||
485 | u32 subR[26]; | ||
486 | |||
487 | /** | ||
488 | * k == kll || klr || krl || krr (|| is concatination) | ||
489 | */ | ||
490 | kll = GETU32(key ); | ||
491 | klr = GETU32(key + 4); | ||
492 | krl = GETU32(key + 8); | ||
493 | krr = GETU32(key + 12); | ||
494 | /** | ||
495 | * generate KL dependent subkeys | ||
496 | */ | ||
497 | /* kw1 */ | ||
498 | subl(0) = kll; subr(0) = klr; | ||
499 | /* kw2 */ | ||
500 | subl(1) = krl; subr(1) = krr; | ||
501 | /* rotation left shift 15bit */ | ||
502 | CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15); | ||
503 | /* k3 */ | ||
504 | subl(4) = kll; subr(4) = klr; | ||
505 | /* k4 */ | ||
506 | subl(5) = krl; subr(5) = krr; | ||
507 | /* rotation left shift 15+30bit */ | ||
508 | CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 30); | ||
509 | /* k7 */ | ||
510 | subl(10) = kll; subr(10) = klr; | ||
511 | /* k8 */ | ||
512 | subl(11) = krl; subr(11) = krr; | ||
513 | /* rotation left shift 15+30+15bit */ | ||
514 | CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15); | ||
515 | /* k10 */ | ||
516 | subl(13) = krl; subr(13) = krr; | ||
517 | /* rotation left shift 15+30+15+17 bit */ | ||
518 | CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 17); | ||
519 | /* kl3 */ | ||
520 | subl(16) = kll; subr(16) = klr; | ||
521 | /* kl4 */ | ||
522 | subl(17) = krl; subr(17) = krr; | ||
523 | /* rotation left shift 15+30+15+17+17 bit */ | ||
524 | CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 17); | ||
525 | /* k13 */ | ||
526 | subl(18) = kll; subr(18) = klr; | ||
527 | /* k14 */ | ||
528 | subl(19) = krl; subr(19) = krr; | ||
529 | /* rotation left shift 15+30+15+17+17+17 bit */ | ||
530 | CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 17); | ||
531 | /* k17 */ | ||
532 | subl(22) = kll; subr(22) = klr; | ||
533 | /* k18 */ | ||
534 | subl(23) = krl; subr(23) = krr; | ||
535 | |||
536 | /* generate KA */ | ||
537 | kll = subl(0); klr = subr(0); | ||
538 | krl = subl(1); krr = subr(1); | ||
539 | CAMELLIA_F(kll, klr, | ||
540 | CAMELLIA_SIGMA1L, CAMELLIA_SIGMA1R, | ||
541 | w0, w1, il, ir, t0, t1); | ||
542 | krl ^= w0; krr ^= w1; | ||
543 | CAMELLIA_F(krl, krr, | ||
544 | CAMELLIA_SIGMA2L, CAMELLIA_SIGMA2R, | ||
545 | kll, klr, il, ir, t0, t1); | ||
546 | /* current status == (kll, klr, w0, w1) */ | ||
547 | CAMELLIA_F(kll, klr, | ||
548 | CAMELLIA_SIGMA3L, CAMELLIA_SIGMA3R, | ||
549 | krl, krr, il, ir, t0, t1); | ||
550 | krl ^= w0; krr ^= w1; | ||
551 | CAMELLIA_F(krl, krr, | ||
552 | CAMELLIA_SIGMA4L, CAMELLIA_SIGMA4R, | ||
553 | w0, w1, il, ir, t0, t1); | ||
554 | kll ^= w0; klr ^= w1; | ||
555 | |||
556 | /* generate KA dependent subkeys */ | ||
557 | /* k1, k2 */ | ||
558 | subl(2) = kll; subr(2) = klr; | ||
559 | subl(3) = krl; subr(3) = krr; | ||
560 | CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15); | ||
561 | /* k5,k6 */ | ||
562 | subl(6) = kll; subr(6) = klr; | ||
563 | subl(7) = krl; subr(7) = krr; | ||
564 | CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15); | ||
565 | /* kl1, kl2 */ | ||
566 | subl(8) = kll; subr(8) = klr; | ||
567 | subl(9) = krl; subr(9) = krr; | ||
568 | CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15); | ||
569 | /* k9 */ | ||
570 | subl(12) = kll; subr(12) = klr; | ||
571 | CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15); | ||
572 | /* k11, k12 */ | ||
573 | subl(14) = kll; subr(14) = klr; | ||
574 | subl(15) = krl; subr(15) = krr; | ||
575 | CAMELLIA_ROLDQo32(kll, klr, krl, krr, w0, w1, 34); | ||
576 | /* k15, k16 */ | ||
577 | subl(20) = kll; subr(20) = klr; | ||
578 | subl(21) = krl; subr(21) = krr; | ||
579 | CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 17); | ||
580 | /* kw3, kw4 */ | ||
581 | subl(24) = kll; subr(24) = klr; | ||
582 | subl(25) = krl; subr(25) = krr; | ||
583 | |||
584 | |||
585 | /* absorb kw2 to other subkeys */ | ||
586 | /* round 2 */ | ||
587 | subl(3) ^= subl(1); subr(3) ^= subr(1); | ||
588 | /* round 4 */ | ||
589 | subl(5) ^= subl(1); subr(5) ^= subr(1); | ||
590 | /* round 6 */ | ||
591 | subl(7) ^= subl(1); subr(7) ^= subr(1); | ||
592 | subl(1) ^= subr(1) & ~subr(9); | ||
593 | dw = subl(1) & subl(9), | ||
594 | subr(1) ^= CAMELLIA_RL1(dw); /* modified for FLinv(kl2) */ | ||
595 | /* round 8 */ | ||
596 | subl(11) ^= subl(1); subr(11) ^= subr(1); | ||
597 | /* round 10 */ | ||
598 | subl(13) ^= subl(1); subr(13) ^= subr(1); | ||
599 | /* round 12 */ | ||
600 | subl(15) ^= subl(1); subr(15) ^= subr(1); | ||
601 | subl(1) ^= subr(1) & ~subr(17); | ||
602 | dw = subl(1) & subl(17), | ||
603 | subr(1) ^= CAMELLIA_RL1(dw); /* modified for FLinv(kl4) */ | ||
604 | /* round 14 */ | ||
605 | subl(19) ^= subl(1); subr(19) ^= subr(1); | ||
606 | /* round 16 */ | ||
607 | subl(21) ^= subl(1); subr(21) ^= subr(1); | ||
608 | /* round 18 */ | ||
609 | subl(23) ^= subl(1); subr(23) ^= subr(1); | ||
610 | /* kw3 */ | ||
611 | subl(24) ^= subl(1); subr(24) ^= subr(1); | ||
612 | |||
613 | /* absorb kw4 to other subkeys */ | ||
614 | kw4l = subl(25); kw4r = subr(25); | ||
615 | /* round 17 */ | ||
616 | subl(22) ^= kw4l; subr(22) ^= kw4r; | ||
617 | /* round 15 */ | ||
618 | subl(20) ^= kw4l; subr(20) ^= kw4r; | ||
619 | /* round 13 */ | ||
620 | subl(18) ^= kw4l; subr(18) ^= kw4r; | ||
621 | kw4l ^= kw4r & ~subr(16); | ||
622 | dw = kw4l & subl(16), | ||
623 | kw4r ^= CAMELLIA_RL1(dw); /* modified for FL(kl3) */ | ||
624 | /* round 11 */ | ||
625 | subl(14) ^= kw4l; subr(14) ^= kw4r; | ||
626 | /* round 9 */ | ||
627 | subl(12) ^= kw4l; subr(12) ^= kw4r; | ||
628 | /* round 7 */ | ||
629 | subl(10) ^= kw4l; subr(10) ^= kw4r; | ||
630 | kw4l ^= kw4r & ~subr(8); | ||
631 | dw = kw4l & subl(8), | ||
632 | kw4r ^= CAMELLIA_RL1(dw); /* modified for FL(kl1) */ | ||
633 | /* round 5 */ | ||
634 | subl(6) ^= kw4l; subr(6) ^= kw4r; | ||
635 | /* round 3 */ | ||
636 | subl(4) ^= kw4l; subr(4) ^= kw4r; | ||
637 | /* round 1 */ | ||
638 | subl(2) ^= kw4l; subr(2) ^= kw4r; | ||
639 | /* kw1 */ | ||
640 | subl(0) ^= kw4l; subr(0) ^= kw4r; | ||
641 | |||
642 | |||
643 | /* key XOR is end of F-function */ | ||
644 | CamelliaSubkeyL(0) = subl(0) ^ subl(2);/* kw1 */ | ||
645 | CamelliaSubkeyR(0) = subr(0) ^ subr(2); | ||
646 | CamelliaSubkeyL(2) = subl(3); /* round 1 */ | ||
647 | CamelliaSubkeyR(2) = subr(3); | ||
648 | CamelliaSubkeyL(3) = subl(2) ^ subl(4); /* round 2 */ | ||
649 | CamelliaSubkeyR(3) = subr(2) ^ subr(4); | ||
650 | CamelliaSubkeyL(4) = subl(3) ^ subl(5); /* round 3 */ | ||
651 | CamelliaSubkeyR(4) = subr(3) ^ subr(5); | ||
652 | CamelliaSubkeyL(5) = subl(4) ^ subl(6); /* round 4 */ | ||
653 | CamelliaSubkeyR(5) = subr(4) ^ subr(6); | ||
654 | CamelliaSubkeyL(6) = subl(5) ^ subl(7); /* round 5 */ | ||
655 | CamelliaSubkeyR(6) = subr(5) ^ subr(7); | ||
656 | tl = subl(10) ^ (subr(10) & ~subr(8)); | ||
657 | dw = tl & subl(8), /* FL(kl1) */ | ||
658 | tr = subr(10) ^ CAMELLIA_RL1(dw); | ||
659 | CamelliaSubkeyL(7) = subl(6) ^ tl; /* round 6 */ | ||
660 | CamelliaSubkeyR(7) = subr(6) ^ tr; | ||
661 | CamelliaSubkeyL(8) = subl(8); /* FL(kl1) */ | ||
662 | CamelliaSubkeyR(8) = subr(8); | ||
663 | CamelliaSubkeyL(9) = subl(9); /* FLinv(kl2) */ | ||
664 | CamelliaSubkeyR(9) = subr(9); | ||
665 | tl = subl(7) ^ (subr(7) & ~subr(9)); | ||
666 | dw = tl & subl(9), /* FLinv(kl2) */ | ||
667 | tr = subr(7) ^ CAMELLIA_RL1(dw); | ||
668 | CamelliaSubkeyL(10) = tl ^ subl(11); /* round 7 */ | ||
669 | CamelliaSubkeyR(10) = tr ^ subr(11); | ||
670 | CamelliaSubkeyL(11) = subl(10) ^ subl(12); /* round 8 */ | ||
671 | CamelliaSubkeyR(11) = subr(10) ^ subr(12); | ||
672 | CamelliaSubkeyL(12) = subl(11) ^ subl(13); /* round 9 */ | ||
673 | CamelliaSubkeyR(12) = subr(11) ^ subr(13); | ||
674 | CamelliaSubkeyL(13) = subl(12) ^ subl(14); /* round 10 */ | ||
675 | CamelliaSubkeyR(13) = subr(12) ^ subr(14); | ||
676 | CamelliaSubkeyL(14) = subl(13) ^ subl(15); /* round 11 */ | ||
677 | CamelliaSubkeyR(14) = subr(13) ^ subr(15); | ||
678 | tl = subl(18) ^ (subr(18) & ~subr(16)); | ||
679 | dw = tl & subl(16), /* FL(kl3) */ | ||
680 | tr = subr(18) ^ CAMELLIA_RL1(dw); | ||
681 | CamelliaSubkeyL(15) = subl(14) ^ tl; /* round 12 */ | ||
682 | CamelliaSubkeyR(15) = subr(14) ^ tr; | ||
683 | CamelliaSubkeyL(16) = subl(16); /* FL(kl3) */ | ||
684 | CamelliaSubkeyR(16) = subr(16); | ||
685 | CamelliaSubkeyL(17) = subl(17); /* FLinv(kl4) */ | ||
686 | CamelliaSubkeyR(17) = subr(17); | ||
687 | tl = subl(15) ^ (subr(15) & ~subr(17)); | ||
688 | dw = tl & subl(17), /* FLinv(kl4) */ | ||
689 | tr = subr(15) ^ CAMELLIA_RL1(dw); | ||
690 | CamelliaSubkeyL(18) = tl ^ subl(19); /* round 13 */ | ||
691 | CamelliaSubkeyR(18) = tr ^ subr(19); | ||
692 | CamelliaSubkeyL(19) = subl(18) ^ subl(20); /* round 14 */ | ||
693 | CamelliaSubkeyR(19) = subr(18) ^ subr(20); | ||
694 | CamelliaSubkeyL(20) = subl(19) ^ subl(21); /* round 15 */ | ||
695 | CamelliaSubkeyR(20) = subr(19) ^ subr(21); | ||
696 | CamelliaSubkeyL(21) = subl(20) ^ subl(22); /* round 16 */ | ||
697 | CamelliaSubkeyR(21) = subr(20) ^ subr(22); | ||
698 | CamelliaSubkeyL(22) = subl(21) ^ subl(23); /* round 17 */ | ||
699 | CamelliaSubkeyR(22) = subr(21) ^ subr(23); | ||
700 | CamelliaSubkeyL(23) = subl(22); /* round 18 */ | ||
701 | CamelliaSubkeyR(23) = subr(22); | ||
702 | CamelliaSubkeyL(24) = subl(24) ^ subl(23); /* kw3 */ | ||
703 | CamelliaSubkeyR(24) = subr(24) ^ subr(23); | ||
704 | |||
705 | /* apply the inverse of the last half of P-function */ | ||
706 | dw = CamelliaSubkeyL(2) ^ CamelliaSubkeyR(2), | ||
707 | dw = CAMELLIA_RL8(dw);/* round 1 */ | ||
708 | CamelliaSubkeyR(2) = CamelliaSubkeyL(2) ^ dw, | ||
709 | CamelliaSubkeyL(2) = dw; | ||
710 | dw = CamelliaSubkeyL(3) ^ CamelliaSubkeyR(3), | ||
711 | dw = CAMELLIA_RL8(dw);/* round 2 */ | ||
712 | CamelliaSubkeyR(3) = CamelliaSubkeyL(3) ^ dw, | ||
713 | CamelliaSubkeyL(3) = dw; | ||
714 | dw = CamelliaSubkeyL(4) ^ CamelliaSubkeyR(4), | ||
715 | dw = CAMELLIA_RL8(dw);/* round 3 */ | ||
716 | CamelliaSubkeyR(4) = CamelliaSubkeyL(4) ^ dw, | ||
717 | CamelliaSubkeyL(4) = dw; | ||
718 | dw = CamelliaSubkeyL(5) ^ CamelliaSubkeyR(5), | ||
719 | dw = CAMELLIA_RL8(dw);/* round 4 */ | ||
720 | CamelliaSubkeyR(5) = CamelliaSubkeyL(5) ^ dw, | ||
721 | CamelliaSubkeyL(5) = dw; | ||
722 | dw = CamelliaSubkeyL(6) ^ CamelliaSubkeyR(6), | ||
723 | dw = CAMELLIA_RL8(dw);/* round 5 */ | ||
724 | CamelliaSubkeyR(6) = CamelliaSubkeyL(6) ^ dw, | ||
725 | CamelliaSubkeyL(6) = dw; | ||
726 | dw = CamelliaSubkeyL(7) ^ CamelliaSubkeyR(7), | ||
727 | dw = CAMELLIA_RL8(dw);/* round 6 */ | ||
728 | CamelliaSubkeyR(7) = CamelliaSubkeyL(7) ^ dw, | ||
729 | CamelliaSubkeyL(7) = dw; | ||
730 | dw = CamelliaSubkeyL(10) ^ CamelliaSubkeyR(10), | ||
731 | dw = CAMELLIA_RL8(dw);/* round 7 */ | ||
732 | CamelliaSubkeyR(10) = CamelliaSubkeyL(10) ^ dw, | ||
733 | CamelliaSubkeyL(10) = dw; | ||
734 | dw = CamelliaSubkeyL(11) ^ CamelliaSubkeyR(11), | ||
735 | dw = CAMELLIA_RL8(dw);/* round 8 */ | ||
736 | CamelliaSubkeyR(11) = CamelliaSubkeyL(11) ^ dw, | ||
737 | CamelliaSubkeyL(11) = dw; | ||
738 | dw = CamelliaSubkeyL(12) ^ CamelliaSubkeyR(12), | ||
739 | dw = CAMELLIA_RL8(dw);/* round 9 */ | ||
740 | CamelliaSubkeyR(12) = CamelliaSubkeyL(12) ^ dw, | ||
741 | CamelliaSubkeyL(12) = dw; | ||
742 | dw = CamelliaSubkeyL(13) ^ CamelliaSubkeyR(13), | ||
743 | dw = CAMELLIA_RL8(dw);/* round 10 */ | ||
744 | CamelliaSubkeyR(13) = CamelliaSubkeyL(13) ^ dw, | ||
745 | CamelliaSubkeyL(13) = dw; | ||
746 | dw = CamelliaSubkeyL(14) ^ CamelliaSubkeyR(14), | ||
747 | dw = CAMELLIA_RL8(dw);/* round 11 */ | ||
748 | CamelliaSubkeyR(14) = CamelliaSubkeyL(14) ^ dw, | ||
749 | CamelliaSubkeyL(14) = dw; | ||
750 | dw = CamelliaSubkeyL(15) ^ CamelliaSubkeyR(15), | ||
751 | dw = CAMELLIA_RL8(dw);/* round 12 */ | ||
752 | CamelliaSubkeyR(15) = CamelliaSubkeyL(15) ^ dw, | ||
753 | CamelliaSubkeyL(15) = dw; | ||
754 | dw = CamelliaSubkeyL(18) ^ CamelliaSubkeyR(18), | ||
755 | dw = CAMELLIA_RL8(dw);/* round 13 */ | ||
756 | CamelliaSubkeyR(18) = CamelliaSubkeyL(18) ^ dw, | ||
757 | CamelliaSubkeyL(18) = dw; | ||
758 | dw = CamelliaSubkeyL(19) ^ CamelliaSubkeyR(19), | ||
759 | dw = CAMELLIA_RL8(dw);/* round 14 */ | ||
760 | CamelliaSubkeyR(19) = CamelliaSubkeyL(19) ^ dw, | ||
761 | CamelliaSubkeyL(19) = dw; | ||
762 | dw = CamelliaSubkeyL(20) ^ CamelliaSubkeyR(20), | ||
763 | dw = CAMELLIA_RL8(dw);/* round 15 */ | ||
764 | CamelliaSubkeyR(20) = CamelliaSubkeyL(20) ^ dw, | ||
765 | CamelliaSubkeyL(20) = dw; | ||
766 | dw = CamelliaSubkeyL(21) ^ CamelliaSubkeyR(21), | ||
767 | dw = CAMELLIA_RL8(dw);/* round 16 */ | ||
768 | CamelliaSubkeyR(21) = CamelliaSubkeyL(21) ^ dw, | ||
769 | CamelliaSubkeyL(21) = dw; | ||
770 | dw = CamelliaSubkeyL(22) ^ CamelliaSubkeyR(22), | ||
771 | dw = CAMELLIA_RL8(dw);/* round 17 */ | ||
772 | CamelliaSubkeyR(22) = CamelliaSubkeyL(22) ^ dw, | ||
773 | CamelliaSubkeyL(22) = dw; | ||
774 | dw = CamelliaSubkeyL(23) ^ CamelliaSubkeyR(23), | ||
775 | dw = CAMELLIA_RL8(dw);/* round 18 */ | ||
776 | CamelliaSubkeyR(23) = CamelliaSubkeyL(23) ^ dw, | ||
777 | CamelliaSubkeyL(23) = dw; | ||
778 | |||
779 | return; | ||
780 | } | ||
781 | |||
782 | void camellia_setup256(const u8 *key, u32 *subkey) | ||
783 | { | ||
784 | u32 kll,klr,krl,krr; /* left half of key */ | ||
785 | u32 krll,krlr,krrl,krrr; /* right half of key */ | ||
786 | u32 il, ir, t0, t1, w0, w1; /* temporary variables */ | ||
787 | u32 kw4l, kw4r, dw, tl, tr; | ||
788 | u32 subL[34]; | ||
789 | u32 subR[34]; | ||
790 | |||
791 | /** | ||
792 | * key = (kll || klr || krl || krr || krll || krlr || krrl || krrr) | ||
793 | * (|| is concatination) | ||
794 | */ | ||
795 | |||
796 | kll = GETU32(key ); | ||
797 | klr = GETU32(key + 4); | ||
798 | krl = GETU32(key + 8); | ||
799 | krr = GETU32(key + 12); | ||
800 | krll = GETU32(key + 16); | ||
801 | krlr = GETU32(key + 20); | ||
802 | krrl = GETU32(key + 24); | ||
803 | krrr = GETU32(key + 28); | ||
804 | |||
805 | /* generate KL dependent subkeys */ | ||
806 | /* kw1 */ | ||
807 | subl(0) = kll; subr(0) = klr; | ||
808 | /* kw2 */ | ||
809 | subl(1) = krl; subr(1) = krr; | ||
810 | CAMELLIA_ROLDQo32(kll, klr, krl, krr, w0, w1, 45); | ||
811 | /* k9 */ | ||
812 | subl(12) = kll; subr(12) = klr; | ||
813 | /* k10 */ | ||
814 | subl(13) = krl; subr(13) = krr; | ||
815 | CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15); | ||
816 | /* kl3 */ | ||
817 | subl(16) = kll; subr(16) = klr; | ||
818 | /* kl4 */ | ||
819 | subl(17) = krl; subr(17) = krr; | ||
820 | CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 17); | ||
821 | /* k17 */ | ||
822 | subl(22) = kll; subr(22) = klr; | ||
823 | /* k18 */ | ||
824 | subl(23) = krl; subr(23) = krr; | ||
825 | CAMELLIA_ROLDQo32(kll, klr, krl, krr, w0, w1, 34); | ||
826 | /* k23 */ | ||
827 | subl(30) = kll; subr(30) = klr; | ||
828 | /* k24 */ | ||
829 | subl(31) = krl; subr(31) = krr; | ||
830 | |||
831 | /* generate KR dependent subkeys */ | ||
832 | CAMELLIA_ROLDQ(krll, krlr, krrl, krrr, w0, w1, 15); | ||
833 | /* k3 */ | ||
834 | subl(4) = krll; subr(4) = krlr; | ||
835 | /* k4 */ | ||
836 | subl(5) = krrl; subr(5) = krrr; | ||
837 | CAMELLIA_ROLDQ(krll, krlr, krrl, krrr, w0, w1, 15); | ||
838 | /* kl1 */ | ||
839 | subl(8) = krll; subr(8) = krlr; | ||
840 | /* kl2 */ | ||
841 | subl(9) = krrl; subr(9) = krrr; | ||
842 | CAMELLIA_ROLDQ(krll, krlr, krrl, krrr, w0, w1, 30); | ||
843 | /* k13 */ | ||
844 | subl(18) = krll; subr(18) = krlr; | ||
845 | /* k14 */ | ||
846 | subl(19) = krrl; subr(19) = krrr; | ||
847 | CAMELLIA_ROLDQo32(krll, krlr, krrl, krrr, w0, w1, 34); | ||
848 | /* k19 */ | ||
849 | subl(26) = krll; subr(26) = krlr; | ||
850 | /* k20 */ | ||
851 | subl(27) = krrl; subr(27) = krrr; | ||
852 | CAMELLIA_ROLDQo32(krll, krlr, krrl, krrr, w0, w1, 34); | ||
853 | |||
854 | /* generate KA */ | ||
855 | kll = subl(0) ^ krll; klr = subr(0) ^ krlr; | ||
856 | krl = subl(1) ^ krrl; krr = subr(1) ^ krrr; | ||
857 | CAMELLIA_F(kll, klr, | ||
858 | CAMELLIA_SIGMA1L, CAMELLIA_SIGMA1R, | ||
859 | w0, w1, il, ir, t0, t1); | ||
860 | krl ^= w0; krr ^= w1; | ||
861 | CAMELLIA_F(krl, krr, | ||
862 | CAMELLIA_SIGMA2L, CAMELLIA_SIGMA2R, | ||
863 | kll, klr, il, ir, t0, t1); | ||
864 | kll ^= krll; klr ^= krlr; | ||
865 | CAMELLIA_F(kll, klr, | ||
866 | CAMELLIA_SIGMA3L, CAMELLIA_SIGMA3R, | ||
867 | krl, krr, il, ir, t0, t1); | ||
868 | krl ^= w0 ^ krrl; krr ^= w1 ^ krrr; | ||
869 | CAMELLIA_F(krl, krr, | ||
870 | CAMELLIA_SIGMA4L, CAMELLIA_SIGMA4R, | ||
871 | w0, w1, il, ir, t0, t1); | ||
872 | kll ^= w0; klr ^= w1; | ||
873 | |||
874 | /* generate KB */ | ||
875 | krll ^= kll; krlr ^= klr; | ||
876 | krrl ^= krl; krrr ^= krr; | ||
877 | CAMELLIA_F(krll, krlr, | ||
878 | CAMELLIA_SIGMA5L, CAMELLIA_SIGMA5R, | ||
879 | w0, w1, il, ir, t0, t1); | ||
880 | krrl ^= w0; krrr ^= w1; | ||
881 | CAMELLIA_F(krrl, krrr, | ||
882 | CAMELLIA_SIGMA6L, CAMELLIA_SIGMA6R, | ||
883 | w0, w1, il, ir, t0, t1); | ||
884 | krll ^= w0; krlr ^= w1; | ||
885 | |||
886 | /* generate KA dependent subkeys */ | ||
887 | CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15); | ||
888 | /* k5 */ | ||
889 | subl(6) = kll; subr(6) = klr; | ||
890 | /* k6 */ | ||
891 | subl(7) = krl; subr(7) = krr; | ||
892 | CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 30); | ||
893 | /* k11 */ | ||
894 | subl(14) = kll; subr(14) = klr; | ||
895 | /* k12 */ | ||
896 | subl(15) = krl; subr(15) = krr; | ||
897 | /* rotation left shift 32bit */ | ||
898 | /* kl5 */ | ||
899 | subl(24) = klr; subr(24) = krl; | ||
900 | /* kl6 */ | ||
901 | subl(25) = krr; subr(25) = kll; | ||
902 | /* rotation left shift 49 from k11,k12 -> k21,k22 */ | ||
903 | CAMELLIA_ROLDQo32(kll, klr, krl, krr, w0, w1, 49); | ||
904 | /* k21 */ | ||
905 | subl(28) = kll; subr(28) = klr; | ||
906 | /* k22 */ | ||
907 | subl(29) = krl; subr(29) = krr; | ||
908 | |||
909 | /* generate KB dependent subkeys */ | ||
910 | /* k1 */ | ||
911 | subl(2) = krll; subr(2) = krlr; | ||
912 | /* k2 */ | ||
913 | subl(3) = krrl; subr(3) = krrr; | ||
914 | CAMELLIA_ROLDQ(krll, krlr, krrl, krrr, w0, w1, 30); | ||
915 | /* k7 */ | ||
916 | subl(10) = krll; subr(10) = krlr; | ||
917 | /* k8 */ | ||
918 | subl(11) = krrl; subr(11) = krrr; | ||
919 | CAMELLIA_ROLDQ(krll, krlr, krrl, krrr, w0, w1, 30); | ||
920 | /* k15 */ | ||
921 | subl(20) = krll; subr(20) = krlr; | ||
922 | /* k16 */ | ||
923 | subl(21) = krrl; subr(21) = krrr; | ||
924 | CAMELLIA_ROLDQo32(krll, krlr, krrl, krrr, w0, w1, 51); | ||
925 | /* kw3 */ | ||
926 | subl(32) = krll; subr(32) = krlr; | ||
927 | /* kw4 */ | ||
928 | subl(33) = krrl; subr(33) = krrr; | ||
929 | |||
930 | /* absorb kw2 to other subkeys */ | ||
931 | /* round 2 */ | ||
932 | subl(3) ^= subl(1); subr(3) ^= subr(1); | ||
933 | /* round 4 */ | ||
934 | subl(5) ^= subl(1); subr(5) ^= subr(1); | ||
935 | /* round 6 */ | ||
936 | subl(7) ^= subl(1); subr(7) ^= subr(1); | ||
937 | subl(1) ^= subr(1) & ~subr(9); | ||
938 | dw = subl(1) & subl(9), | ||
939 | subr(1) ^= CAMELLIA_RL1(dw); /* modified for FLinv(kl2) */ | ||
940 | /* round 8 */ | ||
941 | subl(11) ^= subl(1); subr(11) ^= subr(1); | ||
942 | /* round 10 */ | ||
943 | subl(13) ^= subl(1); subr(13) ^= subr(1); | ||
944 | /* round 12 */ | ||
945 | subl(15) ^= subl(1); subr(15) ^= subr(1); | ||
946 | subl(1) ^= subr(1) & ~subr(17); | ||
947 | dw = subl(1) & subl(17), | ||
948 | subr(1) ^= CAMELLIA_RL1(dw); /* modified for FLinv(kl4) */ | ||
949 | /* round 14 */ | ||
950 | subl(19) ^= subl(1); subr(19) ^= subr(1); | ||
951 | /* round 16 */ | ||
952 | subl(21) ^= subl(1); subr(21) ^= subr(1); | ||
953 | /* round 18 */ | ||
954 | subl(23) ^= subl(1); subr(23) ^= subr(1); | ||
955 | subl(1) ^= subr(1) & ~subr(25); | ||
956 | dw = subl(1) & subl(25), | ||
957 | subr(1) ^= CAMELLIA_RL1(dw); /* modified for FLinv(kl6) */ | ||
958 | /* round 20 */ | ||
959 | subl(27) ^= subl(1); subr(27) ^= subr(1); | ||
960 | /* round 22 */ | ||
961 | subl(29) ^= subl(1); subr(29) ^= subr(1); | ||
962 | /* round 24 */ | ||
963 | subl(31) ^= subl(1); subr(31) ^= subr(1); | ||
964 | /* kw3 */ | ||
965 | subl(32) ^= subl(1); subr(32) ^= subr(1); | ||
966 | |||
967 | |||
968 | /* absorb kw4 to other subkeys */ | ||
969 | kw4l = subl(33); kw4r = subr(33); | ||
970 | /* round 23 */ | ||
971 | subl(30) ^= kw4l; subr(30) ^= kw4r; | ||
972 | /* round 21 */ | ||
973 | subl(28) ^= kw4l; subr(28) ^= kw4r; | ||
974 | /* round 19 */ | ||
975 | subl(26) ^= kw4l; subr(26) ^= kw4r; | ||
976 | kw4l ^= kw4r & ~subr(24); | ||
977 | dw = kw4l & subl(24), | ||
978 | kw4r ^= CAMELLIA_RL1(dw); /* modified for FL(kl5) */ | ||
979 | /* round 17 */ | ||
980 | subl(22) ^= kw4l; subr(22) ^= kw4r; | ||
981 | /* round 15 */ | ||
982 | subl(20) ^= kw4l; subr(20) ^= kw4r; | ||
983 | /* round 13 */ | ||
984 | subl(18) ^= kw4l; subr(18) ^= kw4r; | ||
985 | kw4l ^= kw4r & ~subr(16); | ||
986 | dw = kw4l & subl(16), | ||
987 | kw4r ^= CAMELLIA_RL1(dw); /* modified for FL(kl3) */ | ||
988 | /* round 11 */ | ||
989 | subl(14) ^= kw4l; subr(14) ^= kw4r; | ||
990 | /* round 9 */ | ||
991 | subl(12) ^= kw4l; subr(12) ^= kw4r; | ||
992 | /* round 7 */ | ||
993 | subl(10) ^= kw4l; subr(10) ^= kw4r; | ||
994 | kw4l ^= kw4r & ~subr(8); | ||
995 | dw = kw4l & subl(8), | ||
996 | kw4r ^= CAMELLIA_RL1(dw); /* modified for FL(kl1) */ | ||
997 | /* round 5 */ | ||
998 | subl(6) ^= kw4l; subr(6) ^= kw4r; | ||
999 | /* round 3 */ | ||
1000 | subl(4) ^= kw4l; subr(4) ^= kw4r; | ||
1001 | /* round 1 */ | ||
1002 | subl(2) ^= kw4l; subr(2) ^= kw4r; | ||
1003 | /* kw1 */ | ||
1004 | subl(0) ^= kw4l; subr(0) ^= kw4r; | ||
1005 | |||
1006 | /* key XOR is end of F-function */ | ||
1007 | CamelliaSubkeyL(0) = subl(0) ^ subl(2);/* kw1 */ | ||
1008 | CamelliaSubkeyR(0) = subr(0) ^ subr(2); | ||
1009 | CamelliaSubkeyL(2) = subl(3); /* round 1 */ | ||
1010 | CamelliaSubkeyR(2) = subr(3); | ||
1011 | CamelliaSubkeyL(3) = subl(2) ^ subl(4); /* round 2 */ | ||
1012 | CamelliaSubkeyR(3) = subr(2) ^ subr(4); | ||
1013 | CamelliaSubkeyL(4) = subl(3) ^ subl(5); /* round 3 */ | ||
1014 | CamelliaSubkeyR(4) = subr(3) ^ subr(5); | ||
1015 | CamelliaSubkeyL(5) = subl(4) ^ subl(6); /* round 4 */ | ||
1016 | CamelliaSubkeyR(5) = subr(4) ^ subr(6); | ||
1017 | CamelliaSubkeyL(6) = subl(5) ^ subl(7); /* round 5 */ | ||
1018 | CamelliaSubkeyR(6) = subr(5) ^ subr(7); | ||
1019 | tl = subl(10) ^ (subr(10) & ~subr(8)); | ||
1020 | dw = tl & subl(8), /* FL(kl1) */ | ||
1021 | tr = subr(10) ^ CAMELLIA_RL1(dw); | ||
1022 | CamelliaSubkeyL(7) = subl(6) ^ tl; /* round 6 */ | ||
1023 | CamelliaSubkeyR(7) = subr(6) ^ tr; | ||
1024 | CamelliaSubkeyL(8) = subl(8); /* FL(kl1) */ | ||
1025 | CamelliaSubkeyR(8) = subr(8); | ||
1026 | CamelliaSubkeyL(9) = subl(9); /* FLinv(kl2) */ | ||
1027 | CamelliaSubkeyR(9) = subr(9); | ||
1028 | tl = subl(7) ^ (subr(7) & ~subr(9)); | ||
1029 | dw = tl & subl(9), /* FLinv(kl2) */ | ||
1030 | tr = subr(7) ^ CAMELLIA_RL1(dw); | ||
1031 | CamelliaSubkeyL(10) = tl ^ subl(11); /* round 7 */ | ||
1032 | CamelliaSubkeyR(10) = tr ^ subr(11); | ||
1033 | CamelliaSubkeyL(11) = subl(10) ^ subl(12); /* round 8 */ | ||
1034 | CamelliaSubkeyR(11) = subr(10) ^ subr(12); | ||
1035 | CamelliaSubkeyL(12) = subl(11) ^ subl(13); /* round 9 */ | ||
1036 | CamelliaSubkeyR(12) = subr(11) ^ subr(13); | ||
1037 | CamelliaSubkeyL(13) = subl(12) ^ subl(14); /* round 10 */ | ||
1038 | CamelliaSubkeyR(13) = subr(12) ^ subr(14); | ||
1039 | CamelliaSubkeyL(14) = subl(13) ^ subl(15); /* round 11 */ | ||
1040 | CamelliaSubkeyR(14) = subr(13) ^ subr(15); | ||
1041 | tl = subl(18) ^ (subr(18) & ~subr(16)); | ||
1042 | dw = tl & subl(16), /* FL(kl3) */ | ||
1043 | tr = subr(18) ^ CAMELLIA_RL1(dw); | ||
1044 | CamelliaSubkeyL(15) = subl(14) ^ tl; /* round 12 */ | ||
1045 | CamelliaSubkeyR(15) = subr(14) ^ tr; | ||
1046 | CamelliaSubkeyL(16) = subl(16); /* FL(kl3) */ | ||
1047 | CamelliaSubkeyR(16) = subr(16); | ||
1048 | CamelliaSubkeyL(17) = subl(17); /* FLinv(kl4) */ | ||
1049 | CamelliaSubkeyR(17) = subr(17); | ||
1050 | tl = subl(15) ^ (subr(15) & ~subr(17)); | ||
1051 | dw = tl & subl(17), /* FLinv(kl4) */ | ||
1052 | tr = subr(15) ^ CAMELLIA_RL1(dw); | ||
1053 | CamelliaSubkeyL(18) = tl ^ subl(19); /* round 13 */ | ||
1054 | CamelliaSubkeyR(18) = tr ^ subr(19); | ||
1055 | CamelliaSubkeyL(19) = subl(18) ^ subl(20); /* round 14 */ | ||
1056 | CamelliaSubkeyR(19) = subr(18) ^ subr(20); | ||
1057 | CamelliaSubkeyL(20) = subl(19) ^ subl(21); /* round 15 */ | ||
1058 | CamelliaSubkeyR(20) = subr(19) ^ subr(21); | ||
1059 | CamelliaSubkeyL(21) = subl(20) ^ subl(22); /* round 16 */ | ||
1060 | CamelliaSubkeyR(21) = subr(20) ^ subr(22); | ||
1061 | CamelliaSubkeyL(22) = subl(21) ^ subl(23); /* round 17 */ | ||
1062 | CamelliaSubkeyR(22) = subr(21) ^ subr(23); | ||
1063 | tl = subl(26) ^ (subr(26) | ||
1064 | & ~subr(24)); | ||
1065 | dw = tl & subl(24), /* FL(kl5) */ | ||
1066 | tr = subr(26) ^ CAMELLIA_RL1(dw); | ||
1067 | CamelliaSubkeyL(23) = subl(22) ^ tl; /* round 18 */ | ||
1068 | CamelliaSubkeyR(23) = subr(22) ^ tr; | ||
1069 | CamelliaSubkeyL(24) = subl(24); /* FL(kl5) */ | ||
1070 | CamelliaSubkeyR(24) = subr(24); | ||
1071 | CamelliaSubkeyL(25) = subl(25); /* FLinv(kl6) */ | ||
1072 | CamelliaSubkeyR(25) = subr(25); | ||
1073 | tl = subl(23) ^ (subr(23) & | ||
1074 | ~subr(25)); | ||
1075 | dw = tl & subl(25), /* FLinv(kl6) */ | ||
1076 | tr = subr(23) ^ CAMELLIA_RL1(dw); | ||
1077 | CamelliaSubkeyL(26) = tl ^ subl(27); /* round 19 */ | ||
1078 | CamelliaSubkeyR(26) = tr ^ subr(27); | ||
1079 | CamelliaSubkeyL(27) = subl(26) ^ subl(28); /* round 20 */ | ||
1080 | CamelliaSubkeyR(27) = subr(26) ^ subr(28); | ||
1081 | CamelliaSubkeyL(28) = subl(27) ^ subl(29); /* round 21 */ | ||
1082 | CamelliaSubkeyR(28) = subr(27) ^ subr(29); | ||
1083 | CamelliaSubkeyL(29) = subl(28) ^ subl(30); /* round 22 */ | ||
1084 | CamelliaSubkeyR(29) = subr(28) ^ subr(30); | ||
1085 | CamelliaSubkeyL(30) = subl(29) ^ subl(31); /* round 23 */ | ||
1086 | CamelliaSubkeyR(30) = subr(29) ^ subr(31); | ||
1087 | CamelliaSubkeyL(31) = subl(30); /* round 24 */ | ||
1088 | CamelliaSubkeyR(31) = subr(30); | ||
1089 | CamelliaSubkeyL(32) = subl(32) ^ subl(31); /* kw3 */ | ||
1090 | CamelliaSubkeyR(32) = subr(32) ^ subr(31); | ||
1091 | |||
1092 | /* apply the inverse of the last half of P-function */ | ||
1093 | dw = CamelliaSubkeyL(2) ^ CamelliaSubkeyR(2), | ||
1094 | dw = CAMELLIA_RL8(dw);/* round 1 */ | ||
1095 | CamelliaSubkeyR(2) = CamelliaSubkeyL(2) ^ dw, | ||
1096 | CamelliaSubkeyL(2) = dw; | ||
1097 | dw = CamelliaSubkeyL(3) ^ CamelliaSubkeyR(3), | ||
1098 | dw = CAMELLIA_RL8(dw);/* round 2 */ | ||
1099 | CamelliaSubkeyR(3) = CamelliaSubkeyL(3) ^ dw, | ||
1100 | CamelliaSubkeyL(3) = dw; | ||
1101 | dw = CamelliaSubkeyL(4) ^ CamelliaSubkeyR(4), | ||
1102 | dw = CAMELLIA_RL8(dw);/* round 3 */ | ||
1103 | CamelliaSubkeyR(4) = CamelliaSubkeyL(4) ^ dw, | ||
1104 | CamelliaSubkeyL(4) = dw; | ||
1105 | dw = CamelliaSubkeyL(5) ^ CamelliaSubkeyR(5), | ||
1106 | dw = CAMELLIA_RL8(dw);/* round 4 */ | ||
1107 | CamelliaSubkeyR(5) = CamelliaSubkeyL(5) ^ dw, | ||
1108 | CamelliaSubkeyL(5) = dw; | ||
1109 | dw = CamelliaSubkeyL(6) ^ CamelliaSubkeyR(6), | ||
1110 | dw = CAMELLIA_RL8(dw);/* round 5 */ | ||
1111 | CamelliaSubkeyR(6) = CamelliaSubkeyL(6) ^ dw, | ||
1112 | CamelliaSubkeyL(6) = dw; | ||
1113 | dw = CamelliaSubkeyL(7) ^ CamelliaSubkeyR(7), | ||
1114 | dw = CAMELLIA_RL8(dw);/* round 6 */ | ||
1115 | CamelliaSubkeyR(7) = CamelliaSubkeyL(7) ^ dw, | ||
1116 | CamelliaSubkeyL(7) = dw; | ||
1117 | dw = CamelliaSubkeyL(10) ^ CamelliaSubkeyR(10), | ||
1118 | dw = CAMELLIA_RL8(dw);/* round 7 */ | ||
1119 | CamelliaSubkeyR(10) = CamelliaSubkeyL(10) ^ dw, | ||
1120 | CamelliaSubkeyL(10) = dw; | ||
1121 | dw = CamelliaSubkeyL(11) ^ CamelliaSubkeyR(11), | ||
1122 | dw = CAMELLIA_RL8(dw);/* round 8 */ | ||
1123 | CamelliaSubkeyR(11) = CamelliaSubkeyL(11) ^ dw, | ||
1124 | CamelliaSubkeyL(11) = dw; | ||
1125 | dw = CamelliaSubkeyL(12) ^ CamelliaSubkeyR(12), | ||
1126 | dw = CAMELLIA_RL8(dw);/* round 9 */ | ||
1127 | CamelliaSubkeyR(12) = CamelliaSubkeyL(12) ^ dw, | ||
1128 | CamelliaSubkeyL(12) = dw; | ||
1129 | dw = CamelliaSubkeyL(13) ^ CamelliaSubkeyR(13), | ||
1130 | dw = CAMELLIA_RL8(dw);/* round 10 */ | ||
1131 | CamelliaSubkeyR(13) = CamelliaSubkeyL(13) ^ dw, | ||
1132 | CamelliaSubkeyL(13) = dw; | ||
1133 | dw = CamelliaSubkeyL(14) ^ CamelliaSubkeyR(14), | ||
1134 | dw = CAMELLIA_RL8(dw);/* round 11 */ | ||
1135 | CamelliaSubkeyR(14) = CamelliaSubkeyL(14) ^ dw, | ||
1136 | CamelliaSubkeyL(14) = dw; | ||
1137 | dw = CamelliaSubkeyL(15) ^ CamelliaSubkeyR(15), | ||
1138 | dw = CAMELLIA_RL8(dw);/* round 12 */ | ||
1139 | CamelliaSubkeyR(15) = CamelliaSubkeyL(15) ^ dw, | ||
1140 | CamelliaSubkeyL(15) = dw; | ||
1141 | dw = CamelliaSubkeyL(18) ^ CamelliaSubkeyR(18), | ||
1142 | dw = CAMELLIA_RL8(dw);/* round 13 */ | ||
1143 | CamelliaSubkeyR(18) = CamelliaSubkeyL(18) ^ dw, | ||
1144 | CamelliaSubkeyL(18) = dw; | ||
1145 | dw = CamelliaSubkeyL(19) ^ CamelliaSubkeyR(19), | ||
1146 | dw = CAMELLIA_RL8(dw);/* round 14 */ | ||
1147 | CamelliaSubkeyR(19) = CamelliaSubkeyL(19) ^ dw, | ||
1148 | CamelliaSubkeyL(19) = dw; | ||
1149 | dw = CamelliaSubkeyL(20) ^ CamelliaSubkeyR(20), | ||
1150 | dw = CAMELLIA_RL8(dw);/* round 15 */ | ||
1151 | CamelliaSubkeyR(20) = CamelliaSubkeyL(20) ^ dw, | ||
1152 | CamelliaSubkeyL(20) = dw; | ||
1153 | dw = CamelliaSubkeyL(21) ^ CamelliaSubkeyR(21), | ||
1154 | dw = CAMELLIA_RL8(dw);/* round 16 */ | ||
1155 | CamelliaSubkeyR(21) = CamelliaSubkeyL(21) ^ dw, | ||
1156 | CamelliaSubkeyL(21) = dw; | ||
1157 | dw = CamelliaSubkeyL(22) ^ CamelliaSubkeyR(22), | ||
1158 | dw = CAMELLIA_RL8(dw);/* round 17 */ | ||
1159 | CamelliaSubkeyR(22) = CamelliaSubkeyL(22) ^ dw, | ||
1160 | CamelliaSubkeyL(22) = dw; | ||
1161 | dw = CamelliaSubkeyL(23) ^ CamelliaSubkeyR(23), | ||
1162 | dw = CAMELLIA_RL8(dw);/* round 18 */ | ||
1163 | CamelliaSubkeyR(23) = CamelliaSubkeyL(23) ^ dw, | ||
1164 | CamelliaSubkeyL(23) = dw; | ||
1165 | dw = CamelliaSubkeyL(26) ^ CamelliaSubkeyR(26), | ||
1166 | dw = CAMELLIA_RL8(dw);/* round 19 */ | ||
1167 | CamelliaSubkeyR(26) = CamelliaSubkeyL(26) ^ dw, | ||
1168 | CamelliaSubkeyL(26) = dw; | ||
1169 | dw = CamelliaSubkeyL(27) ^ CamelliaSubkeyR(27), | ||
1170 | dw = CAMELLIA_RL8(dw);/* round 20 */ | ||
1171 | CamelliaSubkeyR(27) = CamelliaSubkeyL(27) ^ dw, | ||
1172 | CamelliaSubkeyL(27) = dw; | ||
1173 | dw = CamelliaSubkeyL(28) ^ CamelliaSubkeyR(28), | ||
1174 | dw = CAMELLIA_RL8(dw);/* round 21 */ | ||
1175 | CamelliaSubkeyR(28) = CamelliaSubkeyL(28) ^ dw, | ||
1176 | CamelliaSubkeyL(28) = dw; | ||
1177 | dw = CamelliaSubkeyL(29) ^ CamelliaSubkeyR(29), | ||
1178 | dw = CAMELLIA_RL8(dw);/* round 22 */ | ||
1179 | CamelliaSubkeyR(29) = CamelliaSubkeyL(29) ^ dw, | ||
1180 | CamelliaSubkeyL(29) = dw; | ||
1181 | dw = CamelliaSubkeyL(30) ^ CamelliaSubkeyR(30), | ||
1182 | dw = CAMELLIA_RL8(dw);/* round 23 */ | ||
1183 | CamelliaSubkeyR(30) = CamelliaSubkeyL(30) ^ dw, | ||
1184 | CamelliaSubkeyL(30) = dw; | ||
1185 | dw = CamelliaSubkeyL(31) ^ CamelliaSubkeyR(31), | ||
1186 | dw = CAMELLIA_RL8(dw);/* round 24 */ | ||
1187 | CamelliaSubkeyR(31) = CamelliaSubkeyL(31) ^ dw, | ||
1188 | CamelliaSubkeyL(31) = dw; | ||
1189 | |||
1190 | |||
1191 | return; | ||
1192 | } | ||
1193 | |||
1194 | void camellia_setup192(const u8 *key, u32 *subkey) | ||
1195 | { | ||
1196 | u8 kk[32]; | ||
1197 | u32 krll, krlr, krrl,krrr; | ||
1198 | |||
1199 | memcpy(kk, key, 24); | ||
1200 | memcpy((u8 *)&krll, key+16,4); | ||
1201 | memcpy((u8 *)&krlr, key+20,4); | ||
1202 | krrl = ~krll; | ||
1203 | krrr = ~krlr; | ||
1204 | memcpy(kk+24, (u8 *)&krrl, 4); | ||
1205 | memcpy(kk+28, (u8 *)&krrr, 4); | ||
1206 | camellia_setup256(kk, subkey); | ||
1207 | return; | ||
1208 | } | ||
1209 | |||
1210 | |||
1211 | /** | ||
1212 | * Stuff related to camellia encryption/decryption | ||
1213 | */ | ||
1214 | void camellia_encrypt128(const u32 *subkey, u32 *io) | ||
1215 | { | ||
1216 | u32 il, ir, t0, t1; | ||
1217 | |||
1218 | /* pre whitening but absorb kw2*/ | ||
1219 | io[0] ^= CamelliaSubkeyL(0); | ||
1220 | io[1] ^= CamelliaSubkeyR(0); | ||
1221 | /* main iteration */ | ||
1222 | |||
1223 | CAMELLIA_ROUNDSM(io[0],io[1], | ||
1224 | CamelliaSubkeyL(2),CamelliaSubkeyR(2), | ||
1225 | io[2],io[3],il,ir,t0,t1); | ||
1226 | CAMELLIA_ROUNDSM(io[2],io[3], | ||
1227 | CamelliaSubkeyL(3),CamelliaSubkeyR(3), | ||
1228 | io[0],io[1],il,ir,t0,t1); | ||
1229 | CAMELLIA_ROUNDSM(io[0],io[1], | ||
1230 | CamelliaSubkeyL(4),CamelliaSubkeyR(4), | ||
1231 | io[2],io[3],il,ir,t0,t1); | ||
1232 | CAMELLIA_ROUNDSM(io[2],io[3], | ||
1233 | CamelliaSubkeyL(5),CamelliaSubkeyR(5), | ||
1234 | io[0],io[1],il,ir,t0,t1); | ||
1235 | CAMELLIA_ROUNDSM(io[0],io[1], | ||
1236 | CamelliaSubkeyL(6),CamelliaSubkeyR(6), | ||
1237 | io[2],io[3],il,ir,t0,t1); | ||
1238 | CAMELLIA_ROUNDSM(io[2],io[3], | ||
1239 | CamelliaSubkeyL(7),CamelliaSubkeyR(7), | ||
1240 | io[0],io[1],il,ir,t0,t1); | ||
1241 | |||
1242 | CAMELLIA_FLS(io[0],io[1],io[2],io[3], | ||
1243 | CamelliaSubkeyL(8),CamelliaSubkeyR(8), | ||
1244 | CamelliaSubkeyL(9),CamelliaSubkeyR(9), | ||
1245 | t0,t1,il,ir); | ||
1246 | |||
1247 | CAMELLIA_ROUNDSM(io[0],io[1], | ||
1248 | CamelliaSubkeyL(10),CamelliaSubkeyR(10), | ||
1249 | io[2],io[3],il,ir,t0,t1); | ||
1250 | CAMELLIA_ROUNDSM(io[2],io[3], | ||
1251 | CamelliaSubkeyL(11),CamelliaSubkeyR(11), | ||
1252 | io[0],io[1],il,ir,t0,t1); | ||
1253 | CAMELLIA_ROUNDSM(io[0],io[1], | ||
1254 | CamelliaSubkeyL(12),CamelliaSubkeyR(12), | ||
1255 | io[2],io[3],il,ir,t0,t1); | ||
1256 | CAMELLIA_ROUNDSM(io[2],io[3], | ||
1257 | CamelliaSubkeyL(13),CamelliaSubkeyR(13), | ||
1258 | io[0],io[1],il,ir,t0,t1); | ||
1259 | CAMELLIA_ROUNDSM(io[0],io[1], | ||
1260 | CamelliaSubkeyL(14),CamelliaSubkeyR(14), | ||
1261 | io[2],io[3],il,ir,t0,t1); | ||
1262 | CAMELLIA_ROUNDSM(io[2],io[3], | ||
1263 | CamelliaSubkeyL(15),CamelliaSubkeyR(15), | ||
1264 | io[0],io[1],il,ir,t0,t1); | ||
1265 | |||
1266 | CAMELLIA_FLS(io[0],io[1],io[2],io[3], | ||
1267 | CamelliaSubkeyL(16),CamelliaSubkeyR(16), | ||
1268 | CamelliaSubkeyL(17),CamelliaSubkeyR(17), | ||
1269 | t0,t1,il,ir); | ||
1270 | |||
1271 | CAMELLIA_ROUNDSM(io[0],io[1], | ||
1272 | CamelliaSubkeyL(18),CamelliaSubkeyR(18), | ||
1273 | io[2],io[3],il,ir,t0,t1); | ||
1274 | CAMELLIA_ROUNDSM(io[2],io[3], | ||
1275 | CamelliaSubkeyL(19),CamelliaSubkeyR(19), | ||
1276 | io[0],io[1],il,ir,t0,t1); | ||
1277 | CAMELLIA_ROUNDSM(io[0],io[1], | ||
1278 | CamelliaSubkeyL(20),CamelliaSubkeyR(20), | ||
1279 | io[2],io[3],il,ir,t0,t1); | ||
1280 | CAMELLIA_ROUNDSM(io[2],io[3], | ||
1281 | CamelliaSubkeyL(21),CamelliaSubkeyR(21), | ||
1282 | io[0],io[1],il,ir,t0,t1); | ||
1283 | CAMELLIA_ROUNDSM(io[0],io[1], | ||
1284 | CamelliaSubkeyL(22),CamelliaSubkeyR(22), | ||
1285 | io[2],io[3],il,ir,t0,t1); | ||
1286 | CAMELLIA_ROUNDSM(io[2],io[3], | ||
1287 | CamelliaSubkeyL(23),CamelliaSubkeyR(23), | ||
1288 | io[0],io[1],il,ir,t0,t1); | ||
1289 | |||
1290 | /* post whitening but kw4 */ | ||
1291 | io[2] ^= CamelliaSubkeyL(24); | ||
1292 | io[3] ^= CamelliaSubkeyR(24); | ||
1293 | |||
1294 | t0 = io[0]; | ||
1295 | t1 = io[1]; | ||
1296 | io[0] = io[2]; | ||
1297 | io[1] = io[3]; | ||
1298 | io[2] = t0; | ||
1299 | io[3] = t1; | ||
1300 | |||
1301 | return; | ||
1302 | } | ||
1303 | |||
1304 | void camellia_decrypt128(const u32 *subkey, u32 *io) | ||
1305 | { | ||
1306 | u32 il,ir,t0,t1; /* temporary valiables */ | ||
1307 | |||
1308 | /* pre whitening but absorb kw2*/ | ||
1309 | io[0] ^= CamelliaSubkeyL(24); | ||
1310 | io[1] ^= CamelliaSubkeyR(24); | ||
1311 | |||
1312 | /* main iteration */ | ||
1313 | CAMELLIA_ROUNDSM(io[0],io[1], | ||
1314 | CamelliaSubkeyL(23),CamelliaSubkeyR(23), | ||
1315 | io[2],io[3],il,ir,t0,t1); | ||
1316 | CAMELLIA_ROUNDSM(io[2],io[3], | ||
1317 | CamelliaSubkeyL(22),CamelliaSubkeyR(22), | ||
1318 | io[0],io[1],il,ir,t0,t1); | ||
1319 | CAMELLIA_ROUNDSM(io[0],io[1], | ||
1320 | CamelliaSubkeyL(21),CamelliaSubkeyR(21), | ||
1321 | io[2],io[3],il,ir,t0,t1); | ||
1322 | CAMELLIA_ROUNDSM(io[2],io[3], | ||
1323 | CamelliaSubkeyL(20),CamelliaSubkeyR(20), | ||
1324 | io[0],io[1],il,ir,t0,t1); | ||
1325 | CAMELLIA_ROUNDSM(io[0],io[1], | ||
1326 | CamelliaSubkeyL(19),CamelliaSubkeyR(19), | ||
1327 | io[2],io[3],il,ir,t0,t1); | ||
1328 | CAMELLIA_ROUNDSM(io[2],io[3], | ||
1329 | CamelliaSubkeyL(18),CamelliaSubkeyR(18), | ||
1330 | io[0],io[1],il,ir,t0,t1); | ||
1331 | |||
1332 | CAMELLIA_FLS(io[0],io[1],io[2],io[3], | ||
1333 | CamelliaSubkeyL(17),CamelliaSubkeyR(17), | ||
1334 | CamelliaSubkeyL(16),CamelliaSubkeyR(16), | ||
1335 | t0,t1,il,ir); | ||
1336 | |||
1337 | CAMELLIA_ROUNDSM(io[0],io[1], | ||
1338 | CamelliaSubkeyL(15),CamelliaSubkeyR(15), | ||
1339 | io[2],io[3],il,ir,t0,t1); | ||
1340 | CAMELLIA_ROUNDSM(io[2],io[3], | ||
1341 | CamelliaSubkeyL(14),CamelliaSubkeyR(14), | ||
1342 | io[0],io[1],il,ir,t0,t1); | ||
1343 | CAMELLIA_ROUNDSM(io[0],io[1], | ||
1344 | CamelliaSubkeyL(13),CamelliaSubkeyR(13), | ||
1345 | io[2],io[3],il,ir,t0,t1); | ||
1346 | CAMELLIA_ROUNDSM(io[2],io[3], | ||
1347 | CamelliaSubkeyL(12),CamelliaSubkeyR(12), | ||
1348 | io[0],io[1],il,ir,t0,t1); | ||
1349 | CAMELLIA_ROUNDSM(io[0],io[1], | ||
1350 | CamelliaSubkeyL(11),CamelliaSubkeyR(11), | ||
1351 | io[2],io[3],il,ir,t0,t1); | ||
1352 | CAMELLIA_ROUNDSM(io[2],io[3], | ||
1353 | CamelliaSubkeyL(10),CamelliaSubkeyR(10), | ||
1354 | io[0],io[1],il,ir,t0,t1); | ||
1355 | |||
1356 | CAMELLIA_FLS(io[0],io[1],io[2],io[3], | ||
1357 | CamelliaSubkeyL(9),CamelliaSubkeyR(9), | ||
1358 | CamelliaSubkeyL(8),CamelliaSubkeyR(8), | ||
1359 | t0,t1,il,ir); | ||
1360 | |||
1361 | CAMELLIA_ROUNDSM(io[0],io[1], | ||
1362 | CamelliaSubkeyL(7),CamelliaSubkeyR(7), | ||
1363 | io[2],io[3],il,ir,t0,t1); | ||
1364 | CAMELLIA_ROUNDSM(io[2],io[3], | ||
1365 | CamelliaSubkeyL(6),CamelliaSubkeyR(6), | ||
1366 | io[0],io[1],il,ir,t0,t1); | ||
1367 | CAMELLIA_ROUNDSM(io[0],io[1], | ||
1368 | CamelliaSubkeyL(5),CamelliaSubkeyR(5), | ||
1369 | io[2],io[3],il,ir,t0,t1); | ||
1370 | CAMELLIA_ROUNDSM(io[2],io[3], | ||
1371 | CamelliaSubkeyL(4),CamelliaSubkeyR(4), | ||
1372 | io[0],io[1],il,ir,t0,t1); | ||
1373 | CAMELLIA_ROUNDSM(io[0],io[1], | ||
1374 | CamelliaSubkeyL(3),CamelliaSubkeyR(3), | ||
1375 | io[2],io[3],il,ir,t0,t1); | ||
1376 | CAMELLIA_ROUNDSM(io[2],io[3], | ||
1377 | CamelliaSubkeyL(2),CamelliaSubkeyR(2), | ||
1378 | io[0],io[1],il,ir,t0,t1); | ||
1379 | |||
1380 | /* post whitening but kw4 */ | ||
1381 | io[2] ^= CamelliaSubkeyL(0); | ||
1382 | io[3] ^= CamelliaSubkeyR(0); | ||
1383 | |||
1384 | t0 = io[0]; | ||
1385 | t1 = io[1]; | ||
1386 | io[0] = io[2]; | ||
1387 | io[1] = io[3]; | ||
1388 | io[2] = t0; | ||
1389 | io[3] = t1; | ||
1390 | |||
1391 | return; | ||
1392 | } | ||
1393 | |||
1394 | /** | ||
1395 | * stuff for 192 and 256bit encryption/decryption | ||
1396 | */ | ||
1397 | void camellia_encrypt256(const u32 *subkey, u32 *io) | ||
1398 | { | ||
1399 | u32 il,ir,t0,t1; /* temporary valiables */ | ||
1400 | |||
1401 | /* pre whitening but absorb kw2*/ | ||
1402 | io[0] ^= CamelliaSubkeyL(0); | ||
1403 | io[1] ^= CamelliaSubkeyR(0); | ||
1404 | |||
1405 | /* main iteration */ | ||
1406 | CAMELLIA_ROUNDSM(io[0],io[1], | ||
1407 | CamelliaSubkeyL(2),CamelliaSubkeyR(2), | ||
1408 | io[2],io[3],il,ir,t0,t1); | ||
1409 | CAMELLIA_ROUNDSM(io[2],io[3], | ||
1410 | CamelliaSubkeyL(3),CamelliaSubkeyR(3), | ||
1411 | io[0],io[1],il,ir,t0,t1); | ||
1412 | CAMELLIA_ROUNDSM(io[0],io[1], | ||
1413 | CamelliaSubkeyL(4),CamelliaSubkeyR(4), | ||
1414 | io[2],io[3],il,ir,t0,t1); | ||
1415 | CAMELLIA_ROUNDSM(io[2],io[3], | ||
1416 | CamelliaSubkeyL(5),CamelliaSubkeyR(5), | ||
1417 | io[0],io[1],il,ir,t0,t1); | ||
1418 | CAMELLIA_ROUNDSM(io[0],io[1], | ||
1419 | CamelliaSubkeyL(6),CamelliaSubkeyR(6), | ||
1420 | io[2],io[3],il,ir,t0,t1); | ||
1421 | CAMELLIA_ROUNDSM(io[2],io[3], | ||
1422 | CamelliaSubkeyL(7),CamelliaSubkeyR(7), | ||
1423 | io[0],io[1],il,ir,t0,t1); | ||
1424 | |||
1425 | CAMELLIA_FLS(io[0],io[1],io[2],io[3], | ||
1426 | CamelliaSubkeyL(8),CamelliaSubkeyR(8), | ||
1427 | CamelliaSubkeyL(9),CamelliaSubkeyR(9), | ||
1428 | t0,t1,il,ir); | ||
1429 | |||
1430 | CAMELLIA_ROUNDSM(io[0],io[1], | ||
1431 | CamelliaSubkeyL(10),CamelliaSubkeyR(10), | ||
1432 | io[2],io[3],il,ir,t0,t1); | ||
1433 | CAMELLIA_ROUNDSM(io[2],io[3], | ||
1434 | CamelliaSubkeyL(11),CamelliaSubkeyR(11), | ||
1435 | io[0],io[1],il,ir,t0,t1); | ||
1436 | CAMELLIA_ROUNDSM(io[0],io[1], | ||
1437 | CamelliaSubkeyL(12),CamelliaSubkeyR(12), | ||
1438 | io[2],io[3],il,ir,t0,t1); | ||
1439 | CAMELLIA_ROUNDSM(io[2],io[3], | ||
1440 | CamelliaSubkeyL(13),CamelliaSubkeyR(13), | ||
1441 | io[0],io[1],il,ir,t0,t1); | ||
1442 | CAMELLIA_ROUNDSM(io[0],io[1], | ||
1443 | CamelliaSubkeyL(14),CamelliaSubkeyR(14), | ||
1444 | io[2],io[3],il,ir,t0,t1); | ||
1445 | CAMELLIA_ROUNDSM(io[2],io[3], | ||
1446 | CamelliaSubkeyL(15),CamelliaSubkeyR(15), | ||
1447 | io[0],io[1],il,ir,t0,t1); | ||
1448 | |||
1449 | CAMELLIA_FLS(io[0],io[1],io[2],io[3], | ||
1450 | CamelliaSubkeyL(16),CamelliaSubkeyR(16), | ||
1451 | CamelliaSubkeyL(17),CamelliaSubkeyR(17), | ||
1452 | t0,t1,il,ir); | ||
1453 | |||
1454 | CAMELLIA_ROUNDSM(io[0],io[1], | ||
1455 | CamelliaSubkeyL(18),CamelliaSubkeyR(18), | ||
1456 | io[2],io[3],il,ir,t0,t1); | ||
1457 | CAMELLIA_ROUNDSM(io[2],io[3], | ||
1458 | CamelliaSubkeyL(19),CamelliaSubkeyR(19), | ||
1459 | io[0],io[1],il,ir,t0,t1); | ||
1460 | CAMELLIA_ROUNDSM(io[0],io[1], | ||
1461 | CamelliaSubkeyL(20),CamelliaSubkeyR(20), | ||
1462 | io[2],io[3],il,ir,t0,t1); | ||
1463 | CAMELLIA_ROUNDSM(io[2],io[3], | ||
1464 | CamelliaSubkeyL(21),CamelliaSubkeyR(21), | ||
1465 | io[0],io[1],il,ir,t0,t1); | ||
1466 | CAMELLIA_ROUNDSM(io[0],io[1], | ||
1467 | CamelliaSubkeyL(22),CamelliaSubkeyR(22), | ||
1468 | io[2],io[3],il,ir,t0,t1); | ||
1469 | CAMELLIA_ROUNDSM(io[2],io[3], | ||
1470 | CamelliaSubkeyL(23),CamelliaSubkeyR(23), | ||
1471 | io[0],io[1],il,ir,t0,t1); | ||
1472 | |||
1473 | CAMELLIA_FLS(io[0],io[1],io[2],io[3], | ||
1474 | CamelliaSubkeyL(24),CamelliaSubkeyR(24), | ||
1475 | CamelliaSubkeyL(25),CamelliaSubkeyR(25), | ||
1476 | t0,t1,il,ir); | ||
1477 | |||
1478 | CAMELLIA_ROUNDSM(io[0],io[1], | ||
1479 | CamelliaSubkeyL(26),CamelliaSubkeyR(26), | ||
1480 | io[2],io[3],il,ir,t0,t1); | ||
1481 | CAMELLIA_ROUNDSM(io[2],io[3], | ||
1482 | CamelliaSubkeyL(27),CamelliaSubkeyR(27), | ||
1483 | io[0],io[1],il,ir,t0,t1); | ||
1484 | CAMELLIA_ROUNDSM(io[0],io[1], | ||
1485 | CamelliaSubkeyL(28),CamelliaSubkeyR(28), | ||
1486 | io[2],io[3],il,ir,t0,t1); | ||
1487 | CAMELLIA_ROUNDSM(io[2],io[3], | ||
1488 | CamelliaSubkeyL(29),CamelliaSubkeyR(29), | ||
1489 | io[0],io[1],il,ir,t0,t1); | ||
1490 | CAMELLIA_ROUNDSM(io[0],io[1], | ||
1491 | CamelliaSubkeyL(30),CamelliaSubkeyR(30), | ||
1492 | io[2],io[3],il,ir,t0,t1); | ||
1493 | CAMELLIA_ROUNDSM(io[2],io[3], | ||
1494 | CamelliaSubkeyL(31),CamelliaSubkeyR(31), | ||
1495 | io[0],io[1],il,ir,t0,t1); | ||
1496 | |||
1497 | /* post whitening but kw4 */ | ||
1498 | io[2] ^= CamelliaSubkeyL(32); | ||
1499 | io[3] ^= CamelliaSubkeyR(32); | ||
1500 | |||
1501 | t0 = io[0]; | ||
1502 | t1 = io[1]; | ||
1503 | io[0] = io[2]; | ||
1504 | io[1] = io[3]; | ||
1505 | io[2] = t0; | ||
1506 | io[3] = t1; | ||
1507 | |||
1508 | return; | ||
1509 | } | ||
1510 | |||
1511 | void camellia_decrypt256(const u32 *subkey, u32 *io) | ||
1512 | { | ||
1513 | u32 il,ir,t0,t1; /* temporary valiables */ | ||
1514 | |||
1515 | /* pre whitening but absorb kw2*/ | ||
1516 | io[0] ^= CamelliaSubkeyL(32); | ||
1517 | io[1] ^= CamelliaSubkeyR(32); | ||
1518 | |||
1519 | /* main iteration */ | ||
1520 | CAMELLIA_ROUNDSM(io[0],io[1], | ||
1521 | CamelliaSubkeyL(31),CamelliaSubkeyR(31), | ||
1522 | io[2],io[3],il,ir,t0,t1); | ||
1523 | CAMELLIA_ROUNDSM(io[2],io[3], | ||
1524 | CamelliaSubkeyL(30),CamelliaSubkeyR(30), | ||
1525 | io[0],io[1],il,ir,t0,t1); | ||
1526 | CAMELLIA_ROUNDSM(io[0],io[1], | ||
1527 | CamelliaSubkeyL(29),CamelliaSubkeyR(29), | ||
1528 | io[2],io[3],il,ir,t0,t1); | ||
1529 | CAMELLIA_ROUNDSM(io[2],io[3], | ||
1530 | CamelliaSubkeyL(28),CamelliaSubkeyR(28), | ||
1531 | io[0],io[1],il,ir,t0,t1); | ||
1532 | CAMELLIA_ROUNDSM(io[0],io[1], | ||
1533 | CamelliaSubkeyL(27),CamelliaSubkeyR(27), | ||
1534 | io[2],io[3],il,ir,t0,t1); | ||
1535 | CAMELLIA_ROUNDSM(io[2],io[3], | ||
1536 | CamelliaSubkeyL(26),CamelliaSubkeyR(26), | ||
1537 | io[0],io[1],il,ir,t0,t1); | ||
1538 | |||
1539 | CAMELLIA_FLS(io[0],io[1],io[2],io[3], | ||
1540 | CamelliaSubkeyL(25),CamelliaSubkeyR(25), | ||
1541 | CamelliaSubkeyL(24),CamelliaSubkeyR(24), | ||
1542 | t0,t1,il,ir); | ||
1543 | |||
1544 | CAMELLIA_ROUNDSM(io[0],io[1], | ||
1545 | CamelliaSubkeyL(23),CamelliaSubkeyR(23), | ||
1546 | io[2],io[3],il,ir,t0,t1); | ||
1547 | CAMELLIA_ROUNDSM(io[2],io[3], | ||
1548 | CamelliaSubkeyL(22),CamelliaSubkeyR(22), | ||
1549 | io[0],io[1],il,ir,t0,t1); | ||
1550 | CAMELLIA_ROUNDSM(io[0],io[1], | ||
1551 | CamelliaSubkeyL(21),CamelliaSubkeyR(21), | ||
1552 | io[2],io[3],il,ir,t0,t1); | ||
1553 | CAMELLIA_ROUNDSM(io[2],io[3], | ||
1554 | CamelliaSubkeyL(20),CamelliaSubkeyR(20), | ||
1555 | io[0],io[1],il,ir,t0,t1); | ||
1556 | CAMELLIA_ROUNDSM(io[0],io[1], | ||
1557 | CamelliaSubkeyL(19),CamelliaSubkeyR(19), | ||
1558 | io[2],io[3],il,ir,t0,t1); | ||
1559 | CAMELLIA_ROUNDSM(io[2],io[3], | ||
1560 | CamelliaSubkeyL(18),CamelliaSubkeyR(18), | ||
1561 | io[0],io[1],il,ir,t0,t1); | ||
1562 | |||
1563 | CAMELLIA_FLS(io[0],io[1],io[2],io[3], | ||
1564 | CamelliaSubkeyL(17),CamelliaSubkeyR(17), | ||
1565 | CamelliaSubkeyL(16),CamelliaSubkeyR(16), | ||
1566 | t0,t1,il,ir); | ||
1567 | |||
1568 | CAMELLIA_ROUNDSM(io[0],io[1], | ||
1569 | CamelliaSubkeyL(15),CamelliaSubkeyR(15), | ||
1570 | io[2],io[3],il,ir,t0,t1); | ||
1571 | CAMELLIA_ROUNDSM(io[2],io[3], | ||
1572 | CamelliaSubkeyL(14),CamelliaSubkeyR(14), | ||
1573 | io[0],io[1],il,ir,t0,t1); | ||
1574 | CAMELLIA_ROUNDSM(io[0],io[1], | ||
1575 | CamelliaSubkeyL(13),CamelliaSubkeyR(13), | ||
1576 | io[2],io[3],il,ir,t0,t1); | ||
1577 | CAMELLIA_ROUNDSM(io[2],io[3], | ||
1578 | CamelliaSubkeyL(12),CamelliaSubkeyR(12), | ||
1579 | io[0],io[1],il,ir,t0,t1); | ||
1580 | CAMELLIA_ROUNDSM(io[0],io[1], | ||
1581 | CamelliaSubkeyL(11),CamelliaSubkeyR(11), | ||
1582 | io[2],io[3],il,ir,t0,t1); | ||
1583 | CAMELLIA_ROUNDSM(io[2],io[3], | ||
1584 | CamelliaSubkeyL(10),CamelliaSubkeyR(10), | ||
1585 | io[0],io[1],il,ir,t0,t1); | ||
1586 | |||
1587 | CAMELLIA_FLS(io[0],io[1],io[2],io[3], | ||
1588 | CamelliaSubkeyL(9),CamelliaSubkeyR(9), | ||
1589 | CamelliaSubkeyL(8),CamelliaSubkeyR(8), | ||
1590 | t0,t1,il,ir); | ||
1591 | |||
1592 | CAMELLIA_ROUNDSM(io[0],io[1], | ||
1593 | CamelliaSubkeyL(7),CamelliaSubkeyR(7), | ||
1594 | io[2],io[3],il,ir,t0,t1); | ||
1595 | CAMELLIA_ROUNDSM(io[2],io[3], | ||
1596 | CamelliaSubkeyL(6),CamelliaSubkeyR(6), | ||
1597 | io[0],io[1],il,ir,t0,t1); | ||
1598 | CAMELLIA_ROUNDSM(io[0],io[1], | ||
1599 | CamelliaSubkeyL(5),CamelliaSubkeyR(5), | ||
1600 | io[2],io[3],il,ir,t0,t1); | ||
1601 | CAMELLIA_ROUNDSM(io[2],io[3], | ||
1602 | CamelliaSubkeyL(4),CamelliaSubkeyR(4), | ||
1603 | io[0],io[1],il,ir,t0,t1); | ||
1604 | CAMELLIA_ROUNDSM(io[0],io[1], | ||
1605 | CamelliaSubkeyL(3),CamelliaSubkeyR(3), | ||
1606 | io[2],io[3],il,ir,t0,t1); | ||
1607 | CAMELLIA_ROUNDSM(io[2],io[3], | ||
1608 | CamelliaSubkeyL(2),CamelliaSubkeyR(2), | ||
1609 | io[0],io[1],il,ir,t0,t1); | ||
1610 | |||
1611 | /* post whitening but kw4 */ | ||
1612 | io[2] ^= CamelliaSubkeyL(0); | ||
1613 | io[3] ^= CamelliaSubkeyR(0); | ||
1614 | |||
1615 | t0 = io[0]; | ||
1616 | t1 = io[1]; | ||
1617 | io[0] = io[2]; | ||
1618 | io[1] = io[3]; | ||
1619 | io[2] = t0; | ||
1620 | io[3] = t1; | ||
1621 | |||
1622 | return; | ||
1623 | } | ||
1624 | |||
diff --git a/src/lib/libcrypto/camellia/camellia.h b/src/lib/libcrypto/camellia/camellia.h new file mode 100644 index 0000000000..3c8a359543 --- /dev/null +++ b/src/lib/libcrypto/camellia/camellia.h | |||
@@ -0,0 +1,129 @@ | |||
1 | /* crypto/camellia/camellia.h -*- mode:C; c-file-style: "eay" -*- */ | ||
2 | /* ==================================================================== | ||
3 | * Copyright (c) 2006 The OpenSSL Project. All rights reserved. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions | ||
7 | * are met: | ||
8 | * | ||
9 | * 1. Redistributions of source code must retain the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer. | ||
11 | * | ||
12 | * 2. Redistributions in binary form must reproduce the above copyright | ||
13 | * notice, this list of conditions and the following disclaimer in | ||
14 | * the documentation and/or other materials provided with the | ||
15 | * distribution. | ||
16 | * | ||
17 | * 3. All advertising materials mentioning features or use of this | ||
18 | * software must display the following acknowledgment: | ||
19 | * "This product includes software developed by the OpenSSL Project | ||
20 | * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" | ||
21 | * | ||
22 | * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to | ||
23 | * endorse or promote products derived from this software without | ||
24 | * prior written permission. For written permission, please contact | ||
25 | * openssl-core@openssl.org. | ||
26 | * | ||
27 | * 5. Products derived from this software may not be called "OpenSSL" | ||
28 | * nor may "OpenSSL" appear in their names without prior written | ||
29 | * permission of the OpenSSL Project. | ||
30 | * | ||
31 | * 6. Redistributions of any form whatsoever must retain the following | ||
32 | * acknowledgment: | ||
33 | * "This product includes software developed by the OpenSSL Project | ||
34 | * for use in the OpenSSL Toolkit (http://www.openssl.org/)" | ||
35 | * | ||
36 | * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY | ||
37 | * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
38 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | ||
39 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR | ||
40 | * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
41 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
42 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
43 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
44 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
45 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
46 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED | ||
47 | * OF THE POSSIBILITY OF SUCH DAMAGE. | ||
48 | * ==================================================================== | ||
49 | * | ||
50 | */ | ||
51 | |||
52 | #ifndef HEADER_CAMELLIA_H | ||
53 | #define HEADER_CAMELLIA_H | ||
54 | |||
55 | #include <openssl/opensslconf.h> | ||
56 | |||
57 | #ifdef OPENSSL_NO_CAMELLIA | ||
58 | #error CAMELLIA is disabled. | ||
59 | #endif | ||
60 | |||
61 | #define CAMELLIA_ENCRYPT 1 | ||
62 | #define CAMELLIA_DECRYPT 0 | ||
63 | |||
64 | /* Because array size can't be a const in C, the following two are macros. | ||
65 | Both sizes are in bytes. */ | ||
66 | |||
67 | #ifdef __cplusplus | ||
68 | extern "C" { | ||
69 | #endif | ||
70 | |||
71 | /* This should be a hidden type, but EVP requires that the size be known */ | ||
72 | |||
73 | #define CAMELLIA_BLOCK_SIZE 16 | ||
74 | #define CAMELLIA_TABLE_BYTE_LEN 272 | ||
75 | #define CAMELLIA_TABLE_WORD_LEN (CAMELLIA_TABLE_BYTE_LEN / 4) | ||
76 | |||
77 | /* to match with WORD */ | ||
78 | typedef unsigned int KEY_TABLE_TYPE[CAMELLIA_TABLE_WORD_LEN]; | ||
79 | |||
80 | struct camellia_key_st | ||
81 | { | ||
82 | KEY_TABLE_TYPE rd_key; | ||
83 | int bitLength; | ||
84 | void (*enc)(const unsigned int *subkey, unsigned int *io); | ||
85 | void (*dec)(const unsigned int *subkey, unsigned int *io); | ||
86 | }; | ||
87 | |||
88 | typedef struct camellia_key_st CAMELLIA_KEY; | ||
89 | |||
90 | int Camellia_set_key(const unsigned char *userKey, const int bits, | ||
91 | CAMELLIA_KEY *key); | ||
92 | |||
93 | void Camellia_encrypt(const unsigned char *in, unsigned char *out, | ||
94 | const CAMELLIA_KEY *key); | ||
95 | void Camellia_decrypt(const unsigned char *in, unsigned char *out, | ||
96 | const CAMELLIA_KEY *key); | ||
97 | |||
98 | void Camellia_ecb_encrypt(const unsigned char *in, unsigned char *out, | ||
99 | const CAMELLIA_KEY *key, const int enc); | ||
100 | void Camellia_cbc_encrypt(const unsigned char *in, unsigned char *out, | ||
101 | const unsigned long length, const CAMELLIA_KEY *key, | ||
102 | unsigned char *ivec, const int enc); | ||
103 | void Camellia_cfb128_encrypt(const unsigned char *in, unsigned char *out, | ||
104 | const unsigned long length, const CAMELLIA_KEY *key, | ||
105 | unsigned char *ivec, int *num, const int enc); | ||
106 | void Camellia_cfb1_encrypt(const unsigned char *in, unsigned char *out, | ||
107 | const unsigned long length, const CAMELLIA_KEY *key, | ||
108 | unsigned char *ivec, int *num, const int enc); | ||
109 | void Camellia_cfb8_encrypt(const unsigned char *in, unsigned char *out, | ||
110 | const unsigned long length, const CAMELLIA_KEY *key, | ||
111 | unsigned char *ivec, int *num, const int enc); | ||
112 | void Camellia_cfbr_encrypt_block(const unsigned char *in,unsigned char *out, | ||
113 | const int nbits,const CAMELLIA_KEY *key, | ||
114 | unsigned char *ivec,const int enc); | ||
115 | void Camellia_ofb128_encrypt(const unsigned char *in, unsigned char *out, | ||
116 | const unsigned long length, const CAMELLIA_KEY *key, | ||
117 | unsigned char *ivec, int *num); | ||
118 | void Camellia_ctr128_encrypt(const unsigned char *in, unsigned char *out, | ||
119 | const unsigned long length, const CAMELLIA_KEY *key, | ||
120 | unsigned char ivec[CAMELLIA_BLOCK_SIZE], | ||
121 | unsigned char ecount_buf[CAMELLIA_BLOCK_SIZE], | ||
122 | unsigned int *num); | ||
123 | |||
124 | #ifdef __cplusplus | ||
125 | } | ||
126 | #endif | ||
127 | |||
128 | #endif /* !HEADER_Camellia_H */ | ||
129 | |||
diff --git a/src/lib/libcrypto/camellia/cmll_cbc.c b/src/lib/libcrypto/camellia/cmll_cbc.c new file mode 100644 index 0000000000..4141a7b59b --- /dev/null +++ b/src/lib/libcrypto/camellia/cmll_cbc.c | |||
@@ -0,0 +1,273 @@ | |||
1 | /* crypto/camellia/camellia_cbc.c -*- mode:C; c-file-style: "eay" -*- */ | ||
2 | /* ==================================================================== | ||
3 | * Copyright (c) 2006 The OpenSSL Project. All rights reserved. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions | ||
7 | * are met: | ||
8 | * | ||
9 | * 1. Redistributions of source code must retain the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer. | ||
11 | * | ||
12 | * 2. Redistributions in binary form must reproduce the above copyright | ||
13 | * notice, this list of conditions and the following disclaimer in | ||
14 | * the documentation and/or other materials provided with the | ||
15 | * distribution. | ||
16 | * | ||
17 | * 3. All advertising materials mentioning features or use of this | ||
18 | * software must display the following acknowledgment: | ||
19 | * "This product includes software developed by the OpenSSL Project | ||
20 | * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" | ||
21 | * | ||
22 | * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to | ||
23 | * endorse or promote products derived from this software without | ||
24 | * prior written permission. For written permission, please contact | ||
25 | * openssl-core@openssl.org. | ||
26 | * | ||
27 | * 5. Products derived from this software may not be called "OpenSSL" | ||
28 | * nor may "OpenSSL" appear in their names without prior written | ||
29 | * permission of the OpenSSL Project. | ||
30 | * | ||
31 | * 6. Redistributions of any form whatsoever must retain the following | ||
32 | * acknowledgment: | ||
33 | * "This product includes software developed by the OpenSSL Project | ||
34 | * for use in the OpenSSL Toolkit (http://www.openssl.org/)" | ||
35 | * | ||
36 | * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY | ||
37 | * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
38 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | ||
39 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR | ||
40 | * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
41 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
42 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
43 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
44 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
45 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
46 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED | ||
47 | * OF THE POSSIBILITY OF SUCH DAMAGE. | ||
48 | * ==================================================================== | ||
49 | * | ||
50 | */ | ||
51 | |||
52 | #ifndef CAMELLIA_DEBUG | ||
53 | # ifndef NDEBUG | ||
54 | # define NDEBUG | ||
55 | # endif | ||
56 | #endif | ||
57 | #include <assert.h> | ||
58 | #include <stdio.h> | ||
59 | #include <string.h> | ||
60 | |||
61 | #include <openssl/camellia.h> | ||
62 | #include "cmll_locl.h" | ||
63 | |||
64 | void Camellia_cbc_encrypt(const unsigned char *in, unsigned char *out, | ||
65 | const unsigned long length, const CAMELLIA_KEY *key, | ||
66 | unsigned char *ivec, const int enc) { | ||
67 | |||
68 | unsigned long n; | ||
69 | unsigned long len = length; | ||
70 | const unsigned char *iv = ivec; | ||
71 | union { u32 t32[CAMELLIA_BLOCK_SIZE/sizeof(u32)]; | ||
72 | u8 t8 [CAMELLIA_BLOCK_SIZE]; } tmp; | ||
73 | const union { long one; char little; } camellia_endian = {1}; | ||
74 | |||
75 | |||
76 | assert(in && out && key && ivec); | ||
77 | assert((CAMELLIA_ENCRYPT == enc)||(CAMELLIA_DECRYPT == enc)); | ||
78 | |||
79 | if(((size_t)in|(size_t)out|(size_t)ivec) % sizeof(u32) == 0) | ||
80 | { | ||
81 | if (CAMELLIA_ENCRYPT == enc) | ||
82 | { | ||
83 | while (len >= CAMELLIA_BLOCK_SIZE) | ||
84 | { | ||
85 | XOR4WORD2((u32 *)out, | ||
86 | (u32 *)in, (u32 *)iv); | ||
87 | if (camellia_endian.little) | ||
88 | SWAP4WORD((u32 *)out); | ||
89 | key->enc(key->rd_key, (u32 *)out); | ||
90 | if (camellia_endian.little) | ||
91 | SWAP4WORD((u32 *)out); | ||
92 | iv = out; | ||
93 | len -= CAMELLIA_BLOCK_SIZE; | ||
94 | in += CAMELLIA_BLOCK_SIZE; | ||
95 | out += CAMELLIA_BLOCK_SIZE; | ||
96 | } | ||
97 | if (len) | ||
98 | { | ||
99 | for(n=0; n < len; ++n) | ||
100 | out[n] = in[n] ^ iv[n]; | ||
101 | for(n=len; n < CAMELLIA_BLOCK_SIZE; ++n) | ||
102 | out[n] = iv[n]; | ||
103 | if (camellia_endian.little) | ||
104 | SWAP4WORD((u32 *)out); | ||
105 | key->enc(key->rd_key, (u32 *)out); | ||
106 | if (camellia_endian.little) | ||
107 | SWAP4WORD((u32 *)out); | ||
108 | iv = out; | ||
109 | } | ||
110 | memcpy(ivec,iv,CAMELLIA_BLOCK_SIZE); | ||
111 | } | ||
112 | else if (in != out) | ||
113 | { | ||
114 | while (len >= CAMELLIA_BLOCK_SIZE) | ||
115 | { | ||
116 | memcpy(out,in,CAMELLIA_BLOCK_SIZE); | ||
117 | if (camellia_endian.little) | ||
118 | SWAP4WORD((u32 *)out); | ||
119 | key->dec(key->rd_key,(u32 *)out); | ||
120 | if (camellia_endian.little) | ||
121 | SWAP4WORD((u32 *)out); | ||
122 | XOR4WORD((u32 *)out, (u32 *)iv); | ||
123 | iv = in; | ||
124 | len -= CAMELLIA_BLOCK_SIZE; | ||
125 | in += CAMELLIA_BLOCK_SIZE; | ||
126 | out += CAMELLIA_BLOCK_SIZE; | ||
127 | } | ||
128 | if (len) | ||
129 | { | ||
130 | memcpy(tmp.t8, in, CAMELLIA_BLOCK_SIZE); | ||
131 | if (camellia_endian.little) | ||
132 | SWAP4WORD(tmp.t32); | ||
133 | key->dec(key->rd_key, tmp.t32); | ||
134 | if (camellia_endian.little) | ||
135 | SWAP4WORD(tmp.t32); | ||
136 | for(n=0; n < len; ++n) | ||
137 | out[n] = tmp.t8[n] ^ iv[n]; | ||
138 | iv = in; | ||
139 | } | ||
140 | memcpy(ivec,iv,CAMELLIA_BLOCK_SIZE); | ||
141 | } | ||
142 | else /* in == out */ | ||
143 | { | ||
144 | while (len >= CAMELLIA_BLOCK_SIZE) | ||
145 | { | ||
146 | memcpy(tmp.t8, in, CAMELLIA_BLOCK_SIZE); | ||
147 | if (camellia_endian.little) | ||
148 | SWAP4WORD((u32 *)out); | ||
149 | key->dec(key->rd_key, (u32 *)out); | ||
150 | if (camellia_endian.little) | ||
151 | SWAP4WORD((u32 *)out); | ||
152 | XOR4WORD((u32 *)out, (u32 *)ivec); | ||
153 | memcpy(ivec, tmp.t8, CAMELLIA_BLOCK_SIZE); | ||
154 | len -= CAMELLIA_BLOCK_SIZE; | ||
155 | in += CAMELLIA_BLOCK_SIZE; | ||
156 | out += CAMELLIA_BLOCK_SIZE; | ||
157 | } | ||
158 | if (len) | ||
159 | { | ||
160 | memcpy(tmp.t8, in, CAMELLIA_BLOCK_SIZE); | ||
161 | if (camellia_endian.little) | ||
162 | SWAP4WORD((u32 *)out); | ||
163 | key->dec(key->rd_key,(u32 *)out); | ||
164 | if (camellia_endian.little) | ||
165 | SWAP4WORD((u32 *)out); | ||
166 | for(n=0; n < len; ++n) | ||
167 | out[n] ^= ivec[n]; | ||
168 | for(n=len; n < CAMELLIA_BLOCK_SIZE; ++n) | ||
169 | out[n] = tmp.t8[n]; | ||
170 | memcpy(ivec, tmp.t8, CAMELLIA_BLOCK_SIZE); | ||
171 | } | ||
172 | } | ||
173 | } | ||
174 | else /* no aligned */ | ||
175 | { | ||
176 | if (CAMELLIA_ENCRYPT == enc) | ||
177 | { | ||
178 | while (len >= CAMELLIA_BLOCK_SIZE) | ||
179 | { | ||
180 | for(n=0; n < CAMELLIA_BLOCK_SIZE; ++n) | ||
181 | tmp.t8[n] = in[n] ^ iv[n]; | ||
182 | if (camellia_endian.little) | ||
183 | SWAP4WORD(tmp.t32); | ||
184 | key->enc(key->rd_key, tmp.t32); | ||
185 | if (camellia_endian.little) | ||
186 | SWAP4WORD(tmp.t32); | ||
187 | memcpy(out, tmp.t8, CAMELLIA_BLOCK_SIZE); | ||
188 | iv = out; | ||
189 | len -= CAMELLIA_BLOCK_SIZE; | ||
190 | in += CAMELLIA_BLOCK_SIZE; | ||
191 | out += CAMELLIA_BLOCK_SIZE; | ||
192 | } | ||
193 | if (len) | ||
194 | { | ||
195 | for(n=0; n < len; ++n) | ||
196 | tmp.t8[n] = in[n] ^ iv[n]; | ||
197 | for(n=len; n < CAMELLIA_BLOCK_SIZE; ++n) | ||
198 | tmp.t8[n] = iv[n]; | ||
199 | if (camellia_endian.little) | ||
200 | SWAP4WORD(tmp.t32); | ||
201 | key->enc(key->rd_key, tmp.t32); | ||
202 | if (camellia_endian.little) | ||
203 | SWAP4WORD(tmp.t32); | ||
204 | memcpy(out, tmp.t8, CAMELLIA_BLOCK_SIZE); | ||
205 | iv = out; | ||
206 | } | ||
207 | memcpy(ivec,iv,CAMELLIA_BLOCK_SIZE); | ||
208 | } | ||
209 | else if (in != out) | ||
210 | { | ||
211 | while (len >= CAMELLIA_BLOCK_SIZE) | ||
212 | { | ||
213 | memcpy(tmp.t8,in,CAMELLIA_BLOCK_SIZE); | ||
214 | if (camellia_endian.little) | ||
215 | SWAP4WORD(tmp.t32); | ||
216 | key->dec(key->rd_key,tmp.t32); | ||
217 | if (camellia_endian.little) | ||
218 | SWAP4WORD(tmp.t32); | ||
219 | for(n=0; n < CAMELLIA_BLOCK_SIZE; ++n) | ||
220 | out[n] = tmp.t8[n] ^ iv[n]; | ||
221 | iv = in; | ||
222 | len -= CAMELLIA_BLOCK_SIZE; | ||
223 | in += CAMELLIA_BLOCK_SIZE; | ||
224 | out += CAMELLIA_BLOCK_SIZE; | ||
225 | } | ||
226 | if (len) | ||
227 | { | ||
228 | memcpy(tmp.t8, in, CAMELLIA_BLOCK_SIZE); | ||
229 | if (camellia_endian.little) | ||
230 | SWAP4WORD(tmp.t32); | ||
231 | key->dec(key->rd_key, tmp.t32); | ||
232 | if (camellia_endian.little) | ||
233 | SWAP4WORD(tmp.t32); | ||
234 | for(n=0; n < len; ++n) | ||
235 | out[n] = tmp.t8[n] ^ iv[n]; | ||
236 | iv = in; | ||
237 | } | ||
238 | memcpy(ivec,iv,CAMELLIA_BLOCK_SIZE); | ||
239 | } | ||
240 | else | ||
241 | { | ||
242 | while (len >= CAMELLIA_BLOCK_SIZE) | ||
243 | { | ||
244 | memcpy(tmp.t8, in, CAMELLIA_BLOCK_SIZE); | ||
245 | if (camellia_endian.little) | ||
246 | SWAP4WORD(tmp.t32); | ||
247 | key->dec(key->rd_key, tmp.t32); | ||
248 | if (camellia_endian.little) | ||
249 | SWAP4WORD(tmp.t32); | ||
250 | for(n=0; n < CAMELLIA_BLOCK_SIZE; ++n) | ||
251 | tmp.t8[n] ^= ivec[n]; | ||
252 | memcpy(ivec, in, CAMELLIA_BLOCK_SIZE); | ||
253 | memcpy(out, tmp.t8, CAMELLIA_BLOCK_SIZE); | ||
254 | len -= CAMELLIA_BLOCK_SIZE; | ||
255 | in += CAMELLIA_BLOCK_SIZE; | ||
256 | out += CAMELLIA_BLOCK_SIZE; | ||
257 | } | ||
258 | if (len) | ||
259 | { | ||
260 | memcpy(tmp.t8, in, CAMELLIA_BLOCK_SIZE); | ||
261 | if (camellia_endian.little) | ||
262 | SWAP4WORD(tmp.t32); | ||
263 | key->dec(key->rd_key,tmp.t32); | ||
264 | if (camellia_endian.little) | ||
265 | SWAP4WORD(tmp.t32); | ||
266 | for(n=0; n < len; ++n) | ||
267 | tmp.t8[n] ^= ivec[n]; | ||
268 | memcpy(ivec, in, CAMELLIA_BLOCK_SIZE); | ||
269 | memcpy(out,tmp.t8,len); | ||
270 | } | ||
271 | } | ||
272 | } | ||
273 | } | ||
diff --git a/src/lib/libcrypto/camellia/cmll_cfb.c b/src/lib/libcrypto/camellia/cmll_cfb.c new file mode 100644 index 0000000000..af0f9f49ad --- /dev/null +++ b/src/lib/libcrypto/camellia/cmll_cfb.c | |||
@@ -0,0 +1,235 @@ | |||
1 | /* crypto/camellia/camellia_cfb.c -*- mode:C; c-file-style: "eay" -*- */ | ||
2 | /* ==================================================================== | ||
3 | * Copyright (c) 2006 The OpenSSL Project. All rights reserved. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions | ||
7 | * are met: | ||
8 | * | ||
9 | * 1. Redistributions of source code must retain the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer. | ||
11 | * | ||
12 | * 2. Redistributions in binary form must reproduce the above copyright | ||
13 | * notice, this list of conditions and the following disclaimer in | ||
14 | * the documentation and/or other materials provided with the | ||
15 | * distribution. | ||
16 | * | ||
17 | * 3. All advertising materials mentioning features or use of this | ||
18 | * software must display the following acknowledgment: | ||
19 | * "This product includes software developed by the OpenSSL Project | ||
20 | * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" | ||
21 | * | ||
22 | * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to | ||
23 | * endorse or promote products derived from this software without | ||
24 | * prior written permission. For written permission, please contact | ||
25 | * openssl-core@openssl.org. | ||
26 | * | ||
27 | * 5. Products derived from this software may not be called "OpenSSL" | ||
28 | * nor may "OpenSSL" appear in their names without prior written | ||
29 | * permission of the OpenSSL Project. | ||
30 | * | ||
31 | * 6. Redistributions of any form whatsoever must retain the following | ||
32 | * acknowledgment: | ||
33 | * "This product includes software developed by the OpenSSL Project | ||
34 | * for use in the OpenSSL Toolkit (http://www.openssl.org/)" | ||
35 | * | ||
36 | * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY | ||
37 | * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
38 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | ||
39 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR | ||
40 | * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
41 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
42 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
43 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
44 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
45 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
46 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED | ||
47 | * OF THE POSSIBILITY OF SUCH DAMAGE. | ||
48 | * ==================================================================== | ||
49 | * | ||
50 | */ | ||
51 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) | ||
52 | * All rights reserved. | ||
53 | * | ||
54 | * This package is an SSL implementation written | ||
55 | * by Eric Young (eay@cryptsoft.com). | ||
56 | * The implementation was written so as to conform with Netscapes SSL. | ||
57 | * | ||
58 | * This library is free for commercial and non-commercial use as long as | ||
59 | * the following conditions are aheared to. The following conditions | ||
60 | * apply to all code found in this distribution, be it the RC4, RSA, | ||
61 | * lhash, DES, etc., code; not just the SSL code. The SSL documentation | ||
62 | * included with this distribution is covered by the same copyright terms | ||
63 | * except that the holder is Tim Hudson (tjh@cryptsoft.com). | ||
64 | * | ||
65 | * Copyright remains Eric Young's, and as such any Copyright notices in | ||
66 | * the code are not to be removed. | ||
67 | * If this package is used in a product, Eric Young should be given attribution | ||
68 | * as the author of the parts of the library used. | ||
69 | * This can be in the form of a textual message at program startup or | ||
70 | * in documentation (online or textual) provided with the package. | ||
71 | * | ||
72 | * Redistribution and use in source and binary forms, with or without | ||
73 | * modification, are permitted provided that the following conditions | ||
74 | * are met: | ||
75 | * 1. Redistributions of source code must retain the copyright | ||
76 | * notice, this list of conditions and the following disclaimer. | ||
77 | * 2. Redistributions in binary form must reproduce the above copyright | ||
78 | * notice, this list of conditions and the following disclaimer in the | ||
79 | * documentation and/or other materials provided with the distribution. | ||
80 | * 3. All advertising materials mentioning features or use of this software | ||
81 | * must display the following acknowledgement: | ||
82 | * "This product includes cryptographic software written by | ||
83 | * Eric Young (eay@cryptsoft.com)" | ||
84 | * The word 'cryptographic' can be left out if the rouines from the library | ||
85 | * being used are not cryptographic related :-). | ||
86 | * 4. If you include any Windows specific code (or a derivative thereof) from | ||
87 | * the apps directory (application code) you must include an acknowledgement: | ||
88 | * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" | ||
89 | * | ||
90 | * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND | ||
91 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
92 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
93 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | ||
94 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
95 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
96 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
97 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
98 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
99 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
100 | * SUCH DAMAGE. | ||
101 | * | ||
102 | * The licence and distribution terms for any publically available version or | ||
103 | * derivative of this code cannot be changed. i.e. this code cannot simply be | ||
104 | * copied and put under another distribution licence | ||
105 | * [including the GNU Public Licence.] | ||
106 | */ | ||
107 | |||
108 | #ifndef CAMELLIA_DEBUG | ||
109 | # ifndef NDEBUG | ||
110 | # define NDEBUG | ||
111 | # endif | ||
112 | #endif | ||
113 | #include <assert.h> | ||
114 | #include <string.h> | ||
115 | |||
116 | #include <openssl/camellia.h> | ||
117 | #include "cmll_locl.h" | ||
118 | #include "e_os.h" | ||
119 | |||
120 | |||
121 | /* The input and output encrypted as though 128bit cfb mode is being | ||
122 | * used. The extra state information to record how much of the | ||
123 | * 128bit block we have used is contained in *num; | ||
124 | */ | ||
125 | |||
126 | void Camellia_cfb128_encrypt(const unsigned char *in, unsigned char *out, | ||
127 | const unsigned long length, const CAMELLIA_KEY *key, | ||
128 | unsigned char *ivec, int *num, const int enc) | ||
129 | { | ||
130 | |||
131 | unsigned int n; | ||
132 | unsigned long l = length; | ||
133 | unsigned char c; | ||
134 | |||
135 | assert(in && out && key && ivec && num); | ||
136 | |||
137 | n = *num; | ||
138 | |||
139 | if (enc) | ||
140 | { | ||
141 | while (l--) | ||
142 | { | ||
143 | if (n == 0) | ||
144 | { | ||
145 | Camellia_encrypt(ivec, ivec, key); | ||
146 | } | ||
147 | ivec[n] = *(out++) = *(in++) ^ ivec[n]; | ||
148 | n = (n+1) % CAMELLIA_BLOCK_SIZE; | ||
149 | } | ||
150 | } | ||
151 | else | ||
152 | { | ||
153 | while (l--) | ||
154 | { | ||
155 | if (n == 0) | ||
156 | { | ||
157 | Camellia_encrypt(ivec, ivec, key); | ||
158 | } | ||
159 | c = *(in); | ||
160 | *(out++) = *(in++) ^ ivec[n]; | ||
161 | ivec[n] = c; | ||
162 | n = (n+1) % CAMELLIA_BLOCK_SIZE; | ||
163 | } | ||
164 | } | ||
165 | |||
166 | *num=n; | ||
167 | } | ||
168 | |||
169 | /* This expects a single block of size nbits for both in and out. Note that | ||
170 | it corrupts any extra bits in the last byte of out */ | ||
171 | void Camellia_cfbr_encrypt_block(const unsigned char *in,unsigned char *out, | ||
172 | const int nbits,const CAMELLIA_KEY *key, | ||
173 | unsigned char *ivec,const int enc) | ||
174 | { | ||
175 | int n,rem,num; | ||
176 | unsigned char ovec[CAMELLIA_BLOCK_SIZE*2]; | ||
177 | |||
178 | if (nbits<=0 || nbits>128) return; | ||
179 | |||
180 | /* fill in the first half of the new IV with the current IV */ | ||
181 | memcpy(ovec,ivec,CAMELLIA_BLOCK_SIZE); | ||
182 | /* construct the new IV */ | ||
183 | Camellia_encrypt(ivec,ivec,key); | ||
184 | num = (nbits+7)/8; | ||
185 | if (enc) /* encrypt the input */ | ||
186 | for(n=0 ; n < num ; ++n) | ||
187 | out[n] = (ovec[CAMELLIA_BLOCK_SIZE+n] = in[n] ^ ivec[n]); | ||
188 | else /* decrypt the input */ | ||
189 | for(n=0 ; n < num ; ++n) | ||
190 | out[n] = (ovec[CAMELLIA_BLOCK_SIZE+n] = in[n]) ^ ivec[n]; | ||
191 | /* shift ovec left... */ | ||
192 | rem = nbits%8; | ||
193 | num = nbits/8; | ||
194 | if(rem==0) | ||
195 | memcpy(ivec,ovec+num,CAMELLIA_BLOCK_SIZE); | ||
196 | else | ||
197 | for(n=0 ; n < CAMELLIA_BLOCK_SIZE ; ++n) | ||
198 | ivec[n] = ovec[n+num]<<rem | ovec[n+num+1]>>(8-rem); | ||
199 | |||
200 | /* it is not necessary to cleanse ovec, since the IV is not secret */ | ||
201 | } | ||
202 | |||
203 | /* N.B. This expects the input to be packed, MS bit first */ | ||
204 | void Camellia_cfb1_encrypt(const unsigned char *in, unsigned char *out, | ||
205 | const unsigned long length, const CAMELLIA_KEY *key, | ||
206 | unsigned char *ivec, int *num, const int enc) | ||
207 | { | ||
208 | unsigned int n; | ||
209 | unsigned char c[1],d[1]; | ||
210 | |||
211 | assert(in && out && key && ivec && num); | ||
212 | assert(*num == 0); | ||
213 | |||
214 | memset(out,0,(length+7)/8); | ||
215 | for(n=0 ; n < length ; ++n) | ||
216 | { | ||
217 | c[0]=(in[n/8]&(1 << (7-n%8))) ? 0x80 : 0; | ||
218 | Camellia_cfbr_encrypt_block(c,d,1,key,ivec,enc); | ||
219 | out[n/8]=(out[n/8]&~(1 << (7-n%8)))|((d[0]&0x80) >> (n%8)); | ||
220 | } | ||
221 | } | ||
222 | |||
223 | void Camellia_cfb8_encrypt(const unsigned char *in, unsigned char *out, | ||
224 | const unsigned long length, const CAMELLIA_KEY *key, | ||
225 | unsigned char *ivec, int *num, const int enc) | ||
226 | { | ||
227 | unsigned int n; | ||
228 | |||
229 | assert(in && out && key && ivec && num); | ||
230 | assert(*num == 0); | ||
231 | |||
232 | for(n=0 ; n < length ; ++n) | ||
233 | Camellia_cfbr_encrypt_block(&in[n],&out[n],8,key,ivec,enc); | ||
234 | } | ||
235 | |||
diff --git a/src/lib/libcrypto/camellia/cmll_ctr.c b/src/lib/libcrypto/camellia/cmll_ctr.c new file mode 100644 index 0000000000..cc21b70890 --- /dev/null +++ b/src/lib/libcrypto/camellia/cmll_ctr.c | |||
@@ -0,0 +1,143 @@ | |||
1 | /* crypto/camellia/camellia_ctr.c -*- mode:C; c-file-style: "eay" -*- */ | ||
2 | /* ==================================================================== | ||
3 | * Copyright (c) 2006 The OpenSSL Project. All rights reserved. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions | ||
7 | * are met: | ||
8 | * | ||
9 | * 1. Redistributions of source code must retain the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer. | ||
11 | * | ||
12 | * 2. Redistributions in binary form must reproduce the above copyright | ||
13 | * notice, this list of conditions and the following disclaimer in | ||
14 | * the documentation and/or other materials provided with the | ||
15 | * distribution. | ||
16 | * | ||
17 | * 3. All advertising materials mentioning features or use of this | ||
18 | * software must display the following acknowledgment: | ||
19 | * "This product includes software developed by the OpenSSL Project | ||
20 | * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" | ||
21 | * | ||
22 | * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to | ||
23 | * endorse or promote products derived from this software without | ||
24 | * prior written permission. For written permission, please contact | ||
25 | * openssl-core@openssl.org. | ||
26 | * | ||
27 | * 5. Products derived from this software may not be called "OpenSSL" | ||
28 | * nor may "OpenSSL" appear in their names without prior written | ||
29 | * permission of the OpenSSL Project. | ||
30 | * | ||
31 | * 6. Redistributions of any form whatsoever must retain the following | ||
32 | * acknowledgment: | ||
33 | * "This product includes software developed by the OpenSSL Project | ||
34 | * for use in the OpenSSL Toolkit (http://www.openssl.org/)" | ||
35 | * | ||
36 | * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY | ||
37 | * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
38 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | ||
39 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR | ||
40 | * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
41 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
42 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
43 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
44 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
45 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
46 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED | ||
47 | * OF THE POSSIBILITY OF SUCH DAMAGE. | ||
48 | * ==================================================================== | ||
49 | * | ||
50 | */ | ||
51 | |||
52 | #ifndef CAMELLIA_DEBUG | ||
53 | # ifndef NDEBUG | ||
54 | # define NDEBUG | ||
55 | # endif | ||
56 | #endif | ||
57 | #include <assert.h> | ||
58 | |||
59 | #include <openssl/camellia.h> | ||
60 | #include "cmll_locl.h" | ||
61 | |||
62 | /* NOTE: the IV/counter CTR mode is big-endian. The rest of the Camellia code | ||
63 | * is endian-neutral. */ | ||
64 | /* increment counter (128-bit int) by 1 */ | ||
65 | static void Camellia_ctr128_inc(unsigned char *counter) | ||
66 | { | ||
67 | unsigned long c; | ||
68 | |||
69 | /* Grab bottom dword of counter and increment */ | ||
70 | c = GETU32(counter + 12); | ||
71 | c++; c &= 0xFFFFFFFF; | ||
72 | PUTU32(counter + 12, c); | ||
73 | |||
74 | /* if no overflow, we're done */ | ||
75 | if (c) | ||
76 | return; | ||
77 | |||
78 | /* Grab 1st dword of counter and increment */ | ||
79 | c = GETU32(counter + 8); | ||
80 | c++; c &= 0xFFFFFFFF; | ||
81 | PUTU32(counter + 8, c); | ||
82 | |||
83 | /* if no overflow, we're done */ | ||
84 | if (c) | ||
85 | return; | ||
86 | |||
87 | /* Grab 2nd dword of counter and increment */ | ||
88 | c = GETU32(counter + 4); | ||
89 | c++; c &= 0xFFFFFFFF; | ||
90 | PUTU32(counter + 4, c); | ||
91 | |||
92 | /* if no overflow, we're done */ | ||
93 | if (c) | ||
94 | return; | ||
95 | |||
96 | /* Grab top dword of counter and increment */ | ||
97 | c = GETU32(counter + 0); | ||
98 | c++; c &= 0xFFFFFFFF; | ||
99 | PUTU32(counter + 0, c); | ||
100 | } | ||
101 | |||
102 | /* The input encrypted as though 128bit counter mode is being | ||
103 | * used. The extra state information to record how much of the | ||
104 | * 128bit block we have used is contained in *num, and the | ||
105 | * encrypted counter is kept in ecount_buf. Both *num and | ||
106 | * ecount_buf must be initialised with zeros before the first | ||
107 | * call to Camellia_ctr128_encrypt(). | ||
108 | * | ||
109 | * This algorithm assumes that the counter is in the x lower bits | ||
110 | * of the IV (ivec), and that the application has full control over | ||
111 | * overflow and the rest of the IV. This implementation takes NO | ||
112 | * responsability for checking that the counter doesn't overflow | ||
113 | * into the rest of the IV when incremented. | ||
114 | */ | ||
115 | void Camellia_ctr128_encrypt(const unsigned char *in, unsigned char *out, | ||
116 | const unsigned long length, const CAMELLIA_KEY *key, | ||
117 | unsigned char ivec[CAMELLIA_BLOCK_SIZE], | ||
118 | unsigned char ecount_buf[CAMELLIA_BLOCK_SIZE], | ||
119 | unsigned int *num) | ||
120 | { | ||
121 | |||
122 | unsigned int n; | ||
123 | unsigned long l=length; | ||
124 | |||
125 | assert(in && out && key && counter && num); | ||
126 | assert(*num < CAMELLIA_BLOCK_SIZE); | ||
127 | |||
128 | n = *num; | ||
129 | |||
130 | while (l--) | ||
131 | { | ||
132 | if (n == 0) | ||
133 | { | ||
134 | Camellia_encrypt(ivec, ecount_buf, key); | ||
135 | Camellia_ctr128_inc(ivec); | ||
136 | } | ||
137 | *(out++) = *(in++) ^ ecount_buf[n]; | ||
138 | n = (n+1) % CAMELLIA_BLOCK_SIZE; | ||
139 | } | ||
140 | |||
141 | *num=n; | ||
142 | } | ||
143 | |||
diff --git a/src/lib/libcrypto/camellia/cmll_ecb.c b/src/lib/libcrypto/camellia/cmll_ecb.c new file mode 100644 index 0000000000..70dc0e5632 --- /dev/null +++ b/src/lib/libcrypto/camellia/cmll_ecb.c | |||
@@ -0,0 +1,74 @@ | |||
1 | /* crypto/camellia/camellia_ecb.c -*- mode:C; c-file-style: "eay" -*- */ | ||
2 | /* ==================================================================== | ||
3 | * Copyright (c) 2006 The OpenSSL Project. All rights reserved. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions | ||
7 | * are met: | ||
8 | * | ||
9 | * 1. Redistributions of source code must retain the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer. | ||
11 | * | ||
12 | * 2. Redistributions in binary form must reproduce the above copyright | ||
13 | * notice, this list of conditions and the following disclaimer in | ||
14 | * the documentation and/or other materials provided with the | ||
15 | * distribution. | ||
16 | * | ||
17 | * 3. All advertising materials mentioning features or use of this | ||
18 | * software must display the following acknowledgment: | ||
19 | * "This product includes software developed by the OpenSSL Project | ||
20 | * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" | ||
21 | * | ||
22 | * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to | ||
23 | * endorse or promote products derived from this software without | ||
24 | * prior written permission. For written permission, please contact | ||
25 | * openssl-core@openssl.org. | ||
26 | * | ||
27 | * 5. Products derived from this software may not be called "OpenSSL" | ||
28 | * nor may "OpenSSL" appear in their names without prior written | ||
29 | * permission of the OpenSSL Project. | ||
30 | * | ||
31 | * 6. Redistributions of any form whatsoever must retain the following | ||
32 | * acknowledgment: | ||
33 | * "This product includes software developed by the OpenSSL Project | ||
34 | * for use in the OpenSSL Toolkit (http://www.openssl.org/)" | ||
35 | * | ||
36 | * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY | ||
37 | * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
38 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | ||
39 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR | ||
40 | * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
41 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
42 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
43 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
44 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
45 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
46 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED | ||
47 | * OF THE POSSIBILITY OF SUCH DAMAGE. | ||
48 | * ==================================================================== | ||
49 | * | ||
50 | */ | ||
51 | |||
52 | #ifndef CAMELLIA_DEBUG | ||
53 | # ifndef NDEBUG | ||
54 | # define NDEBUG | ||
55 | # endif | ||
56 | #endif | ||
57 | #include <assert.h> | ||
58 | |||
59 | #include <openssl/camellia.h> | ||
60 | #include "cmll_locl.h" | ||
61 | |||
62 | void Camellia_ecb_encrypt(const unsigned char *in, unsigned char *out, | ||
63 | const CAMELLIA_KEY *key, const int enc) | ||
64 | { | ||
65 | |||
66 | assert(in && out && key); | ||
67 | assert((CAMELLIA_ENCRYPT == enc)||(CAMELLIA_DECRYPT == enc)); | ||
68 | |||
69 | if (CAMELLIA_ENCRYPT == enc) | ||
70 | Camellia_encrypt(in, out, key); | ||
71 | else | ||
72 | Camellia_decrypt(in, out, key); | ||
73 | } | ||
74 | |||
diff --git a/src/lib/libcrypto/camellia/cmll_locl.h b/src/lib/libcrypto/camellia/cmll_locl.h new file mode 100644 index 0000000000..2ac2e95435 --- /dev/null +++ b/src/lib/libcrypto/camellia/cmll_locl.h | |||
@@ -0,0 +1,165 @@ | |||
1 | /* crypto/camellia/camellia_locl.h -*- mode:C; c-file-style: "eay" -*- */ | ||
2 | /* ==================================================================== | ||
3 | * Copyright 2006 NTT (Nippon Telegraph and Telephone Corporation) . | ||
4 | * ALL RIGHTS RESERVED. | ||
5 | * | ||
6 | * Intellectual Property information for Camellia: | ||
7 | * http://info.isl.ntt.co.jp/crypt/eng/info/chiteki.html | ||
8 | * | ||
9 | * News Release for Announcement of Camellia open source: | ||
10 | * http://www.ntt.co.jp/news/news06e/0604/060413a.html | ||
11 | * | ||
12 | * The Camellia Code included herein is developed by | ||
13 | * NTT (Nippon Telegraph and Telephone Corporation), and is contributed | ||
14 | * to the OpenSSL project. | ||
15 | * | ||
16 | * The Camellia Code is licensed pursuant to the OpenSSL open source | ||
17 | * license provided below. | ||
18 | */ | ||
19 | /* ==================================================================== | ||
20 | * Copyright (c) 2006 The OpenSSL Project. All rights reserved. | ||
21 | * | ||
22 | * Redistribution and use in source and binary forms, with or without | ||
23 | * modification, are permitted provided that the following conditions | ||
24 | * are met: | ||
25 | * | ||
26 | * 1. Redistributions of source code must retain the above copyright | ||
27 | * notice, this list of conditions and the following disclaimer. | ||
28 | * | ||
29 | * 2. Redistributions in binary form must reproduce the above copyright | ||
30 | * notice, this list of conditions and the following disclaimer in | ||
31 | * the documentation and/or other materials provided with the | ||
32 | * distribution. | ||
33 | * | ||
34 | * 3. All advertising materials mentioning features or use of this | ||
35 | * software must display the following acknowledgment: | ||
36 | * "This product includes software developed by the OpenSSL Project | ||
37 | * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" | ||
38 | * | ||
39 | * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to | ||
40 | * endorse or promote products derived from this software without | ||
41 | * prior written permission. For written permission, please contact | ||
42 | * openssl-core@openssl.org. | ||
43 | * | ||
44 | * 5. Products derived from this software may not be called "OpenSSL" | ||
45 | * nor may "OpenSSL" appear in their names without prior written | ||
46 | * permission of the OpenSSL Project. | ||
47 | * | ||
48 | * 6. Redistributions of any form whatsoever must retain the following | ||
49 | * acknowledgment: | ||
50 | * "This product includes software developed by the OpenSSL Project | ||
51 | * for use in the OpenSSL Toolkit (http://www.openssl.org/)" | ||
52 | * | ||
53 | * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY | ||
54 | * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
55 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | ||
56 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR | ||
57 | * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
58 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
59 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
60 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
61 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
62 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
63 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED | ||
64 | * OF THE POSSIBILITY OF SUCH DAMAGE. | ||
65 | * ==================================================================== | ||
66 | */ | ||
67 | |||
68 | #ifndef HEADER_CAMELLIA_LOCL_H | ||
69 | #define HEADER_CAMELLIA_LOCL_H | ||
70 | |||
71 | #include "openssl/e_os2.h" | ||
72 | #include <stdio.h> | ||
73 | #include <stdlib.h> | ||
74 | #include <string.h> | ||
75 | |||
76 | typedef unsigned char u8; | ||
77 | typedef unsigned int u32; | ||
78 | |||
79 | #ifdef __cplusplus | ||
80 | extern "C" { | ||
81 | #endif | ||
82 | |||
83 | #if defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_AMD64) || defined(_M_X64)) | ||
84 | # define SWAP(x) ( _lrotl(x, 8) & 0x00ff00ff | _lrotr(x, 8) & 0xff00ff00 ) | ||
85 | # define GETU32(p) SWAP(*((u32 *)(p))) | ||
86 | # define PUTU32(ct, st) { *((u32 *)(ct)) = SWAP((st)); } | ||
87 | # define CAMELLIA_SWAP4(x) (x = ( _lrotl(x, 8) & 0x00ff00ff | _lrotr(x, 8) & 0xff00ff00) ) | ||
88 | |||
89 | #else /* not windows */ | ||
90 | # define GETU32(pt) (((u32)(pt)[0] << 24) \ | ||
91 | ^ ((u32)(pt)[1] << 16) \ | ||
92 | ^ ((u32)(pt)[2] << 8) \ | ||
93 | ^ ((u32)(pt)[3])) | ||
94 | |||
95 | # define PUTU32(ct, st) { (ct)[0] = (u8)((st) >> 24); \ | ||
96 | (ct)[1] = (u8)((st) >> 16); \ | ||
97 | (ct)[2] = (u8)((st) >> 8); \ | ||
98 | (ct)[3] = (u8)(st); } | ||
99 | |||
100 | #if (defined (__GNUC__) && (defined(__x86_64__) || defined(__x86_64))) | ||
101 | #define CAMELLIA_SWAP4(x) \ | ||
102 | do{\ | ||
103 | asm("bswap %1" : "+r" (x));\ | ||
104 | }while(0) | ||
105 | #else | ||
106 | #define CAMELLIA_SWAP4(x) \ | ||
107 | do{\ | ||
108 | x = ((u32)x << 16) + ((u32)x >> 16);\ | ||
109 | x = (((u32)x & 0xff00ff) << 8) + (((u32)x >> 8) & 0xff00ff);\ | ||
110 | } while(0) | ||
111 | #endif | ||
112 | #endif | ||
113 | |||
114 | #define COPY4WORD(dst, src) \ | ||
115 | do \ | ||
116 | { \ | ||
117 | (dst)[0]=(src)[0]; \ | ||
118 | (dst)[1]=(src)[1]; \ | ||
119 | (dst)[2]=(src)[2]; \ | ||
120 | (dst)[3]=(src)[3]; \ | ||
121 | }while(0) | ||
122 | |||
123 | #define SWAP4WORD(word) \ | ||
124 | do \ | ||
125 | { \ | ||
126 | CAMELLIA_SWAP4((word)[0]); \ | ||
127 | CAMELLIA_SWAP4((word)[1]); \ | ||
128 | CAMELLIA_SWAP4((word)[2]); \ | ||
129 | CAMELLIA_SWAP4((word)[3]); \ | ||
130 | }while(0) | ||
131 | |||
132 | #define XOR4WORD(a, b)/* a = a ^ b */ \ | ||
133 | do \ | ||
134 | { \ | ||
135 | (a)[0]^=(b)[0]; \ | ||
136 | (a)[1]^=(b)[1]; \ | ||
137 | (a)[2]^=(b)[2]; \ | ||
138 | (a)[3]^=(b)[3]; \ | ||
139 | }while(0) | ||
140 | |||
141 | #define XOR4WORD2(a, b, c)/* a = b ^ c */ \ | ||
142 | do \ | ||
143 | { \ | ||
144 | (a)[0]=(b)[0]^(c)[0]; \ | ||
145 | (a)[1]=(b)[1]^(c)[1]; \ | ||
146 | (a)[2]=(b)[2]^(c)[2]; \ | ||
147 | (a)[3]=(b)[3]^(c)[3]; \ | ||
148 | }while(0) | ||
149 | |||
150 | |||
151 | void camellia_setup128(const u8 *key, u32 *subkey); | ||
152 | void camellia_setup192(const u8 *key, u32 *subkey); | ||
153 | void camellia_setup256(const u8 *key, u32 *subkey); | ||
154 | |||
155 | void camellia_encrypt128(const u32 *subkey, u32 *io); | ||
156 | void camellia_decrypt128(const u32 *subkey, u32 *io); | ||
157 | void camellia_encrypt256(const u32 *subkey, u32 *io); | ||
158 | void camellia_decrypt256(const u32 *subkey, u32 *io); | ||
159 | |||
160 | #ifdef __cplusplus | ||
161 | } | ||
162 | #endif | ||
163 | |||
164 | #endif /* #ifndef HEADER_CAMELLIA_LOCL_H */ | ||
165 | |||
diff --git a/src/lib/libcrypto/camellia/cmll_misc.c b/src/lib/libcrypto/camellia/cmll_misc.c new file mode 100644 index 0000000000..f1047b54e0 --- /dev/null +++ b/src/lib/libcrypto/camellia/cmll_misc.c | |||
@@ -0,0 +1,116 @@ | |||
1 | /* crypto/camellia/camellia_misc.c -*- mode:C; c-file-style: "eay" -*- */ | ||
2 | /* ==================================================================== | ||
3 | * Copyright (c) 2006 The OpenSSL Project. All rights reserved. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions | ||
7 | * are met: | ||
8 | * | ||
9 | * 1. Redistributions of source code must retain the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer. | ||
11 | * | ||
12 | * 2. Redistributions in binary form must reproduce the above copyright | ||
13 | * notice, this list of conditions and the following disclaimer in | ||
14 | * the documentation and/or other materials provided with the | ||
15 | * distribution. | ||
16 | * | ||
17 | * 3. All advertising materials mentioning features or use of this | ||
18 | * software must display the following acknowledgment: | ||
19 | * "This product includes software developed by the OpenSSL Project | ||
20 | * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" | ||
21 | * | ||
22 | * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to | ||
23 | * endorse or promote products derived from this software without | ||
24 | * prior written permission. For written permission, please contact | ||
25 | * openssl-core@openssl.org. | ||
26 | * | ||
27 | * 5. Products derived from this software may not be called "OpenSSL" | ||
28 | * nor may "OpenSSL" appear in their names without prior written | ||
29 | * permission of the OpenSSL Project. | ||
30 | * | ||
31 | * 6. Redistributions of any form whatsoever must retain the following | ||
32 | * acknowledgment: | ||
33 | * "This product includes software developed by the OpenSSL Project | ||
34 | * for use in the OpenSSL Toolkit (http://www.openssl.org/)" | ||
35 | * | ||
36 | * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY | ||
37 | * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
38 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | ||
39 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR | ||
40 | * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
41 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
42 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
43 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
44 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
45 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
46 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED | ||
47 | * OF THE POSSIBILITY OF SUCH DAMAGE. | ||
48 | * ==================================================================== | ||
49 | * | ||
50 | */ | ||
51 | |||
52 | #include <openssl/opensslv.h> | ||
53 | #include <openssl/camellia.h> | ||
54 | #include "cmll_locl.h" | ||
55 | |||
56 | const char CAMELLIA_version[]="CAMELLIA" OPENSSL_VERSION_PTEXT; | ||
57 | |||
58 | int Camellia_set_key(const unsigned char *userKey, const int bits, | ||
59 | CAMELLIA_KEY *key) | ||
60 | { | ||
61 | if (!userKey || !key) | ||
62 | { | ||
63 | return -1; | ||
64 | } | ||
65 | |||
66 | switch(bits) | ||
67 | { | ||
68 | case 128: | ||
69 | camellia_setup128(userKey, (unsigned int *)key->rd_key); | ||
70 | key->enc = camellia_encrypt128; | ||
71 | key->dec = camellia_decrypt128; | ||
72 | break; | ||
73 | case 192: | ||
74 | camellia_setup192(userKey, (unsigned int *)key->rd_key); | ||
75 | key->enc = camellia_encrypt256; | ||
76 | key->dec = camellia_decrypt256; | ||
77 | break; | ||
78 | case 256: | ||
79 | camellia_setup256(userKey, (unsigned int *)key->rd_key); | ||
80 | key->enc = camellia_encrypt256; | ||
81 | key->dec = camellia_decrypt256; | ||
82 | break; | ||
83 | default: | ||
84 | return -2; | ||
85 | } | ||
86 | |||
87 | key->bitLength = bits; | ||
88 | return 0; | ||
89 | } | ||
90 | |||
91 | void Camellia_encrypt(const unsigned char *in, unsigned char *out, | ||
92 | const CAMELLIA_KEY *key) | ||
93 | { | ||
94 | u32 tmp[CAMELLIA_BLOCK_SIZE/sizeof(u32)]; | ||
95 | const union { long one; char little; } camellia_endian = {1}; | ||
96 | |||
97 | memcpy(tmp, in, CAMELLIA_BLOCK_SIZE); | ||
98 | if (camellia_endian.little) SWAP4WORD(tmp); | ||
99 | key->enc(key->rd_key, tmp); | ||
100 | if (camellia_endian.little) SWAP4WORD(tmp); | ||
101 | memcpy(out, tmp, CAMELLIA_BLOCK_SIZE); | ||
102 | } | ||
103 | |||
104 | void Camellia_decrypt(const unsigned char *in, unsigned char *out, | ||
105 | const CAMELLIA_KEY *key) | ||
106 | { | ||
107 | u32 tmp[CAMELLIA_BLOCK_SIZE/sizeof(u32)]; | ||
108 | const union { long one; char little; } camellia_endian = {1}; | ||
109 | |||
110 | memcpy(tmp, in, CAMELLIA_BLOCK_SIZE); | ||
111 | if (camellia_endian.little) SWAP4WORD(tmp); | ||
112 | key->dec(key->rd_key, tmp); | ||
113 | if (camellia_endian.little) SWAP4WORD(tmp); | ||
114 | memcpy(out, tmp, CAMELLIA_BLOCK_SIZE); | ||
115 | } | ||
116 | |||
diff --git a/src/lib/libcrypto/camellia/cmll_ofb.c b/src/lib/libcrypto/camellia/cmll_ofb.c new file mode 100644 index 0000000000..d89cf9f3b3 --- /dev/null +++ b/src/lib/libcrypto/camellia/cmll_ofb.c | |||
@@ -0,0 +1,141 @@ | |||
1 | /* crypto/camellia/camellia_ofb.c -*- mode:C; c-file-style: "eay" -*- */ | ||
2 | /* ==================================================================== | ||
3 | * Copyright (c) 2006 The OpenSSL Project. All rights reserved. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions | ||
7 | * are met: | ||
8 | * | ||
9 | * 1. Redistributions of source code must retain the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer. | ||
11 | * | ||
12 | * 2. Redistributions in binary form must reproduce the above copyright | ||
13 | * notice, this list of conditions and the following disclaimer in | ||
14 | * the documentation and/or other materials provided with the | ||
15 | * distribution. | ||
16 | * | ||
17 | * 3. All advertising materials mentioning features or use of this | ||
18 | * software must display the following acknowledgment: | ||
19 | * "This product includes software developed by the OpenSSL Project | ||
20 | * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" | ||
21 | * | ||
22 | * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to | ||
23 | * endorse or promote products derived from this software without | ||
24 | * prior written permission. For written permission, please contact | ||
25 | * openssl-core@openssl.org. | ||
26 | * | ||
27 | * 5. Products derived from this software may not be called "OpenSSL" | ||
28 | * nor may "OpenSSL" appear in their names without prior written | ||
29 | * permission of the OpenSSL Project. | ||
30 | * | ||
31 | * 6. Redistributions of any form whatsoever must retain the following | ||
32 | * acknowledgment: | ||
33 | * "This product includes software developed by the OpenSSL Project | ||
34 | * for use in the OpenSSL Toolkit (http://www.openssl.org/)" | ||
35 | * | ||
36 | * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY | ||
37 | * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
38 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | ||
39 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR | ||
40 | * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
41 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
42 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
43 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
44 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
45 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
46 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED | ||
47 | * OF THE POSSIBILITY OF SUCH DAMAGE. | ||
48 | * ==================================================================== | ||
49 | * | ||
50 | */ | ||
51 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) | ||
52 | * All rights reserved. | ||
53 | * | ||
54 | * This package is an SSL implementation written | ||
55 | * by Eric Young (eay@cryptsoft.com). | ||
56 | * The implementation was written so as to conform with Netscapes SSL. | ||
57 | * | ||
58 | * This library is free for commercial and non-commercial use as long as | ||
59 | * the following conditions are aheared to. The following conditions | ||
60 | * apply to all code found in this distribution, be it the RC4, RSA, | ||
61 | * lhash, DES, etc., code; not just the SSL code. The SSL documentation | ||
62 | * included with this distribution is covered by the same copyright terms | ||
63 | * except that the holder is Tim Hudson (tjh@cryptsoft.com). | ||
64 | * | ||
65 | * Copyright remains Eric Young's, and as such any Copyright notices in | ||
66 | * the code are not to be removed. | ||
67 | * If this package is used in a product, Eric Young should be given attribution | ||
68 | * as the author of the parts of the library used. | ||
69 | * This can be in the form of a textual message at program startup or | ||
70 | * in documentation (online or textual) provided with the package. | ||
71 | * | ||
72 | * Redistribution and use in source and binary forms, with or without | ||
73 | * modification, are permitted provided that the following conditions | ||
74 | * are met: | ||
75 | * 1. Redistributions of source code must retain the copyright | ||
76 | * notice, this list of conditions and the following disclaimer. | ||
77 | * 2. Redistributions in binary form must reproduce the above copyright | ||
78 | * notice, this list of conditions and the following disclaimer in the | ||
79 | * documentation and/or other materials provided with the distribution. | ||
80 | * 3. All advertising materials mentioning features or use of this software | ||
81 | * must display the following acknowledgement: | ||
82 | * "This product includes cryptographic software written by | ||
83 | * Eric Young (eay@cryptsoft.com)" | ||
84 | * The word 'cryptographic' can be left out if the rouines from the library | ||
85 | * being used are not cryptographic related :-). | ||
86 | * 4. If you include any Windows specific code (or a derivative thereof) from | ||
87 | * the apps directory (application code) you must include an acknowledgement: | ||
88 | * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" | ||
89 | * | ||
90 | * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND | ||
91 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
92 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
93 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | ||
94 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
95 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
96 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
97 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
98 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
99 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
100 | * SUCH DAMAGE. | ||
101 | * | ||
102 | * The licence and distribution terms for any publically available version or | ||
103 | * derivative of this code cannot be changed. i.e. this code cannot simply be | ||
104 | * copied and put under another distribution licence | ||
105 | * [including the GNU Public Licence.] | ||
106 | */ | ||
107 | |||
108 | #ifndef CAMELLIA_DEBUG | ||
109 | # ifndef NDEBUG | ||
110 | # define NDEBUG | ||
111 | # endif | ||
112 | #endif | ||
113 | #include <assert.h> | ||
114 | #include <openssl/camellia.h> | ||
115 | #include "cmll_locl.h" | ||
116 | |||
117 | /* The input and output encrypted as though 128bit ofb mode is being | ||
118 | * used. The extra state information to record how much of the | ||
119 | * 128bit block we have used is contained in *num; | ||
120 | */ | ||
121 | void Camellia_ofb128_encrypt(const unsigned char *in, unsigned char *out, | ||
122 | const unsigned long length, const CAMELLIA_KEY *key, | ||
123 | unsigned char *ivec, int *num) { | ||
124 | |||
125 | unsigned int n; | ||
126 | unsigned long l=length; | ||
127 | |||
128 | assert(in && out && key && ivec && num); | ||
129 | |||
130 | n = *num; | ||
131 | |||
132 | while (l--) { | ||
133 | if (n == 0) { | ||
134 | Camellia_encrypt(ivec, ivec, key); | ||
135 | } | ||
136 | *(out++) = *(in++) ^ ivec[n]; | ||
137 | n = (n+1) % CAMELLIA_BLOCK_SIZE; | ||
138 | } | ||
139 | |||
140 | *num=n; | ||
141 | } | ||
diff --git a/src/lib/libcrypto/cms/cms.h b/src/lib/libcrypto/cms/cms.h new file mode 100644 index 0000000000..25f88745f2 --- /dev/null +++ b/src/lib/libcrypto/cms/cms.h | |||
@@ -0,0 +1,473 @@ | |||
1 | /* crypto/cms/cms.h */ | ||
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 | |||
55 | #ifndef HEADER_CMS_H | ||
56 | #define HEADER_CMS_H | ||
57 | |||
58 | #include <openssl/x509.h> | ||
59 | |||
60 | #ifdef OPENSSL_NO_CMS | ||
61 | #error CMS is disabled. | ||
62 | #endif | ||
63 | |||
64 | #ifdef __cplusplus | ||
65 | extern "C" { | ||
66 | #endif | ||
67 | |||
68 | |||
69 | typedef struct CMS_ContentInfo_st CMS_ContentInfo; | ||
70 | typedef struct CMS_SignerInfo_st CMS_SignerInfo; | ||
71 | typedef struct CMS_CertificateChoices CMS_CertificateChoices; | ||
72 | typedef struct CMS_RevocationInfoChoice_st CMS_RevocationInfoChoice; | ||
73 | typedef struct CMS_RecipientInfo_st CMS_RecipientInfo; | ||
74 | typedef struct CMS_ReceiptRequest_st CMS_ReceiptRequest; | ||
75 | typedef struct CMS_Receipt_st CMS_Receipt; | ||
76 | |||
77 | DECLARE_STACK_OF(CMS_SignerInfo) | ||
78 | DECLARE_STACK_OF(GENERAL_NAMES) | ||
79 | DECLARE_ASN1_FUNCTIONS_const(CMS_ContentInfo) | ||
80 | DECLARE_ASN1_FUNCTIONS_const(CMS_ReceiptRequest) | ||
81 | |||
82 | #define CMS_SIGNERINFO_ISSUER_SERIAL 0 | ||
83 | #define CMS_SIGNERINFO_KEYIDENTIFIER 1 | ||
84 | |||
85 | #define CMS_RECIPINFO_TRANS 0 | ||
86 | #define CMS_RECIPINFO_AGREE 1 | ||
87 | #define CMS_RECIPINFO_KEK 2 | ||
88 | #define CMS_RECIPINFO_PASS 3 | ||
89 | #define CMS_RECIPINFO_OTHER 4 | ||
90 | |||
91 | /* S/MIME related flags */ | ||
92 | |||
93 | #define CMS_TEXT 0x1 | ||
94 | #define CMS_NOCERTS 0x2 | ||
95 | #define CMS_NO_CONTENT_VERIFY 0x4 | ||
96 | #define CMS_NO_ATTR_VERIFY 0x8 | ||
97 | #define CMS_NOSIGS \ | ||
98 | (CMS_NO_CONTENT_VERIFY|CMS_NO_ATTR_VERIFY) | ||
99 | #define CMS_NOINTERN 0x10 | ||
100 | #define CMS_NO_SIGNER_CERT_VERIFY 0x20 | ||
101 | #define CMS_NOVERIFY 0x20 | ||
102 | #define CMS_DETACHED 0x40 | ||
103 | #define CMS_BINARY 0x80 | ||
104 | #define CMS_NOATTR 0x100 | ||
105 | #define CMS_NOSMIMECAP 0x200 | ||
106 | #define CMS_NOOLDMIMETYPE 0x400 | ||
107 | #define CMS_CRLFEOL 0x800 | ||
108 | #define CMS_STREAM 0x1000 | ||
109 | #define CMS_NOCRL 0x2000 | ||
110 | #define CMS_PARTIAL 0x4000 | ||
111 | #define CMS_REUSE_DIGEST 0x8000 | ||
112 | #define CMS_USE_KEYID 0x10000 | ||
113 | |||
114 | const ASN1_OBJECT *CMS_get0_type(CMS_ContentInfo *cms); | ||
115 | |||
116 | BIO *CMS_dataInit(CMS_ContentInfo *cms, BIO *icont); | ||
117 | int CMS_dataFinal(CMS_ContentInfo *cms, BIO *bio); | ||
118 | |||
119 | ASN1_OCTET_STRING **CMS_get0_content(CMS_ContentInfo *cms); | ||
120 | int CMS_is_detached(CMS_ContentInfo *cms); | ||
121 | int CMS_set_detached(CMS_ContentInfo *cms, int detached); | ||
122 | |||
123 | #ifdef HEADER_PEM_H | ||
124 | DECLARE_PEM_rw_const(CMS, CMS_ContentInfo) | ||
125 | #endif | ||
126 | |||
127 | CMS_ContentInfo *d2i_CMS_bio(BIO *bp, CMS_ContentInfo **cms); | ||
128 | int i2d_CMS_bio(BIO *bp, CMS_ContentInfo *cms); | ||
129 | |||
130 | CMS_ContentInfo *SMIME_read_CMS(BIO *bio, BIO **bcont); | ||
131 | int SMIME_write_CMS(BIO *bio, CMS_ContentInfo *cms, BIO *data, int flags); | ||
132 | |||
133 | int CMS_final(CMS_ContentInfo *cms, BIO *data, BIO *dcont, unsigned int flags); | ||
134 | |||
135 | CMS_ContentInfo *CMS_sign(X509 *signcert, EVP_PKEY *pkey, STACK_OF(X509) *certs, | ||
136 | BIO *data, unsigned int flags); | ||
137 | |||
138 | CMS_ContentInfo *CMS_sign_receipt(CMS_SignerInfo *si, | ||
139 | X509 *signcert, EVP_PKEY *pkey, | ||
140 | STACK_OF(X509) *certs, | ||
141 | unsigned int flags); | ||
142 | |||
143 | int CMS_data(CMS_ContentInfo *cms, BIO *out, unsigned int flags); | ||
144 | CMS_ContentInfo *CMS_data_create(BIO *in, unsigned int flags); | ||
145 | |||
146 | int CMS_digest_verify(CMS_ContentInfo *cms, BIO *dcont, BIO *out, | ||
147 | unsigned int flags); | ||
148 | CMS_ContentInfo *CMS_digest_create(BIO *in, const EVP_MD *md, | ||
149 | unsigned int flags); | ||
150 | |||
151 | int CMS_EncryptedData_decrypt(CMS_ContentInfo *cms, | ||
152 | const unsigned char *key, size_t keylen, | ||
153 | BIO *dcont, BIO *out, unsigned int flags); | ||
154 | |||
155 | CMS_ContentInfo *CMS_EncryptedData_encrypt(BIO *in, const EVP_CIPHER *cipher, | ||
156 | const unsigned char *key, size_t keylen, | ||
157 | unsigned int flags); | ||
158 | |||
159 | int CMS_EncryptedData_set1_key(CMS_ContentInfo *cms, const EVP_CIPHER *ciph, | ||
160 | const unsigned char *key, size_t keylen); | ||
161 | |||
162 | int CMS_verify(CMS_ContentInfo *cms, STACK_OF(X509) *certs, | ||
163 | X509_STORE *store, BIO *dcont, BIO *out, unsigned int flags); | ||
164 | |||
165 | int CMS_verify_receipt(CMS_ContentInfo *rcms, CMS_ContentInfo *ocms, | ||
166 | STACK_OF(X509) *certs, | ||
167 | X509_STORE *store, unsigned int flags); | ||
168 | |||
169 | STACK_OF(X509) *CMS_get0_signers(CMS_ContentInfo *cms); | ||
170 | |||
171 | CMS_ContentInfo *CMS_encrypt(STACK_OF(X509) *certs, BIO *in, | ||
172 | const EVP_CIPHER *cipher, unsigned int flags); | ||
173 | |||
174 | int CMS_decrypt(CMS_ContentInfo *cms, EVP_PKEY *pkey, X509 *cert, | ||
175 | BIO *dcont, BIO *out, | ||
176 | unsigned int flags); | ||
177 | |||
178 | int CMS_decrypt_set1_pkey(CMS_ContentInfo *cms, EVP_PKEY *pk, X509 *cert); | ||
179 | int CMS_decrypt_set1_key(CMS_ContentInfo *cms, | ||
180 | unsigned char *key, size_t keylen, | ||
181 | unsigned char *id, size_t idlen); | ||
182 | |||
183 | STACK_OF(CMS_RecipientInfo) *CMS_get0_RecipientInfos(CMS_ContentInfo *cms); | ||
184 | int CMS_RecipientInfo_type(CMS_RecipientInfo *ri); | ||
185 | CMS_ContentInfo *CMS_EnvelopedData_create(const EVP_CIPHER *cipher); | ||
186 | CMS_RecipientInfo *CMS_add1_recipient_cert(CMS_ContentInfo *cms, | ||
187 | X509 *recip, unsigned int flags); | ||
188 | int CMS_RecipientInfo_set0_pkey(CMS_RecipientInfo *ri, EVP_PKEY *pkey); | ||
189 | int CMS_RecipientInfo_ktri_cert_cmp(CMS_RecipientInfo *ri, X509 *cert); | ||
190 | int CMS_RecipientInfo_ktri_get0_algs(CMS_RecipientInfo *ri, | ||
191 | EVP_PKEY **pk, X509 **recip, | ||
192 | X509_ALGOR **palg); | ||
193 | int CMS_RecipientInfo_ktri_get0_signer_id(CMS_RecipientInfo *ri, | ||
194 | ASN1_OCTET_STRING **keyid, | ||
195 | X509_NAME **issuer, ASN1_INTEGER **sno); | ||
196 | |||
197 | CMS_RecipientInfo *CMS_add0_recipient_key(CMS_ContentInfo *cms, int nid, | ||
198 | unsigned char *key, size_t keylen, | ||
199 | unsigned char *id, size_t idlen, | ||
200 | ASN1_GENERALIZEDTIME *date, | ||
201 | ASN1_OBJECT *otherTypeId, | ||
202 | ASN1_TYPE *otherType); | ||
203 | |||
204 | int CMS_RecipientInfo_kekri_get0_id(CMS_RecipientInfo *ri, | ||
205 | X509_ALGOR **palg, | ||
206 | ASN1_OCTET_STRING **pid, | ||
207 | ASN1_GENERALIZEDTIME **pdate, | ||
208 | ASN1_OBJECT **potherid, | ||
209 | ASN1_TYPE **pothertype); | ||
210 | |||
211 | int CMS_RecipientInfo_set0_key(CMS_RecipientInfo *ri, | ||
212 | unsigned char *key, size_t keylen); | ||
213 | |||
214 | int CMS_RecipientInfo_kekri_id_cmp(CMS_RecipientInfo *ri, | ||
215 | const unsigned char *id, size_t idlen); | ||
216 | |||
217 | int CMS_RecipientInfo_decrypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri); | ||
218 | |||
219 | int CMS_uncompress(CMS_ContentInfo *cms, BIO *dcont, BIO *out, | ||
220 | unsigned int flags); | ||
221 | CMS_ContentInfo *CMS_compress(BIO *in, int comp_nid, unsigned int flags); | ||
222 | |||
223 | int CMS_set1_eContentType(CMS_ContentInfo *cms, const ASN1_OBJECT *oid); | ||
224 | const ASN1_OBJECT *CMS_get0_eContentType(CMS_ContentInfo *cms); | ||
225 | |||
226 | CMS_CertificateChoices *CMS_add0_CertificateChoices(CMS_ContentInfo *cms); | ||
227 | int CMS_add0_cert(CMS_ContentInfo *cms, X509 *cert); | ||
228 | int CMS_add1_cert(CMS_ContentInfo *cms, X509 *cert); | ||
229 | STACK_OF(X509) *CMS_get1_certs(CMS_ContentInfo *cms); | ||
230 | |||
231 | CMS_RevocationInfoChoice *CMS_add0_RevocationInfoChoice(CMS_ContentInfo *cms); | ||
232 | int CMS_add0_crl(CMS_ContentInfo *cms, X509_CRL *crl); | ||
233 | STACK_OF(X509_CRL) *CMS_get1_crls(CMS_ContentInfo *cms); | ||
234 | |||
235 | int CMS_SignedData_init(CMS_ContentInfo *cms); | ||
236 | CMS_SignerInfo *CMS_add1_signer(CMS_ContentInfo *cms, | ||
237 | X509 *signer, EVP_PKEY *pk, const EVP_MD *md, | ||
238 | unsigned int flags); | ||
239 | STACK_OF(CMS_SignerInfo) *CMS_get0_SignerInfos(CMS_ContentInfo *cms); | ||
240 | |||
241 | void CMS_SignerInfo_set1_signer_cert(CMS_SignerInfo *si, X509 *signer); | ||
242 | int CMS_SignerInfo_get0_signer_id(CMS_SignerInfo *si, | ||
243 | ASN1_OCTET_STRING **keyid, | ||
244 | X509_NAME **issuer, ASN1_INTEGER **sno); | ||
245 | int CMS_SignerInfo_cert_cmp(CMS_SignerInfo *si, X509 *cert); | ||
246 | int CMS_set1_signers_certs(CMS_ContentInfo *cms, STACK_OF(X509) *certs, | ||
247 | unsigned int flags); | ||
248 | void CMS_SignerInfo_get0_algs(CMS_SignerInfo *si, EVP_PKEY **pk, X509 **signer, | ||
249 | X509_ALGOR **pdig, X509_ALGOR **psig); | ||
250 | int CMS_SignerInfo_sign(CMS_SignerInfo *si); | ||
251 | int CMS_SignerInfo_verify(CMS_SignerInfo *si); | ||
252 | int CMS_SignerInfo_verify_content(CMS_SignerInfo *si, BIO *chain); | ||
253 | |||
254 | int CMS_add_smimecap(CMS_SignerInfo *si, STACK_OF(X509_ALGOR) *algs); | ||
255 | int CMS_add_simple_smimecap(STACK_OF(X509_ALGOR) **algs, | ||
256 | int algnid, int keysize); | ||
257 | int CMS_add_standard_smimecap(STACK_OF(X509_ALGOR) **smcap); | ||
258 | |||
259 | int CMS_signed_get_attr_count(const CMS_SignerInfo *si); | ||
260 | int CMS_signed_get_attr_by_NID(const CMS_SignerInfo *si, int nid, | ||
261 | int lastpos); | ||
262 | int CMS_signed_get_attr_by_OBJ(const CMS_SignerInfo *si, ASN1_OBJECT *obj, | ||
263 | int lastpos); | ||
264 | X509_ATTRIBUTE *CMS_signed_get_attr(const CMS_SignerInfo *si, int loc); | ||
265 | X509_ATTRIBUTE *CMS_signed_delete_attr(CMS_SignerInfo *si, int loc); | ||
266 | int CMS_signed_add1_attr(CMS_SignerInfo *si, X509_ATTRIBUTE *attr); | ||
267 | int CMS_signed_add1_attr_by_OBJ(CMS_SignerInfo *si, | ||
268 | const ASN1_OBJECT *obj, int type, | ||
269 | const void *bytes, int len); | ||
270 | int CMS_signed_add1_attr_by_NID(CMS_SignerInfo *si, | ||
271 | int nid, int type, | ||
272 | const void *bytes, int len); | ||
273 | int CMS_signed_add1_attr_by_txt(CMS_SignerInfo *si, | ||
274 | const char *attrname, int type, | ||
275 | const void *bytes, int len); | ||
276 | void *CMS_signed_get0_data_by_OBJ(CMS_SignerInfo *si, ASN1_OBJECT *oid, | ||
277 | int lastpos, int type); | ||
278 | |||
279 | int CMS_unsigned_get_attr_count(const CMS_SignerInfo *si); | ||
280 | int CMS_unsigned_get_attr_by_NID(const CMS_SignerInfo *si, int nid, | ||
281 | int lastpos); | ||
282 | int CMS_unsigned_get_attr_by_OBJ(const CMS_SignerInfo *si, ASN1_OBJECT *obj, | ||
283 | int lastpos); | ||
284 | X509_ATTRIBUTE *CMS_unsigned_get_attr(const CMS_SignerInfo *si, int loc); | ||
285 | X509_ATTRIBUTE *CMS_unsigned_delete_attr(CMS_SignerInfo *si, int loc); | ||
286 | int CMS_unsigned_add1_attr(CMS_SignerInfo *si, X509_ATTRIBUTE *attr); | ||
287 | int CMS_unsigned_add1_attr_by_OBJ(CMS_SignerInfo *si, | ||
288 | const ASN1_OBJECT *obj, int type, | ||
289 | const void *bytes, int len); | ||
290 | int CMS_unsigned_add1_attr_by_NID(CMS_SignerInfo *si, | ||
291 | int nid, int type, | ||
292 | const void *bytes, int len); | ||
293 | int CMS_unsigned_add1_attr_by_txt(CMS_SignerInfo *si, | ||
294 | const char *attrname, int type, | ||
295 | const void *bytes, int len); | ||
296 | void *CMS_unsigned_get0_data_by_OBJ(CMS_SignerInfo *si, ASN1_OBJECT *oid, | ||
297 | int lastpos, int type); | ||
298 | |||
299 | #ifdef HEADER_X509V3_H | ||
300 | |||
301 | int CMS_get1_ReceiptRequest(CMS_SignerInfo *si, CMS_ReceiptRequest **prr); | ||
302 | CMS_ReceiptRequest *CMS_ReceiptRequest_create0(unsigned char *id, int idlen, | ||
303 | int allorfirst, | ||
304 | STACK_OF(GENERAL_NAMES) *receiptList, | ||
305 | STACK_OF(GENERAL_NAMES) *receiptsTo); | ||
306 | int CMS_add1_ReceiptRequest(CMS_SignerInfo *si, CMS_ReceiptRequest *rr); | ||
307 | void CMS_ReceiptRequest_get0_values(CMS_ReceiptRequest *rr, | ||
308 | ASN1_STRING **pcid, | ||
309 | int *pallorfirst, | ||
310 | STACK_OF(GENERAL_NAMES) **plist, | ||
311 | STACK_OF(GENERAL_NAMES) **prto); | ||
312 | |||
313 | #endif | ||
314 | |||
315 | /* BEGIN ERROR CODES */ | ||
316 | /* The following lines are auto generated by the script mkerr.pl. Any changes | ||
317 | * made after this point may be overwritten when the script is next run. | ||
318 | */ | ||
319 | void ERR_load_CMS_strings(void); | ||
320 | |||
321 | /* Error codes for the CMS functions. */ | ||
322 | |||
323 | /* Function codes. */ | ||
324 | #define CMS_F_CHECK_CONTENT 99 | ||
325 | #define CMS_F_CMS_ADD0_CERT 164 | ||
326 | #define CMS_F_CMS_ADD0_RECIPIENT_KEY 100 | ||
327 | #define CMS_F_CMS_ADD1_RECEIPTREQUEST 158 | ||
328 | #define CMS_F_CMS_ADD1_RECIPIENT_CERT 101 | ||
329 | #define CMS_F_CMS_ADD1_SIGNER 102 | ||
330 | #define CMS_F_CMS_ADD1_SIGNINGTIME 103 | ||
331 | #define CMS_F_CMS_COMPRESS 104 | ||
332 | #define CMS_F_CMS_COMPRESSEDDATA_CREATE 105 | ||
333 | #define CMS_F_CMS_COMPRESSEDDATA_INIT_BIO 106 | ||
334 | #define CMS_F_CMS_COPY_CONTENT 107 | ||
335 | #define CMS_F_CMS_COPY_MESSAGEDIGEST 108 | ||
336 | #define CMS_F_CMS_DATA 109 | ||
337 | #define CMS_F_CMS_DATAFINAL 110 | ||
338 | #define CMS_F_CMS_DATAINIT 111 | ||
339 | #define CMS_F_CMS_DECRYPT 112 | ||
340 | #define CMS_F_CMS_DECRYPT_SET1_KEY 113 | ||
341 | #define CMS_F_CMS_DECRYPT_SET1_PKEY 114 | ||
342 | #define CMS_F_CMS_DIGESTALGORITHM_FIND_CTX 115 | ||
343 | #define CMS_F_CMS_DIGESTALGORITHM_INIT_BIO 116 | ||
344 | #define CMS_F_CMS_DIGESTEDDATA_DO_FINAL 117 | ||
345 | #define CMS_F_CMS_DIGEST_VERIFY 118 | ||
346 | #define CMS_F_CMS_ENCODE_RECEIPT 161 | ||
347 | #define CMS_F_CMS_ENCRYPT 119 | ||
348 | #define CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO 120 | ||
349 | #define CMS_F_CMS_ENCRYPTEDDATA_DECRYPT 121 | ||
350 | #define CMS_F_CMS_ENCRYPTEDDATA_ENCRYPT 122 | ||
351 | #define CMS_F_CMS_ENCRYPTEDDATA_SET1_KEY 123 | ||
352 | #define CMS_F_CMS_ENVELOPEDDATA_CREATE 124 | ||
353 | #define CMS_F_CMS_ENVELOPEDDATA_INIT_BIO 125 | ||
354 | #define CMS_F_CMS_ENVELOPED_DATA_INIT 126 | ||
355 | #define CMS_F_CMS_FINAL 127 | ||
356 | #define CMS_F_CMS_GET0_CERTIFICATE_CHOICES 128 | ||
357 | #define CMS_F_CMS_GET0_CONTENT 129 | ||
358 | #define CMS_F_CMS_GET0_ECONTENT_TYPE 130 | ||
359 | #define CMS_F_CMS_GET0_ENVELOPED 131 | ||
360 | #define CMS_F_CMS_GET0_REVOCATION_CHOICES 132 | ||
361 | #define CMS_F_CMS_GET0_SIGNED 133 | ||
362 | #define CMS_F_CMS_MSGSIGDIGEST_ADD1 162 | ||
363 | #define CMS_F_CMS_RECEIPTREQUEST_CREATE0 159 | ||
364 | #define CMS_F_CMS_RECEIPT_VERIFY 160 | ||
365 | #define CMS_F_CMS_RECIPIENTINFO_DECRYPT 134 | ||
366 | #define CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT 135 | ||
367 | #define CMS_F_CMS_RECIPIENTINFO_KEKRI_ENCRYPT 136 | ||
368 | #define CMS_F_CMS_RECIPIENTINFO_KEKRI_GET0_ID 137 | ||
369 | #define CMS_F_CMS_RECIPIENTINFO_KEKRI_ID_CMP 138 | ||
370 | #define CMS_F_CMS_RECIPIENTINFO_KTRI_CERT_CMP 139 | ||
371 | #define CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT 140 | ||
372 | #define CMS_F_CMS_RECIPIENTINFO_KTRI_ENCRYPT 141 | ||
373 | #define CMS_F_CMS_RECIPIENTINFO_KTRI_GET0_ALGS 142 | ||
374 | #define CMS_F_CMS_RECIPIENTINFO_KTRI_GET0_SIGNER_ID 143 | ||
375 | #define CMS_F_CMS_RECIPIENTINFO_SET0_KEY 144 | ||
376 | #define CMS_F_CMS_RECIPIENTINFO_SET0_PKEY 145 | ||
377 | #define CMS_F_CMS_SET1_SIGNERIDENTIFIER 146 | ||
378 | #define CMS_F_CMS_SET_DETACHED 147 | ||
379 | #define CMS_F_CMS_SIGN 148 | ||
380 | #define CMS_F_CMS_SIGNED_DATA_INIT 149 | ||
381 | #define CMS_F_CMS_SIGNERINFO_CONTENT_SIGN 150 | ||
382 | #define CMS_F_CMS_SIGNERINFO_SIGN 151 | ||
383 | #define CMS_F_CMS_SIGNERINFO_VERIFY 152 | ||
384 | #define CMS_F_CMS_SIGNERINFO_VERIFY_CERT 153 | ||
385 | #define CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT 154 | ||
386 | #define CMS_F_CMS_SIGN_RECEIPT 163 | ||
387 | #define CMS_F_CMS_STREAM 155 | ||
388 | #define CMS_F_CMS_UNCOMPRESS 156 | ||
389 | #define CMS_F_CMS_VERIFY 157 | ||
390 | |||
391 | /* Reason codes. */ | ||
392 | #define CMS_R_ADD_SIGNER_ERROR 99 | ||
393 | #define CMS_R_CERTIFICATE_ALREADY_PRESENT 175 | ||
394 | #define CMS_R_CERTIFICATE_HAS_NO_KEYID 160 | ||
395 | #define CMS_R_CERTIFICATE_VERIFY_ERROR 100 | ||
396 | #define CMS_R_CIPHER_INITIALISATION_ERROR 101 | ||
397 | #define CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR 102 | ||
398 | #define CMS_R_CMS_DATAFINAL_ERROR 103 | ||
399 | #define CMS_R_CMS_LIB 104 | ||
400 | #define CMS_R_CONTENTIDENTIFIER_MISMATCH 170 | ||
401 | #define CMS_R_CONTENT_NOT_FOUND 105 | ||
402 | #define CMS_R_CONTENT_TYPE_MISMATCH 171 | ||
403 | #define CMS_R_CONTENT_TYPE_NOT_COMPRESSED_DATA 106 | ||
404 | #define CMS_R_CONTENT_TYPE_NOT_ENVELOPED_DATA 107 | ||
405 | #define CMS_R_CONTENT_TYPE_NOT_SIGNED_DATA 108 | ||
406 | #define CMS_R_CONTENT_VERIFY_ERROR 109 | ||
407 | #define CMS_R_CTRL_ERROR 110 | ||
408 | #define CMS_R_CTRL_FAILURE 111 | ||
409 | #define CMS_R_DECRYPT_ERROR 112 | ||
410 | #define CMS_R_DIGEST_ERROR 161 | ||
411 | #define CMS_R_ERROR_GETTING_PUBLIC_KEY 113 | ||
412 | #define CMS_R_ERROR_READING_MESSAGEDIGEST_ATTRIBUTE 114 | ||
413 | #define CMS_R_ERROR_SETTING_KEY 115 | ||
414 | #define CMS_R_ERROR_SETTING_RECIPIENTINFO 116 | ||
415 | #define CMS_R_INVALID_ENCRYPTED_KEY_LENGTH 117 | ||
416 | #define CMS_R_INVALID_KEY_LENGTH 118 | ||
417 | #define CMS_R_MD_BIO_INIT_ERROR 119 | ||
418 | #define CMS_R_MESSAGEDIGEST_ATTRIBUTE_WRONG_LENGTH 120 | ||
419 | #define CMS_R_MESSAGEDIGEST_WRONG_LENGTH 121 | ||
420 | #define CMS_R_MSGSIGDIGEST_ERROR 172 | ||
421 | #define CMS_R_MSGSIGDIGEST_VERIFICATION_FAILURE 162 | ||
422 | #define CMS_R_MSGSIGDIGEST_WRONG_LENGTH 163 | ||
423 | #define CMS_R_NEED_ONE_SIGNER 164 | ||
424 | #define CMS_R_NOT_A_SIGNED_RECEIPT 165 | ||
425 | #define CMS_R_NOT_ENCRYPTED_DATA 122 | ||
426 | #define CMS_R_NOT_KEK 123 | ||
427 | #define CMS_R_NOT_KEY_TRANSPORT 124 | ||
428 | #define CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE 125 | ||
429 | #define CMS_R_NO_CIPHER 126 | ||
430 | #define CMS_R_NO_CONTENT 127 | ||
431 | #define CMS_R_NO_CONTENT_TYPE 173 | ||
432 | #define CMS_R_NO_DEFAULT_DIGEST 128 | ||
433 | #define CMS_R_NO_DIGEST_SET 129 | ||
434 | #define CMS_R_NO_KEY 130 | ||
435 | #define CMS_R_NO_KEY_OR_CERT 174 | ||
436 | #define CMS_R_NO_MATCHING_DIGEST 131 | ||
437 | #define CMS_R_NO_MATCHING_RECIPIENT 132 | ||
438 | #define CMS_R_NO_MATCHING_SIGNATURE 166 | ||
439 | #define CMS_R_NO_MSGSIGDIGEST 167 | ||
440 | #define CMS_R_NO_PRIVATE_KEY 133 | ||
441 | #define CMS_R_NO_PUBLIC_KEY 134 | ||
442 | #define CMS_R_NO_RECEIPT_REQUEST 168 | ||
443 | #define CMS_R_NO_SIGNERS 135 | ||
444 | #define CMS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE 136 | ||
445 | #define CMS_R_RECEIPT_DECODE_ERROR 169 | ||
446 | #define CMS_R_RECIPIENT_ERROR 137 | ||
447 | #define CMS_R_SIGNER_CERTIFICATE_NOT_FOUND 138 | ||
448 | #define CMS_R_SIGNFINAL_ERROR 139 | ||
449 | #define CMS_R_SMIME_TEXT_ERROR 140 | ||
450 | #define CMS_R_STORE_INIT_ERROR 141 | ||
451 | #define CMS_R_TYPE_NOT_COMPRESSED_DATA 142 | ||
452 | #define CMS_R_TYPE_NOT_DATA 143 | ||
453 | #define CMS_R_TYPE_NOT_DIGESTED_DATA 144 | ||
454 | #define CMS_R_TYPE_NOT_ENCRYPTED_DATA 145 | ||
455 | #define CMS_R_TYPE_NOT_ENVELOPED_DATA 146 | ||
456 | #define CMS_R_UNABLE_TO_FINALIZE_CONTEXT 147 | ||
457 | #define CMS_R_UNKNOWN_CIPHER 148 | ||
458 | #define CMS_R_UNKNOWN_DIGEST_ALGORIHM 149 | ||
459 | #define CMS_R_UNKNOWN_ID 150 | ||
460 | #define CMS_R_UNSUPPORTED_COMPRESSION_ALGORITHM 151 | ||
461 | #define CMS_R_UNSUPPORTED_CONTENT_TYPE 152 | ||
462 | #define CMS_R_UNSUPPORTED_KEK_ALGORITHM 153 | ||
463 | #define CMS_R_UNSUPPORTED_RECIPIENT_TYPE 154 | ||
464 | #define CMS_R_UNSUPPORTED_RECPIENTINFO_TYPE 155 | ||
465 | #define CMS_R_UNSUPPORTED_TYPE 156 | ||
466 | #define CMS_R_UNWRAP_ERROR 157 | ||
467 | #define CMS_R_VERIFICATION_FAILURE 158 | ||
468 | #define CMS_R_WRAP_ERROR 159 | ||
469 | |||
470 | #ifdef __cplusplus | ||
471 | } | ||
472 | #endif | ||
473 | #endif | ||
diff --git a/src/lib/libcrypto/cms/cms_asn1.c b/src/lib/libcrypto/cms/cms_asn1.c new file mode 100644 index 0000000000..7664921861 --- /dev/null +++ b/src/lib/libcrypto/cms/cms_asn1.c | |||
@@ -0,0 +1,346 @@ | |||
1 | /* crypto/cms/cms_asn1.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 <openssl/asn1t.h> | ||
55 | #include <openssl/pem.h> | ||
56 | #include <openssl/x509v3.h> | ||
57 | #include "cms.h" | ||
58 | #include "cms_lcl.h" | ||
59 | |||
60 | |||
61 | ASN1_SEQUENCE(CMS_IssuerAndSerialNumber) = { | ||
62 | ASN1_SIMPLE(CMS_IssuerAndSerialNumber, issuer, X509_NAME), | ||
63 | ASN1_SIMPLE(CMS_IssuerAndSerialNumber, serialNumber, ASN1_INTEGER) | ||
64 | } ASN1_SEQUENCE_END(CMS_IssuerAndSerialNumber) | ||
65 | |||
66 | ASN1_SEQUENCE(CMS_OtherCertificateFormat) = { | ||
67 | ASN1_SIMPLE(CMS_OtherCertificateFormat, otherCertFormat, ASN1_OBJECT), | ||
68 | ASN1_OPT(CMS_OtherCertificateFormat, otherCert, ASN1_ANY) | ||
69 | } ASN1_SEQUENCE_END(CMS_OtherCertificateFormat) | ||
70 | |||
71 | ASN1_CHOICE(CMS_CertificateChoices) = { | ||
72 | ASN1_SIMPLE(CMS_CertificateChoices, d.certificate, X509), | ||
73 | ASN1_IMP(CMS_CertificateChoices, d.extendedCertificate, ASN1_SEQUENCE, 0), | ||
74 | ASN1_IMP(CMS_CertificateChoices, d.v1AttrCert, ASN1_SEQUENCE, 1), | ||
75 | ASN1_IMP(CMS_CertificateChoices, d.v2AttrCert, ASN1_SEQUENCE, 2), | ||
76 | ASN1_IMP(CMS_CertificateChoices, d.other, CMS_OtherCertificateFormat, 3) | ||
77 | } ASN1_CHOICE_END(CMS_CertificateChoices) | ||
78 | |||
79 | ASN1_CHOICE(CMS_SignerIdentifier) = { | ||
80 | ASN1_SIMPLE(CMS_SignerIdentifier, d.issuerAndSerialNumber, CMS_IssuerAndSerialNumber), | ||
81 | ASN1_IMP(CMS_SignerIdentifier, d.subjectKeyIdentifier, ASN1_OCTET_STRING, 0) | ||
82 | } ASN1_CHOICE_END(CMS_SignerIdentifier) | ||
83 | |||
84 | ASN1_NDEF_SEQUENCE(CMS_EncapsulatedContentInfo) = { | ||
85 | ASN1_SIMPLE(CMS_EncapsulatedContentInfo, eContentType, ASN1_OBJECT), | ||
86 | ASN1_NDEF_EXP_OPT(CMS_EncapsulatedContentInfo, eContent, ASN1_OCTET_STRING_NDEF, 0) | ||
87 | } ASN1_NDEF_SEQUENCE_END(CMS_EncapsulatedContentInfo) | ||
88 | |||
89 | /* Minor tweak to operation: free up signer key, cert */ | ||
90 | static int cms_si_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it) | ||
91 | { | ||
92 | if(operation == ASN1_OP_FREE_POST) | ||
93 | { | ||
94 | CMS_SignerInfo *si = (CMS_SignerInfo *)*pval; | ||
95 | if (si->pkey) | ||
96 | EVP_PKEY_free(si->pkey); | ||
97 | if (si->signer) | ||
98 | X509_free(si->signer); | ||
99 | } | ||
100 | return 1; | ||
101 | } | ||
102 | |||
103 | ASN1_SEQUENCE_cb(CMS_SignerInfo, cms_si_cb) = { | ||
104 | ASN1_SIMPLE(CMS_SignerInfo, version, LONG), | ||
105 | ASN1_SIMPLE(CMS_SignerInfo, sid, CMS_SignerIdentifier), | ||
106 | ASN1_SIMPLE(CMS_SignerInfo, digestAlgorithm, X509_ALGOR), | ||
107 | ASN1_IMP_SET_OF_OPT(CMS_SignerInfo, signedAttrs, X509_ATTRIBUTE, 0), | ||
108 | ASN1_SIMPLE(CMS_SignerInfo, signatureAlgorithm, X509_ALGOR), | ||
109 | ASN1_SIMPLE(CMS_SignerInfo, signature, ASN1_OCTET_STRING), | ||
110 | ASN1_IMP_SET_OF_OPT(CMS_SignerInfo, unsignedAttrs, X509_ATTRIBUTE, 1) | ||
111 | } ASN1_SEQUENCE_END_cb(CMS_SignerInfo, CMS_SignerInfo) | ||
112 | |||
113 | ASN1_SEQUENCE(CMS_OtherRevocationInfoFormat) = { | ||
114 | ASN1_SIMPLE(CMS_OtherRevocationInfoFormat, otherRevInfoFormat, ASN1_OBJECT), | ||
115 | ASN1_OPT(CMS_OtherRevocationInfoFormat, otherRevInfo, ASN1_ANY) | ||
116 | } ASN1_SEQUENCE_END(CMS_OtherRevocationInfoFormat) | ||
117 | |||
118 | ASN1_CHOICE(CMS_RevocationInfoChoice) = { | ||
119 | ASN1_SIMPLE(CMS_RevocationInfoChoice, d.crl, X509_CRL), | ||
120 | ASN1_IMP(CMS_RevocationInfoChoice, d.other, CMS_OtherRevocationInfoFormat, 1) | ||
121 | } ASN1_CHOICE_END(CMS_RevocationInfoChoice) | ||
122 | |||
123 | ASN1_NDEF_SEQUENCE(CMS_SignedData) = { | ||
124 | ASN1_SIMPLE(CMS_SignedData, version, LONG), | ||
125 | ASN1_SET_OF(CMS_SignedData, digestAlgorithms, X509_ALGOR), | ||
126 | ASN1_SIMPLE(CMS_SignedData, encapContentInfo, CMS_EncapsulatedContentInfo), | ||
127 | ASN1_IMP_SET_OF_OPT(CMS_SignedData, certificates, CMS_CertificateChoices, 0), | ||
128 | ASN1_IMP_SET_OF_OPT(CMS_SignedData, crls, CMS_RevocationInfoChoice, 1), | ||
129 | ASN1_SET_OF(CMS_SignedData, signerInfos, CMS_SignerInfo) | ||
130 | } ASN1_NDEF_SEQUENCE_END(CMS_SignedData) | ||
131 | |||
132 | ASN1_SEQUENCE(CMS_OriginatorInfo) = { | ||
133 | ASN1_IMP_SET_OF_OPT(CMS_SignedData, certificates, CMS_CertificateChoices, 0), | ||
134 | ASN1_IMP_SET_OF_OPT(CMS_SignedData, crls, CMS_RevocationInfoChoice, 1) | ||
135 | } ASN1_SEQUENCE_END(CMS_OriginatorInfo) | ||
136 | |||
137 | ASN1_NDEF_SEQUENCE(CMS_EncryptedContentInfo) = { | ||
138 | ASN1_SIMPLE(CMS_EncryptedContentInfo, contentType, ASN1_OBJECT), | ||
139 | ASN1_SIMPLE(CMS_EncryptedContentInfo, contentEncryptionAlgorithm, X509_ALGOR), | ||
140 | ASN1_IMP_OPT(CMS_EncryptedContentInfo, encryptedContent, ASN1_OCTET_STRING_NDEF, 0) | ||
141 | } ASN1_NDEF_SEQUENCE_END(CMS_EncryptedContentInfo) | ||
142 | |||
143 | ASN1_SEQUENCE(CMS_KeyTransRecipientInfo) = { | ||
144 | ASN1_SIMPLE(CMS_KeyTransRecipientInfo, version, LONG), | ||
145 | ASN1_SIMPLE(CMS_KeyTransRecipientInfo, rid, CMS_SignerIdentifier), | ||
146 | ASN1_SIMPLE(CMS_KeyTransRecipientInfo, keyEncryptionAlgorithm, X509_ALGOR), | ||
147 | ASN1_SIMPLE(CMS_KeyTransRecipientInfo, encryptedKey, ASN1_OCTET_STRING) | ||
148 | } ASN1_SEQUENCE_END(CMS_KeyTransRecipientInfo) | ||
149 | |||
150 | ASN1_SEQUENCE(CMS_OtherKeyAttribute) = { | ||
151 | ASN1_SIMPLE(CMS_OtherKeyAttribute, keyAttrId, ASN1_OBJECT), | ||
152 | ASN1_OPT(CMS_OtherKeyAttribute, keyAttr, ASN1_ANY) | ||
153 | } ASN1_SEQUENCE_END(CMS_OtherKeyAttribute) | ||
154 | |||
155 | ASN1_SEQUENCE(CMS_RecipientKeyIdentifier) = { | ||
156 | ASN1_SIMPLE(CMS_RecipientKeyIdentifier, subjectKeyIdentifier, ASN1_OCTET_STRING), | ||
157 | ASN1_OPT(CMS_RecipientKeyIdentifier, date, ASN1_GENERALIZEDTIME), | ||
158 | ASN1_OPT(CMS_RecipientKeyIdentifier, other, CMS_OtherKeyAttribute) | ||
159 | } ASN1_SEQUENCE_END(CMS_RecipientKeyIdentifier) | ||
160 | |||
161 | ASN1_CHOICE(CMS_KeyAgreeRecipientIdentifier) = { | ||
162 | ASN1_SIMPLE(CMS_KeyAgreeRecipientIdentifier, d.issuerAndSerialNumber, CMS_IssuerAndSerialNumber), | ||
163 | ASN1_IMP(CMS_KeyAgreeRecipientIdentifier, d.rKeyId, CMS_RecipientKeyIdentifier, 0) | ||
164 | } ASN1_CHOICE_END(CMS_KeyAgreeRecipientIdentifier) | ||
165 | |||
166 | ASN1_SEQUENCE(CMS_RecipientEncryptedKey) = { | ||
167 | ASN1_SIMPLE(CMS_RecipientEncryptedKey, rid, CMS_KeyAgreeRecipientIdentifier), | ||
168 | ASN1_SIMPLE(CMS_RecipientEncryptedKey, encryptedKey, ASN1_OCTET_STRING) | ||
169 | } ASN1_SEQUENCE_END(CMS_RecipientEncryptedKey) | ||
170 | |||
171 | ASN1_SEQUENCE(CMS_OriginatorPublicKey) = { | ||
172 | ASN1_SIMPLE(CMS_OriginatorPublicKey, algorithm, X509_ALGOR), | ||
173 | ASN1_SIMPLE(CMS_OriginatorPublicKey, publicKey, ASN1_BIT_STRING) | ||
174 | } ASN1_SEQUENCE_END(CMS_OriginatorPublicKey) | ||
175 | |||
176 | ASN1_CHOICE(CMS_OriginatorIdentifierOrKey) = { | ||
177 | ASN1_SIMPLE(CMS_OriginatorIdentifierOrKey, d.issuerAndSerialNumber, CMS_IssuerAndSerialNumber), | ||
178 | ASN1_IMP(CMS_OriginatorIdentifierOrKey, d.subjectKeyIdentifier, ASN1_OCTET_STRING, 0), | ||
179 | ASN1_IMP(CMS_OriginatorIdentifierOrKey, d.originatorKey, CMS_OriginatorPublicKey, 1) | ||
180 | } ASN1_CHOICE_END(CMS_OriginatorIdentifierOrKey) | ||
181 | |||
182 | ASN1_SEQUENCE(CMS_KeyAgreeRecipientInfo) = { | ||
183 | ASN1_SIMPLE(CMS_KeyAgreeRecipientInfo, version, LONG), | ||
184 | ASN1_EXP(CMS_KeyAgreeRecipientInfo, originator, CMS_OriginatorIdentifierOrKey, 0), | ||
185 | ASN1_EXP_OPT(CMS_KeyAgreeRecipientInfo, ukm, ASN1_OCTET_STRING, 1), | ||
186 | ASN1_SIMPLE(CMS_KeyAgreeRecipientInfo, keyEncryptionAlgorithm, X509_ALGOR), | ||
187 | ASN1_SEQUENCE_OF(CMS_KeyAgreeRecipientInfo, recipientEncryptedKeys, CMS_RecipientEncryptedKey) | ||
188 | } ASN1_SEQUENCE_END(CMS_KeyAgreeRecipientInfo) | ||
189 | |||
190 | ASN1_SEQUENCE(CMS_KEKIdentifier) = { | ||
191 | ASN1_SIMPLE(CMS_KEKIdentifier, keyIdentifier, ASN1_OCTET_STRING), | ||
192 | ASN1_OPT(CMS_KEKIdentifier, date, ASN1_GENERALIZEDTIME), | ||
193 | ASN1_OPT(CMS_KEKIdentifier, other, CMS_OtherKeyAttribute) | ||
194 | } ASN1_SEQUENCE_END(CMS_KEKIdentifier) | ||
195 | |||
196 | ASN1_SEQUENCE(CMS_KEKRecipientInfo) = { | ||
197 | ASN1_SIMPLE(CMS_KEKRecipientInfo, version, LONG), | ||
198 | ASN1_SIMPLE(CMS_KEKRecipientInfo, kekid, CMS_KEKIdentifier), | ||
199 | ASN1_SIMPLE(CMS_KEKRecipientInfo, keyEncryptionAlgorithm, X509_ALGOR), | ||
200 | ASN1_SIMPLE(CMS_KEKRecipientInfo, encryptedKey, ASN1_OCTET_STRING) | ||
201 | } ASN1_SEQUENCE_END(CMS_KEKRecipientInfo) | ||
202 | |||
203 | ASN1_SEQUENCE(CMS_PasswordRecipientInfo) = { | ||
204 | ASN1_SIMPLE(CMS_PasswordRecipientInfo, version, LONG), | ||
205 | ASN1_IMP_OPT(CMS_PasswordRecipientInfo, keyDerivationAlgorithm, X509_ALGOR, 0), | ||
206 | ASN1_SIMPLE(CMS_PasswordRecipientInfo, keyEncryptionAlgorithm, X509_ALGOR), | ||
207 | ASN1_SIMPLE(CMS_PasswordRecipientInfo, encryptedKey, ASN1_OCTET_STRING) | ||
208 | } ASN1_SEQUENCE_END(CMS_PasswordRecipientInfo) | ||
209 | |||
210 | ASN1_SEQUENCE(CMS_OtherRecipientInfo) = { | ||
211 | ASN1_SIMPLE(CMS_OtherRecipientInfo, oriType, ASN1_OBJECT), | ||
212 | ASN1_OPT(CMS_OtherRecipientInfo, oriValue, ASN1_ANY) | ||
213 | } ASN1_SEQUENCE_END(CMS_OtherRecipientInfo) | ||
214 | |||
215 | /* Free up RecipientInfo additional data */ | ||
216 | static int cms_ri_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it) | ||
217 | { | ||
218 | if(operation == ASN1_OP_FREE_PRE) | ||
219 | { | ||
220 | CMS_RecipientInfo *ri = (CMS_RecipientInfo *)*pval; | ||
221 | if (ri->type == CMS_RECIPINFO_TRANS) | ||
222 | { | ||
223 | CMS_KeyTransRecipientInfo *ktri = ri->d.ktri; | ||
224 | if (ktri->pkey) | ||
225 | EVP_PKEY_free(ktri->pkey); | ||
226 | if (ktri->recip) | ||
227 | X509_free(ktri->recip); | ||
228 | } | ||
229 | else if (ri->type == CMS_RECIPINFO_KEK) | ||
230 | { | ||
231 | CMS_KEKRecipientInfo *kekri = ri->d.kekri; | ||
232 | if (kekri->key) | ||
233 | { | ||
234 | OPENSSL_cleanse(kekri->key, kekri->keylen); | ||
235 | OPENSSL_free(kekri->key); | ||
236 | } | ||
237 | } | ||
238 | } | ||
239 | return 1; | ||
240 | } | ||
241 | |||
242 | ASN1_CHOICE_cb(CMS_RecipientInfo, cms_ri_cb) = { | ||
243 | ASN1_SIMPLE(CMS_RecipientInfo, d.ktri, CMS_KeyTransRecipientInfo), | ||
244 | ASN1_IMP(CMS_RecipientInfo, d.kari, CMS_KeyAgreeRecipientInfo, 1), | ||
245 | ASN1_IMP(CMS_RecipientInfo, d.kekri, CMS_KEKRecipientInfo, 2), | ||
246 | ASN1_IMP(CMS_RecipientInfo, d.pwri, CMS_PasswordRecipientInfo, 3), | ||
247 | ASN1_IMP(CMS_RecipientInfo, d.ori, CMS_OtherRecipientInfo, 4) | ||
248 | } ASN1_CHOICE_END_cb(CMS_RecipientInfo, CMS_RecipientInfo, type) | ||
249 | |||
250 | ASN1_NDEF_SEQUENCE(CMS_EnvelopedData) = { | ||
251 | ASN1_SIMPLE(CMS_EnvelopedData, version, LONG), | ||
252 | ASN1_IMP_OPT(CMS_EnvelopedData, originatorInfo, CMS_OriginatorInfo, 0), | ||
253 | ASN1_SET_OF(CMS_EnvelopedData, recipientInfos, CMS_RecipientInfo), | ||
254 | ASN1_SIMPLE(CMS_EnvelopedData, encryptedContentInfo, CMS_EncryptedContentInfo), | ||
255 | ASN1_IMP_SET_OF_OPT(CMS_EnvelopedData, unprotectedAttrs, X509_ATTRIBUTE, 1) | ||
256 | } ASN1_NDEF_SEQUENCE_END(CMS_EnvelopedData) | ||
257 | |||
258 | ASN1_NDEF_SEQUENCE(CMS_DigestedData) = { | ||
259 | ASN1_SIMPLE(CMS_DigestedData, version, LONG), | ||
260 | ASN1_SIMPLE(CMS_DigestedData, digestAlgorithm, X509_ALGOR), | ||
261 | ASN1_SIMPLE(CMS_DigestedData, encapContentInfo, CMS_EncapsulatedContentInfo), | ||
262 | ASN1_SIMPLE(CMS_DigestedData, digest, ASN1_OCTET_STRING) | ||
263 | } ASN1_NDEF_SEQUENCE_END(CMS_DigestedData) | ||
264 | |||
265 | ASN1_NDEF_SEQUENCE(CMS_EncryptedData) = { | ||
266 | ASN1_SIMPLE(CMS_EncryptedData, version, LONG), | ||
267 | ASN1_SIMPLE(CMS_EncryptedData, encryptedContentInfo, CMS_EncryptedContentInfo), | ||
268 | ASN1_IMP_SET_OF_OPT(CMS_EncryptedData, unprotectedAttrs, X509_ATTRIBUTE, 1) | ||
269 | } ASN1_NDEF_SEQUENCE_END(CMS_EncryptedData) | ||
270 | |||
271 | ASN1_NDEF_SEQUENCE(CMS_AuthenticatedData) = { | ||
272 | ASN1_SIMPLE(CMS_AuthenticatedData, version, LONG), | ||
273 | ASN1_IMP_OPT(CMS_AuthenticatedData, originatorInfo, CMS_OriginatorInfo, 0), | ||
274 | ASN1_SET_OF(CMS_AuthenticatedData, recipientInfos, CMS_RecipientInfo), | ||
275 | ASN1_SIMPLE(CMS_AuthenticatedData, macAlgorithm, X509_ALGOR), | ||
276 | ASN1_IMP(CMS_AuthenticatedData, digestAlgorithm, X509_ALGOR, 1), | ||
277 | ASN1_SIMPLE(CMS_AuthenticatedData, encapContentInfo, CMS_EncapsulatedContentInfo), | ||
278 | ASN1_IMP_SET_OF_OPT(CMS_AuthenticatedData, authAttrs, X509_ALGOR, 2), | ||
279 | ASN1_SIMPLE(CMS_AuthenticatedData, mac, ASN1_OCTET_STRING), | ||
280 | ASN1_IMP_SET_OF_OPT(CMS_AuthenticatedData, unauthAttrs, X509_ALGOR, 3) | ||
281 | } ASN1_NDEF_SEQUENCE_END(CMS_AuthenticatedData) | ||
282 | |||
283 | ASN1_NDEF_SEQUENCE(CMS_CompressedData) = { | ||
284 | ASN1_SIMPLE(CMS_CompressedData, version, LONG), | ||
285 | ASN1_SIMPLE(CMS_CompressedData, compressionAlgorithm, X509_ALGOR), | ||
286 | ASN1_SIMPLE(CMS_CompressedData, encapContentInfo, CMS_EncapsulatedContentInfo), | ||
287 | } ASN1_NDEF_SEQUENCE_END(CMS_CompressedData) | ||
288 | |||
289 | /* This is the ANY DEFINED BY table for the top level ContentInfo structure */ | ||
290 | |||
291 | ASN1_ADB_TEMPLATE(cms_default) = ASN1_EXP(CMS_ContentInfo, d.other, ASN1_ANY, 0); | ||
292 | |||
293 | ASN1_ADB(CMS_ContentInfo) = { | ||
294 | ADB_ENTRY(NID_pkcs7_data, ASN1_NDEF_EXP(CMS_ContentInfo, d.data, ASN1_OCTET_STRING_NDEF, 0)), | ||
295 | ADB_ENTRY(NID_pkcs7_signed, ASN1_NDEF_EXP(CMS_ContentInfo, d.signedData, CMS_SignedData, 0)), | ||
296 | ADB_ENTRY(NID_pkcs7_enveloped, ASN1_NDEF_EXP(CMS_ContentInfo, d.envelopedData, CMS_EnvelopedData, 0)), | ||
297 | ADB_ENTRY(NID_pkcs7_digest, ASN1_NDEF_EXP(CMS_ContentInfo, d.digestedData, CMS_DigestedData, 0)), | ||
298 | ADB_ENTRY(NID_pkcs7_encrypted, ASN1_NDEF_EXP(CMS_ContentInfo, d.encryptedData, CMS_EncryptedData, 0)), | ||
299 | ADB_ENTRY(NID_id_smime_ct_authData, ASN1_NDEF_EXP(CMS_ContentInfo, d.authenticatedData, CMS_AuthenticatedData, 0)), | ||
300 | ADB_ENTRY(NID_id_smime_ct_compressedData, ASN1_NDEF_EXP(CMS_ContentInfo, d.compressedData, CMS_CompressedData, 0)), | ||
301 | } ASN1_ADB_END(CMS_ContentInfo, 0, contentType, 0, &cms_default_tt, NULL); | ||
302 | |||
303 | ASN1_NDEF_SEQUENCE(CMS_ContentInfo) = { | ||
304 | ASN1_SIMPLE(CMS_ContentInfo, contentType, ASN1_OBJECT), | ||
305 | ASN1_ADB_OBJECT(CMS_ContentInfo) | ||
306 | } ASN1_NDEF_SEQUENCE_END(CMS_ContentInfo) | ||
307 | |||
308 | /* Specials for signed attributes */ | ||
309 | |||
310 | /* When signing attributes we want to reorder them to match the sorted | ||
311 | * encoding. | ||
312 | */ | ||
313 | |||
314 | ASN1_ITEM_TEMPLATE(CMS_Attributes_Sign) = | ||
315 | ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SET_ORDER, 0, CMS_ATTRIBUTES, X509_ATTRIBUTE) | ||
316 | ASN1_ITEM_TEMPLATE_END(CMS_Attributes_Sign) | ||
317 | |||
318 | /* When verifying attributes we need to use the received order. So | ||
319 | * we use SEQUENCE OF and tag it to SET OF | ||
320 | */ | ||
321 | |||
322 | ASN1_ITEM_TEMPLATE(CMS_Attributes_Verify) = | ||
323 | ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF | ASN1_TFLG_IMPTAG | ASN1_TFLG_UNIVERSAL, | ||
324 | V_ASN1_SET, CMS_ATTRIBUTES, X509_ATTRIBUTE) | ||
325 | ASN1_ITEM_TEMPLATE_END(CMS_Attributes_Verify) | ||
326 | |||
327 | |||
328 | |||
329 | ASN1_CHOICE(CMS_ReceiptsFrom) = { | ||
330 | ASN1_IMP(CMS_ReceiptsFrom, d.allOrFirstTier, LONG, 0), | ||
331 | ASN1_IMP_SEQUENCE_OF(CMS_ReceiptsFrom, d.receiptList, GENERAL_NAMES, 1) | ||
332 | } ASN1_CHOICE_END(CMS_ReceiptsFrom) | ||
333 | |||
334 | ASN1_SEQUENCE(CMS_ReceiptRequest) = { | ||
335 | ASN1_SIMPLE(CMS_ReceiptRequest, signedContentIdentifier, ASN1_OCTET_STRING), | ||
336 | ASN1_SIMPLE(CMS_ReceiptRequest, receiptsFrom, CMS_ReceiptsFrom), | ||
337 | ASN1_SEQUENCE_OF(CMS_ReceiptRequest, receiptsTo, GENERAL_NAMES) | ||
338 | } ASN1_SEQUENCE_END(CMS_ReceiptRequest) | ||
339 | |||
340 | ASN1_SEQUENCE(CMS_Receipt) = { | ||
341 | ASN1_SIMPLE(CMS_Receipt, version, LONG), | ||
342 | ASN1_SIMPLE(CMS_Receipt, contentType, ASN1_OBJECT), | ||
343 | ASN1_SIMPLE(CMS_Receipt, signedContentIdentifier, ASN1_OCTET_STRING), | ||
344 | ASN1_SIMPLE(CMS_Receipt, originatorSignatureValue, ASN1_OCTET_STRING) | ||
345 | } ASN1_SEQUENCE_END(CMS_Receipt) | ||
346 | |||
diff --git a/src/lib/libcrypto/cms/cms_att.c b/src/lib/libcrypto/cms/cms_att.c new file mode 100644 index 0000000000..5b71722ebc --- /dev/null +++ b/src/lib/libcrypto/cms/cms_att.c | |||
@@ -0,0 +1,195 @@ | |||
1 | /* crypto/cms/cms_att.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 <openssl/asn1t.h> | ||
55 | #include <openssl/pem.h> | ||
56 | #include <openssl/x509v3.h> | ||
57 | #include <openssl/err.h> | ||
58 | #include "cms.h" | ||
59 | #include "cms_lcl.h" | ||
60 | |||
61 | /* CMS SignedData Attribute utilities */ | ||
62 | |||
63 | int CMS_signed_get_attr_count(const CMS_SignerInfo *si) | ||
64 | { | ||
65 | return X509at_get_attr_count(si->signedAttrs); | ||
66 | } | ||
67 | |||
68 | int CMS_signed_get_attr_by_NID(const CMS_SignerInfo *si, int nid, | ||
69 | int lastpos) | ||
70 | { | ||
71 | return X509at_get_attr_by_NID(si->signedAttrs, nid, lastpos); | ||
72 | } | ||
73 | |||
74 | int CMS_signed_get_attr_by_OBJ(const CMS_SignerInfo *si, ASN1_OBJECT *obj, | ||
75 | int lastpos) | ||
76 | { | ||
77 | return X509at_get_attr_by_OBJ(si->signedAttrs, obj, lastpos); | ||
78 | } | ||
79 | |||
80 | X509_ATTRIBUTE *CMS_signed_get_attr(const CMS_SignerInfo *si, int loc) | ||
81 | { | ||
82 | return X509at_get_attr(si->signedAttrs, loc); | ||
83 | } | ||
84 | |||
85 | X509_ATTRIBUTE *CMS_signed_delete_attr(CMS_SignerInfo *si, int loc) | ||
86 | { | ||
87 | return X509at_delete_attr(si->signedAttrs, loc); | ||
88 | } | ||
89 | |||
90 | int CMS_signed_add1_attr(CMS_SignerInfo *si, X509_ATTRIBUTE *attr) | ||
91 | { | ||
92 | if(X509at_add1_attr(&si->signedAttrs, attr)) return 1; | ||
93 | return 0; | ||
94 | } | ||
95 | |||
96 | int CMS_signed_add1_attr_by_OBJ(CMS_SignerInfo *si, | ||
97 | const ASN1_OBJECT *obj, int type, | ||
98 | const void *bytes, int len) | ||
99 | { | ||
100 | if(X509at_add1_attr_by_OBJ(&si->signedAttrs, obj, | ||
101 | type, bytes, len)) return 1; | ||
102 | return 0; | ||
103 | } | ||
104 | |||
105 | int CMS_signed_add1_attr_by_NID(CMS_SignerInfo *si, | ||
106 | int nid, int type, | ||
107 | const void *bytes, int len) | ||
108 | { | ||
109 | if(X509at_add1_attr_by_NID(&si->signedAttrs, nid, | ||
110 | type, bytes, len)) return 1; | ||
111 | return 0; | ||
112 | } | ||
113 | |||
114 | int CMS_signed_add1_attr_by_txt(CMS_SignerInfo *si, | ||
115 | const char *attrname, int type, | ||
116 | const void *bytes, int len) | ||
117 | { | ||
118 | if(X509at_add1_attr_by_txt(&si->signedAttrs, attrname, | ||
119 | type, bytes, len)) return 1; | ||
120 | return 0; | ||
121 | } | ||
122 | |||
123 | void *CMS_signed_get0_data_by_OBJ(CMS_SignerInfo *si, ASN1_OBJECT *oid, | ||
124 | int lastpos, int type) | ||
125 | { | ||
126 | return X509at_get0_data_by_OBJ(si->signedAttrs, oid, lastpos, type); | ||
127 | } | ||
128 | |||
129 | int CMS_unsigned_get_attr_count(const CMS_SignerInfo *si) | ||
130 | { | ||
131 | return X509at_get_attr_count(si->unsignedAttrs); | ||
132 | } | ||
133 | |||
134 | int CMS_unsigned_get_attr_by_NID(const CMS_SignerInfo *si, int nid, | ||
135 | int lastpos) | ||
136 | { | ||
137 | return X509at_get_attr_by_NID(si->unsignedAttrs, nid, lastpos); | ||
138 | } | ||
139 | |||
140 | int CMS_unsigned_get_attr_by_OBJ(const CMS_SignerInfo *si, ASN1_OBJECT *obj, | ||
141 | int lastpos) | ||
142 | { | ||
143 | return X509at_get_attr_by_OBJ(si->unsignedAttrs, obj, lastpos); | ||
144 | } | ||
145 | |||
146 | X509_ATTRIBUTE *CMS_unsigned_get_attr(const CMS_SignerInfo *si, int loc) | ||
147 | { | ||
148 | return X509at_get_attr(si->unsignedAttrs, loc); | ||
149 | } | ||
150 | |||
151 | X509_ATTRIBUTE *CMS_unsigned_delete_attr(CMS_SignerInfo *si, int loc) | ||
152 | { | ||
153 | return X509at_delete_attr(si->unsignedAttrs, loc); | ||
154 | } | ||
155 | |||
156 | int CMS_unsigned_add1_attr(CMS_SignerInfo *si, X509_ATTRIBUTE *attr) | ||
157 | { | ||
158 | if(X509at_add1_attr(&si->unsignedAttrs, attr)) return 1; | ||
159 | return 0; | ||
160 | } | ||
161 | |||
162 | int CMS_unsigned_add1_attr_by_OBJ(CMS_SignerInfo *si, | ||
163 | const ASN1_OBJECT *obj, int type, | ||
164 | const void *bytes, int len) | ||
165 | { | ||
166 | if(X509at_add1_attr_by_OBJ(&si->unsignedAttrs, obj, | ||
167 | type, bytes, len)) return 1; | ||
168 | return 0; | ||
169 | } | ||
170 | |||
171 | int CMS_unsigned_add1_attr_by_NID(CMS_SignerInfo *si, | ||
172 | int nid, int type, | ||
173 | const void *bytes, int len) | ||
174 | { | ||
175 | if(X509at_add1_attr_by_NID(&si->unsignedAttrs, nid, | ||
176 | type, bytes, len)) return 1; | ||
177 | return 0; | ||
178 | } | ||
179 | |||
180 | int CMS_unsigned_add1_attr_by_txt(CMS_SignerInfo *si, | ||
181 | const char *attrname, int type, | ||
182 | const void *bytes, int len) | ||
183 | { | ||
184 | if(X509at_add1_attr_by_txt(&si->unsignedAttrs, attrname, | ||
185 | type, bytes, len)) return 1; | ||
186 | return 0; | ||
187 | } | ||
188 | |||
189 | void *CMS_unsigned_get0_data_by_OBJ(CMS_SignerInfo *si, ASN1_OBJECT *oid, | ||
190 | int lastpos, int type) | ||
191 | { | ||
192 | return X509at_get0_data_by_OBJ(si->unsignedAttrs, oid, lastpos, type); | ||
193 | } | ||
194 | |||
195 | /* Specific attribute cases */ | ||
diff --git a/src/lib/libcrypto/cms/cms_cd.c b/src/lib/libcrypto/cms/cms_cd.c new file mode 100644 index 0000000000..a5fc2c4e2b --- /dev/null +++ b/src/lib/libcrypto/cms/cms_cd.c | |||
@@ -0,0 +1,134 @@ | |||
1 | /* crypto/cms/cms_cd.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/asn1t.h> | ||
56 | #include <openssl/pem.h> | ||
57 | #include <openssl/x509v3.h> | ||
58 | #include <openssl/err.h> | ||
59 | #include <openssl/cms.h> | ||
60 | #include <openssl/bio.h> | ||
61 | #include <openssl/comp.h> | ||
62 | #include "cms_lcl.h" | ||
63 | |||
64 | DECLARE_ASN1_ITEM(CMS_CompressedData) | ||
65 | |||
66 | #ifdef ZLIB | ||
67 | |||
68 | /* CMS CompressedData Utilities */ | ||
69 | |||
70 | CMS_ContentInfo *cms_CompressedData_create(int comp_nid) | ||
71 | { | ||
72 | CMS_ContentInfo *cms; | ||
73 | CMS_CompressedData *cd; | ||
74 | /* Will need something cleverer if there is ever more than one | ||
75 | * compression algorithm or parameters have some meaning... | ||
76 | */ | ||
77 | if (comp_nid != NID_zlib_compression) | ||
78 | { | ||
79 | CMSerr(CMS_F_CMS_COMPRESSEDDATA_CREATE, | ||
80 | CMS_R_UNSUPPORTED_COMPRESSION_ALGORITHM); | ||
81 | return NULL; | ||
82 | } | ||
83 | cms = CMS_ContentInfo_new(); | ||
84 | if (!cms) | ||
85 | return NULL; | ||
86 | |||
87 | cd = M_ASN1_new_of(CMS_CompressedData); | ||
88 | |||
89 | if (!cd) | ||
90 | goto err; | ||
91 | |||
92 | cms->contentType = OBJ_nid2obj(NID_id_smime_ct_compressedData); | ||
93 | cms->d.compressedData = cd; | ||
94 | |||
95 | cd->version = 0; | ||
96 | |||
97 | X509_ALGOR_set0(cd->compressionAlgorithm, | ||
98 | OBJ_nid2obj(NID_zlib_compression), | ||
99 | V_ASN1_UNDEF, NULL); | ||
100 | |||
101 | cd->encapContentInfo->eContentType = OBJ_nid2obj(NID_pkcs7_data); | ||
102 | |||
103 | return cms; | ||
104 | |||
105 | err: | ||
106 | |||
107 | if (cms) | ||
108 | CMS_ContentInfo_free(cms); | ||
109 | |||
110 | return NULL; | ||
111 | } | ||
112 | |||
113 | BIO *cms_CompressedData_init_bio(CMS_ContentInfo *cms) | ||
114 | { | ||
115 | CMS_CompressedData *cd; | ||
116 | ASN1_OBJECT *compoid; | ||
117 | if (OBJ_obj2nid(cms->contentType) != NID_id_smime_ct_compressedData) | ||
118 | { | ||
119 | CMSerr(CMS_F_CMS_COMPRESSEDDATA_INIT_BIO, | ||
120 | CMS_R_CONTENT_TYPE_NOT_COMPRESSED_DATA); | ||
121 | return NULL; | ||
122 | } | ||
123 | cd = cms->d.compressedData; | ||
124 | X509_ALGOR_get0(&compoid, NULL, NULL, cd->compressionAlgorithm); | ||
125 | if (OBJ_obj2nid(compoid) != NID_zlib_compression) | ||
126 | { | ||
127 | CMSerr(CMS_F_CMS_COMPRESSEDDATA_INIT_BIO, | ||
128 | CMS_R_UNSUPPORTED_COMPRESSION_ALGORITHM); | ||
129 | return NULL; | ||
130 | } | ||
131 | return BIO_new(BIO_f_zlib()); | ||
132 | } | ||
133 | |||
134 | #endif | ||
diff --git a/src/lib/libcrypto/cms/cms_dd.c b/src/lib/libcrypto/cms/cms_dd.c new file mode 100644 index 0000000000..8919c15be1 --- /dev/null +++ b/src/lib/libcrypto/cms/cms_dd.c | |||
@@ -0,0 +1,148 @@ | |||
1 | /* crypto/cms/cms_dd.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/asn1t.h> | ||
56 | #include <openssl/pem.h> | ||
57 | #include <openssl/x509v3.h> | ||
58 | #include <openssl/err.h> | ||
59 | #include <openssl/cms.h> | ||
60 | #include "cms_lcl.h" | ||
61 | |||
62 | DECLARE_ASN1_ITEM(CMS_DigestedData) | ||
63 | |||
64 | /* CMS DigestedData Utilities */ | ||
65 | |||
66 | CMS_ContentInfo *cms_DigestedData_create(const EVP_MD *md) | ||
67 | { | ||
68 | CMS_ContentInfo *cms; | ||
69 | CMS_DigestedData *dd; | ||
70 | cms = CMS_ContentInfo_new(); | ||
71 | if (!cms) | ||
72 | return NULL; | ||
73 | |||
74 | dd = M_ASN1_new_of(CMS_DigestedData); | ||
75 | |||
76 | if (!dd) | ||
77 | goto err; | ||
78 | |||
79 | cms->contentType = OBJ_nid2obj(NID_pkcs7_digest); | ||
80 | cms->d.digestedData = dd; | ||
81 | |||
82 | dd->version = 0; | ||
83 | dd->encapContentInfo->eContentType = OBJ_nid2obj(NID_pkcs7_data); | ||
84 | |||
85 | cms_DigestAlgorithm_set(dd->digestAlgorithm, md); | ||
86 | |||
87 | return cms; | ||
88 | |||
89 | err: | ||
90 | |||
91 | if (cms) | ||
92 | CMS_ContentInfo_free(cms); | ||
93 | |||
94 | return NULL; | ||
95 | } | ||
96 | |||
97 | BIO *cms_DigestedData_init_bio(CMS_ContentInfo *cms) | ||
98 | { | ||
99 | CMS_DigestedData *dd; | ||
100 | dd = cms->d.digestedData; | ||
101 | return cms_DigestAlgorithm_init_bio(dd->digestAlgorithm); | ||
102 | } | ||
103 | |||
104 | int cms_DigestedData_do_final(CMS_ContentInfo *cms, BIO *chain, int verify) | ||
105 | { | ||
106 | EVP_MD_CTX mctx; | ||
107 | unsigned char md[EVP_MAX_MD_SIZE]; | ||
108 | unsigned int mdlen; | ||
109 | int r = 0; | ||
110 | CMS_DigestedData *dd; | ||
111 | EVP_MD_CTX_init(&mctx); | ||
112 | |||
113 | dd = cms->d.digestedData; | ||
114 | |||
115 | if (!cms_DigestAlgorithm_find_ctx(&mctx, chain, dd->digestAlgorithm)) | ||
116 | goto err; | ||
117 | |||
118 | if (EVP_DigestFinal_ex(&mctx, md, &mdlen) <= 0) | ||
119 | goto err; | ||
120 | |||
121 | if (verify) | ||
122 | { | ||
123 | if (mdlen != (unsigned int)dd->digest->length) | ||
124 | { | ||
125 | CMSerr(CMS_F_CMS_DIGESTEDDATA_DO_FINAL, | ||
126 | CMS_R_MESSAGEDIGEST_WRONG_LENGTH); | ||
127 | goto err; | ||
128 | } | ||
129 | |||
130 | if (memcmp(md, dd->digest->data, mdlen)) | ||
131 | CMSerr(CMS_F_CMS_DIGESTEDDATA_DO_FINAL, | ||
132 | CMS_R_VERIFICATION_FAILURE); | ||
133 | else | ||
134 | r = 1; | ||
135 | } | ||
136 | else | ||
137 | { | ||
138 | if (!ASN1_STRING_set(dd->digest, md, mdlen)) | ||
139 | goto err; | ||
140 | r = 1; | ||
141 | } | ||
142 | |||
143 | err: | ||
144 | EVP_MD_CTX_cleanup(&mctx); | ||
145 | |||
146 | return r; | ||
147 | |||
148 | } | ||
diff --git a/src/lib/libcrypto/cms/cms_enc.c b/src/lib/libcrypto/cms/cms_enc.c new file mode 100644 index 0000000000..bab26235bd --- /dev/null +++ b/src/lib/libcrypto/cms/cms_enc.c | |||
@@ -0,0 +1,262 @@ | |||
1 | /* crypto/cms/cms_enc.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/asn1t.h> | ||
56 | #include <openssl/pem.h> | ||
57 | #include <openssl/x509v3.h> | ||
58 | #include <openssl/err.h> | ||
59 | #include <openssl/cms.h> | ||
60 | #include <openssl/rand.h> | ||
61 | #include "cms_lcl.h" | ||
62 | |||
63 | /* CMS EncryptedData Utilities */ | ||
64 | |||
65 | DECLARE_ASN1_ITEM(CMS_EncryptedData) | ||
66 | |||
67 | /* Return BIO based on EncryptedContentInfo and key */ | ||
68 | |||
69 | BIO *cms_EncryptedContent_init_bio(CMS_EncryptedContentInfo *ec) | ||
70 | { | ||
71 | BIO *b; | ||
72 | EVP_CIPHER_CTX *ctx; | ||
73 | const EVP_CIPHER *ciph; | ||
74 | X509_ALGOR *calg = ec->contentEncryptionAlgorithm; | ||
75 | unsigned char iv[EVP_MAX_IV_LENGTH], *piv = NULL; | ||
76 | |||
77 | int ok = 0; | ||
78 | |||
79 | int enc, keep_key = 0; | ||
80 | |||
81 | enc = ec->cipher ? 1 : 0; | ||
82 | |||
83 | b = BIO_new(BIO_f_cipher()); | ||
84 | if (!b) | ||
85 | { | ||
86 | CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO, | ||
87 | ERR_R_MALLOC_FAILURE); | ||
88 | return NULL; | ||
89 | } | ||
90 | |||
91 | BIO_get_cipher_ctx(b, &ctx); | ||
92 | |||
93 | if (enc) | ||
94 | { | ||
95 | ciph = ec->cipher; | ||
96 | /* If not keeping key set cipher to NULL so subsequent calls | ||
97 | * decrypt. | ||
98 | */ | ||
99 | if (ec->key) | ||
100 | ec->cipher = NULL; | ||
101 | } | ||
102 | else | ||
103 | { | ||
104 | ciph = EVP_get_cipherbyobj(calg->algorithm); | ||
105 | |||
106 | if (!ciph) | ||
107 | { | ||
108 | CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO, | ||
109 | CMS_R_UNKNOWN_CIPHER); | ||
110 | goto err; | ||
111 | } | ||
112 | } | ||
113 | |||
114 | if (EVP_CipherInit_ex(ctx, ciph, NULL, NULL, NULL, enc) <= 0) | ||
115 | { | ||
116 | CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO, | ||
117 | CMS_R_CIPHER_INITIALISATION_ERROR); | ||
118 | goto err; | ||
119 | } | ||
120 | |||
121 | if (enc) | ||
122 | { | ||
123 | int ivlen; | ||
124 | calg->algorithm = OBJ_nid2obj(EVP_CIPHER_CTX_type(ctx)); | ||
125 | /* Generate a random IV if we need one */ | ||
126 | ivlen = EVP_CIPHER_CTX_iv_length(ctx); | ||
127 | if (ivlen > 0) | ||
128 | { | ||
129 | if (RAND_pseudo_bytes(iv, ivlen) <= 0) | ||
130 | goto err; | ||
131 | piv = iv; | ||
132 | } | ||
133 | } | ||
134 | else if (EVP_CIPHER_asn1_to_param(ctx, calg->parameter) <= 0) | ||
135 | { | ||
136 | CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO, | ||
137 | CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR); | ||
138 | goto err; | ||
139 | } | ||
140 | |||
141 | |||
142 | if (enc && !ec->key) | ||
143 | { | ||
144 | /* Generate random key */ | ||
145 | if (!ec->keylen) | ||
146 | ec->keylen = EVP_CIPHER_CTX_key_length(ctx); | ||
147 | ec->key = OPENSSL_malloc(ec->keylen); | ||
148 | if (!ec->key) | ||
149 | { | ||
150 | CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO, | ||
151 | ERR_R_MALLOC_FAILURE); | ||
152 | goto err; | ||
153 | } | ||
154 | if (EVP_CIPHER_CTX_rand_key(ctx, ec->key) <= 0) | ||
155 | goto err; | ||
156 | keep_key = 1; | ||
157 | } | ||
158 | else if (ec->keylen != (unsigned int)EVP_CIPHER_CTX_key_length(ctx)) | ||
159 | { | ||
160 | /* If necessary set key length */ | ||
161 | if (EVP_CIPHER_CTX_set_key_length(ctx, ec->keylen) <= 0) | ||
162 | { | ||
163 | CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO, | ||
164 | CMS_R_INVALID_KEY_LENGTH); | ||
165 | goto err; | ||
166 | } | ||
167 | } | ||
168 | |||
169 | if (EVP_CipherInit_ex(ctx, NULL, NULL, ec->key, piv, enc) <= 0) | ||
170 | { | ||
171 | CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO, | ||
172 | CMS_R_CIPHER_INITIALISATION_ERROR); | ||
173 | goto err; | ||
174 | } | ||
175 | |||
176 | if (piv) | ||
177 | { | ||
178 | calg->parameter = ASN1_TYPE_new(); | ||
179 | if (!calg->parameter) | ||
180 | { | ||
181 | CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO, | ||
182 | ERR_R_MALLOC_FAILURE); | ||
183 | goto err; | ||
184 | } | ||
185 | if (EVP_CIPHER_param_to_asn1(ctx, calg->parameter) <= 0) | ||
186 | { | ||
187 | CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO, | ||
188 | CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR); | ||
189 | goto err; | ||
190 | } | ||
191 | } | ||
192 | ok = 1; | ||
193 | |||
194 | err: | ||
195 | if (ec->key && !keep_key) | ||
196 | { | ||
197 | OPENSSL_cleanse(ec->key, ec->keylen); | ||
198 | OPENSSL_free(ec->key); | ||
199 | ec->key = NULL; | ||
200 | } | ||
201 | if (ok) | ||
202 | return b; | ||
203 | BIO_free(b); | ||
204 | return NULL; | ||
205 | } | ||
206 | |||
207 | int cms_EncryptedContent_init(CMS_EncryptedContentInfo *ec, | ||
208 | const EVP_CIPHER *cipher, | ||
209 | const unsigned char *key, size_t keylen) | ||
210 | { | ||
211 | ec->cipher = cipher; | ||
212 | if (key) | ||
213 | { | ||
214 | ec->key = OPENSSL_malloc(keylen); | ||
215 | if (!ec->key) | ||
216 | return 0; | ||
217 | memcpy(ec->key, key, keylen); | ||
218 | } | ||
219 | ec->keylen = keylen; | ||
220 | if (cipher) | ||
221 | ec->contentType = OBJ_nid2obj(NID_pkcs7_data); | ||
222 | return 1; | ||
223 | } | ||
224 | |||
225 | int CMS_EncryptedData_set1_key(CMS_ContentInfo *cms, const EVP_CIPHER *ciph, | ||
226 | const unsigned char *key, size_t keylen) | ||
227 | { | ||
228 | CMS_EncryptedContentInfo *ec; | ||
229 | if (!key || !keylen) | ||
230 | { | ||
231 | CMSerr(CMS_F_CMS_ENCRYPTEDDATA_SET1_KEY, CMS_R_NO_KEY); | ||
232 | return 0; | ||
233 | } | ||
234 | if (ciph) | ||
235 | { | ||
236 | cms->d.encryptedData = M_ASN1_new_of(CMS_EncryptedData); | ||
237 | if (!cms->d.encryptedData) | ||
238 | { | ||
239 | CMSerr(CMS_F_CMS_ENCRYPTEDDATA_SET1_KEY, | ||
240 | ERR_R_MALLOC_FAILURE); | ||
241 | return 0; | ||
242 | } | ||
243 | cms->contentType = OBJ_nid2obj(NID_pkcs7_encrypted); | ||
244 | cms->d.encryptedData->version = 0; | ||
245 | } | ||
246 | else if (OBJ_obj2nid(cms->contentType) != NID_pkcs7_encrypted) | ||
247 | { | ||
248 | CMSerr(CMS_F_CMS_ENCRYPTEDDATA_SET1_KEY, | ||
249 | CMS_R_NOT_ENCRYPTED_DATA); | ||
250 | return 0; | ||
251 | } | ||
252 | ec = cms->d.encryptedData->encryptedContentInfo; | ||
253 | return cms_EncryptedContent_init(ec, ciph, key, keylen); | ||
254 | } | ||
255 | |||
256 | BIO *cms_EncryptedData_init_bio(CMS_ContentInfo *cms) | ||
257 | { | ||
258 | CMS_EncryptedData *enc = cms->d.encryptedData; | ||
259 | if (enc->encryptedContentInfo->cipher && enc->unprotectedAttrs) | ||
260 | enc->version = 2; | ||
261 | return cms_EncryptedContent_init_bio(enc->encryptedContentInfo); | ||
262 | } | ||
diff --git a/src/lib/libcrypto/cms/cms_env.c b/src/lib/libcrypto/cms/cms_env.c new file mode 100644 index 0000000000..d499ae85b4 --- /dev/null +++ b/src/lib/libcrypto/cms/cms_env.c | |||
@@ -0,0 +1,825 @@ | |||
1 | /* crypto/cms/cms_env.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/asn1t.h> | ||
56 | #include <openssl/pem.h> | ||
57 | #include <openssl/x509v3.h> | ||
58 | #include <openssl/err.h> | ||
59 | #include <openssl/cms.h> | ||
60 | #include <openssl/rand.h> | ||
61 | #include <openssl/aes.h> | ||
62 | #include "cms_lcl.h" | ||
63 | |||
64 | /* CMS EnvelopedData Utilities */ | ||
65 | |||
66 | DECLARE_ASN1_ITEM(CMS_EnvelopedData) | ||
67 | DECLARE_ASN1_ITEM(CMS_RecipientInfo) | ||
68 | DECLARE_ASN1_ITEM(CMS_KeyTransRecipientInfo) | ||
69 | DECLARE_ASN1_ITEM(CMS_KEKRecipientInfo) | ||
70 | DECLARE_ASN1_ITEM(CMS_OtherKeyAttribute) | ||
71 | |||
72 | DECLARE_STACK_OF(CMS_RecipientInfo) | ||
73 | |||
74 | static CMS_EnvelopedData *cms_get0_enveloped(CMS_ContentInfo *cms) | ||
75 | { | ||
76 | if (OBJ_obj2nid(cms->contentType) != NID_pkcs7_enveloped) | ||
77 | { | ||
78 | CMSerr(CMS_F_CMS_GET0_ENVELOPED, | ||
79 | CMS_R_CONTENT_TYPE_NOT_ENVELOPED_DATA); | ||
80 | return NULL; | ||
81 | } | ||
82 | return cms->d.envelopedData; | ||
83 | } | ||
84 | |||
85 | static CMS_EnvelopedData *cms_enveloped_data_init(CMS_ContentInfo *cms) | ||
86 | { | ||
87 | if (cms->d.other == NULL) | ||
88 | { | ||
89 | cms->d.envelopedData = M_ASN1_new_of(CMS_EnvelopedData); | ||
90 | if (!cms->d.envelopedData) | ||
91 | { | ||
92 | CMSerr(CMS_F_CMS_ENVELOPED_DATA_INIT, | ||
93 | ERR_R_MALLOC_FAILURE); | ||
94 | return NULL; | ||
95 | } | ||
96 | cms->d.envelopedData->version = 0; | ||
97 | cms->d.envelopedData->encryptedContentInfo->contentType = | ||
98 | OBJ_nid2obj(NID_pkcs7_data); | ||
99 | ASN1_OBJECT_free(cms->contentType); | ||
100 | cms->contentType = OBJ_nid2obj(NID_pkcs7_enveloped); | ||
101 | return cms->d.envelopedData; | ||
102 | } | ||
103 | return cms_get0_enveloped(cms); | ||
104 | } | ||
105 | |||
106 | STACK_OF(CMS_RecipientInfo) *CMS_get0_RecipientInfos(CMS_ContentInfo *cms) | ||
107 | { | ||
108 | CMS_EnvelopedData *env; | ||
109 | env = cms_get0_enveloped(cms); | ||
110 | if (!env) | ||
111 | return NULL; | ||
112 | return env->recipientInfos; | ||
113 | } | ||
114 | |||
115 | int CMS_RecipientInfo_type(CMS_RecipientInfo *ri) | ||
116 | { | ||
117 | return ri->type; | ||
118 | } | ||
119 | |||
120 | CMS_ContentInfo *CMS_EnvelopedData_create(const EVP_CIPHER *cipher) | ||
121 | { | ||
122 | CMS_ContentInfo *cms; | ||
123 | CMS_EnvelopedData *env; | ||
124 | cms = CMS_ContentInfo_new(); | ||
125 | if (!cms) | ||
126 | goto merr; | ||
127 | env = cms_enveloped_data_init(cms); | ||
128 | if (!env) | ||
129 | goto merr; | ||
130 | if (!cms_EncryptedContent_init(env->encryptedContentInfo, | ||
131 | cipher, NULL, 0)) | ||
132 | goto merr; | ||
133 | return cms; | ||
134 | merr: | ||
135 | if (cms) | ||
136 | CMS_ContentInfo_free(cms); | ||
137 | CMSerr(CMS_F_CMS_ENVELOPEDDATA_CREATE, ERR_R_MALLOC_FAILURE); | ||
138 | return NULL; | ||
139 | } | ||
140 | |||
141 | /* Key Transport Recipient Info (KTRI) routines */ | ||
142 | |||
143 | /* Add a recipient certificate. For now only handle key transport. | ||
144 | * If we ever handle key agreement will need updating. | ||
145 | */ | ||
146 | |||
147 | CMS_RecipientInfo *CMS_add1_recipient_cert(CMS_ContentInfo *cms, | ||
148 | X509 *recip, unsigned int flags) | ||
149 | { | ||
150 | CMS_RecipientInfo *ri = NULL; | ||
151 | CMS_KeyTransRecipientInfo *ktri; | ||
152 | CMS_EnvelopedData *env; | ||
153 | EVP_PKEY *pk = NULL; | ||
154 | int type; | ||
155 | env = cms_get0_enveloped(cms); | ||
156 | if (!env) | ||
157 | goto err; | ||
158 | |||
159 | /* Initialize recipient info */ | ||
160 | ri = M_ASN1_new_of(CMS_RecipientInfo); | ||
161 | if (!ri) | ||
162 | goto merr; | ||
163 | |||
164 | /* Initialize and add key transport recipient info */ | ||
165 | |||
166 | ri->d.ktri = M_ASN1_new_of(CMS_KeyTransRecipientInfo); | ||
167 | if (!ri->d.ktri) | ||
168 | goto merr; | ||
169 | ri->type = CMS_RECIPINFO_TRANS; | ||
170 | |||
171 | ktri = ri->d.ktri; | ||
172 | |||
173 | X509_check_purpose(recip, -1, -1); | ||
174 | pk = X509_get_pubkey(recip); | ||
175 | if (!pk) | ||
176 | { | ||
177 | CMSerr(CMS_F_CMS_ADD1_RECIPIENT_CERT, | ||
178 | CMS_R_ERROR_GETTING_PUBLIC_KEY); | ||
179 | goto err; | ||
180 | } | ||
181 | CRYPTO_add(&recip->references, 1, CRYPTO_LOCK_X509); | ||
182 | ktri->pkey = pk; | ||
183 | ktri->recip = recip; | ||
184 | |||
185 | if (flags & CMS_USE_KEYID) | ||
186 | { | ||
187 | ktri->version = 2; | ||
188 | type = CMS_RECIPINFO_KEYIDENTIFIER; | ||
189 | } | ||
190 | else | ||
191 | { | ||
192 | ktri->version = 0; | ||
193 | type = CMS_RECIPINFO_ISSUER_SERIAL; | ||
194 | } | ||
195 | |||
196 | /* Not a typo: RecipientIdentifier and SignerIdentifier are the | ||
197 | * same structure. | ||
198 | */ | ||
199 | |||
200 | if (!cms_set1_SignerIdentifier(ktri->rid, recip, type)) | ||
201 | goto err; | ||
202 | |||
203 | /* Since we have no EVP_PKEY_ASN1_METHOD in OpenSSL 0.9.8, | ||
204 | * hard code algorithm parameters. | ||
205 | */ | ||
206 | |||
207 | if (pk->type == EVP_PKEY_RSA) | ||
208 | { | ||
209 | X509_ALGOR_set0(ktri->keyEncryptionAlgorithm, | ||
210 | OBJ_nid2obj(NID_rsaEncryption), | ||
211 | V_ASN1_NULL, 0); | ||
212 | } | ||
213 | else | ||
214 | { | ||
215 | CMSerr(CMS_F_CMS_ADD1_RECIPIENT_CERT, | ||
216 | CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE); | ||
217 | goto err; | ||
218 | } | ||
219 | |||
220 | if (!sk_CMS_RecipientInfo_push(env->recipientInfos, ri)) | ||
221 | goto merr; | ||
222 | |||
223 | return ri; | ||
224 | |||
225 | merr: | ||
226 | CMSerr(CMS_F_CMS_ADD1_RECIPIENT_CERT, ERR_R_MALLOC_FAILURE); | ||
227 | err: | ||
228 | if (ri) | ||
229 | M_ASN1_free_of(ri, CMS_RecipientInfo); | ||
230 | return NULL; | ||
231 | |||
232 | } | ||
233 | |||
234 | int CMS_RecipientInfo_ktri_get0_algs(CMS_RecipientInfo *ri, | ||
235 | EVP_PKEY **pk, X509 **recip, | ||
236 | X509_ALGOR **palg) | ||
237 | { | ||
238 | CMS_KeyTransRecipientInfo *ktri; | ||
239 | if (ri->type != CMS_RECIPINFO_TRANS) | ||
240 | { | ||
241 | CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_GET0_ALGS, | ||
242 | CMS_R_NOT_KEY_TRANSPORT); | ||
243 | return 0; | ||
244 | } | ||
245 | |||
246 | ktri = ri->d.ktri; | ||
247 | |||
248 | if (pk) | ||
249 | *pk = ktri->pkey; | ||
250 | if (recip) | ||
251 | *recip = ktri->recip; | ||
252 | if (palg) | ||
253 | *palg = ktri->keyEncryptionAlgorithm; | ||
254 | return 1; | ||
255 | } | ||
256 | |||
257 | int CMS_RecipientInfo_ktri_get0_signer_id(CMS_RecipientInfo *ri, | ||
258 | ASN1_OCTET_STRING **keyid, | ||
259 | X509_NAME **issuer, ASN1_INTEGER **sno) | ||
260 | { | ||
261 | CMS_KeyTransRecipientInfo *ktri; | ||
262 | if (ri->type != CMS_RECIPINFO_TRANS) | ||
263 | { | ||
264 | CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_GET0_SIGNER_ID, | ||
265 | CMS_R_NOT_KEY_TRANSPORT); | ||
266 | return 0; | ||
267 | } | ||
268 | ktri = ri->d.ktri; | ||
269 | |||
270 | return cms_SignerIdentifier_get0_signer_id(ktri->rid, | ||
271 | keyid, issuer, sno); | ||
272 | } | ||
273 | |||
274 | int CMS_RecipientInfo_ktri_cert_cmp(CMS_RecipientInfo *ri, X509 *cert) | ||
275 | { | ||
276 | if (ri->type != CMS_RECIPINFO_TRANS) | ||
277 | { | ||
278 | CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_CERT_CMP, | ||
279 | CMS_R_NOT_KEY_TRANSPORT); | ||
280 | return -2; | ||
281 | } | ||
282 | return cms_SignerIdentifier_cert_cmp(ri->d.ktri->rid, cert); | ||
283 | } | ||
284 | |||
285 | int CMS_RecipientInfo_set0_pkey(CMS_RecipientInfo *ri, EVP_PKEY *pkey) | ||
286 | { | ||
287 | if (ri->type != CMS_RECIPINFO_TRANS) | ||
288 | { | ||
289 | CMSerr(CMS_F_CMS_RECIPIENTINFO_SET0_PKEY, | ||
290 | CMS_R_NOT_KEY_TRANSPORT); | ||
291 | return 0; | ||
292 | } | ||
293 | ri->d.ktri->pkey = pkey; | ||
294 | return 1; | ||
295 | } | ||
296 | |||
297 | /* Encrypt content key in key transport recipient info */ | ||
298 | |||
299 | static int cms_RecipientInfo_ktri_encrypt(CMS_ContentInfo *cms, | ||
300 | CMS_RecipientInfo *ri) | ||
301 | { | ||
302 | CMS_KeyTransRecipientInfo *ktri; | ||
303 | CMS_EncryptedContentInfo *ec; | ||
304 | unsigned char *ek = NULL; | ||
305 | int eklen; | ||
306 | |||
307 | int ret = 0; | ||
308 | |||
309 | if (ri->type != CMS_RECIPINFO_TRANS) | ||
310 | { | ||
311 | CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_ENCRYPT, | ||
312 | CMS_R_NOT_KEY_TRANSPORT); | ||
313 | return 0; | ||
314 | } | ||
315 | ktri = ri->d.ktri; | ||
316 | ec = cms->d.envelopedData->encryptedContentInfo; | ||
317 | |||
318 | eklen = EVP_PKEY_size(ktri->pkey); | ||
319 | |||
320 | ek = OPENSSL_malloc(eklen); | ||
321 | |||
322 | if (ek == NULL) | ||
323 | { | ||
324 | CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_ENCRYPT, | ||
325 | ERR_R_MALLOC_FAILURE); | ||
326 | goto err; | ||
327 | } | ||
328 | |||
329 | eklen = EVP_PKEY_encrypt(ek, ec->key, ec->keylen, ktri->pkey); | ||
330 | |||
331 | if (eklen <= 0) | ||
332 | goto err; | ||
333 | |||
334 | ASN1_STRING_set0(ktri->encryptedKey, ek, eklen); | ||
335 | ek = NULL; | ||
336 | |||
337 | ret = 1; | ||
338 | |||
339 | err: | ||
340 | if (ek) | ||
341 | OPENSSL_free(ek); | ||
342 | return ret; | ||
343 | |||
344 | } | ||
345 | |||
346 | /* Decrypt content key from KTRI */ | ||
347 | |||
348 | static int cms_RecipientInfo_ktri_decrypt(CMS_ContentInfo *cms, | ||
349 | CMS_RecipientInfo *ri) | ||
350 | { | ||
351 | CMS_KeyTransRecipientInfo *ktri = ri->d.ktri; | ||
352 | unsigned char *ek = NULL; | ||
353 | int eklen; | ||
354 | int ret = 0; | ||
355 | |||
356 | if (ktri->pkey == NULL) | ||
357 | { | ||
358 | CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT, | ||
359 | CMS_R_NO_PRIVATE_KEY); | ||
360 | return 0; | ||
361 | } | ||
362 | |||
363 | eklen = EVP_PKEY_size(ktri->pkey); | ||
364 | |||
365 | ek = OPENSSL_malloc(eklen); | ||
366 | |||
367 | if (ek == NULL) | ||
368 | { | ||
369 | CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT, | ||
370 | ERR_R_MALLOC_FAILURE); | ||
371 | goto err; | ||
372 | } | ||
373 | |||
374 | eklen = EVP_PKEY_decrypt(ek, | ||
375 | ktri->encryptedKey->data, | ||
376 | ktri->encryptedKey->length, ktri->pkey); | ||
377 | if (eklen <= 0) | ||
378 | { | ||
379 | CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT, CMS_R_CMS_LIB); | ||
380 | goto err; | ||
381 | } | ||
382 | |||
383 | ret = 1; | ||
384 | |||
385 | cms->d.envelopedData->encryptedContentInfo->key = ek; | ||
386 | cms->d.envelopedData->encryptedContentInfo->keylen = eklen; | ||
387 | |||
388 | err: | ||
389 | if (!ret && ek) | ||
390 | OPENSSL_free(ek); | ||
391 | |||
392 | return ret; | ||
393 | } | ||
394 | |||
395 | /* Key Encrypted Key (KEK) RecipientInfo routines */ | ||
396 | |||
397 | int CMS_RecipientInfo_kekri_id_cmp(CMS_RecipientInfo *ri, | ||
398 | const unsigned char *id, size_t idlen) | ||
399 | { | ||
400 | ASN1_OCTET_STRING tmp_os; | ||
401 | CMS_KEKRecipientInfo *kekri; | ||
402 | if (ri->type != CMS_RECIPINFO_KEK) | ||
403 | { | ||
404 | CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_ID_CMP, CMS_R_NOT_KEK); | ||
405 | return -2; | ||
406 | } | ||
407 | kekri = ri->d.kekri; | ||
408 | tmp_os.type = V_ASN1_OCTET_STRING; | ||
409 | tmp_os.flags = 0; | ||
410 | tmp_os.data = (unsigned char *)id; | ||
411 | tmp_os.length = (int)idlen; | ||
412 | return ASN1_OCTET_STRING_cmp(&tmp_os, kekri->kekid->keyIdentifier); | ||
413 | } | ||
414 | |||
415 | /* For now hard code AES key wrap info */ | ||
416 | |||
417 | static size_t aes_wrap_keylen(int nid) | ||
418 | { | ||
419 | switch (nid) | ||
420 | { | ||
421 | case NID_id_aes128_wrap: | ||
422 | return 16; | ||
423 | |||
424 | case NID_id_aes192_wrap: | ||
425 | return 24; | ||
426 | |||
427 | case NID_id_aes256_wrap: | ||
428 | return 32; | ||
429 | |||
430 | default: | ||
431 | return 0; | ||
432 | } | ||
433 | } | ||
434 | |||
435 | CMS_RecipientInfo *CMS_add0_recipient_key(CMS_ContentInfo *cms, int nid, | ||
436 | unsigned char *key, size_t keylen, | ||
437 | unsigned char *id, size_t idlen, | ||
438 | ASN1_GENERALIZEDTIME *date, | ||
439 | ASN1_OBJECT *otherTypeId, | ||
440 | ASN1_TYPE *otherType) | ||
441 | { | ||
442 | CMS_RecipientInfo *ri = NULL; | ||
443 | CMS_EnvelopedData *env; | ||
444 | CMS_KEKRecipientInfo *kekri; | ||
445 | env = cms_get0_enveloped(cms); | ||
446 | if (!env) | ||
447 | goto err; | ||
448 | |||
449 | if (nid == NID_undef) | ||
450 | { | ||
451 | switch (keylen) | ||
452 | { | ||
453 | case 16: | ||
454 | nid = NID_id_aes128_wrap; | ||
455 | break; | ||
456 | |||
457 | case 24: | ||
458 | nid = NID_id_aes192_wrap; | ||
459 | break; | ||
460 | |||
461 | case 32: | ||
462 | nid = NID_id_aes256_wrap; | ||
463 | break; | ||
464 | |||
465 | default: | ||
466 | CMSerr(CMS_F_CMS_ADD0_RECIPIENT_KEY, | ||
467 | CMS_R_INVALID_KEY_LENGTH); | ||
468 | goto err; | ||
469 | } | ||
470 | |||
471 | } | ||
472 | else | ||
473 | { | ||
474 | |||
475 | size_t exp_keylen = aes_wrap_keylen(nid); | ||
476 | |||
477 | if (!exp_keylen) | ||
478 | { | ||
479 | CMSerr(CMS_F_CMS_ADD0_RECIPIENT_KEY, | ||
480 | CMS_R_UNSUPPORTED_KEK_ALGORITHM); | ||
481 | goto err; | ||
482 | } | ||
483 | |||
484 | if (keylen != exp_keylen) | ||
485 | { | ||
486 | CMSerr(CMS_F_CMS_ADD0_RECIPIENT_KEY, | ||
487 | CMS_R_INVALID_KEY_LENGTH); | ||
488 | goto err; | ||
489 | } | ||
490 | |||
491 | } | ||
492 | |||
493 | /* Initialize recipient info */ | ||
494 | ri = M_ASN1_new_of(CMS_RecipientInfo); | ||
495 | if (!ri) | ||
496 | goto merr; | ||
497 | |||
498 | ri->d.kekri = M_ASN1_new_of(CMS_KEKRecipientInfo); | ||
499 | if (!ri->d.kekri) | ||
500 | goto merr; | ||
501 | ri->type = CMS_RECIPINFO_KEK; | ||
502 | |||
503 | kekri = ri->d.kekri; | ||
504 | |||
505 | if (otherTypeId) | ||
506 | { | ||
507 | kekri->kekid->other = M_ASN1_new_of(CMS_OtherKeyAttribute); | ||
508 | if (kekri->kekid->other == NULL) | ||
509 | goto merr; | ||
510 | } | ||
511 | |||
512 | if (!sk_CMS_RecipientInfo_push(env->recipientInfos, ri)) | ||
513 | goto merr; | ||
514 | |||
515 | |||
516 | /* After this point no calls can fail */ | ||
517 | |||
518 | kekri->version = 4; | ||
519 | |||
520 | kekri->key = key; | ||
521 | kekri->keylen = keylen; | ||
522 | |||
523 | ASN1_STRING_set0(kekri->kekid->keyIdentifier, id, idlen); | ||
524 | |||
525 | kekri->kekid->date = date; | ||
526 | |||
527 | if (kekri->kekid->other) | ||
528 | { | ||
529 | kekri->kekid->other->keyAttrId = otherTypeId; | ||
530 | kekri->kekid->other->keyAttr = otherType; | ||
531 | } | ||
532 | |||
533 | X509_ALGOR_set0(kekri->keyEncryptionAlgorithm, | ||
534 | OBJ_nid2obj(nid), V_ASN1_UNDEF, NULL); | ||
535 | |||
536 | return ri; | ||
537 | |||
538 | merr: | ||
539 | CMSerr(CMS_F_CMS_ADD0_RECIPIENT_KEY, ERR_R_MALLOC_FAILURE); | ||
540 | err: | ||
541 | if (ri) | ||
542 | M_ASN1_free_of(ri, CMS_RecipientInfo); | ||
543 | return NULL; | ||
544 | |||
545 | } | ||
546 | |||
547 | int CMS_RecipientInfo_kekri_get0_id(CMS_RecipientInfo *ri, | ||
548 | X509_ALGOR **palg, | ||
549 | ASN1_OCTET_STRING **pid, | ||
550 | ASN1_GENERALIZEDTIME **pdate, | ||
551 | ASN1_OBJECT **potherid, | ||
552 | ASN1_TYPE **pothertype) | ||
553 | { | ||
554 | CMS_KEKIdentifier *rkid; | ||
555 | if (ri->type != CMS_RECIPINFO_KEK) | ||
556 | { | ||
557 | CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_GET0_ID, CMS_R_NOT_KEK); | ||
558 | return 0; | ||
559 | } | ||
560 | rkid = ri->d.kekri->kekid; | ||
561 | if (palg) | ||
562 | *palg = ri->d.kekri->keyEncryptionAlgorithm; | ||
563 | if (pid) | ||
564 | *pid = rkid->keyIdentifier; | ||
565 | if (pdate) | ||
566 | *pdate = rkid->date; | ||
567 | if (potherid) | ||
568 | { | ||
569 | if (rkid->other) | ||
570 | *potherid = rkid->other->keyAttrId; | ||
571 | else | ||
572 | *potherid = NULL; | ||
573 | } | ||
574 | if (pothertype) | ||
575 | { | ||
576 | if (rkid->other) | ||
577 | *pothertype = rkid->other->keyAttr; | ||
578 | else | ||
579 | *pothertype = NULL; | ||
580 | } | ||
581 | return 1; | ||
582 | } | ||
583 | |||
584 | int CMS_RecipientInfo_set0_key(CMS_RecipientInfo *ri, | ||
585 | unsigned char *key, size_t keylen) | ||
586 | { | ||
587 | CMS_KEKRecipientInfo *kekri; | ||
588 | if (ri->type != CMS_RECIPINFO_KEK) | ||
589 | { | ||
590 | CMSerr(CMS_F_CMS_RECIPIENTINFO_SET0_KEY, CMS_R_NOT_KEK); | ||
591 | return 0; | ||
592 | } | ||
593 | |||
594 | kekri = ri->d.kekri; | ||
595 | kekri->key = key; | ||
596 | kekri->keylen = keylen; | ||
597 | return 1; | ||
598 | } | ||
599 | |||
600 | |||
601 | /* Encrypt content key in KEK recipient info */ | ||
602 | |||
603 | static int cms_RecipientInfo_kekri_encrypt(CMS_ContentInfo *cms, | ||
604 | CMS_RecipientInfo *ri) | ||
605 | { | ||
606 | CMS_EncryptedContentInfo *ec; | ||
607 | CMS_KEKRecipientInfo *kekri; | ||
608 | AES_KEY actx; | ||
609 | unsigned char *wkey = NULL; | ||
610 | int wkeylen; | ||
611 | int r = 0; | ||
612 | |||
613 | ec = cms->d.envelopedData->encryptedContentInfo; | ||
614 | |||
615 | kekri = ri->d.kekri; | ||
616 | |||
617 | if (!kekri->key) | ||
618 | { | ||
619 | CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_ENCRYPT, CMS_R_NO_KEY); | ||
620 | return 0; | ||
621 | } | ||
622 | |||
623 | if (AES_set_encrypt_key(kekri->key, kekri->keylen << 3, &actx)) | ||
624 | { | ||
625 | CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_ENCRYPT, | ||
626 | CMS_R_ERROR_SETTING_KEY); | ||
627 | goto err; | ||
628 | } | ||
629 | |||
630 | wkey = OPENSSL_malloc(ec->keylen + 8); | ||
631 | |||
632 | if (!wkey) | ||
633 | { | ||
634 | CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_ENCRYPT, | ||
635 | ERR_R_MALLOC_FAILURE); | ||
636 | goto err; | ||
637 | } | ||
638 | |||
639 | wkeylen = AES_wrap_key(&actx, NULL, wkey, ec->key, ec->keylen); | ||
640 | |||
641 | if (wkeylen <= 0) | ||
642 | { | ||
643 | CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_ENCRYPT, CMS_R_WRAP_ERROR); | ||
644 | goto err; | ||
645 | } | ||
646 | |||
647 | ASN1_STRING_set0(kekri->encryptedKey, wkey, wkeylen); | ||
648 | |||
649 | r = 1; | ||
650 | |||
651 | err: | ||
652 | |||
653 | if (!r && wkey) | ||
654 | OPENSSL_free(wkey); | ||
655 | OPENSSL_cleanse(&actx, sizeof(actx)); | ||
656 | |||
657 | return r; | ||
658 | |||
659 | } | ||
660 | |||
661 | /* Decrypt content key in KEK recipient info */ | ||
662 | |||
663 | static int cms_RecipientInfo_kekri_decrypt(CMS_ContentInfo *cms, | ||
664 | CMS_RecipientInfo *ri) | ||
665 | { | ||
666 | CMS_EncryptedContentInfo *ec; | ||
667 | CMS_KEKRecipientInfo *kekri; | ||
668 | AES_KEY actx; | ||
669 | unsigned char *ukey = NULL; | ||
670 | int ukeylen; | ||
671 | int r = 0, wrap_nid; | ||
672 | |||
673 | ec = cms->d.envelopedData->encryptedContentInfo; | ||
674 | |||
675 | kekri = ri->d.kekri; | ||
676 | |||
677 | if (!kekri->key) | ||
678 | { | ||
679 | CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT, CMS_R_NO_KEY); | ||
680 | return 0; | ||
681 | } | ||
682 | |||
683 | wrap_nid = OBJ_obj2nid(kekri->keyEncryptionAlgorithm->algorithm); | ||
684 | if (aes_wrap_keylen(wrap_nid) != kekri->keylen) | ||
685 | { | ||
686 | CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT, | ||
687 | CMS_R_INVALID_KEY_LENGTH); | ||
688 | return 0; | ||
689 | } | ||
690 | |||
691 | /* If encrypted key length is invalid don't bother */ | ||
692 | |||
693 | if (kekri->encryptedKey->length < 16) | ||
694 | { | ||
695 | CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT, | ||
696 | CMS_R_INVALID_ENCRYPTED_KEY_LENGTH); | ||
697 | goto err; | ||
698 | } | ||
699 | |||
700 | if (AES_set_decrypt_key(kekri->key, kekri->keylen << 3, &actx)) | ||
701 | { | ||
702 | CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT, | ||
703 | CMS_R_ERROR_SETTING_KEY); | ||
704 | goto err; | ||
705 | } | ||
706 | |||
707 | ukey = OPENSSL_malloc(kekri->encryptedKey->length - 8); | ||
708 | |||
709 | if (!ukey) | ||
710 | { | ||
711 | CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT, | ||
712 | ERR_R_MALLOC_FAILURE); | ||
713 | goto err; | ||
714 | } | ||
715 | |||
716 | ukeylen = AES_unwrap_key(&actx, NULL, ukey, | ||
717 | kekri->encryptedKey->data, | ||
718 | kekri->encryptedKey->length); | ||
719 | |||
720 | if (ukeylen <= 0) | ||
721 | { | ||
722 | CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT, | ||
723 | CMS_R_UNWRAP_ERROR); | ||
724 | goto err; | ||
725 | } | ||
726 | |||
727 | ec->key = ukey; | ||
728 | ec->keylen = ukeylen; | ||
729 | |||
730 | r = 1; | ||
731 | |||
732 | err: | ||
733 | |||
734 | if (!r && ukey) | ||
735 | OPENSSL_free(ukey); | ||
736 | OPENSSL_cleanse(&actx, sizeof(actx)); | ||
737 | |||
738 | return r; | ||
739 | |||
740 | } | ||
741 | |||
742 | int CMS_RecipientInfo_decrypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri) | ||
743 | { | ||
744 | switch(ri->type) | ||
745 | { | ||
746 | case CMS_RECIPINFO_TRANS: | ||
747 | return cms_RecipientInfo_ktri_decrypt(cms, ri); | ||
748 | |||
749 | case CMS_RECIPINFO_KEK: | ||
750 | return cms_RecipientInfo_kekri_decrypt(cms, ri); | ||
751 | |||
752 | default: | ||
753 | CMSerr(CMS_F_CMS_RECIPIENTINFO_DECRYPT, | ||
754 | CMS_R_UNSUPPORTED_RECPIENTINFO_TYPE); | ||
755 | return 0; | ||
756 | } | ||
757 | } | ||
758 | |||
759 | BIO *cms_EnvelopedData_init_bio(CMS_ContentInfo *cms) | ||
760 | { | ||
761 | CMS_EncryptedContentInfo *ec; | ||
762 | STACK_OF(CMS_RecipientInfo) *rinfos; | ||
763 | CMS_RecipientInfo *ri; | ||
764 | int i, r, ok = 0; | ||
765 | BIO *ret; | ||
766 | |||
767 | /* Get BIO first to set up key */ | ||
768 | |||
769 | ec = cms->d.envelopedData->encryptedContentInfo; | ||
770 | ret = cms_EncryptedContent_init_bio(ec); | ||
771 | |||
772 | /* If error or no cipher end of processing */ | ||
773 | |||
774 | if (!ret || !ec->cipher) | ||
775 | return ret; | ||
776 | |||
777 | /* Now encrypt content key according to each RecipientInfo type */ | ||
778 | |||
779 | rinfos = cms->d.envelopedData->recipientInfos; | ||
780 | |||
781 | for (i = 0; i < sk_CMS_RecipientInfo_num(rinfos); i++) | ||
782 | { | ||
783 | ri = sk_CMS_RecipientInfo_value(rinfos, i); | ||
784 | |||
785 | switch (ri->type) | ||
786 | { | ||
787 | case CMS_RECIPINFO_TRANS: | ||
788 | r = cms_RecipientInfo_ktri_encrypt(cms, ri); | ||
789 | break; | ||
790 | |||
791 | case CMS_RECIPINFO_KEK: | ||
792 | r = cms_RecipientInfo_kekri_encrypt(cms, ri); | ||
793 | break; | ||
794 | |||
795 | default: | ||
796 | CMSerr(CMS_F_CMS_ENVELOPEDDATA_INIT_BIO, | ||
797 | CMS_R_UNSUPPORTED_RECIPIENT_TYPE); | ||
798 | goto err; | ||
799 | } | ||
800 | |||
801 | if (r <= 0) | ||
802 | { | ||
803 | CMSerr(CMS_F_CMS_ENVELOPEDDATA_INIT_BIO, | ||
804 | CMS_R_ERROR_SETTING_RECIPIENTINFO); | ||
805 | goto err; | ||
806 | } | ||
807 | } | ||
808 | |||
809 | ok = 1; | ||
810 | |||
811 | err: | ||
812 | ec->cipher = NULL; | ||
813 | if (ec->key) | ||
814 | { | ||
815 | OPENSSL_cleanse(ec->key, ec->keylen); | ||
816 | OPENSSL_free(ec->key); | ||
817 | ec->key = NULL; | ||
818 | ec->keylen = 0; | ||
819 | } | ||
820 | if (ok) | ||
821 | return ret; | ||
822 | BIO_free(ret); | ||
823 | return NULL; | ||
824 | |||
825 | } | ||
diff --git a/src/lib/libcrypto/cms/cms_err.c b/src/lib/libcrypto/cms/cms_err.c new file mode 100644 index 0000000000..52fa53954f --- /dev/null +++ b/src/lib/libcrypto/cms/cms_err.c | |||
@@ -0,0 +1,236 @@ | |||
1 | /* crypto/cms/cms_err.c */ | ||
2 | /* ==================================================================== | ||
3 | * Copyright (c) 1999-2008 The OpenSSL Project. All rights reserved. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions | ||
7 | * are met: | ||
8 | * | ||
9 | * 1. Redistributions of source code must retain the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer. | ||
11 | * | ||
12 | * 2. Redistributions in binary form must reproduce the above copyright | ||
13 | * notice, this list of conditions and the following disclaimer in | ||
14 | * the documentation and/or other materials provided with the | ||
15 | * distribution. | ||
16 | * | ||
17 | * 3. All advertising materials mentioning features or use of this | ||
18 | * software must display the following acknowledgment: | ||
19 | * "This product includes software developed by the OpenSSL Project | ||
20 | * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" | ||
21 | * | ||
22 | * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to | ||
23 | * endorse or promote products derived from this software without | ||
24 | * prior written permission. For written permission, please contact | ||
25 | * openssl-core@OpenSSL.org. | ||
26 | * | ||
27 | * 5. Products derived from this software may not be called "OpenSSL" | ||
28 | * nor may "OpenSSL" appear in their names without prior written | ||
29 | * permission of the OpenSSL Project. | ||
30 | * | ||
31 | * 6. Redistributions of any form whatsoever must retain the following | ||
32 | * acknowledgment: | ||
33 | * "This product includes software developed by the OpenSSL Project | ||
34 | * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" | ||
35 | * | ||
36 | * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY | ||
37 | * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
38 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | ||
39 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR | ||
40 | * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
41 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
42 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
43 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
44 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
45 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
46 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED | ||
47 | * OF THE POSSIBILITY OF SUCH DAMAGE. | ||
48 | * ==================================================================== | ||
49 | * | ||
50 | * This product includes cryptographic software written by Eric Young | ||
51 | * (eay@cryptsoft.com). This product includes software written by Tim | ||
52 | * Hudson (tjh@cryptsoft.com). | ||
53 | * | ||
54 | */ | ||
55 | |||
56 | /* NOTE: this file was auto generated by the mkerr.pl script: any changes | ||
57 | * made to it will be overwritten when the script next updates this file, | ||
58 | * only reason strings will be preserved. | ||
59 | */ | ||
60 | |||
61 | #include <stdio.h> | ||
62 | #include <openssl/err.h> | ||
63 | #include <openssl/cms.h> | ||
64 | |||
65 | /* BEGIN ERROR CODES */ | ||
66 | #ifndef OPENSSL_NO_ERR | ||
67 | |||
68 | #define ERR_FUNC(func) ERR_PACK(ERR_LIB_CMS,func,0) | ||
69 | #define ERR_REASON(reason) ERR_PACK(ERR_LIB_CMS,0,reason) | ||
70 | |||
71 | static ERR_STRING_DATA CMS_str_functs[]= | ||
72 | { | ||
73 | {ERR_FUNC(CMS_F_CHECK_CONTENT), "CHECK_CONTENT"}, | ||
74 | {ERR_FUNC(CMS_F_CMS_ADD0_CERT), "CMS_add0_cert"}, | ||
75 | {ERR_FUNC(CMS_F_CMS_ADD0_RECIPIENT_KEY), "CMS_add0_recipient_key"}, | ||
76 | {ERR_FUNC(CMS_F_CMS_ADD1_RECEIPTREQUEST), "CMS_add1_ReceiptRequest"}, | ||
77 | {ERR_FUNC(CMS_F_CMS_ADD1_RECIPIENT_CERT), "CMS_add1_recipient_cert"}, | ||
78 | {ERR_FUNC(CMS_F_CMS_ADD1_SIGNER), "CMS_add1_signer"}, | ||
79 | {ERR_FUNC(CMS_F_CMS_ADD1_SIGNINGTIME), "CMS_ADD1_SIGNINGTIME"}, | ||
80 | {ERR_FUNC(CMS_F_CMS_COMPRESS), "CMS_compress"}, | ||
81 | {ERR_FUNC(CMS_F_CMS_COMPRESSEDDATA_CREATE), "cms_CompressedData_create"}, | ||
82 | {ERR_FUNC(CMS_F_CMS_COMPRESSEDDATA_INIT_BIO), "cms_CompressedData_init_bio"}, | ||
83 | {ERR_FUNC(CMS_F_CMS_COPY_CONTENT), "CMS_COPY_CONTENT"}, | ||
84 | {ERR_FUNC(CMS_F_CMS_COPY_MESSAGEDIGEST), "CMS_COPY_MESSAGEDIGEST"}, | ||
85 | {ERR_FUNC(CMS_F_CMS_DATA), "CMS_data"}, | ||
86 | {ERR_FUNC(CMS_F_CMS_DATAFINAL), "CMS_dataFinal"}, | ||
87 | {ERR_FUNC(CMS_F_CMS_DATAINIT), "CMS_dataInit"}, | ||
88 | {ERR_FUNC(CMS_F_CMS_DECRYPT), "CMS_decrypt"}, | ||
89 | {ERR_FUNC(CMS_F_CMS_DECRYPT_SET1_KEY), "CMS_decrypt_set1_key"}, | ||
90 | {ERR_FUNC(CMS_F_CMS_DECRYPT_SET1_PKEY), "CMS_decrypt_set1_pkey"}, | ||
91 | {ERR_FUNC(CMS_F_CMS_DIGESTALGORITHM_FIND_CTX), "cms_DigestAlgorithm_find_ctx"}, | ||
92 | {ERR_FUNC(CMS_F_CMS_DIGESTALGORITHM_INIT_BIO), "cms_DigestAlgorithm_init_bio"}, | ||
93 | {ERR_FUNC(CMS_F_CMS_DIGESTEDDATA_DO_FINAL), "cms_DigestedData_do_final"}, | ||
94 | {ERR_FUNC(CMS_F_CMS_DIGEST_VERIFY), "CMS_digest_verify"}, | ||
95 | {ERR_FUNC(CMS_F_CMS_ENCODE_RECEIPT), "cms_encode_Receipt"}, | ||
96 | {ERR_FUNC(CMS_F_CMS_ENCRYPT), "CMS_encrypt"}, | ||
97 | {ERR_FUNC(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO), "cms_EncryptedContent_init_bio"}, | ||
98 | {ERR_FUNC(CMS_F_CMS_ENCRYPTEDDATA_DECRYPT), "CMS_EncryptedData_decrypt"}, | ||
99 | {ERR_FUNC(CMS_F_CMS_ENCRYPTEDDATA_ENCRYPT), "CMS_EncryptedData_encrypt"}, | ||
100 | {ERR_FUNC(CMS_F_CMS_ENCRYPTEDDATA_SET1_KEY), "CMS_EncryptedData_set1_key"}, | ||
101 | {ERR_FUNC(CMS_F_CMS_ENVELOPEDDATA_CREATE), "CMS_EnvelopedData_create"}, | ||
102 | {ERR_FUNC(CMS_F_CMS_ENVELOPEDDATA_INIT_BIO), "cms_EnvelopedData_init_bio"}, | ||
103 | {ERR_FUNC(CMS_F_CMS_ENVELOPED_DATA_INIT), "CMS_ENVELOPED_DATA_INIT"}, | ||
104 | {ERR_FUNC(CMS_F_CMS_FINAL), "CMS_final"}, | ||
105 | {ERR_FUNC(CMS_F_CMS_GET0_CERTIFICATE_CHOICES), "CMS_GET0_CERTIFICATE_CHOICES"}, | ||
106 | {ERR_FUNC(CMS_F_CMS_GET0_CONTENT), "CMS_get0_content"}, | ||
107 | {ERR_FUNC(CMS_F_CMS_GET0_ECONTENT_TYPE), "CMS_GET0_ECONTENT_TYPE"}, | ||
108 | {ERR_FUNC(CMS_F_CMS_GET0_ENVELOPED), "CMS_GET0_ENVELOPED"}, | ||
109 | {ERR_FUNC(CMS_F_CMS_GET0_REVOCATION_CHOICES), "CMS_GET0_REVOCATION_CHOICES"}, | ||
110 | {ERR_FUNC(CMS_F_CMS_GET0_SIGNED), "CMS_GET0_SIGNED"}, | ||
111 | {ERR_FUNC(CMS_F_CMS_MSGSIGDIGEST_ADD1), "cms_msgSigDigest_add1"}, | ||
112 | {ERR_FUNC(CMS_F_CMS_RECEIPTREQUEST_CREATE0), "CMS_ReceiptRequest_create0"}, | ||
113 | {ERR_FUNC(CMS_F_CMS_RECEIPT_VERIFY), "cms_Receipt_verify"}, | ||
114 | {ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_DECRYPT), "CMS_RecipientInfo_decrypt"}, | ||
115 | {ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT), "CMS_RECIPIENTINFO_KEKRI_DECRYPT"}, | ||
116 | {ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_KEKRI_ENCRYPT), "CMS_RECIPIENTINFO_KEKRI_ENCRYPT"}, | ||
117 | {ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_KEKRI_GET0_ID), "CMS_RecipientInfo_kekri_get0_id"}, | ||
118 | {ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_KEKRI_ID_CMP), "CMS_RecipientInfo_kekri_id_cmp"}, | ||
119 | {ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_KTRI_CERT_CMP), "CMS_RecipientInfo_ktri_cert_cmp"}, | ||
120 | {ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT), "CMS_RECIPIENTINFO_KTRI_DECRYPT"}, | ||
121 | {ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_KTRI_ENCRYPT), "CMS_RECIPIENTINFO_KTRI_ENCRYPT"}, | ||
122 | {ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_KTRI_GET0_ALGS), "CMS_RecipientInfo_ktri_get0_algs"}, | ||
123 | {ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_KTRI_GET0_SIGNER_ID), "CMS_RecipientInfo_ktri_get0_signer_id"}, | ||
124 | {ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_SET0_KEY), "CMS_RecipientInfo_set0_key"}, | ||
125 | {ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_SET0_PKEY), "CMS_RecipientInfo_set0_pkey"}, | ||
126 | {ERR_FUNC(CMS_F_CMS_SET1_SIGNERIDENTIFIER), "cms_set1_SignerIdentifier"}, | ||
127 | {ERR_FUNC(CMS_F_CMS_SET_DETACHED), "CMS_set_detached"}, | ||
128 | {ERR_FUNC(CMS_F_CMS_SIGN), "CMS_sign"}, | ||
129 | {ERR_FUNC(CMS_F_CMS_SIGNED_DATA_INIT), "CMS_SIGNED_DATA_INIT"}, | ||
130 | {ERR_FUNC(CMS_F_CMS_SIGNERINFO_CONTENT_SIGN), "CMS_SIGNERINFO_CONTENT_SIGN"}, | ||
131 | {ERR_FUNC(CMS_F_CMS_SIGNERINFO_SIGN), "CMS_SignerInfo_sign"}, | ||
132 | {ERR_FUNC(CMS_F_CMS_SIGNERINFO_VERIFY), "CMS_SignerInfo_verify"}, | ||
133 | {ERR_FUNC(CMS_F_CMS_SIGNERINFO_VERIFY_CERT), "CMS_SIGNERINFO_VERIFY_CERT"}, | ||
134 | {ERR_FUNC(CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT), "CMS_SignerInfo_verify_content"}, | ||
135 | {ERR_FUNC(CMS_F_CMS_SIGN_RECEIPT), "CMS_sign_receipt"}, | ||
136 | {ERR_FUNC(CMS_F_CMS_STREAM), "CMS_STREAM"}, | ||
137 | {ERR_FUNC(CMS_F_CMS_UNCOMPRESS), "CMS_uncompress"}, | ||
138 | {ERR_FUNC(CMS_F_CMS_VERIFY), "CMS_verify"}, | ||
139 | {0,NULL} | ||
140 | }; | ||
141 | |||
142 | static ERR_STRING_DATA CMS_str_reasons[]= | ||
143 | { | ||
144 | {ERR_REASON(CMS_R_ADD_SIGNER_ERROR) ,"add signer error"}, | ||
145 | {ERR_REASON(CMS_R_CERTIFICATE_ALREADY_PRESENT),"certificate already present"}, | ||
146 | {ERR_REASON(CMS_R_CERTIFICATE_HAS_NO_KEYID),"certificate has no keyid"}, | ||
147 | {ERR_REASON(CMS_R_CERTIFICATE_VERIFY_ERROR),"certificate verify error"}, | ||
148 | {ERR_REASON(CMS_R_CIPHER_INITIALISATION_ERROR),"cipher initialisation error"}, | ||
149 | {ERR_REASON(CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR),"cipher parameter initialisation error"}, | ||
150 | {ERR_REASON(CMS_R_CMS_DATAFINAL_ERROR) ,"cms datafinal error"}, | ||
151 | {ERR_REASON(CMS_R_CMS_LIB) ,"cms lib"}, | ||
152 | {ERR_REASON(CMS_R_CONTENTIDENTIFIER_MISMATCH),"contentidentifier mismatch"}, | ||
153 | {ERR_REASON(CMS_R_CONTENT_NOT_FOUND) ,"content not found"}, | ||
154 | {ERR_REASON(CMS_R_CONTENT_TYPE_MISMATCH) ,"content type mismatch"}, | ||
155 | {ERR_REASON(CMS_R_CONTENT_TYPE_NOT_COMPRESSED_DATA),"content type not compressed data"}, | ||
156 | {ERR_REASON(CMS_R_CONTENT_TYPE_NOT_ENVELOPED_DATA),"content type not enveloped data"}, | ||
157 | {ERR_REASON(CMS_R_CONTENT_TYPE_NOT_SIGNED_DATA),"content type not signed data"}, | ||
158 | {ERR_REASON(CMS_R_CONTENT_VERIFY_ERROR) ,"content verify error"}, | ||
159 | {ERR_REASON(CMS_R_CTRL_ERROR) ,"ctrl error"}, | ||
160 | {ERR_REASON(CMS_R_CTRL_FAILURE) ,"ctrl failure"}, | ||
161 | {ERR_REASON(CMS_R_DECRYPT_ERROR) ,"decrypt error"}, | ||
162 | {ERR_REASON(CMS_R_DIGEST_ERROR) ,"digest error"}, | ||
163 | {ERR_REASON(CMS_R_ERROR_GETTING_PUBLIC_KEY),"error getting public key"}, | ||
164 | {ERR_REASON(CMS_R_ERROR_READING_MESSAGEDIGEST_ATTRIBUTE),"error reading messagedigest attribute"}, | ||
165 | {ERR_REASON(CMS_R_ERROR_SETTING_KEY) ,"error setting key"}, | ||
166 | {ERR_REASON(CMS_R_ERROR_SETTING_RECIPIENTINFO),"error setting recipientinfo"}, | ||
167 | {ERR_REASON(CMS_R_INVALID_ENCRYPTED_KEY_LENGTH),"invalid encrypted key length"}, | ||
168 | {ERR_REASON(CMS_R_INVALID_KEY_LENGTH) ,"invalid key length"}, | ||
169 | {ERR_REASON(CMS_R_MD_BIO_INIT_ERROR) ,"md bio init error"}, | ||
170 | {ERR_REASON(CMS_R_MESSAGEDIGEST_ATTRIBUTE_WRONG_LENGTH),"messagedigest attribute wrong length"}, | ||
171 | {ERR_REASON(CMS_R_MESSAGEDIGEST_WRONG_LENGTH),"messagedigest wrong length"}, | ||
172 | {ERR_REASON(CMS_R_MSGSIGDIGEST_ERROR) ,"msgsigdigest error"}, | ||
173 | {ERR_REASON(CMS_R_MSGSIGDIGEST_VERIFICATION_FAILURE),"msgsigdigest verification failure"}, | ||
174 | {ERR_REASON(CMS_R_MSGSIGDIGEST_WRONG_LENGTH),"msgsigdigest wrong length"}, | ||
175 | {ERR_REASON(CMS_R_NEED_ONE_SIGNER) ,"need one signer"}, | ||
176 | {ERR_REASON(CMS_R_NOT_A_SIGNED_RECEIPT) ,"not a signed receipt"}, | ||
177 | {ERR_REASON(CMS_R_NOT_ENCRYPTED_DATA) ,"not encrypted data"}, | ||
178 | {ERR_REASON(CMS_R_NOT_KEK) ,"not kek"}, | ||
179 | {ERR_REASON(CMS_R_NOT_KEY_TRANSPORT) ,"not key transport"}, | ||
180 | {ERR_REASON(CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE),"not supported for this key type"}, | ||
181 | {ERR_REASON(CMS_R_NO_CIPHER) ,"no cipher"}, | ||
182 | {ERR_REASON(CMS_R_NO_CONTENT) ,"no content"}, | ||
183 | {ERR_REASON(CMS_R_NO_CONTENT_TYPE) ,"no content type"}, | ||
184 | {ERR_REASON(CMS_R_NO_DEFAULT_DIGEST) ,"no default digest"}, | ||
185 | {ERR_REASON(CMS_R_NO_DIGEST_SET) ,"no digest set"}, | ||
186 | {ERR_REASON(CMS_R_NO_KEY) ,"no key"}, | ||
187 | {ERR_REASON(CMS_R_NO_KEY_OR_CERT) ,"no key or cert"}, | ||
188 | {ERR_REASON(CMS_R_NO_MATCHING_DIGEST) ,"no matching digest"}, | ||
189 | {ERR_REASON(CMS_R_NO_MATCHING_RECIPIENT) ,"no matching recipient"}, | ||
190 | {ERR_REASON(CMS_R_NO_MATCHING_SIGNATURE) ,"no matching signature"}, | ||
191 | {ERR_REASON(CMS_R_NO_MSGSIGDIGEST) ,"no msgsigdigest"}, | ||
192 | {ERR_REASON(CMS_R_NO_PRIVATE_KEY) ,"no private key"}, | ||
193 | {ERR_REASON(CMS_R_NO_PUBLIC_KEY) ,"no public key"}, | ||
194 | {ERR_REASON(CMS_R_NO_RECEIPT_REQUEST) ,"no receipt request"}, | ||
195 | {ERR_REASON(CMS_R_NO_SIGNERS) ,"no signers"}, | ||
196 | {ERR_REASON(CMS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE),"private key does not match certificate"}, | ||
197 | {ERR_REASON(CMS_R_RECEIPT_DECODE_ERROR) ,"receipt decode error"}, | ||
198 | {ERR_REASON(CMS_R_RECIPIENT_ERROR) ,"recipient error"}, | ||
199 | {ERR_REASON(CMS_R_SIGNER_CERTIFICATE_NOT_FOUND),"signer certificate not found"}, | ||
200 | {ERR_REASON(CMS_R_SIGNFINAL_ERROR) ,"signfinal error"}, | ||
201 | {ERR_REASON(CMS_R_SMIME_TEXT_ERROR) ,"smime text error"}, | ||
202 | {ERR_REASON(CMS_R_STORE_INIT_ERROR) ,"store init error"}, | ||
203 | {ERR_REASON(CMS_R_TYPE_NOT_COMPRESSED_DATA),"type not compressed data"}, | ||
204 | {ERR_REASON(CMS_R_TYPE_NOT_DATA) ,"type not data"}, | ||
205 | {ERR_REASON(CMS_R_TYPE_NOT_DIGESTED_DATA),"type not digested data"}, | ||
206 | {ERR_REASON(CMS_R_TYPE_NOT_ENCRYPTED_DATA),"type not encrypted data"}, | ||
207 | {ERR_REASON(CMS_R_TYPE_NOT_ENVELOPED_DATA),"type not enveloped data"}, | ||
208 | {ERR_REASON(CMS_R_UNABLE_TO_FINALIZE_CONTEXT),"unable to finalize context"}, | ||
209 | {ERR_REASON(CMS_R_UNKNOWN_CIPHER) ,"unknown cipher"}, | ||
210 | {ERR_REASON(CMS_R_UNKNOWN_DIGEST_ALGORIHM),"unknown digest algorihm"}, | ||
211 | {ERR_REASON(CMS_R_UNKNOWN_ID) ,"unknown id"}, | ||
212 | {ERR_REASON(CMS_R_UNSUPPORTED_COMPRESSION_ALGORITHM),"unsupported compression algorithm"}, | ||
213 | {ERR_REASON(CMS_R_UNSUPPORTED_CONTENT_TYPE),"unsupported content type"}, | ||
214 | {ERR_REASON(CMS_R_UNSUPPORTED_KEK_ALGORITHM),"unsupported kek algorithm"}, | ||
215 | {ERR_REASON(CMS_R_UNSUPPORTED_RECIPIENT_TYPE),"unsupported recipient type"}, | ||
216 | {ERR_REASON(CMS_R_UNSUPPORTED_RECPIENTINFO_TYPE),"unsupported recpientinfo type"}, | ||
217 | {ERR_REASON(CMS_R_UNSUPPORTED_TYPE) ,"unsupported type"}, | ||
218 | {ERR_REASON(CMS_R_UNWRAP_ERROR) ,"unwrap error"}, | ||
219 | {ERR_REASON(CMS_R_VERIFICATION_FAILURE) ,"verification failure"}, | ||
220 | {ERR_REASON(CMS_R_WRAP_ERROR) ,"wrap error"}, | ||
221 | {0,NULL} | ||
222 | }; | ||
223 | |||
224 | #endif | ||
225 | |||
226 | void ERR_load_CMS_strings(void) | ||
227 | { | ||
228 | #ifndef OPENSSL_NO_ERR | ||
229 | |||
230 | if (ERR_func_error_string(CMS_str_functs[0].error) == NULL) | ||
231 | { | ||
232 | ERR_load_strings(0,CMS_str_functs); | ||
233 | ERR_load_strings(0,CMS_str_reasons); | ||
234 | } | ||
235 | #endif | ||
236 | } | ||
diff --git a/src/lib/libcrypto/cms/cms_ess.c b/src/lib/libcrypto/cms/cms_ess.c new file mode 100644 index 0000000000..ed34ff3228 --- /dev/null +++ b/src/lib/libcrypto/cms/cms_ess.c | |||
@@ -0,0 +1,420 @@ | |||
1 | /* crypto/cms/cms_ess.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/asn1t.h> | ||
56 | #include <openssl/pem.h> | ||
57 | #include <openssl/rand.h> | ||
58 | #include <openssl/x509v3.h> | ||
59 | #include <openssl/err.h> | ||
60 | #include <openssl/cms.h> | ||
61 | #include "cms_lcl.h" | ||
62 | |||
63 | DECLARE_ASN1_ITEM(CMS_ReceiptRequest) | ||
64 | DECLARE_ASN1_ITEM(CMS_Receipt) | ||
65 | |||
66 | IMPLEMENT_ASN1_FUNCTIONS_const(CMS_ReceiptRequest) | ||
67 | |||
68 | /* ESS services: for now just Signed Receipt related */ | ||
69 | |||
70 | int CMS_get1_ReceiptRequest(CMS_SignerInfo *si, CMS_ReceiptRequest **prr) | ||
71 | { | ||
72 | ASN1_STRING *str; | ||
73 | CMS_ReceiptRequest *rr = NULL; | ||
74 | if (prr) | ||
75 | *prr = NULL; | ||
76 | str = CMS_signed_get0_data_by_OBJ(si, | ||
77 | OBJ_nid2obj(NID_id_smime_aa_receiptRequest), | ||
78 | -3, V_ASN1_SEQUENCE); | ||
79 | if (!str) | ||
80 | return 0; | ||
81 | |||
82 | rr = ASN1_item_unpack(str, ASN1_ITEM_rptr(CMS_ReceiptRequest)); | ||
83 | if (!rr) | ||
84 | return -1; | ||
85 | if (prr) | ||
86 | *prr = rr; | ||
87 | else | ||
88 | CMS_ReceiptRequest_free(rr); | ||
89 | return 1; | ||
90 | } | ||
91 | |||
92 | CMS_ReceiptRequest *CMS_ReceiptRequest_create0(unsigned char *id, int idlen, | ||
93 | int allorfirst, | ||
94 | STACK_OF(GENERAL_NAMES) *receiptList, | ||
95 | STACK_OF(GENERAL_NAMES) *receiptsTo) | ||
96 | { | ||
97 | CMS_ReceiptRequest *rr = NULL; | ||
98 | |||
99 | rr = CMS_ReceiptRequest_new(); | ||
100 | if (!rr) | ||
101 | goto merr; | ||
102 | if (id) | ||
103 | ASN1_STRING_set0(rr->signedContentIdentifier, id, idlen); | ||
104 | else | ||
105 | { | ||
106 | if (!ASN1_STRING_set(rr->signedContentIdentifier, NULL, 32)) | ||
107 | goto merr; | ||
108 | if (RAND_pseudo_bytes(rr->signedContentIdentifier->data, 32) | ||
109 | <= 0) | ||
110 | goto err; | ||
111 | } | ||
112 | |||
113 | sk_GENERAL_NAMES_pop_free(rr->receiptsTo, GENERAL_NAMES_free); | ||
114 | rr->receiptsTo = receiptsTo; | ||
115 | |||
116 | if (receiptList) | ||
117 | { | ||
118 | rr->receiptsFrom->type = 1; | ||
119 | rr->receiptsFrom->d.receiptList = receiptList; | ||
120 | } | ||
121 | else | ||
122 | { | ||
123 | rr->receiptsFrom->type = 0; | ||
124 | rr->receiptsFrom->d.allOrFirstTier = allorfirst; | ||
125 | } | ||
126 | |||
127 | return rr; | ||
128 | |||
129 | merr: | ||
130 | CMSerr(CMS_F_CMS_RECEIPTREQUEST_CREATE0, ERR_R_MALLOC_FAILURE); | ||
131 | |||
132 | err: | ||
133 | if (rr) | ||
134 | CMS_ReceiptRequest_free(rr); | ||
135 | |||
136 | return NULL; | ||
137 | |||
138 | } | ||
139 | |||
140 | int CMS_add1_ReceiptRequest(CMS_SignerInfo *si, CMS_ReceiptRequest *rr) | ||
141 | { | ||
142 | unsigned char *rrder = NULL; | ||
143 | int rrderlen, r = 0; | ||
144 | |||
145 | rrderlen = i2d_CMS_ReceiptRequest(rr, &rrder); | ||
146 | if (rrderlen < 0) | ||
147 | goto merr; | ||
148 | |||
149 | if (!CMS_signed_add1_attr_by_NID(si, NID_id_smime_aa_receiptRequest, | ||
150 | V_ASN1_SEQUENCE, rrder, rrderlen)) | ||
151 | goto merr; | ||
152 | |||
153 | r = 1; | ||
154 | |||
155 | merr: | ||
156 | if (!r) | ||
157 | CMSerr(CMS_F_CMS_ADD1_RECEIPTREQUEST, ERR_R_MALLOC_FAILURE); | ||
158 | |||
159 | if (rrder) | ||
160 | OPENSSL_free(rrder); | ||
161 | |||
162 | return r; | ||
163 | |||
164 | } | ||
165 | |||
166 | void CMS_ReceiptRequest_get0_values(CMS_ReceiptRequest *rr, | ||
167 | ASN1_STRING **pcid, | ||
168 | int *pallorfirst, | ||
169 | STACK_OF(GENERAL_NAMES) **plist, | ||
170 | STACK_OF(GENERAL_NAMES) **prto) | ||
171 | { | ||
172 | if (pcid) | ||
173 | *pcid = rr->signedContentIdentifier; | ||
174 | if (rr->receiptsFrom->type == 0) | ||
175 | { | ||
176 | if (pallorfirst) | ||
177 | *pallorfirst = (int)rr->receiptsFrom->d.allOrFirstTier; | ||
178 | if (plist) | ||
179 | *plist = NULL; | ||
180 | } | ||
181 | else | ||
182 | { | ||
183 | if (pallorfirst) | ||
184 | *pallorfirst = -1; | ||
185 | if (plist) | ||
186 | *plist = rr->receiptsFrom->d.receiptList; | ||
187 | } | ||
188 | if (prto) | ||
189 | *prto = rr->receiptsTo; | ||
190 | } | ||
191 | |||
192 | /* Digest a SignerInfo structure for msgSigDigest attribute processing */ | ||
193 | |||
194 | static int cms_msgSigDigest(CMS_SignerInfo *si, | ||
195 | unsigned char *dig, unsigned int *diglen) | ||
196 | { | ||
197 | const EVP_MD *md; | ||
198 | md = EVP_get_digestbyobj(si->digestAlgorithm->algorithm); | ||
199 | if (md == NULL) | ||
200 | return 0; | ||
201 | if (!ASN1_item_digest(ASN1_ITEM_rptr(CMS_Attributes_Verify), md, | ||
202 | si->signedAttrs, dig, diglen)) | ||
203 | return 0; | ||
204 | return 1; | ||
205 | } | ||
206 | |||
207 | /* Add a msgSigDigest attribute to a SignerInfo */ | ||
208 | |||
209 | int cms_msgSigDigest_add1(CMS_SignerInfo *dest, CMS_SignerInfo *src) | ||
210 | { | ||
211 | unsigned char dig[EVP_MAX_MD_SIZE]; | ||
212 | unsigned int diglen; | ||
213 | if (!cms_msgSigDigest(src, dig, &diglen)) | ||
214 | { | ||
215 | CMSerr(CMS_F_CMS_MSGSIGDIGEST_ADD1, CMS_R_MSGSIGDIGEST_ERROR); | ||
216 | return 0; | ||
217 | } | ||
218 | if (!CMS_signed_add1_attr_by_NID(dest, NID_id_smime_aa_msgSigDigest, | ||
219 | V_ASN1_OCTET_STRING, dig, diglen)) | ||
220 | { | ||
221 | CMSerr(CMS_F_CMS_MSGSIGDIGEST_ADD1, ERR_R_MALLOC_FAILURE); | ||
222 | return 0; | ||
223 | } | ||
224 | return 1; | ||
225 | } | ||
226 | |||
227 | /* Verify signed receipt after it has already passed normal CMS verify */ | ||
228 | |||
229 | int cms_Receipt_verify(CMS_ContentInfo *cms, CMS_ContentInfo *req_cms) | ||
230 | { | ||
231 | int r = 0, i; | ||
232 | CMS_ReceiptRequest *rr = NULL; | ||
233 | CMS_Receipt *rct = NULL; | ||
234 | STACK_OF(CMS_SignerInfo) *sis, *osis; | ||
235 | CMS_SignerInfo *si, *osi = NULL; | ||
236 | ASN1_OCTET_STRING *msig, **pcont; | ||
237 | ASN1_OBJECT *octype; | ||
238 | unsigned char dig[EVP_MAX_MD_SIZE]; | ||
239 | unsigned int diglen; | ||
240 | |||
241 | /* Get SignerInfos, also checks SignedData content type */ | ||
242 | osis = CMS_get0_SignerInfos(req_cms); | ||
243 | sis = CMS_get0_SignerInfos(cms); | ||
244 | if (!osis || !sis) | ||
245 | goto err; | ||
246 | |||
247 | if (sk_CMS_SignerInfo_num(sis) != 1) | ||
248 | { | ||
249 | CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_NEED_ONE_SIGNER); | ||
250 | goto err; | ||
251 | } | ||
252 | |||
253 | /* Check receipt content type */ | ||
254 | if (OBJ_obj2nid(CMS_get0_eContentType(cms)) != NID_id_smime_ct_receipt) | ||
255 | { | ||
256 | CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_NOT_A_SIGNED_RECEIPT); | ||
257 | goto err; | ||
258 | } | ||
259 | |||
260 | /* Extract and decode receipt content */ | ||
261 | pcont = CMS_get0_content(cms); | ||
262 | if (!pcont || !*pcont) | ||
263 | { | ||
264 | CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_NO_CONTENT); | ||
265 | goto err; | ||
266 | } | ||
267 | |||
268 | rct = ASN1_item_unpack(*pcont, ASN1_ITEM_rptr(CMS_Receipt)); | ||
269 | |||
270 | if (!rct) | ||
271 | { | ||
272 | CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_RECEIPT_DECODE_ERROR); | ||
273 | goto err; | ||
274 | } | ||
275 | |||
276 | /* Locate original request */ | ||
277 | |||
278 | for (i = 0; i < sk_CMS_SignerInfo_num(osis); i++) | ||
279 | { | ||
280 | osi = sk_CMS_SignerInfo_value(osis, i); | ||
281 | if (!ASN1_STRING_cmp(osi->signature, | ||
282 | rct->originatorSignatureValue)) | ||
283 | break; | ||
284 | } | ||
285 | |||
286 | if (i == sk_CMS_SignerInfo_num(osis)) | ||
287 | { | ||
288 | CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_NO_MATCHING_SIGNATURE); | ||
289 | goto err; | ||
290 | } | ||
291 | |||
292 | si = sk_CMS_SignerInfo_value(sis, 0); | ||
293 | |||
294 | /* Get msgSigDigest value and compare */ | ||
295 | |||
296 | msig = CMS_signed_get0_data_by_OBJ(si, | ||
297 | OBJ_nid2obj(NID_id_smime_aa_msgSigDigest), | ||
298 | -3, V_ASN1_OCTET_STRING); | ||
299 | |||
300 | if (!msig) | ||
301 | { | ||
302 | CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_NO_MSGSIGDIGEST); | ||
303 | goto err; | ||
304 | } | ||
305 | |||
306 | if (!cms_msgSigDigest(osi, dig, &diglen)) | ||
307 | { | ||
308 | CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_MSGSIGDIGEST_ERROR); | ||
309 | goto err; | ||
310 | } | ||
311 | |||
312 | if (diglen != (unsigned int)msig->length) | ||
313 | { | ||
314 | CMSerr(CMS_F_CMS_RECEIPT_VERIFY, | ||
315 | CMS_R_MSGSIGDIGEST_WRONG_LENGTH); | ||
316 | goto err; | ||
317 | } | ||
318 | |||
319 | if (memcmp(dig, msig->data, diglen)) | ||
320 | { | ||
321 | CMSerr(CMS_F_CMS_RECEIPT_VERIFY, | ||
322 | CMS_R_MSGSIGDIGEST_VERIFICATION_FAILURE); | ||
323 | goto err; | ||
324 | } | ||
325 | |||
326 | /* Compare content types */ | ||
327 | |||
328 | octype = CMS_signed_get0_data_by_OBJ(osi, | ||
329 | OBJ_nid2obj(NID_pkcs9_contentType), | ||
330 | -3, V_ASN1_OBJECT); | ||
331 | if (!octype) | ||
332 | { | ||
333 | CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_NO_CONTENT_TYPE); | ||
334 | goto err; | ||
335 | } | ||
336 | |||
337 | /* Compare details in receipt request */ | ||
338 | |||
339 | if (OBJ_cmp(octype, rct->contentType)) | ||
340 | { | ||
341 | CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_CONTENT_TYPE_MISMATCH); | ||
342 | goto err; | ||
343 | } | ||
344 | |||
345 | /* Get original receipt request details */ | ||
346 | |||
347 | if (!CMS_get1_ReceiptRequest(osi, &rr)) | ||
348 | { | ||
349 | CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_NO_RECEIPT_REQUEST); | ||
350 | goto err; | ||
351 | } | ||
352 | |||
353 | if (ASN1_STRING_cmp(rr->signedContentIdentifier, | ||
354 | rct->signedContentIdentifier)) | ||
355 | { | ||
356 | CMSerr(CMS_F_CMS_RECEIPT_VERIFY, | ||
357 | CMS_R_CONTENTIDENTIFIER_MISMATCH); | ||
358 | goto err; | ||
359 | } | ||
360 | |||
361 | r = 1; | ||
362 | |||
363 | err: | ||
364 | if (rr) | ||
365 | CMS_ReceiptRequest_free(rr); | ||
366 | if (rct) | ||
367 | M_ASN1_free_of(rct, CMS_Receipt); | ||
368 | |||
369 | return r; | ||
370 | |||
371 | } | ||
372 | |||
373 | /* Encode a Receipt into an OCTET STRING read for including into content of | ||
374 | * a SignedData ContentInfo. | ||
375 | */ | ||
376 | |||
377 | ASN1_OCTET_STRING *cms_encode_Receipt(CMS_SignerInfo *si) | ||
378 | { | ||
379 | CMS_Receipt rct; | ||
380 | CMS_ReceiptRequest *rr = NULL; | ||
381 | ASN1_OBJECT *ctype; | ||
382 | ASN1_OCTET_STRING *os = NULL; | ||
383 | |||
384 | /* Get original receipt request */ | ||
385 | |||
386 | /* Get original receipt request details */ | ||
387 | |||
388 | if (!CMS_get1_ReceiptRequest(si, &rr)) | ||
389 | { | ||
390 | CMSerr(CMS_F_CMS_ENCODE_RECEIPT, CMS_R_NO_RECEIPT_REQUEST); | ||
391 | goto err; | ||
392 | } | ||
393 | |||
394 | /* Get original content type */ | ||
395 | |||
396 | ctype = CMS_signed_get0_data_by_OBJ(si, | ||
397 | OBJ_nid2obj(NID_pkcs9_contentType), | ||
398 | -3, V_ASN1_OBJECT); | ||
399 | if (!ctype) | ||
400 | { | ||
401 | CMSerr(CMS_F_CMS_ENCODE_RECEIPT, CMS_R_NO_CONTENT_TYPE); | ||
402 | goto err; | ||
403 | } | ||
404 | |||
405 | rct.version = 1; | ||
406 | rct.contentType = ctype; | ||
407 | rct.signedContentIdentifier = rr->signedContentIdentifier; | ||
408 | rct.originatorSignatureValue = si->signature; | ||
409 | |||
410 | os = ASN1_item_pack(&rct, ASN1_ITEM_rptr(CMS_Receipt), NULL); | ||
411 | |||
412 | err: | ||
413 | if (rr) | ||
414 | CMS_ReceiptRequest_free(rr); | ||
415 | |||
416 | return os; | ||
417 | |||
418 | } | ||
419 | |||
420 | |||
diff --git a/src/lib/libcrypto/cms/cms_io.c b/src/lib/libcrypto/cms/cms_io.c new file mode 100644 index 0000000000..30f5ddfe6d --- /dev/null +++ b/src/lib/libcrypto/cms/cms_io.c | |||
@@ -0,0 +1,140 @@ | |||
1 | /* crypto/cms/cms_io.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 <openssl/asn1t.h> | ||
55 | #include <openssl/x509.h> | ||
56 | #include <openssl/err.h> | ||
57 | #include <openssl/pem.h> | ||
58 | #include "cms.h" | ||
59 | #include "cms_lcl.h" | ||
60 | |||
61 | CMS_ContentInfo *d2i_CMS_bio(BIO *bp, CMS_ContentInfo **cms) | ||
62 | { | ||
63 | return ASN1_item_d2i_bio(ASN1_ITEM_rptr(CMS_ContentInfo), bp, cms); | ||
64 | } | ||
65 | |||
66 | int i2d_CMS_bio(BIO *bp, CMS_ContentInfo *cms) | ||
67 | { | ||
68 | return ASN1_item_i2d_bio(ASN1_ITEM_rptr(CMS_ContentInfo), bp, cms); | ||
69 | } | ||
70 | |||
71 | IMPLEMENT_PEM_rw_const(CMS, CMS_ContentInfo, PEM_STRING_CMS, CMS_ContentInfo) | ||
72 | |||
73 | /* Callback for int_smime_write_ASN1 */ | ||
74 | |||
75 | static int cms_output_data(BIO *out, BIO *data, ASN1_VALUE *val, int flags, | ||
76 | const ASN1_ITEM *it) | ||
77 | { | ||
78 | CMS_ContentInfo *cms = (CMS_ContentInfo *)val; | ||
79 | BIO *tmpbio, *cmsbio; | ||
80 | int r = 0; | ||
81 | |||
82 | if (!(flags & SMIME_DETACHED)) | ||
83 | { | ||
84 | SMIME_crlf_copy(data, out, flags); | ||
85 | return 1; | ||
86 | } | ||
87 | |||
88 | /* Let CMS code prepend any needed BIOs */ | ||
89 | |||
90 | cmsbio = CMS_dataInit(cms, out); | ||
91 | |||
92 | if (!cmsbio) | ||
93 | return 0; | ||
94 | |||
95 | /* Copy data across, passing through filter BIOs for processing */ | ||
96 | SMIME_crlf_copy(data, cmsbio, flags); | ||
97 | |||
98 | /* Finalize structure */ | ||
99 | if (CMS_dataFinal(cms, cmsbio) <= 0) | ||
100 | goto err; | ||
101 | |||
102 | r = 1; | ||
103 | |||
104 | err: | ||
105 | |||
106 | /* Now remove any digests prepended to the BIO */ | ||
107 | |||
108 | while (cmsbio != out) | ||
109 | { | ||
110 | tmpbio = BIO_pop(cmsbio); | ||
111 | BIO_free(cmsbio); | ||
112 | cmsbio = tmpbio; | ||
113 | } | ||
114 | |||
115 | return 1; | ||
116 | |||
117 | } | ||
118 | |||
119 | |||
120 | int SMIME_write_CMS(BIO *bio, CMS_ContentInfo *cms, BIO *data, int flags) | ||
121 | { | ||
122 | STACK_OF(X509_ALGOR) *mdalgs; | ||
123 | int ctype_nid = OBJ_obj2nid(cms->contentType); | ||
124 | int econt_nid = OBJ_obj2nid(CMS_get0_eContentType(cms)); | ||
125 | if (ctype_nid == NID_pkcs7_signed) | ||
126 | mdalgs = cms->d.signedData->digestAlgorithms; | ||
127 | else | ||
128 | mdalgs = NULL; | ||
129 | |||
130 | return int_smime_write_ASN1(bio, (ASN1_VALUE *)cms, data, flags, | ||
131 | ctype_nid, econt_nid, mdalgs, | ||
132 | cms_output_data, | ||
133 | ASN1_ITEM_rptr(CMS_ContentInfo)); | ||
134 | } | ||
135 | |||
136 | CMS_ContentInfo *SMIME_read_CMS(BIO *bio, BIO **bcont) | ||
137 | { | ||
138 | return (CMS_ContentInfo *)SMIME_read_ASN1(bio, bcont, | ||
139 | ASN1_ITEM_rptr(CMS_ContentInfo)); | ||
140 | } | ||
diff --git a/src/lib/libcrypto/cms/cms_lcl.h b/src/lib/libcrypto/cms/cms_lcl.h new file mode 100644 index 0000000000..7d60fac67e --- /dev/null +++ b/src/lib/libcrypto/cms/cms_lcl.h | |||
@@ -0,0 +1,460 @@ | |||
1 | /* crypto/cms/cms_lcl.h */ | ||
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 | #ifndef HEADER_CMS_LCL_H | ||
55 | #define HEADER_CMS_LCL_H | ||
56 | |||
57 | #ifdef __cplusplus | ||
58 | extern "C" { | ||
59 | #endif | ||
60 | |||
61 | #include <openssl/x509.h> | ||
62 | |||
63 | /* Cryptographic message syntax (CMS) structures: taken | ||
64 | * from RFC3852 | ||
65 | */ | ||
66 | |||
67 | /* Forward references */ | ||
68 | |||
69 | typedef struct CMS_IssuerAndSerialNumber_st CMS_IssuerAndSerialNumber; | ||
70 | typedef struct CMS_EncapsulatedContentInfo_st CMS_EncapsulatedContentInfo; | ||
71 | typedef struct CMS_SignerIdentifier_st CMS_SignerIdentifier; | ||
72 | typedef struct CMS_SignedData_st CMS_SignedData; | ||
73 | typedef struct CMS_OtherRevocationInfoFormat_st CMS_OtherRevocationInfoFormat; | ||
74 | typedef struct CMS_OriginatorInfo_st CMS_OriginatorInfo; | ||
75 | typedef struct CMS_EncryptedContentInfo_st CMS_EncryptedContentInfo; | ||
76 | typedef struct CMS_EnvelopedData_st CMS_EnvelopedData; | ||
77 | typedef struct CMS_DigestedData_st CMS_DigestedData; | ||
78 | typedef struct CMS_EncryptedData_st CMS_EncryptedData; | ||
79 | typedef struct CMS_AuthenticatedData_st CMS_AuthenticatedData; | ||
80 | typedef struct CMS_CompressedData_st CMS_CompressedData; | ||
81 | typedef struct CMS_OtherCertificateFormat_st CMS_OtherCertificateFormat; | ||
82 | typedef struct CMS_KeyTransRecipientInfo_st CMS_KeyTransRecipientInfo; | ||
83 | typedef struct CMS_OriginatorPublicKey_st CMS_OriginatorPublicKey; | ||
84 | typedef struct CMS_OriginatorIdentifierOrKey_st CMS_OriginatorIdentifierOrKey; | ||
85 | typedef struct CMS_KeyAgreeRecipientInfo_st CMS_KeyAgreeRecipientInfo; | ||
86 | typedef struct CMS_OtherKeyAttribute_st CMS_OtherKeyAttribute; | ||
87 | typedef struct CMS_RecipientKeyIdentifier_st CMS_RecipientKeyIdentifier; | ||
88 | typedef struct CMS_KeyAgreeRecipientIdentifier_st CMS_KeyAgreeRecipientIdentifier; | ||
89 | typedef struct CMS_RecipientEncryptedKey_st CMS_RecipientEncryptedKey; | ||
90 | typedef struct CMS_KEKIdentifier_st CMS_KEKIdentifier; | ||
91 | typedef struct CMS_KEKRecipientInfo_st CMS_KEKRecipientInfo; | ||
92 | typedef struct CMS_PasswordRecipientInfo_st CMS_PasswordRecipientInfo; | ||
93 | typedef struct CMS_OtherRecipientInfo_st CMS_OtherRecipientInfo; | ||
94 | typedef struct CMS_ReceiptsFrom_st CMS_ReceiptsFrom; | ||
95 | |||
96 | struct CMS_ContentInfo_st | ||
97 | { | ||
98 | ASN1_OBJECT *contentType; | ||
99 | union { | ||
100 | ASN1_OCTET_STRING *data; | ||
101 | CMS_SignedData *signedData; | ||
102 | CMS_EnvelopedData *envelopedData; | ||
103 | CMS_DigestedData *digestedData; | ||
104 | CMS_EncryptedData *encryptedData; | ||
105 | CMS_AuthenticatedData *authenticatedData; | ||
106 | CMS_CompressedData *compressedData; | ||
107 | ASN1_TYPE *other; | ||
108 | /* Other types ... */ | ||
109 | void *otherData; | ||
110 | } d; | ||
111 | }; | ||
112 | |||
113 | struct CMS_SignedData_st | ||
114 | { | ||
115 | long version; | ||
116 | STACK_OF(X509_ALGOR) *digestAlgorithms; | ||
117 | CMS_EncapsulatedContentInfo *encapContentInfo; | ||
118 | STACK_OF(CMS_CertificateChoices) *certificates; | ||
119 | STACK_OF(CMS_RevocationInfoChoice) *crls; | ||
120 | STACK_OF(CMS_SignerInfo) *signerInfos; | ||
121 | }; | ||
122 | |||
123 | struct CMS_EncapsulatedContentInfo_st | ||
124 | { | ||
125 | ASN1_OBJECT *eContentType; | ||
126 | ASN1_OCTET_STRING *eContent; | ||
127 | /* Set to 1 if incomplete structure only part set up */ | ||
128 | int partial; | ||
129 | }; | ||
130 | |||
131 | struct CMS_SignerInfo_st | ||
132 | { | ||
133 | long version; | ||
134 | CMS_SignerIdentifier *sid; | ||
135 | X509_ALGOR *digestAlgorithm; | ||
136 | STACK_OF(X509_ATTRIBUTE) *signedAttrs; | ||
137 | X509_ALGOR *signatureAlgorithm; | ||
138 | ASN1_OCTET_STRING *signature; | ||
139 | STACK_OF(X509_ATTRIBUTE) *unsignedAttrs; | ||
140 | /* Signing certificate and key */ | ||
141 | X509 *signer; | ||
142 | EVP_PKEY *pkey; | ||
143 | }; | ||
144 | |||
145 | struct CMS_SignerIdentifier_st | ||
146 | { | ||
147 | int type; | ||
148 | union { | ||
149 | CMS_IssuerAndSerialNumber *issuerAndSerialNumber; | ||
150 | ASN1_OCTET_STRING *subjectKeyIdentifier; | ||
151 | } d; | ||
152 | }; | ||
153 | |||
154 | struct CMS_EnvelopedData_st | ||
155 | { | ||
156 | long version; | ||
157 | CMS_OriginatorInfo *originatorInfo; | ||
158 | STACK_OF(CMS_RecipientInfo) *recipientInfos; | ||
159 | CMS_EncryptedContentInfo *encryptedContentInfo; | ||
160 | STACK_OF(X509_ATTRIBUTE) *unprotectedAttrs; | ||
161 | }; | ||
162 | |||
163 | struct CMS_OriginatorInfo_st | ||
164 | { | ||
165 | STACK_OF(CMS_CertificateChoices) *certificates; | ||
166 | STACK_OF(CMS_RevocationInfoChoice) *crls; | ||
167 | }; | ||
168 | |||
169 | struct CMS_EncryptedContentInfo_st | ||
170 | { | ||
171 | ASN1_OBJECT *contentType; | ||
172 | X509_ALGOR *contentEncryptionAlgorithm; | ||
173 | ASN1_OCTET_STRING *encryptedContent; | ||
174 | /* Content encryption algorithm and key */ | ||
175 | const EVP_CIPHER *cipher; | ||
176 | unsigned char *key; | ||
177 | size_t keylen; | ||
178 | }; | ||
179 | |||
180 | struct CMS_RecipientInfo_st | ||
181 | { | ||
182 | int type; | ||
183 | union { | ||
184 | CMS_KeyTransRecipientInfo *ktri; | ||
185 | CMS_KeyAgreeRecipientInfo *kari; | ||
186 | CMS_KEKRecipientInfo *kekri; | ||
187 | CMS_PasswordRecipientInfo *pwri; | ||
188 | CMS_OtherRecipientInfo *ori; | ||
189 | } d; | ||
190 | }; | ||
191 | |||
192 | typedef CMS_SignerIdentifier CMS_RecipientIdentifier; | ||
193 | |||
194 | struct CMS_KeyTransRecipientInfo_st | ||
195 | { | ||
196 | long version; | ||
197 | CMS_RecipientIdentifier *rid; | ||
198 | X509_ALGOR *keyEncryptionAlgorithm; | ||
199 | ASN1_OCTET_STRING *encryptedKey; | ||
200 | /* Recipient Key and cert */ | ||
201 | X509 *recip; | ||
202 | EVP_PKEY *pkey; | ||
203 | }; | ||
204 | |||
205 | struct CMS_KeyAgreeRecipientInfo_st | ||
206 | { | ||
207 | long version; | ||
208 | CMS_OriginatorIdentifierOrKey *originator; | ||
209 | ASN1_OCTET_STRING *ukm; | ||
210 | X509_ALGOR *keyEncryptionAlgorithm; | ||
211 | STACK_OF(CMS_RecipientEncryptedKey) *recipientEncryptedKeys; | ||
212 | }; | ||
213 | |||
214 | struct CMS_OriginatorIdentifierOrKey_st | ||
215 | { | ||
216 | int type; | ||
217 | union { | ||
218 | CMS_IssuerAndSerialNumber *issuerAndSerialNumber; | ||
219 | ASN1_OCTET_STRING *subjectKeyIdentifier; | ||
220 | CMS_OriginatorPublicKey *originatorKey; | ||
221 | } d; | ||
222 | }; | ||
223 | |||
224 | struct CMS_OriginatorPublicKey_st | ||
225 | { | ||
226 | X509_ALGOR *algorithm; | ||
227 | ASN1_BIT_STRING *publicKey; | ||
228 | }; | ||
229 | |||
230 | struct CMS_RecipientEncryptedKey_st | ||
231 | { | ||
232 | CMS_KeyAgreeRecipientIdentifier *rid; | ||
233 | ASN1_OCTET_STRING *encryptedKey; | ||
234 | }; | ||
235 | |||
236 | struct CMS_KeyAgreeRecipientIdentifier_st | ||
237 | { | ||
238 | int type; | ||
239 | union { | ||
240 | CMS_IssuerAndSerialNumber *issuerAndSerialNumber; | ||
241 | CMS_RecipientKeyIdentifier *rKeyId; | ||
242 | } d; | ||
243 | }; | ||
244 | |||
245 | struct CMS_RecipientKeyIdentifier_st | ||
246 | { | ||
247 | ASN1_OCTET_STRING *subjectKeyIdentifier; | ||
248 | ASN1_GENERALIZEDTIME *date; | ||
249 | CMS_OtherKeyAttribute *other; | ||
250 | }; | ||
251 | |||
252 | struct CMS_KEKRecipientInfo_st | ||
253 | { | ||
254 | long version; | ||
255 | CMS_KEKIdentifier *kekid; | ||
256 | X509_ALGOR *keyEncryptionAlgorithm; | ||
257 | ASN1_OCTET_STRING *encryptedKey; | ||
258 | /* Extra info: symmetric key to use */ | ||
259 | unsigned char *key; | ||
260 | size_t keylen; | ||
261 | }; | ||
262 | |||
263 | struct CMS_KEKIdentifier_st | ||
264 | { | ||
265 | ASN1_OCTET_STRING *keyIdentifier; | ||
266 | ASN1_GENERALIZEDTIME *date; | ||
267 | CMS_OtherKeyAttribute *other; | ||
268 | }; | ||
269 | |||
270 | struct CMS_PasswordRecipientInfo_st | ||
271 | { | ||
272 | long version; | ||
273 | X509_ALGOR *keyDerivationAlgorithm; | ||
274 | X509_ALGOR *keyEncryptionAlgorithm; | ||
275 | ASN1_OCTET_STRING *encryptedKey; | ||
276 | }; | ||
277 | |||
278 | struct CMS_OtherRecipientInfo_st | ||
279 | { | ||
280 | ASN1_OBJECT *oriType; | ||
281 | ASN1_TYPE *oriValue; | ||
282 | }; | ||
283 | |||
284 | struct CMS_DigestedData_st | ||
285 | { | ||
286 | long version; | ||
287 | X509_ALGOR *digestAlgorithm; | ||
288 | CMS_EncapsulatedContentInfo *encapContentInfo; | ||
289 | ASN1_OCTET_STRING *digest; | ||
290 | }; | ||
291 | |||
292 | struct CMS_EncryptedData_st | ||
293 | { | ||
294 | long version; | ||
295 | CMS_EncryptedContentInfo *encryptedContentInfo; | ||
296 | STACK_OF(X509_ATTRIBUTE) *unprotectedAttrs; | ||
297 | }; | ||
298 | |||
299 | struct CMS_AuthenticatedData_st | ||
300 | { | ||
301 | long version; | ||
302 | CMS_OriginatorInfo *originatorInfo; | ||
303 | STACK_OF(CMS_RecipientInfo) *recipientInfos; | ||
304 | X509_ALGOR *macAlgorithm; | ||
305 | X509_ALGOR *digestAlgorithm; | ||
306 | CMS_EncapsulatedContentInfo *encapContentInfo; | ||
307 | STACK_OF(X509_ATTRIBUTE) *authAttrs; | ||
308 | ASN1_OCTET_STRING *mac; | ||
309 | STACK_OF(X509_ATTRIBUTE) *unauthAttrs; | ||
310 | }; | ||
311 | |||
312 | struct CMS_CompressedData_st | ||
313 | { | ||
314 | long version; | ||
315 | X509_ALGOR *compressionAlgorithm; | ||
316 | STACK_OF(CMS_RecipientInfo) *recipientInfos; | ||
317 | CMS_EncapsulatedContentInfo *encapContentInfo; | ||
318 | }; | ||
319 | |||
320 | struct CMS_RevocationInfoChoice_st | ||
321 | { | ||
322 | int type; | ||
323 | union { | ||
324 | X509_CRL *crl; | ||
325 | CMS_OtherRevocationInfoFormat *other; | ||
326 | } d; | ||
327 | }; | ||
328 | |||
329 | #define CMS_REVCHOICE_CRL 0 | ||
330 | #define CMS_REVCHOICE_OTHER 1 | ||
331 | |||
332 | struct CMS_OtherRevocationInfoFormat_st | ||
333 | { | ||
334 | ASN1_OBJECT *otherRevInfoFormat; | ||
335 | ASN1_TYPE *otherRevInfo; | ||
336 | }; | ||
337 | |||
338 | struct CMS_CertificateChoices | ||
339 | { | ||
340 | int type; | ||
341 | union { | ||
342 | X509 *certificate; | ||
343 | ASN1_STRING *extendedCertificate; /* Obsolete */ | ||
344 | ASN1_STRING *v1AttrCert; /* Left encoded for now */ | ||
345 | ASN1_STRING *v2AttrCert; /* Left encoded for now */ | ||
346 | CMS_OtherCertificateFormat *other; | ||
347 | } d; | ||
348 | }; | ||
349 | |||
350 | #define CMS_CERTCHOICE_CERT 0 | ||
351 | #define CMS_CERTCHOICE_EXCERT 1 | ||
352 | #define CMS_CERTCHOICE_V1ACERT 2 | ||
353 | #define CMS_CERTCHOICE_V2ACERT 3 | ||
354 | #define CMS_CERTCHOICE_OTHER 4 | ||
355 | |||
356 | struct CMS_OtherCertificateFormat_st | ||
357 | { | ||
358 | ASN1_OBJECT *otherCertFormat; | ||
359 | ASN1_TYPE *otherCert; | ||
360 | }; | ||
361 | |||
362 | /* This is also defined in pkcs7.h but we duplicate it | ||
363 | * to allow the CMS code to be independent of PKCS#7 | ||
364 | */ | ||
365 | |||
366 | struct CMS_IssuerAndSerialNumber_st | ||
367 | { | ||
368 | X509_NAME *issuer; | ||
369 | ASN1_INTEGER *serialNumber; | ||
370 | }; | ||
371 | |||
372 | struct CMS_OtherKeyAttribute_st | ||
373 | { | ||
374 | ASN1_OBJECT *keyAttrId; | ||
375 | ASN1_TYPE *keyAttr; | ||
376 | }; | ||
377 | |||
378 | /* ESS structures */ | ||
379 | |||
380 | #ifdef HEADER_X509V3_H | ||
381 | |||
382 | struct CMS_ReceiptRequest_st | ||
383 | { | ||
384 | ASN1_OCTET_STRING *signedContentIdentifier; | ||
385 | CMS_ReceiptsFrom *receiptsFrom; | ||
386 | STACK_OF(GENERAL_NAMES) *receiptsTo; | ||
387 | }; | ||
388 | |||
389 | |||
390 | struct CMS_ReceiptsFrom_st | ||
391 | { | ||
392 | int type; | ||
393 | union | ||
394 | { | ||
395 | long allOrFirstTier; | ||
396 | STACK_OF(GENERAL_NAMES) *receiptList; | ||
397 | } d; | ||
398 | }; | ||
399 | #endif | ||
400 | |||
401 | struct CMS_Receipt_st | ||
402 | { | ||
403 | long version; | ||
404 | ASN1_OBJECT *contentType; | ||
405 | ASN1_OCTET_STRING *signedContentIdentifier; | ||
406 | ASN1_OCTET_STRING *originatorSignatureValue; | ||
407 | }; | ||
408 | |||
409 | DECLARE_ASN1_ITEM(CMS_SignerInfo) | ||
410 | DECLARE_ASN1_ITEM(CMS_IssuerAndSerialNumber) | ||
411 | DECLARE_ASN1_ITEM(CMS_Attributes_Sign) | ||
412 | DECLARE_ASN1_ITEM(CMS_Attributes_Verify) | ||
413 | DECLARE_ASN1_ALLOC_FUNCTIONS(CMS_IssuerAndSerialNumber) | ||
414 | |||
415 | #define CMS_SIGNERINFO_ISSUER_SERIAL 0 | ||
416 | #define CMS_SIGNERINFO_KEYIDENTIFIER 1 | ||
417 | |||
418 | #define CMS_RECIPINFO_ISSUER_SERIAL 0 | ||
419 | #define CMS_RECIPINFO_KEYIDENTIFIER 1 | ||
420 | |||
421 | BIO *cms_content_bio(CMS_ContentInfo *cms); | ||
422 | |||
423 | CMS_ContentInfo *cms_Data_create(void); | ||
424 | |||
425 | CMS_ContentInfo *cms_DigestedData_create(const EVP_MD *md); | ||
426 | BIO *cms_DigestedData_init_bio(CMS_ContentInfo *cms); | ||
427 | int cms_DigestedData_do_final(CMS_ContentInfo *cms, BIO *chain, int verify); | ||
428 | |||
429 | BIO *cms_SignedData_init_bio(CMS_ContentInfo *cms); | ||
430 | int cms_SignedData_final(CMS_ContentInfo *cms, BIO *chain); | ||
431 | int cms_set1_SignerIdentifier(CMS_SignerIdentifier *sid, X509 *cert, int type); | ||
432 | int cms_SignerIdentifier_get0_signer_id(CMS_SignerIdentifier *sid, | ||
433 | ASN1_OCTET_STRING **keyid, | ||
434 | X509_NAME **issuer, ASN1_INTEGER **sno); | ||
435 | int cms_SignerIdentifier_cert_cmp(CMS_SignerIdentifier *sid, X509 *cert); | ||
436 | |||
437 | CMS_ContentInfo *cms_CompressedData_create(int comp_nid); | ||
438 | BIO *cms_CompressedData_init_bio(CMS_ContentInfo *cms); | ||
439 | |||
440 | void cms_DigestAlgorithm_set(X509_ALGOR *alg, const EVP_MD *md); | ||
441 | BIO *cms_DigestAlgorithm_init_bio(X509_ALGOR *digestAlgorithm); | ||
442 | int cms_DigestAlgorithm_find_ctx(EVP_MD_CTX *mctx, BIO *chain, | ||
443 | X509_ALGOR *mdalg); | ||
444 | |||
445 | BIO *cms_EncryptedContent_init_bio(CMS_EncryptedContentInfo *ec); | ||
446 | BIO *cms_EncryptedData_init_bio(CMS_ContentInfo *cms); | ||
447 | int cms_EncryptedContent_init(CMS_EncryptedContentInfo *ec, | ||
448 | const EVP_CIPHER *cipher, | ||
449 | const unsigned char *key, size_t keylen); | ||
450 | |||
451 | int cms_Receipt_verify(CMS_ContentInfo *cms, CMS_ContentInfo *req_cms); | ||
452 | int cms_msgSigDigest_add1(CMS_SignerInfo *dest, CMS_SignerInfo *src); | ||
453 | ASN1_OCTET_STRING *cms_encode_Receipt(CMS_SignerInfo *si); | ||
454 | |||
455 | BIO *cms_EnvelopedData_init_bio(CMS_ContentInfo *cms); | ||
456 | |||
457 | #ifdef __cplusplus | ||
458 | } | ||
459 | #endif | ||
460 | #endif | ||
diff --git a/src/lib/libcrypto/cms/cms_lib.c b/src/lib/libcrypto/cms/cms_lib.c new file mode 100644 index 0000000000..8e6c1d29a5 --- /dev/null +++ b/src/lib/libcrypto/cms/cms_lib.c | |||
@@ -0,0 +1,623 @@ | |||
1 | /* crypto/cms/cms_lib.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 <openssl/asn1t.h> | ||
55 | #include <openssl/x509.h> | ||
56 | #include <openssl/err.h> | ||
57 | #include <openssl/pem.h> | ||
58 | #include <openssl/bio.h> | ||
59 | #include <openssl/asn1.h> | ||
60 | #include "cms.h" | ||
61 | #include "cms_lcl.h" | ||
62 | |||
63 | IMPLEMENT_ASN1_FUNCTIONS_const(CMS_ContentInfo) | ||
64 | |||
65 | DECLARE_ASN1_ITEM(CMS_CertificateChoices) | ||
66 | DECLARE_ASN1_ITEM(CMS_RevocationInfoChoice) | ||
67 | DECLARE_STACK_OF(CMS_CertificateChoices) | ||
68 | DECLARE_STACK_OF(CMS_RevocationInfoChoice) | ||
69 | |||
70 | const ASN1_OBJECT *CMS_get0_type(CMS_ContentInfo *cms) | ||
71 | { | ||
72 | return cms->contentType; | ||
73 | } | ||
74 | |||
75 | CMS_ContentInfo *cms_Data_create(void) | ||
76 | { | ||
77 | CMS_ContentInfo *cms; | ||
78 | cms = CMS_ContentInfo_new(); | ||
79 | if (cms) | ||
80 | { | ||
81 | cms->contentType = OBJ_nid2obj(NID_pkcs7_data); | ||
82 | /* Never detached */ | ||
83 | CMS_set_detached(cms, 0); | ||
84 | } | ||
85 | return cms; | ||
86 | } | ||
87 | |||
88 | BIO *cms_content_bio(CMS_ContentInfo *cms) | ||
89 | { | ||
90 | ASN1_OCTET_STRING **pos = CMS_get0_content(cms); | ||
91 | if (!pos) | ||
92 | return NULL; | ||
93 | /* If content detached data goes nowhere: create NULL BIO */ | ||
94 | if (!*pos) | ||
95 | return BIO_new(BIO_s_null()); | ||
96 | /* If content not detached and created return memory BIO | ||
97 | */ | ||
98 | if (!*pos || ((*pos)->flags == ASN1_STRING_FLAG_CONT)) | ||
99 | return BIO_new(BIO_s_mem()); | ||
100 | /* Else content was read in: return read only BIO for it */ | ||
101 | return BIO_new_mem_buf((*pos)->data, (*pos)->length); | ||
102 | } | ||
103 | |||
104 | BIO *CMS_dataInit(CMS_ContentInfo *cms, BIO *icont) | ||
105 | { | ||
106 | BIO *cmsbio, *cont; | ||
107 | if (icont) | ||
108 | cont = icont; | ||
109 | else | ||
110 | cont = cms_content_bio(cms); | ||
111 | if (!cont) | ||
112 | { | ||
113 | CMSerr(CMS_F_CMS_DATAINIT, CMS_R_NO_CONTENT); | ||
114 | return NULL; | ||
115 | } | ||
116 | switch (OBJ_obj2nid(cms->contentType)) | ||
117 | { | ||
118 | |||
119 | case NID_pkcs7_data: | ||
120 | return cont; | ||
121 | |||
122 | case NID_pkcs7_signed: | ||
123 | cmsbio = cms_SignedData_init_bio(cms); | ||
124 | break; | ||
125 | |||
126 | case NID_pkcs7_digest: | ||
127 | cmsbio = cms_DigestedData_init_bio(cms); | ||
128 | break; | ||
129 | #ifdef ZLIB | ||
130 | case NID_id_smime_ct_compressedData: | ||
131 | cmsbio = cms_CompressedData_init_bio(cms); | ||
132 | break; | ||
133 | #endif | ||
134 | |||
135 | case NID_pkcs7_encrypted: | ||
136 | cmsbio = cms_EncryptedData_init_bio(cms); | ||
137 | break; | ||
138 | |||
139 | case NID_pkcs7_enveloped: | ||
140 | cmsbio = cms_EnvelopedData_init_bio(cms); | ||
141 | break; | ||
142 | |||
143 | default: | ||
144 | CMSerr(CMS_F_CMS_DATAINIT, CMS_R_UNSUPPORTED_TYPE); | ||
145 | return NULL; | ||
146 | } | ||
147 | |||
148 | if (cmsbio) | ||
149 | return BIO_push(cmsbio, cont); | ||
150 | |||
151 | if (!icont) | ||
152 | BIO_free(cont); | ||
153 | return NULL; | ||
154 | |||
155 | } | ||
156 | |||
157 | int CMS_dataFinal(CMS_ContentInfo *cms, BIO *cmsbio) | ||
158 | { | ||
159 | ASN1_OCTET_STRING **pos = CMS_get0_content(cms); | ||
160 | if (!pos) | ||
161 | return 0; | ||
162 | /* If ebmedded content find memory BIO and set content */ | ||
163 | if (*pos && ((*pos)->flags & ASN1_STRING_FLAG_CONT)) | ||
164 | { | ||
165 | BIO *mbio; | ||
166 | unsigned char *cont; | ||
167 | long contlen; | ||
168 | mbio = BIO_find_type(cmsbio, BIO_TYPE_MEM); | ||
169 | if (!mbio) | ||
170 | { | ||
171 | CMSerr(CMS_F_CMS_DATAFINAL, CMS_R_CONTENT_NOT_FOUND); | ||
172 | return 0; | ||
173 | } | ||
174 | contlen = BIO_get_mem_data(mbio, &cont); | ||
175 | /* Set bio as read only so its content can't be clobbered */ | ||
176 | BIO_set_flags(mbio, BIO_FLAGS_MEM_RDONLY); | ||
177 | BIO_set_mem_eof_return(mbio, 0); | ||
178 | ASN1_STRING_set0(*pos, cont, contlen); | ||
179 | (*pos)->flags &= ~ASN1_STRING_FLAG_CONT; | ||
180 | } | ||
181 | |||
182 | switch (OBJ_obj2nid(cms->contentType)) | ||
183 | { | ||
184 | |||
185 | case NID_pkcs7_data: | ||
186 | case NID_pkcs7_enveloped: | ||
187 | case NID_pkcs7_encrypted: | ||
188 | case NID_id_smime_ct_compressedData: | ||
189 | /* Nothing to do */ | ||
190 | return 1; | ||
191 | |||
192 | case NID_pkcs7_signed: | ||
193 | return cms_SignedData_final(cms, cmsbio); | ||
194 | |||
195 | case NID_pkcs7_digest: | ||
196 | return cms_DigestedData_do_final(cms, cmsbio, 0); | ||
197 | |||
198 | default: | ||
199 | CMSerr(CMS_F_CMS_DATAFINAL, CMS_R_UNSUPPORTED_TYPE); | ||
200 | return 0; | ||
201 | } | ||
202 | } | ||
203 | |||
204 | /* Return an OCTET STRING pointer to content. This allows it to | ||
205 | * be accessed or set later. | ||
206 | */ | ||
207 | |||
208 | ASN1_OCTET_STRING **CMS_get0_content(CMS_ContentInfo *cms) | ||
209 | { | ||
210 | switch (OBJ_obj2nid(cms->contentType)) | ||
211 | { | ||
212 | |||
213 | case NID_pkcs7_data: | ||
214 | return &cms->d.data; | ||
215 | |||
216 | case NID_pkcs7_signed: | ||
217 | return &cms->d.signedData->encapContentInfo->eContent; | ||
218 | |||
219 | case NID_pkcs7_enveloped: | ||
220 | return &cms->d.envelopedData->encryptedContentInfo->encryptedContent; | ||
221 | |||
222 | case NID_pkcs7_digest: | ||
223 | return &cms->d.digestedData->encapContentInfo->eContent; | ||
224 | |||
225 | case NID_pkcs7_encrypted: | ||
226 | return &cms->d.encryptedData->encryptedContentInfo->encryptedContent; | ||
227 | |||
228 | case NID_id_smime_ct_authData: | ||
229 | return &cms->d.authenticatedData->encapContentInfo->eContent; | ||
230 | |||
231 | case NID_id_smime_ct_compressedData: | ||
232 | return &cms->d.compressedData->encapContentInfo->eContent; | ||
233 | |||
234 | default: | ||
235 | if (cms->d.other->type == V_ASN1_OCTET_STRING) | ||
236 | return &cms->d.other->value.octet_string; | ||
237 | CMSerr(CMS_F_CMS_GET0_CONTENT, CMS_R_UNSUPPORTED_CONTENT_TYPE); | ||
238 | return NULL; | ||
239 | |||
240 | } | ||
241 | } | ||
242 | |||
243 | /* Return an ASN1_OBJECT pointer to content type. This allows it to | ||
244 | * be accessed or set later. | ||
245 | */ | ||
246 | |||
247 | static ASN1_OBJECT **cms_get0_econtent_type(CMS_ContentInfo *cms) | ||
248 | { | ||
249 | switch (OBJ_obj2nid(cms->contentType)) | ||
250 | { | ||
251 | |||
252 | case NID_pkcs7_signed: | ||
253 | return &cms->d.signedData->encapContentInfo->eContentType; | ||
254 | |||
255 | case NID_pkcs7_enveloped: | ||
256 | return &cms->d.envelopedData->encryptedContentInfo->contentType; | ||
257 | |||
258 | case NID_pkcs7_digest: | ||
259 | return &cms->d.digestedData->encapContentInfo->eContentType; | ||
260 | |||
261 | case NID_pkcs7_encrypted: | ||
262 | return &cms->d.encryptedData->encryptedContentInfo->contentType; | ||
263 | |||
264 | case NID_id_smime_ct_authData: | ||
265 | return &cms->d.authenticatedData->encapContentInfo->eContentType; | ||
266 | |||
267 | case NID_id_smime_ct_compressedData: | ||
268 | return &cms->d.compressedData->encapContentInfo->eContentType; | ||
269 | |||
270 | default: | ||
271 | CMSerr(CMS_F_CMS_GET0_ECONTENT_TYPE, | ||
272 | CMS_R_UNSUPPORTED_CONTENT_TYPE); | ||
273 | return NULL; | ||
274 | |||
275 | } | ||
276 | } | ||
277 | |||
278 | const ASN1_OBJECT *CMS_get0_eContentType(CMS_ContentInfo *cms) | ||
279 | { | ||
280 | ASN1_OBJECT **petype; | ||
281 | petype = cms_get0_econtent_type(cms); | ||
282 | if (petype) | ||
283 | return *petype; | ||
284 | return NULL; | ||
285 | } | ||
286 | |||
287 | int CMS_set1_eContentType(CMS_ContentInfo *cms, const ASN1_OBJECT *oid) | ||
288 | { | ||
289 | ASN1_OBJECT **petype, *etype; | ||
290 | petype = cms_get0_econtent_type(cms); | ||
291 | if (!petype) | ||
292 | return 0; | ||
293 | if (!oid) | ||
294 | return 1; | ||
295 | etype = OBJ_dup(oid); | ||
296 | if (!etype) | ||
297 | return 0; | ||
298 | ASN1_OBJECT_free(*petype); | ||
299 | *petype = etype; | ||
300 | return 1; | ||
301 | } | ||
302 | |||
303 | int CMS_is_detached(CMS_ContentInfo *cms) | ||
304 | { | ||
305 | ASN1_OCTET_STRING **pos; | ||
306 | pos = CMS_get0_content(cms); | ||
307 | if (!pos) | ||
308 | return -1; | ||
309 | if (*pos) | ||
310 | return 0; | ||
311 | return 1; | ||
312 | } | ||
313 | |||
314 | int CMS_set_detached(CMS_ContentInfo *cms, int detached) | ||
315 | { | ||
316 | ASN1_OCTET_STRING **pos; | ||
317 | pos = CMS_get0_content(cms); | ||
318 | if (!pos) | ||
319 | return 0; | ||
320 | if (detached) | ||
321 | { | ||
322 | if (*pos) | ||
323 | { | ||
324 | ASN1_OCTET_STRING_free(*pos); | ||
325 | *pos = NULL; | ||
326 | } | ||
327 | return 1; | ||
328 | } | ||
329 | if (!*pos) | ||
330 | *pos = ASN1_OCTET_STRING_new(); | ||
331 | if (*pos) | ||
332 | { | ||
333 | /* NB: special flag to show content is created and not | ||
334 | * read in. | ||
335 | */ | ||
336 | (*pos)->flags |= ASN1_STRING_FLAG_CONT; | ||
337 | return 1; | ||
338 | } | ||
339 | CMSerr(CMS_F_CMS_SET_DETACHED, ERR_R_MALLOC_FAILURE); | ||
340 | return 0; | ||
341 | } | ||
342 | |||
343 | /* Set up an X509_ALGOR DigestAlgorithmIdentifier from an EVP_MD */ | ||
344 | |||
345 | void cms_DigestAlgorithm_set(X509_ALGOR *alg, const EVP_MD *md) | ||
346 | { | ||
347 | int param_type; | ||
348 | |||
349 | switch (EVP_MD_type(md)) | ||
350 | { | ||
351 | case NID_sha1: | ||
352 | case NID_sha224: | ||
353 | case NID_sha256: | ||
354 | case NID_sha384: | ||
355 | case NID_sha512: | ||
356 | param_type = V_ASN1_UNDEF; | ||
357 | break; | ||
358 | |||
359 | default: | ||
360 | param_type = V_ASN1_NULL; | ||
361 | break; | ||
362 | } | ||
363 | |||
364 | X509_ALGOR_set0(alg, OBJ_nid2obj(EVP_MD_type(md)), param_type, NULL); | ||
365 | |||
366 | } | ||
367 | |||
368 | /* Create a digest BIO from an X509_ALGOR structure */ | ||
369 | |||
370 | BIO *cms_DigestAlgorithm_init_bio(X509_ALGOR *digestAlgorithm) | ||
371 | { | ||
372 | BIO *mdbio = NULL; | ||
373 | ASN1_OBJECT *digestoid; | ||
374 | const EVP_MD *digest; | ||
375 | X509_ALGOR_get0(&digestoid, NULL, NULL, digestAlgorithm); | ||
376 | digest = EVP_get_digestbyobj(digestoid); | ||
377 | if (!digest) | ||
378 | { | ||
379 | CMSerr(CMS_F_CMS_DIGESTALGORITHM_INIT_BIO, | ||
380 | CMS_R_UNKNOWN_DIGEST_ALGORIHM); | ||
381 | goto err; | ||
382 | } | ||
383 | mdbio = BIO_new(BIO_f_md()); | ||
384 | if (!mdbio || !BIO_set_md(mdbio, digest)) | ||
385 | { | ||
386 | CMSerr(CMS_F_CMS_DIGESTALGORITHM_INIT_BIO, | ||
387 | CMS_R_MD_BIO_INIT_ERROR); | ||
388 | goto err; | ||
389 | } | ||
390 | return mdbio; | ||
391 | err: | ||
392 | if (mdbio) | ||
393 | BIO_free(mdbio); | ||
394 | return NULL; | ||
395 | } | ||
396 | |||
397 | /* Locate a message digest content from a BIO chain based on SignerInfo */ | ||
398 | |||
399 | int cms_DigestAlgorithm_find_ctx(EVP_MD_CTX *mctx, BIO *chain, | ||
400 | X509_ALGOR *mdalg) | ||
401 | { | ||
402 | int nid; | ||
403 | ASN1_OBJECT *mdoid; | ||
404 | X509_ALGOR_get0(&mdoid, NULL, NULL, mdalg); | ||
405 | nid = OBJ_obj2nid(mdoid); | ||
406 | /* Look for digest type to match signature */ | ||
407 | for (;;) | ||
408 | { | ||
409 | EVP_MD_CTX *mtmp; | ||
410 | chain = BIO_find_type(chain, BIO_TYPE_MD); | ||
411 | if (chain == NULL) | ||
412 | { | ||
413 | CMSerr(CMS_F_CMS_DIGESTALGORITHM_FIND_CTX, | ||
414 | CMS_R_NO_MATCHING_DIGEST); | ||
415 | return 0; | ||
416 | } | ||
417 | BIO_get_md_ctx(chain, &mtmp); | ||
418 | if (EVP_MD_CTX_type(mtmp) == nid) | ||
419 | { | ||
420 | EVP_MD_CTX_copy_ex(mctx, mtmp); | ||
421 | return 1; | ||
422 | } | ||
423 | chain = BIO_next(chain); | ||
424 | } | ||
425 | } | ||
426 | |||
427 | static STACK_OF(CMS_CertificateChoices) **cms_get0_certificate_choices(CMS_ContentInfo *cms) | ||
428 | { | ||
429 | switch (OBJ_obj2nid(cms->contentType)) | ||
430 | { | ||
431 | |||
432 | case NID_pkcs7_signed: | ||
433 | return &cms->d.signedData->certificates; | ||
434 | |||
435 | case NID_pkcs7_enveloped: | ||
436 | return &cms->d.envelopedData->originatorInfo->certificates; | ||
437 | |||
438 | default: | ||
439 | CMSerr(CMS_F_CMS_GET0_CERTIFICATE_CHOICES, | ||
440 | CMS_R_UNSUPPORTED_CONTENT_TYPE); | ||
441 | return NULL; | ||
442 | |||
443 | } | ||
444 | } | ||
445 | |||
446 | CMS_CertificateChoices *CMS_add0_CertificateChoices(CMS_ContentInfo *cms) | ||
447 | { | ||
448 | STACK_OF(CMS_CertificateChoices) **pcerts; | ||
449 | CMS_CertificateChoices *cch; | ||
450 | pcerts = cms_get0_certificate_choices(cms); | ||
451 | if (!pcerts) | ||
452 | return NULL; | ||
453 | if (!*pcerts) | ||
454 | *pcerts = sk_CMS_CertificateChoices_new_null(); | ||
455 | if (!*pcerts) | ||
456 | return NULL; | ||
457 | cch = M_ASN1_new_of(CMS_CertificateChoices); | ||
458 | if (!cch) | ||
459 | return NULL; | ||
460 | if (!sk_CMS_CertificateChoices_push(*pcerts, cch)) | ||
461 | { | ||
462 | M_ASN1_free_of(cch, CMS_CertificateChoices); | ||
463 | return NULL; | ||
464 | } | ||
465 | return cch; | ||
466 | } | ||
467 | |||
468 | int CMS_add0_cert(CMS_ContentInfo *cms, X509 *cert) | ||
469 | { | ||
470 | CMS_CertificateChoices *cch; | ||
471 | STACK_OF(CMS_CertificateChoices) **pcerts; | ||
472 | int i; | ||
473 | pcerts = cms_get0_certificate_choices(cms); | ||
474 | if (!pcerts) | ||
475 | return 0; | ||
476 | if (!pcerts) | ||
477 | return 0; | ||
478 | for (i = 0; i < sk_CMS_CertificateChoices_num(*pcerts); i++) | ||
479 | { | ||
480 | cch = sk_CMS_CertificateChoices_value(*pcerts, i); | ||
481 | if (cch->type == CMS_CERTCHOICE_CERT) | ||
482 | { | ||
483 | if (!X509_cmp(cch->d.certificate, cert)) | ||
484 | { | ||
485 | CMSerr(CMS_F_CMS_ADD0_CERT, | ||
486 | CMS_R_CERTIFICATE_ALREADY_PRESENT); | ||
487 | return 0; | ||
488 | } | ||
489 | } | ||
490 | } | ||
491 | cch = CMS_add0_CertificateChoices(cms); | ||
492 | if (!cch) | ||
493 | return 0; | ||
494 | cch->type = CMS_CERTCHOICE_CERT; | ||
495 | cch->d.certificate = cert; | ||
496 | return 1; | ||
497 | } | ||
498 | |||
499 | int CMS_add1_cert(CMS_ContentInfo *cms, X509 *cert) | ||
500 | { | ||
501 | int r; | ||
502 | r = CMS_add0_cert(cms, cert); | ||
503 | if (r > 0) | ||
504 | CRYPTO_add(&cert->references, 1, CRYPTO_LOCK_X509); | ||
505 | return r; | ||
506 | } | ||
507 | |||
508 | static STACK_OF(CMS_RevocationInfoChoice) **cms_get0_revocation_choices(CMS_ContentInfo *cms) | ||
509 | { | ||
510 | switch (OBJ_obj2nid(cms->contentType)) | ||
511 | { | ||
512 | |||
513 | case NID_pkcs7_signed: | ||
514 | return &cms->d.signedData->crls; | ||
515 | |||
516 | case NID_pkcs7_enveloped: | ||
517 | return &cms->d.envelopedData->originatorInfo->crls; | ||
518 | |||
519 | default: | ||
520 | CMSerr(CMS_F_CMS_GET0_REVOCATION_CHOICES, | ||
521 | CMS_R_UNSUPPORTED_CONTENT_TYPE); | ||
522 | return NULL; | ||
523 | |||
524 | } | ||
525 | } | ||
526 | |||
527 | CMS_RevocationInfoChoice *CMS_add0_RevocationInfoChoice(CMS_ContentInfo *cms) | ||
528 | { | ||
529 | STACK_OF(CMS_RevocationInfoChoice) **pcrls; | ||
530 | CMS_RevocationInfoChoice *rch; | ||
531 | pcrls = cms_get0_revocation_choices(cms); | ||
532 | if (!pcrls) | ||
533 | return NULL; | ||
534 | if (!*pcrls) | ||
535 | *pcrls = sk_CMS_RevocationInfoChoice_new_null(); | ||
536 | if (!*pcrls) | ||
537 | return NULL; | ||
538 | rch = M_ASN1_new_of(CMS_RevocationInfoChoice); | ||
539 | if (!rch) | ||
540 | return NULL; | ||
541 | if (!sk_CMS_RevocationInfoChoice_push(*pcrls, rch)) | ||
542 | { | ||
543 | M_ASN1_free_of(rch, CMS_RevocationInfoChoice); | ||
544 | return NULL; | ||
545 | } | ||
546 | return rch; | ||
547 | } | ||
548 | |||
549 | int CMS_add0_crl(CMS_ContentInfo *cms, X509_CRL *crl) | ||
550 | { | ||
551 | CMS_RevocationInfoChoice *rch; | ||
552 | rch = CMS_add0_RevocationInfoChoice(cms); | ||
553 | if (!rch) | ||
554 | return 0; | ||
555 | rch->type = CMS_REVCHOICE_CRL; | ||
556 | rch->d.crl = crl; | ||
557 | return 1; | ||
558 | } | ||
559 | |||
560 | STACK_OF(X509) *CMS_get1_certs(CMS_ContentInfo *cms) | ||
561 | { | ||
562 | STACK_OF(X509) *certs = NULL; | ||
563 | CMS_CertificateChoices *cch; | ||
564 | STACK_OF(CMS_CertificateChoices) **pcerts; | ||
565 | int i; | ||
566 | pcerts = cms_get0_certificate_choices(cms); | ||
567 | if (!pcerts) | ||
568 | return NULL; | ||
569 | for (i = 0; i < sk_CMS_CertificateChoices_num(*pcerts); i++) | ||
570 | { | ||
571 | cch = sk_CMS_CertificateChoices_value(*pcerts, i); | ||
572 | if (cch->type == 0) | ||
573 | { | ||
574 | if (!certs) | ||
575 | { | ||
576 | certs = sk_X509_new_null(); | ||
577 | if (!certs) | ||
578 | return NULL; | ||
579 | } | ||
580 | if (!sk_X509_push(certs, cch->d.certificate)) | ||
581 | { | ||
582 | sk_X509_pop_free(certs, X509_free); | ||
583 | return NULL; | ||
584 | } | ||
585 | CRYPTO_add(&cch->d.certificate->references, | ||
586 | 1, CRYPTO_LOCK_X509); | ||
587 | } | ||
588 | } | ||
589 | return certs; | ||
590 | |||
591 | } | ||
592 | |||
593 | STACK_OF(X509_CRL) *CMS_get1_crls(CMS_ContentInfo *cms) | ||
594 | { | ||
595 | STACK_OF(X509_CRL) *crls = NULL; | ||
596 | STACK_OF(CMS_RevocationInfoChoice) **pcrls; | ||
597 | CMS_RevocationInfoChoice *rch; | ||
598 | int i; | ||
599 | pcrls = cms_get0_revocation_choices(cms); | ||
600 | if (!pcrls) | ||
601 | return NULL; | ||
602 | for (i = 0; i < sk_CMS_RevocationInfoChoice_num(*pcrls); i++) | ||
603 | { | ||
604 | rch = sk_CMS_RevocationInfoChoice_value(*pcrls, i); | ||
605 | if (rch->type == 0) | ||
606 | { | ||
607 | if (!crls) | ||
608 | { | ||
609 | crls = sk_X509_CRL_new_null(); | ||
610 | if (!crls) | ||
611 | return NULL; | ||
612 | } | ||
613 | if (!sk_X509_CRL_push(crls, rch->d.crl)) | ||
614 | { | ||
615 | sk_X509_CRL_pop_free(crls, X509_CRL_free); | ||
616 | return NULL; | ||
617 | } | ||
618 | CRYPTO_add(&rch->d.crl->references, | ||
619 | 1, CRYPTO_LOCK_X509_CRL); | ||
620 | } | ||
621 | } | ||
622 | return crls; | ||
623 | } | ||
diff --git a/src/lib/libcrypto/cms/cms_sd.c b/src/lib/libcrypto/cms/cms_sd.c new file mode 100644 index 0000000000..591bfbec33 --- /dev/null +++ b/src/lib/libcrypto/cms/cms_sd.c | |||
@@ -0,0 +1,1014 @@ | |||
1 | /* crypto/cms/cms_sd.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/asn1t.h> | ||
56 | #include <openssl/pem.h> | ||
57 | #include <openssl/x509v3.h> | ||
58 | #include <openssl/err.h> | ||
59 | #include <openssl/cms.h> | ||
60 | #include "cms_lcl.h" | ||
61 | |||
62 | /* CMS SignedData Utilities */ | ||
63 | |||
64 | DECLARE_ASN1_ITEM(CMS_SignedData) | ||
65 | |||
66 | static CMS_SignedData *cms_get0_signed(CMS_ContentInfo *cms) | ||
67 | { | ||
68 | if (OBJ_obj2nid(cms->contentType) != NID_pkcs7_signed) | ||
69 | { | ||
70 | CMSerr(CMS_F_CMS_GET0_SIGNED, CMS_R_CONTENT_TYPE_NOT_SIGNED_DATA); | ||
71 | return NULL; | ||
72 | } | ||
73 | return cms->d.signedData; | ||
74 | } | ||
75 | |||
76 | static CMS_SignedData *cms_signed_data_init(CMS_ContentInfo *cms) | ||
77 | { | ||
78 | if (cms->d.other == NULL) | ||
79 | { | ||
80 | cms->d.signedData = M_ASN1_new_of(CMS_SignedData); | ||
81 | if (!cms->d.signedData) | ||
82 | { | ||
83 | CMSerr(CMS_F_CMS_SIGNED_DATA_INIT, ERR_R_MALLOC_FAILURE); | ||
84 | return NULL; | ||
85 | } | ||
86 | cms->d.signedData->version = 1; | ||
87 | cms->d.signedData->encapContentInfo->eContentType = | ||
88 | OBJ_nid2obj(NID_pkcs7_data); | ||
89 | cms->d.signedData->encapContentInfo->partial = 1; | ||
90 | ASN1_OBJECT_free(cms->contentType); | ||
91 | cms->contentType = OBJ_nid2obj(NID_pkcs7_signed); | ||
92 | return cms->d.signedData; | ||
93 | } | ||
94 | return cms_get0_signed(cms); | ||
95 | } | ||
96 | |||
97 | /* Just initialize SignedData e.g. for certs only structure */ | ||
98 | |||
99 | int CMS_SignedData_init(CMS_ContentInfo *cms) | ||
100 | { | ||
101 | if (cms_signed_data_init(cms)) | ||
102 | return 1; | ||
103 | else | ||
104 | return 0; | ||
105 | } | ||
106 | |||
107 | /* Check structures and fixup version numbers (if necessary) */ | ||
108 | |||
109 | static void cms_sd_set_version(CMS_SignedData *sd) | ||
110 | { | ||
111 | int i; | ||
112 | CMS_CertificateChoices *cch; | ||
113 | CMS_RevocationInfoChoice *rch; | ||
114 | CMS_SignerInfo *si; | ||
115 | |||
116 | for (i = 0; i < sk_CMS_CertificateChoices_num(sd->certificates); i++) | ||
117 | { | ||
118 | cch = sk_CMS_CertificateChoices_value(sd->certificates, i); | ||
119 | if (cch->type == CMS_CERTCHOICE_OTHER) | ||
120 | { | ||
121 | if (sd->version < 5) | ||
122 | sd->version = 5; | ||
123 | } | ||
124 | else if (cch->type == CMS_CERTCHOICE_V2ACERT) | ||
125 | { | ||
126 | if (sd->version < 4) | ||
127 | sd->version = 4; | ||
128 | } | ||
129 | else if (cch->type == CMS_CERTCHOICE_V1ACERT) | ||
130 | { | ||
131 | if (sd->version < 3) | ||
132 | sd->version = 3; | ||
133 | } | ||
134 | } | ||
135 | |||
136 | for (i = 0; i < sk_CMS_RevocationInfoChoice_num(sd->crls); i++) | ||
137 | { | ||
138 | rch = sk_CMS_RevocationInfoChoice_value(sd->crls, i); | ||
139 | if (rch->type == CMS_REVCHOICE_OTHER) | ||
140 | { | ||
141 | if (sd->version < 5) | ||
142 | sd->version = 5; | ||
143 | } | ||
144 | } | ||
145 | |||
146 | if ((OBJ_obj2nid(sd->encapContentInfo->eContentType) != NID_pkcs7_data) | ||
147 | && (sd->version < 3)) | ||
148 | sd->version = 3; | ||
149 | |||
150 | for (i = 0; i < sk_CMS_SignerInfo_num(sd->signerInfos); i++) | ||
151 | { | ||
152 | si = sk_CMS_SignerInfo_value(sd->signerInfos, i); | ||
153 | if (si->sid->type == CMS_SIGNERINFO_KEYIDENTIFIER) | ||
154 | { | ||
155 | if (si->version < 3) | ||
156 | si->version = 3; | ||
157 | if (sd->version < 3) | ||
158 | sd->version = 3; | ||
159 | } | ||
160 | else | ||
161 | sd->version = 1; | ||
162 | } | ||
163 | |||
164 | if (sd->version < 1) | ||
165 | sd->version = 1; | ||
166 | |||
167 | } | ||
168 | |||
169 | /* Copy an existing messageDigest value */ | ||
170 | |||
171 | static int cms_copy_messageDigest(CMS_ContentInfo *cms, CMS_SignerInfo *si) | ||
172 | { | ||
173 | STACK_OF(CMS_SignerInfo) *sinfos; | ||
174 | CMS_SignerInfo *sitmp; | ||
175 | int i; | ||
176 | sinfos = CMS_get0_SignerInfos(cms); | ||
177 | for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++) | ||
178 | { | ||
179 | ASN1_OCTET_STRING *messageDigest; | ||
180 | sitmp = sk_CMS_SignerInfo_value(sinfos, i); | ||
181 | if (sitmp == si) | ||
182 | continue; | ||
183 | if (CMS_signed_get_attr_count(sitmp) < 0) | ||
184 | continue; | ||
185 | if (OBJ_cmp(si->digestAlgorithm->algorithm, | ||
186 | sitmp->digestAlgorithm->algorithm)) | ||
187 | continue; | ||
188 | messageDigest = CMS_signed_get0_data_by_OBJ(sitmp, | ||
189 | OBJ_nid2obj(NID_pkcs9_messageDigest), | ||
190 | -3, V_ASN1_OCTET_STRING); | ||
191 | if (!messageDigest) | ||
192 | { | ||
193 | CMSerr(CMS_F_CMS_COPY_MESSAGEDIGEST, | ||
194 | CMS_R_ERROR_READING_MESSAGEDIGEST_ATTRIBUTE); | ||
195 | return 0; | ||
196 | } | ||
197 | |||
198 | if (CMS_signed_add1_attr_by_NID(si, NID_pkcs9_messageDigest, | ||
199 | V_ASN1_OCTET_STRING, | ||
200 | messageDigest, -1)) | ||
201 | return 1; | ||
202 | else | ||
203 | return 0; | ||
204 | } | ||
205 | CMSerr(CMS_F_CMS_COPY_MESSAGEDIGEST, CMS_R_NO_MATCHING_DIGEST); | ||
206 | return 0; | ||
207 | } | ||
208 | |||
209 | int cms_set1_SignerIdentifier(CMS_SignerIdentifier *sid, X509 *cert, int type) | ||
210 | { | ||
211 | switch(type) | ||
212 | { | ||
213 | case CMS_SIGNERINFO_ISSUER_SERIAL: | ||
214 | sid->d.issuerAndSerialNumber = | ||
215 | M_ASN1_new_of(CMS_IssuerAndSerialNumber); | ||
216 | if (!sid->d.issuerAndSerialNumber) | ||
217 | goto merr; | ||
218 | if (!X509_NAME_set(&sid->d.issuerAndSerialNumber->issuer, | ||
219 | X509_get_issuer_name(cert))) | ||
220 | goto merr; | ||
221 | ASN1_STRING_free(sid->d.issuerAndSerialNumber->serialNumber); | ||
222 | sid->d.issuerAndSerialNumber->serialNumber = | ||
223 | ASN1_STRING_dup(X509_get_serialNumber(cert)); | ||
224 | if(!sid->d.issuerAndSerialNumber->serialNumber) | ||
225 | goto merr; | ||
226 | break; | ||
227 | |||
228 | case CMS_SIGNERINFO_KEYIDENTIFIER: | ||
229 | if (!cert->skid) | ||
230 | { | ||
231 | CMSerr(CMS_F_CMS_SET1_SIGNERIDENTIFIER, | ||
232 | CMS_R_CERTIFICATE_HAS_NO_KEYID); | ||
233 | return 0; | ||
234 | } | ||
235 | sid->d.subjectKeyIdentifier = ASN1_STRING_dup(cert->skid); | ||
236 | if (!sid->d.subjectKeyIdentifier) | ||
237 | goto merr; | ||
238 | break; | ||
239 | |||
240 | default: | ||
241 | CMSerr(CMS_F_CMS_SET1_SIGNERIDENTIFIER, CMS_R_UNKNOWN_ID); | ||
242 | return 0; | ||
243 | } | ||
244 | |||
245 | sid->type = type; | ||
246 | |||
247 | return 1; | ||
248 | |||
249 | merr: | ||
250 | CMSerr(CMS_F_CMS_SET1_SIGNERIDENTIFIER, ERR_R_MALLOC_FAILURE); | ||
251 | return 0; | ||
252 | |||
253 | } | ||
254 | |||
255 | int cms_SignerIdentifier_get0_signer_id(CMS_SignerIdentifier *sid, | ||
256 | ASN1_OCTET_STRING **keyid, | ||
257 | X509_NAME **issuer, ASN1_INTEGER **sno) | ||
258 | { | ||
259 | if (sid->type == CMS_SIGNERINFO_ISSUER_SERIAL) | ||
260 | { | ||
261 | if (issuer) | ||
262 | *issuer = sid->d.issuerAndSerialNumber->issuer; | ||
263 | if (sno) | ||
264 | *sno = sid->d.issuerAndSerialNumber->serialNumber; | ||
265 | } | ||
266 | else if (sid->type == CMS_SIGNERINFO_KEYIDENTIFIER) | ||
267 | { | ||
268 | if (keyid) | ||
269 | *keyid = sid->d.subjectKeyIdentifier; | ||
270 | } | ||
271 | else | ||
272 | return 0; | ||
273 | return 1; | ||
274 | } | ||
275 | |||
276 | int cms_SignerIdentifier_cert_cmp(CMS_SignerIdentifier *sid, X509 *cert) | ||
277 | { | ||
278 | int ret; | ||
279 | if (sid->type == CMS_SIGNERINFO_ISSUER_SERIAL) | ||
280 | { | ||
281 | ret = X509_NAME_cmp(sid->d.issuerAndSerialNumber->issuer, | ||
282 | X509_get_issuer_name(cert)); | ||
283 | if (ret) | ||
284 | return ret; | ||
285 | return ASN1_INTEGER_cmp(sid->d.issuerAndSerialNumber->serialNumber, | ||
286 | X509_get_serialNumber(cert)); | ||
287 | } | ||
288 | else if (sid->type == CMS_SIGNERINFO_KEYIDENTIFIER) | ||
289 | { | ||
290 | X509_check_purpose(cert, -1, -1); | ||
291 | if (!cert->skid) | ||
292 | return -1; | ||
293 | return ASN1_OCTET_STRING_cmp(sid->d.subjectKeyIdentifier, | ||
294 | cert->skid); | ||
295 | } | ||
296 | else | ||
297 | return -1; | ||
298 | } | ||
299 | |||
300 | CMS_SignerInfo *CMS_add1_signer(CMS_ContentInfo *cms, | ||
301 | X509 *signer, EVP_PKEY *pk, const EVP_MD *md, | ||
302 | unsigned int flags) | ||
303 | { | ||
304 | CMS_SignedData *sd; | ||
305 | CMS_SignerInfo *si = NULL; | ||
306 | X509_ALGOR *alg; | ||
307 | int i, type; | ||
308 | if(!X509_check_private_key(signer, pk)) | ||
309 | { | ||
310 | CMSerr(CMS_F_CMS_ADD1_SIGNER, | ||
311 | CMS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE); | ||
312 | return NULL; | ||
313 | } | ||
314 | sd = cms_signed_data_init(cms); | ||
315 | if (!sd) | ||
316 | goto err; | ||
317 | si = M_ASN1_new_of(CMS_SignerInfo); | ||
318 | if (!si) | ||
319 | goto merr; | ||
320 | X509_check_purpose(signer, -1, -1); | ||
321 | |||
322 | CRYPTO_add(&pk->references, 1, CRYPTO_LOCK_EVP_PKEY); | ||
323 | CRYPTO_add(&signer->references, 1, CRYPTO_LOCK_X509); | ||
324 | |||
325 | si->pkey = pk; | ||
326 | si->signer = signer; | ||
327 | |||
328 | if (flags & CMS_USE_KEYID) | ||
329 | { | ||
330 | si->version = 3; | ||
331 | if (sd->version < 3) | ||
332 | sd->version = 3; | ||
333 | type = CMS_SIGNERINFO_KEYIDENTIFIER; | ||
334 | } | ||
335 | else | ||
336 | { | ||
337 | type = CMS_SIGNERINFO_ISSUER_SERIAL; | ||
338 | si->version = 1; | ||
339 | } | ||
340 | |||
341 | if (!cms_set1_SignerIdentifier(si->sid, signer, type)) | ||
342 | goto err; | ||
343 | |||
344 | /* Since no EVP_PKEY_METHOD in 0.9.8 hard code SHA1 as default */ | ||
345 | if (md == NULL) | ||
346 | md = EVP_sha1(); | ||
347 | |||
348 | /* OpenSSL 0.9.8 only supports SHA1 with non-RSA keys */ | ||
349 | |||
350 | if ((pk->type != EVP_PKEY_RSA) && (EVP_MD_type(md) != NID_sha1)) | ||
351 | { | ||
352 | CMSerr(CMS_F_CMS_ADD1_SIGNER, | ||
353 | CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE); | ||
354 | goto err; | ||
355 | } | ||
356 | |||
357 | cms_DigestAlgorithm_set(si->digestAlgorithm, md); | ||
358 | |||
359 | /* See if digest is present in digestAlgorithms */ | ||
360 | for (i = 0; i < sk_X509_ALGOR_num(sd->digestAlgorithms); i++) | ||
361 | { | ||
362 | ASN1_OBJECT *aoid; | ||
363 | alg = sk_X509_ALGOR_value(sd->digestAlgorithms, i); | ||
364 | X509_ALGOR_get0(&aoid, NULL, NULL, alg); | ||
365 | if (OBJ_obj2nid(aoid) == EVP_MD_type(md)) | ||
366 | break; | ||
367 | } | ||
368 | |||
369 | if (i == sk_X509_ALGOR_num(sd->digestAlgorithms)) | ||
370 | { | ||
371 | alg = X509_ALGOR_new(); | ||
372 | if (!alg) | ||
373 | goto merr; | ||
374 | cms_DigestAlgorithm_set(alg, md); | ||
375 | if (!sk_X509_ALGOR_push(sd->digestAlgorithms, alg)) | ||
376 | { | ||
377 | X509_ALGOR_free(alg); | ||
378 | goto merr; | ||
379 | } | ||
380 | } | ||
381 | |||
382 | /* Since we have no EVP_PKEY_ASN1_METHOD in OpenSSL 0.9.8, | ||
383 | * hard code algorithm parameters. | ||
384 | */ | ||
385 | |||
386 | switch (pk->type) | ||
387 | { | ||
388 | |||
389 | case EVP_PKEY_RSA: | ||
390 | X509_ALGOR_set0(si->signatureAlgorithm, | ||
391 | OBJ_nid2obj(NID_rsaEncryption), | ||
392 | V_ASN1_NULL, 0); | ||
393 | break; | ||
394 | |||
395 | case EVP_PKEY_DSA: | ||
396 | X509_ALGOR_set0(si->signatureAlgorithm, | ||
397 | OBJ_nid2obj(NID_dsaWithSHA1), | ||
398 | V_ASN1_UNDEF, 0); | ||
399 | break; | ||
400 | |||
401 | |||
402 | case EVP_PKEY_EC: | ||
403 | X509_ALGOR_set0(si->signatureAlgorithm, | ||
404 | OBJ_nid2obj(NID_ecdsa_with_SHA1), | ||
405 | V_ASN1_UNDEF, 0); | ||
406 | break; | ||
407 | |||
408 | default: | ||
409 | CMSerr(CMS_F_CMS_ADD1_SIGNER, | ||
410 | CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE); | ||
411 | goto err; | ||
412 | |||
413 | } | ||
414 | |||
415 | if (!(flags & CMS_NOATTR)) | ||
416 | { | ||
417 | /* Initialialize signed attributes strutucture so other | ||
418 | * attributes such as signing time etc are added later | ||
419 | * even if we add none here. | ||
420 | */ | ||
421 | if (!si->signedAttrs) | ||
422 | { | ||
423 | si->signedAttrs = sk_X509_ATTRIBUTE_new_null(); | ||
424 | if (!si->signedAttrs) | ||
425 | goto merr; | ||
426 | } | ||
427 | |||
428 | if (!(flags & CMS_NOSMIMECAP)) | ||
429 | { | ||
430 | STACK_OF(X509_ALGOR) *smcap = NULL; | ||
431 | i = CMS_add_standard_smimecap(&smcap); | ||
432 | if (i) | ||
433 | i = CMS_add_smimecap(si, smcap); | ||
434 | sk_X509_ALGOR_pop_free(smcap, X509_ALGOR_free); | ||
435 | if (!i) | ||
436 | goto merr; | ||
437 | } | ||
438 | if (flags & CMS_REUSE_DIGEST) | ||
439 | { | ||
440 | if (!cms_copy_messageDigest(cms, si)) | ||
441 | goto err; | ||
442 | if (!(flags & CMS_PARTIAL) && | ||
443 | !CMS_SignerInfo_sign(si)) | ||
444 | goto err; | ||
445 | } | ||
446 | } | ||
447 | |||
448 | if (!(flags & CMS_NOCERTS)) | ||
449 | { | ||
450 | /* NB ignore -1 return for duplicate cert */ | ||
451 | if (!CMS_add1_cert(cms, signer)) | ||
452 | goto merr; | ||
453 | } | ||
454 | |||
455 | if (!sd->signerInfos) | ||
456 | sd->signerInfos = sk_CMS_SignerInfo_new_null(); | ||
457 | if (!sd->signerInfos || | ||
458 | !sk_CMS_SignerInfo_push(sd->signerInfos, si)) | ||
459 | goto merr; | ||
460 | |||
461 | return si; | ||
462 | |||
463 | merr: | ||
464 | CMSerr(CMS_F_CMS_ADD1_SIGNER, ERR_R_MALLOC_FAILURE); | ||
465 | err: | ||
466 | if (si) | ||
467 | M_ASN1_free_of(si, CMS_SignerInfo); | ||
468 | return NULL; | ||
469 | |||
470 | } | ||
471 | |||
472 | static int cms_add1_signingTime(CMS_SignerInfo *si, ASN1_TIME *t) | ||
473 | { | ||
474 | ASN1_TIME *tt; | ||
475 | int r = 0; | ||
476 | if (t) | ||
477 | tt = t; | ||
478 | else | ||
479 | tt = X509_gmtime_adj(NULL, 0); | ||
480 | |||
481 | if (!tt) | ||
482 | goto merr; | ||
483 | |||
484 | if (CMS_signed_add1_attr_by_NID(si, NID_pkcs9_signingTime, | ||
485 | tt->type, tt, -1) <= 0) | ||
486 | goto merr; | ||
487 | |||
488 | r = 1; | ||
489 | |||
490 | merr: | ||
491 | |||
492 | if (!t) | ||
493 | ASN1_TIME_free(tt); | ||
494 | |||
495 | if (!r) | ||
496 | CMSerr(CMS_F_CMS_ADD1_SIGNINGTIME, ERR_R_MALLOC_FAILURE); | ||
497 | |||
498 | return r; | ||
499 | |||
500 | } | ||
501 | |||
502 | STACK_OF(CMS_SignerInfo) *CMS_get0_SignerInfos(CMS_ContentInfo *cms) | ||
503 | { | ||
504 | CMS_SignedData *sd; | ||
505 | sd = cms_get0_signed(cms); | ||
506 | if (!sd) | ||
507 | return NULL; | ||
508 | return sd->signerInfos; | ||
509 | } | ||
510 | |||
511 | STACK_OF(X509) *CMS_get0_signers(CMS_ContentInfo *cms) | ||
512 | { | ||
513 | STACK_OF(X509) *signers = NULL; | ||
514 | STACK_OF(CMS_SignerInfo) *sinfos; | ||
515 | CMS_SignerInfo *si; | ||
516 | int i; | ||
517 | sinfos = CMS_get0_SignerInfos(cms); | ||
518 | for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++) | ||
519 | { | ||
520 | si = sk_CMS_SignerInfo_value(sinfos, i); | ||
521 | if (si->signer) | ||
522 | { | ||
523 | if (!signers) | ||
524 | { | ||
525 | signers = sk_X509_new_null(); | ||
526 | if (!signers) | ||
527 | return NULL; | ||
528 | } | ||
529 | if (!sk_X509_push(signers, si->signer)) | ||
530 | { | ||
531 | sk_X509_free(signers); | ||
532 | return NULL; | ||
533 | } | ||
534 | } | ||
535 | } | ||
536 | return signers; | ||
537 | } | ||
538 | |||
539 | void CMS_SignerInfo_set1_signer_cert(CMS_SignerInfo *si, X509 *signer) | ||
540 | { | ||
541 | if (signer) | ||
542 | { | ||
543 | CRYPTO_add(&signer->references, 1, CRYPTO_LOCK_X509); | ||
544 | if (si->pkey) | ||
545 | EVP_PKEY_free(si->pkey); | ||
546 | si->pkey = X509_get_pubkey(signer); | ||
547 | } | ||
548 | if (si->signer) | ||
549 | X509_free(si->signer); | ||
550 | si->signer = signer; | ||
551 | } | ||
552 | |||
553 | int CMS_SignerInfo_get0_signer_id(CMS_SignerInfo *si, | ||
554 | ASN1_OCTET_STRING **keyid, | ||
555 | X509_NAME **issuer, ASN1_INTEGER **sno) | ||
556 | { | ||
557 | return cms_SignerIdentifier_get0_signer_id(si->sid, keyid, issuer, sno); | ||
558 | } | ||
559 | |||
560 | int CMS_SignerInfo_cert_cmp(CMS_SignerInfo *si, X509 *cert) | ||
561 | { | ||
562 | return cms_SignerIdentifier_cert_cmp(si->sid, cert); | ||
563 | } | ||
564 | |||
565 | int CMS_set1_signers_certs(CMS_ContentInfo *cms, STACK_OF(X509) *scerts, | ||
566 | unsigned int flags) | ||
567 | { | ||
568 | CMS_SignedData *sd; | ||
569 | CMS_SignerInfo *si; | ||
570 | CMS_CertificateChoices *cch; | ||
571 | STACK_OF(CMS_CertificateChoices) *certs; | ||
572 | X509 *x; | ||
573 | int i, j; | ||
574 | int ret = 0; | ||
575 | sd = cms_get0_signed(cms); | ||
576 | if (!sd) | ||
577 | return -1; | ||
578 | certs = sd->certificates; | ||
579 | for (i = 0; i < sk_CMS_SignerInfo_num(sd->signerInfos); i++) | ||
580 | { | ||
581 | si = sk_CMS_SignerInfo_value(sd->signerInfos, i); | ||
582 | if (si->signer) | ||
583 | continue; | ||
584 | |||
585 | for (j = 0; j < sk_X509_num(scerts); j++) | ||
586 | { | ||
587 | x = sk_X509_value(scerts, j); | ||
588 | if (CMS_SignerInfo_cert_cmp(si, x) == 0) | ||
589 | { | ||
590 | CMS_SignerInfo_set1_signer_cert(si, x); | ||
591 | ret++; | ||
592 | break; | ||
593 | } | ||
594 | } | ||
595 | |||
596 | if (si->signer || (flags & CMS_NOINTERN)) | ||
597 | continue; | ||
598 | |||
599 | for (j = 0; j < sk_CMS_CertificateChoices_num(certs); j++) | ||
600 | { | ||
601 | cch = sk_CMS_CertificateChoices_value(certs, j); | ||
602 | if (cch->type != 0) | ||
603 | continue; | ||
604 | x = cch->d.certificate; | ||
605 | if (CMS_SignerInfo_cert_cmp(si, x) == 0) | ||
606 | { | ||
607 | CMS_SignerInfo_set1_signer_cert(si, x); | ||
608 | ret++; | ||
609 | break; | ||
610 | } | ||
611 | } | ||
612 | } | ||
613 | return ret; | ||
614 | } | ||
615 | |||
616 | void CMS_SignerInfo_get0_algs(CMS_SignerInfo *si, EVP_PKEY **pk, X509 **signer, | ||
617 | X509_ALGOR **pdig, X509_ALGOR **psig) | ||
618 | { | ||
619 | if (pk) | ||
620 | *pk = si->pkey; | ||
621 | if (signer) | ||
622 | *signer = si->signer; | ||
623 | if (pdig) | ||
624 | *pdig = si->digestAlgorithm; | ||
625 | if (psig) | ||
626 | *psig = si->signatureAlgorithm; | ||
627 | } | ||
628 | |||
629 | /* In OpenSSL 0.9.8 we have the link between digest types and public | ||
630 | * key types so we need to fixup the digest type if the public key | ||
631 | * type is not appropriate. | ||
632 | */ | ||
633 | |||
634 | static void cms_fixup_mctx(EVP_MD_CTX *mctx, EVP_PKEY *pkey) | ||
635 | { | ||
636 | if (EVP_MD_CTX_type(mctx) != NID_sha1) | ||
637 | return; | ||
638 | #ifndef OPENSSL_NO_DSA | ||
639 | if (pkey->type == EVP_PKEY_DSA) | ||
640 | mctx->digest = EVP_dss1(); | ||
641 | #endif | ||
642 | #ifndef OPENSSL_NO_ECDSA | ||
643 | if (pkey->type == EVP_PKEY_EC) | ||
644 | mctx->digest = EVP_ecdsa(); | ||
645 | #endif | ||
646 | } | ||
647 | |||
648 | static int cms_SignerInfo_content_sign(CMS_ContentInfo *cms, | ||
649 | CMS_SignerInfo *si, BIO *chain) | ||
650 | { | ||
651 | EVP_MD_CTX mctx; | ||
652 | int r = 0; | ||
653 | EVP_MD_CTX_init(&mctx); | ||
654 | |||
655 | |||
656 | if (!si->pkey) | ||
657 | { | ||
658 | CMSerr(CMS_F_CMS_SIGNERINFO_CONTENT_SIGN, CMS_R_NO_PRIVATE_KEY); | ||
659 | return 0; | ||
660 | } | ||
661 | |||
662 | if (!cms_DigestAlgorithm_find_ctx(&mctx, chain, si->digestAlgorithm)) | ||
663 | goto err; | ||
664 | |||
665 | /* If any signed attributes calculate and add messageDigest attribute */ | ||
666 | |||
667 | if (CMS_signed_get_attr_count(si) >= 0) | ||
668 | { | ||
669 | ASN1_OBJECT *ctype = | ||
670 | cms->d.signedData->encapContentInfo->eContentType; | ||
671 | unsigned char md[EVP_MAX_MD_SIZE]; | ||
672 | unsigned int mdlen; | ||
673 | EVP_DigestFinal_ex(&mctx, md, &mdlen); | ||
674 | if (!CMS_signed_add1_attr_by_NID(si, NID_pkcs9_messageDigest, | ||
675 | V_ASN1_OCTET_STRING, | ||
676 | md, mdlen)) | ||
677 | goto err; | ||
678 | /* Copy content type across */ | ||
679 | if (CMS_signed_add1_attr_by_NID(si, NID_pkcs9_contentType, | ||
680 | V_ASN1_OBJECT, ctype, -1) <= 0) | ||
681 | goto err; | ||
682 | if (!CMS_SignerInfo_sign(si)) | ||
683 | goto err; | ||
684 | } | ||
685 | else | ||
686 | { | ||
687 | unsigned char *sig; | ||
688 | unsigned int siglen; | ||
689 | sig = OPENSSL_malloc(EVP_PKEY_size(si->pkey)); | ||
690 | if (!sig) | ||
691 | { | ||
692 | CMSerr(CMS_F_CMS_SIGNERINFO_CONTENT_SIGN, | ||
693 | ERR_R_MALLOC_FAILURE); | ||
694 | goto err; | ||
695 | } | ||
696 | cms_fixup_mctx(&mctx, si->pkey); | ||
697 | if (!EVP_SignFinal(&mctx, sig, &siglen, si->pkey)) | ||
698 | { | ||
699 | CMSerr(CMS_F_CMS_SIGNERINFO_CONTENT_SIGN, | ||
700 | CMS_R_SIGNFINAL_ERROR); | ||
701 | OPENSSL_free(sig); | ||
702 | goto err; | ||
703 | } | ||
704 | ASN1_STRING_set0(si->signature, sig, siglen); | ||
705 | } | ||
706 | |||
707 | r = 1; | ||
708 | |||
709 | err: | ||
710 | EVP_MD_CTX_cleanup(&mctx); | ||
711 | return r; | ||
712 | |||
713 | } | ||
714 | |||
715 | int cms_SignedData_final(CMS_ContentInfo *cms, BIO *chain) | ||
716 | { | ||
717 | STACK_OF(CMS_SignerInfo) *sinfos; | ||
718 | CMS_SignerInfo *si; | ||
719 | int i; | ||
720 | sinfos = CMS_get0_SignerInfos(cms); | ||
721 | for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++) | ||
722 | { | ||
723 | si = sk_CMS_SignerInfo_value(sinfos, i); | ||
724 | if (!cms_SignerInfo_content_sign(cms, si, chain)) | ||
725 | return 0; | ||
726 | } | ||
727 | cms->d.signedData->encapContentInfo->partial = 0; | ||
728 | return 1; | ||
729 | } | ||
730 | |||
731 | int CMS_SignerInfo_sign(CMS_SignerInfo *si) | ||
732 | { | ||
733 | EVP_MD_CTX mctx; | ||
734 | unsigned char *abuf = NULL; | ||
735 | int alen; | ||
736 | unsigned int siglen; | ||
737 | const EVP_MD *md = NULL; | ||
738 | |||
739 | md = EVP_get_digestbyobj(si->digestAlgorithm->algorithm); | ||
740 | if (md == NULL) | ||
741 | return 0; | ||
742 | |||
743 | EVP_MD_CTX_init(&mctx); | ||
744 | |||
745 | if (CMS_signed_get_attr_by_NID(si, NID_pkcs9_signingTime, -1) < 0) | ||
746 | { | ||
747 | if (!cms_add1_signingTime(si, NULL)) | ||
748 | goto err; | ||
749 | } | ||
750 | |||
751 | if (EVP_SignInit_ex(&mctx, md, NULL) <= 0) | ||
752 | goto err; | ||
753 | |||
754 | #if 0 | ||
755 | if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_SIGN, | ||
756 | EVP_PKEY_CTRL_CMS_SIGN, 0, si) <= 0) | ||
757 | { | ||
758 | CMSerr(CMS_F_CMS_SIGNERINFO_SIGN, CMS_R_CTRL_ERROR); | ||
759 | goto err; | ||
760 | } | ||
761 | #endif | ||
762 | |||
763 | alen = ASN1_item_i2d((ASN1_VALUE *)si->signedAttrs,&abuf, | ||
764 | ASN1_ITEM_rptr(CMS_Attributes_Sign)); | ||
765 | if(!abuf) | ||
766 | goto err; | ||
767 | if (EVP_SignUpdate(&mctx, abuf, alen) <= 0) | ||
768 | goto err; | ||
769 | siglen = EVP_PKEY_size(si->pkey); | ||
770 | OPENSSL_free(abuf); | ||
771 | abuf = OPENSSL_malloc(siglen); | ||
772 | if(!abuf) | ||
773 | goto err; | ||
774 | cms_fixup_mctx(&mctx, si->pkey); | ||
775 | if (EVP_SignFinal(&mctx, abuf, &siglen, si->pkey) <= 0) | ||
776 | goto err; | ||
777 | #if 0 | ||
778 | if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_SIGN, | ||
779 | EVP_PKEY_CTRL_CMS_SIGN, 1, si) <= 0) | ||
780 | { | ||
781 | CMSerr(CMS_F_CMS_SIGNERINFO_SIGN, CMS_R_CTRL_ERROR); | ||
782 | goto err; | ||
783 | } | ||
784 | #endif | ||
785 | EVP_MD_CTX_cleanup(&mctx); | ||
786 | |||
787 | ASN1_STRING_set0(si->signature, abuf, siglen); | ||
788 | |||
789 | return 1; | ||
790 | |||
791 | err: | ||
792 | if (abuf) | ||
793 | OPENSSL_free(abuf); | ||
794 | EVP_MD_CTX_cleanup(&mctx); | ||
795 | return 0; | ||
796 | |||
797 | } | ||
798 | |||
799 | int CMS_SignerInfo_verify(CMS_SignerInfo *si) | ||
800 | { | ||
801 | EVP_MD_CTX mctx; | ||
802 | unsigned char *abuf = NULL; | ||
803 | int alen, r = -1; | ||
804 | const EVP_MD *md = NULL; | ||
805 | |||
806 | if (!si->pkey) | ||
807 | { | ||
808 | CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY, CMS_R_NO_PUBLIC_KEY); | ||
809 | return -1; | ||
810 | } | ||
811 | |||
812 | md = EVP_get_digestbyobj(si->digestAlgorithm->algorithm); | ||
813 | if (md == NULL) | ||
814 | return -1; | ||
815 | EVP_MD_CTX_init(&mctx); | ||
816 | if (EVP_VerifyInit_ex(&mctx, md, NULL) <= 0) | ||
817 | goto err; | ||
818 | |||
819 | alen = ASN1_item_i2d((ASN1_VALUE *)si->signedAttrs,&abuf, | ||
820 | ASN1_ITEM_rptr(CMS_Attributes_Verify)); | ||
821 | if(!abuf) | ||
822 | goto err; | ||
823 | r = EVP_VerifyUpdate(&mctx, abuf, alen); | ||
824 | OPENSSL_free(abuf); | ||
825 | if (r <= 0) | ||
826 | { | ||
827 | r = -1; | ||
828 | goto err; | ||
829 | } | ||
830 | cms_fixup_mctx(&mctx, si->pkey); | ||
831 | r = EVP_VerifyFinal(&mctx, | ||
832 | si->signature->data, si->signature->length, si->pkey); | ||
833 | if (!r) | ||
834 | CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY, CMS_R_VERIFICATION_FAILURE); | ||
835 | err: | ||
836 | EVP_MD_CTX_cleanup(&mctx); | ||
837 | return r; | ||
838 | } | ||
839 | |||
840 | /* Create a chain of digest BIOs from a CMS ContentInfo */ | ||
841 | |||
842 | BIO *cms_SignedData_init_bio(CMS_ContentInfo *cms) | ||
843 | { | ||
844 | int i; | ||
845 | CMS_SignedData *sd; | ||
846 | BIO *chain = NULL; | ||
847 | sd = cms_get0_signed(cms); | ||
848 | if (!sd) | ||
849 | return NULL; | ||
850 | if (cms->d.signedData->encapContentInfo->partial) | ||
851 | cms_sd_set_version(sd); | ||
852 | for (i = 0; i < sk_X509_ALGOR_num(sd->digestAlgorithms); i++) | ||
853 | { | ||
854 | X509_ALGOR *digestAlgorithm; | ||
855 | BIO *mdbio; | ||
856 | digestAlgorithm = sk_X509_ALGOR_value(sd->digestAlgorithms, i); | ||
857 | mdbio = cms_DigestAlgorithm_init_bio(digestAlgorithm); | ||
858 | if (!mdbio) | ||
859 | goto err; | ||
860 | if (chain) | ||
861 | BIO_push(chain, mdbio); | ||
862 | else | ||
863 | chain = mdbio; | ||
864 | } | ||
865 | return chain; | ||
866 | err: | ||
867 | if (chain) | ||
868 | BIO_free_all(chain); | ||
869 | return NULL; | ||
870 | } | ||
871 | |||
872 | int CMS_SignerInfo_verify_content(CMS_SignerInfo *si, BIO *chain) | ||
873 | { | ||
874 | ASN1_OCTET_STRING *os = NULL; | ||
875 | EVP_MD_CTX mctx; | ||
876 | int r = -1; | ||
877 | EVP_MD_CTX_init(&mctx); | ||
878 | /* If we have any signed attributes look for messageDigest value */ | ||
879 | if (CMS_signed_get_attr_count(si) >= 0) | ||
880 | { | ||
881 | os = CMS_signed_get0_data_by_OBJ(si, | ||
882 | OBJ_nid2obj(NID_pkcs9_messageDigest), | ||
883 | -3, V_ASN1_OCTET_STRING); | ||
884 | if (!os) | ||
885 | { | ||
886 | CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT, | ||
887 | CMS_R_ERROR_READING_MESSAGEDIGEST_ATTRIBUTE); | ||
888 | goto err; | ||
889 | } | ||
890 | } | ||
891 | |||
892 | if (!cms_DigestAlgorithm_find_ctx(&mctx, chain, si->digestAlgorithm)) | ||
893 | goto err; | ||
894 | |||
895 | /* If messageDigest found compare it */ | ||
896 | |||
897 | if (os) | ||
898 | { | ||
899 | unsigned char mval[EVP_MAX_MD_SIZE]; | ||
900 | unsigned int mlen; | ||
901 | if (EVP_DigestFinal_ex(&mctx, mval, &mlen) <= 0) | ||
902 | { | ||
903 | CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT, | ||
904 | CMS_R_UNABLE_TO_FINALIZE_CONTEXT); | ||
905 | goto err; | ||
906 | } | ||
907 | if (mlen != (unsigned int)os->length) | ||
908 | { | ||
909 | CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT, | ||
910 | CMS_R_MESSAGEDIGEST_ATTRIBUTE_WRONG_LENGTH); | ||
911 | goto err; | ||
912 | } | ||
913 | |||
914 | if (memcmp(mval, os->data, mlen)) | ||
915 | { | ||
916 | CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT, | ||
917 | CMS_R_VERIFICATION_FAILURE); | ||
918 | r = 0; | ||
919 | } | ||
920 | else | ||
921 | r = 1; | ||
922 | } | ||
923 | else | ||
924 | { | ||
925 | cms_fixup_mctx(&mctx, si->pkey); | ||
926 | r = EVP_VerifyFinal(&mctx, si->signature->data, | ||
927 | si->signature->length, si->pkey); | ||
928 | if (r <= 0) | ||
929 | { | ||
930 | CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT, | ||
931 | CMS_R_VERIFICATION_FAILURE); | ||
932 | r = 0; | ||
933 | } | ||
934 | } | ||
935 | |||
936 | err: | ||
937 | EVP_MD_CTX_cleanup(&mctx); | ||
938 | return r; | ||
939 | |||
940 | } | ||
941 | |||
942 | int CMS_add_smimecap(CMS_SignerInfo *si, STACK_OF(X509_ALGOR) *algs) | ||
943 | { | ||
944 | unsigned char *smder = NULL; | ||
945 | int smderlen, r; | ||
946 | smderlen = i2d_X509_ALGORS(algs, &smder); | ||
947 | if (smderlen <= 0) | ||
948 | return 0; | ||
949 | r = CMS_signed_add1_attr_by_NID(si, NID_SMIMECapabilities, | ||
950 | V_ASN1_SEQUENCE, smder, smderlen); | ||
951 | OPENSSL_free(smder); | ||
952 | return r; | ||
953 | } | ||
954 | |||
955 | int CMS_add_simple_smimecap(STACK_OF(X509_ALGOR) **algs, | ||
956 | int algnid, int keysize) | ||
957 | { | ||
958 | X509_ALGOR *alg; | ||
959 | ASN1_INTEGER *key = NULL; | ||
960 | if (keysize > 0) | ||
961 | { | ||
962 | key = ASN1_INTEGER_new(); | ||
963 | if (!key || !ASN1_INTEGER_set(key, keysize)) | ||
964 | return 0; | ||
965 | } | ||
966 | alg = X509_ALGOR_new(); | ||
967 | if (!alg) | ||
968 | { | ||
969 | if (key) | ||
970 | ASN1_INTEGER_free(key); | ||
971 | return 0; | ||
972 | } | ||
973 | |||
974 | X509_ALGOR_set0(alg, OBJ_nid2obj(algnid), | ||
975 | key ? V_ASN1_INTEGER : V_ASN1_UNDEF, key); | ||
976 | if (!*algs) | ||
977 | *algs = sk_X509_ALGOR_new_null(); | ||
978 | if (!*algs || !sk_X509_ALGOR_push(*algs, alg)) | ||
979 | { | ||
980 | X509_ALGOR_free(alg); | ||
981 | return 0; | ||
982 | } | ||
983 | return 1; | ||
984 | } | ||
985 | |||
986 | /* Check to see if a cipher exists and if so add S/MIME capabilities */ | ||
987 | |||
988 | static int cms_add_cipher_smcap(STACK_OF(X509_ALGOR) **sk, int nid, int arg) | ||
989 | { | ||
990 | if (EVP_get_cipherbynid(nid)) | ||
991 | return CMS_add_simple_smimecap(sk, nid, arg); | ||
992 | return 1; | ||
993 | } | ||
994 | #if 0 | ||
995 | static int cms_add_digest_smcap(STACK_OF(X509_ALGOR) **sk, int nid, int arg) | ||
996 | { | ||
997 | if (EVP_get_digestbynid(nid)) | ||
998 | return CMS_add_simple_smimecap(sk, nid, arg); | ||
999 | return 1; | ||
1000 | } | ||
1001 | #endif | ||
1002 | int CMS_add_standard_smimecap(STACK_OF(X509_ALGOR) **smcap) | ||
1003 | { | ||
1004 | if (!cms_add_cipher_smcap(smcap, NID_aes_256_cbc, -1) | ||
1005 | || !cms_add_cipher_smcap(smcap, NID_aes_192_cbc, -1) | ||
1006 | || !cms_add_cipher_smcap(smcap, NID_aes_128_cbc, -1) | ||
1007 | || !cms_add_cipher_smcap(smcap, NID_des_ede3_cbc, -1) | ||
1008 | || !cms_add_cipher_smcap(smcap, NID_rc2_cbc, 128) | ||
1009 | || !cms_add_cipher_smcap(smcap, NID_rc2_cbc, 64) | ||
1010 | || !cms_add_cipher_smcap(smcap, NID_des_cbc, -1) | ||
1011 | || !cms_add_cipher_smcap(smcap, NID_rc2_cbc, 40)) | ||
1012 | return 0; | ||
1013 | return 1; | ||
1014 | } | ||
diff --git a/src/lib/libcrypto/cms/cms_smime.c b/src/lib/libcrypto/cms/cms_smime.c new file mode 100644 index 0000000000..f79c504e91 --- /dev/null +++ b/src/lib/libcrypto/cms/cms_smime.c | |||
@@ -0,0 +1,806 @@ | |||
1 | /* crypto/cms/cms_smime.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/asn1t.h> | ||
56 | #include <openssl/x509.h> | ||
57 | #include <openssl/x509v3.h> | ||
58 | #include <openssl/err.h> | ||
59 | #include <openssl/cms.h> | ||
60 | #include "cms_lcl.h" | ||
61 | |||
62 | static int cms_copy_content(BIO *out, BIO *in, unsigned int flags) | ||
63 | { | ||
64 | unsigned char buf[4096]; | ||
65 | int r = 0, i; | ||
66 | BIO *tmpout = NULL; | ||
67 | |||
68 | if (out == NULL) | ||
69 | tmpout = BIO_new(BIO_s_null()); | ||
70 | else if (flags & CMS_TEXT) | ||
71 | tmpout = BIO_new(BIO_s_mem()); | ||
72 | else | ||
73 | tmpout = out; | ||
74 | |||
75 | if(!tmpout) | ||
76 | { | ||
77 | CMSerr(CMS_F_CMS_COPY_CONTENT,ERR_R_MALLOC_FAILURE); | ||
78 | goto err; | ||
79 | } | ||
80 | |||
81 | /* Read all content through chain to process digest, decrypt etc */ | ||
82 | for (;;) | ||
83 | { | ||
84 | i=BIO_read(in,buf,sizeof(buf)); | ||
85 | if (i <= 0) | ||
86 | { | ||
87 | if (BIO_method_type(in) == BIO_TYPE_CIPHER) | ||
88 | { | ||
89 | if (!BIO_get_cipher_status(in)) | ||
90 | goto err; | ||
91 | } | ||
92 | break; | ||
93 | } | ||
94 | |||
95 | if (tmpout) | ||
96 | BIO_write(tmpout, buf, i); | ||
97 | } | ||
98 | |||
99 | if(flags & CMS_TEXT) | ||
100 | { | ||
101 | if(!SMIME_text(tmpout, out)) | ||
102 | { | ||
103 | CMSerr(CMS_F_CMS_COPY_CONTENT,CMS_R_SMIME_TEXT_ERROR); | ||
104 | goto err; | ||
105 | } | ||
106 | } | ||
107 | |||
108 | r = 1; | ||
109 | |||
110 | err: | ||
111 | if (tmpout && (tmpout != out)) | ||
112 | BIO_free(tmpout); | ||
113 | return r; | ||
114 | |||
115 | } | ||
116 | |||
117 | static int check_content(CMS_ContentInfo *cms) | ||
118 | { | ||
119 | ASN1_OCTET_STRING **pos = CMS_get0_content(cms); | ||
120 | if (!pos || !*pos) | ||
121 | { | ||
122 | CMSerr(CMS_F_CHECK_CONTENT, CMS_R_NO_CONTENT); | ||
123 | return 0; | ||
124 | } | ||
125 | return 1; | ||
126 | } | ||
127 | |||
128 | static void do_free_upto(BIO *f, BIO *upto) | ||
129 | { | ||
130 | if (upto) | ||
131 | { | ||
132 | BIO *tbio; | ||
133 | do | ||
134 | { | ||
135 | tbio = BIO_pop(f); | ||
136 | BIO_free(f); | ||
137 | f = tbio; | ||
138 | } | ||
139 | while (f != upto); | ||
140 | } | ||
141 | else | ||
142 | BIO_free_all(f); | ||
143 | } | ||
144 | |||
145 | int CMS_data(CMS_ContentInfo *cms, BIO *out, unsigned int flags) | ||
146 | { | ||
147 | BIO *cont; | ||
148 | int r; | ||
149 | if (OBJ_obj2nid(CMS_get0_type(cms)) != NID_pkcs7_data) | ||
150 | { | ||
151 | CMSerr(CMS_F_CMS_DATA, CMS_R_TYPE_NOT_DATA); | ||
152 | return 0; | ||
153 | } | ||
154 | cont = CMS_dataInit(cms, NULL); | ||
155 | if (!cont) | ||
156 | return 0; | ||
157 | r = cms_copy_content(out, cont, flags); | ||
158 | BIO_free_all(cont); | ||
159 | return r; | ||
160 | } | ||
161 | |||
162 | CMS_ContentInfo *CMS_data_create(BIO *in, unsigned int flags) | ||
163 | { | ||
164 | CMS_ContentInfo *cms; | ||
165 | cms = cms_Data_create(); | ||
166 | if (!cms) | ||
167 | return NULL; | ||
168 | |||
169 | if (CMS_final(cms, in, NULL, flags)) | ||
170 | return cms; | ||
171 | |||
172 | CMS_ContentInfo_free(cms); | ||
173 | |||
174 | return NULL; | ||
175 | } | ||
176 | |||
177 | int CMS_digest_verify(CMS_ContentInfo *cms, BIO *dcont, BIO *out, | ||
178 | unsigned int flags) | ||
179 | { | ||
180 | BIO *cont; | ||
181 | int r; | ||
182 | if (OBJ_obj2nid(CMS_get0_type(cms)) != NID_pkcs7_digest) | ||
183 | { | ||
184 | CMSerr(CMS_F_CMS_DIGEST_VERIFY, CMS_R_TYPE_NOT_DIGESTED_DATA); | ||
185 | return 0; | ||
186 | } | ||
187 | |||
188 | if (!dcont && !check_content(cms)) | ||
189 | return 0; | ||
190 | |||
191 | cont = CMS_dataInit(cms, dcont); | ||
192 | if (!cont) | ||
193 | return 0; | ||
194 | r = cms_copy_content(out, cont, flags); | ||
195 | if (r) | ||
196 | r = cms_DigestedData_do_final(cms, cont, 1); | ||
197 | do_free_upto(cont, dcont); | ||
198 | return r; | ||
199 | } | ||
200 | |||
201 | CMS_ContentInfo *CMS_digest_create(BIO *in, const EVP_MD *md, | ||
202 | unsigned int flags) | ||
203 | { | ||
204 | CMS_ContentInfo *cms; | ||
205 | if (!md) | ||
206 | md = EVP_sha1(); | ||
207 | cms = cms_DigestedData_create(md); | ||
208 | if (!cms) | ||
209 | return NULL; | ||
210 | |||
211 | if(!(flags & CMS_DETACHED)) | ||
212 | { | ||
213 | flags &= ~CMS_STREAM; | ||
214 | CMS_set_detached(cms, 0); | ||
215 | } | ||
216 | |||
217 | if ((flags & CMS_STREAM) || CMS_final(cms, in, NULL, flags)) | ||
218 | return cms; | ||
219 | |||
220 | CMS_ContentInfo_free(cms); | ||
221 | return NULL; | ||
222 | } | ||
223 | |||
224 | int CMS_EncryptedData_decrypt(CMS_ContentInfo *cms, | ||
225 | const unsigned char *key, size_t keylen, | ||
226 | BIO *dcont, BIO *out, unsigned int flags) | ||
227 | { | ||
228 | BIO *cont; | ||
229 | int r; | ||
230 | if (OBJ_obj2nid(CMS_get0_type(cms)) != NID_pkcs7_encrypted) | ||
231 | { | ||
232 | CMSerr(CMS_F_CMS_ENCRYPTEDDATA_DECRYPT, | ||
233 | CMS_R_TYPE_NOT_ENCRYPTED_DATA); | ||
234 | return 0; | ||
235 | } | ||
236 | |||
237 | if (!dcont && !check_content(cms)) | ||
238 | return 0; | ||
239 | |||
240 | if (CMS_EncryptedData_set1_key(cms, NULL, key, keylen) <= 0) | ||
241 | return 0; | ||
242 | cont = CMS_dataInit(cms, dcont); | ||
243 | if (!cont) | ||
244 | return 0; | ||
245 | r = cms_copy_content(out, cont, flags); | ||
246 | do_free_upto(cont, dcont); | ||
247 | return r; | ||
248 | } | ||
249 | |||
250 | CMS_ContentInfo *CMS_EncryptedData_encrypt(BIO *in, const EVP_CIPHER *cipher, | ||
251 | const unsigned char *key, size_t keylen, | ||
252 | unsigned int flags) | ||
253 | { | ||
254 | CMS_ContentInfo *cms; | ||
255 | if (!cipher) | ||
256 | { | ||
257 | CMSerr(CMS_F_CMS_ENCRYPTEDDATA_ENCRYPT, CMS_R_NO_CIPHER); | ||
258 | return NULL; | ||
259 | } | ||
260 | cms = CMS_ContentInfo_new(); | ||
261 | if (!cms) | ||
262 | return NULL; | ||
263 | if (!CMS_EncryptedData_set1_key(cms, cipher, key, keylen)) | ||
264 | return NULL; | ||
265 | |||
266 | if(!(flags & CMS_DETACHED)) | ||
267 | { | ||
268 | flags &= ~CMS_STREAM; | ||
269 | CMS_set_detached(cms, 0); | ||
270 | } | ||
271 | |||
272 | if ((flags & (CMS_STREAM|CMS_PARTIAL)) | ||
273 | || CMS_final(cms, in, NULL, flags)) | ||
274 | return cms; | ||
275 | |||
276 | CMS_ContentInfo_free(cms); | ||
277 | return NULL; | ||
278 | } | ||
279 | |||
280 | static int cms_signerinfo_verify_cert(CMS_SignerInfo *si, | ||
281 | X509_STORE *store, | ||
282 | STACK_OF(X509) *certs, | ||
283 | STACK_OF(X509_CRL) *crls, | ||
284 | unsigned int flags) | ||
285 | { | ||
286 | X509_STORE_CTX ctx; | ||
287 | X509 *signer; | ||
288 | int i, j, r = 0; | ||
289 | CMS_SignerInfo_get0_algs(si, NULL, &signer, NULL, NULL); | ||
290 | if (!X509_STORE_CTX_init(&ctx, store, signer, certs)) | ||
291 | { | ||
292 | CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CERT, | ||
293 | CMS_R_STORE_INIT_ERROR); | ||
294 | goto err; | ||
295 | } | ||
296 | X509_STORE_CTX_set_purpose(&ctx, X509_PURPOSE_SMIME_SIGN); | ||
297 | if (crls) | ||
298 | X509_STORE_CTX_set0_crls(&ctx, crls); | ||
299 | |||
300 | i = X509_verify_cert(&ctx); | ||
301 | if (i <= 0) | ||
302 | { | ||
303 | j = X509_STORE_CTX_get_error(&ctx); | ||
304 | CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CERT, | ||
305 | CMS_R_CERTIFICATE_VERIFY_ERROR); | ||
306 | ERR_add_error_data(2, "Verify error:", | ||
307 | X509_verify_cert_error_string(j)); | ||
308 | goto err; | ||
309 | } | ||
310 | r = 1; | ||
311 | err: | ||
312 | X509_STORE_CTX_cleanup(&ctx); | ||
313 | return r; | ||
314 | |||
315 | } | ||
316 | |||
317 | int CMS_verify(CMS_ContentInfo *cms, STACK_OF(X509) *certs, | ||
318 | X509_STORE *store, BIO *dcont, BIO *out, unsigned int flags) | ||
319 | { | ||
320 | CMS_SignerInfo *si; | ||
321 | STACK_OF(CMS_SignerInfo) *sinfos; | ||
322 | STACK_OF(X509) *cms_certs = NULL; | ||
323 | STACK_OF(X509_CRL) *crls = NULL; | ||
324 | X509 *signer; | ||
325 | int i, scount = 0, ret = 0; | ||
326 | BIO *cmsbio = NULL, *tmpin = NULL; | ||
327 | |||
328 | if (!dcont && !check_content(cms)) | ||
329 | return 0; | ||
330 | |||
331 | /* Attempt to find all signer certificates */ | ||
332 | |||
333 | sinfos = CMS_get0_SignerInfos(cms); | ||
334 | |||
335 | if (sk_CMS_SignerInfo_num(sinfos) <= 0) | ||
336 | { | ||
337 | CMSerr(CMS_F_CMS_VERIFY, CMS_R_NO_SIGNERS); | ||
338 | goto err; | ||
339 | } | ||
340 | |||
341 | for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++) | ||
342 | { | ||
343 | si = sk_CMS_SignerInfo_value(sinfos, i); | ||
344 | CMS_SignerInfo_get0_algs(si, NULL, &signer, NULL, NULL); | ||
345 | if (signer) | ||
346 | scount++; | ||
347 | } | ||
348 | |||
349 | if (scount != sk_CMS_SignerInfo_num(sinfos)) | ||
350 | scount += CMS_set1_signers_certs(cms, certs, flags); | ||
351 | |||
352 | if (scount != sk_CMS_SignerInfo_num(sinfos)) | ||
353 | { | ||
354 | CMSerr(CMS_F_CMS_VERIFY, CMS_R_SIGNER_CERTIFICATE_NOT_FOUND); | ||
355 | goto err; | ||
356 | } | ||
357 | |||
358 | /* Attempt to verify all signers certs */ | ||
359 | |||
360 | if (!(flags & CMS_NO_SIGNER_CERT_VERIFY)) | ||
361 | { | ||
362 | cms_certs = CMS_get1_certs(cms); | ||
363 | if (!(flags & CMS_NOCRL)) | ||
364 | crls = CMS_get1_crls(cms); | ||
365 | for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++) | ||
366 | { | ||
367 | si = sk_CMS_SignerInfo_value(sinfos, i); | ||
368 | if (!cms_signerinfo_verify_cert(si, store, | ||
369 | cms_certs, crls, flags)) | ||
370 | goto err; | ||
371 | } | ||
372 | } | ||
373 | |||
374 | /* Attempt to verify all SignerInfo signed attribute signatures */ | ||
375 | |||
376 | if (!(flags & CMS_NO_ATTR_VERIFY)) | ||
377 | { | ||
378 | for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++) | ||
379 | { | ||
380 | si = sk_CMS_SignerInfo_value(sinfos, i); | ||
381 | if (CMS_signed_get_attr_count(si) < 0) | ||
382 | continue; | ||
383 | if (CMS_SignerInfo_verify(si) <= 0) | ||
384 | goto err; | ||
385 | } | ||
386 | } | ||
387 | |||
388 | /* Performance optimization: if the content is a memory BIO then | ||
389 | * store its contents in a temporary read only memory BIO. This | ||
390 | * avoids potentially large numbers of slow copies of data which will | ||
391 | * occur when reading from a read write memory BIO when signatures | ||
392 | * are calculated. | ||
393 | */ | ||
394 | |||
395 | if (dcont && (BIO_method_type(dcont) == BIO_TYPE_MEM)) | ||
396 | { | ||
397 | char *ptr; | ||
398 | long len; | ||
399 | len = BIO_get_mem_data(dcont, &ptr); | ||
400 | tmpin = BIO_new_mem_buf(ptr, len); | ||
401 | if (tmpin == NULL) | ||
402 | { | ||
403 | CMSerr(CMS_F_CMS_VERIFY,ERR_R_MALLOC_FAILURE); | ||
404 | return 0; | ||
405 | } | ||
406 | } | ||
407 | else | ||
408 | tmpin = dcont; | ||
409 | |||
410 | |||
411 | cmsbio=CMS_dataInit(cms, tmpin); | ||
412 | if (!cmsbio) | ||
413 | goto err; | ||
414 | |||
415 | if (!cms_copy_content(out, cmsbio, flags)) | ||
416 | goto err; | ||
417 | |||
418 | if (!(flags & CMS_NO_CONTENT_VERIFY)) | ||
419 | { | ||
420 | for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++) | ||
421 | { | ||
422 | si = sk_CMS_SignerInfo_value(sinfos, i); | ||
423 | if (!CMS_SignerInfo_verify_content(si, cmsbio)) | ||
424 | { | ||
425 | CMSerr(CMS_F_CMS_VERIFY, | ||
426 | CMS_R_CONTENT_VERIFY_ERROR); | ||
427 | goto err; | ||
428 | } | ||
429 | } | ||
430 | } | ||
431 | |||
432 | ret = 1; | ||
433 | |||
434 | err: | ||
435 | |||
436 | if (dcont && (tmpin == dcont)) | ||
437 | do_free_upto(cmsbio, dcont); | ||
438 | else | ||
439 | BIO_free_all(cmsbio); | ||
440 | |||
441 | if (cms_certs) | ||
442 | sk_X509_pop_free(cms_certs, X509_free); | ||
443 | if (crls) | ||
444 | sk_X509_CRL_pop_free(crls, X509_CRL_free); | ||
445 | |||
446 | return ret; | ||
447 | } | ||
448 | |||
449 | int CMS_verify_receipt(CMS_ContentInfo *rcms, CMS_ContentInfo *ocms, | ||
450 | STACK_OF(X509) *certs, | ||
451 | X509_STORE *store, unsigned int flags) | ||
452 | { | ||
453 | int r; | ||
454 | r = CMS_verify(rcms, certs, store, NULL, NULL, flags); | ||
455 | if (r <= 0) | ||
456 | return r; | ||
457 | return cms_Receipt_verify(rcms, ocms); | ||
458 | } | ||
459 | |||
460 | CMS_ContentInfo *CMS_sign(X509 *signcert, EVP_PKEY *pkey, STACK_OF(X509) *certs, | ||
461 | BIO *data, unsigned int flags) | ||
462 | { | ||
463 | CMS_ContentInfo *cms; | ||
464 | int i; | ||
465 | |||
466 | cms = CMS_ContentInfo_new(); | ||
467 | if (!cms || !CMS_SignedData_init(cms)) | ||
468 | goto merr; | ||
469 | |||
470 | if (pkey && !CMS_add1_signer(cms, signcert, pkey, NULL, flags)) | ||
471 | { | ||
472 | CMSerr(CMS_F_CMS_SIGN, CMS_R_ADD_SIGNER_ERROR); | ||
473 | goto err; | ||
474 | } | ||
475 | |||
476 | for (i = 0; i < sk_X509_num(certs); i++) | ||
477 | { | ||
478 | X509 *x = sk_X509_value(certs, i); | ||
479 | if (!CMS_add1_cert(cms, x)) | ||
480 | goto merr; | ||
481 | } | ||
482 | |||
483 | if(!(flags & CMS_DETACHED)) | ||
484 | { | ||
485 | flags &= ~CMS_STREAM; | ||
486 | CMS_set_detached(cms, 0); | ||
487 | } | ||
488 | |||
489 | if ((flags & (CMS_STREAM|CMS_PARTIAL)) | ||
490 | || CMS_final(cms, data, NULL, flags)) | ||
491 | return cms; | ||
492 | else | ||
493 | goto err; | ||
494 | |||
495 | merr: | ||
496 | CMSerr(CMS_F_CMS_SIGN, ERR_R_MALLOC_FAILURE); | ||
497 | |||
498 | err: | ||
499 | if (cms) | ||
500 | CMS_ContentInfo_free(cms); | ||
501 | return NULL; | ||
502 | } | ||
503 | |||
504 | CMS_ContentInfo *CMS_sign_receipt(CMS_SignerInfo *si, | ||
505 | X509 *signcert, EVP_PKEY *pkey, | ||
506 | STACK_OF(X509) *certs, | ||
507 | unsigned int flags) | ||
508 | { | ||
509 | CMS_SignerInfo *rct_si; | ||
510 | CMS_ContentInfo *cms = NULL; | ||
511 | ASN1_OCTET_STRING **pos, *os; | ||
512 | BIO *rct_cont = NULL; | ||
513 | int r = 0; | ||
514 | |||
515 | flags &= ~CMS_STREAM; | ||
516 | /* Not really detached but avoids content being allocated */ | ||
517 | flags |= CMS_PARTIAL|CMS_BINARY|CMS_DETACHED; | ||
518 | if (!pkey || !signcert) | ||
519 | { | ||
520 | CMSerr(CMS_F_CMS_SIGN_RECEIPT, CMS_R_NO_KEY_OR_CERT); | ||
521 | return NULL; | ||
522 | } | ||
523 | |||
524 | /* Initialize signed data */ | ||
525 | |||
526 | cms = CMS_sign(NULL, NULL, certs, NULL, flags); | ||
527 | if (!cms) | ||
528 | goto err; | ||
529 | |||
530 | /* Set inner content type to signed receipt */ | ||
531 | if (!CMS_set1_eContentType(cms, OBJ_nid2obj(NID_id_smime_ct_receipt))) | ||
532 | goto err; | ||
533 | |||
534 | rct_si = CMS_add1_signer(cms, signcert, pkey, NULL, flags); | ||
535 | if (!rct_si) | ||
536 | { | ||
537 | CMSerr(CMS_F_CMS_SIGN_RECEIPT, CMS_R_ADD_SIGNER_ERROR); | ||
538 | goto err; | ||
539 | } | ||
540 | |||
541 | os = cms_encode_Receipt(si); | ||
542 | |||
543 | if (!os) | ||
544 | goto err; | ||
545 | |||
546 | /* Set content to digest */ | ||
547 | rct_cont = BIO_new_mem_buf(os->data, os->length); | ||
548 | if (!rct_cont) | ||
549 | goto err; | ||
550 | |||
551 | /* Add msgSigDigest attribute */ | ||
552 | |||
553 | if (!cms_msgSigDigest_add1(rct_si, si)) | ||
554 | goto err; | ||
555 | |||
556 | /* Finalize structure */ | ||
557 | if (!CMS_final(cms, rct_cont, NULL, flags)) | ||
558 | goto err; | ||
559 | |||
560 | /* Set embedded content */ | ||
561 | pos = CMS_get0_content(cms); | ||
562 | *pos = os; | ||
563 | |||
564 | r = 1; | ||
565 | |||
566 | err: | ||
567 | if (rct_cont) | ||
568 | BIO_free(rct_cont); | ||
569 | if (r) | ||
570 | return cms; | ||
571 | CMS_ContentInfo_free(cms); | ||
572 | return NULL; | ||
573 | |||
574 | } | ||
575 | |||
576 | CMS_ContentInfo *CMS_encrypt(STACK_OF(X509) *certs, BIO *data, | ||
577 | const EVP_CIPHER *cipher, unsigned int flags) | ||
578 | { | ||
579 | CMS_ContentInfo *cms; | ||
580 | int i; | ||
581 | X509 *recip; | ||
582 | cms = CMS_EnvelopedData_create(cipher); | ||
583 | if (!cms) | ||
584 | goto merr; | ||
585 | for (i = 0; i < sk_X509_num(certs); i++) | ||
586 | { | ||
587 | recip = sk_X509_value(certs, i); | ||
588 | if (!CMS_add1_recipient_cert(cms, recip, flags)) | ||
589 | { | ||
590 | CMSerr(CMS_F_CMS_ENCRYPT, CMS_R_RECIPIENT_ERROR); | ||
591 | goto err; | ||
592 | } | ||
593 | } | ||
594 | |||
595 | if(!(flags & CMS_DETACHED)) | ||
596 | { | ||
597 | flags &= ~CMS_STREAM; | ||
598 | CMS_set_detached(cms, 0); | ||
599 | } | ||
600 | |||
601 | if ((flags & (CMS_STREAM|CMS_PARTIAL)) | ||
602 | || CMS_final(cms, data, NULL, flags)) | ||
603 | return cms; | ||
604 | else | ||
605 | goto err; | ||
606 | |||
607 | merr: | ||
608 | CMSerr(CMS_F_CMS_ENCRYPT, ERR_R_MALLOC_FAILURE); | ||
609 | err: | ||
610 | if (cms) | ||
611 | CMS_ContentInfo_free(cms); | ||
612 | return NULL; | ||
613 | } | ||
614 | |||
615 | int CMS_decrypt_set1_pkey(CMS_ContentInfo *cms, EVP_PKEY *pk, X509 *cert) | ||
616 | { | ||
617 | STACK_OF(CMS_RecipientInfo) *ris; | ||
618 | CMS_RecipientInfo *ri; | ||
619 | int i, r; | ||
620 | ris = CMS_get0_RecipientInfos(cms); | ||
621 | for (i = 0; i < sk_CMS_RecipientInfo_num(ris); i++) | ||
622 | { | ||
623 | ri = sk_CMS_RecipientInfo_value(ris, i); | ||
624 | if (CMS_RecipientInfo_type(ri) != CMS_RECIPINFO_TRANS) | ||
625 | continue; | ||
626 | /* If we have a cert try matching RecipientInfo | ||
627 | * otherwise try them all. | ||
628 | */ | ||
629 | if (!cert || (CMS_RecipientInfo_ktri_cert_cmp(ri, cert) == 0)) | ||
630 | { | ||
631 | CMS_RecipientInfo_set0_pkey(ri, pk); | ||
632 | r = CMS_RecipientInfo_decrypt(cms, ri); | ||
633 | CMS_RecipientInfo_set0_pkey(ri, NULL); | ||
634 | if (r > 0) | ||
635 | return 1; | ||
636 | if (cert) | ||
637 | { | ||
638 | CMSerr(CMS_F_CMS_DECRYPT_SET1_PKEY, | ||
639 | CMS_R_DECRYPT_ERROR); | ||
640 | return 0; | ||
641 | } | ||
642 | ERR_clear_error(); | ||
643 | } | ||
644 | } | ||
645 | |||
646 | CMSerr(CMS_F_CMS_DECRYPT_SET1_PKEY, CMS_R_NO_MATCHING_RECIPIENT); | ||
647 | return 0; | ||
648 | |||
649 | } | ||
650 | |||
651 | int CMS_decrypt_set1_key(CMS_ContentInfo *cms, | ||
652 | unsigned char *key, size_t keylen, | ||
653 | unsigned char *id, size_t idlen) | ||
654 | { | ||
655 | STACK_OF(CMS_RecipientInfo) *ris; | ||
656 | CMS_RecipientInfo *ri; | ||
657 | int i, r; | ||
658 | ris = CMS_get0_RecipientInfos(cms); | ||
659 | for (i = 0; i < sk_CMS_RecipientInfo_num(ris); i++) | ||
660 | { | ||
661 | ri = sk_CMS_RecipientInfo_value(ris, i); | ||
662 | if (CMS_RecipientInfo_type(ri) != CMS_RECIPINFO_KEK) | ||
663 | continue; | ||
664 | |||
665 | /* If we have an id try matching RecipientInfo | ||
666 | * otherwise try them all. | ||
667 | */ | ||
668 | if (!id || (CMS_RecipientInfo_kekri_id_cmp(ri, id, idlen) == 0)) | ||
669 | { | ||
670 | CMS_RecipientInfo_set0_key(ri, key, keylen); | ||
671 | r = CMS_RecipientInfo_decrypt(cms, ri); | ||
672 | CMS_RecipientInfo_set0_key(ri, NULL, 0); | ||
673 | if (r > 0) | ||
674 | return 1; | ||
675 | if (id) | ||
676 | { | ||
677 | CMSerr(CMS_F_CMS_DECRYPT_SET1_KEY, | ||
678 | CMS_R_DECRYPT_ERROR); | ||
679 | return 0; | ||
680 | } | ||
681 | ERR_clear_error(); | ||
682 | } | ||
683 | } | ||
684 | |||
685 | CMSerr(CMS_F_CMS_DECRYPT_SET1_KEY, CMS_R_NO_MATCHING_RECIPIENT); | ||
686 | return 0; | ||
687 | |||
688 | } | ||
689 | |||
690 | int CMS_decrypt(CMS_ContentInfo *cms, EVP_PKEY *pk, X509 *cert, | ||
691 | BIO *dcont, BIO *out, | ||
692 | unsigned int flags) | ||
693 | { | ||
694 | int r; | ||
695 | BIO *cont; | ||
696 | if (OBJ_obj2nid(CMS_get0_type(cms)) != NID_pkcs7_enveloped) | ||
697 | { | ||
698 | CMSerr(CMS_F_CMS_DECRYPT, CMS_R_TYPE_NOT_ENVELOPED_DATA); | ||
699 | return 0; | ||
700 | } | ||
701 | if (!dcont && !check_content(cms)) | ||
702 | return 0; | ||
703 | if (pk && !CMS_decrypt_set1_pkey(cms, pk, cert)) | ||
704 | return 0; | ||
705 | |||
706 | cont = CMS_dataInit(cms, dcont); | ||
707 | if (!cont) | ||
708 | return 0; | ||
709 | r = cms_copy_content(out, cont, flags); | ||
710 | do_free_upto(cont, dcont); | ||
711 | return r; | ||
712 | } | ||
713 | |||
714 | int CMS_final(CMS_ContentInfo *cms, BIO *data, BIO *dcont, unsigned int flags) | ||
715 | { | ||
716 | BIO *cmsbio; | ||
717 | int ret = 0; | ||
718 | if (!(cmsbio = CMS_dataInit(cms, dcont))) | ||
719 | { | ||
720 | CMSerr(CMS_F_CMS_FINAL,ERR_R_MALLOC_FAILURE); | ||
721 | return 0; | ||
722 | } | ||
723 | |||
724 | SMIME_crlf_copy(data, cmsbio, flags); | ||
725 | |||
726 | (void)BIO_flush(cmsbio); | ||
727 | |||
728 | |||
729 | if (!CMS_dataFinal(cms, cmsbio)) | ||
730 | { | ||
731 | CMSerr(CMS_F_CMS_FINAL,CMS_R_CMS_DATAFINAL_ERROR); | ||
732 | goto err; | ||
733 | } | ||
734 | |||
735 | ret = 1; | ||
736 | |||
737 | err: | ||
738 | do_free_upto(cmsbio, dcont); | ||
739 | |||
740 | return ret; | ||
741 | |||
742 | } | ||
743 | |||
744 | #ifdef ZLIB | ||
745 | |||
746 | int CMS_uncompress(CMS_ContentInfo *cms, BIO *dcont, BIO *out, | ||
747 | unsigned int flags) | ||
748 | { | ||
749 | BIO *cont; | ||
750 | int r; | ||
751 | if (OBJ_obj2nid(CMS_get0_type(cms)) != NID_id_smime_ct_compressedData) | ||
752 | { | ||
753 | CMSerr(CMS_F_CMS_UNCOMPRESS, | ||
754 | CMS_R_TYPE_NOT_COMPRESSED_DATA); | ||
755 | return 0; | ||
756 | } | ||
757 | |||
758 | if (!dcont && !check_content(cms)) | ||
759 | return 0; | ||
760 | |||
761 | cont = CMS_dataInit(cms, dcont); | ||
762 | if (!cont) | ||
763 | return 0; | ||
764 | r = cms_copy_content(out, cont, flags); | ||
765 | do_free_upto(cont, dcont); | ||
766 | return r; | ||
767 | } | ||
768 | |||
769 | CMS_ContentInfo *CMS_compress(BIO *in, int comp_nid, unsigned int flags) | ||
770 | { | ||
771 | CMS_ContentInfo *cms; | ||
772 | if (comp_nid <= 0) | ||
773 | comp_nid = NID_zlib_compression; | ||
774 | cms = cms_CompressedData_create(comp_nid); | ||
775 | if (!cms) | ||
776 | return NULL; | ||
777 | |||
778 | if(!(flags & CMS_DETACHED)) | ||
779 | { | ||
780 | flags &= ~CMS_STREAM; | ||
781 | CMS_set_detached(cms, 0); | ||
782 | } | ||
783 | |||
784 | if (CMS_final(cms, in, NULL, flags)) | ||
785 | return cms; | ||
786 | |||
787 | CMS_ContentInfo_free(cms); | ||
788 | return NULL; | ||
789 | } | ||
790 | |||
791 | #else | ||
792 | |||
793 | int CMS_uncompress(CMS_ContentInfo *cms, BIO *dcont, BIO *out, | ||
794 | unsigned int flags) | ||
795 | { | ||
796 | CMSerr(CMS_F_CMS_UNCOMPRESS, CMS_R_UNSUPPORTED_COMPRESSION_ALGORITHM); | ||
797 | return 0; | ||
798 | } | ||
799 | |||
800 | CMS_ContentInfo *CMS_compress(BIO *in, int comp_nid, unsigned int flags) | ||
801 | { | ||
802 | CMSerr(CMS_F_CMS_COMPRESS, CMS_R_UNSUPPORTED_COMPRESSION_ALGORITHM); | ||
803 | return NULL; | ||
804 | } | ||
805 | |||
806 | #endif | ||
diff --git a/src/lib/libcrypto/des/asm/des_enc.m4 b/src/lib/libcrypto/des/asm/des_enc.m4 new file mode 100644 index 0000000000..f5b1928f99 --- /dev/null +++ b/src/lib/libcrypto/des/asm/des_enc.m4 | |||
@@ -0,0 +1,1980 @@ | |||
1 | ! des_enc.m4 | ||
2 | ! des_enc.S (generated from des_enc.m4) | ||
3 | ! | ||
4 | ! UltraSPARC assembler version of the LibDES/SSLeay/OpenSSL des_enc.c file. | ||
5 | ! | ||
6 | ! Version 1.0. 32-bit version. | ||
7 | ! | ||
8 | ! June 8, 2000. | ||
9 | ! | ||
10 | ! Version 2.0. 32/64-bit, PIC-ification, blended CPU adaptation | ||
11 | ! by Andy Polyakov. | ||
12 | ! | ||
13 | ! January 1, 2003. | ||
14 | ! | ||
15 | ! Assembler version: Copyright Svend Olaf Mikkelsen. | ||
16 | ! | ||
17 | ! Original C code: Copyright Eric A. Young. | ||
18 | ! | ||
19 | ! This code can be freely used by LibDES/SSLeay/OpenSSL users. | ||
20 | ! | ||
21 | ! The LibDES/SSLeay/OpenSSL copyright notices must be respected. | ||
22 | ! | ||
23 | ! This version can be redistributed. | ||
24 | ! | ||
25 | ! To expand the m4 macros: m4 -B 8192 des_enc.m4 > des_enc.S | ||
26 | ! | ||
27 | ! Global registers 1 to 5 are used. This is the same as done by the | ||
28 | ! cc compiler. The UltraSPARC load/store little endian feature is used. | ||
29 | ! | ||
30 | ! Instruction grouping often refers to one CPU cycle. | ||
31 | ! | ||
32 | ! Assemble through gcc: gcc -c -mcpu=ultrasparc -o des_enc.o des_enc.S | ||
33 | ! | ||
34 | ! Assemble through cc: cc -c -xarch=v8plusa -o des_enc.o des_enc.S | ||
35 | ! | ||
36 | ! Performance improvement according to './apps/openssl speed des' | ||
37 | ! | ||
38 | ! 32-bit build: | ||
39 | ! 23% faster than cc-5.2 -xarch=v8plus -xO5 | ||
40 | ! 115% faster than gcc-3.2.1 -m32 -mcpu=ultrasparc -O5 | ||
41 | ! 64-bit build: | ||
42 | ! 50% faster than cc-5.2 -xarch=v9 -xO5 | ||
43 | ! 100% faster than gcc-3.2.1 -m64 -mcpu=ultrasparc -O5 | ||
44 | ! | ||
45 | |||
46 | .ident "des_enc.m4 2.1" | ||
47 | |||
48 | #if defined(__SUNPRO_C) && defined(__sparcv9) | ||
49 | # define ABI64 /* They've said -xarch=v9 at command line */ | ||
50 | #elif defined(__GNUC__) && defined(__arch64__) | ||
51 | # define ABI64 /* They've said -m64 at command line */ | ||
52 | #endif | ||
53 | |||
54 | #ifdef ABI64 | ||
55 | .register %g2,#scratch | ||
56 | .register %g3,#scratch | ||
57 | # define FRAME -192 | ||
58 | # define BIAS 2047 | ||
59 | # define LDPTR ldx | ||
60 | # define STPTR stx | ||
61 | # define ARG0 128 | ||
62 | # define ARGSZ 8 | ||
63 | # ifndef OPENSSL_SYSNAME_ULTRASPARC | ||
64 | # define OPENSSL_SYSNAME_ULTRASPARC | ||
65 | # endif | ||
66 | #else | ||
67 | # define FRAME -96 | ||
68 | # define BIAS 0 | ||
69 | # define LDPTR ld | ||
70 | # define STPTR st | ||
71 | # define ARG0 68 | ||
72 | # define ARGSZ 4 | ||
73 | #endif | ||
74 | |||
75 | #define LOOPS 7 | ||
76 | |||
77 | #define global0 %g0 | ||
78 | #define global1 %g1 | ||
79 | #define global2 %g2 | ||
80 | #define global3 %g3 | ||
81 | #define global4 %g4 | ||
82 | #define global5 %g5 | ||
83 | |||
84 | #define local0 %l0 | ||
85 | #define local1 %l1 | ||
86 | #define local2 %l2 | ||
87 | #define local3 %l3 | ||
88 | #define local4 %l4 | ||
89 | #define local5 %l5 | ||
90 | #define local7 %l6 | ||
91 | #define local6 %l7 | ||
92 | |||
93 | #define in0 %i0 | ||
94 | #define in1 %i1 | ||
95 | #define in2 %i2 | ||
96 | #define in3 %i3 | ||
97 | #define in4 %i4 | ||
98 | #define in5 %i5 | ||
99 | #define in6 %i6 | ||
100 | #define in7 %i7 | ||
101 | |||
102 | #define out0 %o0 | ||
103 | #define out1 %o1 | ||
104 | #define out2 %o2 | ||
105 | #define out3 %o3 | ||
106 | #define out4 %o4 | ||
107 | #define out5 %o5 | ||
108 | #define out6 %o6 | ||
109 | #define out7 %o7 | ||
110 | |||
111 | #define stub stb | ||
112 | |||
113 | changequote({,}) | ||
114 | |||
115 | |||
116 | ! Macro definitions: | ||
117 | |||
118 | |||
119 | ! {ip_macro} | ||
120 | ! | ||
121 | ! The logic used in initial and final permutations is the same as in | ||
122 | ! the C code. The permutations are done with a clever shift, xor, and | ||
123 | ! technique. | ||
124 | ! | ||
125 | ! The macro also loads address sbox 1 to 5 to global 1 to 5, address | ||
126 | ! sbox 6 to local6, and addres sbox 8 to out3. | ||
127 | ! | ||
128 | ! Rotates the halfs 3 left to bring the sbox bits in convenient positions. | ||
129 | ! | ||
130 | ! Loads key first round from address in parameter 5 to out0, out1. | ||
131 | ! | ||
132 | ! After the the original LibDES initial permutation, the resulting left | ||
133 | ! is in the variable initially used for right and vice versa. The macro | ||
134 | ! implements the possibility to keep the halfs in the original registers. | ||
135 | ! | ||
136 | ! parameter 1 left | ||
137 | ! parameter 2 right | ||
138 | ! parameter 3 result left (modify in first round) | ||
139 | ! parameter 4 result right (use in first round) | ||
140 | ! parameter 5 key address | ||
141 | ! parameter 6 1/2 for include encryption/decryption | ||
142 | ! parameter 7 1 for move in1 to in3 | ||
143 | ! parameter 8 1 for move in3 to in4, 2 for move in4 to in3 | ||
144 | ! parameter 9 1 for load ks3 and ks2 to in4 and in3 | ||
145 | |||
146 | define(ip_macro, { | ||
147 | |||
148 | ! {ip_macro} | ||
149 | ! $1 $2 $4 $3 $5 $6 $7 $8 $9 | ||
150 | |||
151 | ld [out2+256], local1 | ||
152 | srl $2, 4, local4 | ||
153 | |||
154 | xor local4, $1, local4 | ||
155 | ifelse($7,1,{mov in1, in3},{nop}) | ||
156 | |||
157 | ld [out2+260], local2 | ||
158 | and local4, local1, local4 | ||
159 | ifelse($8,1,{mov in3, in4},{}) | ||
160 | ifelse($8,2,{mov in4, in3},{}) | ||
161 | |||
162 | ld [out2+280], out4 ! loop counter | ||
163 | sll local4, 4, local1 | ||
164 | xor $1, local4, $1 | ||
165 | |||
166 | ld [out2+264], local3 | ||
167 | srl $1, 16, local4 | ||
168 | xor $2, local1, $2 | ||
169 | |||
170 | ifelse($9,1,{LDPTR KS3, in4},{}) | ||
171 | xor local4, $2, local4 | ||
172 | nop !sethi %hi(DES_SPtrans), global1 ! sbox addr | ||
173 | |||
174 | ifelse($9,1,{LDPTR KS2, in3},{}) | ||
175 | and local4, local2, local4 | ||
176 | nop !or global1, %lo(DES_SPtrans), global1 ! sbox addr | ||
177 | |||
178 | sll local4, 16, local1 | ||
179 | xor $2, local4, $2 | ||
180 | |||
181 | srl $2, 2, local4 | ||
182 | xor $1, local1, $1 | ||
183 | |||
184 | sethi %hi(16711680), local5 | ||
185 | xor local4, $1, local4 | ||
186 | |||
187 | and local4, local3, local4 | ||
188 | or local5, 255, local5 | ||
189 | |||
190 | sll local4, 2, local2 | ||
191 | xor $1, local4, $1 | ||
192 | |||
193 | srl $1, 8, local4 | ||
194 | xor $2, local2, $2 | ||
195 | |||
196 | xor local4, $2, local4 | ||
197 | add global1, 768, global4 | ||
198 | |||
199 | and local4, local5, local4 | ||
200 | add global1, 1024, global5 | ||
201 | |||
202 | ld [out2+272], local7 | ||
203 | sll local4, 8, local1 | ||
204 | xor $2, local4, $2 | ||
205 | |||
206 | srl $2, 1, local4 | ||
207 | xor $1, local1, $1 | ||
208 | |||
209 | ld [$5], out0 ! key 7531 | ||
210 | xor local4, $1, local4 | ||
211 | add global1, 256, global2 | ||
212 | |||
213 | ld [$5+4], out1 ! key 8642 | ||
214 | and local4, local7, local4 | ||
215 | add global1, 512, global3 | ||
216 | |||
217 | sll local4, 1, local1 | ||
218 | xor $1, local4, $1 | ||
219 | |||
220 | sll $1, 3, local3 | ||
221 | xor $2, local1, $2 | ||
222 | |||
223 | sll $2, 3, local2 | ||
224 | add global1, 1280, local6 ! address sbox 8 | ||
225 | |||
226 | srl $1, 29, local4 | ||
227 | add global1, 1792, out3 ! address sbox 8 | ||
228 | |||
229 | srl $2, 29, local1 | ||
230 | or local4, local3, $4 | ||
231 | |||
232 | or local2, local1, $3 | ||
233 | |||
234 | ifelse($6, 1, { | ||
235 | |||
236 | ld [out2+284], local5 ! 0x0000FC00 used in the rounds | ||
237 | or local2, local1, $3 | ||
238 | xor $4, out0, local1 | ||
239 | |||
240 | call .des_enc.1 | ||
241 | and local1, 252, local1 | ||
242 | |||
243 | },{}) | ||
244 | |||
245 | ifelse($6, 2, { | ||
246 | |||
247 | ld [out2+284], local5 ! 0x0000FC00 used in the rounds | ||
248 | or local2, local1, $3 | ||
249 | xor $4, out0, local1 | ||
250 | |||
251 | call .des_dec.1 | ||
252 | and local1, 252, local1 | ||
253 | |||
254 | },{}) | ||
255 | }) | ||
256 | |||
257 | |||
258 | ! {rounds_macro} | ||
259 | ! | ||
260 | ! The logic used in the DES rounds is the same as in the C code, | ||
261 | ! except that calculations for sbox 1 and sbox 5 begin before | ||
262 | ! the previous round is finished. | ||
263 | ! | ||
264 | ! In each round one half (work) is modified based on key and the | ||
265 | ! other half (use). | ||
266 | ! | ||
267 | ! In this version we do two rounds in a loop repeated 7 times | ||
268 | ! and two rounds seperately. | ||
269 | ! | ||
270 | ! One half has the bits for the sboxes in the following positions: | ||
271 | ! | ||
272 | ! 777777xx555555xx333333xx111111xx | ||
273 | ! | ||
274 | ! 88xx666666xx444444xx222222xx8888 | ||
275 | ! | ||
276 | ! The bits for each sbox are xor-ed with the key bits for that box. | ||
277 | ! The above xx bits are cleared, and the result used for lookup in | ||
278 | ! the sbox table. Each sbox entry contains the 4 output bits permuted | ||
279 | ! into 32 bits according to the P permutation. | ||
280 | ! | ||
281 | ! In the description of DES, left and right are switched after | ||
282 | ! each round, except after last round. In this code the original | ||
283 | ! left and right are kept in the same register in all rounds, meaning | ||
284 | ! that after the 16 rounds the result for right is in the register | ||
285 | ! originally used for left. | ||
286 | ! | ||
287 | ! parameter 1 first work (left in first round) | ||
288 | ! parameter 2 first use (right in first round) | ||
289 | ! parameter 3 enc/dec 1/-1 | ||
290 | ! parameter 4 loop label | ||
291 | ! parameter 5 key address register | ||
292 | ! parameter 6 optional address for key next encryption/decryption | ||
293 | ! parameter 7 not empty for include retl | ||
294 | ! | ||
295 | ! also compares in2 to 8 | ||
296 | |||
297 | define(rounds_macro, { | ||
298 | |||
299 | ! {rounds_macro} | ||
300 | ! $1 $2 $3 $4 $5 $6 $7 $8 $9 | ||
301 | |||
302 | xor $2, out0, local1 | ||
303 | |||
304 | ld [out2+284], local5 ! 0x0000FC00 | ||
305 | ba $4 | ||
306 | and local1, 252, local1 | ||
307 | |||
308 | .align 32 | ||
309 | |||
310 | $4: | ||
311 | ! local6 is address sbox 6 | ||
312 | ! out3 is address sbox 8 | ||
313 | ! out4 is loop counter | ||
314 | |||
315 | ld [global1+local1], local1 | ||
316 | xor $2, out1, out1 ! 8642 | ||
317 | xor $2, out0, out0 ! 7531 | ||
318 | fmovs %f0, %f0 ! fxor used for alignment | ||
319 | |||
320 | srl out1, 4, local0 ! rotate 4 right | ||
321 | and out0, local5, local3 ! 3 | ||
322 | fmovs %f0, %f0 | ||
323 | |||
324 | ld [$5+$3*8], local7 ! key 7531 next round | ||
325 | srl local3, 8, local3 ! 3 | ||
326 | and local0, 252, local2 ! 2 | ||
327 | fmovs %f0, %f0 | ||
328 | |||
329 | ld [global3+local3],local3 ! 3 | ||
330 | sll out1, 28, out1 ! rotate | ||
331 | xor $1, local1, $1 ! 1 finished, local1 now sbox 7 | ||
332 | |||
333 | ld [global2+local2], local2 ! 2 | ||
334 | srl out0, 24, local1 ! 7 | ||
335 | or out1, local0, out1 ! rotate | ||
336 | |||
337 | ldub [out2+local1], local1 ! 7 (and 0xFC) | ||
338 | srl out1, 24, local0 ! 8 | ||
339 | and out1, local5, local4 ! 4 | ||
340 | |||
341 | ldub [out2+local0], local0 ! 8 (and 0xFC) | ||
342 | srl local4, 8, local4 ! 4 | ||
343 | xor $1, local2, $1 ! 2 finished local2 now sbox 6 | ||
344 | |||
345 | ld [global4+local4],local4 ! 4 | ||
346 | srl out1, 16, local2 ! 6 | ||
347 | xor $1, local3, $1 ! 3 finished local3 now sbox 5 | ||
348 | |||
349 | ld [out3+local0],local0 ! 8 | ||
350 | and local2, 252, local2 ! 6 | ||
351 | add global1, 1536, local5 ! address sbox 7 | ||
352 | |||
353 | ld [local6+local2], local2 ! 6 | ||
354 | srl out0, 16, local3 ! 5 | ||
355 | xor $1, local4, $1 ! 4 finished | ||
356 | |||
357 | ld [local5+local1],local1 ! 7 | ||
358 | and local3, 252, local3 ! 5 | ||
359 | xor $1, local0, $1 ! 8 finished | ||
360 | |||
361 | ld [global5+local3],local3 ! 5 | ||
362 | xor $1, local2, $1 ! 6 finished | ||
363 | subcc out4, 1, out4 | ||
364 | |||
365 | ld [$5+$3*8+4], out0 ! key 8642 next round | ||
366 | xor $1, local7, local2 ! sbox 5 next round | ||
367 | xor $1, local1, $1 ! 7 finished | ||
368 | |||
369 | srl local2, 16, local2 ! sbox 5 next round | ||
370 | xor $1, local3, $1 ! 5 finished | ||
371 | |||
372 | ld [$5+$3*16+4], out1 ! key 8642 next round again | ||
373 | and local2, 252, local2 ! sbox5 next round | ||
374 | ! next round | ||
375 | xor $1, local7, local7 ! 7531 | ||
376 | |||
377 | ld [global5+local2], local2 ! 5 | ||
378 | srl local7, 24, local3 ! 7 | ||
379 | xor $1, out0, out0 ! 8642 | ||
380 | |||
381 | ldub [out2+local3], local3 ! 7 (and 0xFC) | ||
382 | srl out0, 4, local0 ! rotate 4 right | ||
383 | and local7, 252, local1 ! 1 | ||
384 | |||
385 | sll out0, 28, out0 ! rotate | ||
386 | xor $2, local2, $2 ! 5 finished local2 used | ||
387 | |||
388 | srl local0, 8, local4 ! 4 | ||
389 | and local0, 252, local2 ! 2 | ||
390 | ld [local5+local3], local3 ! 7 | ||
391 | |||
392 | srl local0, 16, local5 ! 6 | ||
393 | or out0, local0, out0 ! rotate | ||
394 | ld [global2+local2], local2 ! 2 | ||
395 | |||
396 | srl out0, 24, local0 | ||
397 | ld [$5+$3*16], out0 ! key 7531 next round | ||
398 | and local4, 252, local4 ! 4 | ||
399 | |||
400 | and local5, 252, local5 ! 6 | ||
401 | ld [global4+local4], local4 ! 4 | ||
402 | xor $2, local3, $2 ! 7 finished local3 used | ||
403 | |||
404 | and local0, 252, local0 ! 8 | ||
405 | ld [local6+local5], local5 ! 6 | ||
406 | xor $2, local2, $2 ! 2 finished local2 now sbox 3 | ||
407 | |||
408 | srl local7, 8, local2 ! 3 start | ||
409 | ld [out3+local0], local0 ! 8 | ||
410 | xor $2, local4, $2 ! 4 finished | ||
411 | |||
412 | and local2, 252, local2 ! 3 | ||
413 | ld [global1+local1], local1 ! 1 | ||
414 | xor $2, local5, $2 ! 6 finished local5 used | ||
415 | |||
416 | ld [global3+local2], local2 ! 3 | ||
417 | xor $2, local0, $2 ! 8 finished | ||
418 | add $5, $3*16, $5 ! enc add 8, dec add -8 to key pointer | ||
419 | |||
420 | ld [out2+284], local5 ! 0x0000FC00 | ||
421 | xor $2, out0, local4 ! sbox 1 next round | ||
422 | xor $2, local1, $2 ! 1 finished | ||
423 | |||
424 | xor $2, local2, $2 ! 3 finished | ||
425 | #ifdef OPENSSL_SYSNAME_ULTRASPARC | ||
426 | bne,pt %icc, $4 | ||
427 | #else | ||
428 | bne $4 | ||
429 | #endif | ||
430 | and local4, 252, local1 ! sbox 1 next round | ||
431 | |||
432 | ! two rounds more: | ||
433 | |||
434 | ld [global1+local1], local1 | ||
435 | xor $2, out1, out1 | ||
436 | xor $2, out0, out0 | ||
437 | |||
438 | srl out1, 4, local0 ! rotate | ||
439 | and out0, local5, local3 | ||
440 | |||
441 | ld [$5+$3*8], local7 ! key 7531 | ||
442 | srl local3, 8, local3 | ||
443 | and local0, 252, local2 | ||
444 | |||
445 | ld [global3+local3],local3 | ||
446 | sll out1, 28, out1 ! rotate | ||
447 | xor $1, local1, $1 ! 1 finished, local1 now sbox 7 | ||
448 | |||
449 | ld [global2+local2], local2 | ||
450 | srl out0, 24, local1 | ||
451 | or out1, local0, out1 ! rotate | ||
452 | |||
453 | ldub [out2+local1], local1 | ||
454 | srl out1, 24, local0 | ||
455 | and out1, local5, local4 | ||
456 | |||
457 | ldub [out2+local0], local0 | ||
458 | srl local4, 8, local4 | ||
459 | xor $1, local2, $1 ! 2 finished local2 now sbox 6 | ||
460 | |||
461 | ld [global4+local4],local4 | ||
462 | srl out1, 16, local2 | ||
463 | xor $1, local3, $1 ! 3 finished local3 now sbox 5 | ||
464 | |||
465 | ld [out3+local0],local0 | ||
466 | and local2, 252, local2 | ||
467 | add global1, 1536, local5 ! address sbox 7 | ||
468 | |||
469 | ld [local6+local2], local2 | ||
470 | srl out0, 16, local3 | ||
471 | xor $1, local4, $1 ! 4 finished | ||
472 | |||
473 | ld [local5+local1],local1 | ||
474 | and local3, 252, local3 | ||
475 | xor $1, local0, $1 | ||
476 | |||
477 | ld [global5+local3],local3 | ||
478 | xor $1, local2, $1 ! 6 finished | ||
479 | cmp in2, 8 | ||
480 | |||
481 | ifelse($6,{}, {}, {ld [out2+280], out4}) ! loop counter | ||
482 | xor $1, local7, local2 ! sbox 5 next round | ||
483 | xor $1, local1, $1 ! 7 finished | ||
484 | |||
485 | ld [$5+$3*8+4], out0 | ||
486 | srl local2, 16, local2 ! sbox 5 next round | ||
487 | xor $1, local3, $1 ! 5 finished | ||
488 | |||
489 | and local2, 252, local2 | ||
490 | ! next round (two rounds more) | ||
491 | xor $1, local7, local7 ! 7531 | ||
492 | |||
493 | ld [global5+local2], local2 | ||
494 | srl local7, 24, local3 | ||
495 | xor $1, out0, out0 ! 8642 | ||
496 | |||
497 | ldub [out2+local3], local3 | ||
498 | srl out0, 4, local0 ! rotate | ||
499 | and local7, 252, local1 | ||
500 | |||
501 | sll out0, 28, out0 ! rotate | ||
502 | xor $2, local2, $2 ! 5 finished local2 used | ||
503 | |||
504 | srl local0, 8, local4 | ||
505 | and local0, 252, local2 | ||
506 | ld [local5+local3], local3 | ||
507 | |||
508 | srl local0, 16, local5 | ||
509 | or out0, local0, out0 ! rotate | ||
510 | ld [global2+local2], local2 | ||
511 | |||
512 | srl out0, 24, local0 | ||
513 | ifelse($6,{}, {}, {ld [$6], out0}) ! key next encryption/decryption | ||
514 | and local4, 252, local4 | ||
515 | |||
516 | and local5, 252, local5 | ||
517 | ld [global4+local4], local4 | ||
518 | xor $2, local3, $2 ! 7 finished local3 used | ||
519 | |||
520 | and local0, 252, local0 | ||
521 | ld [local6+local5], local5 | ||
522 | xor $2, local2, $2 ! 2 finished local2 now sbox 3 | ||
523 | |||
524 | srl local7, 8, local2 ! 3 start | ||
525 | ld [out3+local0], local0 | ||
526 | xor $2, local4, $2 | ||
527 | |||
528 | and local2, 252, local2 | ||
529 | ld [global1+local1], local1 | ||
530 | xor $2, local5, $2 ! 6 finished local5 used | ||
531 | |||
532 | ld [global3+local2], local2 | ||
533 | srl $1, 3, local3 | ||
534 | xor $2, local0, $2 | ||
535 | |||
536 | ifelse($6,{}, {}, {ld [$6+4], out1}) ! key next encryption/decryption | ||
537 | sll $1, 29, local4 | ||
538 | xor $2, local1, $2 | ||
539 | |||
540 | ifelse($7,{}, {}, {retl}) | ||
541 | xor $2, local2, $2 | ||
542 | }) | ||
543 | |||
544 | |||
545 | ! {fp_macro} | ||
546 | ! | ||
547 | ! parameter 1 right (original left) | ||
548 | ! parameter 2 left (original right) | ||
549 | ! parameter 3 1 for optional store to [in0] | ||
550 | ! parameter 4 1 for load input/output address to local5/7 | ||
551 | ! | ||
552 | ! The final permutation logic switches the halfes, meaning that | ||
553 | ! left and right ends up the the registers originally used. | ||
554 | |||
555 | define(fp_macro, { | ||
556 | |||
557 | ! {fp_macro} | ||
558 | ! $1 $2 $3 $4 $5 $6 $7 $8 $9 | ||
559 | |||
560 | ! initially undo the rotate 3 left done after initial permutation | ||
561 | ! original left is received shifted 3 right and 29 left in local3/4 | ||
562 | |||
563 | sll $2, 29, local1 | ||
564 | or local3, local4, $1 | ||
565 | |||
566 | srl $2, 3, $2 | ||
567 | sethi %hi(0x55555555), local2 | ||
568 | |||
569 | or $2, local1, $2 | ||
570 | or local2, %lo(0x55555555), local2 | ||
571 | |||
572 | srl $2, 1, local3 | ||
573 | sethi %hi(0x00ff00ff), local1 | ||
574 | xor local3, $1, local3 | ||
575 | or local1, %lo(0x00ff00ff), local1 | ||
576 | and local3, local2, local3 | ||
577 | sethi %hi(0x33333333), local4 | ||
578 | sll local3, 1, local2 | ||
579 | |||
580 | xor $1, local3, $1 | ||
581 | |||
582 | srl $1, 8, local3 | ||
583 | xor $2, local2, $2 | ||
584 | xor local3, $2, local3 | ||
585 | or local4, %lo(0x33333333), local4 | ||
586 | and local3, local1, local3 | ||
587 | sethi %hi(0x0000ffff), local1 | ||
588 | sll local3, 8, local2 | ||
589 | |||
590 | xor $2, local3, $2 | ||
591 | |||
592 | srl $2, 2, local3 | ||
593 | xor $1, local2, $1 | ||
594 | xor local3, $1, local3 | ||
595 | or local1, %lo(0x0000ffff), local1 | ||
596 | and local3, local4, local3 | ||
597 | sethi %hi(0x0f0f0f0f), local4 | ||
598 | sll local3, 2, local2 | ||
599 | |||
600 | ifelse($4,1, {LDPTR INPUT, local5}) | ||
601 | xor $1, local3, $1 | ||
602 | |||
603 | ifelse($4,1, {LDPTR OUTPUT, local7}) | ||
604 | srl $1, 16, local3 | ||
605 | xor $2, local2, $2 | ||
606 | xor local3, $2, local3 | ||
607 | or local4, %lo(0x0f0f0f0f), local4 | ||
608 | and local3, local1, local3 | ||
609 | sll local3, 16, local2 | ||
610 | |||
611 | xor $2, local3, local1 | ||
612 | |||
613 | srl local1, 4, local3 | ||
614 | xor $1, local2, $1 | ||
615 | xor local3, $1, local3 | ||
616 | and local3, local4, local3 | ||
617 | sll local3, 4, local2 | ||
618 | |||
619 | xor $1, local3, $1 | ||
620 | |||
621 | ! optional store: | ||
622 | |||
623 | ifelse($3,1, {st $1, [in0]}) | ||
624 | |||
625 | xor local1, local2, $2 | ||
626 | |||
627 | ifelse($3,1, {st $2, [in0+4]}) | ||
628 | |||
629 | }) | ||
630 | |||
631 | |||
632 | ! {fp_ip_macro} | ||
633 | ! | ||
634 | ! Does initial permutation for next block mixed with | ||
635 | ! final permutation for current block. | ||
636 | ! | ||
637 | ! parameter 1 original left | ||
638 | ! parameter 2 original right | ||
639 | ! parameter 3 left ip | ||
640 | ! parameter 4 right ip | ||
641 | ! parameter 5 1: load ks1/ks2 to in3/in4, add 120 to in4 | ||
642 | ! 2: mov in4 to in3 | ||
643 | ! | ||
644 | ! also adds -8 to length in2 and loads loop counter to out4 | ||
645 | |||
646 | define(fp_ip_macro, { | ||
647 | |||
648 | ! {fp_ip_macro} | ||
649 | ! $1 $2 $3 $4 $5 $6 $7 $8 $9 | ||
650 | |||
651 | define({temp1},{out4}) | ||
652 | define({temp2},{local3}) | ||
653 | |||
654 | define({ip1},{local1}) | ||
655 | define({ip2},{local2}) | ||
656 | define({ip4},{local4}) | ||
657 | define({ip5},{local5}) | ||
658 | |||
659 | ! $1 in local3, local4 | ||
660 | |||
661 | ld [out2+256], ip1 | ||
662 | sll out5, 29, temp1 | ||
663 | or local3, local4, $1 | ||
664 | |||
665 | srl out5, 3, $2 | ||
666 | ifelse($5,2,{mov in4, in3}) | ||
667 | |||
668 | ld [out2+272], ip5 | ||
669 | srl $4, 4, local0 | ||
670 | or $2, temp1, $2 | ||
671 | |||
672 | srl $2, 1, temp1 | ||
673 | xor temp1, $1, temp1 | ||
674 | |||
675 | and temp1, ip5, temp1 | ||
676 | xor local0, $3, local0 | ||
677 | |||
678 | sll temp1, 1, temp2 | ||
679 | xor $1, temp1, $1 | ||
680 | |||
681 | and local0, ip1, local0 | ||
682 | add in2, -8, in2 | ||
683 | |||
684 | sll local0, 4, local7 | ||
685 | xor $3, local0, $3 | ||
686 | |||
687 | ld [out2+268], ip4 | ||
688 | srl $1, 8, temp1 | ||
689 | xor $2, temp2, $2 | ||
690 | ld [out2+260], ip2 | ||
691 | srl $3, 16, local0 | ||
692 | xor $4, local7, $4 | ||
693 | xor temp1, $2, temp1 | ||
694 | xor local0, $4, local0 | ||
695 | and temp1, ip4, temp1 | ||
696 | and local0, ip2, local0 | ||
697 | sll temp1, 8, temp2 | ||
698 | xor $2, temp1, $2 | ||
699 | sll local0, 16, local7 | ||
700 | xor $4, local0, $4 | ||
701 | |||
702 | srl $2, 2, temp1 | ||
703 | xor $1, temp2, $1 | ||
704 | |||
705 | ld [out2+264], temp2 ! ip3 | ||
706 | srl $4, 2, local0 | ||
707 | xor $3, local7, $3 | ||
708 | xor temp1, $1, temp1 | ||
709 | xor local0, $3, local0 | ||
710 | and temp1, temp2, temp1 | ||
711 | and local0, temp2, local0 | ||
712 | sll temp1, 2, temp2 | ||
713 | xor $1, temp1, $1 | ||
714 | sll local0, 2, local7 | ||
715 | xor $3, local0, $3 | ||
716 | |||
717 | srl $1, 16, temp1 | ||
718 | xor $2, temp2, $2 | ||
719 | srl $3, 8, local0 | ||
720 | xor $4, local7, $4 | ||
721 | xor temp1, $2, temp1 | ||
722 | xor local0, $4, local0 | ||
723 | and temp1, ip2, temp1 | ||
724 | and local0, ip4, local0 | ||
725 | sll temp1, 16, temp2 | ||
726 | xor $2, temp1, local4 | ||
727 | sll local0, 8, local7 | ||
728 | xor $4, local0, $4 | ||
729 | |||
730 | srl $4, 1, local0 | ||
731 | xor $3, local7, $3 | ||
732 | |||
733 | srl local4, 4, temp1 | ||
734 | xor local0, $3, local0 | ||
735 | |||
736 | xor $1, temp2, $1 | ||
737 | and local0, ip5, local0 | ||
738 | |||
739 | sll local0, 1, local7 | ||
740 | xor temp1, $1, temp1 | ||
741 | |||
742 | xor $3, local0, $3 | ||
743 | xor $4, local7, $4 | ||
744 | |||
745 | sll $3, 3, local5 | ||
746 | and temp1, ip1, temp1 | ||
747 | |||
748 | sll temp1, 4, temp2 | ||
749 | xor $1, temp1, $1 | ||
750 | |||
751 | ifelse($5,1,{LDPTR KS2, in4}) | ||
752 | sll $4, 3, local2 | ||
753 | xor local4, temp2, $2 | ||
754 | |||
755 | ! reload since used as temporar: | ||
756 | |||
757 | ld [out2+280], out4 ! loop counter | ||
758 | |||
759 | srl $3, 29, local0 | ||
760 | ifelse($5,1,{add in4, 120, in4}) | ||
761 | |||
762 | ifelse($5,1,{LDPTR KS1, in3}) | ||
763 | srl $4, 29, local7 | ||
764 | |||
765 | or local0, local5, $4 | ||
766 | or local2, local7, $3 | ||
767 | |||
768 | }) | ||
769 | |||
770 | |||
771 | |||
772 | ! {load_little_endian} | ||
773 | ! | ||
774 | ! parameter 1 address | ||
775 | ! parameter 2 destination left | ||
776 | ! parameter 3 destination right | ||
777 | ! parameter 4 temporar | ||
778 | ! parameter 5 label | ||
779 | |||
780 | define(load_little_endian, { | ||
781 | |||
782 | ! {load_little_endian} | ||
783 | ! $1 $2 $3 $4 $5 $6 $7 $8 $9 | ||
784 | |||
785 | ! first in memory to rightmost in register | ||
786 | |||
787 | #ifdef OPENSSL_SYSNAME_ULTRASPARC | ||
788 | andcc $1, 3, global0 | ||
789 | bne,pn %icc, $5 | ||
790 | nop | ||
791 | |||
792 | lda [$1] 0x88, $2 | ||
793 | add $1, 4, $4 | ||
794 | |||
795 | ba,pt %icc, $5a | ||
796 | lda [$4] 0x88, $3 | ||
797 | #endif | ||
798 | |||
799 | $5: | ||
800 | ldub [$1+3], $2 | ||
801 | |||
802 | ldub [$1+2], $4 | ||
803 | sll $2, 8, $2 | ||
804 | or $2, $4, $2 | ||
805 | |||
806 | ldub [$1+1], $4 | ||
807 | sll $2, 8, $2 | ||
808 | or $2, $4, $2 | ||
809 | |||
810 | ldub [$1+0], $4 | ||
811 | sll $2, 8, $2 | ||
812 | or $2, $4, $2 | ||
813 | |||
814 | |||
815 | ldub [$1+3+4], $3 | ||
816 | |||
817 | ldub [$1+2+4], $4 | ||
818 | sll $3, 8, $3 | ||
819 | or $3, $4, $3 | ||
820 | |||
821 | ldub [$1+1+4], $4 | ||
822 | sll $3, 8, $3 | ||
823 | or $3, $4, $3 | ||
824 | |||
825 | ldub [$1+0+4], $4 | ||
826 | sll $3, 8, $3 | ||
827 | or $3, $4, $3 | ||
828 | $5a: | ||
829 | |||
830 | }) | ||
831 | |||
832 | |||
833 | ! {load_little_endian_inc} | ||
834 | ! | ||
835 | ! parameter 1 address | ||
836 | ! parameter 2 destination left | ||
837 | ! parameter 3 destination right | ||
838 | ! parameter 4 temporar | ||
839 | ! parameter 4 label | ||
840 | ! | ||
841 | ! adds 8 to address | ||
842 | |||
843 | define(load_little_endian_inc, { | ||
844 | |||
845 | ! {load_little_endian_inc} | ||
846 | ! $1 $2 $3 $4 $5 $6 $7 $8 $9 | ||
847 | |||
848 | ! first in memory to rightmost in register | ||
849 | |||
850 | #ifdef OPENSSL_SYSNAME_ULTRASPARC | ||
851 | andcc $1, 3, global0 | ||
852 | bne,pn %icc, $5 | ||
853 | nop | ||
854 | |||
855 | lda [$1] 0x88, $2 | ||
856 | add $1, 4, $1 | ||
857 | |||
858 | lda [$1] 0x88, $3 | ||
859 | ba,pt %icc, $5a | ||
860 | add $1, 4, $1 | ||
861 | #endif | ||
862 | |||
863 | $5: | ||
864 | ldub [$1+3], $2 | ||
865 | |||
866 | ldub [$1+2], $4 | ||
867 | sll $2, 8, $2 | ||
868 | or $2, $4, $2 | ||
869 | |||
870 | ldub [$1+1], $4 | ||
871 | sll $2, 8, $2 | ||
872 | or $2, $4, $2 | ||
873 | |||
874 | ldub [$1+0], $4 | ||
875 | sll $2, 8, $2 | ||
876 | or $2, $4, $2 | ||
877 | |||
878 | ldub [$1+3+4], $3 | ||
879 | add $1, 8, $1 | ||
880 | |||
881 | ldub [$1+2+4-8], $4 | ||
882 | sll $3, 8, $3 | ||
883 | or $3, $4, $3 | ||
884 | |||
885 | ldub [$1+1+4-8], $4 | ||
886 | sll $3, 8, $3 | ||
887 | or $3, $4, $3 | ||
888 | |||
889 | ldub [$1+0+4-8], $4 | ||
890 | sll $3, 8, $3 | ||
891 | or $3, $4, $3 | ||
892 | $5a: | ||
893 | |||
894 | }) | ||
895 | |||
896 | |||
897 | ! {load_n_bytes} | ||
898 | ! | ||
899 | ! Loads 1 to 7 bytes little endian | ||
900 | ! Remaining bytes are zeroed. | ||
901 | ! | ||
902 | ! parameter 1 address | ||
903 | ! parameter 2 length | ||
904 | ! parameter 3 destination register left | ||
905 | ! parameter 4 destination register right | ||
906 | ! parameter 5 temp | ||
907 | ! parameter 6 temp2 | ||
908 | ! parameter 7 label | ||
909 | ! parameter 8 return label | ||
910 | |||
911 | define(load_n_bytes, { | ||
912 | |||
913 | ! {load_n_bytes} | ||
914 | ! $1 $2 $5 $6 $7 $8 $7 $8 $9 | ||
915 | |||
916 | $7.0: call .+8 | ||
917 | sll $2, 2, $6 | ||
918 | |||
919 | add %o7,$7.jmp.table-$7.0,$5 | ||
920 | |||
921 | add $5, $6, $5 | ||
922 | mov 0, $4 | ||
923 | |||
924 | ld [$5], $5 | ||
925 | |||
926 | jmp %o7+$5 | ||
927 | mov 0, $3 | ||
928 | |||
929 | $7.7: | ||
930 | ldub [$1+6], $5 | ||
931 | sll $5, 16, $5 | ||
932 | or $3, $5, $3 | ||
933 | $7.6: | ||
934 | ldub [$1+5], $5 | ||
935 | sll $5, 8, $5 | ||
936 | or $3, $5, $3 | ||
937 | $7.5: | ||
938 | ldub [$1+4], $5 | ||
939 | or $3, $5, $3 | ||
940 | $7.4: | ||
941 | ldub [$1+3], $5 | ||
942 | sll $5, 24, $5 | ||
943 | or $4, $5, $4 | ||
944 | $7.3: | ||
945 | ldub [$1+2], $5 | ||
946 | sll $5, 16, $5 | ||
947 | or $4, $5, $4 | ||
948 | $7.2: | ||
949 | ldub [$1+1], $5 | ||
950 | sll $5, 8, $5 | ||
951 | or $4, $5, $4 | ||
952 | $7.1: | ||
953 | ldub [$1+0], $5 | ||
954 | ba $8 | ||
955 | or $4, $5, $4 | ||
956 | |||
957 | .align 4 | ||
958 | |||
959 | $7.jmp.table: | ||
960 | .word 0 | ||
961 | .word $7.1-$7.0 | ||
962 | .word $7.2-$7.0 | ||
963 | .word $7.3-$7.0 | ||
964 | .word $7.4-$7.0 | ||
965 | .word $7.5-$7.0 | ||
966 | .word $7.6-$7.0 | ||
967 | .word $7.7-$7.0 | ||
968 | }) | ||
969 | |||
970 | |||
971 | ! {store_little_endian} | ||
972 | ! | ||
973 | ! parameter 1 address | ||
974 | ! parameter 2 source left | ||
975 | ! parameter 3 source right | ||
976 | ! parameter 4 temporar | ||
977 | |||
978 | define(store_little_endian, { | ||
979 | |||
980 | ! {store_little_endian} | ||
981 | ! $1 $2 $3 $4 $5 $6 $7 $8 $9 | ||
982 | |||
983 | ! rightmost in register to first in memory | ||
984 | |||
985 | #ifdef OPENSSL_SYSNAME_ULTRASPARC | ||
986 | andcc $1, 3, global0 | ||
987 | bne,pn %icc, $5 | ||
988 | nop | ||
989 | |||
990 | sta $2, [$1] 0x88 | ||
991 | add $1, 4, $4 | ||
992 | |||
993 | ba,pt %icc, $5a | ||
994 | sta $3, [$4] 0x88 | ||
995 | #endif | ||
996 | |||
997 | $5: | ||
998 | and $2, 255, $4 | ||
999 | stub $4, [$1+0] | ||
1000 | |||
1001 | srl $2, 8, $4 | ||
1002 | and $4, 255, $4 | ||
1003 | stub $4, [$1+1] | ||
1004 | |||
1005 | srl $2, 16, $4 | ||
1006 | and $4, 255, $4 | ||
1007 | stub $4, [$1+2] | ||
1008 | |||
1009 | srl $2, 24, $4 | ||
1010 | stub $4, [$1+3] | ||
1011 | |||
1012 | |||
1013 | and $3, 255, $4 | ||
1014 | stub $4, [$1+0+4] | ||
1015 | |||
1016 | srl $3, 8, $4 | ||
1017 | and $4, 255, $4 | ||
1018 | stub $4, [$1+1+4] | ||
1019 | |||
1020 | srl $3, 16, $4 | ||
1021 | and $4, 255, $4 | ||
1022 | stub $4, [$1+2+4] | ||
1023 | |||
1024 | srl $3, 24, $4 | ||
1025 | stub $4, [$1+3+4] | ||
1026 | |||
1027 | $5a: | ||
1028 | |||
1029 | }) | ||
1030 | |||
1031 | |||
1032 | ! {store_n_bytes} | ||
1033 | ! | ||
1034 | ! Stores 1 to 7 bytes little endian | ||
1035 | ! | ||
1036 | ! parameter 1 address | ||
1037 | ! parameter 2 length | ||
1038 | ! parameter 3 source register left | ||
1039 | ! parameter 4 source register right | ||
1040 | ! parameter 5 temp | ||
1041 | ! parameter 6 temp2 | ||
1042 | ! parameter 7 label | ||
1043 | ! parameter 8 return label | ||
1044 | |||
1045 | define(store_n_bytes, { | ||
1046 | |||
1047 | ! {store_n_bytes} | ||
1048 | ! $1 $2 $5 $6 $7 $8 $7 $8 $9 | ||
1049 | |||
1050 | $7.0: call .+8 | ||
1051 | sll $2, 2, $6 | ||
1052 | |||
1053 | add %o7,$7.jmp.table-$7.0,$5 | ||
1054 | |||
1055 | add $5, $6, $5 | ||
1056 | |||
1057 | ld [$5], $5 | ||
1058 | |||
1059 | jmp %o7+$5 | ||
1060 | nop | ||
1061 | |||
1062 | $7.7: | ||
1063 | srl $3, 16, $5 | ||
1064 | and $5, 0xff, $5 | ||
1065 | stub $5, [$1+6] | ||
1066 | $7.6: | ||
1067 | srl $3, 8, $5 | ||
1068 | and $5, 0xff, $5 | ||
1069 | stub $5, [$1+5] | ||
1070 | $7.5: | ||
1071 | and $3, 0xff, $5 | ||
1072 | stub $5, [$1+4] | ||
1073 | $7.4: | ||
1074 | srl $4, 24, $5 | ||
1075 | stub $5, [$1+3] | ||
1076 | $7.3: | ||
1077 | srl $4, 16, $5 | ||
1078 | and $5, 0xff, $5 | ||
1079 | stub $5, [$1+2] | ||
1080 | $7.2: | ||
1081 | srl $4, 8, $5 | ||
1082 | and $5, 0xff, $5 | ||
1083 | stub $5, [$1+1] | ||
1084 | $7.1: | ||
1085 | and $4, 0xff, $5 | ||
1086 | |||
1087 | |||
1088 | ba $8 | ||
1089 | stub $5, [$1] | ||
1090 | |||
1091 | .align 4 | ||
1092 | |||
1093 | $7.jmp.table: | ||
1094 | |||
1095 | .word 0 | ||
1096 | .word $7.1-$7.0 | ||
1097 | .word $7.2-$7.0 | ||
1098 | .word $7.3-$7.0 | ||
1099 | .word $7.4-$7.0 | ||
1100 | .word $7.5-$7.0 | ||
1101 | .word $7.6-$7.0 | ||
1102 | .word $7.7-$7.0 | ||
1103 | }) | ||
1104 | |||
1105 | |||
1106 | define(testvalue,{1}) | ||
1107 | |||
1108 | define(register_init, { | ||
1109 | |||
1110 | ! For test purposes: | ||
1111 | |||
1112 | sethi %hi(testvalue), local0 | ||
1113 | or local0, %lo(testvalue), local0 | ||
1114 | |||
1115 | ifelse($1,{},{}, {mov local0, $1}) | ||
1116 | ifelse($2,{},{}, {mov local0, $2}) | ||
1117 | ifelse($3,{},{}, {mov local0, $3}) | ||
1118 | ifelse($4,{},{}, {mov local0, $4}) | ||
1119 | ifelse($5,{},{}, {mov local0, $5}) | ||
1120 | ifelse($6,{},{}, {mov local0, $6}) | ||
1121 | ifelse($7,{},{}, {mov local0, $7}) | ||
1122 | ifelse($8,{},{}, {mov local0, $8}) | ||
1123 | |||
1124 | mov local0, local1 | ||
1125 | mov local0, local2 | ||
1126 | mov local0, local3 | ||
1127 | mov local0, local4 | ||
1128 | mov local0, local5 | ||
1129 | mov local0, local7 | ||
1130 | mov local0, local6 | ||
1131 | mov local0, out0 | ||
1132 | mov local0, out1 | ||
1133 | mov local0, out2 | ||
1134 | mov local0, out3 | ||
1135 | mov local0, out4 | ||
1136 | mov local0, out5 | ||
1137 | mov local0, global1 | ||
1138 | mov local0, global2 | ||
1139 | mov local0, global3 | ||
1140 | mov local0, global4 | ||
1141 | mov local0, global5 | ||
1142 | |||
1143 | }) | ||
1144 | |||
1145 | .section ".text" | ||
1146 | |||
1147 | .align 32 | ||
1148 | |||
1149 | .des_enc: | ||
1150 | |||
1151 | ! key address in3 | ||
1152 | ! loads key next encryption/decryption first round from [in4] | ||
1153 | |||
1154 | rounds_macro(in5, out5, 1, .des_enc.1, in3, in4, retl) | ||
1155 | |||
1156 | |||
1157 | .align 32 | ||
1158 | |||
1159 | .des_dec: | ||
1160 | |||
1161 | ! implemented with out5 as first parameter to avoid | ||
1162 | ! register exchange in ede modes | ||
1163 | |||
1164 | ! key address in4 | ||
1165 | ! loads key next encryption/decryption first round from [in3] | ||
1166 | |||
1167 | rounds_macro(out5, in5, -1, .des_dec.1, in4, in3, retl) | ||
1168 | |||
1169 | |||
1170 | |||
1171 | ! void DES_encrypt1(data, ks, enc) | ||
1172 | ! ******************************* | ||
1173 | |||
1174 | .align 32 | ||
1175 | .global DES_encrypt1 | ||
1176 | .type DES_encrypt1,#function | ||
1177 | |||
1178 | DES_encrypt1: | ||
1179 | |||
1180 | save %sp, FRAME, %sp | ||
1181 | |||
1182 | call .PIC.me.up | ||
1183 | mov .PIC.me.up-(.-4),out0 | ||
1184 | |||
1185 | ld [in0], in5 ! left | ||
1186 | cmp in2, 0 ! enc | ||
1187 | |||
1188 | #ifdef OPENSSL_SYSNAME_ULTRASPARC | ||
1189 | be,pn %icc, .encrypt.dec ! enc/dec | ||
1190 | #else | ||
1191 | be .encrypt.dec | ||
1192 | #endif | ||
1193 | ld [in0+4], out5 ! right | ||
1194 | |||
1195 | ! parameter 6 1/2 for include encryption/decryption | ||
1196 | ! parameter 7 1 for move in1 to in3 | ||
1197 | ! parameter 8 1 for move in3 to in4, 2 for move in4 to in3 | ||
1198 | |||
1199 | ip_macro(in5, out5, in5, out5, in3, 0, 1, 1) | ||
1200 | |||
1201 | rounds_macro(in5, out5, 1, .des_encrypt1.1, in3, in4) ! in4 not used | ||
1202 | |||
1203 | fp_macro(in5, out5, 1) ! 1 for store to [in0] | ||
1204 | |||
1205 | ret | ||
1206 | restore | ||
1207 | |||
1208 | .encrypt.dec: | ||
1209 | |||
1210 | add in1, 120, in3 ! use last subkey for first round | ||
1211 | |||
1212 | ! parameter 6 1/2 for include encryption/decryption | ||
1213 | ! parameter 7 1 for move in1 to in3 | ||
1214 | ! parameter 8 1 for move in3 to in4, 2 for move in4 to in3 | ||
1215 | |||
1216 | ip_macro(in5, out5, out5, in5, in4, 2, 0, 1) ! include dec, ks in4 | ||
1217 | |||
1218 | fp_macro(out5, in5, 1) ! 1 for store to [in0] | ||
1219 | |||
1220 | ret | ||
1221 | restore | ||
1222 | |||
1223 | .DES_encrypt1.end: | ||
1224 | .size DES_encrypt1,.DES_encrypt1.end-DES_encrypt1 | ||
1225 | |||
1226 | |||
1227 | ! void DES_encrypt2(data, ks, enc) | ||
1228 | !********************************* | ||
1229 | |||
1230 | ! encrypts/decrypts without initial/final permutation | ||
1231 | |||
1232 | .align 32 | ||
1233 | .global DES_encrypt2 | ||
1234 | .type DES_encrypt2,#function | ||
1235 | |||
1236 | DES_encrypt2: | ||
1237 | |||
1238 | save %sp, FRAME, %sp | ||
1239 | |||
1240 | call .PIC.me.up | ||
1241 | mov .PIC.me.up-(.-4),out0 | ||
1242 | |||
1243 | ! Set sbox address 1 to 6 and rotate halfs 3 left | ||
1244 | ! Errors caught by destest? Yes. Still? *NO* | ||
1245 | |||
1246 | !sethi %hi(DES_SPtrans), global1 ! address sbox 1 | ||
1247 | |||
1248 | !or global1, %lo(DES_SPtrans), global1 ! sbox 1 | ||
1249 | |||
1250 | add global1, 256, global2 ! sbox 2 | ||
1251 | add global1, 512, global3 ! sbox 3 | ||
1252 | |||
1253 | ld [in0], out5 ! right | ||
1254 | add global1, 768, global4 ! sbox 4 | ||
1255 | add global1, 1024, global5 ! sbox 5 | ||
1256 | |||
1257 | ld [in0+4], in5 ! left | ||
1258 | add global1, 1280, local6 ! sbox 6 | ||
1259 | add global1, 1792, out3 ! sbox 8 | ||
1260 | |||
1261 | ! rotate | ||
1262 | |||
1263 | sll in5, 3, local5 | ||
1264 | mov in1, in3 ! key address to in3 | ||
1265 | |||
1266 | sll out5, 3, local7 | ||
1267 | srl in5, 29, in5 | ||
1268 | |||
1269 | srl out5, 29, out5 | ||
1270 | add in5, local5, in5 | ||
1271 | |||
1272 | add out5, local7, out5 | ||
1273 | cmp in2, 0 | ||
1274 | |||
1275 | ! we use our own stackframe | ||
1276 | |||
1277 | #ifdef OPENSSL_SYSNAME_ULTRASPARC | ||
1278 | be,pn %icc, .encrypt2.dec ! decryption | ||
1279 | #else | ||
1280 | be .encrypt2.dec | ||
1281 | #endif | ||
1282 | STPTR in0, [%sp+BIAS+ARG0+0*ARGSZ] | ||
1283 | |||
1284 | ld [in3], out0 ! key 7531 first round | ||
1285 | mov LOOPS, out4 ! loop counter | ||
1286 | |||
1287 | ld [in3+4], out1 ! key 8642 first round | ||
1288 | sethi %hi(0x0000FC00), local5 | ||
1289 | |||
1290 | call .des_enc | ||
1291 | mov in3, in4 | ||
1292 | |||
1293 | ! rotate | ||
1294 | sll in5, 29, in0 | ||
1295 | srl in5, 3, in5 | ||
1296 | sll out5, 29, in1 | ||
1297 | add in5, in0, in5 | ||
1298 | srl out5, 3, out5 | ||
1299 | LDPTR [%sp+BIAS+ARG0+0*ARGSZ], in0 | ||
1300 | add out5, in1, out5 | ||
1301 | st in5, [in0] | ||
1302 | st out5, [in0+4] | ||
1303 | |||
1304 | ret | ||
1305 | restore | ||
1306 | |||
1307 | |||
1308 | .encrypt2.dec: | ||
1309 | |||
1310 | add in3, 120, in4 | ||
1311 | |||
1312 | ld [in4], out0 ! key 7531 first round | ||
1313 | mov LOOPS, out4 ! loop counter | ||
1314 | |||
1315 | ld [in4+4], out1 ! key 8642 first round | ||
1316 | sethi %hi(0x0000FC00), local5 | ||
1317 | |||
1318 | mov in5, local1 ! left expected in out5 | ||
1319 | mov out5, in5 | ||
1320 | |||
1321 | call .des_dec | ||
1322 | mov local1, out5 | ||
1323 | |||
1324 | .encrypt2.finish: | ||
1325 | |||
1326 | ! rotate | ||
1327 | sll in5, 29, in0 | ||
1328 | srl in5, 3, in5 | ||
1329 | sll out5, 29, in1 | ||
1330 | add in5, in0, in5 | ||
1331 | srl out5, 3, out5 | ||
1332 | LDPTR [%sp+BIAS+ARG0+0*ARGSZ], in0 | ||
1333 | add out5, in1, out5 | ||
1334 | st out5, [in0] | ||
1335 | st in5, [in0+4] | ||
1336 | |||
1337 | ret | ||
1338 | restore | ||
1339 | |||
1340 | .DES_encrypt2.end: | ||
1341 | .size DES_encrypt2, .DES_encrypt2.end-DES_encrypt2 | ||
1342 | |||
1343 | |||
1344 | ! void DES_encrypt3(data, ks1, ks2, ks3) | ||
1345 | ! ************************************** | ||
1346 | |||
1347 | .align 32 | ||
1348 | .global DES_encrypt3 | ||
1349 | .type DES_encrypt3,#function | ||
1350 | |||
1351 | DES_encrypt3: | ||
1352 | |||
1353 | save %sp, FRAME, %sp | ||
1354 | |||
1355 | call .PIC.me.up | ||
1356 | mov .PIC.me.up-(.-4),out0 | ||
1357 | |||
1358 | ld [in0], in5 ! left | ||
1359 | add in2, 120, in4 ! ks2 | ||
1360 | |||
1361 | ld [in0+4], out5 ! right | ||
1362 | mov in3, in2 ! save ks3 | ||
1363 | |||
1364 | ! parameter 6 1/2 for include encryption/decryption | ||
1365 | ! parameter 7 1 for mov in1 to in3 | ||
1366 | ! parameter 8 1 for mov in3 to in4 | ||
1367 | ! parameter 9 1 for load ks3 and ks2 to in4 and in3 | ||
1368 | |||
1369 | ip_macro(in5, out5, in5, out5, in3, 1, 1, 0, 0) | ||
1370 | |||
1371 | call .des_dec | ||
1372 | mov in2, in3 ! preload ks3 | ||
1373 | |||
1374 | call .des_enc | ||
1375 | nop | ||
1376 | |||
1377 | fp_macro(in5, out5, 1) | ||
1378 | |||
1379 | ret | ||
1380 | restore | ||
1381 | |||
1382 | .DES_encrypt3.end: | ||
1383 | .size DES_encrypt3,.DES_encrypt3.end-DES_encrypt3 | ||
1384 | |||
1385 | |||
1386 | ! void DES_decrypt3(data, ks1, ks2, ks3) | ||
1387 | ! ************************************** | ||
1388 | |||
1389 | .align 32 | ||
1390 | .global DES_decrypt3 | ||
1391 | .type DES_decrypt3,#function | ||
1392 | |||
1393 | DES_decrypt3: | ||
1394 | |||
1395 | save %sp, FRAME, %sp | ||
1396 | |||
1397 | call .PIC.me.up | ||
1398 | mov .PIC.me.up-(.-4),out0 | ||
1399 | |||
1400 | ld [in0], in5 ! left | ||
1401 | add in3, 120, in4 ! ks3 | ||
1402 | |||
1403 | ld [in0+4], out5 ! right | ||
1404 | mov in2, in3 ! ks2 | ||
1405 | |||
1406 | ! parameter 6 1/2 for include encryption/decryption | ||
1407 | ! parameter 7 1 for mov in1 to in3 | ||
1408 | ! parameter 8 1 for mov in3 to in4 | ||
1409 | ! parameter 9 1 for load ks3 and ks2 to in4 and in3 | ||
1410 | |||
1411 | ip_macro(in5, out5, out5, in5, in4, 2, 0, 0, 0) | ||
1412 | |||
1413 | call .des_enc | ||
1414 | add in1, 120, in4 ! preload ks1 | ||
1415 | |||
1416 | call .des_dec | ||
1417 | nop | ||
1418 | |||
1419 | fp_macro(out5, in5, 1) | ||
1420 | |||
1421 | ret | ||
1422 | restore | ||
1423 | |||
1424 | .DES_decrypt3.end: | ||
1425 | .size DES_decrypt3,.DES_decrypt3.end-DES_decrypt3 | ||
1426 | |||
1427 | .align 256 | ||
1428 | .type .des_and,#object | ||
1429 | .size .des_and,284 | ||
1430 | |||
1431 | .des_and: | ||
1432 | |||
1433 | ! This table is used for AND 0xFC when it is known that register | ||
1434 | ! bits 8-31 are zero. Makes it possible to do three arithmetic | ||
1435 | ! operations in one cycle. | ||
1436 | |||
1437 | .byte 0, 0, 0, 0, 4, 4, 4, 4 | ||
1438 | .byte 8, 8, 8, 8, 12, 12, 12, 12 | ||
1439 | .byte 16, 16, 16, 16, 20, 20, 20, 20 | ||
1440 | .byte 24, 24, 24, 24, 28, 28, 28, 28 | ||
1441 | .byte 32, 32, 32, 32, 36, 36, 36, 36 | ||
1442 | .byte 40, 40, 40, 40, 44, 44, 44, 44 | ||
1443 | .byte 48, 48, 48, 48, 52, 52, 52, 52 | ||
1444 | .byte 56, 56, 56, 56, 60, 60, 60, 60 | ||
1445 | .byte 64, 64, 64, 64, 68, 68, 68, 68 | ||
1446 | .byte 72, 72, 72, 72, 76, 76, 76, 76 | ||
1447 | .byte 80, 80, 80, 80, 84, 84, 84, 84 | ||
1448 | .byte 88, 88, 88, 88, 92, 92, 92, 92 | ||
1449 | .byte 96, 96, 96, 96, 100, 100, 100, 100 | ||
1450 | .byte 104, 104, 104, 104, 108, 108, 108, 108 | ||
1451 | .byte 112, 112, 112, 112, 116, 116, 116, 116 | ||
1452 | .byte 120, 120, 120, 120, 124, 124, 124, 124 | ||
1453 | .byte 128, 128, 128, 128, 132, 132, 132, 132 | ||
1454 | .byte 136, 136, 136, 136, 140, 140, 140, 140 | ||
1455 | .byte 144, 144, 144, 144, 148, 148, 148, 148 | ||
1456 | .byte 152, 152, 152, 152, 156, 156, 156, 156 | ||
1457 | .byte 160, 160, 160, 160, 164, 164, 164, 164 | ||
1458 | .byte 168, 168, 168, 168, 172, 172, 172, 172 | ||
1459 | .byte 176, 176, 176, 176, 180, 180, 180, 180 | ||
1460 | .byte 184, 184, 184, 184, 188, 188, 188, 188 | ||
1461 | .byte 192, 192, 192, 192, 196, 196, 196, 196 | ||
1462 | .byte 200, 200, 200, 200, 204, 204, 204, 204 | ||
1463 | .byte 208, 208, 208, 208, 212, 212, 212, 212 | ||
1464 | .byte 216, 216, 216, 216, 220, 220, 220, 220 | ||
1465 | .byte 224, 224, 224, 224, 228, 228, 228, 228 | ||
1466 | .byte 232, 232, 232, 232, 236, 236, 236, 236 | ||
1467 | .byte 240, 240, 240, 240, 244, 244, 244, 244 | ||
1468 | .byte 248, 248, 248, 248, 252, 252, 252, 252 | ||
1469 | |||
1470 | ! 5 numbers for initil/final permutation | ||
1471 | |||
1472 | .word 0x0f0f0f0f ! offset 256 | ||
1473 | .word 0x0000ffff ! 260 | ||
1474 | .word 0x33333333 ! 264 | ||
1475 | .word 0x00ff00ff ! 268 | ||
1476 | .word 0x55555555 ! 272 | ||
1477 | |||
1478 | .word 0 ! 276 | ||
1479 | .word LOOPS ! 280 | ||
1480 | .word 0x0000FC00 ! 284 | ||
1481 | .PIC.DES_SPtrans: | ||
1482 | .word %r_disp32(DES_SPtrans) | ||
1483 | |||
1484 | ! input: out0 offset between .PIC.me.up and caller | ||
1485 | ! output: out0 pointer to .PIC.me.up | ||
1486 | ! out2 pointer to .des_and | ||
1487 | ! global1 pointer to DES_SPtrans | ||
1488 | .align 32 | ||
1489 | .PIC.me.up: | ||
1490 | add out0,%o7,out0 ! pointer to .PIC.me.up | ||
1491 | #if 1 | ||
1492 | ld [out0+(.PIC.DES_SPtrans-.PIC.me.up)],global1 | ||
1493 | add global1,(.PIC.DES_SPtrans-.PIC.me.up),global1 | ||
1494 | add global1,out0,global1 | ||
1495 | #else | ||
1496 | # ifdef OPENSSL_PIC | ||
1497 | ! In case anybody wonders why this code is same for both ABI. | ||
1498 | ! To start with it is not. Do note LDPTR below. But of course | ||
1499 | ! you must be wondering why the rest of it does not contain | ||
1500 | ! things like %hh, %hm and %lm. Well, those are needed only | ||
1501 | ! if OpenSSL library *itself* will become larger than 4GB, | ||
1502 | ! which is not going to happen any time soon. | ||
1503 | sethi %hi(DES_SPtrans),global1 | ||
1504 | or global1,%lo(DES_SPtrans),global1 | ||
1505 | sethi %hi(_GLOBAL_OFFSET_TABLE_-(.PIC.me.up-.)),out2 | ||
1506 | add global1,out0,global1 | ||
1507 | add out2,%lo(_GLOBAL_OFFSET_TABLE_-(.PIC.me.up-.)),out2 | ||
1508 | LDPTR [out2+global1],global1 | ||
1509 | # elif 0 | ||
1510 | setn DES_SPtrans,out2,global1 ! synthetic instruction ! | ||
1511 | # elif defined(ABI64) | ||
1512 | sethi %hh(DES_SPtrans),out2 | ||
1513 | or out2,%hm(DES_SPtrans),out2 | ||
1514 | sethi %lm(DES_SPtrans),global1 | ||
1515 | or global1,%lo(DES_SPtrans),global1 | ||
1516 | sllx out2,32,out2 | ||
1517 | or out2,global1,global1 | ||
1518 | # else | ||
1519 | sethi %hi(DES_SPtrans),global1 | ||
1520 | or global1,%lo(DES_SPtrans),global1 | ||
1521 | # endif | ||
1522 | #endif | ||
1523 | retl | ||
1524 | add out0,.des_and-.PIC.me.up,out2 | ||
1525 | |||
1526 | ! void DES_ncbc_encrypt(input, output, length, schedule, ivec, enc) | ||
1527 | ! ***************************************************************** | ||
1528 | |||
1529 | |||
1530 | .align 32 | ||
1531 | .global DES_ncbc_encrypt | ||
1532 | .type DES_ncbc_encrypt,#function | ||
1533 | |||
1534 | DES_ncbc_encrypt: | ||
1535 | |||
1536 | save %sp, FRAME, %sp | ||
1537 | |||
1538 | define({INPUT}, { [%sp+BIAS+ARG0+0*ARGSZ] }) | ||
1539 | define({OUTPUT}, { [%sp+BIAS+ARG0+1*ARGSZ] }) | ||
1540 | define({IVEC}, { [%sp+BIAS+ARG0+4*ARGSZ] }) | ||
1541 | |||
1542 | call .PIC.me.up | ||
1543 | mov .PIC.me.up-(.-4),out0 | ||
1544 | |||
1545 | cmp in5, 0 ! enc | ||
1546 | |||
1547 | #ifdef OPENSSL_SYSNAME_ULTRASPARC | ||
1548 | be,pn %icc, .ncbc.dec | ||
1549 | #else | ||
1550 | be .ncbc.dec | ||
1551 | #endif | ||
1552 | STPTR in4, IVEC | ||
1553 | |||
1554 | ! addr left right temp label | ||
1555 | load_little_endian(in4, in5, out5, local3, .LLE1) ! iv | ||
1556 | |||
1557 | addcc in2, -8, in2 ! bytes missing when first block done | ||
1558 | |||
1559 | #ifdef OPENSSL_SYSNAME_ULTRASPARC | ||
1560 | bl,pn %icc, .ncbc.enc.seven.or.less | ||
1561 | #else | ||
1562 | bl .ncbc.enc.seven.or.less | ||
1563 | #endif | ||
1564 | mov in3, in4 ! schedule | ||
1565 | |||
1566 | .ncbc.enc.next.block: | ||
1567 | |||
1568 | load_little_endian(in0, out4, global4, local3, .LLE2) ! block | ||
1569 | |||
1570 | .ncbc.enc.next.block_1: | ||
1571 | |||
1572 | xor in5, out4, in5 ! iv xor | ||
1573 | xor out5, global4, out5 ! iv xor | ||
1574 | |||
1575 | ! parameter 8 1 for move in3 to in4, 2 for move in4 to in3 | ||
1576 | ip_macro(in5, out5, in5, out5, in3, 0, 0, 2) | ||
1577 | |||
1578 | .ncbc.enc.next.block_2: | ||
1579 | |||
1580 | !// call .des_enc ! compares in2 to 8 | ||
1581 | ! rounds inlined for alignment purposes | ||
1582 | |||
1583 | add global1, 768, global4 ! address sbox 4 since register used below | ||
1584 | |||
1585 | rounds_macro(in5, out5, 1, .ncbc.enc.1, in3, in4) ! include encryption ks in3 | ||
1586 | |||
1587 | #ifdef OPENSSL_SYSNAME_ULTRASPARC | ||
1588 | bl,pn %icc, .ncbc.enc.next.block_fp | ||
1589 | #else | ||
1590 | bl .ncbc.enc.next.block_fp | ||
1591 | #endif | ||
1592 | add in0, 8, in0 ! input address | ||
1593 | |||
1594 | ! If 8 or more bytes are to be encrypted after this block, | ||
1595 | ! we combine final permutation for this block with initial | ||
1596 | ! permutation for next block. Load next block: | ||
1597 | |||
1598 | load_little_endian(in0, global3, global4, local5, .LLE12) | ||
1599 | |||
1600 | ! parameter 1 original left | ||
1601 | ! parameter 2 original right | ||
1602 | ! parameter 3 left ip | ||
1603 | ! parameter 4 right ip | ||
1604 | ! parameter 5 1: load ks1/ks2 to in3/in4, add 120 to in4 | ||
1605 | ! 2: mov in4 to in3 | ||
1606 | ! | ||
1607 | ! also adds -8 to length in2 and loads loop counter to out4 | ||
1608 | |||
1609 | fp_ip_macro(out0, out1, global3, global4, 2) | ||
1610 | |||
1611 | store_little_endian(in1, out0, out1, local3, .SLE10) ! block | ||
1612 | |||
1613 | ld [in3], out0 ! key 7531 first round next block | ||
1614 | mov in5, local1 | ||
1615 | xor global3, out5, in5 ! iv xor next block | ||
1616 | |||
1617 | ld [in3+4], out1 ! key 8642 | ||
1618 | add global1, 512, global3 ! address sbox 3 since register used | ||
1619 | xor global4, local1, out5 ! iv xor next block | ||
1620 | |||
1621 | ba .ncbc.enc.next.block_2 | ||
1622 | add in1, 8, in1 ! output adress | ||
1623 | |||
1624 | .ncbc.enc.next.block_fp: | ||
1625 | |||
1626 | fp_macro(in5, out5) | ||
1627 | |||
1628 | store_little_endian(in1, in5, out5, local3, .SLE1) ! block | ||
1629 | |||
1630 | addcc in2, -8, in2 ! bytes missing when next block done | ||
1631 | |||
1632 | #ifdef OPENSSL_SYSNAME_ULTRASPARC | ||
1633 | bpos,pt %icc, .ncbc.enc.next.block ! also jumps if 0 | ||
1634 | #else | ||
1635 | bpos .ncbc.enc.next.block | ||
1636 | #endif | ||
1637 | add in1, 8, in1 | ||
1638 | |||
1639 | .ncbc.enc.seven.or.less: | ||
1640 | |||
1641 | cmp in2, -8 | ||
1642 | |||
1643 | #ifdef OPENSSL_SYSNAME_ULTRASPARC | ||
1644 | ble,pt %icc, .ncbc.enc.finish | ||
1645 | #else | ||
1646 | ble .ncbc.enc.finish | ||
1647 | #endif | ||
1648 | nop | ||
1649 | |||
1650 | add in2, 8, local1 ! bytes to load | ||
1651 | |||
1652 | ! addr, length, dest left, dest right, temp, temp2, label, ret label | ||
1653 | load_n_bytes(in0, local1, global4, out4, local2, local3, .LNB1, .ncbc.enc.next.block_1) | ||
1654 | |||
1655 | ! Loads 1 to 7 bytes little endian to global4, out4 | ||
1656 | |||
1657 | |||
1658 | .ncbc.enc.finish: | ||
1659 | |||
1660 | LDPTR IVEC, local4 | ||
1661 | store_little_endian(local4, in5, out5, local5, .SLE2) ! ivec | ||
1662 | |||
1663 | ret | ||
1664 | restore | ||
1665 | |||
1666 | |||
1667 | .ncbc.dec: | ||
1668 | |||
1669 | STPTR in0, INPUT | ||
1670 | cmp in2, 0 ! length | ||
1671 | add in3, 120, in3 | ||
1672 | |||
1673 | LDPTR IVEC, local7 ! ivec | ||
1674 | #ifdef OPENSSL_SYSNAME_ULTRASPARC | ||
1675 | ble,pn %icc, .ncbc.dec.finish | ||
1676 | #else | ||
1677 | ble .ncbc.dec.finish | ||
1678 | #endif | ||
1679 | mov in3, in4 ! schedule | ||
1680 | |||
1681 | STPTR in1, OUTPUT | ||
1682 | mov in0, local5 ! input | ||
1683 | |||
1684 | load_little_endian(local7, in0, in1, local3, .LLE3) ! ivec | ||
1685 | |||
1686 | .ncbc.dec.next.block: | ||
1687 | |||
1688 | load_little_endian(local5, in5, out5, local3, .LLE4) ! block | ||
1689 | |||
1690 | ! parameter 6 1/2 for include encryption/decryption | ||
1691 | ! parameter 7 1 for mov in1 to in3 | ||
1692 | ! parameter 8 1 for mov in3 to in4 | ||
1693 | |||
1694 | ip_macro(in5, out5, out5, in5, in4, 2, 0, 1) ! include decryprion ks in4 | ||
1695 | |||
1696 | fp_macro(out5, in5, 0, 1) ! 1 for input and output address to local5/7 | ||
1697 | |||
1698 | ! in2 is bytes left to be stored | ||
1699 | ! in2 is compared to 8 in the rounds | ||
1700 | |||
1701 | xor out5, in0, out4 ! iv xor | ||
1702 | #ifdef OPENSSL_SYSNAME_ULTRASPARC | ||
1703 | bl,pn %icc, .ncbc.dec.seven.or.less | ||
1704 | #else | ||
1705 | bl .ncbc.dec.seven.or.less | ||
1706 | #endif | ||
1707 | xor in5, in1, global4 ! iv xor | ||
1708 | |||
1709 | ! Load ivec next block now, since input and output address might be the same. | ||
1710 | |||
1711 | load_little_endian_inc(local5, in0, in1, local3, .LLE5) ! iv | ||
1712 | |||
1713 | store_little_endian(local7, out4, global4, local3, .SLE3) | ||
1714 | |||
1715 | STPTR local5, INPUT | ||
1716 | add local7, 8, local7 | ||
1717 | addcc in2, -8, in2 | ||
1718 | |||
1719 | #ifdef OPENSSL_SYSNAME_ULTRASPARC | ||
1720 | bg,pt %icc, .ncbc.dec.next.block | ||
1721 | #else | ||
1722 | bg .ncbc.dec.next.block | ||
1723 | #endif | ||
1724 | STPTR local7, OUTPUT | ||
1725 | |||
1726 | |||
1727 | .ncbc.dec.store.iv: | ||
1728 | |||
1729 | LDPTR IVEC, local4 ! ivec | ||
1730 | store_little_endian(local4, in0, in1, local5, .SLE4) | ||
1731 | |||
1732 | .ncbc.dec.finish: | ||
1733 | |||
1734 | ret | ||
1735 | restore | ||
1736 | |||
1737 | .ncbc.dec.seven.or.less: | ||
1738 | |||
1739 | load_little_endian_inc(local5, in0, in1, local3, .LLE13) ! ivec | ||
1740 | |||
1741 | store_n_bytes(local7, in2, global4, out4, local3, local4, .SNB1, .ncbc.dec.store.iv) | ||
1742 | |||
1743 | |||
1744 | .DES_ncbc_encrypt.end: | ||
1745 | .size DES_ncbc_encrypt, .DES_ncbc_encrypt.end-DES_ncbc_encrypt | ||
1746 | |||
1747 | |||
1748 | ! void DES_ede3_cbc_encrypt(input, output, lenght, ks1, ks2, ks3, ivec, enc) | ||
1749 | ! ************************************************************************** | ||
1750 | |||
1751 | |||
1752 | .align 32 | ||
1753 | .global DES_ede3_cbc_encrypt | ||
1754 | .type DES_ede3_cbc_encrypt,#function | ||
1755 | |||
1756 | DES_ede3_cbc_encrypt: | ||
1757 | |||
1758 | save %sp, FRAME, %sp | ||
1759 | |||
1760 | define({KS1}, { [%sp+BIAS+ARG0+3*ARGSZ] }) | ||
1761 | define({KS2}, { [%sp+BIAS+ARG0+4*ARGSZ] }) | ||
1762 | define({KS3}, { [%sp+BIAS+ARG0+5*ARGSZ] }) | ||
1763 | |||
1764 | call .PIC.me.up | ||
1765 | mov .PIC.me.up-(.-4),out0 | ||
1766 | |||
1767 | LDPTR [%fp+BIAS+ARG0+7*ARGSZ], local3 ! enc | ||
1768 | LDPTR [%fp+BIAS+ARG0+6*ARGSZ], local4 ! ivec | ||
1769 | cmp local3, 0 ! enc | ||
1770 | |||
1771 | #ifdef OPENSSL_SYSNAME_ULTRASPARC | ||
1772 | be,pn %icc, .ede3.dec | ||
1773 | #else | ||
1774 | be .ede3.dec | ||
1775 | #endif | ||
1776 | STPTR in4, KS2 | ||
1777 | |||
1778 | STPTR in5, KS3 | ||
1779 | |||
1780 | load_little_endian(local4, in5, out5, local3, .LLE6) ! ivec | ||
1781 | |||
1782 | addcc in2, -8, in2 ! bytes missing after next block | ||
1783 | |||
1784 | #ifdef OPENSSL_SYSNAME_ULTRASPARC | ||
1785 | bl,pn %icc, .ede3.enc.seven.or.less | ||
1786 | #else | ||
1787 | bl .ede3.enc.seven.or.less | ||
1788 | #endif | ||
1789 | STPTR in3, KS1 | ||
1790 | |||
1791 | .ede3.enc.next.block: | ||
1792 | |||
1793 | load_little_endian(in0, out4, global4, local3, .LLE7) | ||
1794 | |||
1795 | .ede3.enc.next.block_1: | ||
1796 | |||
1797 | LDPTR KS2, in4 | ||
1798 | xor in5, out4, in5 ! iv xor | ||
1799 | xor out5, global4, out5 ! iv xor | ||
1800 | |||
1801 | LDPTR KS1, in3 | ||
1802 | add in4, 120, in4 ! for decryption we use last subkey first | ||
1803 | nop | ||
1804 | |||
1805 | ip_macro(in5, out5, in5, out5, in3) | ||
1806 | |||
1807 | .ede3.enc.next.block_2: | ||
1808 | |||
1809 | call .des_enc ! ks1 in3 | ||
1810 | nop | ||
1811 | |||
1812 | call .des_dec ! ks2 in4 | ||
1813 | LDPTR KS3, in3 | ||
1814 | |||
1815 | call .des_enc ! ks3 in3 compares in2 to 8 | ||
1816 | nop | ||
1817 | |||
1818 | #ifdef OPENSSL_SYSNAME_ULTRASPARC | ||
1819 | bl,pn %icc, .ede3.enc.next.block_fp | ||
1820 | #else | ||
1821 | bl .ede3.enc.next.block_fp | ||
1822 | #endif | ||
1823 | add in0, 8, in0 | ||
1824 | |||
1825 | ! If 8 or more bytes are to be encrypted after this block, | ||
1826 | ! we combine final permutation for this block with initial | ||
1827 | ! permutation for next block. Load next block: | ||
1828 | |||
1829 | load_little_endian(in0, global3, global4, local5, .LLE11) | ||
1830 | |||
1831 | ! parameter 1 original left | ||
1832 | ! parameter 2 original right | ||
1833 | ! parameter 3 left ip | ||
1834 | ! parameter 4 right ip | ||
1835 | ! parameter 5 1: load ks1/ks2 to in3/in4, add 120 to in4 | ||
1836 | ! 2: mov in4 to in3 | ||
1837 | ! | ||
1838 | ! also adds -8 to length in2 and loads loop counter to out4 | ||
1839 | |||
1840 | fp_ip_macro(out0, out1, global3, global4, 1) | ||
1841 | |||
1842 | store_little_endian(in1, out0, out1, local3, .SLE9) ! block | ||
1843 | |||
1844 | mov in5, local1 | ||
1845 | xor global3, out5, in5 ! iv xor next block | ||
1846 | |||
1847 | ld [in3], out0 ! key 7531 | ||
1848 | add global1, 512, global3 ! address sbox 3 | ||
1849 | xor global4, local1, out5 ! iv xor next block | ||
1850 | |||
1851 | ld [in3+4], out1 ! key 8642 | ||
1852 | add global1, 768, global4 ! address sbox 4 | ||
1853 | ba .ede3.enc.next.block_2 | ||
1854 | add in1, 8, in1 | ||
1855 | |||
1856 | .ede3.enc.next.block_fp: | ||
1857 | |||
1858 | fp_macro(in5, out5) | ||
1859 | |||
1860 | store_little_endian(in1, in5, out5, local3, .SLE5) ! block | ||
1861 | |||
1862 | addcc in2, -8, in2 ! bytes missing when next block done | ||
1863 | |||
1864 | #ifdef OPENSSL_SYSNAME_ULTRASPARC | ||
1865 | bpos,pt %icc, .ede3.enc.next.block | ||
1866 | #else | ||
1867 | bpos .ede3.enc.next.block | ||
1868 | #endif | ||
1869 | add in1, 8, in1 | ||
1870 | |||
1871 | .ede3.enc.seven.or.less: | ||
1872 | |||
1873 | cmp in2, -8 | ||
1874 | |||
1875 | #ifdef OPENSSL_SYSNAME_ULTRASPARC | ||
1876 | ble,pt %icc, .ede3.enc.finish | ||
1877 | #else | ||
1878 | ble .ede3.enc.finish | ||
1879 | #endif | ||
1880 | nop | ||
1881 | |||
1882 | add in2, 8, local1 ! bytes to load | ||
1883 | |||
1884 | ! addr, length, dest left, dest right, temp, temp2, label, ret label | ||
1885 | load_n_bytes(in0, local1, global4, out4, local2, local3, .LNB2, .ede3.enc.next.block_1) | ||
1886 | |||
1887 | .ede3.enc.finish: | ||
1888 | |||
1889 | LDPTR [%fp+BIAS+ARG0+6*ARGSZ], local4 ! ivec | ||
1890 | store_little_endian(local4, in5, out5, local5, .SLE6) ! ivec | ||
1891 | |||
1892 | ret | ||
1893 | restore | ||
1894 | |||
1895 | .ede3.dec: | ||
1896 | |||
1897 | STPTR in0, INPUT | ||
1898 | add in5, 120, in5 | ||
1899 | |||
1900 | STPTR in1, OUTPUT | ||
1901 | mov in0, local5 | ||
1902 | add in3, 120, in3 | ||
1903 | |||
1904 | STPTR in3, KS1 | ||
1905 | cmp in2, 0 | ||
1906 | |||
1907 | #ifdef OPENSSL_SYSNAME_ULTRASPARC | ||
1908 | ble %icc, .ede3.dec.finish | ||
1909 | #else | ||
1910 | ble .ede3.dec.finish | ||
1911 | #endif | ||
1912 | STPTR in5, KS3 | ||
1913 | |||
1914 | LDPTR [%fp+BIAS+ARG0+6*ARGSZ], local7 ! iv | ||
1915 | load_little_endian(local7, in0, in1, local3, .LLE8) | ||
1916 | |||
1917 | .ede3.dec.next.block: | ||
1918 | |||
1919 | load_little_endian(local5, in5, out5, local3, .LLE9) | ||
1920 | |||
1921 | ! parameter 6 1/2 for include encryption/decryption | ||
1922 | ! parameter 7 1 for mov in1 to in3 | ||
1923 | ! parameter 8 1 for mov in3 to in4 | ||
1924 | ! parameter 9 1 for load ks3 and ks2 to in4 and in3 | ||
1925 | |||
1926 | ip_macro(in5, out5, out5, in5, in4, 2, 0, 0, 1) ! inc .des_dec ks3 in4 | ||
1927 | |||
1928 | call .des_enc ! ks2 in3 | ||
1929 | LDPTR KS1, in4 | ||
1930 | |||
1931 | call .des_dec ! ks1 in4 | ||
1932 | nop | ||
1933 | |||
1934 | fp_macro(out5, in5, 0, 1) ! 1 for input and output address local5/7 | ||
1935 | |||
1936 | ! in2 is bytes left to be stored | ||
1937 | ! in2 is compared to 8 in the rounds | ||
1938 | |||
1939 | xor out5, in0, out4 | ||
1940 | #ifdef OPENSSL_SYSNAME_ULTRASPARC | ||
1941 | bl,pn %icc, .ede3.dec.seven.or.less | ||
1942 | #else | ||
1943 | bl .ede3.dec.seven.or.less | ||
1944 | #endif | ||
1945 | xor in5, in1, global4 | ||
1946 | |||
1947 | load_little_endian_inc(local5, in0, in1, local3, .LLE10) ! iv next block | ||
1948 | |||
1949 | store_little_endian(local7, out4, global4, local3, .SLE7) ! block | ||
1950 | |||
1951 | STPTR local5, INPUT | ||
1952 | addcc in2, -8, in2 | ||
1953 | add local7, 8, local7 | ||
1954 | |||
1955 | #ifdef OPENSSL_SYSNAME_ULTRASPARC | ||
1956 | bg,pt %icc, .ede3.dec.next.block | ||
1957 | #else | ||
1958 | bg .ede3.dec.next.block | ||
1959 | #endif | ||
1960 | STPTR local7, OUTPUT | ||
1961 | |||
1962 | .ede3.dec.store.iv: | ||
1963 | |||
1964 | LDPTR [%fp+BIAS+ARG0+6*ARGSZ], local4 ! ivec | ||
1965 | store_little_endian(local4, in0, in1, local5, .SLE8) ! ivec | ||
1966 | |||
1967 | .ede3.dec.finish: | ||
1968 | |||
1969 | ret | ||
1970 | restore | ||
1971 | |||
1972 | .ede3.dec.seven.or.less: | ||
1973 | |||
1974 | load_little_endian_inc(local5, in0, in1, local3, .LLE14) ! iv | ||
1975 | |||
1976 | store_n_bytes(local7, in2, global4, out4, local3, local4, .SNB2, .ede3.dec.store.iv) | ||
1977 | |||
1978 | |||
1979 | .DES_ede3_cbc_encrypt.end: | ||
1980 | .size DES_ede3_cbc_encrypt,.DES_ede3_cbc_encrypt.end-DES_ede3_cbc_encrypt | ||
diff --git a/src/lib/libcrypto/dh/dh_depr.c b/src/lib/libcrypto/dh/dh_depr.c new file mode 100644 index 0000000000..acc05f252c --- /dev/null +++ b/src/lib/libcrypto/dh/dh_depr.c | |||
@@ -0,0 +1,83 @@ | |||
1 | /* crypto/dh/dh_depr.c */ | ||
2 | /* ==================================================================== | ||
3 | * Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions | ||
7 | * are met: | ||
8 | * | ||
9 | * 1. Redistributions of source code must retain the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer. | ||
11 | * | ||
12 | * 2. Redistributions in binary form must reproduce the above copyright | ||
13 | * notice, this list of conditions and the following disclaimer in | ||
14 | * the documentation and/or other materials provided with the | ||
15 | * distribution. | ||
16 | * | ||
17 | * 3. All advertising materials mentioning features or use of this | ||
18 | * software must display the following acknowledgment: | ||
19 | * "This product includes software developed by the OpenSSL Project | ||
20 | * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" | ||
21 | * | ||
22 | * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to | ||
23 | * endorse or promote products derived from this software without | ||
24 | * prior written permission. For written permission, please contact | ||
25 | * openssl-core@openssl.org. | ||
26 | * | ||
27 | * 5. Products derived from this software may not be called "OpenSSL" | ||
28 | * nor may "OpenSSL" appear in their names without prior written | ||
29 | * permission of the OpenSSL Project. | ||
30 | * | ||
31 | * 6. Redistributions of any form whatsoever must retain the following | ||
32 | * acknowledgment: | ||
33 | * "This product includes software developed by the OpenSSL Project | ||
34 | * for use in the OpenSSL Toolkit (http://www.openssl.org/)" | ||
35 | * | ||
36 | * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY | ||
37 | * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
38 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | ||
39 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR | ||
40 | * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
41 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
42 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
43 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
44 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
45 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
46 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED | ||
47 | * OF THE POSSIBILITY OF SUCH DAMAGE. | ||
48 | * ==================================================================== | ||
49 | * | ||
50 | * This product includes cryptographic software written by Eric Young | ||
51 | * (eay@cryptsoft.com). This product includes software written by Tim | ||
52 | * Hudson (tjh@cryptsoft.com). | ||
53 | * | ||
54 | */ | ||
55 | |||
56 | |||
57 | /* This file contains deprecated functions as wrappers to the new ones */ | ||
58 | |||
59 | #include <stdio.h> | ||
60 | #include "cryptlib.h" | ||
61 | #include <openssl/bn.h> | ||
62 | #include <openssl/dh.h> | ||
63 | |||
64 | static void *dummy=&dummy; | ||
65 | |||
66 | #ifndef OPENSSL_NO_DEPRECATED | ||
67 | DH *DH_generate_parameters(int prime_len, int generator, | ||
68 | void (*callback)(int,int,void *), void *cb_arg) | ||
69 | { | ||
70 | BN_GENCB cb; | ||
71 | DH *ret=NULL; | ||
72 | |||
73 | if((ret=DH_new()) == NULL) | ||
74 | return NULL; | ||
75 | |||
76 | BN_GENCB_set_old(&cb, callback, cb_arg); | ||
77 | |||
78 | if(DH_generate_parameters_ex(ret, prime_len, generator, &cb)) | ||
79 | return ret; | ||
80 | DH_free(ret); | ||
81 | return NULL; | ||
82 | } | ||
83 | #endif | ||
diff --git a/src/lib/libcrypto/doc/ERR_set_mark.pod b/src/lib/libcrypto/doc/ERR_set_mark.pod new file mode 100644 index 0000000000..d3ca4f2e77 --- /dev/null +++ b/src/lib/libcrypto/doc/ERR_set_mark.pod | |||
@@ -0,0 +1,38 @@ | |||
1 | =pod | ||
2 | |||
3 | =head1 NAME | ||
4 | |||
5 | ERR_set_mark, ERR_pop_to_mark - set marks and pop errors until mark | ||
6 | |||
7 | =head1 SYNOPSIS | ||
8 | |||
9 | #include <openssl/err.h> | ||
10 | |||
11 | int ERR_set_mark(void); | ||
12 | |||
13 | int ERR_pop_to_mark(void); | ||
14 | |||
15 | =head1 DESCRIPTION | ||
16 | |||
17 | ERR_set_mark() sets a mark on the current topmost error record if there | ||
18 | is one. | ||
19 | |||
20 | ERR_pop_to_mark() will pop the top of the error stack until a mark is found. | ||
21 | The mark is then removed. If there is no mark, the whole stack is removed. | ||
22 | |||
23 | =head1 RETURN VALUES | ||
24 | |||
25 | ERR_set_mark() returns 0 if the error stack is empty, otherwise 1. | ||
26 | |||
27 | ERR_pop_to_mark() returns 0 if there was no mark in the error stack, which | ||
28 | implies that the stack became empty, otherwise 1. | ||
29 | |||
30 | =head1 SEE ALSO | ||
31 | |||
32 | L<err(3)|err(3)> | ||
33 | |||
34 | =head1 HISTORY | ||
35 | |||
36 | ERR_set_mark() and ERR_pop_to_mark() were added in OpenSSL 0.9.8. | ||
37 | |||
38 | =cut | ||
diff --git a/src/lib/libcrypto/doc/PKCS12_create.pod b/src/lib/libcrypto/doc/PKCS12_create.pod index 48f3bb8cb8..de7cab2bdf 100644 --- a/src/lib/libcrypto/doc/PKCS12_create.pod +++ b/src/lib/libcrypto/doc/PKCS12_create.pod | |||
@@ -46,6 +46,24 @@ export grade software which could use signing only keys of arbitrary size but | |||
46 | had restrictions on the permissible sizes of keys which could be used for | 46 | had restrictions on the permissible sizes of keys which could be used for |
47 | encryption. | 47 | encryption. |
48 | 48 | ||
49 | =head1 NEW FUNCTIONALITY IN OPENSSL 0.9.8 | ||
50 | |||
51 | Some additional functionality was added to PKCS12_create() in OpenSSL | ||
52 | 0.9.8. These extensions are detailed below. | ||
53 | |||
54 | If a certificate contains an B<alias> or B<keyid> then this will be | ||
55 | used for the corresponding B<friendlyName> or B<localKeyID> in the | ||
56 | PKCS12 structure. | ||
57 | |||
58 | Either B<pkey>, B<cert> or both can be B<NULL> to indicate that no key or | ||
59 | certficate is required. In previous versions both had to be present or | ||
60 | a fatal error is returned. | ||
61 | |||
62 | B<nid_key> or B<nid_cert> can be set to -1 indicating that no encryption | ||
63 | should be used. | ||
64 | |||
65 | B<mac_iter> can be set to -1 and the MAC will then be omitted entirely. | ||
66 | |||
49 | =head1 SEE ALSO | 67 | =head1 SEE ALSO |
50 | 68 | ||
51 | L<d2i_PKCS12(3)|d2i_PKCS12(3)> | 69 | L<d2i_PKCS12(3)|d2i_PKCS12(3)> |
diff --git a/src/lib/libcrypto/doc/PKCS7_sign.pod b/src/lib/libcrypto/doc/PKCS7_sign.pod index fc7e649b34..ffd0c734b0 100644 --- a/src/lib/libcrypto/doc/PKCS7_sign.pod +++ b/src/lib/libcrypto/doc/PKCS7_sign.pod | |||
@@ -51,6 +51,24 @@ If present the SMIMECapabilities attribute indicates support for the following | |||
51 | algorithms: triple DES, 128 bit RC2, 64 bit RC2, DES and 40 bit RC2. If any | 51 | algorithms: triple DES, 128 bit RC2, 64 bit RC2, DES and 40 bit RC2. If any |
52 | of these algorithms is disabled then it will not be included. | 52 | of these algorithms is disabled then it will not be included. |
53 | 53 | ||
54 | If the flags B<PKCS7_PARTSIGN> is set then the returned B<PKCS7> structure | ||
55 | is just initialized ready to perform the signing operation. The signing | ||
56 | is however B<not> performed and the data to be signed is not read from | ||
57 | the B<data> parameter. Signing is deferred until after the data has been | ||
58 | written. In this way data can be signed in a single pass. Currently the | ||
59 | flag B<PKCS7_DETACHED> B<must> also be set. | ||
60 | |||
61 | =head1 NOTES | ||
62 | |||
63 | Currently the flag B<PKCS7_PARTSIGN> is only supported for detached | ||
64 | data. If this flag is set the returned B<PKCS7> structure is B<not> | ||
65 | complete and outputting its contents via a function that does not | ||
66 | properly finalize the B<PKCS7> structure will give unpredictable | ||
67 | results. | ||
68 | |||
69 | At present only the SMIME_write_PKCS7() function properly finalizes the | ||
70 | structure. | ||
71 | |||
54 | =head1 BUGS | 72 | =head1 BUGS |
55 | 73 | ||
56 | PKCS7_sign() is somewhat limited. It does not support multiple signers, some | 74 | PKCS7_sign() is somewhat limited. It does not support multiple signers, some |
@@ -64,10 +82,6 @@ signed due to memory restraints. There should be a way to sign data without | |||
64 | having to hold it all in memory, this would however require fairly major | 82 | having to hold it all in memory, this would however require fairly major |
65 | revisions of the OpenSSL ASN1 code. | 83 | revisions of the OpenSSL ASN1 code. |
66 | 84 | ||
67 | Clear text signing does not store the content in memory but the way PKCS7_sign() | ||
68 | operates means that two passes of the data must typically be made: one to compute | ||
69 | the signatures and a second to output the data along with the signature. There | ||
70 | should be a way to process the data with only a single pass. | ||
71 | 85 | ||
72 | =head1 RETURN VALUES | 86 | =head1 RETURN VALUES |
73 | 87 | ||
@@ -82,4 +96,6 @@ L<ERR_get_error(3)|ERR_get_error(3)>, L<PKCS7_verify(3)|PKCS7_verify(3)> | |||
82 | 96 | ||
83 | PKCS7_sign() was added to OpenSSL 0.9.5 | 97 | PKCS7_sign() was added to OpenSSL 0.9.5 |
84 | 98 | ||
99 | The B<PKCS7_PARTSIGN> flag was added in OpenSSL 0.9.8 | ||
100 | |||
85 | =cut | 101 | =cut |
diff --git a/src/lib/libcrypto/doc/SMIME_write_PKCS7.pod b/src/lib/libcrypto/doc/SMIME_write_PKCS7.pod index 2cfad2e049..61945b3887 100644 --- a/src/lib/libcrypto/doc/SMIME_write_PKCS7.pod +++ b/src/lib/libcrypto/doc/SMIME_write_PKCS7.pod | |||
@@ -30,18 +30,20 @@ If the B<PKCS7_TEXT> flag is set MIME headers for type B<text/plain> | |||
30 | are added to the content, this only makes sense if B<PKCS7_DETACHED> | 30 | are added to the content, this only makes sense if B<PKCS7_DETACHED> |
31 | is also set. | 31 | is also set. |
32 | 32 | ||
33 | If cleartext signing is being used then the data must be read twice: | 33 | If the B<PKCS7_PARTSIGN> flag is set the signed data is finalized |
34 | once to compute the signature in PKCS7_sign() and once to output the | 34 | and output along with the content. This flag should only be set |
35 | S/MIME message. | 35 | if B<PKCS7_DETACHED> is also set and the previous call to PKCS7_sign() |
36 | also set these flags. | ||
37 | |||
38 | If cleartext signing is being used and B<PKCS7_PARTSIGN> not set then | ||
39 | the data must be read twice: once to compute the signature in PKCS7_sign() | ||
40 | and once to output the S/MIME message. | ||
36 | 41 | ||
37 | =head1 BUGS | 42 | =head1 BUGS |
38 | 43 | ||
39 | SMIME_write_PKCS7() always base64 encodes PKCS#7 structures, there | 44 | SMIME_write_PKCS7() always base64 encodes PKCS#7 structures, there |
40 | should be an option to disable this. | 45 | should be an option to disable this. |
41 | 46 | ||
42 | There should really be a way to produce cleartext signing using only | ||
43 | a single pass of the data. | ||
44 | |||
45 | =head1 RETURN VALUES | 47 | =head1 RETURN VALUES |
46 | 48 | ||
47 | SMIME_write_PKCS7() returns 1 for success or 0 for failure. | 49 | SMIME_write_PKCS7() returns 1 for success or 0 for failure. |
diff --git a/src/lib/libcrypto/doc/X509_NAME_print_ex.pod b/src/lib/libcrypto/doc/X509_NAME_print_ex.pod index 919b908919..2579a5dc9d 100644 --- a/src/lib/libcrypto/doc/X509_NAME_print_ex.pod +++ b/src/lib/libcrypto/doc/X509_NAME_print_ex.pod | |||
@@ -86,10 +86,10 @@ is equivalent to: | |||
86 | B<ASN1_STRFLGS_RFC2253 | XN_FLAG_SEP_COMMA_PLUS | XN_FLAG_DN_REV | XN_FLAG_FN_SN | XN_FLAG_DUMP_UNKNOWN_FIELDS> | 86 | B<ASN1_STRFLGS_RFC2253 | XN_FLAG_SEP_COMMA_PLUS | XN_FLAG_DN_REV | XN_FLAG_FN_SN | XN_FLAG_DUMP_UNKNOWN_FIELDS> |
87 | 87 | ||
88 | 88 | ||
89 | B<XN_FLAG_ONELINE> is a more readable one line format it is the same as: | 89 | B<XN_FLAG_ONELINE> is a more readable one line format which is the same as: |
90 | B<ASN1_STRFLGS_RFC2253 | ASN1_STRFLGS_ESC_QUOTE | XN_FLAG_SEP_CPLUS_SPC | XN_FLAG_SPC_EQ | XN_FLAG_FN_SN> | 90 | B<ASN1_STRFLGS_RFC2253 | ASN1_STRFLGS_ESC_QUOTE | XN_FLAG_SEP_CPLUS_SPC | XN_FLAG_SPC_EQ | XN_FLAG_FN_SN> |
91 | 91 | ||
92 | B<XN_FLAG_MULTILINE> is a multiline format is is the same as: | 92 | B<XN_FLAG_MULTILINE> is a multiline format which is the same as: |
93 | B<ASN1_STRFLGS_ESC_CTRL | ASN1_STRFLGS_ESC_MSB | XN_FLAG_SEP_MULTILINE | XN_FLAG_SPC_EQ | XN_FLAG_FN_LN | XN_FLAG_FN_ALIGN> | 93 | B<ASN1_STRFLGS_ESC_CTRL | ASN1_STRFLGS_ESC_MSB | XN_FLAG_SEP_MULTILINE | XN_FLAG_SPC_EQ | XN_FLAG_FN_LN | XN_FLAG_FN_ALIGN> |
94 | 94 | ||
95 | B<XN_FLAG_COMPAT> uses a format identical to X509_NAME_print(): in fact it calls X509_NAME_print() internally. | 95 | B<XN_FLAG_COMPAT> uses a format identical to X509_NAME_print(): in fact it calls X509_NAME_print() internally. |
diff --git a/src/lib/libcrypto/doc/d2i_X509.pod b/src/lib/libcrypto/doc/d2i_X509.pod index 5e3c3d0985..5bfa18afbb 100644 --- a/src/lib/libcrypto/doc/d2i_X509.pod +++ b/src/lib/libcrypto/doc/d2i_X509.pod | |||
@@ -9,7 +9,7 @@ i2d_X509_fp - X509 encode and decode functions | |||
9 | 9 | ||
10 | #include <openssl/x509.h> | 10 | #include <openssl/x509.h> |
11 | 11 | ||
12 | X509 *d2i_X509(X509 **px, unsigned char **in, int len); | 12 | X509 *d2i_X509(X509 **px, const unsigned char **in, int len); |
13 | int i2d_X509(X509 *x, unsigned char **out); | 13 | int i2d_X509(X509 *x, unsigned char **out); |
14 | 14 | ||
15 | X509 *d2i_X509_bio(BIO *bp, X509 **x); | 15 | X509 *d2i_X509_bio(BIO *bp, X509 **x); |
@@ -23,13 +23,13 @@ i2d_X509_fp - X509 encode and decode functions | |||
23 | The X509 encode and decode routines encode and parse an | 23 | The X509 encode and decode routines encode and parse an |
24 | B<X509> structure, which represents an X509 certificate. | 24 | B<X509> structure, which represents an X509 certificate. |
25 | 25 | ||
26 | d2i_X509() attempts to decode B<len> bytes at B<*out>. If | 26 | d2i_X509() attempts to decode B<len> bytes at B<*in>. If |
27 | successful a pointer to the B<X509> structure is returned. If an error | 27 | successful a pointer to the B<X509> structure is returned. If an error |
28 | occurred then B<NULL> is returned. If B<px> is not B<NULL> then the | 28 | occurred then B<NULL> is returned. If B<px> is not B<NULL> then the |
29 | returned structure is written to B<*px>. If B<*px> is not B<NULL> | 29 | returned structure is written to B<*px>. If B<*px> is not B<NULL> |
30 | then it is assumed that B<*px> contains a valid B<X509> | 30 | then it is assumed that B<*px> contains a valid B<X509> |
31 | structure and an attempt is made to reuse it. If the call is | 31 | structure and an attempt is made to reuse it. If the call is |
32 | successful B<*out> is incremented to the byte following the | 32 | successful B<*in> is incremented to the byte following the |
33 | parsed data. | 33 | parsed data. |
34 | 34 | ||
35 | i2d_X509() encodes the structure pointed to by B<x> into DER format. | 35 | i2d_X509() encodes the structure pointed to by B<x> into DER format. |
diff --git a/src/lib/libcrypto/doc/d2i_X509_CRL.pod b/src/lib/libcrypto/doc/d2i_X509_CRL.pod index 06c5b23c09..e7295a5d61 100644 --- a/src/lib/libcrypto/doc/d2i_X509_CRL.pod +++ b/src/lib/libcrypto/doc/d2i_X509_CRL.pod | |||
@@ -9,7 +9,7 @@ i2d_X509_CRL_bio, i2d_X509_CRL_fp - PKCS#10 certificate request functions. | |||
9 | 9 | ||
10 | #include <openssl/x509.h> | 10 | #include <openssl/x509.h> |
11 | 11 | ||
12 | X509_CRL *d2i_X509_CRL(X509_CRL **a, unsigned char **pp, long length); | 12 | X509_CRL *d2i_X509_CRL(X509_CRL **a, const unsigned char **pp, long length); |
13 | int i2d_X509_CRL(X509_CRL *a, unsigned char **pp); | 13 | int i2d_X509_CRL(X509_CRL *a, unsigned char **pp); |
14 | 14 | ||
15 | X509_CRL *d2i_X509_CRL_bio(BIO *bp, X509_CRL **x); | 15 | X509_CRL *d2i_X509_CRL_bio(BIO *bp, X509_CRL **x); |
diff --git a/src/lib/libcrypto/doc/d2i_X509_REQ.pod b/src/lib/libcrypto/doc/d2i_X509_REQ.pod index be4ad68257..ae32a3891d 100644 --- a/src/lib/libcrypto/doc/d2i_X509_REQ.pod +++ b/src/lib/libcrypto/doc/d2i_X509_REQ.pod | |||
@@ -9,7 +9,7 @@ i2d_X509_REQ_bio, i2d_X509_REQ_fp - PKCS#10 certificate request functions. | |||
9 | 9 | ||
10 | #include <openssl/x509.h> | 10 | #include <openssl/x509.h> |
11 | 11 | ||
12 | X509_REQ *d2i_X509_REQ(X509_REQ **a, unsigned char **pp, long length); | 12 | X509_REQ *d2i_X509_REQ(X509_REQ **a, const unsigned char **pp, long length); |
13 | int i2d_X509_REQ(X509_REQ *a, unsigned char **pp); | 13 | int i2d_X509_REQ(X509_REQ *a, unsigned char **pp); |
14 | 14 | ||
15 | X509_REQ *d2i_X509_REQ_bio(BIO *bp, X509_REQ **x); | 15 | X509_REQ *d2i_X509_REQ_bio(BIO *bp, X509_REQ **x); |
diff --git a/src/lib/libcrypto/doc/engine.pod b/src/lib/libcrypto/doc/engine.pod index c77dad5562..f5ab1c3e50 100644 --- a/src/lib/libcrypto/doc/engine.pod +++ b/src/lib/libcrypto/doc/engine.pod | |||
@@ -23,21 +23,26 @@ engine - ENGINE cryptographic module support | |||
23 | 23 | ||
24 | void ENGINE_load_openssl(void); | 24 | void ENGINE_load_openssl(void); |
25 | void ENGINE_load_dynamic(void); | 25 | void ENGINE_load_dynamic(void); |
26 | void ENGINE_load_cswift(void); | 26 | #ifndef OPENSSL_NO_STATIC_ENGINE |
27 | void ENGINE_load_chil(void); | 27 | void ENGINE_load_4758cca(void); |
28 | void ENGINE_load_aep(void); | ||
28 | void ENGINE_load_atalla(void); | 29 | void ENGINE_load_atalla(void); |
30 | void ENGINE_load_chil(void); | ||
31 | void ENGINE_load_cswift(void); | ||
32 | void ENGINE_load_gmp(void); | ||
29 | void ENGINE_load_nuron(void); | 33 | void ENGINE_load_nuron(void); |
30 | void ENGINE_load_ubsec(void); | ||
31 | void ENGINE_load_aep(void); | ||
32 | void ENGINE_load_sureware(void); | 34 | void ENGINE_load_sureware(void); |
33 | void ENGINE_load_4758cca(void); | 35 | void ENGINE_load_ubsec(void); |
34 | void ENGINE_load_openbsd_dev_crypto(void); | 36 | #endif |
37 | void ENGINE_load_cryptodev(void); | ||
35 | void ENGINE_load_builtin_engines(void); | 38 | void ENGINE_load_builtin_engines(void); |
36 | 39 | ||
37 | void ENGINE_cleanup(void); | 40 | void ENGINE_cleanup(void); |
38 | 41 | ||
39 | ENGINE *ENGINE_get_default_RSA(void); | 42 | ENGINE *ENGINE_get_default_RSA(void); |
40 | ENGINE *ENGINE_get_default_DSA(void); | 43 | ENGINE *ENGINE_get_default_DSA(void); |
44 | ENGINE *ENGINE_get_default_ECDH(void); | ||
45 | ENGINE *ENGINE_get_default_ECDSA(void); | ||
41 | ENGINE *ENGINE_get_default_DH(void); | 46 | ENGINE *ENGINE_get_default_DH(void); |
42 | ENGINE *ENGINE_get_default_RAND(void); | 47 | ENGINE *ENGINE_get_default_RAND(void); |
43 | ENGINE *ENGINE_get_cipher_engine(int nid); | 48 | ENGINE *ENGINE_get_cipher_engine(int nid); |
@@ -45,6 +50,8 @@ engine - ENGINE cryptographic module support | |||
45 | 50 | ||
46 | int ENGINE_set_default_RSA(ENGINE *e); | 51 | int ENGINE_set_default_RSA(ENGINE *e); |
47 | int ENGINE_set_default_DSA(ENGINE *e); | 52 | int ENGINE_set_default_DSA(ENGINE *e); |
53 | int ENGINE_set_default_ECDH(ENGINE *e); | ||
54 | int ENGINE_set_default_ECDSA(ENGINE *e); | ||
48 | int ENGINE_set_default_DH(ENGINE *e); | 55 | int ENGINE_set_default_DH(ENGINE *e); |
49 | int ENGINE_set_default_RAND(ENGINE *e); | 56 | int ENGINE_set_default_RAND(ENGINE *e); |
50 | int ENGINE_set_default_ciphers(ENGINE *e); | 57 | int ENGINE_set_default_ciphers(ENGINE *e); |
@@ -62,12 +69,21 @@ engine - ENGINE cryptographic module support | |||
62 | int ENGINE_register_DSA(ENGINE *e); | 69 | int ENGINE_register_DSA(ENGINE *e); |
63 | void ENGINE_unregister_DSA(ENGINE *e); | 70 | void ENGINE_unregister_DSA(ENGINE *e); |
64 | void ENGINE_register_all_DSA(void); | 71 | void ENGINE_register_all_DSA(void); |
72 | int ENGINE_register_ECDH(ENGINE *e); | ||
73 | void ENGINE_unregister_ECDH(ENGINE *e); | ||
74 | void ENGINE_register_all_ECDH(void); | ||
75 | int ENGINE_register_ECDSA(ENGINE *e); | ||
76 | void ENGINE_unregister_ECDSA(ENGINE *e); | ||
77 | void ENGINE_register_all_ECDSA(void); | ||
65 | int ENGINE_register_DH(ENGINE *e); | 78 | int ENGINE_register_DH(ENGINE *e); |
66 | void ENGINE_unregister_DH(ENGINE *e); | 79 | void ENGINE_unregister_DH(ENGINE *e); |
67 | void ENGINE_register_all_DH(void); | 80 | void ENGINE_register_all_DH(void); |
68 | int ENGINE_register_RAND(ENGINE *e); | 81 | int ENGINE_register_RAND(ENGINE *e); |
69 | void ENGINE_unregister_RAND(ENGINE *e); | 82 | void ENGINE_unregister_RAND(ENGINE *e); |
70 | void ENGINE_register_all_RAND(void); | 83 | void ENGINE_register_all_RAND(void); |
84 | int ENGINE_register_STORE(ENGINE *e); | ||
85 | void ENGINE_unregister_STORE(ENGINE *e); | ||
86 | void ENGINE_register_all_STORE(void); | ||
71 | int ENGINE_register_ciphers(ENGINE *e); | 87 | int ENGINE_register_ciphers(ENGINE *e); |
72 | void ENGINE_unregister_ciphers(ENGINE *e); | 88 | void ENGINE_unregister_ciphers(ENGINE *e); |
73 | void ENGINE_register_all_ciphers(void); | 89 | void ENGINE_register_all_ciphers(void); |
@@ -77,12 +93,12 @@ engine - ENGINE cryptographic module support | |||
77 | int ENGINE_register_complete(ENGINE *e); | 93 | int ENGINE_register_complete(ENGINE *e); |
78 | int ENGINE_register_all_complete(void); | 94 | int ENGINE_register_all_complete(void); |
79 | 95 | ||
80 | int ENGINE_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)()); | 96 | int ENGINE_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void)); |
81 | int ENGINE_cmd_is_executable(ENGINE *e, int cmd); | 97 | int ENGINE_cmd_is_executable(ENGINE *e, int cmd); |
82 | int ENGINE_ctrl_cmd(ENGINE *e, const char *cmd_name, | 98 | int ENGINE_ctrl_cmd(ENGINE *e, const char *cmd_name, |
83 | long i, void *p, void (*f)(), int cmd_optional); | 99 | long i, void *p, void (*f)(void), int cmd_optional); |
84 | int ENGINE_ctrl_cmd_string(ENGINE *e, const char *cmd_name, const char *arg, | 100 | int ENGINE_ctrl_cmd_string(ENGINE *e, const char *cmd_name, const char *arg, |
85 | int cmd_optional); | 101 | int cmd_optional); |
86 | 102 | ||
87 | int ENGINE_set_ex_data(ENGINE *e, int idx, void *arg); | 103 | int ENGINE_set_ex_data(ENGINE *e, int idx, void *arg); |
88 | void *ENGINE_get_ex_data(const ENGINE *e, int idx); | 104 | void *ENGINE_get_ex_data(const ENGINE *e, int idx); |
@@ -92,13 +108,17 @@ engine - ENGINE cryptographic module support | |||
92 | 108 | ||
93 | ENGINE *ENGINE_new(void); | 109 | ENGINE *ENGINE_new(void); |
94 | int ENGINE_free(ENGINE *e); | 110 | int ENGINE_free(ENGINE *e); |
111 | int ENGINE_up_ref(ENGINE *e); | ||
95 | 112 | ||
96 | int ENGINE_set_id(ENGINE *e, const char *id); | 113 | int ENGINE_set_id(ENGINE *e, const char *id); |
97 | int ENGINE_set_name(ENGINE *e, const char *name); | 114 | int ENGINE_set_name(ENGINE *e, const char *name); |
98 | int ENGINE_set_RSA(ENGINE *e, const RSA_METHOD *rsa_meth); | 115 | int ENGINE_set_RSA(ENGINE *e, const RSA_METHOD *rsa_meth); |
99 | int ENGINE_set_DSA(ENGINE *e, const DSA_METHOD *dsa_meth); | 116 | int ENGINE_set_DSA(ENGINE *e, const DSA_METHOD *dsa_meth); |
117 | int ENGINE_set_ECDH(ENGINE *e, const ECDH_METHOD *dh_meth); | ||
118 | int ENGINE_set_ECDSA(ENGINE *e, const ECDSA_METHOD *dh_meth); | ||
100 | int ENGINE_set_DH(ENGINE *e, const DH_METHOD *dh_meth); | 119 | int ENGINE_set_DH(ENGINE *e, const DH_METHOD *dh_meth); |
101 | int ENGINE_set_RAND(ENGINE *e, const RAND_METHOD *rand_meth); | 120 | int ENGINE_set_RAND(ENGINE *e, const RAND_METHOD *rand_meth); |
121 | int ENGINE_set_STORE(ENGINE *e, const STORE_METHOD *rand_meth); | ||
102 | int ENGINE_set_destroy_function(ENGINE *e, ENGINE_GEN_INT_FUNC_PTR destroy_f); | 122 | int ENGINE_set_destroy_function(ENGINE *e, ENGINE_GEN_INT_FUNC_PTR destroy_f); |
103 | int ENGINE_set_init_function(ENGINE *e, ENGINE_GEN_INT_FUNC_PTR init_f); | 123 | int ENGINE_set_init_function(ENGINE *e, ENGINE_GEN_INT_FUNC_PTR init_f); |
104 | int ENGINE_set_finish_function(ENGINE *e, ENGINE_GEN_INT_FUNC_PTR finish_f); | 124 | int ENGINE_set_finish_function(ENGINE *e, ENGINE_GEN_INT_FUNC_PTR finish_f); |
@@ -114,8 +134,11 @@ engine - ENGINE cryptographic module support | |||
114 | const char *ENGINE_get_name(const ENGINE *e); | 134 | const char *ENGINE_get_name(const ENGINE *e); |
115 | const RSA_METHOD *ENGINE_get_RSA(const ENGINE *e); | 135 | const RSA_METHOD *ENGINE_get_RSA(const ENGINE *e); |
116 | const DSA_METHOD *ENGINE_get_DSA(const ENGINE *e); | 136 | const DSA_METHOD *ENGINE_get_DSA(const ENGINE *e); |
137 | const ECDH_METHOD *ENGINE_get_ECDH(const ENGINE *e); | ||
138 | const ECDSA_METHOD *ENGINE_get_ECDSA(const ENGINE *e); | ||
117 | const DH_METHOD *ENGINE_get_DH(const ENGINE *e); | 139 | const DH_METHOD *ENGINE_get_DH(const ENGINE *e); |
118 | const RAND_METHOD *ENGINE_get_RAND(const ENGINE *e); | 140 | const RAND_METHOD *ENGINE_get_RAND(const ENGINE *e); |
141 | const STORE_METHOD *ENGINE_get_STORE(const ENGINE *e); | ||
119 | ENGINE_GEN_INT_FUNC_PTR ENGINE_get_destroy_function(const ENGINE *e); | 142 | ENGINE_GEN_INT_FUNC_PTR ENGINE_get_destroy_function(const ENGINE *e); |
120 | ENGINE_GEN_INT_FUNC_PTR ENGINE_get_init_function(const ENGINE *e); | 143 | ENGINE_GEN_INT_FUNC_PTR ENGINE_get_init_function(const ENGINE *e); |
121 | ENGINE_GEN_INT_FUNC_PTR ENGINE_get_finish_function(const ENGINE *e); | 144 | ENGINE_GEN_INT_FUNC_PTR ENGINE_get_finish_function(const ENGINE *e); |
@@ -148,7 +171,8 @@ The cryptographic functionality that can be provided by an B<ENGINE> | |||
148 | implementation includes the following abstractions; | 171 | implementation includes the following abstractions; |
149 | 172 | ||
150 | RSA_METHOD - for providing alternative RSA implementations | 173 | RSA_METHOD - for providing alternative RSA implementations |
151 | DSA_METHOD, DH_METHOD, RAND_METHOD - alternative DSA, DH, and RAND | 174 | DSA_METHOD, DH_METHOD, RAND_METHOD, ECDH_METHOD, ECDSA_METHOD, |
175 | STORE_METHOD - similarly for other OpenSSL APIs | ||
152 | EVP_CIPHER - potentially multiple cipher algorithms (indexed by 'nid') | 176 | EVP_CIPHER - potentially multiple cipher algorithms (indexed by 'nid') |
153 | EVP_DIGEST - potentially multiple hash algorithms (indexed by 'nid') | 177 | EVP_DIGEST - potentially multiple hash algorithms (indexed by 'nid') |
154 | key-loading - loading public and/or private EVP_PKEY keys | 178 | key-loading - loading public and/or private EVP_PKEY keys |
@@ -157,52 +181,45 @@ implementation includes the following abstractions; | |||
157 | 181 | ||
158 | Due to the modular nature of the ENGINE API, pointers to ENGINEs need to be | 182 | Due to the modular nature of the ENGINE API, pointers to ENGINEs need to be |
159 | treated as handles - ie. not only as pointers, but also as references to | 183 | treated as handles - ie. not only as pointers, but also as references to |
160 | the underlying ENGINE object. Ie. you should obtain a new reference when | 184 | the underlying ENGINE object. Ie. one should obtain a new reference when |
161 | making copies of an ENGINE pointer if the copies will be used (and | 185 | making copies of an ENGINE pointer if the copies will be used (and |
162 | released) independantly. | 186 | released) independently. |
163 | 187 | ||
164 | ENGINE objects have two levels of reference-counting to match the way in | 188 | ENGINE objects have two levels of reference-counting to match the way in |
165 | which the objects are used. At the most basic level, each ENGINE pointer is | 189 | which the objects are used. At the most basic level, each ENGINE pointer is |
166 | inherently a B<structural> reference - you need a structural reference | 190 | inherently a B<structural> reference - a structural reference is required |
167 | simply to refer to the pointer value at all, as this kind of reference is | 191 | to use the pointer value at all, as this kind of reference is a guarantee |
168 | your guarantee that the structure can not be deallocated until you release | 192 | that the structure can not be deallocated until the reference is released. |
169 | your reference. | 193 | |
170 | 194 | However, a structural reference provides no guarantee that the ENGINE is | |
171 | However, a structural reference provides no guarantee that the ENGINE has | 195 | initiliased and able to use any of its cryptographic |
172 | been initiliased to be usable to perform any of its cryptographic | 196 | implementations. Indeed it's quite possible that most ENGINEs will not |
173 | implementations - and indeed it's quite possible that most ENGINEs will not | 197 | initialise at all in typical environments, as ENGINEs are typically used to |
174 | initialised at all on standard setups, as ENGINEs are typically used to | ||
175 | support specialised hardware. To use an ENGINE's functionality, you need a | 198 | support specialised hardware. To use an ENGINE's functionality, you need a |
176 | B<functional> reference. This kind of reference can be considered a | 199 | B<functional> reference. This kind of reference can be considered a |
177 | specialised form of structural reference, because each functional reference | 200 | specialised form of structural reference, because each functional reference |
178 | implicitly contains a structural reference as well - however to avoid | 201 | implicitly contains a structural reference as well - however to avoid |
179 | difficult-to-find programming bugs, it is recommended to treat the two | 202 | difficult-to-find programming bugs, it is recommended to treat the two |
180 | kinds of reference independantly. If you have a functional reference to an | 203 | kinds of reference independently. If you have a functional reference to an |
181 | ENGINE, you have a guarantee that the ENGINE has been initialised ready to | 204 | ENGINE, you have a guarantee that the ENGINE has been initialised ready to |
182 | perform cryptographic operations and will not be uninitialised or cleaned | 205 | perform cryptographic operations and will remain uninitialised |
183 | up until after you have released your reference. | 206 | until after you have released your reference. |
184 | |||
185 | We will discuss the two kinds of reference separately, including how to | ||
186 | tell which one you are dealing with at any given point in time (after all | ||
187 | they are both simply (ENGINE *) pointers, the difference is in the way they | ||
188 | are used). | ||
189 | 207 | ||
190 | I<Structural references> | 208 | I<Structural references> |
191 | 209 | ||
192 | This basic type of reference is typically used for creating new ENGINEs | 210 | This basic type of reference is used for instantiating new ENGINEs, |
193 | dynamically, iterating across OpenSSL's internal linked-list of loaded | 211 | iterating across OpenSSL's internal linked-list of loaded |
194 | ENGINEs, reading information about an ENGINE, etc. Essentially a structural | 212 | ENGINEs, reading information about an ENGINE, etc. Essentially a structural |
195 | reference is sufficient if you only need to query or manipulate the data of | 213 | reference is sufficient if you only need to query or manipulate the data of |
196 | an ENGINE implementation rather than use its functionality. | 214 | an ENGINE implementation rather than use its functionality. |
197 | 215 | ||
198 | The ENGINE_new() function returns a structural reference to a new (empty) | 216 | The ENGINE_new() function returns a structural reference to a new (empty) |
199 | ENGINE object. Other than that, structural references come from return | 217 | ENGINE object. There are other ENGINE API functions that return structural |
200 | values to various ENGINE API functions such as; ENGINE_by_id(), | 218 | references such as; ENGINE_by_id(), ENGINE_get_first(), ENGINE_get_last(), |
201 | ENGINE_get_first(), ENGINE_get_last(), ENGINE_get_next(), | 219 | ENGINE_get_next(), ENGINE_get_prev(). All structural references should be |
202 | ENGINE_get_prev(). All structural references should be released by a | 220 | released by a corresponding to call to the ENGINE_free() function - the |
203 | corresponding to call to the ENGINE_free() function - the ENGINE object | 221 | ENGINE object itself will only actually be cleaned up and deallocated when |
204 | itself will only actually be cleaned up and deallocated when the last | 222 | the last structural reference is released. |
205 | structural reference is released. | ||
206 | 223 | ||
207 | It should also be noted that many ENGINE API function calls that accept a | 224 | It should also be noted that many ENGINE API function calls that accept a |
208 | structural reference will internally obtain another reference - typically | 225 | structural reference will internally obtain another reference - typically |
@@ -237,15 +254,9 @@ call the ENGINE_init() function. This returns zero if the ENGINE was not | |||
237 | already operational and couldn't be successfully initialised (eg. lack of | 254 | already operational and couldn't be successfully initialised (eg. lack of |
238 | system drivers, no special hardware attached, etc), otherwise it will | 255 | system drivers, no special hardware attached, etc), otherwise it will |
239 | return non-zero to indicate that the ENGINE is now operational and will | 256 | return non-zero to indicate that the ENGINE is now operational and will |
240 | have allocated a new B<functional> reference to the ENGINE. In this case, | 257 | have allocated a new B<functional> reference to the ENGINE. All functional |
241 | the supplied ENGINE pointer is, from the point of the view of the caller, | 258 | references are released by calling ENGINE_finish() (which removes the |
242 | both a structural reference and a functional reference - so if the caller | 259 | implicit structural reference as well). |
243 | intends to use it as a functional reference it should free the structural | ||
244 | reference with ENGINE_free() first. If the caller wishes to use it only as | ||
245 | a structural reference (eg. if the ENGINE_init() call was simply to test if | ||
246 | the ENGINE seems available/online), then it should free the functional | ||
247 | reference; all functional references are released by the ENGINE_finish() | ||
248 | function. | ||
249 | 260 | ||
250 | The second way to get a functional reference is by asking OpenSSL for a | 261 | The second way to get a functional reference is by asking OpenSSL for a |
251 | default implementation for a given task, eg. by ENGINE_get_default_RSA(), | 262 | default implementation for a given task, eg. by ENGINE_get_default_RSA(), |
@@ -259,26 +270,21 @@ algorithm-specific types in OpenSSL, such as RSA, DSA, EVP_CIPHER_CTX, etc. | |||
259 | For each supported abstraction, the ENGINE code maintains an internal table | 270 | For each supported abstraction, the ENGINE code maintains an internal table |
260 | of state to control which implementations are available for a given | 271 | of state to control which implementations are available for a given |
261 | abstraction and which should be used by default. These implementations are | 272 | abstraction and which should be used by default. These implementations are |
262 | registered in the tables separated-out by an 'nid' index, because | 273 | registered in the tables and indexed by an 'nid' value, because |
263 | abstractions like EVP_CIPHER and EVP_DIGEST support many distinct | 274 | abstractions like EVP_CIPHER and EVP_DIGEST support many distinct |
264 | algorithms and modes - ENGINEs will support different numbers and | 275 | algorithms and modes, and ENGINEs can support arbitrarily many of them. |
265 | combinations of these. In the case of other abstractions like RSA, DSA, | 276 | In the case of other abstractions like RSA, DSA, etc, there is only one |
266 | etc, there is only one "algorithm" so all implementations implicitly | 277 | "algorithm" so all implementations implicitly register using the same 'nid' |
267 | register using the same 'nid' index. ENGINEs can be B<registered> into | 278 | index. |
268 | these tables to make themselves available for use automatically by the | 279 | |
269 | various abstractions, eg. RSA. For illustrative purposes, we continue with | 280 | When a default ENGINE is requested for a given abstraction/algorithm/mode, (eg. |
270 | the RSA example, though all comments apply similarly to the other | 281 | when calling RSA_new_method(NULL)), a "get_default" call will be made to the |
271 | abstractions (they each get their own table and linkage to the | 282 | ENGINE subsystem to process the corresponding state table and return a |
272 | corresponding section of openssl code). | 283 | functional reference to an initialised ENGINE whose implementation should be |
273 | 284 | used. If no ENGINE should (or can) be used, it will return NULL and the caller | |
274 | When a new RSA key is being created, ie. in RSA_new_method(), a | 285 | will operate with a NULL ENGINE handle - this usually equates to using the |
275 | "get_default" call will be made to the ENGINE subsystem to process the RSA | 286 | conventional software implementation. In the latter case, OpenSSL will from |
276 | state table and return a functional reference to an initialised ENGINE | 287 | then on behave the way it used to before the ENGINE API existed. |
277 | whose RSA_METHOD should be used. If no ENGINE should (or can) be used, it | ||
278 | will return NULL and the RSA key will operate with a NULL ENGINE handle by | ||
279 | using the conventional RSA implementation in OpenSSL (and will from then on | ||
280 | behave the way it used to before the ENGINE API existed - for details see | ||
281 | L<RSA_new_method(3)|RSA_new_method(3)>). | ||
282 | 288 | ||
283 | Each state table has a flag to note whether it has processed this | 289 | Each state table has a flag to note whether it has processed this |
284 | "get_default" query since the table was last modified, because to process | 290 | "get_default" query since the table was last modified, because to process |
@@ -295,36 +301,9 @@ instead the only way for the state table to return a non-NULL ENGINE to the | |||
295 | "get_default" query will be if one is expressly set in the table. Eg. | 301 | "get_default" query will be if one is expressly set in the table. Eg. |
296 | ENGINE_set_default_RSA() does the same job as ENGINE_register_RSA() except | 302 | ENGINE_set_default_RSA() does the same job as ENGINE_register_RSA() except |
297 | that it also sets the state table's cached response for the "get_default" | 303 | that it also sets the state table's cached response for the "get_default" |
298 | query. | 304 | query. In the case of abstractions like EVP_CIPHER, where implementations are |
299 | 305 | indexed by 'nid', these flags and cached-responses are distinct for each 'nid' | |
300 | In the case of abstractions like EVP_CIPHER, where implementations are | 306 | value. |
301 | indexed by 'nid', these flags and cached-responses are distinct for each | ||
302 | 'nid' value. | ||
303 | |||
304 | It is worth illustrating the difference between "registration" of ENGINEs | ||
305 | into these per-algorithm state tables and using the alternative | ||
306 | "set_default" functions. The latter handles both "registration" and also | ||
307 | setting the cached "default" ENGINE in each relevant state table - so | ||
308 | registered ENGINEs will only have a chance to be initialised for use as a | ||
309 | default if a default ENGINE wasn't already set for the same state table. | ||
310 | Eg. if ENGINE X supports cipher nids {A,B} and RSA, ENGINE Y supports | ||
311 | ciphers {A} and DSA, and the following code is executed; | ||
312 | |||
313 | ENGINE_register_complete(X); | ||
314 | ENGINE_set_default(Y, ENGINE_METHOD_ALL); | ||
315 | e1 = ENGINE_get_default_RSA(); | ||
316 | e2 = ENGINE_get_cipher_engine(A); | ||
317 | e3 = ENGINE_get_cipher_engine(B); | ||
318 | e4 = ENGINE_get_default_DSA(); | ||
319 | e5 = ENGINE_get_cipher_engine(C); | ||
320 | |||
321 | The results would be as follows; | ||
322 | |||
323 | assert(e1 == X); | ||
324 | assert(e2 == Y); | ||
325 | assert(e3 == X); | ||
326 | assert(e4 == Y); | ||
327 | assert(e5 == NULL); | ||
328 | 307 | ||
329 | =head2 Application requirements | 308 | =head2 Application requirements |
330 | 309 | ||
@@ -360,7 +339,7 @@ mention an important API function; | |||
360 | 339 | ||
361 | If no ENGINE API functions are called at all in an application, then there | 340 | If no ENGINE API functions are called at all in an application, then there |
362 | are no inherent memory leaks to worry about from the ENGINE functionality, | 341 | are no inherent memory leaks to worry about from the ENGINE functionality, |
363 | however if any ENGINEs are "load"ed, even if they are never registered or | 342 | however if any ENGINEs are loaded, even if they are never registered or |
364 | used, it is necessary to use the ENGINE_cleanup() function to | 343 | used, it is necessary to use the ENGINE_cleanup() function to |
365 | correspondingly cleanup before program exit, if the caller wishes to avoid | 344 | correspondingly cleanup before program exit, if the caller wishes to avoid |
366 | memory leaks. This mechanism uses an internal callback registration table | 345 | memory leaks. This mechanism uses an internal callback registration table |
@@ -375,7 +354,7 @@ linker. | |||
375 | The fact that ENGINEs are made visible to OpenSSL (and thus are linked into | 354 | The fact that ENGINEs are made visible to OpenSSL (and thus are linked into |
376 | the program and loaded into memory at run-time) does not mean they are | 355 | the program and loaded into memory at run-time) does not mean they are |
377 | "registered" or called into use by OpenSSL automatically - that behaviour | 356 | "registered" or called into use by OpenSSL automatically - that behaviour |
378 | is something for the application to have control over. Some applications | 357 | is something for the application to control. Some applications |
379 | will want to allow the user to specify exactly which ENGINE they want used | 358 | will want to allow the user to specify exactly which ENGINE they want used |
380 | if any is to be used at all. Others may prefer to load all support and have | 359 | if any is to be used at all. Others may prefer to load all support and have |
381 | OpenSSL automatically use at run-time any ENGINE that is able to | 360 | OpenSSL automatically use at run-time any ENGINE that is able to |
@@ -433,7 +412,7 @@ it should be used. The following code illustrates how this can work; | |||
433 | That's all that's required. Eg. the next time OpenSSL tries to set up an | 412 | That's all that's required. Eg. the next time OpenSSL tries to set up an |
434 | RSA key, any bundled ENGINEs that implement RSA_METHOD will be passed to | 413 | RSA key, any bundled ENGINEs that implement RSA_METHOD will be passed to |
435 | ENGINE_init() and if any of those succeed, that ENGINE will be set as the | 414 | ENGINE_init() and if any of those succeed, that ENGINE will be set as the |
436 | default for use with RSA from then on. | 415 | default for RSA use from then on. |
437 | 416 | ||
438 | =head2 Advanced configuration support | 417 | =head2 Advanced configuration support |
439 | 418 | ||
@@ -441,7 +420,7 @@ There is a mechanism supported by the ENGINE framework that allows each | |||
441 | ENGINE implementation to define an arbitrary set of configuration | 420 | ENGINE implementation to define an arbitrary set of configuration |
442 | "commands" and expose them to OpenSSL and any applications based on | 421 | "commands" and expose them to OpenSSL and any applications based on |
443 | OpenSSL. This mechanism is entirely based on the use of name-value pairs | 422 | OpenSSL. This mechanism is entirely based on the use of name-value pairs |
444 | and and assumes ASCII input (no unicode or UTF for now!), so it is ideal if | 423 | and assumes ASCII input (no unicode or UTF for now!), so it is ideal if |
445 | applications want to provide a transparent way for users to provide | 424 | applications want to provide a transparent way for users to provide |
446 | arbitrary configuration "directives" directly to such ENGINEs. It is also | 425 | arbitrary configuration "directives" directly to such ENGINEs. It is also |
447 | possible for the application to dynamically interrogate the loaded ENGINE | 426 | possible for the application to dynamically interrogate the loaded ENGINE |
@@ -450,8 +429,8 @@ available "control commands", providing a more flexible configuration | |||
450 | scheme. However, if the user is expected to know which ENGINE device he/she | 429 | scheme. However, if the user is expected to know which ENGINE device he/she |
451 | is using (in the case of specialised hardware, this goes without saying) | 430 | is using (in the case of specialised hardware, this goes without saying) |
452 | then applications may not need to concern themselves with discovering the | 431 | then applications may not need to concern themselves with discovering the |
453 | supported control commands and simply prefer to allow settings to passed | 432 | supported control commands and simply prefer to pass settings into ENGINEs |
454 | into ENGINEs exactly as they are provided by the user. | 433 | exactly as they are provided by the user. |
455 | 434 | ||
456 | Before illustrating how control commands work, it is worth mentioning what | 435 | Before illustrating how control commands work, it is worth mentioning what |
457 | they are typically used for. Broadly speaking there are two uses for | 436 | they are typically used for. Broadly speaking there are two uses for |
@@ -459,13 +438,13 @@ control commands; the first is to provide the necessary details to the | |||
459 | implementation (which may know nothing at all specific to the host system) | 438 | implementation (which may know nothing at all specific to the host system) |
460 | so that it can be initialised for use. This could include the path to any | 439 | so that it can be initialised for use. This could include the path to any |
461 | driver or config files it needs to load, required network addresses, | 440 | driver or config files it needs to load, required network addresses, |
462 | smart-card identifiers, passwords to initialise password-protected devices, | 441 | smart-card identifiers, passwords to initialise protected devices, |
463 | logging information, etc etc. This class of commands typically needs to be | 442 | logging information, etc etc. This class of commands typically needs to be |
464 | passed to an ENGINE B<before> attempting to initialise it, ie. before | 443 | passed to an ENGINE B<before> attempting to initialise it, ie. before |
465 | calling ENGINE_init(). The other class of commands consist of settings or | 444 | calling ENGINE_init(). The other class of commands consist of settings or |
466 | operations that tweak certain behaviour or cause certain operations to take | 445 | operations that tweak certain behaviour or cause certain operations to take |
467 | place, and these commands may work either before or after ENGINE_init(), or | 446 | place, and these commands may work either before or after ENGINE_init(), or |
468 | in same cases both. ENGINE implementations should provide indications of | 447 | in some cases both. ENGINE implementations should provide indications of |
469 | this in the descriptions attached to builtin control commands and/or in | 448 | this in the descriptions attached to builtin control commands and/or in |
470 | external product documentation. | 449 | external product documentation. |
471 | 450 | ||
@@ -529,14 +508,14 @@ FALSE. | |||
529 | I<Discovering supported control commands> | 508 | I<Discovering supported control commands> |
530 | 509 | ||
531 | It is possible to discover at run-time the names, numerical-ids, descriptions | 510 | It is possible to discover at run-time the names, numerical-ids, descriptions |
532 | and input parameters of the control commands supported from a structural | 511 | and input parameters of the control commands supported by an ENGINE using a |
533 | reference to any ENGINE. It is first important to note that some control | 512 | structural reference. Note that some control commands are defined by OpenSSL |
534 | commands are defined by OpenSSL itself and it will intercept and handle these | 513 | itself and it will intercept and handle these control commands on behalf of the |
535 | control commands on behalf of the ENGINE, ie. the ENGINE's ctrl() handler is not | 514 | ENGINE, ie. the ENGINE's ctrl() handler is not used for the control command. |
536 | used for the control command. openssl/engine.h defines a symbol, | 515 | openssl/engine.h defines an index, ENGINE_CMD_BASE, that all control commands |
537 | ENGINE_CMD_BASE, that all control commands implemented by ENGINEs from. Any | 516 | implemented by ENGINEs should be numbered from. Any command value lower than |
538 | command value lower than this symbol is considered a "generic" command is | 517 | this symbol is considered a "generic" command is handled directly by the |
539 | handled directly by the OpenSSL core routines. | 518 | OpenSSL core routines. |
540 | 519 | ||
541 | It is using these "core" control commands that one can discover the the control | 520 | It is using these "core" control commands that one can discover the the control |
542 | commands implemented by a given ENGINE, specifically the commands; | 521 | commands implemented by a given ENGINE, specifically the commands; |
@@ -552,8 +531,8 @@ commands implemented by a given ENGINE, specifically the commands; | |||
552 | #define ENGINE_CTRL_GET_CMD_FLAGS 18 | 531 | #define ENGINE_CTRL_GET_CMD_FLAGS 18 |
553 | 532 | ||
554 | Whilst these commands are automatically processed by the OpenSSL framework code, | 533 | Whilst these commands are automatically processed by the OpenSSL framework code, |
555 | they use various properties exposed by each ENGINE by which to process these | 534 | they use various properties exposed by each ENGINE to process these |
556 | queries. An ENGINE has 3 properties it exposes that can affect this behaviour; | 535 | queries. An ENGINE has 3 properties it exposes that can affect how this behaves; |
557 | it can supply a ctrl() handler, it can specify ENGINE_FLAGS_MANUAL_CMD_CTRL in | 536 | it can supply a ctrl() handler, it can specify ENGINE_FLAGS_MANUAL_CMD_CTRL in |
558 | the ENGINE's flags, and it can expose an array of control command descriptions. | 537 | the ENGINE's flags, and it can expose an array of control command descriptions. |
559 | If an ENGINE specifies the ENGINE_FLAGS_MANUAL_CMD_CTRL flag, then it will | 538 | If an ENGINE specifies the ENGINE_FLAGS_MANUAL_CMD_CTRL flag, then it will |
@@ -608,14 +587,13 @@ extension). | |||
608 | The ENGINE API and internal architecture is currently being reviewed. Slated for | 587 | The ENGINE API and internal architecture is currently being reviewed. Slated for |
609 | possible release in 0.9.8 is support for transparent loading of "dynamic" | 588 | possible release in 0.9.8 is support for transparent loading of "dynamic" |
610 | ENGINEs (built as self-contained shared-libraries). This would allow ENGINE | 589 | ENGINEs (built as self-contained shared-libraries). This would allow ENGINE |
611 | implementations to be provided independantly of OpenSSL libraries and/or | 590 | implementations to be provided independently of OpenSSL libraries and/or |
612 | OpenSSL-based applications, and would also remove any requirement for | 591 | OpenSSL-based applications, and would also remove any requirement for |
613 | applications to explicitly use the "dynamic" ENGINE to bind to shared-library | 592 | applications to explicitly use the "dynamic" ENGINE to bind to shared-library |
614 | implementations. | 593 | implementations. |
615 | 594 | ||
616 | =head1 SEE ALSO | 595 | =head1 SEE ALSO |
617 | 596 | ||
618 | L<rsa(3)|rsa(3)>, L<dsa(3)|dsa(3)>, L<dh(3)|dh(3)>, L<rand(3)|rand(3)>, | 597 | L<rsa(3)|rsa(3)>, L<dsa(3)|dsa(3)>, L<dh(3)|dh(3)>, L<rand(3)|rand(3)> |
619 | L<RSA_new_method(3)|RSA_new_method(3)> | ||
620 | 598 | ||
621 | =cut | 599 | =cut |
diff --git a/src/lib/libcrypto/doc/x509.pod b/src/lib/libcrypto/doc/x509.pod new file mode 100644 index 0000000000..f9e58e0e41 --- /dev/null +++ b/src/lib/libcrypto/doc/x509.pod | |||
@@ -0,0 +1,64 @@ | |||
1 | =pod | ||
2 | |||
3 | =head1 NAME | ||
4 | |||
5 | x509 - X.509 certificate handling | ||
6 | |||
7 | =head1 SYNOPSIS | ||
8 | |||
9 | #include <openssl/x509.h> | ||
10 | |||
11 | =head1 DESCRIPTION | ||
12 | |||
13 | A X.509 certificate is a structured grouping of information about | ||
14 | an individual, a device, or anything one can imagine. A X.509 CRL | ||
15 | (certificate revocation list) is a tool to help determine if a | ||
16 | certificate is still valid. The exact definition of those can be | ||
17 | found in the X.509 document from ITU-T, or in RFC3280 from PKIX. | ||
18 | In OpenSSL, the type X509 is used to express such a certificate, and | ||
19 | the type X509_CRL is used to express a CRL. | ||
20 | |||
21 | A related structure is a certificate request, defined in PKCS#10 from | ||
22 | RSA Security, Inc, also reflected in RFC2896. In OpenSSL, the type | ||
23 | X509_REQ is used to express such a certificate request. | ||
24 | |||
25 | To handle some complex parts of a certificate, there are the types | ||
26 | X509_NAME (to express a certificate name), X509_ATTRIBUTE (to express | ||
27 | a certificate attributes), X509_EXTENSION (to express a certificate | ||
28 | extension) and a few more. | ||
29 | |||
30 | Finally, there's the supertype X509_INFO, which can contain a CRL, a | ||
31 | certificate and a corresponding private key. | ||
32 | |||
33 | B<X509_>I<...>, B<d2i_X509_>I<...> and B<i2d_X509_>I<...> handle X.509 | ||
34 | certificates, with some exceptions, shown below. | ||
35 | |||
36 | B<X509_CRL_>I<...>, B<d2i_X509_CRL_>I<...> and B<i2d_X509_CRL_>I<...> | ||
37 | handle X.509 CRLs. | ||
38 | |||
39 | B<X509_REQ_>I<...>, B<d2i_X509_REQ_>I<...> and B<i2d_X509_REQ_>I<...> | ||
40 | handle PKCS#10 certificate requests. | ||
41 | |||
42 | B<X509_NAME_>I<...> handle certificate names. | ||
43 | |||
44 | B<X509_ATTRIBUTE_>I<...> handle certificate attributes. | ||
45 | |||
46 | B<X509_EXTENSION_>I<...> handle certificate extensions. | ||
47 | |||
48 | =head1 SEE ALSO | ||
49 | |||
50 | L<X509_NAME_ENTRY_get_object(3)|X509_NAME_ENTRY_get_object(3)>, | ||
51 | L<X509_NAME_add_entry_by_txt(3)|X509_NAME_add_entry_by_txt(3)>, | ||
52 | L<X509_NAME_add_entry_by_NID(3)|X509_NAME_add_entry_by_NID(3)>, | ||
53 | L<X509_NAME_print_ex(3)|X509_NAME_print_ex(3)>, | ||
54 | L<X509_NAME_new(3)|X509_NAME_new(3)>, | ||
55 | L<d2i_X509(3)|d2i_X509(3)>, | ||
56 | L<d2i_X509_ALGOR(3)|d2i_X509_ALGOR(3)>, | ||
57 | L<d2i_X509_CRL(3)|d2i_X509_CRL(3)>, | ||
58 | L<d2i_X509_NAME(3)|d2i_X509_NAME(3)>, | ||
59 | L<d2i_X509_REQ(3)|d2i_X509_REQ(3)>, | ||
60 | L<d2i_X509_SIG(3)|d2i_X509_SIG(3)>, | ||
61 | L<crypto(3)|crypto(3)>, | ||
62 | L<x509v3(3)|x509v3(3)> | ||
63 | |||
64 | =cut | ||
diff --git a/src/lib/libcrypto/dsa/dsa_depr.c b/src/lib/libcrypto/dsa/dsa_depr.c new file mode 100644 index 0000000000..f2da680eb4 --- /dev/null +++ b/src/lib/libcrypto/dsa/dsa_depr.c | |||
@@ -0,0 +1,106 @@ | |||
1 | /* crypto/dsa/dsa_depr.c */ | ||
2 | /* ==================================================================== | ||
3 | * Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions | ||
7 | * are met: | ||
8 | * | ||
9 | * 1. Redistributions of source code must retain the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer. | ||
11 | * | ||
12 | * 2. Redistributions in binary form must reproduce the above copyright | ||
13 | * notice, this list of conditions and the following disclaimer in | ||
14 | * the documentation and/or other materials provided with the | ||
15 | * distribution. | ||
16 | * | ||
17 | * 3. All advertising materials mentioning features or use of this | ||
18 | * software must display the following acknowledgment: | ||
19 | * "This product includes software developed by the OpenSSL Project | ||
20 | * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" | ||
21 | * | ||
22 | * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to | ||
23 | * endorse or promote products derived from this software without | ||
24 | * prior written permission. For written permission, please contact | ||
25 | * openssl-core@openssl.org. | ||
26 | * | ||
27 | * 5. Products derived from this software may not be called "OpenSSL" | ||
28 | * nor may "OpenSSL" appear in their names without prior written | ||
29 | * permission of the OpenSSL Project. | ||
30 | * | ||
31 | * 6. Redistributions of any form whatsoever must retain the following | ||
32 | * acknowledgment: | ||
33 | * "This product includes software developed by the OpenSSL Project | ||
34 | * for use in the OpenSSL Toolkit (http://www.openssl.org/)" | ||
35 | * | ||
36 | * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY | ||
37 | * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
38 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | ||
39 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR | ||
40 | * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
41 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
42 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
43 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
44 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
45 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
46 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED | ||
47 | * OF THE POSSIBILITY OF SUCH DAMAGE. | ||
48 | * ==================================================================== | ||
49 | * | ||
50 | * This product includes cryptographic software written by Eric Young | ||
51 | * (eay@cryptsoft.com). This product includes software written by Tim | ||
52 | * Hudson (tjh@cryptsoft.com). | ||
53 | * | ||
54 | */ | ||
55 | |||
56 | /* This file contains deprecated function(s) that are now wrappers to the new | ||
57 | * version(s). */ | ||
58 | |||
59 | #undef GENUINE_DSA | ||
60 | |||
61 | #ifdef GENUINE_DSA | ||
62 | /* Parameter generation follows the original release of FIPS PUB 186, | ||
63 | * Appendix 2.2 (i.e. use SHA as defined in FIPS PUB 180) */ | ||
64 | #define HASH EVP_sha() | ||
65 | #else | ||
66 | /* Parameter generation follows the updated Appendix 2.2 for FIPS PUB 186, | ||
67 | * also Appendix 2.2 of FIPS PUB 186-1 (i.e. use SHA as defined in | ||
68 | * FIPS PUB 180-1) */ | ||
69 | #define HASH EVP_sha1() | ||
70 | #endif | ||
71 | |||
72 | static void *dummy=&dummy; | ||
73 | |||
74 | #ifndef OPENSSL_NO_SHA | ||
75 | |||
76 | #include <stdio.h> | ||
77 | #include <time.h> | ||
78 | #include "cryptlib.h" | ||
79 | #include <openssl/evp.h> | ||
80 | #include <openssl/bn.h> | ||
81 | #include <openssl/dsa.h> | ||
82 | #include <openssl/rand.h> | ||
83 | #include <openssl/sha.h> | ||
84 | |||
85 | #ifndef OPENSSL_NO_DEPRECATED | ||
86 | DSA *DSA_generate_parameters(int bits, | ||
87 | unsigned char *seed_in, int seed_len, | ||
88 | int *counter_ret, unsigned long *h_ret, | ||
89 | void (*callback)(int, int, void *), | ||
90 | void *cb_arg) | ||
91 | { | ||
92 | BN_GENCB cb; | ||
93 | DSA *ret; | ||
94 | |||
95 | if ((ret=DSA_new()) == NULL) return NULL; | ||
96 | |||
97 | BN_GENCB_set_old(&cb, callback, cb_arg); | ||
98 | |||
99 | if(DSA_generate_parameters_ex(ret, bits, seed_in, seed_len, | ||
100 | counter_ret, h_ret, &cb)) | ||
101 | return ret; | ||
102 | DSA_free(ret); | ||
103 | return NULL; | ||
104 | } | ||
105 | #endif | ||
106 | #endif | ||
diff --git a/src/lib/libcrypto/ec/ec2_mult.c b/src/lib/libcrypto/ec/ec2_mult.c new file mode 100644 index 0000000000..ff368fd7d7 --- /dev/null +++ b/src/lib/libcrypto/ec/ec2_mult.c | |||
@@ -0,0 +1,380 @@ | |||
1 | /* crypto/ec/ec2_mult.c */ | ||
2 | /* ==================================================================== | ||
3 | * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. | ||
4 | * | ||
5 | * The Elliptic Curve Public-Key Crypto Library (ECC Code) included | ||
6 | * herein is developed by SUN MICROSYSTEMS, INC., and is contributed | ||
7 | * to the OpenSSL project. | ||
8 | * | ||
9 | * The ECC Code is licensed pursuant to the OpenSSL open source | ||
10 | * license provided below. | ||
11 | * | ||
12 | * The software is originally written by Sheueling Chang Shantz and | ||
13 | * Douglas Stebila of Sun Microsystems Laboratories. | ||
14 | * | ||
15 | */ | ||
16 | /* ==================================================================== | ||
17 | * Copyright (c) 1998-2003 The OpenSSL Project. All rights reserved. | ||
18 | * | ||
19 | * Redistribution and use in source and binary forms, with or without | ||
20 | * modification, are permitted provided that the following conditions | ||
21 | * are met: | ||
22 | * | ||
23 | * 1. Redistributions of source code must retain the above copyright | ||
24 | * notice, this list of conditions and the following disclaimer. | ||
25 | * | ||
26 | * 2. Redistributions in binary form must reproduce the above copyright | ||
27 | * notice, this list of conditions and the following disclaimer in | ||
28 | * the documentation and/or other materials provided with the | ||
29 | * distribution. | ||
30 | * | ||
31 | * 3. All advertising materials mentioning features or use of this | ||
32 | * software must display the following acknowledgment: | ||
33 | * "This product includes software developed by the OpenSSL Project | ||
34 | * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" | ||
35 | * | ||
36 | * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to | ||
37 | * endorse or promote products derived from this software without | ||
38 | * prior written permission. For written permission, please contact | ||
39 | * openssl-core@openssl.org. | ||
40 | * | ||
41 | * 5. Products derived from this software may not be called "OpenSSL" | ||
42 | * nor may "OpenSSL" appear in their names without prior written | ||
43 | * permission of the OpenSSL Project. | ||
44 | * | ||
45 | * 6. Redistributions of any form whatsoever must retain the following | ||
46 | * acknowledgment: | ||
47 | * "This product includes software developed by the OpenSSL Project | ||
48 | * for use in the OpenSSL Toolkit (http://www.openssl.org/)" | ||
49 | * | ||
50 | * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY | ||
51 | * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
52 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | ||
53 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR | ||
54 | * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
55 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
56 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
57 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
58 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
59 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
60 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED | ||
61 | * OF THE POSSIBILITY OF SUCH DAMAGE. | ||
62 | * ==================================================================== | ||
63 | * | ||
64 | * This product includes cryptographic software written by Eric Young | ||
65 | * (eay@cryptsoft.com). This product includes software written by Tim | ||
66 | * Hudson (tjh@cryptsoft.com). | ||
67 | * | ||
68 | */ | ||
69 | |||
70 | #include <openssl/err.h> | ||
71 | |||
72 | #include "ec_lcl.h" | ||
73 | |||
74 | |||
75 | /* Compute the x-coordinate x/z for the point 2*(x/z) in Montgomery projective | ||
76 | * coordinates. | ||
77 | * Uses algorithm Mdouble in appendix of | ||
78 | * Lopez, J. and Dahab, R. "Fast multiplication on elliptic curves over | ||
79 | * GF(2^m) without precomputation". | ||
80 | * modified to not require precomputation of c=b^{2^{m-1}}. | ||
81 | */ | ||
82 | static int gf2m_Mdouble(const EC_GROUP *group, BIGNUM *x, BIGNUM *z, BN_CTX *ctx) | ||
83 | { | ||
84 | BIGNUM *t1; | ||
85 | int ret = 0; | ||
86 | |||
87 | /* Since Mdouble is static we can guarantee that ctx != NULL. */ | ||
88 | BN_CTX_start(ctx); | ||
89 | t1 = BN_CTX_get(ctx); | ||
90 | if (t1 == NULL) goto err; | ||
91 | |||
92 | if (!group->meth->field_sqr(group, x, x, ctx)) goto err; | ||
93 | if (!group->meth->field_sqr(group, t1, z, ctx)) goto err; | ||
94 | if (!group->meth->field_mul(group, z, x, t1, ctx)) goto err; | ||
95 | if (!group->meth->field_sqr(group, x, x, ctx)) goto err; | ||
96 | if (!group->meth->field_sqr(group, t1, t1, ctx)) goto err; | ||
97 | if (!group->meth->field_mul(group, t1, &group->b, t1, ctx)) goto err; | ||
98 | if (!BN_GF2m_add(x, x, t1)) goto err; | ||
99 | |||
100 | ret = 1; | ||
101 | |||
102 | err: | ||
103 | BN_CTX_end(ctx); | ||
104 | return ret; | ||
105 | } | ||
106 | |||
107 | /* Compute the x-coordinate x1/z1 for the point (x1/z1)+(x2/x2) in Montgomery | ||
108 | * projective coordinates. | ||
109 | * Uses algorithm Madd in appendix of | ||
110 | * Lopex, J. and Dahab, R. "Fast multiplication on elliptic curves over | ||
111 | * GF(2^m) without precomputation". | ||
112 | */ | ||
113 | static int gf2m_Madd(const EC_GROUP *group, const BIGNUM *x, BIGNUM *x1, BIGNUM *z1, | ||
114 | const BIGNUM *x2, const BIGNUM *z2, BN_CTX *ctx) | ||
115 | { | ||
116 | BIGNUM *t1, *t2; | ||
117 | int ret = 0; | ||
118 | |||
119 | /* Since Madd is static we can guarantee that ctx != NULL. */ | ||
120 | BN_CTX_start(ctx); | ||
121 | t1 = BN_CTX_get(ctx); | ||
122 | t2 = BN_CTX_get(ctx); | ||
123 | if (t2 == NULL) goto err; | ||
124 | |||
125 | if (!BN_copy(t1, x)) goto err; | ||
126 | if (!group->meth->field_mul(group, x1, x1, z2, ctx)) goto err; | ||
127 | if (!group->meth->field_mul(group, z1, z1, x2, ctx)) goto err; | ||
128 | if (!group->meth->field_mul(group, t2, x1, z1, ctx)) goto err; | ||
129 | if (!BN_GF2m_add(z1, z1, x1)) goto err; | ||
130 | if (!group->meth->field_sqr(group, z1, z1, ctx)) goto err; | ||
131 | if (!group->meth->field_mul(group, x1, z1, t1, ctx)) goto err; | ||
132 | if (!BN_GF2m_add(x1, x1, t2)) goto err; | ||
133 | |||
134 | ret = 1; | ||
135 | |||
136 | err: | ||
137 | BN_CTX_end(ctx); | ||
138 | return ret; | ||
139 | } | ||
140 | |||
141 | /* Compute the x, y affine coordinates from the point (x1, z1) (x2, z2) | ||
142 | * using Montgomery point multiplication algorithm Mxy() in appendix of | ||
143 | * Lopex, J. and Dahab, R. "Fast multiplication on elliptic curves over | ||
144 | * GF(2^m) without precomputation". | ||
145 | * Returns: | ||
146 | * 0 on error | ||
147 | * 1 if return value should be the point at infinity | ||
148 | * 2 otherwise | ||
149 | */ | ||
150 | static int gf2m_Mxy(const EC_GROUP *group, const BIGNUM *x, const BIGNUM *y, BIGNUM *x1, | ||
151 | BIGNUM *z1, BIGNUM *x2, BIGNUM *z2, BN_CTX *ctx) | ||
152 | { | ||
153 | BIGNUM *t3, *t4, *t5; | ||
154 | int ret = 0; | ||
155 | |||
156 | if (BN_is_zero(z1)) | ||
157 | { | ||
158 | BN_zero(x2); | ||
159 | BN_zero(z2); | ||
160 | return 1; | ||
161 | } | ||
162 | |||
163 | if (BN_is_zero(z2)) | ||
164 | { | ||
165 | if (!BN_copy(x2, x)) return 0; | ||
166 | if (!BN_GF2m_add(z2, x, y)) return 0; | ||
167 | return 2; | ||
168 | } | ||
169 | |||
170 | /* Since Mxy is static we can guarantee that ctx != NULL. */ | ||
171 | BN_CTX_start(ctx); | ||
172 | t3 = BN_CTX_get(ctx); | ||
173 | t4 = BN_CTX_get(ctx); | ||
174 | t5 = BN_CTX_get(ctx); | ||
175 | if (t5 == NULL) goto err; | ||
176 | |||
177 | if (!BN_one(t5)) goto err; | ||
178 | |||
179 | if (!group->meth->field_mul(group, t3, z1, z2, ctx)) goto err; | ||
180 | |||
181 | if (!group->meth->field_mul(group, z1, z1, x, ctx)) goto err; | ||
182 | if (!BN_GF2m_add(z1, z1, x1)) goto err; | ||
183 | if (!group->meth->field_mul(group, z2, z2, x, ctx)) goto err; | ||
184 | if (!group->meth->field_mul(group, x1, z2, x1, ctx)) goto err; | ||
185 | if (!BN_GF2m_add(z2, z2, x2)) goto err; | ||
186 | |||
187 | if (!group->meth->field_mul(group, z2, z2, z1, ctx)) goto err; | ||
188 | if (!group->meth->field_sqr(group, t4, x, ctx)) goto err; | ||
189 | if (!BN_GF2m_add(t4, t4, y)) goto err; | ||
190 | if (!group->meth->field_mul(group, t4, t4, t3, ctx)) goto err; | ||
191 | if (!BN_GF2m_add(t4, t4, z2)) goto err; | ||
192 | |||
193 | if (!group->meth->field_mul(group, t3, t3, x, ctx)) goto err; | ||
194 | if (!group->meth->field_div(group, t3, t5, t3, ctx)) goto err; | ||
195 | if (!group->meth->field_mul(group, t4, t3, t4, ctx)) goto err; | ||
196 | if (!group->meth->field_mul(group, x2, x1, t3, ctx)) goto err; | ||
197 | if (!BN_GF2m_add(z2, x2, x)) goto err; | ||
198 | |||
199 | if (!group->meth->field_mul(group, z2, z2, t4, ctx)) goto err; | ||
200 | if (!BN_GF2m_add(z2, z2, y)) goto err; | ||
201 | |||
202 | ret = 2; | ||
203 | |||
204 | err: | ||
205 | BN_CTX_end(ctx); | ||
206 | return ret; | ||
207 | } | ||
208 | |||
209 | /* Computes scalar*point and stores the result in r. | ||
210 | * point can not equal r. | ||
211 | * Uses algorithm 2P of | ||
212 | * Lopex, J. and Dahab, R. "Fast multiplication on elliptic curves over | ||
213 | * GF(2^m) without precomputation". | ||
214 | */ | ||
215 | static int ec_GF2m_montgomery_point_multiply(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, | ||
216 | const EC_POINT *point, BN_CTX *ctx) | ||
217 | { | ||
218 | BIGNUM *x1, *x2, *z1, *z2; | ||
219 | int ret = 0, i, j; | ||
220 | BN_ULONG mask; | ||
221 | |||
222 | if (r == point) | ||
223 | { | ||
224 | ECerr(EC_F_EC_GF2M_MONTGOMERY_POINT_MULTIPLY, EC_R_INVALID_ARGUMENT); | ||
225 | return 0; | ||
226 | } | ||
227 | |||
228 | /* if result should be point at infinity */ | ||
229 | if ((scalar == NULL) || BN_is_zero(scalar) || (point == NULL) || | ||
230 | EC_POINT_is_at_infinity(group, point)) | ||
231 | { | ||
232 | return EC_POINT_set_to_infinity(group, r); | ||
233 | } | ||
234 | |||
235 | /* only support affine coordinates */ | ||
236 | if (!point->Z_is_one) return 0; | ||
237 | |||
238 | /* Since point_multiply is static we can guarantee that ctx != NULL. */ | ||
239 | BN_CTX_start(ctx); | ||
240 | x1 = BN_CTX_get(ctx); | ||
241 | z1 = BN_CTX_get(ctx); | ||
242 | if (z1 == NULL) goto err; | ||
243 | |||
244 | x2 = &r->X; | ||
245 | z2 = &r->Y; | ||
246 | |||
247 | if (!BN_GF2m_mod_arr(x1, &point->X, group->poly)) goto err; /* x1 = x */ | ||
248 | if (!BN_one(z1)) goto err; /* z1 = 1 */ | ||
249 | if (!group->meth->field_sqr(group, z2, x1, ctx)) goto err; /* z2 = x1^2 = x^2 */ | ||
250 | if (!group->meth->field_sqr(group, x2, z2, ctx)) goto err; | ||
251 | if (!BN_GF2m_add(x2, x2, &group->b)) goto err; /* x2 = x^4 + b */ | ||
252 | |||
253 | /* find top most bit and go one past it */ | ||
254 | i = scalar->top - 1; j = BN_BITS2 - 1; | ||
255 | mask = BN_TBIT; | ||
256 | while (!(scalar->d[i] & mask)) { mask >>= 1; j--; } | ||
257 | mask >>= 1; j--; | ||
258 | /* if top most bit was at word break, go to next word */ | ||
259 | if (!mask) | ||
260 | { | ||
261 | i--; j = BN_BITS2 - 1; | ||
262 | mask = BN_TBIT; | ||
263 | } | ||
264 | |||
265 | for (; i >= 0; i--) | ||
266 | { | ||
267 | for (; j >= 0; j--) | ||
268 | { | ||
269 | if (scalar->d[i] & mask) | ||
270 | { | ||
271 | if (!gf2m_Madd(group, &point->X, x1, z1, x2, z2, ctx)) goto err; | ||
272 | if (!gf2m_Mdouble(group, x2, z2, ctx)) goto err; | ||
273 | } | ||
274 | else | ||
275 | { | ||
276 | if (!gf2m_Madd(group, &point->X, x2, z2, x1, z1, ctx)) goto err; | ||
277 | if (!gf2m_Mdouble(group, x1, z1, ctx)) goto err; | ||
278 | } | ||
279 | mask >>= 1; | ||
280 | } | ||
281 | j = BN_BITS2 - 1; | ||
282 | mask = BN_TBIT; | ||
283 | } | ||
284 | |||
285 | /* convert out of "projective" coordinates */ | ||
286 | i = gf2m_Mxy(group, &point->X, &point->Y, x1, z1, x2, z2, ctx); | ||
287 | if (i == 0) goto err; | ||
288 | else if (i == 1) | ||
289 | { | ||
290 | if (!EC_POINT_set_to_infinity(group, r)) goto err; | ||
291 | } | ||
292 | else | ||
293 | { | ||
294 | if (!BN_one(&r->Z)) goto err; | ||
295 | r->Z_is_one = 1; | ||
296 | } | ||
297 | |||
298 | /* GF(2^m) field elements should always have BIGNUM::neg = 0 */ | ||
299 | BN_set_negative(&r->X, 0); | ||
300 | BN_set_negative(&r->Y, 0); | ||
301 | |||
302 | ret = 1; | ||
303 | |||
304 | err: | ||
305 | BN_CTX_end(ctx); | ||
306 | return ret; | ||
307 | } | ||
308 | |||
309 | |||
310 | /* Computes the sum | ||
311 | * scalar*group->generator + scalars[0]*points[0] + ... + scalars[num-1]*points[num-1] | ||
312 | * gracefully ignoring NULL scalar values. | ||
313 | */ | ||
314 | int ec_GF2m_simple_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, | ||
315 | size_t num, const EC_POINT *points[], const BIGNUM *scalars[], BN_CTX *ctx) | ||
316 | { | ||
317 | BN_CTX *new_ctx = NULL; | ||
318 | int ret = 0; | ||
319 | size_t i; | ||
320 | EC_POINT *p=NULL; | ||
321 | |||
322 | if (ctx == NULL) | ||
323 | { | ||
324 | ctx = new_ctx = BN_CTX_new(); | ||
325 | if (ctx == NULL) | ||
326 | return 0; | ||
327 | } | ||
328 | |||
329 | /* This implementation is more efficient than the wNAF implementation for 2 | ||
330 | * or fewer points. Use the ec_wNAF_mul implementation for 3 or more points, | ||
331 | * or if we can perform a fast multiplication based on precomputation. | ||
332 | */ | ||
333 | if ((scalar && (num > 1)) || (num > 2) || (num == 0 && EC_GROUP_have_precompute_mult(group))) | ||
334 | { | ||
335 | ret = ec_wNAF_mul(group, r, scalar, num, points, scalars, ctx); | ||
336 | goto err; | ||
337 | } | ||
338 | |||
339 | if ((p = EC_POINT_new(group)) == NULL) goto err; | ||
340 | |||
341 | if (!EC_POINT_set_to_infinity(group, r)) goto err; | ||
342 | |||
343 | if (scalar) | ||
344 | { | ||
345 | if (!ec_GF2m_montgomery_point_multiply(group, p, scalar, group->generator, ctx)) goto err; | ||
346 | if (BN_is_negative(scalar)) | ||
347 | if (!group->meth->invert(group, p, ctx)) goto err; | ||
348 | if (!group->meth->add(group, r, r, p, ctx)) goto err; | ||
349 | } | ||
350 | |||
351 | for (i = 0; i < num; i++) | ||
352 | { | ||
353 | if (!ec_GF2m_montgomery_point_multiply(group, p, scalars[i], points[i], ctx)) goto err; | ||
354 | if (BN_is_negative(scalars[i])) | ||
355 | if (!group->meth->invert(group, p, ctx)) goto err; | ||
356 | if (!group->meth->add(group, r, r, p, ctx)) goto err; | ||
357 | } | ||
358 | |||
359 | ret = 1; | ||
360 | |||
361 | err: | ||
362 | if (p) EC_POINT_free(p); | ||
363 | if (new_ctx != NULL) | ||
364 | BN_CTX_free(new_ctx); | ||
365 | return ret; | ||
366 | } | ||
367 | |||
368 | |||
369 | /* Precomputation for point multiplication: fall back to wNAF methods | ||
370 | * because ec_GF2m_simple_mul() uses ec_wNAF_mul() if appropriate */ | ||
371 | |||
372 | int ec_GF2m_precompute_mult(EC_GROUP *group, BN_CTX *ctx) | ||
373 | { | ||
374 | return ec_wNAF_precompute_mult(group, ctx); | ||
375 | } | ||
376 | |||
377 | int ec_GF2m_have_precompute_mult(const EC_GROUP *group) | ||
378 | { | ||
379 | return ec_wNAF_have_precompute_mult(group); | ||
380 | } | ||
diff --git a/src/lib/libcrypto/ec/ec2_smpl.c b/src/lib/libcrypto/ec/ec2_smpl.c new file mode 100644 index 0000000000..5cd1eac41f --- /dev/null +++ b/src/lib/libcrypto/ec/ec2_smpl.c | |||
@@ -0,0 +1,971 @@ | |||
1 | /* crypto/ec/ec2_smpl.c */ | ||
2 | /* ==================================================================== | ||
3 | * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. | ||
4 | * | ||
5 | * The Elliptic Curve Public-Key Crypto Library (ECC Code) included | ||
6 | * herein is developed by SUN MICROSYSTEMS, INC., and is contributed | ||
7 | * to the OpenSSL project. | ||
8 | * | ||
9 | * The ECC Code is licensed pursuant to the OpenSSL open source | ||
10 | * license provided below. | ||
11 | * | ||
12 | * The software is originally written by Sheueling Chang Shantz and | ||
13 | * Douglas Stebila of Sun Microsystems Laboratories. | ||
14 | * | ||
15 | */ | ||
16 | /* ==================================================================== | ||
17 | * Copyright (c) 1998-2003 The OpenSSL Project. All rights reserved. | ||
18 | * | ||
19 | * Redistribution and use in source and binary forms, with or without | ||
20 | * modification, are permitted provided that the following conditions | ||
21 | * are met: | ||
22 | * | ||
23 | * 1. Redistributions of source code must retain the above copyright | ||
24 | * notice, this list of conditions and the following disclaimer. | ||
25 | * | ||
26 | * 2. Redistributions in binary form must reproduce the above copyright | ||
27 | * notice, this list of conditions and the following disclaimer in | ||
28 | * the documentation and/or other materials provided with the | ||
29 | * distribution. | ||
30 | * | ||
31 | * 3. All advertising materials mentioning features or use of this | ||
32 | * software must display the following acknowledgment: | ||
33 | * "This product includes software developed by the OpenSSL Project | ||
34 | * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" | ||
35 | * | ||
36 | * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to | ||
37 | * endorse or promote products derived from this software without | ||
38 | * prior written permission. For written permission, please contact | ||
39 | * openssl-core@openssl.org. | ||
40 | * | ||
41 | * 5. Products derived from this software may not be called "OpenSSL" | ||
42 | * nor may "OpenSSL" appear in their names without prior written | ||
43 | * permission of the OpenSSL Project. | ||
44 | * | ||
45 | * 6. Redistributions of any form whatsoever must retain the following | ||
46 | * acknowledgment: | ||
47 | * "This product includes software developed by the OpenSSL Project | ||
48 | * for use in the OpenSSL Toolkit (http://www.openssl.org/)" | ||
49 | * | ||
50 | * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY | ||
51 | * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
52 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | ||
53 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR | ||
54 | * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
55 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
56 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
57 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
58 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
59 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
60 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED | ||
61 | * OF THE POSSIBILITY OF SUCH DAMAGE. | ||
62 | * ==================================================================== | ||
63 | * | ||
64 | * This product includes cryptographic software written by Eric Young | ||
65 | * (eay@cryptsoft.com). This product includes software written by Tim | ||
66 | * Hudson (tjh@cryptsoft.com). | ||
67 | * | ||
68 | */ | ||
69 | |||
70 | #include <openssl/err.h> | ||
71 | |||
72 | #include "ec_lcl.h" | ||
73 | |||
74 | |||
75 | const EC_METHOD *EC_GF2m_simple_method(void) | ||
76 | { | ||
77 | static const EC_METHOD ret = { | ||
78 | NID_X9_62_characteristic_two_field, | ||
79 | ec_GF2m_simple_group_init, | ||
80 | ec_GF2m_simple_group_finish, | ||
81 | ec_GF2m_simple_group_clear_finish, | ||
82 | ec_GF2m_simple_group_copy, | ||
83 | ec_GF2m_simple_group_set_curve, | ||
84 | ec_GF2m_simple_group_get_curve, | ||
85 | ec_GF2m_simple_group_get_degree, | ||
86 | ec_GF2m_simple_group_check_discriminant, | ||
87 | ec_GF2m_simple_point_init, | ||
88 | ec_GF2m_simple_point_finish, | ||
89 | ec_GF2m_simple_point_clear_finish, | ||
90 | ec_GF2m_simple_point_copy, | ||
91 | ec_GF2m_simple_point_set_to_infinity, | ||
92 | 0 /* set_Jprojective_coordinates_GFp */, | ||
93 | 0 /* get_Jprojective_coordinates_GFp */, | ||
94 | ec_GF2m_simple_point_set_affine_coordinates, | ||
95 | ec_GF2m_simple_point_get_affine_coordinates, | ||
96 | ec_GF2m_simple_set_compressed_coordinates, | ||
97 | ec_GF2m_simple_point2oct, | ||
98 | ec_GF2m_simple_oct2point, | ||
99 | ec_GF2m_simple_add, | ||
100 | ec_GF2m_simple_dbl, | ||
101 | ec_GF2m_simple_invert, | ||
102 | ec_GF2m_simple_is_at_infinity, | ||
103 | ec_GF2m_simple_is_on_curve, | ||
104 | ec_GF2m_simple_cmp, | ||
105 | ec_GF2m_simple_make_affine, | ||
106 | ec_GF2m_simple_points_make_affine, | ||
107 | |||
108 | /* the following three method functions are defined in ec2_mult.c */ | ||
109 | ec_GF2m_simple_mul, | ||
110 | ec_GF2m_precompute_mult, | ||
111 | ec_GF2m_have_precompute_mult, | ||
112 | |||
113 | ec_GF2m_simple_field_mul, | ||
114 | ec_GF2m_simple_field_sqr, | ||
115 | ec_GF2m_simple_field_div, | ||
116 | 0 /* field_encode */, | ||
117 | 0 /* field_decode */, | ||
118 | 0 /* field_set_to_one */ }; | ||
119 | |||
120 | return &ret; | ||
121 | } | ||
122 | |||
123 | |||
124 | /* Initialize a GF(2^m)-based EC_GROUP structure. | ||
125 | * Note that all other members are handled by EC_GROUP_new. | ||
126 | */ | ||
127 | int ec_GF2m_simple_group_init(EC_GROUP *group) | ||
128 | { | ||
129 | BN_init(&group->field); | ||
130 | BN_init(&group->a); | ||
131 | BN_init(&group->b); | ||
132 | return 1; | ||
133 | } | ||
134 | |||
135 | |||
136 | /* Free a GF(2^m)-based EC_GROUP structure. | ||
137 | * Note that all other members are handled by EC_GROUP_free. | ||
138 | */ | ||
139 | void ec_GF2m_simple_group_finish(EC_GROUP *group) | ||
140 | { | ||
141 | BN_free(&group->field); | ||
142 | BN_free(&group->a); | ||
143 | BN_free(&group->b); | ||
144 | } | ||
145 | |||
146 | |||
147 | /* Clear and free a GF(2^m)-based EC_GROUP structure. | ||
148 | * Note that all other members are handled by EC_GROUP_clear_free. | ||
149 | */ | ||
150 | void ec_GF2m_simple_group_clear_finish(EC_GROUP *group) | ||
151 | { | ||
152 | BN_clear_free(&group->field); | ||
153 | BN_clear_free(&group->a); | ||
154 | BN_clear_free(&group->b); | ||
155 | group->poly[0] = 0; | ||
156 | group->poly[1] = 0; | ||
157 | group->poly[2] = 0; | ||
158 | group->poly[3] = 0; | ||
159 | group->poly[4] = 0; | ||
160 | } | ||
161 | |||
162 | |||
163 | /* Copy a GF(2^m)-based EC_GROUP structure. | ||
164 | * Note that all other members are handled by EC_GROUP_copy. | ||
165 | */ | ||
166 | int ec_GF2m_simple_group_copy(EC_GROUP *dest, const EC_GROUP *src) | ||
167 | { | ||
168 | int i; | ||
169 | if (!BN_copy(&dest->field, &src->field)) return 0; | ||
170 | if (!BN_copy(&dest->a, &src->a)) return 0; | ||
171 | if (!BN_copy(&dest->b, &src->b)) return 0; | ||
172 | dest->poly[0] = src->poly[0]; | ||
173 | dest->poly[1] = src->poly[1]; | ||
174 | dest->poly[2] = src->poly[2]; | ||
175 | dest->poly[3] = src->poly[3]; | ||
176 | dest->poly[4] = src->poly[4]; | ||
177 | bn_wexpand(&dest->a, (int)(dest->poly[0] + BN_BITS2 - 1) / BN_BITS2); | ||
178 | bn_wexpand(&dest->b, (int)(dest->poly[0] + BN_BITS2 - 1) / BN_BITS2); | ||
179 | for (i = dest->a.top; i < dest->a.dmax; i++) dest->a.d[i] = 0; | ||
180 | for (i = dest->b.top; i < dest->b.dmax; i++) dest->b.d[i] = 0; | ||
181 | return 1; | ||
182 | } | ||
183 | |||
184 | |||
185 | /* Set the curve parameters of an EC_GROUP structure. */ | ||
186 | int ec_GF2m_simple_group_set_curve(EC_GROUP *group, | ||
187 | const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx) | ||
188 | { | ||
189 | int ret = 0, i; | ||
190 | |||
191 | /* group->field */ | ||
192 | if (!BN_copy(&group->field, p)) goto err; | ||
193 | i = BN_GF2m_poly2arr(&group->field, group->poly, 5); | ||
194 | if ((i != 5) && (i != 3)) | ||
195 | { | ||
196 | ECerr(EC_F_EC_GF2M_SIMPLE_GROUP_SET_CURVE, EC_R_UNSUPPORTED_FIELD); | ||
197 | goto err; | ||
198 | } | ||
199 | |||
200 | /* group->a */ | ||
201 | if (!BN_GF2m_mod_arr(&group->a, a, group->poly)) goto err; | ||
202 | bn_wexpand(&group->a, (int)(group->poly[0] + BN_BITS2 - 1) / BN_BITS2); | ||
203 | for (i = group->a.top; i < group->a.dmax; i++) group->a.d[i] = 0; | ||
204 | |||
205 | /* group->b */ | ||
206 | if (!BN_GF2m_mod_arr(&group->b, b, group->poly)) goto err; | ||
207 | bn_wexpand(&group->b, (int)(group->poly[0] + BN_BITS2 - 1) / BN_BITS2); | ||
208 | for (i = group->b.top; i < group->b.dmax; i++) group->b.d[i] = 0; | ||
209 | |||
210 | ret = 1; | ||
211 | err: | ||
212 | return ret; | ||
213 | } | ||
214 | |||
215 | |||
216 | /* Get the curve parameters of an EC_GROUP structure. | ||
217 | * If p, a, or b are NULL then there values will not be set but the method will return with success. | ||
218 | */ | ||
219 | int ec_GF2m_simple_group_get_curve(const EC_GROUP *group, BIGNUM *p, BIGNUM *a, BIGNUM *b, BN_CTX *ctx) | ||
220 | { | ||
221 | int ret = 0; | ||
222 | |||
223 | if (p != NULL) | ||
224 | { | ||
225 | if (!BN_copy(p, &group->field)) return 0; | ||
226 | } | ||
227 | |||
228 | if (a != NULL) | ||
229 | { | ||
230 | if (!BN_copy(a, &group->a)) goto err; | ||
231 | } | ||
232 | |||
233 | if (b != NULL) | ||
234 | { | ||
235 | if (!BN_copy(b, &group->b)) goto err; | ||
236 | } | ||
237 | |||
238 | ret = 1; | ||
239 | |||
240 | err: | ||
241 | return ret; | ||
242 | } | ||
243 | |||
244 | |||
245 | /* Gets the degree of the field. For a curve over GF(2^m) this is the value m. */ | ||
246 | int ec_GF2m_simple_group_get_degree(const EC_GROUP *group) | ||
247 | { | ||
248 | return BN_num_bits(&group->field)-1; | ||
249 | } | ||
250 | |||
251 | |||
252 | /* Checks the discriminant of the curve. | ||
253 | * y^2 + x*y = x^3 + a*x^2 + b is an elliptic curve <=> b != 0 (mod p) | ||
254 | */ | ||
255 | int ec_GF2m_simple_group_check_discriminant(const EC_GROUP *group, BN_CTX *ctx) | ||
256 | { | ||
257 | int ret = 0; | ||
258 | BIGNUM *b; | ||
259 | BN_CTX *new_ctx = NULL; | ||
260 | |||
261 | if (ctx == NULL) | ||
262 | { | ||
263 | ctx = new_ctx = BN_CTX_new(); | ||
264 | if (ctx == NULL) | ||
265 | { | ||
266 | ECerr(EC_F_EC_GF2M_SIMPLE_GROUP_CHECK_DISCRIMINANT, ERR_R_MALLOC_FAILURE); | ||
267 | goto err; | ||
268 | } | ||
269 | } | ||
270 | BN_CTX_start(ctx); | ||
271 | b = BN_CTX_get(ctx); | ||
272 | if (b == NULL) goto err; | ||
273 | |||
274 | if (!BN_GF2m_mod_arr(b, &group->b, group->poly)) goto err; | ||
275 | |||
276 | /* check the discriminant: | ||
277 | * y^2 + x*y = x^3 + a*x^2 + b is an elliptic curve <=> b != 0 (mod p) | ||
278 | */ | ||
279 | if (BN_is_zero(b)) goto err; | ||
280 | |||
281 | ret = 1; | ||
282 | |||
283 | err: | ||
284 | if (ctx != NULL) | ||
285 | BN_CTX_end(ctx); | ||
286 | if (new_ctx != NULL) | ||
287 | BN_CTX_free(new_ctx); | ||
288 | return ret; | ||
289 | } | ||
290 | |||
291 | |||
292 | /* Initializes an EC_POINT. */ | ||
293 | int ec_GF2m_simple_point_init(EC_POINT *point) | ||
294 | { | ||
295 | BN_init(&point->X); | ||
296 | BN_init(&point->Y); | ||
297 | BN_init(&point->Z); | ||
298 | return 1; | ||
299 | } | ||
300 | |||
301 | |||
302 | /* Frees an EC_POINT. */ | ||
303 | void ec_GF2m_simple_point_finish(EC_POINT *point) | ||
304 | { | ||
305 | BN_free(&point->X); | ||
306 | BN_free(&point->Y); | ||
307 | BN_free(&point->Z); | ||
308 | } | ||
309 | |||
310 | |||
311 | /* Clears and frees an EC_POINT. */ | ||
312 | void ec_GF2m_simple_point_clear_finish(EC_POINT *point) | ||
313 | { | ||
314 | BN_clear_free(&point->X); | ||
315 | BN_clear_free(&point->Y); | ||
316 | BN_clear_free(&point->Z); | ||
317 | point->Z_is_one = 0; | ||
318 | } | ||
319 | |||
320 | |||
321 | /* Copy the contents of one EC_POINT into another. Assumes dest is initialized. */ | ||
322 | int ec_GF2m_simple_point_copy(EC_POINT *dest, const EC_POINT *src) | ||
323 | { | ||
324 | if (!BN_copy(&dest->X, &src->X)) return 0; | ||
325 | if (!BN_copy(&dest->Y, &src->Y)) return 0; | ||
326 | if (!BN_copy(&dest->Z, &src->Z)) return 0; | ||
327 | dest->Z_is_one = src->Z_is_one; | ||
328 | |||
329 | return 1; | ||
330 | } | ||
331 | |||
332 | |||
333 | /* Set an EC_POINT to the point at infinity. | ||
334 | * A point at infinity is represented by having Z=0. | ||
335 | */ | ||
336 | int ec_GF2m_simple_point_set_to_infinity(const EC_GROUP *group, EC_POINT *point) | ||
337 | { | ||
338 | point->Z_is_one = 0; | ||
339 | BN_zero(&point->Z); | ||
340 | return 1; | ||
341 | } | ||
342 | |||
343 | |||
344 | /* Set the coordinates of an EC_POINT using affine coordinates. | ||
345 | * Note that the simple implementation only uses affine coordinates. | ||
346 | */ | ||
347 | int ec_GF2m_simple_point_set_affine_coordinates(const EC_GROUP *group, EC_POINT *point, | ||
348 | const BIGNUM *x, const BIGNUM *y, BN_CTX *ctx) | ||
349 | { | ||
350 | int ret = 0; | ||
351 | if (x == NULL || y == NULL) | ||
352 | { | ||
353 | ECerr(EC_F_EC_GF2M_SIMPLE_POINT_SET_AFFINE_COORDINATES, ERR_R_PASSED_NULL_PARAMETER); | ||
354 | return 0; | ||
355 | } | ||
356 | |||
357 | if (!BN_copy(&point->X, x)) goto err; | ||
358 | BN_set_negative(&point->X, 0); | ||
359 | if (!BN_copy(&point->Y, y)) goto err; | ||
360 | BN_set_negative(&point->Y, 0); | ||
361 | if (!BN_copy(&point->Z, BN_value_one())) goto err; | ||
362 | BN_set_negative(&point->Z, 0); | ||
363 | point->Z_is_one = 1; | ||
364 | ret = 1; | ||
365 | |||
366 | err: | ||
367 | return ret; | ||
368 | } | ||
369 | |||
370 | |||
371 | /* Gets the affine coordinates of an EC_POINT. | ||
372 | * Note that the simple implementation only uses affine coordinates. | ||
373 | */ | ||
374 | int ec_GF2m_simple_point_get_affine_coordinates(const EC_GROUP *group, const EC_POINT *point, | ||
375 | BIGNUM *x, BIGNUM *y, BN_CTX *ctx) | ||
376 | { | ||
377 | int ret = 0; | ||
378 | |||
379 | if (EC_POINT_is_at_infinity(group, point)) | ||
380 | { | ||
381 | ECerr(EC_F_EC_GF2M_SIMPLE_POINT_GET_AFFINE_COORDINATES, EC_R_POINT_AT_INFINITY); | ||
382 | return 0; | ||
383 | } | ||
384 | |||
385 | if (BN_cmp(&point->Z, BN_value_one())) | ||
386 | { | ||
387 | ECerr(EC_F_EC_GF2M_SIMPLE_POINT_GET_AFFINE_COORDINATES, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); | ||
388 | return 0; | ||
389 | } | ||
390 | if (x != NULL) | ||
391 | { | ||
392 | if (!BN_copy(x, &point->X)) goto err; | ||
393 | BN_set_negative(x, 0); | ||
394 | } | ||
395 | if (y != NULL) | ||
396 | { | ||
397 | if (!BN_copy(y, &point->Y)) goto err; | ||
398 | BN_set_negative(y, 0); | ||
399 | } | ||
400 | ret = 1; | ||
401 | |||
402 | err: | ||
403 | return ret; | ||
404 | } | ||
405 | |||
406 | |||
407 | /* Include patented algorithms. */ | ||
408 | #include "ec2_smpt.c" | ||
409 | |||
410 | |||
411 | /* Converts an EC_POINT to an octet string. | ||
412 | * If buf is NULL, the encoded length will be returned. | ||
413 | * If the length len of buf is smaller than required an error will be returned. | ||
414 | * | ||
415 | * The point compression section of this function is patented by Certicom Corp. | ||
416 | * under US Patent 6,141,420. Point compression is disabled by default and can | ||
417 | * be enabled by defining the preprocessor macro OPENSSL_EC_BIN_PT_COMP at | ||
418 | * Configure-time. | ||
419 | */ | ||
420 | size_t ec_GF2m_simple_point2oct(const EC_GROUP *group, const EC_POINT *point, point_conversion_form_t form, | ||
421 | unsigned char *buf, size_t len, BN_CTX *ctx) | ||
422 | { | ||
423 | size_t ret; | ||
424 | BN_CTX *new_ctx = NULL; | ||
425 | int used_ctx = 0; | ||
426 | BIGNUM *x, *y, *yxi; | ||
427 | size_t field_len, i, skip; | ||
428 | |||
429 | #ifndef OPENSSL_EC_BIN_PT_COMP | ||
430 | if ((form == POINT_CONVERSION_COMPRESSED) || (form == POINT_CONVERSION_HYBRID)) | ||
431 | { | ||
432 | ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, ERR_R_DISABLED); | ||
433 | goto err; | ||
434 | } | ||
435 | #endif | ||
436 | |||
437 | if ((form != POINT_CONVERSION_COMPRESSED) | ||
438 | && (form != POINT_CONVERSION_UNCOMPRESSED) | ||
439 | && (form != POINT_CONVERSION_HYBRID)) | ||
440 | { | ||
441 | ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, EC_R_INVALID_FORM); | ||
442 | goto err; | ||
443 | } | ||
444 | |||
445 | if (EC_POINT_is_at_infinity(group, point)) | ||
446 | { | ||
447 | /* encodes to a single 0 octet */ | ||
448 | if (buf != NULL) | ||
449 | { | ||
450 | if (len < 1) | ||
451 | { | ||
452 | ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, EC_R_BUFFER_TOO_SMALL); | ||
453 | return 0; | ||
454 | } | ||
455 | buf[0] = 0; | ||
456 | } | ||
457 | return 1; | ||
458 | } | ||
459 | |||
460 | |||
461 | /* ret := required output buffer length */ | ||
462 | field_len = (EC_GROUP_get_degree(group) + 7) / 8; | ||
463 | ret = (form == POINT_CONVERSION_COMPRESSED) ? 1 + field_len : 1 + 2*field_len; | ||
464 | |||
465 | /* if 'buf' is NULL, just return required length */ | ||
466 | if (buf != NULL) | ||
467 | { | ||
468 | if (len < ret) | ||
469 | { | ||
470 | ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, EC_R_BUFFER_TOO_SMALL); | ||
471 | goto err; | ||
472 | } | ||
473 | |||
474 | if (ctx == NULL) | ||
475 | { | ||
476 | ctx = new_ctx = BN_CTX_new(); | ||
477 | if (ctx == NULL) | ||
478 | return 0; | ||
479 | } | ||
480 | |||
481 | BN_CTX_start(ctx); | ||
482 | used_ctx = 1; | ||
483 | x = BN_CTX_get(ctx); | ||
484 | y = BN_CTX_get(ctx); | ||
485 | yxi = BN_CTX_get(ctx); | ||
486 | if (yxi == NULL) goto err; | ||
487 | |||
488 | if (!EC_POINT_get_affine_coordinates_GF2m(group, point, x, y, ctx)) goto err; | ||
489 | |||
490 | buf[0] = form; | ||
491 | #ifdef OPENSSL_EC_BIN_PT_COMP | ||
492 | if ((form != POINT_CONVERSION_UNCOMPRESSED) && !BN_is_zero(x)) | ||
493 | { | ||
494 | if (!group->meth->field_div(group, yxi, y, x, ctx)) goto err; | ||
495 | if (BN_is_odd(yxi)) buf[0]++; | ||
496 | } | ||
497 | #endif | ||
498 | |||
499 | i = 1; | ||
500 | |||
501 | skip = field_len - BN_num_bytes(x); | ||
502 | if (skip > field_len) | ||
503 | { | ||
504 | ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR); | ||
505 | goto err; | ||
506 | } | ||
507 | while (skip > 0) | ||
508 | { | ||
509 | buf[i++] = 0; | ||
510 | skip--; | ||
511 | } | ||
512 | skip = BN_bn2bin(x, buf + i); | ||
513 | i += skip; | ||
514 | if (i != 1 + field_len) | ||
515 | { | ||
516 | ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR); | ||
517 | goto err; | ||
518 | } | ||
519 | |||
520 | if (form == POINT_CONVERSION_UNCOMPRESSED || form == POINT_CONVERSION_HYBRID) | ||
521 | { | ||
522 | skip = field_len - BN_num_bytes(y); | ||
523 | if (skip > field_len) | ||
524 | { | ||
525 | ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR); | ||
526 | goto err; | ||
527 | } | ||
528 | while (skip > 0) | ||
529 | { | ||
530 | buf[i++] = 0; | ||
531 | skip--; | ||
532 | } | ||
533 | skip = BN_bn2bin(y, buf + i); | ||
534 | i += skip; | ||
535 | } | ||
536 | |||
537 | if (i != ret) | ||
538 | { | ||
539 | ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR); | ||
540 | goto err; | ||
541 | } | ||
542 | } | ||
543 | |||
544 | if (used_ctx) | ||
545 | BN_CTX_end(ctx); | ||
546 | if (new_ctx != NULL) | ||
547 | BN_CTX_free(new_ctx); | ||
548 | return ret; | ||
549 | |||
550 | err: | ||
551 | if (used_ctx) | ||
552 | BN_CTX_end(ctx); | ||
553 | if (new_ctx != NULL) | ||
554 | BN_CTX_free(new_ctx); | ||
555 | return 0; | ||
556 | } | ||
557 | |||
558 | |||
559 | /* Converts an octet string representation to an EC_POINT. | ||
560 | * Note that the simple implementation only uses affine coordinates. | ||
561 | */ | ||
562 | int ec_GF2m_simple_oct2point(const EC_GROUP *group, EC_POINT *point, | ||
563 | const unsigned char *buf, size_t len, BN_CTX *ctx) | ||
564 | { | ||
565 | point_conversion_form_t form; | ||
566 | int y_bit; | ||
567 | BN_CTX *new_ctx = NULL; | ||
568 | BIGNUM *x, *y, *yxi; | ||
569 | size_t field_len, enc_len; | ||
570 | int ret = 0; | ||
571 | |||
572 | if (len == 0) | ||
573 | { | ||
574 | ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_BUFFER_TOO_SMALL); | ||
575 | return 0; | ||
576 | } | ||
577 | form = buf[0]; | ||
578 | y_bit = form & 1; | ||
579 | form = form & ~1U; | ||
580 | if ((form != 0) && (form != POINT_CONVERSION_COMPRESSED) | ||
581 | && (form != POINT_CONVERSION_UNCOMPRESSED) | ||
582 | && (form != POINT_CONVERSION_HYBRID)) | ||
583 | { | ||
584 | ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING); | ||
585 | return 0; | ||
586 | } | ||
587 | if ((form == 0 || form == POINT_CONVERSION_UNCOMPRESSED) && y_bit) | ||
588 | { | ||
589 | ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING); | ||
590 | return 0; | ||
591 | } | ||
592 | |||
593 | if (form == 0) | ||
594 | { | ||
595 | if (len != 1) | ||
596 | { | ||
597 | ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING); | ||
598 | return 0; | ||
599 | } | ||
600 | |||
601 | return EC_POINT_set_to_infinity(group, point); | ||
602 | } | ||
603 | |||
604 | field_len = (EC_GROUP_get_degree(group) + 7) / 8; | ||
605 | enc_len = (form == POINT_CONVERSION_COMPRESSED) ? 1 + field_len : 1 + 2*field_len; | ||
606 | |||
607 | if (len != enc_len) | ||
608 | { | ||
609 | ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING); | ||
610 | return 0; | ||
611 | } | ||
612 | |||
613 | if (ctx == NULL) | ||
614 | { | ||
615 | ctx = new_ctx = BN_CTX_new(); | ||
616 | if (ctx == NULL) | ||
617 | return 0; | ||
618 | } | ||
619 | |||
620 | BN_CTX_start(ctx); | ||
621 | x = BN_CTX_get(ctx); | ||
622 | y = BN_CTX_get(ctx); | ||
623 | yxi = BN_CTX_get(ctx); | ||
624 | if (yxi == NULL) goto err; | ||
625 | |||
626 | if (!BN_bin2bn(buf + 1, field_len, x)) goto err; | ||
627 | if (BN_ucmp(x, &group->field) >= 0) | ||
628 | { | ||
629 | ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING); | ||
630 | goto err; | ||
631 | } | ||
632 | |||
633 | if (form == POINT_CONVERSION_COMPRESSED) | ||
634 | { | ||
635 | if (!EC_POINT_set_compressed_coordinates_GF2m(group, point, x, y_bit, ctx)) goto err; | ||
636 | } | ||
637 | else | ||
638 | { | ||
639 | if (!BN_bin2bn(buf + 1 + field_len, field_len, y)) goto err; | ||
640 | if (BN_ucmp(y, &group->field) >= 0) | ||
641 | { | ||
642 | ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING); | ||
643 | goto err; | ||
644 | } | ||
645 | if (form == POINT_CONVERSION_HYBRID) | ||
646 | { | ||
647 | if (!group->meth->field_div(group, yxi, y, x, ctx)) goto err; | ||
648 | if (y_bit != BN_is_odd(yxi)) | ||
649 | { | ||
650 | ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING); | ||
651 | goto err; | ||
652 | } | ||
653 | } | ||
654 | |||
655 | if (!EC_POINT_set_affine_coordinates_GF2m(group, point, x, y, ctx)) goto err; | ||
656 | } | ||
657 | |||
658 | if (!EC_POINT_is_on_curve(group, point, ctx)) /* test required by X9.62 */ | ||
659 | { | ||
660 | ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_POINT_IS_NOT_ON_CURVE); | ||
661 | goto err; | ||
662 | } | ||
663 | |||
664 | ret = 1; | ||
665 | |||
666 | err: | ||
667 | BN_CTX_end(ctx); | ||
668 | if (new_ctx != NULL) | ||
669 | BN_CTX_free(new_ctx); | ||
670 | return ret; | ||
671 | } | ||
672 | |||
673 | |||
674 | /* Computes a + b and stores the result in r. r could be a or b, a could be b. | ||
675 | * Uses algorithm A.10.2 of IEEE P1363. | ||
676 | */ | ||
677 | int ec_GF2m_simple_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, const EC_POINT *b, BN_CTX *ctx) | ||
678 | { | ||
679 | BN_CTX *new_ctx = NULL; | ||
680 | BIGNUM *x0, *y0, *x1, *y1, *x2, *y2, *s, *t; | ||
681 | int ret = 0; | ||
682 | |||
683 | if (EC_POINT_is_at_infinity(group, a)) | ||
684 | { | ||
685 | if (!EC_POINT_copy(r, b)) return 0; | ||
686 | return 1; | ||
687 | } | ||
688 | |||
689 | if (EC_POINT_is_at_infinity(group, b)) | ||
690 | { | ||
691 | if (!EC_POINT_copy(r, a)) return 0; | ||
692 | return 1; | ||
693 | } | ||
694 | |||
695 | if (ctx == NULL) | ||
696 | { | ||
697 | ctx = new_ctx = BN_CTX_new(); | ||
698 | if (ctx == NULL) | ||
699 | return 0; | ||
700 | } | ||
701 | |||
702 | BN_CTX_start(ctx); | ||
703 | x0 = BN_CTX_get(ctx); | ||
704 | y0 = BN_CTX_get(ctx); | ||
705 | x1 = BN_CTX_get(ctx); | ||
706 | y1 = BN_CTX_get(ctx); | ||
707 | x2 = BN_CTX_get(ctx); | ||
708 | y2 = BN_CTX_get(ctx); | ||
709 | s = BN_CTX_get(ctx); | ||
710 | t = BN_CTX_get(ctx); | ||
711 | if (t == NULL) goto err; | ||
712 | |||
713 | if (a->Z_is_one) | ||
714 | { | ||
715 | if (!BN_copy(x0, &a->X)) goto err; | ||
716 | if (!BN_copy(y0, &a->Y)) goto err; | ||
717 | } | ||
718 | else | ||
719 | { | ||
720 | if (!EC_POINT_get_affine_coordinates_GF2m(group, a, x0, y0, ctx)) goto err; | ||
721 | } | ||
722 | if (b->Z_is_one) | ||
723 | { | ||
724 | if (!BN_copy(x1, &b->X)) goto err; | ||
725 | if (!BN_copy(y1, &b->Y)) goto err; | ||
726 | } | ||
727 | else | ||
728 | { | ||
729 | if (!EC_POINT_get_affine_coordinates_GF2m(group, b, x1, y1, ctx)) goto err; | ||
730 | } | ||
731 | |||
732 | |||
733 | if (BN_GF2m_cmp(x0, x1)) | ||
734 | { | ||
735 | if (!BN_GF2m_add(t, x0, x1)) goto err; | ||
736 | if (!BN_GF2m_add(s, y0, y1)) goto err; | ||
737 | if (!group->meth->field_div(group, s, s, t, ctx)) goto err; | ||
738 | if (!group->meth->field_sqr(group, x2, s, ctx)) goto err; | ||
739 | if (!BN_GF2m_add(x2, x2, &group->a)) goto err; | ||
740 | if (!BN_GF2m_add(x2, x2, s)) goto err; | ||
741 | if (!BN_GF2m_add(x2, x2, t)) goto err; | ||
742 | } | ||
743 | else | ||
744 | { | ||
745 | if (BN_GF2m_cmp(y0, y1) || BN_is_zero(x1)) | ||
746 | { | ||
747 | if (!EC_POINT_set_to_infinity(group, r)) goto err; | ||
748 | ret = 1; | ||
749 | goto err; | ||
750 | } | ||
751 | if (!group->meth->field_div(group, s, y1, x1, ctx)) goto err; | ||
752 | if (!BN_GF2m_add(s, s, x1)) goto err; | ||
753 | |||
754 | if (!group->meth->field_sqr(group, x2, s, ctx)) goto err; | ||
755 | if (!BN_GF2m_add(x2, x2, s)) goto err; | ||
756 | if (!BN_GF2m_add(x2, x2, &group->a)) goto err; | ||
757 | } | ||
758 | |||
759 | if (!BN_GF2m_add(y2, x1, x2)) goto err; | ||
760 | if (!group->meth->field_mul(group, y2, y2, s, ctx)) goto err; | ||
761 | if (!BN_GF2m_add(y2, y2, x2)) goto err; | ||
762 | if (!BN_GF2m_add(y2, y2, y1)) goto err; | ||
763 | |||
764 | if (!EC_POINT_set_affine_coordinates_GF2m(group, r, x2, y2, ctx)) goto err; | ||
765 | |||
766 | ret = 1; | ||
767 | |||
768 | err: | ||
769 | BN_CTX_end(ctx); | ||
770 | if (new_ctx != NULL) | ||
771 | BN_CTX_free(new_ctx); | ||
772 | return ret; | ||
773 | } | ||
774 | |||
775 | |||
776 | /* Computes 2 * a and stores the result in r. r could be a. | ||
777 | * Uses algorithm A.10.2 of IEEE P1363. | ||
778 | */ | ||
779 | int ec_GF2m_simple_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, BN_CTX *ctx) | ||
780 | { | ||
781 | return ec_GF2m_simple_add(group, r, a, a, ctx); | ||
782 | } | ||
783 | |||
784 | |||
785 | int ec_GF2m_simple_invert(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx) | ||
786 | { | ||
787 | if (EC_POINT_is_at_infinity(group, point) || BN_is_zero(&point->Y)) | ||
788 | /* point is its own inverse */ | ||
789 | return 1; | ||
790 | |||
791 | if (!EC_POINT_make_affine(group, point, ctx)) return 0; | ||
792 | return BN_GF2m_add(&point->Y, &point->X, &point->Y); | ||
793 | } | ||
794 | |||
795 | |||
796 | /* Indicates whether the given point is the point at infinity. */ | ||
797 | int ec_GF2m_simple_is_at_infinity(const EC_GROUP *group, const EC_POINT *point) | ||
798 | { | ||
799 | return BN_is_zero(&point->Z); | ||
800 | } | ||
801 | |||
802 | |||
803 | /* Determines whether the given EC_POINT is an actual point on the curve defined | ||
804 | * in the EC_GROUP. A point is valid if it satisfies the Weierstrass equation: | ||
805 | * y^2 + x*y = x^3 + a*x^2 + b. | ||
806 | */ | ||
807 | int ec_GF2m_simple_is_on_curve(const EC_GROUP *group, const EC_POINT *point, BN_CTX *ctx) | ||
808 | { | ||
809 | int ret = -1; | ||
810 | BN_CTX *new_ctx = NULL; | ||
811 | BIGNUM *lh, *y2; | ||
812 | int (*field_mul)(const EC_GROUP *, BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *); | ||
813 | int (*field_sqr)(const EC_GROUP *, BIGNUM *, const BIGNUM *, BN_CTX *); | ||
814 | |||
815 | if (EC_POINT_is_at_infinity(group, point)) | ||
816 | return 1; | ||
817 | |||
818 | field_mul = group->meth->field_mul; | ||
819 | field_sqr = group->meth->field_sqr; | ||
820 | |||
821 | /* only support affine coordinates */ | ||
822 | if (!point->Z_is_one) goto err; | ||
823 | |||
824 | if (ctx == NULL) | ||
825 | { | ||
826 | ctx = new_ctx = BN_CTX_new(); | ||
827 | if (ctx == NULL) | ||
828 | return -1; | ||
829 | } | ||
830 | |||
831 | BN_CTX_start(ctx); | ||
832 | y2 = BN_CTX_get(ctx); | ||
833 | lh = BN_CTX_get(ctx); | ||
834 | if (lh == NULL) goto err; | ||
835 | |||
836 | /* We have a curve defined by a Weierstrass equation | ||
837 | * y^2 + x*y = x^3 + a*x^2 + b. | ||
838 | * <=> x^3 + a*x^2 + x*y + b + y^2 = 0 | ||
839 | * <=> ((x + a) * x + y ) * x + b + y^2 = 0 | ||
840 | */ | ||
841 | if (!BN_GF2m_add(lh, &point->X, &group->a)) goto err; | ||
842 | if (!field_mul(group, lh, lh, &point->X, ctx)) goto err; | ||
843 | if (!BN_GF2m_add(lh, lh, &point->Y)) goto err; | ||
844 | if (!field_mul(group, lh, lh, &point->X, ctx)) goto err; | ||
845 | if (!BN_GF2m_add(lh, lh, &group->b)) goto err; | ||
846 | if (!field_sqr(group, y2, &point->Y, ctx)) goto err; | ||
847 | if (!BN_GF2m_add(lh, lh, y2)) goto err; | ||
848 | ret = BN_is_zero(lh); | ||
849 | err: | ||
850 | if (ctx) BN_CTX_end(ctx); | ||
851 | if (new_ctx) BN_CTX_free(new_ctx); | ||
852 | return ret; | ||
853 | } | ||
854 | |||
855 | |||
856 | /* Indicates whether two points are equal. | ||
857 | * Return values: | ||
858 | * -1 error | ||
859 | * 0 equal (in affine coordinates) | ||
860 | * 1 not equal | ||
861 | */ | ||
862 | int ec_GF2m_simple_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b, BN_CTX *ctx) | ||
863 | { | ||
864 | BIGNUM *aX, *aY, *bX, *bY; | ||
865 | BN_CTX *new_ctx = NULL; | ||
866 | int ret = -1; | ||
867 | |||
868 | if (EC_POINT_is_at_infinity(group, a)) | ||
869 | { | ||
870 | return EC_POINT_is_at_infinity(group, b) ? 0 : 1; | ||
871 | } | ||
872 | |||
873 | if (a->Z_is_one && b->Z_is_one) | ||
874 | { | ||
875 | return ((BN_cmp(&a->X, &b->X) == 0) && BN_cmp(&a->Y, &b->Y) == 0) ? 0 : 1; | ||
876 | } | ||
877 | |||
878 | if (ctx == NULL) | ||
879 | { | ||
880 | ctx = new_ctx = BN_CTX_new(); | ||
881 | if (ctx == NULL) | ||
882 | return -1; | ||
883 | } | ||
884 | |||
885 | BN_CTX_start(ctx); | ||
886 | aX = BN_CTX_get(ctx); | ||
887 | aY = BN_CTX_get(ctx); | ||
888 | bX = BN_CTX_get(ctx); | ||
889 | bY = BN_CTX_get(ctx); | ||
890 | if (bY == NULL) goto err; | ||
891 | |||
892 | if (!EC_POINT_get_affine_coordinates_GF2m(group, a, aX, aY, ctx)) goto err; | ||
893 | if (!EC_POINT_get_affine_coordinates_GF2m(group, b, bX, bY, ctx)) goto err; | ||
894 | ret = ((BN_cmp(aX, bX) == 0) && BN_cmp(aY, bY) == 0) ? 0 : 1; | ||
895 | |||
896 | err: | ||
897 | if (ctx) BN_CTX_end(ctx); | ||
898 | if (new_ctx) BN_CTX_free(new_ctx); | ||
899 | return ret; | ||
900 | } | ||
901 | |||
902 | |||
903 | /* Forces the given EC_POINT to internally use affine coordinates. */ | ||
904 | int ec_GF2m_simple_make_affine(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx) | ||
905 | { | ||
906 | BN_CTX *new_ctx = NULL; | ||
907 | BIGNUM *x, *y; | ||
908 | int ret = 0; | ||
909 | |||
910 | if (point->Z_is_one || EC_POINT_is_at_infinity(group, point)) | ||
911 | return 1; | ||
912 | |||
913 | if (ctx == NULL) | ||
914 | { | ||
915 | ctx = new_ctx = BN_CTX_new(); | ||
916 | if (ctx == NULL) | ||
917 | return 0; | ||
918 | } | ||
919 | |||
920 | BN_CTX_start(ctx); | ||
921 | x = BN_CTX_get(ctx); | ||
922 | y = BN_CTX_get(ctx); | ||
923 | if (y == NULL) goto err; | ||
924 | |||
925 | if (!EC_POINT_get_affine_coordinates_GF2m(group, point, x, y, ctx)) goto err; | ||
926 | if (!BN_copy(&point->X, x)) goto err; | ||
927 | if (!BN_copy(&point->Y, y)) goto err; | ||
928 | if (!BN_one(&point->Z)) goto err; | ||
929 | |||
930 | ret = 1; | ||
931 | |||
932 | err: | ||
933 | if (ctx) BN_CTX_end(ctx); | ||
934 | if (new_ctx) BN_CTX_free(new_ctx); | ||
935 | return ret; | ||
936 | } | ||
937 | |||
938 | |||
939 | /* Forces each of the EC_POINTs in the given array to use affine coordinates. */ | ||
940 | int ec_GF2m_simple_points_make_affine(const EC_GROUP *group, size_t num, EC_POINT *points[], BN_CTX *ctx) | ||
941 | { | ||
942 | size_t i; | ||
943 | |||
944 | for (i = 0; i < num; i++) | ||
945 | { | ||
946 | if (!group->meth->make_affine(group, points[i], ctx)) return 0; | ||
947 | } | ||
948 | |||
949 | return 1; | ||
950 | } | ||
951 | |||
952 | |||
953 | /* Wrapper to simple binary polynomial field multiplication implementation. */ | ||
954 | int ec_GF2m_simple_field_mul(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx) | ||
955 | { | ||
956 | return BN_GF2m_mod_mul_arr(r, a, b, group->poly, ctx); | ||
957 | } | ||
958 | |||
959 | |||
960 | /* Wrapper to simple binary polynomial field squaring implementation. */ | ||
961 | int ec_GF2m_simple_field_sqr(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, BN_CTX *ctx) | ||
962 | { | ||
963 | return BN_GF2m_mod_sqr_arr(r, a, group->poly, ctx); | ||
964 | } | ||
965 | |||
966 | |||
967 | /* Wrapper to simple binary polynomial field division implementation. */ | ||
968 | int ec_GF2m_simple_field_div(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx) | ||
969 | { | ||
970 | return BN_GF2m_mod_div(r, a, b, &group->field, ctx); | ||
971 | } | ||
diff --git a/src/lib/libcrypto/ec/ec_asn1.c b/src/lib/libcrypto/ec/ec_asn1.c new file mode 100644 index 0000000000..ae55539859 --- /dev/null +++ b/src/lib/libcrypto/ec/ec_asn1.c | |||
@@ -0,0 +1,1429 @@ | |||
1 | /* crypto/ec/ec_asn1.c */ | ||
2 | /* | ||
3 | * Written by Nils Larsch for the OpenSSL project. | ||
4 | */ | ||
5 | /* ==================================================================== | ||
6 | * Copyright (c) 2000-2003 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 | * This product includes cryptographic software written by Eric Young | ||
54 | * (eay@cryptsoft.com). This product includes software written by Tim | ||
55 | * Hudson (tjh@cryptsoft.com). | ||
56 | * | ||
57 | */ | ||
58 | |||
59 | #include <string.h> | ||
60 | #include "ec_lcl.h" | ||
61 | #include <openssl/err.h> | ||
62 | #include <openssl/asn1t.h> | ||
63 | #include <openssl/objects.h> | ||
64 | |||
65 | |||
66 | int EC_GROUP_get_basis_type(const EC_GROUP *group) | ||
67 | { | ||
68 | int i=0; | ||
69 | |||
70 | if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) != | ||
71 | NID_X9_62_characteristic_two_field) | ||
72 | /* everything else is currently not supported */ | ||
73 | return 0; | ||
74 | |||
75 | while (group->poly[i] != 0) | ||
76 | i++; | ||
77 | |||
78 | if (i == 4) | ||
79 | return NID_X9_62_ppBasis; | ||
80 | else if (i == 2) | ||
81 | return NID_X9_62_tpBasis; | ||
82 | else | ||
83 | /* everything else is currently not supported */ | ||
84 | return 0; | ||
85 | } | ||
86 | |||
87 | int EC_GROUP_get_trinomial_basis(const EC_GROUP *group, unsigned int *k) | ||
88 | { | ||
89 | if (group == NULL) | ||
90 | return 0; | ||
91 | |||
92 | if (EC_GROUP_method_of(group)->group_set_curve != ec_GF2m_simple_group_set_curve | ||
93 | || !((group->poly[0] != 0) && (group->poly[1] != 0) && (group->poly[2] == 0))) | ||
94 | { | ||
95 | ECerr(EC_F_EC_GROUP_GET_TRINOMIAL_BASIS, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); | ||
96 | return 0; | ||
97 | } | ||
98 | |||
99 | if (k) | ||
100 | *k = group->poly[1]; | ||
101 | |||
102 | return 1; | ||
103 | } | ||
104 | |||
105 | int EC_GROUP_get_pentanomial_basis(const EC_GROUP *group, unsigned int *k1, | ||
106 | unsigned int *k2, unsigned int *k3) | ||
107 | { | ||
108 | if (group == NULL) | ||
109 | return 0; | ||
110 | |||
111 | if (EC_GROUP_method_of(group)->group_set_curve != ec_GF2m_simple_group_set_curve | ||
112 | || !((group->poly[0] != 0) && (group->poly[1] != 0) && (group->poly[2] != 0) && (group->poly[3] != 0) && (group->poly[4] == 0))) | ||
113 | { | ||
114 | ECerr(EC_F_EC_GROUP_GET_PENTANOMIAL_BASIS, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); | ||
115 | return 0; | ||
116 | } | ||
117 | |||
118 | if (k1) | ||
119 | *k1 = group->poly[3]; | ||
120 | if (k2) | ||
121 | *k2 = group->poly[2]; | ||
122 | if (k3) | ||
123 | *k3 = group->poly[1]; | ||
124 | |||
125 | return 1; | ||
126 | } | ||
127 | |||
128 | |||
129 | |||
130 | /* some structures needed for the asn1 encoding */ | ||
131 | typedef struct x9_62_pentanomial_st { | ||
132 | long k1; | ||
133 | long k2; | ||
134 | long k3; | ||
135 | } X9_62_PENTANOMIAL; | ||
136 | |||
137 | typedef struct x9_62_characteristic_two_st { | ||
138 | long m; | ||
139 | ASN1_OBJECT *type; | ||
140 | union { | ||
141 | char *ptr; | ||
142 | /* NID_X9_62_onBasis */ | ||
143 | ASN1_NULL *onBasis; | ||
144 | /* NID_X9_62_tpBasis */ | ||
145 | ASN1_INTEGER *tpBasis; | ||
146 | /* NID_X9_62_ppBasis */ | ||
147 | X9_62_PENTANOMIAL *ppBasis; | ||
148 | /* anything else */ | ||
149 | ASN1_TYPE *other; | ||
150 | } p; | ||
151 | } X9_62_CHARACTERISTIC_TWO; | ||
152 | |||
153 | typedef struct x9_62_fieldid_st { | ||
154 | ASN1_OBJECT *fieldType; | ||
155 | union { | ||
156 | char *ptr; | ||
157 | /* NID_X9_62_prime_field */ | ||
158 | ASN1_INTEGER *prime; | ||
159 | /* NID_X9_62_characteristic_two_field */ | ||
160 | X9_62_CHARACTERISTIC_TWO *char_two; | ||
161 | /* anything else */ | ||
162 | ASN1_TYPE *other; | ||
163 | } p; | ||
164 | } X9_62_FIELDID; | ||
165 | |||
166 | typedef struct x9_62_curve_st { | ||
167 | ASN1_OCTET_STRING *a; | ||
168 | ASN1_OCTET_STRING *b; | ||
169 | ASN1_BIT_STRING *seed; | ||
170 | } X9_62_CURVE; | ||
171 | |||
172 | typedef struct ec_parameters_st { | ||
173 | long version; | ||
174 | X9_62_FIELDID *fieldID; | ||
175 | X9_62_CURVE *curve; | ||
176 | ASN1_OCTET_STRING *base; | ||
177 | ASN1_INTEGER *order; | ||
178 | ASN1_INTEGER *cofactor; | ||
179 | } ECPARAMETERS; | ||
180 | |||
181 | struct ecpk_parameters_st { | ||
182 | int type; | ||
183 | union { | ||
184 | ASN1_OBJECT *named_curve; | ||
185 | ECPARAMETERS *parameters; | ||
186 | ASN1_NULL *implicitlyCA; | ||
187 | } value; | ||
188 | }/* ECPKPARAMETERS */; | ||
189 | |||
190 | /* SEC1 ECPrivateKey */ | ||
191 | typedef struct ec_privatekey_st { | ||
192 | long version; | ||
193 | ASN1_OCTET_STRING *privateKey; | ||
194 | ECPKPARAMETERS *parameters; | ||
195 | ASN1_BIT_STRING *publicKey; | ||
196 | } EC_PRIVATEKEY; | ||
197 | |||
198 | /* the OpenSSL ASN.1 definitions */ | ||
199 | ASN1_SEQUENCE(X9_62_PENTANOMIAL) = { | ||
200 | ASN1_SIMPLE(X9_62_PENTANOMIAL, k1, LONG), | ||
201 | ASN1_SIMPLE(X9_62_PENTANOMIAL, k2, LONG), | ||
202 | ASN1_SIMPLE(X9_62_PENTANOMIAL, k3, LONG) | ||
203 | } ASN1_SEQUENCE_END(X9_62_PENTANOMIAL) | ||
204 | |||
205 | DECLARE_ASN1_ALLOC_FUNCTIONS(X9_62_PENTANOMIAL) | ||
206 | IMPLEMENT_ASN1_ALLOC_FUNCTIONS(X9_62_PENTANOMIAL) | ||
207 | |||
208 | ASN1_ADB_TEMPLATE(char_two_def) = ASN1_SIMPLE(X9_62_CHARACTERISTIC_TWO, p.other, ASN1_ANY); | ||
209 | |||
210 | ASN1_ADB(X9_62_CHARACTERISTIC_TWO) = { | ||
211 | ADB_ENTRY(NID_X9_62_onBasis, ASN1_SIMPLE(X9_62_CHARACTERISTIC_TWO, p.onBasis, ASN1_NULL)), | ||
212 | ADB_ENTRY(NID_X9_62_tpBasis, ASN1_SIMPLE(X9_62_CHARACTERISTIC_TWO, p.tpBasis, ASN1_INTEGER)), | ||
213 | ADB_ENTRY(NID_X9_62_ppBasis, ASN1_SIMPLE(X9_62_CHARACTERISTIC_TWO, p.ppBasis, X9_62_PENTANOMIAL)) | ||
214 | } ASN1_ADB_END(X9_62_CHARACTERISTIC_TWO, 0, type, 0, &char_two_def_tt, NULL); | ||
215 | |||
216 | ASN1_SEQUENCE(X9_62_CHARACTERISTIC_TWO) = { | ||
217 | ASN1_SIMPLE(X9_62_CHARACTERISTIC_TWO, m, LONG), | ||
218 | ASN1_SIMPLE(X9_62_CHARACTERISTIC_TWO, type, ASN1_OBJECT), | ||
219 | ASN1_ADB_OBJECT(X9_62_CHARACTERISTIC_TWO) | ||
220 | } ASN1_SEQUENCE_END(X9_62_CHARACTERISTIC_TWO) | ||
221 | |||
222 | DECLARE_ASN1_ALLOC_FUNCTIONS(X9_62_CHARACTERISTIC_TWO) | ||
223 | IMPLEMENT_ASN1_ALLOC_FUNCTIONS(X9_62_CHARACTERISTIC_TWO) | ||
224 | |||
225 | ASN1_ADB_TEMPLATE(fieldID_def) = ASN1_SIMPLE(X9_62_FIELDID, p.other, ASN1_ANY); | ||
226 | |||
227 | ASN1_ADB(X9_62_FIELDID) = { | ||
228 | ADB_ENTRY(NID_X9_62_prime_field, ASN1_SIMPLE(X9_62_FIELDID, p.prime, ASN1_INTEGER)), | ||
229 | ADB_ENTRY(NID_X9_62_characteristic_two_field, ASN1_SIMPLE(X9_62_FIELDID, p.char_two, X9_62_CHARACTERISTIC_TWO)) | ||
230 | } ASN1_ADB_END(X9_62_FIELDID, 0, fieldType, 0, &fieldID_def_tt, NULL); | ||
231 | |||
232 | ASN1_SEQUENCE(X9_62_FIELDID) = { | ||
233 | ASN1_SIMPLE(X9_62_FIELDID, fieldType, ASN1_OBJECT), | ||
234 | ASN1_ADB_OBJECT(X9_62_FIELDID) | ||
235 | } ASN1_SEQUENCE_END(X9_62_FIELDID) | ||
236 | |||
237 | ASN1_SEQUENCE(X9_62_CURVE) = { | ||
238 | ASN1_SIMPLE(X9_62_CURVE, a, ASN1_OCTET_STRING), | ||
239 | ASN1_SIMPLE(X9_62_CURVE, b, ASN1_OCTET_STRING), | ||
240 | ASN1_OPT(X9_62_CURVE, seed, ASN1_BIT_STRING) | ||
241 | } ASN1_SEQUENCE_END(X9_62_CURVE) | ||
242 | |||
243 | ASN1_SEQUENCE(ECPARAMETERS) = { | ||
244 | ASN1_SIMPLE(ECPARAMETERS, version, LONG), | ||
245 | ASN1_SIMPLE(ECPARAMETERS, fieldID, X9_62_FIELDID), | ||
246 | ASN1_SIMPLE(ECPARAMETERS, curve, X9_62_CURVE), | ||
247 | ASN1_SIMPLE(ECPARAMETERS, base, ASN1_OCTET_STRING), | ||
248 | ASN1_SIMPLE(ECPARAMETERS, order, ASN1_INTEGER), | ||
249 | ASN1_OPT(ECPARAMETERS, cofactor, ASN1_INTEGER) | ||
250 | } ASN1_SEQUENCE_END(ECPARAMETERS) | ||
251 | |||
252 | DECLARE_ASN1_ALLOC_FUNCTIONS(ECPARAMETERS) | ||
253 | IMPLEMENT_ASN1_ALLOC_FUNCTIONS(ECPARAMETERS) | ||
254 | |||
255 | ASN1_CHOICE(ECPKPARAMETERS) = { | ||
256 | ASN1_SIMPLE(ECPKPARAMETERS, value.named_curve, ASN1_OBJECT), | ||
257 | ASN1_SIMPLE(ECPKPARAMETERS, value.parameters, ECPARAMETERS), | ||
258 | ASN1_SIMPLE(ECPKPARAMETERS, value.implicitlyCA, ASN1_NULL) | ||
259 | } ASN1_CHOICE_END(ECPKPARAMETERS) | ||
260 | |||
261 | DECLARE_ASN1_FUNCTIONS_const(ECPKPARAMETERS) | ||
262 | DECLARE_ASN1_ENCODE_FUNCTIONS_const(ECPKPARAMETERS, ECPKPARAMETERS) | ||
263 | IMPLEMENT_ASN1_FUNCTIONS_const(ECPKPARAMETERS) | ||
264 | |||
265 | ASN1_SEQUENCE(EC_PRIVATEKEY) = { | ||
266 | ASN1_SIMPLE(EC_PRIVATEKEY, version, LONG), | ||
267 | ASN1_SIMPLE(EC_PRIVATEKEY, privateKey, ASN1_OCTET_STRING), | ||
268 | ASN1_EXP_OPT(EC_PRIVATEKEY, parameters, ECPKPARAMETERS, 0), | ||
269 | ASN1_EXP_OPT(EC_PRIVATEKEY, publicKey, ASN1_BIT_STRING, 1) | ||
270 | } ASN1_SEQUENCE_END(EC_PRIVATEKEY) | ||
271 | |||
272 | DECLARE_ASN1_FUNCTIONS_const(EC_PRIVATEKEY) | ||
273 | DECLARE_ASN1_ENCODE_FUNCTIONS_const(EC_PRIVATEKEY, EC_PRIVATEKEY) | ||
274 | IMPLEMENT_ASN1_FUNCTIONS_const(EC_PRIVATEKEY) | ||
275 | |||
276 | /* some declarations of internal function */ | ||
277 | |||
278 | /* ec_asn1_group2field() sets the values in a X9_62_FIELDID object */ | ||
279 | static int ec_asn1_group2fieldid(const EC_GROUP *, X9_62_FIELDID *); | ||
280 | /* ec_asn1_group2curve() sets the values in a X9_62_CURVE object */ | ||
281 | static int ec_asn1_group2curve(const EC_GROUP *, X9_62_CURVE *); | ||
282 | /* ec_asn1_parameters2group() creates a EC_GROUP object from a | ||
283 | * ECPARAMETERS object */ | ||
284 | static EC_GROUP *ec_asn1_parameters2group(const ECPARAMETERS *); | ||
285 | /* ec_asn1_group2parameters() creates a ECPARAMETERS object from a | ||
286 | * EC_GROUP object */ | ||
287 | static ECPARAMETERS *ec_asn1_group2parameters(const EC_GROUP *,ECPARAMETERS *); | ||
288 | /* ec_asn1_pkparameters2group() creates a EC_GROUP object from a | ||
289 | * ECPKPARAMETERS object */ | ||
290 | static EC_GROUP *ec_asn1_pkparameters2group(const ECPKPARAMETERS *); | ||
291 | /* ec_asn1_group2pkparameters() creates a ECPKPARAMETERS object from a | ||
292 | * EC_GROUP object */ | ||
293 | static ECPKPARAMETERS *ec_asn1_group2pkparameters(const EC_GROUP *, | ||
294 | ECPKPARAMETERS *); | ||
295 | |||
296 | |||
297 | /* the function definitions */ | ||
298 | |||
299 | static int ec_asn1_group2fieldid(const EC_GROUP *group, X9_62_FIELDID *field) | ||
300 | { | ||
301 | int ok=0, nid; | ||
302 | BIGNUM *tmp = NULL; | ||
303 | |||
304 | if (group == NULL || field == NULL) | ||
305 | return 0; | ||
306 | |||
307 | /* clear the old values (if necessary) */ | ||
308 | if (field->fieldType != NULL) | ||
309 | ASN1_OBJECT_free(field->fieldType); | ||
310 | if (field->p.other != NULL) | ||
311 | ASN1_TYPE_free(field->p.other); | ||
312 | |||
313 | nid = EC_METHOD_get_field_type(EC_GROUP_method_of(group)); | ||
314 | /* set OID for the field */ | ||
315 | if ((field->fieldType = OBJ_nid2obj(nid)) == NULL) | ||
316 | { | ||
317 | ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_OBJ_LIB); | ||
318 | goto err; | ||
319 | } | ||
320 | |||
321 | if (nid == NID_X9_62_prime_field) | ||
322 | { | ||
323 | if ((tmp = BN_new()) == NULL) | ||
324 | { | ||
325 | ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_MALLOC_FAILURE); | ||
326 | goto err; | ||
327 | } | ||
328 | /* the parameters are specified by the prime number p */ | ||
329 | if (!EC_GROUP_get_curve_GFp(group, tmp, NULL, NULL, NULL)) | ||
330 | { | ||
331 | ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_EC_LIB); | ||
332 | goto err; | ||
333 | } | ||
334 | /* set the prime number */ | ||
335 | field->p.prime = BN_to_ASN1_INTEGER(tmp,NULL); | ||
336 | if (field->p.prime == NULL) | ||
337 | { | ||
338 | ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_ASN1_LIB); | ||
339 | goto err; | ||
340 | } | ||
341 | } | ||
342 | else /* nid == NID_X9_62_characteristic_two_field */ | ||
343 | { | ||
344 | int field_type; | ||
345 | X9_62_CHARACTERISTIC_TWO *char_two; | ||
346 | |||
347 | field->p.char_two = X9_62_CHARACTERISTIC_TWO_new(); | ||
348 | char_two = field->p.char_two; | ||
349 | |||
350 | if (char_two == NULL) | ||
351 | { | ||
352 | ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_MALLOC_FAILURE); | ||
353 | goto err; | ||
354 | } | ||
355 | |||
356 | char_two->m = (long)EC_GROUP_get_degree(group); | ||
357 | |||
358 | field_type = EC_GROUP_get_basis_type(group); | ||
359 | |||
360 | if (field_type == 0) | ||
361 | { | ||
362 | ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_EC_LIB); | ||
363 | goto err; | ||
364 | } | ||
365 | /* set base type OID */ | ||
366 | if ((char_two->type = OBJ_nid2obj(field_type)) == NULL) | ||
367 | { | ||
368 | ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_OBJ_LIB); | ||
369 | goto err; | ||
370 | } | ||
371 | |||
372 | if (field_type == NID_X9_62_tpBasis) | ||
373 | { | ||
374 | unsigned int k; | ||
375 | |||
376 | if (!EC_GROUP_get_trinomial_basis(group, &k)) | ||
377 | goto err; | ||
378 | |||
379 | char_two->p.tpBasis = ASN1_INTEGER_new(); | ||
380 | if (!char_two->p.tpBasis) | ||
381 | { | ||
382 | ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_MALLOC_FAILURE); | ||
383 | goto err; | ||
384 | } | ||
385 | if (!ASN1_INTEGER_set(char_two->p.tpBasis, (long)k)) | ||
386 | { | ||
387 | ECerr(EC_F_EC_ASN1_GROUP2FIELDID, | ||
388 | ERR_R_ASN1_LIB); | ||
389 | goto err; | ||
390 | } | ||
391 | } | ||
392 | else if (field_type == NID_X9_62_ppBasis) | ||
393 | { | ||
394 | unsigned int k1, k2, k3; | ||
395 | |||
396 | if (!EC_GROUP_get_pentanomial_basis(group, &k1, &k2, &k3)) | ||
397 | goto err; | ||
398 | |||
399 | char_two->p.ppBasis = X9_62_PENTANOMIAL_new(); | ||
400 | if (!char_two->p.ppBasis) | ||
401 | { | ||
402 | ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_MALLOC_FAILURE); | ||
403 | goto err; | ||
404 | } | ||
405 | |||
406 | /* set k? values */ | ||
407 | char_two->p.ppBasis->k1 = (long)k1; | ||
408 | char_two->p.ppBasis->k2 = (long)k2; | ||
409 | char_two->p.ppBasis->k3 = (long)k3; | ||
410 | } | ||
411 | else /* field_type == NID_X9_62_onBasis */ | ||
412 | { | ||
413 | /* for ONB the parameters are (asn1) NULL */ | ||
414 | char_two->p.onBasis = ASN1_NULL_new(); | ||
415 | if (!char_two->p.onBasis) | ||
416 | { | ||
417 | ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_MALLOC_FAILURE); | ||
418 | goto err; | ||
419 | } | ||
420 | } | ||
421 | } | ||
422 | |||
423 | ok = 1; | ||
424 | |||
425 | err : if (tmp) | ||
426 | BN_free(tmp); | ||
427 | return(ok); | ||
428 | } | ||
429 | |||
430 | static int ec_asn1_group2curve(const EC_GROUP *group, X9_62_CURVE *curve) | ||
431 | { | ||
432 | int ok=0, nid; | ||
433 | BIGNUM *tmp_1=NULL, *tmp_2=NULL; | ||
434 | unsigned char *buffer_1=NULL, *buffer_2=NULL, | ||
435 | *a_buf=NULL, *b_buf=NULL; | ||
436 | size_t len_1, len_2; | ||
437 | unsigned char char_zero = 0; | ||
438 | |||
439 | if (!group || !curve || !curve->a || !curve->b) | ||
440 | return 0; | ||
441 | |||
442 | if ((tmp_1 = BN_new()) == NULL || (tmp_2 = BN_new()) == NULL) | ||
443 | { | ||
444 | ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_MALLOC_FAILURE); | ||
445 | goto err; | ||
446 | } | ||
447 | |||
448 | nid = EC_METHOD_get_field_type(EC_GROUP_method_of(group)); | ||
449 | |||
450 | /* get a and b */ | ||
451 | if (nid == NID_X9_62_prime_field) | ||
452 | { | ||
453 | if (!EC_GROUP_get_curve_GFp(group, NULL, tmp_1, tmp_2, NULL)) | ||
454 | { | ||
455 | ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_EC_LIB); | ||
456 | goto err; | ||
457 | } | ||
458 | } | ||
459 | else /* nid == NID_X9_62_characteristic_two_field */ | ||
460 | { | ||
461 | if (!EC_GROUP_get_curve_GF2m(group, NULL, tmp_1, tmp_2, NULL)) | ||
462 | { | ||
463 | ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_EC_LIB); | ||
464 | goto err; | ||
465 | } | ||
466 | } | ||
467 | |||
468 | len_1 = (size_t)BN_num_bytes(tmp_1); | ||
469 | len_2 = (size_t)BN_num_bytes(tmp_2); | ||
470 | |||
471 | if (len_1 == 0) | ||
472 | { | ||
473 | /* len_1 == 0 => a == 0 */ | ||
474 | a_buf = &char_zero; | ||
475 | len_1 = 1; | ||
476 | } | ||
477 | else | ||
478 | { | ||
479 | if ((buffer_1 = OPENSSL_malloc(len_1)) == NULL) | ||
480 | { | ||
481 | ECerr(EC_F_EC_ASN1_GROUP2CURVE, | ||
482 | ERR_R_MALLOC_FAILURE); | ||
483 | goto err; | ||
484 | } | ||
485 | if ( (len_1 = BN_bn2bin(tmp_1, buffer_1)) == 0) | ||
486 | { | ||
487 | ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_BN_LIB); | ||
488 | goto err; | ||
489 | } | ||
490 | a_buf = buffer_1; | ||
491 | } | ||
492 | |||
493 | if (len_2 == 0) | ||
494 | { | ||
495 | /* len_2 == 0 => b == 0 */ | ||
496 | b_buf = &char_zero; | ||
497 | len_2 = 1; | ||
498 | } | ||
499 | else | ||
500 | { | ||
501 | if ((buffer_2 = OPENSSL_malloc(len_2)) == NULL) | ||
502 | { | ||
503 | ECerr(EC_F_EC_ASN1_GROUP2CURVE, | ||
504 | ERR_R_MALLOC_FAILURE); | ||
505 | goto err; | ||
506 | } | ||
507 | if ( (len_2 = BN_bn2bin(tmp_2, buffer_2)) == 0) | ||
508 | { | ||
509 | ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_BN_LIB); | ||
510 | goto err; | ||
511 | } | ||
512 | b_buf = buffer_2; | ||
513 | } | ||
514 | |||
515 | /* set a and b */ | ||
516 | if (!M_ASN1_OCTET_STRING_set(curve->a, a_buf, len_1) || | ||
517 | !M_ASN1_OCTET_STRING_set(curve->b, b_buf, len_2)) | ||
518 | { | ||
519 | ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_ASN1_LIB); | ||
520 | goto err; | ||
521 | } | ||
522 | |||
523 | /* set the seed (optional) */ | ||
524 | if (group->seed) | ||
525 | { | ||
526 | if (!curve->seed) | ||
527 | if ((curve->seed = ASN1_BIT_STRING_new()) == NULL) | ||
528 | { | ||
529 | ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_MALLOC_FAILURE); | ||
530 | goto err; | ||
531 | } | ||
532 | curve->seed->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT|0x07); | ||
533 | curve->seed->flags |= ASN1_STRING_FLAG_BITS_LEFT; | ||
534 | if (!ASN1_BIT_STRING_set(curve->seed, group->seed, | ||
535 | (int)group->seed_len)) | ||
536 | { | ||
537 | ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_ASN1_LIB); | ||
538 | goto err; | ||
539 | } | ||
540 | } | ||
541 | else | ||
542 | { | ||
543 | if (curve->seed) | ||
544 | { | ||
545 | ASN1_BIT_STRING_free(curve->seed); | ||
546 | curve->seed = NULL; | ||
547 | } | ||
548 | } | ||
549 | |||
550 | ok = 1; | ||
551 | |||
552 | err: if (buffer_1) | ||
553 | OPENSSL_free(buffer_1); | ||
554 | if (buffer_2) | ||
555 | OPENSSL_free(buffer_2); | ||
556 | if (tmp_1) | ||
557 | BN_free(tmp_1); | ||
558 | if (tmp_2) | ||
559 | BN_free(tmp_2); | ||
560 | return(ok); | ||
561 | } | ||
562 | |||
563 | static ECPARAMETERS *ec_asn1_group2parameters(const EC_GROUP *group, | ||
564 | ECPARAMETERS *param) | ||
565 | { | ||
566 | int ok=0; | ||
567 | size_t len=0; | ||
568 | ECPARAMETERS *ret=NULL; | ||
569 | BIGNUM *tmp=NULL; | ||
570 | unsigned char *buffer=NULL; | ||
571 | const EC_POINT *point=NULL; | ||
572 | point_conversion_form_t form; | ||
573 | |||
574 | if ((tmp = BN_new()) == NULL) | ||
575 | { | ||
576 | ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_MALLOC_FAILURE); | ||
577 | goto err; | ||
578 | } | ||
579 | |||
580 | if (param == NULL) | ||
581 | { | ||
582 | if ((ret = ECPARAMETERS_new()) == NULL) | ||
583 | { | ||
584 | ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, | ||
585 | ERR_R_MALLOC_FAILURE); | ||
586 | goto err; | ||
587 | } | ||
588 | } | ||
589 | else | ||
590 | ret = param; | ||
591 | |||
592 | /* set the version (always one) */ | ||
593 | ret->version = (long)0x1; | ||
594 | |||
595 | /* set the fieldID */ | ||
596 | if (!ec_asn1_group2fieldid(group, ret->fieldID)) | ||
597 | { | ||
598 | ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_EC_LIB); | ||
599 | goto err; | ||
600 | } | ||
601 | |||
602 | /* set the curve */ | ||
603 | if (!ec_asn1_group2curve(group, ret->curve)) | ||
604 | { | ||
605 | ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_EC_LIB); | ||
606 | goto err; | ||
607 | } | ||
608 | |||
609 | /* set the base point */ | ||
610 | if ((point = EC_GROUP_get0_generator(group)) == NULL) | ||
611 | { | ||
612 | ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, EC_R_UNDEFINED_GENERATOR); | ||
613 | goto err; | ||
614 | } | ||
615 | |||
616 | form = EC_GROUP_get_point_conversion_form(group); | ||
617 | |||
618 | len = EC_POINT_point2oct(group, point, form, NULL, len, NULL); | ||
619 | if (len == 0) | ||
620 | { | ||
621 | ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_EC_LIB); | ||
622 | goto err; | ||
623 | } | ||
624 | if ((buffer = OPENSSL_malloc(len)) == NULL) | ||
625 | { | ||
626 | ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_MALLOC_FAILURE); | ||
627 | goto err; | ||
628 | } | ||
629 | if (!EC_POINT_point2oct(group, point, form, buffer, len, NULL)) | ||
630 | { | ||
631 | ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_EC_LIB); | ||
632 | goto err; | ||
633 | } | ||
634 | if (ret->base == NULL && (ret->base = ASN1_OCTET_STRING_new()) == NULL) | ||
635 | { | ||
636 | ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_MALLOC_FAILURE); | ||
637 | goto err; | ||
638 | } | ||
639 | if (!ASN1_OCTET_STRING_set(ret->base, buffer, len)) | ||
640 | { | ||
641 | ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_ASN1_LIB); | ||
642 | goto err; | ||
643 | } | ||
644 | |||
645 | /* set the order */ | ||
646 | if (!EC_GROUP_get_order(group, tmp, NULL)) | ||
647 | { | ||
648 | ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_EC_LIB); | ||
649 | goto err; | ||
650 | } | ||
651 | ret->order = BN_to_ASN1_INTEGER(tmp, ret->order); | ||
652 | if (ret->order == NULL) | ||
653 | { | ||
654 | ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_ASN1_LIB); | ||
655 | goto err; | ||
656 | } | ||
657 | |||
658 | /* set the cofactor (optional) */ | ||
659 | if (EC_GROUP_get_cofactor(group, tmp, NULL)) | ||
660 | { | ||
661 | ret->cofactor = BN_to_ASN1_INTEGER(tmp, ret->cofactor); | ||
662 | if (ret->cofactor == NULL) | ||
663 | { | ||
664 | ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_ASN1_LIB); | ||
665 | goto err; | ||
666 | } | ||
667 | } | ||
668 | |||
669 | ok = 1; | ||
670 | |||
671 | err : if(!ok) | ||
672 | { | ||
673 | if (ret && !param) | ||
674 | ECPARAMETERS_free(ret); | ||
675 | ret = NULL; | ||
676 | } | ||
677 | if (tmp) | ||
678 | BN_free(tmp); | ||
679 | if (buffer) | ||
680 | OPENSSL_free(buffer); | ||
681 | return(ret); | ||
682 | } | ||
683 | |||
684 | ECPKPARAMETERS *ec_asn1_group2pkparameters(const EC_GROUP *group, | ||
685 | ECPKPARAMETERS *params) | ||
686 | { | ||
687 | int ok = 1, tmp; | ||
688 | ECPKPARAMETERS *ret = params; | ||
689 | |||
690 | if (ret == NULL) | ||
691 | { | ||
692 | if ((ret = ECPKPARAMETERS_new()) == NULL) | ||
693 | { | ||
694 | ECerr(EC_F_EC_ASN1_GROUP2PKPARAMETERS, | ||
695 | ERR_R_MALLOC_FAILURE); | ||
696 | return NULL; | ||
697 | } | ||
698 | } | ||
699 | else | ||
700 | { | ||
701 | if (ret->type == 0 && ret->value.named_curve) | ||
702 | ASN1_OBJECT_free(ret->value.named_curve); | ||
703 | else if (ret->type == 1 && ret->value.parameters) | ||
704 | ECPARAMETERS_free(ret->value.parameters); | ||
705 | } | ||
706 | |||
707 | if (EC_GROUP_get_asn1_flag(group)) | ||
708 | { | ||
709 | /* use the asn1 OID to describe the | ||
710 | * the elliptic curve parameters | ||
711 | */ | ||
712 | tmp = EC_GROUP_get_curve_name(group); | ||
713 | if (tmp) | ||
714 | { | ||
715 | ret->type = 0; | ||
716 | if ((ret->value.named_curve = OBJ_nid2obj(tmp)) == NULL) | ||
717 | ok = 0; | ||
718 | } | ||
719 | else | ||
720 | /* we don't kmow the nid => ERROR */ | ||
721 | ok = 0; | ||
722 | } | ||
723 | else | ||
724 | { | ||
725 | /* use the ECPARAMETERS structure */ | ||
726 | ret->type = 1; | ||
727 | if ((ret->value.parameters = ec_asn1_group2parameters( | ||
728 | group, NULL)) == NULL) | ||
729 | ok = 0; | ||
730 | } | ||
731 | |||
732 | if (!ok) | ||
733 | { | ||
734 | ECPKPARAMETERS_free(ret); | ||
735 | return NULL; | ||
736 | } | ||
737 | return ret; | ||
738 | } | ||
739 | |||
740 | static EC_GROUP *ec_asn1_parameters2group(const ECPARAMETERS *params) | ||
741 | { | ||
742 | int ok = 0, tmp; | ||
743 | EC_GROUP *ret = NULL; | ||
744 | BIGNUM *p = NULL, *a = NULL, *b = NULL; | ||
745 | EC_POINT *point=NULL; | ||
746 | long field_bits; | ||
747 | |||
748 | if (!params->fieldID || !params->fieldID->fieldType || | ||
749 | !params->fieldID->p.ptr) | ||
750 | { | ||
751 | ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR); | ||
752 | goto err; | ||
753 | } | ||
754 | |||
755 | /* now extract the curve parameters a and b */ | ||
756 | if (!params->curve || !params->curve->a || | ||
757 | !params->curve->a->data || !params->curve->b || | ||
758 | !params->curve->b->data) | ||
759 | { | ||
760 | ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR); | ||
761 | goto err; | ||
762 | } | ||
763 | a = BN_bin2bn(params->curve->a->data, params->curve->a->length, NULL); | ||
764 | if (a == NULL) | ||
765 | { | ||
766 | ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_BN_LIB); | ||
767 | goto err; | ||
768 | } | ||
769 | b = BN_bin2bn(params->curve->b->data, params->curve->b->length, NULL); | ||
770 | if (b == NULL) | ||
771 | { | ||
772 | ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_BN_LIB); | ||
773 | goto err; | ||
774 | } | ||
775 | |||
776 | /* get the field parameters */ | ||
777 | tmp = OBJ_obj2nid(params->fieldID->fieldType); | ||
778 | |||
779 | if (tmp == NID_X9_62_characteristic_two_field) | ||
780 | { | ||
781 | X9_62_CHARACTERISTIC_TWO *char_two; | ||
782 | |||
783 | char_two = params->fieldID->p.char_two; | ||
784 | |||
785 | field_bits = char_two->m; | ||
786 | if (field_bits > OPENSSL_ECC_MAX_FIELD_BITS) | ||
787 | { | ||
788 | ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_FIELD_TOO_LARGE); | ||
789 | goto err; | ||
790 | } | ||
791 | |||
792 | if ((p = BN_new()) == NULL) | ||
793 | { | ||
794 | ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_MALLOC_FAILURE); | ||
795 | goto err; | ||
796 | } | ||
797 | |||
798 | /* get the base type */ | ||
799 | tmp = OBJ_obj2nid(char_two->type); | ||
800 | |||
801 | if (tmp == NID_X9_62_tpBasis) | ||
802 | { | ||
803 | long tmp_long; | ||
804 | |||
805 | if (!char_two->p.tpBasis) | ||
806 | { | ||
807 | ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR); | ||
808 | goto err; | ||
809 | } | ||
810 | |||
811 | tmp_long = ASN1_INTEGER_get(char_two->p.tpBasis); | ||
812 | |||
813 | if (!(char_two->m > tmp_long && tmp_long > 0)) | ||
814 | { | ||
815 | ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_INVALID_TRINOMIAL_BASIS); | ||
816 | goto err; | ||
817 | } | ||
818 | |||
819 | /* create the polynomial */ | ||
820 | if (!BN_set_bit(p, (int)char_two->m)) | ||
821 | goto err; | ||
822 | if (!BN_set_bit(p, (int)tmp_long)) | ||
823 | goto err; | ||
824 | if (!BN_set_bit(p, 0)) | ||
825 | goto err; | ||
826 | } | ||
827 | else if (tmp == NID_X9_62_ppBasis) | ||
828 | { | ||
829 | X9_62_PENTANOMIAL *penta; | ||
830 | |||
831 | penta = char_two->p.ppBasis; | ||
832 | if (!penta) | ||
833 | { | ||
834 | ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR); | ||
835 | goto err; | ||
836 | } | ||
837 | |||
838 | if (!(char_two->m > penta->k3 && penta->k3 > penta->k2 && penta->k2 > penta->k1 && penta->k1 > 0)) | ||
839 | { | ||
840 | ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_INVALID_PENTANOMIAL_BASIS); | ||
841 | goto err; | ||
842 | } | ||
843 | |||
844 | /* create the polynomial */ | ||
845 | if (!BN_set_bit(p, (int)char_two->m)) goto err; | ||
846 | if (!BN_set_bit(p, (int)penta->k1)) goto err; | ||
847 | if (!BN_set_bit(p, (int)penta->k2)) goto err; | ||
848 | if (!BN_set_bit(p, (int)penta->k3)) goto err; | ||
849 | if (!BN_set_bit(p, 0)) goto err; | ||
850 | } | ||
851 | else if (tmp == NID_X9_62_onBasis) | ||
852 | { | ||
853 | ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_NOT_IMPLEMENTED); | ||
854 | goto err; | ||
855 | } | ||
856 | else /* error */ | ||
857 | { | ||
858 | ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR); | ||
859 | goto err; | ||
860 | } | ||
861 | |||
862 | /* create the EC_GROUP structure */ | ||
863 | ret = EC_GROUP_new_curve_GF2m(p, a, b, NULL); | ||
864 | } | ||
865 | else if (tmp == NID_X9_62_prime_field) | ||
866 | { | ||
867 | /* we have a curve over a prime field */ | ||
868 | /* extract the prime number */ | ||
869 | if (!params->fieldID->p.prime) | ||
870 | { | ||
871 | ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR); | ||
872 | goto err; | ||
873 | } | ||
874 | p = ASN1_INTEGER_to_BN(params->fieldID->p.prime, NULL); | ||
875 | if (p == NULL) | ||
876 | { | ||
877 | ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_ASN1_LIB); | ||
878 | goto err; | ||
879 | } | ||
880 | |||
881 | if (BN_is_negative(p) || BN_is_zero(p)) | ||
882 | { | ||
883 | ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_INVALID_FIELD); | ||
884 | goto err; | ||
885 | } | ||
886 | |||
887 | field_bits = BN_num_bits(p); | ||
888 | if (field_bits > OPENSSL_ECC_MAX_FIELD_BITS) | ||
889 | { | ||
890 | ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_FIELD_TOO_LARGE); | ||
891 | goto err; | ||
892 | } | ||
893 | |||
894 | /* create the EC_GROUP structure */ | ||
895 | ret = EC_GROUP_new_curve_GFp(p, a, b, NULL); | ||
896 | } | ||
897 | else | ||
898 | { | ||
899 | ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_INVALID_FIELD); | ||
900 | goto err; | ||
901 | } | ||
902 | |||
903 | if (ret == NULL) | ||
904 | { | ||
905 | ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_EC_LIB); | ||
906 | goto err; | ||
907 | } | ||
908 | |||
909 | /* extract seed (optional) */ | ||
910 | if (params->curve->seed != NULL) | ||
911 | { | ||
912 | if (ret->seed != NULL) | ||
913 | OPENSSL_free(ret->seed); | ||
914 | if (!(ret->seed = OPENSSL_malloc(params->curve->seed->length))) | ||
915 | { | ||
916 | ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, | ||
917 | ERR_R_MALLOC_FAILURE); | ||
918 | goto err; | ||
919 | } | ||
920 | memcpy(ret->seed, params->curve->seed->data, | ||
921 | params->curve->seed->length); | ||
922 | ret->seed_len = params->curve->seed->length; | ||
923 | } | ||
924 | |||
925 | if (!params->order || !params->base || !params->base->data) | ||
926 | { | ||
927 | ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR); | ||
928 | goto err; | ||
929 | } | ||
930 | |||
931 | if ((point = EC_POINT_new(ret)) == NULL) goto err; | ||
932 | |||
933 | /* set the point conversion form */ | ||
934 | EC_GROUP_set_point_conversion_form(ret, (point_conversion_form_t) | ||
935 | (params->base->data[0] & ~0x01)); | ||
936 | |||
937 | /* extract the ec point */ | ||
938 | if (!EC_POINT_oct2point(ret, point, params->base->data, | ||
939 | params->base->length, NULL)) | ||
940 | { | ||
941 | ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_EC_LIB); | ||
942 | goto err; | ||
943 | } | ||
944 | |||
945 | /* extract the order */ | ||
946 | if ((a = ASN1_INTEGER_to_BN(params->order, a)) == NULL) | ||
947 | { | ||
948 | ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_ASN1_LIB); | ||
949 | goto err; | ||
950 | } | ||
951 | if (BN_is_negative(a) || BN_is_zero(a)) | ||
952 | { | ||
953 | ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_INVALID_GROUP_ORDER); | ||
954 | goto err; | ||
955 | } | ||
956 | if (BN_num_bits(a) > (int)field_bits + 1) /* Hasse bound */ | ||
957 | { | ||
958 | ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_INVALID_GROUP_ORDER); | ||
959 | goto err; | ||
960 | } | ||
961 | |||
962 | /* extract the cofactor (optional) */ | ||
963 | if (params->cofactor == NULL) | ||
964 | { | ||
965 | if (b) | ||
966 | { | ||
967 | BN_free(b); | ||
968 | b = NULL; | ||
969 | } | ||
970 | } | ||
971 | else | ||
972 | if ((b = ASN1_INTEGER_to_BN(params->cofactor, b)) == NULL) | ||
973 | { | ||
974 | ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_ASN1_LIB); | ||
975 | goto err; | ||
976 | } | ||
977 | /* set the generator, order and cofactor (if present) */ | ||
978 | if (!EC_GROUP_set_generator(ret, point, a, b)) | ||
979 | { | ||
980 | ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_EC_LIB); | ||
981 | goto err; | ||
982 | } | ||
983 | |||
984 | ok = 1; | ||
985 | |||
986 | err: if (!ok) | ||
987 | { | ||
988 | if (ret) | ||
989 | EC_GROUP_clear_free(ret); | ||
990 | ret = NULL; | ||
991 | } | ||
992 | |||
993 | if (p) | ||
994 | BN_free(p); | ||
995 | if (a) | ||
996 | BN_free(a); | ||
997 | if (b) | ||
998 | BN_free(b); | ||
999 | if (point) | ||
1000 | EC_POINT_free(point); | ||
1001 | return(ret); | ||
1002 | } | ||
1003 | |||
1004 | EC_GROUP *ec_asn1_pkparameters2group(const ECPKPARAMETERS *params) | ||
1005 | { | ||
1006 | EC_GROUP *ret=NULL; | ||
1007 | int tmp=0; | ||
1008 | |||
1009 | if (params == NULL) | ||
1010 | { | ||
1011 | ECerr(EC_F_EC_ASN1_PKPARAMETERS2GROUP, | ||
1012 | EC_R_MISSING_PARAMETERS); | ||
1013 | return NULL; | ||
1014 | } | ||
1015 | |||
1016 | if (params->type == 0) | ||
1017 | { /* the curve is given by an OID */ | ||
1018 | tmp = OBJ_obj2nid(params->value.named_curve); | ||
1019 | if ((ret = EC_GROUP_new_by_curve_name(tmp)) == NULL) | ||
1020 | { | ||
1021 | ECerr(EC_F_EC_ASN1_PKPARAMETERS2GROUP, | ||
1022 | EC_R_EC_GROUP_NEW_BY_NAME_FAILURE); | ||
1023 | return NULL; | ||
1024 | } | ||
1025 | EC_GROUP_set_asn1_flag(ret, OPENSSL_EC_NAMED_CURVE); | ||
1026 | } | ||
1027 | else if (params->type == 1) | ||
1028 | { /* the parameters are given by a ECPARAMETERS | ||
1029 | * structure */ | ||
1030 | ret = ec_asn1_parameters2group(params->value.parameters); | ||
1031 | if (!ret) | ||
1032 | { | ||
1033 | ECerr(EC_F_EC_ASN1_PKPARAMETERS2GROUP, ERR_R_EC_LIB); | ||
1034 | return NULL; | ||
1035 | } | ||
1036 | EC_GROUP_set_asn1_flag(ret, 0x0); | ||
1037 | } | ||
1038 | else if (params->type == 2) | ||
1039 | { /* implicitlyCA */ | ||
1040 | return NULL; | ||
1041 | } | ||
1042 | else | ||
1043 | { | ||
1044 | ECerr(EC_F_EC_ASN1_PKPARAMETERS2GROUP, EC_R_ASN1_ERROR); | ||
1045 | return NULL; | ||
1046 | } | ||
1047 | |||
1048 | return ret; | ||
1049 | } | ||
1050 | |||
1051 | /* EC_GROUP <-> DER encoding of ECPKPARAMETERS */ | ||
1052 | |||
1053 | EC_GROUP *d2i_ECPKParameters(EC_GROUP **a, const unsigned char **in, long len) | ||
1054 | { | ||
1055 | EC_GROUP *group = NULL; | ||
1056 | ECPKPARAMETERS *params = NULL; | ||
1057 | |||
1058 | if ((params = d2i_ECPKPARAMETERS(NULL, in, len)) == NULL) | ||
1059 | { | ||
1060 | ECerr(EC_F_D2I_ECPKPARAMETERS, EC_R_D2I_ECPKPARAMETERS_FAILURE); | ||
1061 | ECPKPARAMETERS_free(params); | ||
1062 | return NULL; | ||
1063 | } | ||
1064 | |||
1065 | if ((group = ec_asn1_pkparameters2group(params)) == NULL) | ||
1066 | { | ||
1067 | ECerr(EC_F_D2I_ECPKPARAMETERS, EC_R_PKPARAMETERS2GROUP_FAILURE); | ||
1068 | return NULL; | ||
1069 | } | ||
1070 | |||
1071 | |||
1072 | if (a && *a) | ||
1073 | EC_GROUP_clear_free(*a); | ||
1074 | if (a) | ||
1075 | *a = group; | ||
1076 | |||
1077 | ECPKPARAMETERS_free(params); | ||
1078 | return(group); | ||
1079 | } | ||
1080 | |||
1081 | int i2d_ECPKParameters(const EC_GROUP *a, unsigned char **out) | ||
1082 | { | ||
1083 | int ret=0; | ||
1084 | ECPKPARAMETERS *tmp = ec_asn1_group2pkparameters(a, NULL); | ||
1085 | if (tmp == NULL) | ||
1086 | { | ||
1087 | ECerr(EC_F_I2D_ECPKPARAMETERS, EC_R_GROUP2PKPARAMETERS_FAILURE); | ||
1088 | return 0; | ||
1089 | } | ||
1090 | if ((ret = i2d_ECPKPARAMETERS(tmp, out)) == 0) | ||
1091 | { | ||
1092 | ECerr(EC_F_I2D_ECPKPARAMETERS, EC_R_I2D_ECPKPARAMETERS_FAILURE); | ||
1093 | ECPKPARAMETERS_free(tmp); | ||
1094 | return 0; | ||
1095 | } | ||
1096 | ECPKPARAMETERS_free(tmp); | ||
1097 | return(ret); | ||
1098 | } | ||
1099 | |||
1100 | /* some EC_KEY functions */ | ||
1101 | |||
1102 | EC_KEY *d2i_ECPrivateKey(EC_KEY **a, const unsigned char **in, long len) | ||
1103 | { | ||
1104 | int ok=0; | ||
1105 | EC_KEY *ret=NULL; | ||
1106 | EC_PRIVATEKEY *priv_key=NULL; | ||
1107 | |||
1108 | if ((priv_key = EC_PRIVATEKEY_new()) == NULL) | ||
1109 | { | ||
1110 | ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_MALLOC_FAILURE); | ||
1111 | return NULL; | ||
1112 | } | ||
1113 | |||
1114 | if ((priv_key = d2i_EC_PRIVATEKEY(&priv_key, in, len)) == NULL) | ||
1115 | { | ||
1116 | ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_EC_LIB); | ||
1117 | EC_PRIVATEKEY_free(priv_key); | ||
1118 | return NULL; | ||
1119 | } | ||
1120 | |||
1121 | if (a == NULL || *a == NULL) | ||
1122 | { | ||
1123 | if ((ret = EC_KEY_new()) == NULL) | ||
1124 | { | ||
1125 | ECerr(EC_F_D2I_ECPRIVATEKEY, | ||
1126 | ERR_R_MALLOC_FAILURE); | ||
1127 | goto err; | ||
1128 | } | ||
1129 | if (a) | ||
1130 | *a = ret; | ||
1131 | } | ||
1132 | else | ||
1133 | ret = *a; | ||
1134 | |||
1135 | if (priv_key->parameters) | ||
1136 | { | ||
1137 | if (ret->group) | ||
1138 | EC_GROUP_clear_free(ret->group); | ||
1139 | ret->group = ec_asn1_pkparameters2group(priv_key->parameters); | ||
1140 | } | ||
1141 | |||
1142 | if (ret->group == NULL) | ||
1143 | { | ||
1144 | ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_EC_LIB); | ||
1145 | goto err; | ||
1146 | } | ||
1147 | |||
1148 | ret->version = priv_key->version; | ||
1149 | |||
1150 | if (priv_key->privateKey) | ||
1151 | { | ||
1152 | ret->priv_key = BN_bin2bn( | ||
1153 | M_ASN1_STRING_data(priv_key->privateKey), | ||
1154 | M_ASN1_STRING_length(priv_key->privateKey), | ||
1155 | ret->priv_key); | ||
1156 | if (ret->priv_key == NULL) | ||
1157 | { | ||
1158 | ECerr(EC_F_D2I_ECPRIVATEKEY, | ||
1159 | ERR_R_BN_LIB); | ||
1160 | goto err; | ||
1161 | } | ||
1162 | } | ||
1163 | else | ||
1164 | { | ||
1165 | ECerr(EC_F_D2I_ECPRIVATEKEY, | ||
1166 | EC_R_MISSING_PRIVATE_KEY); | ||
1167 | goto err; | ||
1168 | } | ||
1169 | |||
1170 | if (priv_key->publicKey) | ||
1171 | { | ||
1172 | const unsigned char *pub_oct; | ||
1173 | size_t pub_oct_len; | ||
1174 | |||
1175 | if (ret->pub_key) | ||
1176 | EC_POINT_clear_free(ret->pub_key); | ||
1177 | ret->pub_key = EC_POINT_new(ret->group); | ||
1178 | if (ret->pub_key == NULL) | ||
1179 | { | ||
1180 | ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_EC_LIB); | ||
1181 | goto err; | ||
1182 | } | ||
1183 | pub_oct = M_ASN1_STRING_data(priv_key->publicKey); | ||
1184 | pub_oct_len = M_ASN1_STRING_length(priv_key->publicKey); | ||
1185 | /* save the point conversion form */ | ||
1186 | ret->conv_form = (point_conversion_form_t)(pub_oct[0] & ~0x01); | ||
1187 | if (!EC_POINT_oct2point(ret->group, ret->pub_key, | ||
1188 | pub_oct, pub_oct_len, NULL)) | ||
1189 | { | ||
1190 | ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_EC_LIB); | ||
1191 | goto err; | ||
1192 | } | ||
1193 | } | ||
1194 | |||
1195 | ok = 1; | ||
1196 | err: | ||
1197 | if (!ok) | ||
1198 | { | ||
1199 | if (ret) | ||
1200 | EC_KEY_free(ret); | ||
1201 | ret = NULL; | ||
1202 | } | ||
1203 | |||
1204 | if (priv_key) | ||
1205 | EC_PRIVATEKEY_free(priv_key); | ||
1206 | |||
1207 | return(ret); | ||
1208 | } | ||
1209 | |||
1210 | int i2d_ECPrivateKey(EC_KEY *a, unsigned char **out) | ||
1211 | { | ||
1212 | int ret=0, ok=0; | ||
1213 | unsigned char *buffer=NULL; | ||
1214 | size_t buf_len=0, tmp_len; | ||
1215 | EC_PRIVATEKEY *priv_key=NULL; | ||
1216 | |||
1217 | if (a == NULL || a->group == NULL || a->priv_key == NULL) | ||
1218 | { | ||
1219 | ECerr(EC_F_I2D_ECPRIVATEKEY, | ||
1220 | ERR_R_PASSED_NULL_PARAMETER); | ||
1221 | goto err; | ||
1222 | } | ||
1223 | |||
1224 | if ((priv_key = EC_PRIVATEKEY_new()) == NULL) | ||
1225 | { | ||
1226 | ECerr(EC_F_I2D_ECPRIVATEKEY, | ||
1227 | ERR_R_MALLOC_FAILURE); | ||
1228 | goto err; | ||
1229 | } | ||
1230 | |||
1231 | priv_key->version = a->version; | ||
1232 | |||
1233 | buf_len = (size_t)BN_num_bytes(a->priv_key); | ||
1234 | buffer = OPENSSL_malloc(buf_len); | ||
1235 | if (buffer == NULL) | ||
1236 | { | ||
1237 | ECerr(EC_F_I2D_ECPRIVATEKEY, | ||
1238 | ERR_R_MALLOC_FAILURE); | ||
1239 | goto err; | ||
1240 | } | ||
1241 | |||
1242 | if (!BN_bn2bin(a->priv_key, buffer)) | ||
1243 | { | ||
1244 | ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_BN_LIB); | ||
1245 | goto err; | ||
1246 | } | ||
1247 | |||
1248 | if (!M_ASN1_OCTET_STRING_set(priv_key->privateKey, buffer, buf_len)) | ||
1249 | { | ||
1250 | ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_ASN1_LIB); | ||
1251 | goto err; | ||
1252 | } | ||
1253 | |||
1254 | if (!(a->enc_flag & EC_PKEY_NO_PARAMETERS)) | ||
1255 | { | ||
1256 | if ((priv_key->parameters = ec_asn1_group2pkparameters( | ||
1257 | a->group, priv_key->parameters)) == NULL) | ||
1258 | { | ||
1259 | ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_EC_LIB); | ||
1260 | goto err; | ||
1261 | } | ||
1262 | } | ||
1263 | |||
1264 | if (!(a->enc_flag & EC_PKEY_NO_PUBKEY)) | ||
1265 | { | ||
1266 | priv_key->publicKey = M_ASN1_BIT_STRING_new(); | ||
1267 | if (priv_key->publicKey == NULL) | ||
1268 | { | ||
1269 | ECerr(EC_F_I2D_ECPRIVATEKEY, | ||
1270 | ERR_R_MALLOC_FAILURE); | ||
1271 | goto err; | ||
1272 | } | ||
1273 | |||
1274 | tmp_len = EC_POINT_point2oct(a->group, a->pub_key, | ||
1275 | a->conv_form, NULL, 0, NULL); | ||
1276 | |||
1277 | if (tmp_len > buf_len) | ||
1278 | { | ||
1279 | unsigned char *tmp_buffer = OPENSSL_realloc(buffer, tmp_len); | ||
1280 | if (!tmp_buffer) | ||
1281 | { | ||
1282 | ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_MALLOC_FAILURE); | ||
1283 | goto err; | ||
1284 | } | ||
1285 | buffer = tmp_buffer; | ||
1286 | buf_len = tmp_len; | ||
1287 | } | ||
1288 | |||
1289 | if (!EC_POINT_point2oct(a->group, a->pub_key, | ||
1290 | a->conv_form, buffer, buf_len, NULL)) | ||
1291 | { | ||
1292 | ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_EC_LIB); | ||
1293 | goto err; | ||
1294 | } | ||
1295 | |||
1296 | priv_key->publicKey->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT|0x07); | ||
1297 | priv_key->publicKey->flags |= ASN1_STRING_FLAG_BITS_LEFT; | ||
1298 | if (!M_ASN1_BIT_STRING_set(priv_key->publicKey, buffer, | ||
1299 | buf_len)) | ||
1300 | { | ||
1301 | ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_ASN1_LIB); | ||
1302 | goto err; | ||
1303 | } | ||
1304 | } | ||
1305 | |||
1306 | if ((ret = i2d_EC_PRIVATEKEY(priv_key, out)) == 0) | ||
1307 | { | ||
1308 | ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_EC_LIB); | ||
1309 | goto err; | ||
1310 | } | ||
1311 | ok=1; | ||
1312 | err: | ||
1313 | if (buffer) | ||
1314 | OPENSSL_free(buffer); | ||
1315 | if (priv_key) | ||
1316 | EC_PRIVATEKEY_free(priv_key); | ||
1317 | return(ok?ret:0); | ||
1318 | } | ||
1319 | |||
1320 | int i2d_ECParameters(EC_KEY *a, unsigned char **out) | ||
1321 | { | ||
1322 | if (a == NULL) | ||
1323 | { | ||
1324 | ECerr(EC_F_I2D_ECPARAMETERS, ERR_R_PASSED_NULL_PARAMETER); | ||
1325 | return 0; | ||
1326 | } | ||
1327 | return i2d_ECPKParameters(a->group, out); | ||
1328 | } | ||
1329 | |||
1330 | EC_KEY *d2i_ECParameters(EC_KEY **a, const unsigned char **in, long len) | ||
1331 | { | ||
1332 | EC_KEY *ret; | ||
1333 | |||
1334 | if (in == NULL || *in == NULL) | ||
1335 | { | ||
1336 | ECerr(EC_F_D2I_ECPARAMETERS, ERR_R_PASSED_NULL_PARAMETER); | ||
1337 | return NULL; | ||
1338 | } | ||
1339 | |||
1340 | if (a == NULL || *a == NULL) | ||
1341 | { | ||
1342 | if ((ret = EC_KEY_new()) == NULL) | ||
1343 | { | ||
1344 | ECerr(EC_F_D2I_ECPARAMETERS, ERR_R_MALLOC_FAILURE); | ||
1345 | return NULL; | ||
1346 | } | ||
1347 | if (a) | ||
1348 | *a = ret; | ||
1349 | } | ||
1350 | else | ||
1351 | ret = *a; | ||
1352 | |||
1353 | if (!d2i_ECPKParameters(&ret->group, in, len)) | ||
1354 | { | ||
1355 | ECerr(EC_F_D2I_ECPARAMETERS, ERR_R_EC_LIB); | ||
1356 | return NULL; | ||
1357 | } | ||
1358 | |||
1359 | return ret; | ||
1360 | } | ||
1361 | |||
1362 | EC_KEY *o2i_ECPublicKey(EC_KEY **a, const unsigned char **in, long len) | ||
1363 | { | ||
1364 | EC_KEY *ret=NULL; | ||
1365 | |||
1366 | if (a == NULL || (*a) == NULL || (*a)->group == NULL) | ||
1367 | { | ||
1368 | /* sorry, but a EC_GROUP-structur is necessary | ||
1369 | * to set the public key */ | ||
1370 | ECerr(EC_F_O2I_ECPUBLICKEY, ERR_R_PASSED_NULL_PARAMETER); | ||
1371 | return 0; | ||
1372 | } | ||
1373 | ret = *a; | ||
1374 | if (ret->pub_key == NULL && | ||
1375 | (ret->pub_key = EC_POINT_new(ret->group)) == NULL) | ||
1376 | { | ||
1377 | ECerr(EC_F_O2I_ECPUBLICKEY, ERR_R_MALLOC_FAILURE); | ||
1378 | return 0; | ||
1379 | } | ||
1380 | if (!EC_POINT_oct2point(ret->group, ret->pub_key, *in, len, NULL)) | ||
1381 | { | ||
1382 | ECerr(EC_F_O2I_ECPUBLICKEY, ERR_R_EC_LIB); | ||
1383 | return 0; | ||
1384 | } | ||
1385 | /* save the point conversion form */ | ||
1386 | ret->conv_form = (point_conversion_form_t)(*in[0] & ~0x01); | ||
1387 | *in += len; | ||
1388 | return ret; | ||
1389 | } | ||
1390 | |||
1391 | int i2o_ECPublicKey(EC_KEY *a, unsigned char **out) | ||
1392 | { | ||
1393 | size_t buf_len=0; | ||
1394 | int new_buffer = 0; | ||
1395 | |||
1396 | if (a == NULL) | ||
1397 | { | ||
1398 | ECerr(EC_F_I2O_ECPUBLICKEY, ERR_R_PASSED_NULL_PARAMETER); | ||
1399 | return 0; | ||
1400 | } | ||
1401 | |||
1402 | buf_len = EC_POINT_point2oct(a->group, a->pub_key, | ||
1403 | a->conv_form, NULL, 0, NULL); | ||
1404 | |||
1405 | if (out == NULL || buf_len == 0) | ||
1406 | /* out == NULL => just return the length of the octet string */ | ||
1407 | return buf_len; | ||
1408 | |||
1409 | if (*out == NULL) | ||
1410 | { | ||
1411 | if ((*out = OPENSSL_malloc(buf_len)) == NULL) | ||
1412 | { | ||
1413 | ECerr(EC_F_I2O_ECPUBLICKEY, ERR_R_MALLOC_FAILURE); | ||
1414 | return 0; | ||
1415 | } | ||
1416 | new_buffer = 1; | ||
1417 | } | ||
1418 | if (!EC_POINT_point2oct(a->group, a->pub_key, a->conv_form, | ||
1419 | *out, buf_len, NULL)) | ||
1420 | { | ||
1421 | ECerr(EC_F_I2O_ECPUBLICKEY, ERR_R_EC_LIB); | ||
1422 | OPENSSL_free(*out); | ||
1423 | *out = NULL; | ||
1424 | return 0; | ||
1425 | } | ||
1426 | if (!new_buffer) | ||
1427 | *out += buf_len; | ||
1428 | return buf_len; | ||
1429 | } | ||
diff --git a/src/lib/libcrypto/ec/ec_check.c b/src/lib/libcrypto/ec/ec_check.c new file mode 100644 index 0000000000..0e316b4b3f --- /dev/null +++ b/src/lib/libcrypto/ec/ec_check.c | |||
@@ -0,0 +1,123 @@ | |||
1 | /* crypto/ec/ec_check.c */ | ||
2 | /* ==================================================================== | ||
3 | * Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions | ||
7 | * are met: | ||
8 | * | ||
9 | * 1. Redistributions of source code must retain the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer. | ||
11 | * | ||
12 | * 2. Redistributions in binary form must reproduce the above copyright | ||
13 | * notice, this list of conditions and the following disclaimer in | ||
14 | * the documentation and/or other materials provided with the | ||
15 | * distribution. | ||
16 | * | ||
17 | * 3. All advertising materials mentioning features or use of this | ||
18 | * software must display the following acknowledgment: | ||
19 | * "This product includes software developed by the OpenSSL Project | ||
20 | * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" | ||
21 | * | ||
22 | * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to | ||
23 | * endorse or promote products derived from this software without | ||
24 | * prior written permission. For written permission, please contact | ||
25 | * openssl-core@openssl.org. | ||
26 | * | ||
27 | * 5. Products derived from this software may not be called "OpenSSL" | ||
28 | * nor may "OpenSSL" appear in their names without prior written | ||
29 | * permission of the OpenSSL Project. | ||
30 | * | ||
31 | * 6. Redistributions of any form whatsoever must retain the following | ||
32 | * acknowledgment: | ||
33 | * "This product includes software developed by the OpenSSL Project | ||
34 | * for use in the OpenSSL Toolkit (http://www.openssl.org/)" | ||
35 | * | ||
36 | * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY | ||
37 | * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
38 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | ||
39 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR | ||
40 | * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
41 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
42 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
43 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
44 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
45 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
46 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED | ||
47 | * OF THE POSSIBILITY OF SUCH DAMAGE. | ||
48 | * ==================================================================== | ||
49 | * | ||
50 | * This product includes cryptographic software written by Eric Young | ||
51 | * (eay@cryptsoft.com). This product includes software written by Tim | ||
52 | * Hudson (tjh@cryptsoft.com). | ||
53 | * | ||
54 | */ | ||
55 | |||
56 | #include "ec_lcl.h" | ||
57 | #include <openssl/err.h> | ||
58 | |||
59 | int EC_GROUP_check(const EC_GROUP *group, BN_CTX *ctx) | ||
60 | { | ||
61 | int ret = 0; | ||
62 | BIGNUM *order; | ||
63 | BN_CTX *new_ctx = NULL; | ||
64 | EC_POINT *point = NULL; | ||
65 | |||
66 | if (ctx == NULL) | ||
67 | { | ||
68 | ctx = new_ctx = BN_CTX_new(); | ||
69 | if (ctx == NULL) | ||
70 | { | ||
71 | ECerr(EC_F_EC_GROUP_CHECK, ERR_R_MALLOC_FAILURE); | ||
72 | goto err; | ||
73 | } | ||
74 | } | ||
75 | BN_CTX_start(ctx); | ||
76 | if ((order = BN_CTX_get(ctx)) == NULL) goto err; | ||
77 | |||
78 | /* check the discriminant */ | ||
79 | if (!EC_GROUP_check_discriminant(group, ctx)) | ||
80 | { | ||
81 | ECerr(EC_F_EC_GROUP_CHECK, EC_R_DISCRIMINANT_IS_ZERO); | ||
82 | goto err; | ||
83 | } | ||
84 | |||
85 | /* check the generator */ | ||
86 | if (group->generator == NULL) | ||
87 | { | ||
88 | ECerr(EC_F_EC_GROUP_CHECK, EC_R_UNDEFINED_GENERATOR); | ||
89 | goto err; | ||
90 | } | ||
91 | if (!EC_POINT_is_on_curve(group, group->generator, ctx)) | ||
92 | { | ||
93 | ECerr(EC_F_EC_GROUP_CHECK, EC_R_POINT_IS_NOT_ON_CURVE); | ||
94 | goto err; | ||
95 | } | ||
96 | |||
97 | /* check the order of the generator */ | ||
98 | if ((point = EC_POINT_new(group)) == NULL) goto err; | ||
99 | if (!EC_GROUP_get_order(group, order, ctx)) goto err; | ||
100 | if (BN_is_zero(order)) | ||
101 | { | ||
102 | ECerr(EC_F_EC_GROUP_CHECK, EC_R_UNDEFINED_ORDER); | ||
103 | goto err; | ||
104 | } | ||
105 | |||
106 | if (!EC_POINT_mul(group, point, order, NULL, NULL, ctx)) goto err; | ||
107 | if (!EC_POINT_is_at_infinity(group, point)) | ||
108 | { | ||
109 | ECerr(EC_F_EC_GROUP_CHECK, EC_R_INVALID_GROUP_ORDER); | ||
110 | goto err; | ||
111 | } | ||
112 | |||
113 | ret = 1; | ||
114 | |||
115 | err: | ||
116 | if (ctx != NULL) | ||
117 | BN_CTX_end(ctx); | ||
118 | if (new_ctx != NULL) | ||
119 | BN_CTX_free(new_ctx); | ||
120 | if (point) | ||
121 | EC_POINT_free(point); | ||
122 | return ret; | ||
123 | } | ||
diff --git a/src/lib/libcrypto/ec/ec_curve.c b/src/lib/libcrypto/ec/ec_curve.c new file mode 100644 index 0000000000..beac20969b --- /dev/null +++ b/src/lib/libcrypto/ec/ec_curve.c | |||
@@ -0,0 +1,1270 @@ | |||
1 | /* crypto/ec/ec_curve.c */ | ||
2 | /* | ||
3 | * Written by Nils Larsch for the OpenSSL project. | ||
4 | */ | ||
5 | /* ==================================================================== | ||
6 | * Copyright (c) 1998-2004 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 | * openssl-core@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 | * This product includes cryptographic software written by Eric Young | ||
54 | * (eay@cryptsoft.com). This product includes software written by Tim | ||
55 | * Hudson (tjh@cryptsoft.com). | ||
56 | * | ||
57 | */ | ||
58 | /* ==================================================================== | ||
59 | * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. | ||
60 | * | ||
61 | * Portions of the attached software ("Contribution") are developed by | ||
62 | * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project. | ||
63 | * | ||
64 | * The Contribution is licensed pursuant to the OpenSSL open source | ||
65 | * license provided above. | ||
66 | * | ||
67 | * The elliptic curve binary polynomial software is originally written by | ||
68 | * Sheueling Chang Shantz and Douglas Stebila of Sun Microsystems Laboratories. | ||
69 | * | ||
70 | */ | ||
71 | |||
72 | #include "ec_lcl.h" | ||
73 | #include <openssl/err.h> | ||
74 | #include <openssl/obj_mac.h> | ||
75 | |||
76 | typedef struct ec_curve_data_st { | ||
77 | int field_type; /* either NID_X9_62_prime_field or | ||
78 | * NID_X9_62_characteristic_two_field */ | ||
79 | const char *p; /* either a prime number or a polynomial */ | ||
80 | const char *a; | ||
81 | const char *b; | ||
82 | const char *x; /* the x coordinate of the generator */ | ||
83 | const char *y; /* the y coordinate of the generator */ | ||
84 | const char *order; /* the order of the group generated by the | ||
85 | * generator */ | ||
86 | const BN_ULONG cofactor;/* the cofactor */ | ||
87 | const unsigned char *seed;/* the seed (optional) */ | ||
88 | size_t seed_len; | ||
89 | const char *comment; /* a short description of the curve */ | ||
90 | } EC_CURVE_DATA; | ||
91 | |||
92 | /* the nist prime curves */ | ||
93 | static const unsigned char _EC_NIST_PRIME_192_SEED[] = { | ||
94 | 0x30,0x45,0xAE,0x6F,0xC8,0x42,0x2F,0x64,0xED,0x57, | ||
95 | 0x95,0x28,0xD3,0x81,0x20,0xEA,0xE1,0x21,0x96,0xD5}; | ||
96 | static const EC_CURVE_DATA _EC_NIST_PRIME_192 = { | ||
97 | NID_X9_62_prime_field, | ||
98 | "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF", | ||
99 | "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC", | ||
100 | "64210519E59C80E70FA7E9AB72243049FEB8DEECC146B9B1", | ||
101 | "188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012", | ||
102 | "07192b95ffc8da78631011ed6b24cdd573f977a11e794811", | ||
103 | "FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831",1, | ||
104 | _EC_NIST_PRIME_192_SEED, 20, | ||
105 | "NIST/X9.62/SECG curve over a 192 bit prime field" | ||
106 | }; | ||
107 | |||
108 | static const unsigned char _EC_NIST_PRIME_224_SEED[] = { | ||
109 | 0xBD,0x71,0x34,0x47,0x99,0xD5,0xC7,0xFC,0xDC,0x45, | ||
110 | 0xB5,0x9F,0xA3,0xB9,0xAB,0x8F,0x6A,0x94,0x8B,0xC5}; | ||
111 | static const EC_CURVE_DATA _EC_NIST_PRIME_224 = { | ||
112 | NID_X9_62_prime_field, | ||
113 | "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001", | ||
114 | "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE", | ||
115 | "B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4", | ||
116 | "B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21", | ||
117 | "bd376388b5f723fb4c22dfe6cd4375a05a07476444d5819985007e34", | ||
118 | "FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D",1, | ||
119 | _EC_NIST_PRIME_224_SEED, 20, | ||
120 | "NIST/SECG curve over a 224 bit prime field" | ||
121 | }; | ||
122 | |||
123 | static const unsigned char _EC_NIST_PRIME_384_SEED[] = { | ||
124 | 0xA3,0x35,0x92,0x6A,0xA3,0x19,0xA2,0x7A,0x1D,0x00, | ||
125 | 0x89,0x6A,0x67,0x73,0xA4,0x82,0x7A,0xCD,0xAC,0x73}; | ||
126 | static const EC_CURVE_DATA _EC_NIST_PRIME_384 = { | ||
127 | NID_X9_62_prime_field, | ||
128 | "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFF" | ||
129 | "FFF0000000000000000FFFFFFFF", | ||
130 | "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFF" | ||
131 | "FFF0000000000000000FFFFFFFC", | ||
132 | "B3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE8141120314088F5013875AC6563" | ||
133 | "98D8A2ED19D2A85C8EDD3EC2AEF", | ||
134 | "AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B9859F741E082542A385502F" | ||
135 | "25DBF55296C3A545E3872760AB7", | ||
136 | "3617de4a96262c6f5d9e98bf9292dc29f8f41dbd289a147ce9da3113b5f0b8c00a60b" | ||
137 | "1ce1d7e819d7a431d7c90ea0e5f", | ||
138 | "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0" | ||
139 | "DB248B0A77AECEC196ACCC52973",1, | ||
140 | _EC_NIST_PRIME_384_SEED, 20, | ||
141 | "NIST/SECG curve over a 384 bit prime field" | ||
142 | }; | ||
143 | |||
144 | static const unsigned char _EC_NIST_PRIME_521_SEED[] = { | ||
145 | 0xD0,0x9E,0x88,0x00,0x29,0x1C,0xB8,0x53,0x96,0xCC, | ||
146 | 0x67,0x17,0x39,0x32,0x84,0xAA,0xA0,0xDA,0x64,0xBA}; | ||
147 | static const EC_CURVE_DATA _EC_NIST_PRIME_521 = { | ||
148 | NID_X9_62_prime_field, | ||
149 | "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" | ||
150 | "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", | ||
151 | "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" | ||
152 | "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC", | ||
153 | "051953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3B8B489918EF109E156" | ||
154 | "193951EC7E937B1652C0BD3BB1BF073573DF883D2C34F1EF451FD46B503F00", | ||
155 | "C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14" | ||
156 | "B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66", | ||
157 | "011839296a789a3bc0045c8a5fb42c7d1bd998f54449579b446817afbd17273e662c9" | ||
158 | "7ee72995ef42640c550b9013fad0761353c7086a272c24088be94769fd16650", | ||
159 | "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51" | ||
160 | "868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409",1, | ||
161 | _EC_NIST_PRIME_521_SEED, 20, | ||
162 | "NIST/SECG curve over a 521 bit prime field" | ||
163 | }; | ||
164 | /* the x9.62 prime curves (minus the nist prime curves) */ | ||
165 | static const unsigned char _EC_X9_62_PRIME_192V2_SEED[] = { | ||
166 | 0x31,0xA9,0x2E,0xE2,0x02,0x9F,0xD1,0x0D,0x90,0x1B, | ||
167 | 0x11,0x3E,0x99,0x07,0x10,0xF0,0xD2,0x1A,0xC6,0xB6}; | ||
168 | static const EC_CURVE_DATA _EC_X9_62_PRIME_192V2 = { | ||
169 | NID_X9_62_prime_field, | ||
170 | "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF", | ||
171 | "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC", | ||
172 | "CC22D6DFB95C6B25E49C0D6364A4E5980C393AA21668D953", | ||
173 | "EEA2BAE7E1497842F2DE7769CFE9C989C072AD696F48034A", | ||
174 | "6574d11d69b6ec7a672bb82a083df2f2b0847de970b2de15", | ||
175 | "FFFFFFFFFFFFFFFFFFFFFFFE5FB1A724DC80418648D8DD31",1, | ||
176 | _EC_X9_62_PRIME_192V2_SEED, 20, | ||
177 | "X9.62 curve over a 192 bit prime field" | ||
178 | }; | ||
179 | |||
180 | static const unsigned char _EC_X9_62_PRIME_192V3_SEED[] = { | ||
181 | 0xC4,0x69,0x68,0x44,0x35,0xDE,0xB3,0x78,0xC4,0xB6, | ||
182 | 0x5C,0xA9,0x59,0x1E,0x2A,0x57,0x63,0x05,0x9A,0x2E}; | ||
183 | static const EC_CURVE_DATA _EC_X9_62_PRIME_192V3 = { | ||
184 | NID_X9_62_prime_field, | ||
185 | "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF", | ||
186 | "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC", | ||
187 | "22123DC2395A05CAA7423DAECCC94760A7D462256BD56916", | ||
188 | "7D29778100C65A1DA1783716588DCE2B8B4AEE8E228F1896", | ||
189 | "38a90f22637337334b49dcb66a6dc8f9978aca7648a943b0", | ||
190 | "FFFFFFFFFFFFFFFFFFFFFFFF7A62D031C83F4294F640EC13",1, | ||
191 | _EC_X9_62_PRIME_192V3_SEED, 20, | ||
192 | "X9.62 curve over a 192 bit prime field" | ||
193 | }; | ||
194 | |||
195 | static const unsigned char _EC_X9_62_PRIME_239V1_SEED[] = { | ||
196 | 0xE4,0x3B,0xB4,0x60,0xF0,0xB8,0x0C,0xC0,0xC0,0xB0, | ||
197 | 0x75,0x79,0x8E,0x94,0x80,0x60,0xF8,0x32,0x1B,0x7D}; | ||
198 | static const EC_CURVE_DATA _EC_X9_62_PRIME_239V1 = { | ||
199 | NID_X9_62_prime_field, | ||
200 | "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF", | ||
201 | "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC", | ||
202 | "6B016C3BDCF18941D0D654921475CA71A9DB2FB27D1D37796185C2942C0A", | ||
203 | "0FFA963CDCA8816CCC33B8642BEDF905C3D358573D3F27FBBD3B3CB9AAAF", | ||
204 | "7debe8e4e90a5dae6e4054ca530ba04654b36818ce226b39fccb7b02f1ae", | ||
205 | "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFF9E5E9A9F5D9071FBD1522688909D0B",1, | ||
206 | _EC_X9_62_PRIME_239V1_SEED, 20, | ||
207 | "X9.62 curve over a 239 bit prime field" | ||
208 | }; | ||
209 | |||
210 | static const unsigned char _EC_X9_62_PRIME_239V2_SEED[] = { | ||
211 | 0xE8,0xB4,0x01,0x16,0x04,0x09,0x53,0x03,0xCA,0x3B, | ||
212 | 0x80,0x99,0x98,0x2B,0xE0,0x9F,0xCB,0x9A,0xE6,0x16}; | ||
213 | static const EC_CURVE_DATA _EC_X9_62_PRIME_239V2 = { | ||
214 | NID_X9_62_prime_field, | ||
215 | "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF", | ||
216 | "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC", | ||
217 | "617FAB6832576CBBFED50D99F0249C3FEE58B94BA0038C7AE84C8C832F2C", | ||
218 | "38AF09D98727705120C921BB5E9E26296A3CDCF2F35757A0EAFD87B830E7", | ||
219 | "5b0125e4dbea0ec7206da0fc01d9b081329fb555de6ef460237dff8be4ba", | ||
220 | "7FFFFFFFFFFFFFFFFFFFFFFF800000CFA7E8594377D414C03821BC582063",1, | ||
221 | _EC_X9_62_PRIME_239V2_SEED, 20, | ||
222 | "X9.62 curve over a 239 bit prime field" | ||
223 | }; | ||
224 | |||
225 | static const unsigned char _EC_X9_62_PRIME_239V3_SEED[] = { | ||
226 | 0x7D,0x73,0x74,0x16,0x8F,0xFE,0x34,0x71,0xB6,0x0A, | ||
227 | 0x85,0x76,0x86,0xA1,0x94,0x75,0xD3,0xBF,0xA2,0xFF}; | ||
228 | static const EC_CURVE_DATA _EC_X9_62_PRIME_239V3 = { | ||
229 | NID_X9_62_prime_field, | ||
230 | "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF", | ||
231 | "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC", | ||
232 | "255705FA2A306654B1F4CB03D6A750A30C250102D4988717D9BA15AB6D3E", | ||
233 | "6768AE8E18BB92CFCF005C949AA2C6D94853D0E660BBF854B1C9505FE95A", | ||
234 | "1607e6898f390c06bc1d552bad226f3b6fcfe48b6e818499af18e3ed6cf3", | ||
235 | "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFF975DEB41B3A6057C3C432146526551",1, | ||
236 | _EC_X9_62_PRIME_239V3_SEED, 20, | ||
237 | "X9.62 curve over a 239 bit prime field" | ||
238 | }; | ||
239 | |||
240 | static const unsigned char _EC_X9_62_PRIME_256V1_SEED[] = { | ||
241 | 0xC4,0x9D,0x36,0x08,0x86,0xE7,0x04,0x93,0x6A,0x66, | ||
242 | 0x78,0xE1,0x13,0x9D,0x26,0xB7,0x81,0x9F,0x7E,0x90}; | ||
243 | static const EC_CURVE_DATA _EC_X9_62_PRIME_256V1 = { | ||
244 | NID_X9_62_prime_field, | ||
245 | "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF", | ||
246 | "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC", | ||
247 | "5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B", | ||
248 | "6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296", | ||
249 | "4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5", | ||
250 | "FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551",1, | ||
251 | _EC_X9_62_PRIME_256V1_SEED, 20, | ||
252 | "X9.62/SECG curve over a 256 bit prime field" | ||
253 | }; | ||
254 | /* the secg prime curves (minus the nist and x9.62 prime curves) */ | ||
255 | static const unsigned char _EC_SECG_PRIME_112R1_SEED[] = { | ||
256 | 0x00,0xF5,0x0B,0x02,0x8E,0x4D,0x69,0x6E,0x67,0x68, | ||
257 | 0x75,0x61,0x51,0x75,0x29,0x04,0x72,0x78,0x3F,0xB1}; | ||
258 | static const EC_CURVE_DATA _EC_SECG_PRIME_112R1 = { | ||
259 | NID_X9_62_prime_field, | ||
260 | "DB7C2ABF62E35E668076BEAD208B", | ||
261 | "DB7C2ABF62E35E668076BEAD2088", | ||
262 | "659EF8BA043916EEDE8911702B22", | ||
263 | "09487239995A5EE76B55F9C2F098", | ||
264 | "a89ce5af8724c0a23e0e0ff77500", | ||
265 | "DB7C2ABF62E35E7628DFAC6561C5",1, | ||
266 | _EC_SECG_PRIME_112R1_SEED, 20, | ||
267 | "SECG/WTLS curve over a 112 bit prime field" | ||
268 | }; | ||
269 | |||
270 | static const unsigned char _EC_SECG_PRIME_112R2_SEED[] = { | ||
271 | 0x00,0x27,0x57,0xA1,0x11,0x4D,0x69,0x6E,0x67,0x68, | ||
272 | 0x75,0x61,0x51,0x75,0x53,0x16,0xC0,0x5E,0x0B,0xD4}; | ||
273 | static const EC_CURVE_DATA _EC_SECG_PRIME_112R2 = { | ||
274 | NID_X9_62_prime_field, | ||
275 | "DB7C2ABF62E35E668076BEAD208B", | ||
276 | "6127C24C05F38A0AAAF65C0EF02C", | ||
277 | "51DEF1815DB5ED74FCC34C85D709", | ||
278 | "4BA30AB5E892B4E1649DD0928643", | ||
279 | "adcd46f5882e3747def36e956e97", | ||
280 | "36DF0AAFD8B8D7597CA10520D04B",4, | ||
281 | _EC_SECG_PRIME_112R2_SEED, 20, | ||
282 | "SECG curve over a 112 bit prime field" | ||
283 | }; | ||
284 | |||
285 | static const unsigned char _EC_SECG_PRIME_128R1_SEED[] = { | ||
286 | 0x00,0x0E,0x0D,0x4D,0x69,0x6E,0x67,0x68,0x75,0x61, | ||
287 | 0x51,0x75,0x0C,0xC0,0x3A,0x44,0x73,0xD0,0x36,0x79}; | ||
288 | static const EC_CURVE_DATA _EC_SECG_PRIME_128R1 = { | ||
289 | NID_X9_62_prime_field, | ||
290 | "FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF", | ||
291 | "FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFC", | ||
292 | "E87579C11079F43DD824993C2CEE5ED3", | ||
293 | "161FF7528B899B2D0C28607CA52C5B86", | ||
294 | "cf5ac8395bafeb13c02da292dded7a83", | ||
295 | "FFFFFFFE0000000075A30D1B9038A115",1, | ||
296 | _EC_SECG_PRIME_128R1_SEED, 20, | ||
297 | "SECG curve over a 128 bit prime field" | ||
298 | }; | ||
299 | |||
300 | static const unsigned char _EC_SECG_PRIME_128R2_SEED[] = { | ||
301 | 0x00,0x4D,0x69,0x6E,0x67,0x68,0x75,0x61,0x51,0x75, | ||
302 | 0x12,0xD8,0xF0,0x34,0x31,0xFC,0xE6,0x3B,0x88,0xF4}; | ||
303 | static const EC_CURVE_DATA _EC_SECG_PRIME_128R2 = { | ||
304 | NID_X9_62_prime_field, | ||
305 | "FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF", | ||
306 | "D6031998D1B3BBFEBF59CC9BBFF9AEE1", | ||
307 | "5EEEFCA380D02919DC2C6558BB6D8A5D", | ||
308 | "7B6AA5D85E572983E6FB32A7CDEBC140", | ||
309 | "27b6916a894d3aee7106fe805fc34b44", | ||
310 | "3FFFFFFF7FFFFFFFBE0024720613B5A3",4, | ||
311 | _EC_SECG_PRIME_128R2_SEED, 20, | ||
312 | "SECG curve over a 128 bit prime field" | ||
313 | }; | ||
314 | |||
315 | static const EC_CURVE_DATA _EC_SECG_PRIME_160K1 = { | ||
316 | NID_X9_62_prime_field, | ||
317 | "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73", | ||
318 | "0", | ||
319 | "7", | ||
320 | "3B4C382CE37AA192A4019E763036F4F5DD4D7EBB", | ||
321 | "938cf935318fdced6bc28286531733c3f03c4fee", | ||
322 | "0100000000000000000001B8FA16DFAB9ACA16B6B3",1, | ||
323 | NULL, 0, | ||
324 | "SECG curve over a 160 bit prime field" | ||
325 | }; | ||
326 | |||
327 | static const unsigned char _EC_SECG_PRIME_160R1_SEED[] = { | ||
328 | 0x10,0x53,0xCD,0xE4,0x2C,0x14,0xD6,0x96,0xE6,0x76, | ||
329 | 0x87,0x56,0x15,0x17,0x53,0x3B,0xF3,0xF8,0x33,0x45}; | ||
330 | static const EC_CURVE_DATA _EC_SECG_PRIME_160R1 = { | ||
331 | NID_X9_62_prime_field, | ||
332 | "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF", | ||
333 | "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFC", | ||
334 | "1C97BEFC54BD7A8B65ACF89F81D4D4ADC565FA45", | ||
335 | "4A96B5688EF573284664698968C38BB913CBFC82", | ||
336 | "23a628553168947d59dcc912042351377ac5fb32", | ||
337 | "0100000000000000000001F4C8F927AED3CA752257",1, | ||
338 | _EC_SECG_PRIME_160R1_SEED, 20, | ||
339 | "SECG curve over a 160 bit prime field" | ||
340 | }; | ||
341 | |||
342 | static const unsigned char _EC_SECG_PRIME_160R2_SEED[] = { | ||
343 | 0xB9,0x9B,0x99,0xB0,0x99,0xB3,0x23,0xE0,0x27,0x09, | ||
344 | 0xA4,0xD6,0x96,0xE6,0x76,0x87,0x56,0x15,0x17,0x51}; | ||
345 | static const EC_CURVE_DATA _EC_SECG_PRIME_160R2 = { | ||
346 | NID_X9_62_prime_field, | ||
347 | "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73", | ||
348 | "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC70", | ||
349 | "B4E134D3FB59EB8BAB57274904664D5AF50388BA", | ||
350 | "52DCB034293A117E1F4FF11B30F7199D3144CE6D", | ||
351 | "feaffef2e331f296e071fa0df9982cfea7d43f2e", | ||
352 | "0100000000000000000000351EE786A818F3A1A16B",1, | ||
353 | _EC_SECG_PRIME_160R2_SEED, 20, | ||
354 | "SECG/WTLS curve over a 160 bit prime field" | ||
355 | }; | ||
356 | |||
357 | static const EC_CURVE_DATA _EC_SECG_PRIME_192K1 = { | ||
358 | NID_X9_62_prime_field, | ||
359 | "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFEE37", | ||
360 | "0", | ||
361 | "3", | ||
362 | "DB4FF10EC057E9AE26B07D0280B7F4341DA5D1B1EAE06C7D", | ||
363 | "9b2f2f6d9c5628a7844163d015be86344082aa88d95e2f9d", | ||
364 | "FFFFFFFFFFFFFFFFFFFFFFFE26F2FC170F69466A74DEFD8D",1, | ||
365 | NULL, 20, | ||
366 | "SECG curve over a 192 bit prime field" | ||
367 | }; | ||
368 | |||
369 | static const EC_CURVE_DATA _EC_SECG_PRIME_224K1 = { | ||
370 | NID_X9_62_prime_field, | ||
371 | "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFE56D", | ||
372 | "0", | ||
373 | "5", | ||
374 | "A1455B334DF099DF30FC28A169A467E9E47075A90F7E650EB6B7A45C", | ||
375 | "7e089fed7fba344282cafbd6f7e319f7c0b0bd59e2ca4bdb556d61a5", | ||
376 | "010000000000000000000000000001DCE8D2EC6184CAF0A971769FB1F7",1, | ||
377 | NULL, 20, | ||
378 | "SECG curve over a 224 bit prime field" | ||
379 | }; | ||
380 | |||
381 | static const EC_CURVE_DATA _EC_SECG_PRIME_256K1 = { | ||
382 | NID_X9_62_prime_field, | ||
383 | "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F", | ||
384 | "0", | ||
385 | "7", | ||
386 | "79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798", | ||
387 | "483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8", | ||
388 | "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141",1, | ||
389 | NULL, 20, | ||
390 | "SECG curve over a 256 bit prime field" | ||
391 | }; | ||
392 | |||
393 | /* some wap/wtls curves */ | ||
394 | static const EC_CURVE_DATA _EC_WTLS_8 = { | ||
395 | NID_X9_62_prime_field, | ||
396 | "FFFFFFFFFFFFFFFFFFFFFFFFFDE7", | ||
397 | "0", | ||
398 | "3", | ||
399 | "1", | ||
400 | "2", | ||
401 | "0100000000000001ECEA551AD837E9",1, | ||
402 | NULL, 20, | ||
403 | "WTLS curve over a 112 bit prime field" | ||
404 | }; | ||
405 | |||
406 | static const EC_CURVE_DATA _EC_WTLS_9 = { | ||
407 | NID_X9_62_prime_field, | ||
408 | "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC808F", | ||
409 | "0", | ||
410 | "3", | ||
411 | "1", | ||
412 | "2", | ||
413 | "0100000000000000000001CDC98AE0E2DE574ABF33",1, | ||
414 | NULL, 20, | ||
415 | "WTLS curve over a 160 bit prime field" | ||
416 | }; | ||
417 | |||
418 | static const EC_CURVE_DATA _EC_WTLS_12 = { | ||
419 | NID_X9_62_prime_field, | ||
420 | "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001", | ||
421 | "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE", | ||
422 | "B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4", | ||
423 | "B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21", | ||
424 | "bd376388b5f723fb4c22dfe6cd4375a05a07476444d5819985007e34", | ||
425 | "FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D", 1, | ||
426 | NULL, 0, | ||
427 | "WTLS curvs over a 224 bit prime field" | ||
428 | }; | ||
429 | |||
430 | /* characteristic two curves */ | ||
431 | static const unsigned char _EC_SECG_CHAR2_113R1_SEED[] = { | ||
432 | 0x10,0xE7,0x23,0xAB,0x14,0xD6,0x96,0xE6,0x76,0x87, | ||
433 | 0x56,0x15,0x17,0x56,0xFE,0xBF,0x8F,0xCB,0x49,0xA9}; | ||
434 | static const EC_CURVE_DATA _EC_SECG_CHAR2_113R1 = { | ||
435 | NID_X9_62_characteristic_two_field, | ||
436 | "020000000000000000000000000201", | ||
437 | "003088250CA6E7C7FE649CE85820F7", | ||
438 | "00E8BEE4D3E2260744188BE0E9C723", | ||
439 | "009D73616F35F4AB1407D73562C10F", | ||
440 | "00A52830277958EE84D1315ED31886", | ||
441 | "0100000000000000D9CCEC8A39E56F", 2, | ||
442 | _EC_SECG_CHAR2_113R1_SEED, 20, | ||
443 | "SECG curve over a 113 bit binary field" | ||
444 | }; | ||
445 | |||
446 | static const unsigned char _EC_SECG_CHAR2_113R2_SEED[] = { | ||
447 | 0x10,0xC0,0xFB,0x15,0x76,0x08,0x60,0xDE,0xF1,0xEE, | ||
448 | 0xF4,0xD6,0x96,0xE6,0x76,0x87,0x56,0x15,0x17,0x5D}; | ||
449 | static const EC_CURVE_DATA _EC_SECG_CHAR2_113R2 = { | ||
450 | NID_X9_62_characteristic_two_field, | ||
451 | "020000000000000000000000000201", | ||
452 | "00689918DBEC7E5A0DD6DFC0AA55C7", | ||
453 | "0095E9A9EC9B297BD4BF36E059184F", | ||
454 | "01A57A6A7B26CA5EF52FCDB8164797", | ||
455 | "00B3ADC94ED1FE674C06E695BABA1D", | ||
456 | "010000000000000108789B2496AF93", 2, | ||
457 | _EC_SECG_CHAR2_113R2_SEED, 20, | ||
458 | "SECG curve over a 113 bit binary field" | ||
459 | }; | ||
460 | |||
461 | static const unsigned char _EC_SECG_CHAR2_131R1_SEED[] = { | ||
462 | 0x4D,0x69,0x6E,0x67,0x68,0x75,0x61,0x51,0x75,0x98, | ||
463 | 0x5B,0xD3,0xAD,0xBA,0xDA,0x21,0xB4,0x3A,0x97,0xE2}; | ||
464 | static const EC_CURVE_DATA _EC_SECG_CHAR2_131R1 = { | ||
465 | NID_X9_62_characteristic_two_field, | ||
466 | "080000000000000000000000000000010D", | ||
467 | "07A11B09A76B562144418FF3FF8C2570B8", | ||
468 | "0217C05610884B63B9C6C7291678F9D341", | ||
469 | "0081BAF91FDF9833C40F9C181343638399", | ||
470 | "078C6E7EA38C001F73C8134B1B4EF9E150", | ||
471 | "0400000000000000023123953A9464B54D", 2, | ||
472 | _EC_SECG_CHAR2_131R1_SEED, 20, | ||
473 | "SECG/WTLS curve over a 131 bit binary field" | ||
474 | }; | ||
475 | |||
476 | static const unsigned char _EC_SECG_CHAR2_131R2_SEED[] = { | ||
477 | 0x98,0x5B,0xD3,0xAD,0xBA,0xD4,0xD6,0x96,0xE6,0x76, | ||
478 | 0x87,0x56,0x15,0x17,0x5A,0x21,0xB4,0x3A,0x97,0xE3}; | ||
479 | static const EC_CURVE_DATA _EC_SECG_CHAR2_131R2 = { | ||
480 | NID_X9_62_characteristic_two_field, | ||
481 | "080000000000000000000000000000010D", | ||
482 | "03E5A88919D7CAFCBF415F07C2176573B2", | ||
483 | "04B8266A46C55657AC734CE38F018F2192", | ||
484 | "0356DCD8F2F95031AD652D23951BB366A8", | ||
485 | "0648F06D867940A5366D9E265DE9EB240F", | ||
486 | "0400000000000000016954A233049BA98F", 2, | ||
487 | _EC_SECG_CHAR2_131R2_SEED, 20, | ||
488 | "SECG curve over a 131 bit binary field" | ||
489 | }; | ||
490 | |||
491 | static const EC_CURVE_DATA _EC_NIST_CHAR2_163K = { | ||
492 | NID_X9_62_characteristic_two_field, | ||
493 | "0800000000000000000000000000000000000000C9", | ||
494 | "1", | ||
495 | "1", | ||
496 | "02FE13C0537BBC11ACAA07D793DE4E6D5E5C94EEE8", | ||
497 | "0289070FB05D38FF58321F2E800536D538CCDAA3D9", | ||
498 | "04000000000000000000020108A2E0CC0D99F8A5EF", 2, | ||
499 | NULL, 0, | ||
500 | "NIST/SECG/WTLS curve over a 163 bit binary field" | ||
501 | }; | ||
502 | |||
503 | static const unsigned char _EC_SECG_CHAR2_163R1_SEED[] = { | ||
504 | 0x24,0xB7,0xB1,0x37,0xC8,0xA1,0x4D,0x69,0x6E,0x67, | ||
505 | 0x68,0x75,0x61,0x51,0x75,0x6F,0xD0,0xDA,0x2E,0x5C}; | ||
506 | static const EC_CURVE_DATA _EC_SECG_CHAR2_163R1 = { | ||
507 | NID_X9_62_characteristic_two_field, | ||
508 | "0800000000000000000000000000000000000000C9", | ||
509 | "07B6882CAAEFA84F9554FF8428BD88E246D2782AE2", | ||
510 | "0713612DCDDCB40AAB946BDA29CA91F73AF958AFD9", | ||
511 | "0369979697AB43897789566789567F787A7876A654", | ||
512 | "00435EDB42EFAFB2989D51FEFCE3C80988F41FF883", | ||
513 | "03FFFFFFFFFFFFFFFFFFFF48AAB689C29CA710279B", 2, | ||
514 | /* The algorithm used to derive the curve parameters from | ||
515 | * the seed used here is slightly different than the | ||
516 | * algorithm described in X9.62 . | ||
517 | */ | ||
518 | #if 0 | ||
519 | _EC_SECG_CHAR2_163R1_SEED, 20, | ||
520 | #else | ||
521 | NULL, 0, | ||
522 | #endif | ||
523 | "SECG curve over a 163 bit binary field" | ||
524 | }; | ||
525 | |||
526 | static const unsigned char _EC_NIST_CHAR2_163B_SEED[] = { | ||
527 | 0x85,0xE2,0x5B,0xFE,0x5C,0x86,0x22,0x6C,0xDB,0x12, | ||
528 | 0x01,0x6F,0x75,0x53,0xF9,0xD0,0xE6,0x93,0xA2,0x68}; | ||
529 | static const EC_CURVE_DATA _EC_NIST_CHAR2_163B ={ | ||
530 | NID_X9_62_characteristic_two_field, | ||
531 | "0800000000000000000000000000000000000000C9", | ||
532 | "1", | ||
533 | "020A601907B8C953CA1481EB10512F78744A3205FD", | ||
534 | "03F0EBA16286A2D57EA0991168D4994637E8343E36", | ||
535 | "00D51FBC6C71A0094FA2CDD545B11C5C0C797324F1", | ||
536 | "040000000000000000000292FE77E70C12A4234C33", 2, | ||
537 | /* The seed here was used to created the curve parameters in normal | ||
538 | * basis representation (and not the polynomial representation used here) | ||
539 | */ | ||
540 | #if 0 | ||
541 | _EC_NIST_CHAR2_163B_SEED, 20, | ||
542 | #else | ||
543 | NULL, 0, | ||
544 | #endif | ||
545 | "NIST/SECG curve over a 163 bit binary field" | ||
546 | }; | ||
547 | |||
548 | static const unsigned char _EC_SECG_CHAR2_193R1_SEED[] = { | ||
549 | 0x10,0x3F,0xAE,0xC7,0x4D,0x69,0x6E,0x67,0x68,0x75, | ||
550 | 0x61,0x51,0x75,0x77,0x7F,0xC5,0xB1,0x91,0xEF,0x30}; | ||
551 | static const EC_CURVE_DATA _EC_SECG_CHAR2_193R1 = { | ||
552 | NID_X9_62_characteristic_two_field, | ||
553 | "02000000000000000000000000000000000000000000008001", | ||
554 | "0017858FEB7A98975169E171F77B4087DE098AC8A911DF7B01", | ||
555 | "00FDFB49BFE6C3A89FACADAA7A1E5BBC7CC1C2E5D831478814", | ||
556 | "01F481BC5F0FF84A74AD6CDF6FDEF4BF6179625372D8C0C5E1", | ||
557 | "0025E399F2903712CCF3EA9E3A1AD17FB0B3201B6AF7CE1B05", | ||
558 | "01000000000000000000000000C7F34A778F443ACC920EBA49", 2, | ||
559 | _EC_SECG_CHAR2_193R1_SEED, 20, | ||
560 | "SECG curve over a 193 bit binary field" | ||
561 | }; | ||
562 | |||
563 | static const unsigned char _EC_SECG_CHAR2_193R2_SEED[] = { | ||
564 | 0x10,0xB7,0xB4,0xD6,0x96,0xE6,0x76,0x87,0x56,0x15, | ||
565 | 0x17,0x51,0x37,0xC8,0xA1,0x6F,0xD0,0xDA,0x22,0x11}; | ||
566 | static const EC_CURVE_DATA _EC_SECG_CHAR2_193R2 = { | ||
567 | NID_X9_62_characteristic_two_field, | ||
568 | "02000000000000000000000000000000000000000000008001", | ||
569 | "0163F35A5137C2CE3EA6ED8667190B0BC43ECD69977702709B", | ||
570 | "00C9BB9E8927D4D64C377E2AB2856A5B16E3EFB7F61D4316AE", | ||
571 | "00D9B67D192E0367C803F39E1A7E82CA14A651350AAE617E8F", | ||
572 | "01CE94335607C304AC29E7DEFBD9CA01F596F927224CDECF6C", | ||
573 | "010000000000000000000000015AAB561B005413CCD4EE99D5", 2, | ||
574 | _EC_SECG_CHAR2_193R2_SEED, 20, | ||
575 | "SECG curve over a 193 bit binary field" | ||
576 | }; | ||
577 | |||
578 | static const EC_CURVE_DATA _EC_NIST_CHAR2_233K = { | ||
579 | NID_X9_62_characteristic_two_field, | ||
580 | "020000000000000000000000000000000000000004000000000000000001", | ||
581 | "0", | ||
582 | "1", | ||
583 | "017232BA853A7E731AF129F22FF4149563A419C26BF50A4C9D6EEFAD6126", | ||
584 | "01DB537DECE819B7F70F555A67C427A8CD9BF18AEB9B56E0C11056FAE6A3", | ||
585 | "008000000000000000000000000000069D5BB915BCD46EFB1AD5F173ABDF", 4, | ||
586 | NULL, 0, | ||
587 | "NIST/SECG/WTLS curve over a 233 bit binary field" | ||
588 | }; | ||
589 | |||
590 | static const unsigned char _EC_NIST_CHAR2_233B_SEED[] = { | ||
591 | 0x74,0xD5,0x9F,0xF0,0x7F,0x6B,0x41,0x3D,0x0E,0xA1, | ||
592 | 0x4B,0x34,0x4B,0x20,0xA2,0xDB,0x04,0x9B,0x50,0xC3}; | ||
593 | static const EC_CURVE_DATA _EC_NIST_CHAR2_233B = { | ||
594 | NID_X9_62_characteristic_two_field, | ||
595 | "020000000000000000000000000000000000000004000000000000000001", | ||
596 | "000000000000000000000000000000000000000000000000000000000001", | ||
597 | "0066647EDE6C332C7F8C0923BB58213B333B20E9CE4281FE115F7D8F90AD", | ||
598 | "00FAC9DFCBAC8313BB2139F1BB755FEF65BC391F8B36F8F8EB7371FD558B", | ||
599 | "01006A08A41903350678E58528BEBF8A0BEFF867A7CA36716F7E01F81052", | ||
600 | "01000000000000000000000000000013E974E72F8A6922031D2603CFE0D7", 2, | ||
601 | _EC_NIST_CHAR2_233B_SEED, 20, | ||
602 | "NIST/SECG/WTLS curve over a 233 bit binary field" | ||
603 | }; | ||
604 | |||
605 | static const EC_CURVE_DATA _EC_SECG_CHAR2_239K1 = { | ||
606 | NID_X9_62_characteristic_two_field, | ||
607 | "800000000000000000004000000000000000000000000000000000000001", | ||
608 | "0", | ||
609 | "1", | ||
610 | "29A0B6A887A983E9730988A68727A8B2D126C44CC2CC7B2A6555193035DC", | ||
611 | "76310804F12E549BDB011C103089E73510ACB275FC312A5DC6B76553F0CA", | ||
612 | "2000000000000000000000000000005A79FEC67CB6E91F1C1DA800E478A5", 4, | ||
613 | NULL, 0, | ||
614 | "SECG curve over a 239 bit binary field" | ||
615 | }; | ||
616 | |||
617 | static const EC_CURVE_DATA _EC_NIST_CHAR2_283K = { | ||
618 | NID_X9_62_characteristic_two_field, | ||
619 | "080000000000000000000000000000000000000000000000000000000000000000001" | ||
620 | "0A1", | ||
621 | "0", | ||
622 | "1", | ||
623 | "0503213F78CA44883F1A3B8162F188E553CD265F23C1567A16876913B0C2AC2458492" | ||
624 | "836", | ||
625 | "01CCDA380F1C9E318D90F95D07E5426FE87E45C0E8184698E45962364E34116177DD2" | ||
626 | "259", | ||
627 | "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9AE2ED07577265DFF7F94451E061E163" | ||
628 | "C61", 4, | ||
629 | NULL, 20, | ||
630 | "NIST/SECG curve over a 283 bit binary field" | ||
631 | }; | ||
632 | |||
633 | static const unsigned char _EC_NIST_CHAR2_283B_SEED[] = { | ||
634 | 0x77,0xE2,0xB0,0x73,0x70,0xEB,0x0F,0x83,0x2A,0x6D, | ||
635 | 0xD5,0xB6,0x2D,0xFC,0x88,0xCD,0x06,0xBB,0x84,0xBE}; | ||
636 | static const EC_CURVE_DATA _EC_NIST_CHAR2_283B = { | ||
637 | NID_X9_62_characteristic_two_field, | ||
638 | "080000000000000000000000000000000000000000000000000000000000000000001" | ||
639 | "0A1", | ||
640 | "000000000000000000000000000000000000000000000000000000000000000000000" | ||
641 | "001", | ||
642 | "027B680AC8B8596DA5A4AF8A19A0303FCA97FD7645309FA2A581485AF6263E313B79A" | ||
643 | "2F5", | ||
644 | "05F939258DB7DD90E1934F8C70B0DFEC2EED25B8557EAC9C80E2E198F8CDBECD86B12" | ||
645 | "053", | ||
646 | "03676854FE24141CB98FE6D4B20D02B4516FF702350EDDB0826779C813F0DF45BE811" | ||
647 | "2F4", | ||
648 | "03FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF90399660FC938A90165B042A7CEFADB" | ||
649 | "307", 2, | ||
650 | _EC_NIST_CHAR2_283B_SEED, 20, | ||
651 | "NIST/SECG curve over a 283 bit binary field" | ||
652 | }; | ||
653 | |||
654 | static const EC_CURVE_DATA _EC_NIST_CHAR2_409K = { | ||
655 | NID_X9_62_characteristic_two_field, | ||
656 | "020000000000000000000000000000000000000000000000000000000000000000000" | ||
657 | "00000000000008000000000000000000001", | ||
658 | "0", | ||
659 | "1", | ||
660 | "0060F05F658F49C1AD3AB1890F7184210EFD0987E307C84C27ACCFB8F9F67CC2C4601" | ||
661 | "89EB5AAAA62EE222EB1B35540CFE9023746", | ||
662 | "01E369050B7C4E42ACBA1DACBF04299C3460782F918EA427E6325165E9EA10E3DA5F6" | ||
663 | "C42E9C55215AA9CA27A5863EC48D8E0286B", | ||
664 | "007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5F83B2D4EA20400" | ||
665 | "EC4557D5ED3E3E7CA5B4B5C83B8E01E5FCF", 4, | ||
666 | NULL, 0, | ||
667 | "NIST/SECG curve over a 409 bit binary field" | ||
668 | }; | ||
669 | |||
670 | static const unsigned char _EC_NIST_CHAR2_409B_SEED[] = { | ||
671 | 0x40,0x99,0xB5,0xA4,0x57,0xF9,0xD6,0x9F,0x79,0x21, | ||
672 | 0x3D,0x09,0x4C,0x4B,0xCD,0x4D,0x42,0x62,0x21,0x0B}; | ||
673 | static const EC_CURVE_DATA _EC_NIST_CHAR2_409B = { | ||
674 | NID_X9_62_characteristic_two_field, | ||
675 | "020000000000000000000000000000000000000000000000000000000000000000000" | ||
676 | "00000000000008000000000000000000001", | ||
677 | "000000000000000000000000000000000000000000000000000000000000000000000" | ||
678 | "00000000000000000000000000000000001", | ||
679 | "0021A5C2C8EE9FEB5C4B9A753B7B476B7FD6422EF1F3DD674761FA99D6AC27C8A9A19" | ||
680 | "7B272822F6CD57A55AA4F50AE317B13545F", | ||
681 | "015D4860D088DDB3496B0C6064756260441CDE4AF1771D4DB01FFE5B34E59703DC255" | ||
682 | "A868A1180515603AEAB60794E54BB7996A7", | ||
683 | "0061B1CFAB6BE5F32BBFA78324ED106A7636B9C5A7BD198D0158AA4F5488D08F38514" | ||
684 | "F1FDF4B4F40D2181B3681C364BA0273C706", | ||
685 | "010000000000000000000000000000000000000000000000000001E2AAD6A612F3330" | ||
686 | "7BE5FA47C3C9E052F838164CD37D9A21173", 2, | ||
687 | _EC_NIST_CHAR2_409B_SEED, 20, | ||
688 | "NIST/SECG curve over a 409 bit binary field" | ||
689 | }; | ||
690 | |||
691 | static const EC_CURVE_DATA _EC_NIST_CHAR2_571K = { | ||
692 | NID_X9_62_characteristic_two_field, | ||
693 | "800000000000000000000000000000000000000000000000000000000000000000000" | ||
694 | "000000000000000000000000000000000000000000000000000000000000000000000" | ||
695 | "00425", | ||
696 | "0", | ||
697 | "1", | ||
698 | "026EB7A859923FBC82189631F8103FE4AC9CA2970012D5D46024804801841CA443709" | ||
699 | "58493B205E647DA304DB4CEB08CBBD1BA39494776FB988B47174DCA88C7E2945283A0" | ||
700 | "1C8972", | ||
701 | "0349DC807F4FBF374F4AEADE3BCA95314DD58CEC9F307A54FFC61EFC006D8A2C9D497" | ||
702 | "9C0AC44AEA74FBEBBB9F772AEDCB620B01A7BA7AF1B320430C8591984F601CD4C143E" | ||
703 | "F1C7A3", | ||
704 | "020000000000000000000000000000000000000000000000000000000000000000000" | ||
705 | "000131850E1F19A63E4B391A8DB917F4138B630D84BE5D639381E91DEB45CFE778F63" | ||
706 | "7C1001", 4, | ||
707 | NULL, 0, | ||
708 | "NIST/SECG curve over a 571 bit binary field" | ||
709 | }; | ||
710 | |||
711 | static const unsigned char _EC_NIST_CHAR2_571B_SEED[] = { | ||
712 | 0x2A,0xA0,0x58,0xF7,0x3A,0x0E,0x33,0xAB,0x48,0x6B, | ||
713 | 0x0F,0x61,0x04,0x10,0xC5,0x3A,0x7F,0x13,0x23,0x10}; | ||
714 | static const EC_CURVE_DATA _EC_NIST_CHAR2_571B = { | ||
715 | NID_X9_62_characteristic_two_field, | ||
716 | "800000000000000000000000000000000000000000000000000000000000000000000" | ||
717 | "000000000000000000000000000000000000000000000000000000000000000000000" | ||
718 | "00425", | ||
719 | "000000000000000000000000000000000000000000000000000000000000000000000" | ||
720 | "000000000000000000000000000000000000000000000000000000000000000000000" | ||
721 | "000001", | ||
722 | "02F40E7E2221F295DE297117B7F3D62F5C6A97FFCB8CEFF1CD6BA8CE4A9A18AD84FFA" | ||
723 | "BBD8EFA59332BE7AD6756A66E294AFD185A78FF12AA520E4DE739BACA0C7FFEFF7F29" | ||
724 | "55727A", | ||
725 | "0303001D34B856296C16C0D40D3CD7750A93D1D2955FA80AA5F40FC8DB7B2ABDBDE53" | ||
726 | "950F4C0D293CDD711A35B67FB1499AE60038614F1394ABFA3B4C850D927E1E7769C8E" | ||
727 | "EC2D19", | ||
728 | "037BF27342DA639B6DCCFFFEB73D69D78C6C27A6009CBBCA1980F8533921E8A684423" | ||
729 | "E43BAB08A576291AF8F461BB2A8B3531D2F0485C19B16E2F1516E23DD3C1A4827AF1B" | ||
730 | "8AC15B", | ||
731 | "03FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" | ||
732 | "FFFE661CE18FF55987308059B186823851EC7DD9CA1161DE93D5174D66E8382E9BB2F" | ||
733 | "E84E47", 2, | ||
734 | _EC_NIST_CHAR2_571B_SEED, 20, | ||
735 | "NIST/SECG curve over a 571 bit binary field" | ||
736 | }; | ||
737 | |||
738 | static const unsigned char _EC_X9_62_CHAR2_163V1_SEED[] = { | ||
739 | 0xD2,0xC0,0xFB,0x15,0x76,0x08,0x60,0xDE,0xF1,0xEE, | ||
740 | 0xF4,0xD6,0x96,0xE6,0x76,0x87,0x56,0x15,0x17,0x54}; | ||
741 | static const EC_CURVE_DATA _EC_X9_62_CHAR2_163V1 = { | ||
742 | NID_X9_62_characteristic_two_field, | ||
743 | "080000000000000000000000000000000000000107", | ||
744 | "072546B5435234A422E0789675F432C89435DE5242", | ||
745 | "00C9517D06D5240D3CFF38C74B20B6CD4D6F9DD4D9", | ||
746 | "07AF69989546103D79329FCC3D74880F33BBE803CB", | ||
747 | "01EC23211B5966ADEA1D3F87F7EA5848AEF0B7CA9F", | ||
748 | "0400000000000000000001E60FC8821CC74DAEAFC1", 2, | ||
749 | _EC_X9_62_CHAR2_163V1_SEED, 20, | ||
750 | "X9.62 curve over a 163 bit binary field" | ||
751 | }; | ||
752 | |||
753 | static const unsigned char _EC_X9_62_CHAR2_163V2_SEED[] = { | ||
754 | 0x53,0x81,0x4C,0x05,0x0D,0x44,0xD6,0x96,0xE6,0x76, | ||
755 | 0x87,0x56,0x15,0x17,0x58,0x0C,0xA4,0xE2,0x9F,0xFD}; | ||
756 | static const EC_CURVE_DATA _EC_X9_62_CHAR2_163V2 = { | ||
757 | NID_X9_62_characteristic_two_field, | ||
758 | "080000000000000000000000000000000000000107", | ||
759 | "0108B39E77C4B108BED981ED0E890E117C511CF072", | ||
760 | "0667ACEB38AF4E488C407433FFAE4F1C811638DF20", | ||
761 | "0024266E4EB5106D0A964D92C4860E2671DB9B6CC5", | ||
762 | "079F684DDF6684C5CD258B3890021B2386DFD19FC5", | ||
763 | "03FFFFFFFFFFFFFFFFFFFDF64DE1151ADBB78F10A7", 2, | ||
764 | _EC_X9_62_CHAR2_163V2_SEED, 20, | ||
765 | "X9.62 curve over a 163 bit binary field" | ||
766 | }; | ||
767 | |||
768 | static const unsigned char _EC_X9_62_CHAR2_163V3_SEED[] = { | ||
769 | 0x50,0xCB,0xF1,0xD9,0x5C,0xA9,0x4D,0x69,0x6E,0x67, | ||
770 | 0x68,0x75,0x61,0x51,0x75,0xF1,0x6A,0x36,0xA3,0xB8}; | ||
771 | static const EC_CURVE_DATA _EC_X9_62_CHAR2_163V3 = { | ||
772 | NID_X9_62_characteristic_two_field, | ||
773 | "080000000000000000000000000000000000000107", | ||
774 | "07A526C63D3E25A256A007699F5447E32AE456B50E", | ||
775 | "03F7061798EB99E238FD6F1BF95B48FEEB4854252B", | ||
776 | "02F9F87B7C574D0BDECF8A22E6524775F98CDEBDCB", | ||
777 | "05B935590C155E17EA48EB3FF3718B893DF59A05D0", | ||
778 | "03FFFFFFFFFFFFFFFFFFFE1AEE140F110AFF961309", 2, | ||
779 | _EC_X9_62_CHAR2_163V3_SEED, 20, | ||
780 | "X9.62 curve over a 163 bit binary field" | ||
781 | }; | ||
782 | |||
783 | static const EC_CURVE_DATA _EC_X9_62_CHAR2_176V1 = { | ||
784 | NID_X9_62_characteristic_two_field, | ||
785 | "0100000000000000000000000000000000080000000007", | ||
786 | "E4E6DB2995065C407D9D39B8D0967B96704BA8E9C90B", | ||
787 | "5DDA470ABE6414DE8EC133AE28E9BBD7FCEC0AE0FFF2", | ||
788 | "8D16C2866798B600F9F08BB4A8E860F3298CE04A5798", | ||
789 | "6FA4539C2DADDDD6BAB5167D61B436E1D92BB16A562C", | ||
790 | "00010092537397ECA4F6145799D62B0A19CE06FE26AD", 0xFF6E, | ||
791 | NULL, 0, | ||
792 | "X9.62 curve over a 176 bit binary field" | ||
793 | }; | ||
794 | |||
795 | static const unsigned char _EC_X9_62_CHAR2_191V1_SEED[] = { | ||
796 | 0x4E,0x13,0xCA,0x54,0x27,0x44,0xD6,0x96,0xE6,0x76, | ||
797 | 0x87,0x56,0x15,0x17,0x55,0x2F,0x27,0x9A,0x8C,0x84}; | ||
798 | static const EC_CURVE_DATA _EC_X9_62_CHAR2_191V1 = { | ||
799 | NID_X9_62_characteristic_two_field, | ||
800 | "800000000000000000000000000000000000000000000201", | ||
801 | "2866537B676752636A68F56554E12640276B649EF7526267", | ||
802 | "2E45EF571F00786F67B0081B9495A3D95462F5DE0AA185EC", | ||
803 | "36B3DAF8A23206F9C4F299D7B21A9C369137F2C84AE1AA0D", | ||
804 | "765BE73433B3F95E332932E70EA245CA2418EA0EF98018FB", | ||
805 | "40000000000000000000000004A20E90C39067C893BBB9A5", 2, | ||
806 | _EC_X9_62_CHAR2_191V1_SEED, 20, | ||
807 | "X9.62 curve over a 191 bit binary field" | ||
808 | }; | ||
809 | |||
810 | static const unsigned char _EC_X9_62_CHAR2_191V2_SEED[] = { | ||
811 | 0x08,0x71,0xEF,0x2F,0xEF,0x24,0xD6,0x96,0xE6,0x76, | ||
812 | 0x87,0x56,0x15,0x17,0x58,0xBE,0xE0,0xD9,0x5C,0x15}; | ||
813 | static const EC_CURVE_DATA _EC_X9_62_CHAR2_191V2 = { | ||
814 | NID_X9_62_characteristic_two_field, | ||
815 | "800000000000000000000000000000000000000000000201", | ||
816 | "401028774D7777C7B7666D1366EA432071274F89FF01E718", | ||
817 | "0620048D28BCBD03B6249C99182B7C8CD19700C362C46A01", | ||
818 | "3809B2B7CC1B28CC5A87926AAD83FD28789E81E2C9E3BF10", | ||
819 | "17434386626D14F3DBF01760D9213A3E1CF37AEC437D668A", | ||
820 | "20000000000000000000000050508CB89F652824E06B8173", 4, | ||
821 | _EC_X9_62_CHAR2_191V2_SEED, 20, | ||
822 | "X9.62 curve over a 191 bit binary field" | ||
823 | }; | ||
824 | |||
825 | static const unsigned char _EC_X9_62_CHAR2_191V3_SEED[] = { | ||
826 | 0xE0,0x53,0x51,0x2D,0xC6,0x84,0xD6,0x96,0xE6,0x76, | ||
827 | 0x87,0x56,0x15,0x17,0x50,0x67,0xAE,0x78,0x6D,0x1F}; | ||
828 | static const EC_CURVE_DATA _EC_X9_62_CHAR2_191V3 = { | ||
829 | NID_X9_62_characteristic_two_field, | ||
830 | "800000000000000000000000000000000000000000000201", | ||
831 | "6C01074756099122221056911C77D77E77A777E7E7E77FCB", | ||
832 | "71FE1AF926CF847989EFEF8DB459F66394D90F32AD3F15E8", | ||
833 | "375D4CE24FDE434489DE8746E71786015009E66E38A926DD", | ||
834 | "545A39176196575D985999366E6AD34CE0A77CD7127B06BE", | ||
835 | "155555555555555555555555610C0B196812BFB6288A3EA3", 6, | ||
836 | _EC_X9_62_CHAR2_191V3_SEED, 20, | ||
837 | "X9.62 curve over a 191 bit binary field" | ||
838 | }; | ||
839 | |||
840 | static const EC_CURVE_DATA _EC_X9_62_CHAR2_208W1 = { | ||
841 | NID_X9_62_characteristic_two_field, | ||
842 | "010000000000000000000000000000000800000000000000000007", | ||
843 | "0000000000000000000000000000000000000000000000000000", | ||
844 | "C8619ED45A62E6212E1160349E2BFA844439FAFC2A3FD1638F9E", | ||
845 | "89FDFBE4ABE193DF9559ECF07AC0CE78554E2784EB8C1ED1A57A", | ||
846 | "0F55B51A06E78E9AC38A035FF520D8B01781BEB1A6BB08617DE3", | ||
847 | "000101BAF95C9723C57B6C21DA2EFF2D5ED588BDD5717E212F9D", 0xFE48, | ||
848 | NULL, 0, | ||
849 | "X9.62 curve over a 208 bit binary field" | ||
850 | }; | ||
851 | |||
852 | static const unsigned char _EC_X9_62_CHAR2_239V1_SEED[] = { | ||
853 | 0xD3,0x4B,0x9A,0x4D,0x69,0x6E,0x67,0x68,0x75,0x61, | ||
854 | 0x51,0x75,0xCA,0x71,0xB9,0x20,0xBF,0xEF,0xB0,0x5D}; | ||
855 | static const EC_CURVE_DATA _EC_X9_62_CHAR2_239V1 = { | ||
856 | NID_X9_62_characteristic_two_field, | ||
857 | "800000000000000000000000000000000000000000000000001000000001", | ||
858 | "32010857077C5431123A46B808906756F543423E8D27877578125778AC76", | ||
859 | "790408F2EEDAF392B012EDEFB3392F30F4327C0CA3F31FC383C422AA8C16", | ||
860 | "57927098FA932E7C0A96D3FD5B706EF7E5F5C156E16B7E7C86038552E91D", | ||
861 | "61D8EE5077C33FECF6F1A16B268DE469C3C7744EA9A971649FC7A9616305", | ||
862 | "2000000000000000000000000000000F4D42FFE1492A4993F1CAD666E447", 4, | ||
863 | _EC_X9_62_CHAR2_239V1_SEED, 20, | ||
864 | "X9.62 curve over a 239 bit binary field" | ||
865 | }; | ||
866 | |||
867 | static const unsigned char _EC_X9_62_CHAR2_239V2_SEED[] = { | ||
868 | 0x2A,0xA6,0x98,0x2F,0xDF,0xA4,0xD6,0x96,0xE6,0x76, | ||
869 | 0x87,0x56,0x15,0x17,0x5D,0x26,0x67,0x27,0x27,0x7D}; | ||
870 | static const EC_CURVE_DATA _EC_X9_62_CHAR2_239V2 = { | ||
871 | NID_X9_62_characteristic_two_field, | ||
872 | "800000000000000000000000000000000000000000000000001000000001", | ||
873 | "4230017757A767FAE42398569B746325D45313AF0766266479B75654E65F", | ||
874 | "5037EA654196CFF0CD82B2C14A2FCF2E3FF8775285B545722F03EACDB74B", | ||
875 | "28F9D04E900069C8DC47A08534FE76D2B900B7D7EF31F5709F200C4CA205", | ||
876 | "5667334C45AFF3B5A03BAD9DD75E2C71A99362567D5453F7FA6E227EC833", | ||
877 | "1555555555555555555555555555553C6F2885259C31E3FCDF154624522D", 6, | ||
878 | _EC_X9_62_CHAR2_239V2_SEED, 20, | ||
879 | "X9.62 curve over a 239 bit binary field" | ||
880 | }; | ||
881 | |||
882 | static const unsigned char _EC_X9_62_CHAR2_239V3_SEED[] = { | ||
883 | 0x9E,0x07,0x6F,0x4D,0x69,0x6E,0x67,0x68,0x75,0x61, | ||
884 | 0x51,0x75,0xE1,0x1E,0x9F,0xDD,0x77,0xF9,0x20,0x41}; | ||
885 | static const EC_CURVE_DATA _EC_X9_62_CHAR2_239V3 = { | ||
886 | NID_X9_62_characteristic_two_field, | ||
887 | "800000000000000000000000000000000000000000000000001000000001", | ||
888 | "01238774666A67766D6676F778E676B66999176666E687666D8766C66A9F", | ||
889 | "6A941977BA9F6A435199ACFC51067ED587F519C5ECB541B8E44111DE1D40", | ||
890 | "70F6E9D04D289C4E89913CE3530BFDE903977D42B146D539BF1BDE4E9C92", | ||
891 | "2E5A0EAF6E5E1305B9004DCE5C0ED7FE59A35608F33837C816D80B79F461", | ||
892 | "0CCCCCCCCCCCCCCCCCCCCCCCCCCCCCAC4912D2D9DF903EF9888B8A0E4CFF", 0xA, | ||
893 | _EC_X9_62_CHAR2_239V3_SEED, 20, | ||
894 | "X9.62 curve over a 239 bit binary field" | ||
895 | }; | ||
896 | |||
897 | static const EC_CURVE_DATA _EC_X9_62_CHAR2_272W1 = { | ||
898 | NID_X9_62_characteristic_two_field, | ||
899 | "010000000000000000000000000000000000000000000000000000010000000000000" | ||
900 | "B", | ||
901 | "91A091F03B5FBA4AB2CCF49C4EDD220FB028712D42BE752B2C40094DBACDB586FB20", | ||
902 | "7167EFC92BB2E3CE7C8AAAFF34E12A9C557003D7C73A6FAF003F99F6CC8482E540F7", | ||
903 | "6108BABB2CEEBCF787058A056CBE0CFE622D7723A289E08A07AE13EF0D10D171DD8D", | ||
904 | "10C7695716851EEF6BA7F6872E6142FBD241B830FF5EFCACECCAB05E02005DDE9D23", | ||
905 | "000100FAF51354E0E39E4892DF6E319C72C8161603FA45AA7B998A167B8F1E629521", | ||
906 | 0xFF06, | ||
907 | NULL, 0, | ||
908 | "X9.62 curve over a 272 bit binary field" | ||
909 | }; | ||
910 | |||
911 | static const EC_CURVE_DATA _EC_X9_62_CHAR2_304W1 = { | ||
912 | NID_X9_62_characteristic_two_field, | ||
913 | "010000000000000000000000000000000000000000000000000000000000000000000" | ||
914 | "000000807", | ||
915 | "FD0D693149A118F651E6DCE6802085377E5F882D1B510B44160074C1288078365A039" | ||
916 | "6C8E681", | ||
917 | "BDDB97E555A50A908E43B01C798EA5DAA6788F1EA2794EFCF57166B8C14039601E558" | ||
918 | "27340BE", | ||
919 | "197B07845E9BE2D96ADB0F5F3C7F2CFFBD7A3EB8B6FEC35C7FD67F26DDF6285A644F7" | ||
920 | "40A2614", | ||
921 | "E19FBEB76E0DA171517ECF401B50289BF014103288527A9B416A105E80260B549FDC1" | ||
922 | "B92C03B", | ||
923 | "000101D556572AABAC800101D556572AABAC8001022D5C91DD173F8FB561DA6899164" | ||
924 | "443051D", 0xFE2E, | ||
925 | NULL, 0, | ||
926 | "X9.62 curve over a 304 bit binary field" | ||
927 | }; | ||
928 | |||
929 | static const unsigned char _EC_X9_62_CHAR2_359V1_SEED[] = { | ||
930 | 0x2B,0x35,0x49,0x20,0xB7,0x24,0xD6,0x96,0xE6,0x76, | ||
931 | 0x87,0x56,0x15,0x17,0x58,0x5B,0xA1,0x33,0x2D,0xC6}; | ||
932 | static const EC_CURVE_DATA _EC_X9_62_CHAR2_359V1 = { | ||
933 | NID_X9_62_characteristic_two_field, | ||
934 | "800000000000000000000000000000000000000000000000000000000000000000000" | ||
935 | "000100000000000000001", | ||
936 | "5667676A654B20754F356EA92017D946567C46675556F19556A04616B567D223A5E05" | ||
937 | "656FB549016A96656A557", | ||
938 | "2472E2D0197C49363F1FE7F5B6DB075D52B6947D135D8CA445805D39BC34562608968" | ||
939 | "7742B6329E70680231988", | ||
940 | "3C258EF3047767E7EDE0F1FDAA79DAEE3841366A132E163ACED4ED2401DF9C6BDCDE9" | ||
941 | "8E8E707C07A2239B1B097", | ||
942 | "53D7E08529547048121E9C95F3791DD804963948F34FAE7BF44EA82365DC7868FE57E" | ||
943 | "4AE2DE211305A407104BD", | ||
944 | "01AF286BCA1AF286BCA1AF286BCA1AF286BCA1AF286BC9FB8F6B85C556892C20A7EB9" | ||
945 | "64FE7719E74F490758D3B", 0x4C, | ||
946 | _EC_X9_62_CHAR2_359V1_SEED, 20, | ||
947 | "X9.62 curve over a 359 bit binary field" | ||
948 | }; | ||
949 | |||
950 | static const EC_CURVE_DATA _EC_X9_62_CHAR2_368W1 = { | ||
951 | NID_X9_62_characteristic_two_field, | ||
952 | "010000000000000000000000000000000000000000000000000000000000000000000" | ||
953 | "0002000000000000000000007", | ||
954 | "E0D2EE25095206F5E2A4F9ED229F1F256E79A0E2B455970D8D0D865BD94778C576D62" | ||
955 | "F0AB7519CCD2A1A906AE30D", | ||
956 | "FC1217D4320A90452C760A58EDCD30C8DD069B3C34453837A34ED50CB54917E1C2112" | ||
957 | "D84D164F444F8F74786046A", | ||
958 | "1085E2755381DCCCE3C1557AFA10C2F0C0C2825646C5B34A394CBCFA8BC16B22E7E78" | ||
959 | "9E927BE216F02E1FB136A5F", | ||
960 | "7B3EB1BDDCBA62D5D8B2059B525797FC73822C59059C623A45FF3843CEE8F87CD1855" | ||
961 | "ADAA81E2A0750B80FDA2310", | ||
962 | "00010090512DA9AF72B08349D98A5DD4C7B0532ECA51CE03E2D10F3B7AC579BD87E90" | ||
963 | "9AE40A6F131E9CFCE5BD967", 0xFF70, | ||
964 | NULL, 0, | ||
965 | "X9.62 curve over a 368 bit binary field" | ||
966 | }; | ||
967 | |||
968 | static const EC_CURVE_DATA _EC_X9_62_CHAR2_431R1 = { | ||
969 | NID_X9_62_characteristic_two_field, | ||
970 | "800000000000000000000000000000000000000000000000000000000000000000000" | ||
971 | "000000001000000000000000000000000000001", | ||
972 | "1A827EF00DD6FC0E234CAF046C6A5D8A85395B236CC4AD2CF32A0CADBDC9DDF620B0E" | ||
973 | "B9906D0957F6C6FEACD615468DF104DE296CD8F", | ||
974 | "10D9B4A3D9047D8B154359ABFB1B7F5485B04CEB868237DDC9DEDA982A679A5A919B6" | ||
975 | "26D4E50A8DD731B107A9962381FB5D807BF2618", | ||
976 | "120FC05D3C67A99DE161D2F4092622FECA701BE4F50F4758714E8A87BBF2A658EF8C2" | ||
977 | "1E7C5EFE965361F6C2999C0C247B0DBD70CE6B7", | ||
978 | "20D0AF8903A96F8D5FA2C255745D3C451B302C9346D9B7E485E7BCE41F6B591F3E8F6" | ||
979 | "ADDCBB0BC4C2F947A7DE1A89B625D6A598B3760", | ||
980 | "0340340340340340340340340340340340340340340340340340340323C313FAB5058" | ||
981 | "9703B5EC68D3587FEC60D161CC149C1AD4A91", 0x2760, | ||
982 | NULL, 0, | ||
983 | "X9.62 curve over a 431 bit binary field" | ||
984 | }; | ||
985 | |||
986 | static const EC_CURVE_DATA _EC_WTLS_1 = { | ||
987 | NID_X9_62_characteristic_two_field, | ||
988 | "020000000000000000000000000201", | ||
989 | "1", | ||
990 | "1", | ||
991 | "01667979A40BA497E5D5C270780617", | ||
992 | "00F44B4AF1ECC2630E08785CEBCC15", | ||
993 | "00FFFFFFFFFFFFFFFDBF91AF6DEA73", 2, | ||
994 | NULL, 0, | ||
995 | "WTLS curve over a 113 bit binary field" | ||
996 | }; | ||
997 | |||
998 | /* IPSec curves */ | ||
999 | /* NOTE: The of curves over a extension field of non prime degree | ||
1000 | * is not recommended (Weil-descent). | ||
1001 | * As the group order is not a prime this curve is not suitable | ||
1002 | * for ECDSA. | ||
1003 | */ | ||
1004 | static const EC_CURVE_DATA _EC_IPSEC_155_ID3 = { | ||
1005 | NID_X9_62_characteristic_two_field, | ||
1006 | "0800000000000000000000004000000000000001", | ||
1007 | "0", | ||
1008 | "07338f", | ||
1009 | "7b", | ||
1010 | "1c8", | ||
1011 | "2AAAAAAAAAAAAAAAAAAC7F3C7881BD0868FA86C",3, | ||
1012 | NULL, 0, | ||
1013 | "\n\tIPSec/IKE/Oakley curve #3 over a 155 bit binary field.\n" | ||
1014 | "\tNot suitable for ECDSA.\n\tQuestionable extension field!" | ||
1015 | }; | ||
1016 | |||
1017 | /* NOTE: The of curves over a extension field of non prime degree | ||
1018 | * is not recommended (Weil-descent). | ||
1019 | * As the group order is not a prime this curve is not suitable | ||
1020 | * for ECDSA. | ||
1021 | */ | ||
1022 | static const EC_CURVE_DATA _EC_IPSEC_185_ID4 = { | ||
1023 | NID_X9_62_characteristic_two_field, | ||
1024 | "020000000000000000000000000000200000000000000001", | ||
1025 | "0", | ||
1026 | "1ee9", | ||
1027 | "18", | ||
1028 | "0d", | ||
1029 | "FFFFFFFFFFFFFFFFFFFFFFEDF97C44DB9F2420BAFCA75E",2, | ||
1030 | NULL, 0, | ||
1031 | "\n\tIPSec/IKE/Oakley curve #4 over a 185 bit binary field.\n" | ||
1032 | "\tNot suitable for ECDSA.\n\tQuestionable extension field!" | ||
1033 | }; | ||
1034 | |||
1035 | typedef struct _ec_list_element_st { | ||
1036 | int nid; | ||
1037 | const EC_CURVE_DATA *data; | ||
1038 | } ec_list_element; | ||
1039 | |||
1040 | static const ec_list_element curve_list[] = { | ||
1041 | /* prime field curves */ | ||
1042 | /* secg curves */ | ||
1043 | { NID_secp112r1, &_EC_SECG_PRIME_112R1}, | ||
1044 | { NID_secp112r2, &_EC_SECG_PRIME_112R2}, | ||
1045 | { NID_secp128r1, &_EC_SECG_PRIME_128R1}, | ||
1046 | { NID_secp128r2, &_EC_SECG_PRIME_128R2}, | ||
1047 | { NID_secp160k1, &_EC_SECG_PRIME_160K1}, | ||
1048 | { NID_secp160r1, &_EC_SECG_PRIME_160R1}, | ||
1049 | { NID_secp160r2, &_EC_SECG_PRIME_160R2}, | ||
1050 | /* SECG secp192r1 is the same as X9.62 prime192v1 and hence omitted */ | ||
1051 | { NID_secp192k1, &_EC_SECG_PRIME_192K1}, | ||
1052 | { NID_secp224k1, &_EC_SECG_PRIME_224K1}, | ||
1053 | { NID_secp224r1, &_EC_NIST_PRIME_224}, | ||
1054 | { NID_secp256k1, &_EC_SECG_PRIME_256K1}, | ||
1055 | /* SECG secp256r1 is the same as X9.62 prime256v1 and hence omitted */ | ||
1056 | { NID_secp384r1, &_EC_NIST_PRIME_384}, | ||
1057 | { NID_secp521r1, &_EC_NIST_PRIME_521}, | ||
1058 | /* X9.62 curves */ | ||
1059 | { NID_X9_62_prime192v1, &_EC_NIST_PRIME_192}, | ||
1060 | { NID_X9_62_prime192v2, &_EC_X9_62_PRIME_192V2}, | ||
1061 | { NID_X9_62_prime192v3, &_EC_X9_62_PRIME_192V3}, | ||
1062 | { NID_X9_62_prime239v1, &_EC_X9_62_PRIME_239V1}, | ||
1063 | { NID_X9_62_prime239v2, &_EC_X9_62_PRIME_239V2}, | ||
1064 | { NID_X9_62_prime239v3, &_EC_X9_62_PRIME_239V3}, | ||
1065 | { NID_X9_62_prime256v1, &_EC_X9_62_PRIME_256V1}, | ||
1066 | /* characteristic two field curves */ | ||
1067 | /* NIST/SECG curves */ | ||
1068 | { NID_sect113r1, &_EC_SECG_CHAR2_113R1}, | ||
1069 | { NID_sect113r2, &_EC_SECG_CHAR2_113R2}, | ||
1070 | { NID_sect131r1, &_EC_SECG_CHAR2_131R1}, | ||
1071 | { NID_sect131r2, &_EC_SECG_CHAR2_131R2}, | ||
1072 | { NID_sect163k1, &_EC_NIST_CHAR2_163K }, | ||
1073 | { NID_sect163r1, &_EC_SECG_CHAR2_163R1}, | ||
1074 | { NID_sect163r2, &_EC_NIST_CHAR2_163B }, | ||
1075 | { NID_sect193r1, &_EC_SECG_CHAR2_193R1}, | ||
1076 | { NID_sect193r2, &_EC_SECG_CHAR2_193R2}, | ||
1077 | { NID_sect233k1, &_EC_NIST_CHAR2_233K }, | ||
1078 | { NID_sect233r1, &_EC_NIST_CHAR2_233B }, | ||
1079 | { NID_sect239k1, &_EC_SECG_CHAR2_239K1}, | ||
1080 | { NID_sect283k1, &_EC_NIST_CHAR2_283K }, | ||
1081 | { NID_sect283r1, &_EC_NIST_CHAR2_283B }, | ||
1082 | { NID_sect409k1, &_EC_NIST_CHAR2_409K }, | ||
1083 | { NID_sect409r1, &_EC_NIST_CHAR2_409B }, | ||
1084 | { NID_sect571k1, &_EC_NIST_CHAR2_571K }, | ||
1085 | { NID_sect571r1, &_EC_NIST_CHAR2_571B }, | ||
1086 | /* X9.62 curves */ | ||
1087 | { NID_X9_62_c2pnb163v1, &_EC_X9_62_CHAR2_163V1}, | ||
1088 | { NID_X9_62_c2pnb163v2, &_EC_X9_62_CHAR2_163V2}, | ||
1089 | { NID_X9_62_c2pnb163v3, &_EC_X9_62_CHAR2_163V3}, | ||
1090 | { NID_X9_62_c2pnb176v1, &_EC_X9_62_CHAR2_176V1}, | ||
1091 | { NID_X9_62_c2tnb191v1, &_EC_X9_62_CHAR2_191V1}, | ||
1092 | { NID_X9_62_c2tnb191v2, &_EC_X9_62_CHAR2_191V2}, | ||
1093 | { NID_X9_62_c2tnb191v3, &_EC_X9_62_CHAR2_191V3}, | ||
1094 | { NID_X9_62_c2pnb208w1, &_EC_X9_62_CHAR2_208W1}, | ||
1095 | { NID_X9_62_c2tnb239v1, &_EC_X9_62_CHAR2_239V1}, | ||
1096 | { NID_X9_62_c2tnb239v2, &_EC_X9_62_CHAR2_239V2}, | ||
1097 | { NID_X9_62_c2tnb239v3, &_EC_X9_62_CHAR2_239V3}, | ||
1098 | { NID_X9_62_c2pnb272w1, &_EC_X9_62_CHAR2_272W1}, | ||
1099 | { NID_X9_62_c2pnb304w1, &_EC_X9_62_CHAR2_304W1}, | ||
1100 | { NID_X9_62_c2tnb359v1, &_EC_X9_62_CHAR2_359V1}, | ||
1101 | { NID_X9_62_c2pnb368w1, &_EC_X9_62_CHAR2_368W1}, | ||
1102 | { NID_X9_62_c2tnb431r1, &_EC_X9_62_CHAR2_431R1}, | ||
1103 | /* the WAP/WTLS curves | ||
1104 | * [unlike SECG, spec has its own OIDs for curves from X9.62] */ | ||
1105 | { NID_wap_wsg_idm_ecid_wtls1, &_EC_WTLS_1}, | ||
1106 | { NID_wap_wsg_idm_ecid_wtls3, &_EC_NIST_CHAR2_163K}, | ||
1107 | { NID_wap_wsg_idm_ecid_wtls4, &_EC_SECG_CHAR2_113R1}, | ||
1108 | { NID_wap_wsg_idm_ecid_wtls5, &_EC_X9_62_CHAR2_163V1}, | ||
1109 | { NID_wap_wsg_idm_ecid_wtls6, &_EC_SECG_PRIME_112R1}, | ||
1110 | { NID_wap_wsg_idm_ecid_wtls7, &_EC_SECG_PRIME_160R2}, | ||
1111 | { NID_wap_wsg_idm_ecid_wtls8, &_EC_WTLS_8}, | ||
1112 | { NID_wap_wsg_idm_ecid_wtls9, &_EC_WTLS_9 }, | ||
1113 | { NID_wap_wsg_idm_ecid_wtls10, &_EC_NIST_CHAR2_233K}, | ||
1114 | { NID_wap_wsg_idm_ecid_wtls11, &_EC_NIST_CHAR2_233B}, | ||
1115 | { NID_wap_wsg_idm_ecid_wtls12, &_EC_WTLS_12}, | ||
1116 | /* IPSec curves */ | ||
1117 | { NID_ipsec3, &_EC_IPSEC_155_ID3}, | ||
1118 | { NID_ipsec4, &_EC_IPSEC_185_ID4}, | ||
1119 | }; | ||
1120 | |||
1121 | static size_t curve_list_length = sizeof(curve_list)/sizeof(ec_list_element); | ||
1122 | |||
1123 | static EC_GROUP *ec_group_new_from_data(const EC_CURVE_DATA *data) | ||
1124 | { | ||
1125 | EC_GROUP *group=NULL; | ||
1126 | EC_POINT *P=NULL; | ||
1127 | BN_CTX *ctx=NULL; | ||
1128 | BIGNUM *p=NULL, *a=NULL, *b=NULL, *x=NULL, *y=NULL, *order=NULL; | ||
1129 | int ok=0; | ||
1130 | |||
1131 | if ((ctx = BN_CTX_new()) == NULL) | ||
1132 | { | ||
1133 | ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_MALLOC_FAILURE); | ||
1134 | goto err; | ||
1135 | } | ||
1136 | if ((p = BN_new()) == NULL || (a = BN_new()) == NULL || | ||
1137 | (b = BN_new()) == NULL || (x = BN_new()) == NULL || | ||
1138 | (y = BN_new()) == NULL || (order = BN_new()) == NULL) | ||
1139 | { | ||
1140 | ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_MALLOC_FAILURE); | ||
1141 | goto err; | ||
1142 | } | ||
1143 | |||
1144 | if (!BN_hex2bn(&p, data->p) || !BN_hex2bn(&a, data->a) | ||
1145 | || !BN_hex2bn(&b, data->b)) | ||
1146 | { | ||
1147 | ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_BN_LIB); | ||
1148 | goto err; | ||
1149 | } | ||
1150 | |||
1151 | if (data->field_type == NID_X9_62_prime_field) | ||
1152 | { | ||
1153 | if ((group = EC_GROUP_new_curve_GFp(p, a, b, ctx)) == NULL) | ||
1154 | { | ||
1155 | ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB); | ||
1156 | goto err; | ||
1157 | } | ||
1158 | } | ||
1159 | else | ||
1160 | { /* field_type == NID_X9_62_characteristic_two_field */ | ||
1161 | if ((group = EC_GROUP_new_curve_GF2m(p, a, b, ctx)) == NULL) | ||
1162 | { | ||
1163 | ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB); | ||
1164 | goto err; | ||
1165 | } | ||
1166 | } | ||
1167 | |||
1168 | if ((P = EC_POINT_new(group)) == NULL) | ||
1169 | { | ||
1170 | ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB); | ||
1171 | goto err; | ||
1172 | } | ||
1173 | |||
1174 | if (!BN_hex2bn(&x, data->x) || !BN_hex2bn(&y, data->y)) | ||
1175 | { | ||
1176 | ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_BN_LIB); | ||
1177 | goto err; | ||
1178 | } | ||
1179 | if (!EC_POINT_set_affine_coordinates_GF2m(group, P, x, y, ctx)) | ||
1180 | { | ||
1181 | ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB); | ||
1182 | goto err; | ||
1183 | } | ||
1184 | if (!BN_hex2bn(&order, data->order) || !BN_set_word(x, data->cofactor)) | ||
1185 | { | ||
1186 | ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_BN_LIB); | ||
1187 | goto err; | ||
1188 | } | ||
1189 | if (!EC_GROUP_set_generator(group, P, order, x)) | ||
1190 | { | ||
1191 | ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB); | ||
1192 | goto err; | ||
1193 | } | ||
1194 | if (data->seed) | ||
1195 | { | ||
1196 | if (!EC_GROUP_set_seed(group, data->seed, data->seed_len)) | ||
1197 | { | ||
1198 | ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB); | ||
1199 | goto err; | ||
1200 | } | ||
1201 | } | ||
1202 | ok=1; | ||
1203 | err: | ||
1204 | if (!ok) | ||
1205 | { | ||
1206 | EC_GROUP_free(group); | ||
1207 | group = NULL; | ||
1208 | } | ||
1209 | if (P) | ||
1210 | EC_POINT_free(P); | ||
1211 | if (ctx) | ||
1212 | BN_CTX_free(ctx); | ||
1213 | if (p) | ||
1214 | BN_free(p); | ||
1215 | if (a) | ||
1216 | BN_free(a); | ||
1217 | if (b) | ||
1218 | BN_free(b); | ||
1219 | if (order) | ||
1220 | BN_free(order); | ||
1221 | if (x) | ||
1222 | BN_free(x); | ||
1223 | if (y) | ||
1224 | BN_free(y); | ||
1225 | return group; | ||
1226 | } | ||
1227 | |||
1228 | EC_GROUP *EC_GROUP_new_by_curve_name(int nid) | ||
1229 | { | ||
1230 | size_t i; | ||
1231 | EC_GROUP *ret = NULL; | ||
1232 | |||
1233 | if (nid <= 0) | ||
1234 | return NULL; | ||
1235 | |||
1236 | for (i=0; i<curve_list_length; i++) | ||
1237 | if (curve_list[i].nid == nid) | ||
1238 | { | ||
1239 | ret = ec_group_new_from_data(curve_list[i].data); | ||
1240 | break; | ||
1241 | } | ||
1242 | |||
1243 | if (ret == NULL) | ||
1244 | { | ||
1245 | ECerr(EC_F_EC_GROUP_NEW_BY_CURVE_NAME, EC_R_UNKNOWN_GROUP); | ||
1246 | return NULL; | ||
1247 | } | ||
1248 | |||
1249 | EC_GROUP_set_curve_name(ret, nid); | ||
1250 | |||
1251 | return ret; | ||
1252 | } | ||
1253 | |||
1254 | size_t EC_get_builtin_curves(EC_builtin_curve *r, size_t nitems) | ||
1255 | { | ||
1256 | size_t i, min; | ||
1257 | |||
1258 | if (r == NULL || nitems == 0) | ||
1259 | return curve_list_length; | ||
1260 | |||
1261 | min = nitems < curve_list_length ? nitems : curve_list_length; | ||
1262 | |||
1263 | for (i = 0; i < min; i++) | ||
1264 | { | ||
1265 | r[i].nid = curve_list[i].nid; | ||
1266 | r[i].comment = curve_list[i].data->comment; | ||
1267 | } | ||
1268 | |||
1269 | return curve_list_length; | ||
1270 | } | ||
diff --git a/src/lib/libcrypto/ec/ec_key.c b/src/lib/libcrypto/ec/ec_key.c new file mode 100644 index 0000000000..3d6c900b95 --- /dev/null +++ b/src/lib/libcrypto/ec/ec_key.c | |||
@@ -0,0 +1,465 @@ | |||
1 | /* crypto/ec/ec_key.c */ | ||
2 | /* | ||
3 | * Written by Nils Larsch for the OpenSSL project. | ||
4 | */ | ||
5 | /* ==================================================================== | ||
6 | * Copyright (c) 1998-2005 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 | * openssl-core@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 | * This product includes cryptographic software written by Eric Young | ||
54 | * (eay@cryptsoft.com). This product includes software written by Tim | ||
55 | * Hudson (tjh@cryptsoft.com). | ||
56 | * | ||
57 | */ | ||
58 | /* ==================================================================== | ||
59 | * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. | ||
60 | * Portions originally developed by SUN MICROSYSTEMS, INC., and | ||
61 | * contributed to the OpenSSL project. | ||
62 | */ | ||
63 | |||
64 | #include <string.h> | ||
65 | #include "ec_lcl.h" | ||
66 | #include <openssl/err.h> | ||
67 | #include <string.h> | ||
68 | |||
69 | EC_KEY *EC_KEY_new(void) | ||
70 | { | ||
71 | EC_KEY *ret; | ||
72 | |||
73 | ret=(EC_KEY *)OPENSSL_malloc(sizeof(EC_KEY)); | ||
74 | if (ret == NULL) | ||
75 | { | ||
76 | ECerr(EC_F_EC_KEY_NEW, ERR_R_MALLOC_FAILURE); | ||
77 | return(NULL); | ||
78 | } | ||
79 | |||
80 | ret->version = 1; | ||
81 | ret->group = NULL; | ||
82 | ret->pub_key = NULL; | ||
83 | ret->priv_key= NULL; | ||
84 | ret->enc_flag= 0; | ||
85 | ret->conv_form = POINT_CONVERSION_UNCOMPRESSED; | ||
86 | ret->references= 1; | ||
87 | ret->method_data = NULL; | ||
88 | return(ret); | ||
89 | } | ||
90 | |||
91 | EC_KEY *EC_KEY_new_by_curve_name(int nid) | ||
92 | { | ||
93 | EC_KEY *ret = EC_KEY_new(); | ||
94 | if (ret == NULL) | ||
95 | return NULL; | ||
96 | ret->group = EC_GROUP_new_by_curve_name(nid); | ||
97 | if (ret->group == NULL) | ||
98 | { | ||
99 | EC_KEY_free(ret); | ||
100 | return NULL; | ||
101 | } | ||
102 | return ret; | ||
103 | } | ||
104 | |||
105 | void EC_KEY_free(EC_KEY *r) | ||
106 | { | ||
107 | int i; | ||
108 | |||
109 | if (r == NULL) return; | ||
110 | |||
111 | i=CRYPTO_add(&r->references,-1,CRYPTO_LOCK_EC); | ||
112 | #ifdef REF_PRINT | ||
113 | REF_PRINT("EC_KEY",r); | ||
114 | #endif | ||
115 | if (i > 0) return; | ||
116 | #ifdef REF_CHECK | ||
117 | if (i < 0) | ||
118 | { | ||
119 | fprintf(stderr,"EC_KEY_free, bad reference count\n"); | ||
120 | abort(); | ||
121 | } | ||
122 | #endif | ||
123 | |||
124 | if (r->group != NULL) | ||
125 | EC_GROUP_free(r->group); | ||
126 | if (r->pub_key != NULL) | ||
127 | EC_POINT_free(r->pub_key); | ||
128 | if (r->priv_key != NULL) | ||
129 | BN_clear_free(r->priv_key); | ||
130 | |||
131 | EC_EX_DATA_free_all_data(&r->method_data); | ||
132 | |||
133 | OPENSSL_cleanse((void *)r, sizeof(EC_KEY)); | ||
134 | |||
135 | OPENSSL_free(r); | ||
136 | } | ||
137 | |||
138 | EC_KEY *EC_KEY_copy(EC_KEY *dest, const EC_KEY *src) | ||
139 | { | ||
140 | EC_EXTRA_DATA *d; | ||
141 | |||
142 | if (dest == NULL || src == NULL) | ||
143 | { | ||
144 | ECerr(EC_F_EC_KEY_COPY, ERR_R_PASSED_NULL_PARAMETER); | ||
145 | return NULL; | ||
146 | } | ||
147 | /* copy the parameters */ | ||
148 | if (src->group) | ||
149 | { | ||
150 | const EC_METHOD *meth = EC_GROUP_method_of(src->group); | ||
151 | /* clear the old group */ | ||
152 | if (dest->group) | ||
153 | EC_GROUP_free(dest->group); | ||
154 | dest->group = EC_GROUP_new(meth); | ||
155 | if (dest->group == NULL) | ||
156 | return NULL; | ||
157 | if (!EC_GROUP_copy(dest->group, src->group)) | ||
158 | return NULL; | ||
159 | } | ||
160 | /* copy the public key */ | ||
161 | if (src->pub_key && src->group) | ||
162 | { | ||
163 | if (dest->pub_key) | ||
164 | EC_POINT_free(dest->pub_key); | ||
165 | dest->pub_key = EC_POINT_new(src->group); | ||
166 | if (dest->pub_key == NULL) | ||
167 | return NULL; | ||
168 | if (!EC_POINT_copy(dest->pub_key, src->pub_key)) | ||
169 | return NULL; | ||
170 | } | ||
171 | /* copy the private key */ | ||
172 | if (src->priv_key) | ||
173 | { | ||
174 | if (dest->priv_key == NULL) | ||
175 | { | ||
176 | dest->priv_key = BN_new(); | ||
177 | if (dest->priv_key == NULL) | ||
178 | return NULL; | ||
179 | } | ||
180 | if (!BN_copy(dest->priv_key, src->priv_key)) | ||
181 | return NULL; | ||
182 | } | ||
183 | /* copy method/extra data */ | ||
184 | EC_EX_DATA_free_all_data(&dest->method_data); | ||
185 | |||
186 | for (d = src->method_data; d != NULL; d = d->next) | ||
187 | { | ||
188 | void *t = d->dup_func(d->data); | ||
189 | |||
190 | if (t == NULL) | ||
191 | return 0; | ||
192 | if (!EC_EX_DATA_set_data(&dest->method_data, t, d->dup_func, d->free_func, d->clear_free_func)) | ||
193 | return 0; | ||
194 | } | ||
195 | |||
196 | /* copy the rest */ | ||
197 | dest->enc_flag = src->enc_flag; | ||
198 | dest->conv_form = src->conv_form; | ||
199 | dest->version = src->version; | ||
200 | |||
201 | return dest; | ||
202 | } | ||
203 | |||
204 | EC_KEY *EC_KEY_dup(const EC_KEY *ec_key) | ||
205 | { | ||
206 | EC_KEY *ret = EC_KEY_new(); | ||
207 | if (ret == NULL) | ||
208 | return NULL; | ||
209 | if (EC_KEY_copy(ret, ec_key) == NULL) | ||
210 | { | ||
211 | EC_KEY_free(ret); | ||
212 | return NULL; | ||
213 | } | ||
214 | return ret; | ||
215 | } | ||
216 | |||
217 | int EC_KEY_up_ref(EC_KEY *r) | ||
218 | { | ||
219 | int i = CRYPTO_add(&r->references, 1, CRYPTO_LOCK_EC); | ||
220 | #ifdef REF_PRINT | ||
221 | REF_PRINT("EC_KEY",r); | ||
222 | #endif | ||
223 | #ifdef REF_CHECK | ||
224 | if (i < 2) | ||
225 | { | ||
226 | fprintf(stderr, "EC_KEY_up, bad reference count\n"); | ||
227 | abort(); | ||
228 | } | ||
229 | #endif | ||
230 | return ((i > 1) ? 1 : 0); | ||
231 | } | ||
232 | |||
233 | int EC_KEY_generate_key(EC_KEY *eckey) | ||
234 | { | ||
235 | int ok = 0; | ||
236 | BN_CTX *ctx = NULL; | ||
237 | BIGNUM *priv_key = NULL, *order = NULL; | ||
238 | EC_POINT *pub_key = NULL; | ||
239 | |||
240 | if (!eckey || !eckey->group) | ||
241 | { | ||
242 | ECerr(EC_F_EC_KEY_GENERATE_KEY, ERR_R_PASSED_NULL_PARAMETER); | ||
243 | return 0; | ||
244 | } | ||
245 | |||
246 | if ((order = BN_new()) == NULL) goto err; | ||
247 | if ((ctx = BN_CTX_new()) == NULL) goto err; | ||
248 | |||
249 | if (eckey->priv_key == NULL) | ||
250 | { | ||
251 | priv_key = BN_new(); | ||
252 | if (priv_key == NULL) | ||
253 | goto err; | ||
254 | } | ||
255 | else | ||
256 | priv_key = eckey->priv_key; | ||
257 | |||
258 | if (!EC_GROUP_get_order(eckey->group, order, ctx)) | ||
259 | goto err; | ||
260 | |||
261 | do | ||
262 | if (!BN_rand_range(priv_key, order)) | ||
263 | goto err; | ||
264 | while (BN_is_zero(priv_key)); | ||
265 | |||
266 | if (eckey->pub_key == NULL) | ||
267 | { | ||
268 | pub_key = EC_POINT_new(eckey->group); | ||
269 | if (pub_key == NULL) | ||
270 | goto err; | ||
271 | } | ||
272 | else | ||
273 | pub_key = eckey->pub_key; | ||
274 | |||
275 | if (!EC_POINT_mul(eckey->group, pub_key, priv_key, NULL, NULL, ctx)) | ||
276 | goto err; | ||
277 | |||
278 | eckey->priv_key = priv_key; | ||
279 | eckey->pub_key = pub_key; | ||
280 | |||
281 | ok=1; | ||
282 | |||
283 | err: | ||
284 | if (order) | ||
285 | BN_free(order); | ||
286 | if (pub_key != NULL && eckey->pub_key == NULL) | ||
287 | EC_POINT_free(pub_key); | ||
288 | if (priv_key != NULL && eckey->priv_key == NULL) | ||
289 | BN_free(priv_key); | ||
290 | if (ctx != NULL) | ||
291 | BN_CTX_free(ctx); | ||
292 | return(ok); | ||
293 | } | ||
294 | |||
295 | int EC_KEY_check_key(const EC_KEY *eckey) | ||
296 | { | ||
297 | int ok = 0; | ||
298 | BN_CTX *ctx = NULL; | ||
299 | BIGNUM *order = NULL; | ||
300 | EC_POINT *point = NULL; | ||
301 | |||
302 | if (!eckey || !eckey->group || !eckey->pub_key) | ||
303 | { | ||
304 | ECerr(EC_F_EC_KEY_CHECK_KEY, ERR_R_PASSED_NULL_PARAMETER); | ||
305 | return 0; | ||
306 | } | ||
307 | |||
308 | if ((ctx = BN_CTX_new()) == NULL) | ||
309 | goto err; | ||
310 | if ((order = BN_new()) == NULL) | ||
311 | goto err; | ||
312 | if ((point = EC_POINT_new(eckey->group)) == NULL) | ||
313 | goto err; | ||
314 | |||
315 | /* testing whether the pub_key is on the elliptic curve */ | ||
316 | if (!EC_POINT_is_on_curve(eckey->group, eckey->pub_key, ctx)) | ||
317 | { | ||
318 | ECerr(EC_F_EC_KEY_CHECK_KEY, EC_R_POINT_IS_NOT_ON_CURVE); | ||
319 | goto err; | ||
320 | } | ||
321 | /* testing whether pub_key * order is the point at infinity */ | ||
322 | if (!EC_GROUP_get_order(eckey->group, order, ctx)) | ||
323 | { | ||
324 | ECerr(EC_F_EC_KEY_CHECK_KEY, EC_R_INVALID_GROUP_ORDER); | ||
325 | goto err; | ||
326 | } | ||
327 | if (!EC_POINT_copy(point, eckey->pub_key)) | ||
328 | { | ||
329 | ECerr(EC_F_EC_KEY_CHECK_KEY, ERR_R_EC_LIB); | ||
330 | goto err; | ||
331 | } | ||
332 | if (!EC_POINT_mul(eckey->group, point, order, NULL, NULL, ctx)) | ||
333 | { | ||
334 | ECerr(EC_F_EC_KEY_CHECK_KEY, ERR_R_EC_LIB); | ||
335 | goto err; | ||
336 | } | ||
337 | if (!EC_POINT_is_at_infinity(eckey->group, point)) | ||
338 | { | ||
339 | ECerr(EC_F_EC_KEY_CHECK_KEY, EC_R_WRONG_ORDER); | ||
340 | goto err; | ||
341 | } | ||
342 | /* in case the priv_key is present : | ||
343 | * check if generator * priv_key == pub_key | ||
344 | */ | ||
345 | if (eckey->priv_key) | ||
346 | { | ||
347 | if (BN_cmp(eckey->priv_key, order) >= 0) | ||
348 | { | ||
349 | ECerr(EC_F_EC_KEY_CHECK_KEY, EC_R_WRONG_ORDER); | ||
350 | goto err; | ||
351 | } | ||
352 | if (!EC_POINT_mul(eckey->group, point, eckey->priv_key, | ||
353 | NULL, NULL, ctx)) | ||
354 | { | ||
355 | ECerr(EC_F_EC_KEY_CHECK_KEY, ERR_R_EC_LIB); | ||
356 | goto err; | ||
357 | } | ||
358 | if (EC_POINT_cmp(eckey->group, point, eckey->pub_key, | ||
359 | ctx) != 0) | ||
360 | { | ||
361 | ECerr(EC_F_EC_KEY_CHECK_KEY, EC_R_INVALID_PRIVATE_KEY); | ||
362 | goto err; | ||
363 | } | ||
364 | } | ||
365 | ok = 1; | ||
366 | err: | ||
367 | if (ctx != NULL) | ||
368 | BN_CTX_free(ctx); | ||
369 | if (order != NULL) | ||
370 | BN_free(order); | ||
371 | if (point != NULL) | ||
372 | EC_POINT_free(point); | ||
373 | return(ok); | ||
374 | } | ||
375 | |||
376 | const EC_GROUP *EC_KEY_get0_group(const EC_KEY *key) | ||
377 | { | ||
378 | return key->group; | ||
379 | } | ||
380 | |||
381 | int EC_KEY_set_group(EC_KEY *key, const EC_GROUP *group) | ||
382 | { | ||
383 | if (key->group != NULL) | ||
384 | EC_GROUP_free(key->group); | ||
385 | key->group = EC_GROUP_dup(group); | ||
386 | return (key->group == NULL) ? 0 : 1; | ||
387 | } | ||
388 | |||
389 | const BIGNUM *EC_KEY_get0_private_key(const EC_KEY *key) | ||
390 | { | ||
391 | return key->priv_key; | ||
392 | } | ||
393 | |||
394 | int EC_KEY_set_private_key(EC_KEY *key, const BIGNUM *priv_key) | ||
395 | { | ||
396 | if (key->priv_key) | ||
397 | BN_clear_free(key->priv_key); | ||
398 | key->priv_key = BN_dup(priv_key); | ||
399 | return (key->priv_key == NULL) ? 0 : 1; | ||
400 | } | ||
401 | |||
402 | const EC_POINT *EC_KEY_get0_public_key(const EC_KEY *key) | ||
403 | { | ||
404 | return key->pub_key; | ||
405 | } | ||
406 | |||
407 | int EC_KEY_set_public_key(EC_KEY *key, const EC_POINT *pub_key) | ||
408 | { | ||
409 | if (key->pub_key != NULL) | ||
410 | EC_POINT_free(key->pub_key); | ||
411 | key->pub_key = EC_POINT_dup(pub_key, key->group); | ||
412 | return (key->pub_key == NULL) ? 0 : 1; | ||
413 | } | ||
414 | |||
415 | unsigned int EC_KEY_get_enc_flags(const EC_KEY *key) | ||
416 | { | ||
417 | return key->enc_flag; | ||
418 | } | ||
419 | |||
420 | void EC_KEY_set_enc_flags(EC_KEY *key, unsigned int flags) | ||
421 | { | ||
422 | key->enc_flag = flags; | ||
423 | } | ||
424 | |||
425 | point_conversion_form_t EC_KEY_get_conv_form(const EC_KEY *key) | ||
426 | { | ||
427 | return key->conv_form; | ||
428 | } | ||
429 | |||
430 | void EC_KEY_set_conv_form(EC_KEY *key, point_conversion_form_t cform) | ||
431 | { | ||
432 | key->conv_form = cform; | ||
433 | if (key->group != NULL) | ||
434 | EC_GROUP_set_point_conversion_form(key->group, cform); | ||
435 | } | ||
436 | |||
437 | void *EC_KEY_get_key_method_data(EC_KEY *key, | ||
438 | void *(*dup_func)(void *), void (*free_func)(void *), void (*clear_free_func)(void *)) | ||
439 | { | ||
440 | return EC_EX_DATA_get_data(key->method_data, dup_func, free_func, clear_free_func); | ||
441 | } | ||
442 | |||
443 | void EC_KEY_insert_key_method_data(EC_KEY *key, void *data, | ||
444 | void *(*dup_func)(void *), void (*free_func)(void *), void (*clear_free_func)(void *)) | ||
445 | { | ||
446 | EC_EXTRA_DATA *ex_data; | ||
447 | CRYPTO_w_lock(CRYPTO_LOCK_EC); | ||
448 | ex_data = EC_EX_DATA_get_data(key->method_data, dup_func, free_func, clear_free_func); | ||
449 | if (ex_data == NULL) | ||
450 | EC_EX_DATA_set_data(&key->method_data, data, dup_func, free_func, clear_free_func); | ||
451 | CRYPTO_w_unlock(CRYPTO_LOCK_EC); | ||
452 | } | ||
453 | |||
454 | void EC_KEY_set_asn1_flag(EC_KEY *key, int flag) | ||
455 | { | ||
456 | if (key->group != NULL) | ||
457 | EC_GROUP_set_asn1_flag(key->group, flag); | ||
458 | } | ||
459 | |||
460 | int EC_KEY_precompute_mult(EC_KEY *key, BN_CTX *ctx) | ||
461 | { | ||
462 | if (key->group == NULL) | ||
463 | return 0; | ||
464 | return EC_GROUP_precompute_mult(key->group, ctx); | ||
465 | } | ||
diff --git a/src/lib/libcrypto/ec/ec_print.c b/src/lib/libcrypto/ec/ec_print.c new file mode 100644 index 0000000000..f7c8a303ac --- /dev/null +++ b/src/lib/libcrypto/ec/ec_print.c | |||
@@ -0,0 +1,195 @@ | |||
1 | /* crypto/ec/ec_print.c */ | ||
2 | /* ==================================================================== | ||
3 | * Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions | ||
7 | * are met: | ||
8 | * | ||
9 | * 1. Redistributions of source code must retain the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer. | ||
11 | * | ||
12 | * 2. Redistributions in binary form must reproduce the above copyright | ||
13 | * notice, this list of conditions and the following disclaimer in | ||
14 | * the documentation and/or other materials provided with the | ||
15 | * distribution. | ||
16 | * | ||
17 | * 3. All advertising materials mentioning features or use of this | ||
18 | * software must display the following acknowledgment: | ||
19 | * "This product includes software developed by the OpenSSL Project | ||
20 | * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" | ||
21 | * | ||
22 | * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to | ||
23 | * endorse or promote products derived from this software without | ||
24 | * prior written permission. For written permission, please contact | ||
25 | * openssl-core@openssl.org. | ||
26 | * | ||
27 | * 5. Products derived from this software may not be called "OpenSSL" | ||
28 | * nor may "OpenSSL" appear in their names without prior written | ||
29 | * permission of the OpenSSL Project. | ||
30 | * | ||
31 | * 6. Redistributions of any form whatsoever must retain the following | ||
32 | * acknowledgment: | ||
33 | * "This product includes software developed by the OpenSSL Project | ||
34 | * for use in the OpenSSL Toolkit (http://www.openssl.org/)" | ||
35 | * | ||
36 | * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY | ||
37 | * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
38 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | ||
39 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR | ||
40 | * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
41 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
42 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
43 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
44 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
45 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
46 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED | ||
47 | * OF THE POSSIBILITY OF SUCH DAMAGE. | ||
48 | * ==================================================================== | ||
49 | * | ||
50 | * This product includes cryptographic software written by Eric Young | ||
51 | * (eay@cryptsoft.com). This product includes software written by Tim | ||
52 | * Hudson (tjh@cryptsoft.com). | ||
53 | * | ||
54 | */ | ||
55 | |||
56 | #include <openssl/crypto.h> | ||
57 | #include "ec_lcl.h" | ||
58 | |||
59 | BIGNUM *EC_POINT_point2bn(const EC_GROUP *group, | ||
60 | const EC_POINT *point, | ||
61 | point_conversion_form_t form, | ||
62 | BIGNUM *ret, | ||
63 | BN_CTX *ctx) | ||
64 | { | ||
65 | size_t buf_len=0; | ||
66 | unsigned char *buf; | ||
67 | |||
68 | buf_len = EC_POINT_point2oct(group, point, form, | ||
69 | NULL, 0, ctx); | ||
70 | if (buf_len == 0) | ||
71 | return NULL; | ||
72 | |||
73 | if ((buf = OPENSSL_malloc(buf_len)) == NULL) | ||
74 | return NULL; | ||
75 | |||
76 | if (!EC_POINT_point2oct(group, point, form, buf, buf_len, ctx)) | ||
77 | { | ||
78 | OPENSSL_free(buf); | ||
79 | return NULL; | ||
80 | } | ||
81 | |||
82 | ret = BN_bin2bn(buf, buf_len, ret); | ||
83 | |||
84 | OPENSSL_free(buf); | ||
85 | |||
86 | return ret; | ||
87 | } | ||
88 | |||
89 | EC_POINT *EC_POINT_bn2point(const EC_GROUP *group, | ||
90 | const BIGNUM *bn, | ||
91 | EC_POINT *point, | ||
92 | BN_CTX *ctx) | ||
93 | { | ||
94 | size_t buf_len=0; | ||
95 | unsigned char *buf; | ||
96 | EC_POINT *ret; | ||
97 | |||
98 | if ((buf_len = BN_num_bytes(bn)) == 0) return NULL; | ||
99 | buf = OPENSSL_malloc(buf_len); | ||
100 | if (buf == NULL) | ||
101 | return NULL; | ||
102 | |||
103 | if (!BN_bn2bin(bn, buf)) | ||
104 | { | ||
105 | OPENSSL_free(buf); | ||
106 | return NULL; | ||
107 | } | ||
108 | |||
109 | if (point == NULL) | ||
110 | { | ||
111 | if ((ret = EC_POINT_new(group)) == NULL) | ||
112 | { | ||
113 | OPENSSL_free(buf); | ||
114 | return NULL; | ||
115 | } | ||
116 | } | ||
117 | else | ||
118 | ret = point; | ||
119 | |||
120 | if (!EC_POINT_oct2point(group, ret, buf, buf_len, ctx)) | ||
121 | { | ||
122 | if (point == NULL) | ||
123 | EC_POINT_clear_free(ret); | ||
124 | OPENSSL_free(buf); | ||
125 | return NULL; | ||
126 | } | ||
127 | |||
128 | OPENSSL_free(buf); | ||
129 | return ret; | ||
130 | } | ||
131 | |||
132 | static const char *HEX_DIGITS = "0123456789ABCDEF"; | ||
133 | |||
134 | /* the return value must be freed (using OPENSSL_free()) */ | ||
135 | char *EC_POINT_point2hex(const EC_GROUP *group, | ||
136 | const EC_POINT *point, | ||
137 | point_conversion_form_t form, | ||
138 | BN_CTX *ctx) | ||
139 | { | ||
140 | char *ret, *p; | ||
141 | size_t buf_len=0,i; | ||
142 | unsigned char *buf, *pbuf; | ||
143 | |||
144 | buf_len = EC_POINT_point2oct(group, point, form, | ||
145 | NULL, 0, ctx); | ||
146 | if (buf_len == 0) | ||
147 | return NULL; | ||
148 | |||
149 | if ((buf = OPENSSL_malloc(buf_len)) == NULL) | ||
150 | return NULL; | ||
151 | |||
152 | if (!EC_POINT_point2oct(group, point, form, buf, buf_len, ctx)) | ||
153 | { | ||
154 | OPENSSL_free(buf); | ||
155 | return NULL; | ||
156 | } | ||
157 | |||
158 | ret = (char *)OPENSSL_malloc(buf_len*2+2); | ||
159 | if (ret == NULL) | ||
160 | { | ||
161 | OPENSSL_free(buf); | ||
162 | return NULL; | ||
163 | } | ||
164 | p = ret; | ||
165 | pbuf = buf; | ||
166 | for (i=buf_len; i > 0; i--) | ||
167 | { | ||
168 | int v = (int) *(pbuf++); | ||
169 | *(p++)=HEX_DIGITS[v>>4]; | ||
170 | *(p++)=HEX_DIGITS[v&0x0F]; | ||
171 | } | ||
172 | *p='\0'; | ||
173 | |||
174 | OPENSSL_free(buf); | ||
175 | |||
176 | return ret; | ||
177 | } | ||
178 | |||
179 | EC_POINT *EC_POINT_hex2point(const EC_GROUP *group, | ||
180 | const char *buf, | ||
181 | EC_POINT *point, | ||
182 | BN_CTX *ctx) | ||
183 | { | ||
184 | EC_POINT *ret=NULL; | ||
185 | BIGNUM *tmp_bn=NULL; | ||
186 | |||
187 | if (!BN_hex2bn(&tmp_bn, buf)) | ||
188 | return NULL; | ||
189 | |||
190 | ret = EC_POINT_bn2point(group, tmp_bn, point, ctx); | ||
191 | |||
192 | BN_clear_free(tmp_bn); | ||
193 | |||
194 | return ret; | ||
195 | } | ||
diff --git a/src/lib/libcrypto/ecdh/ecdh.h b/src/lib/libcrypto/ecdh/ecdh.h new file mode 100644 index 0000000000..b4b58ee65b --- /dev/null +++ b/src/lib/libcrypto/ecdh/ecdh.h | |||
@@ -0,0 +1,123 @@ | |||
1 | /* crypto/ecdh/ecdh.h */ | ||
2 | /* ==================================================================== | ||
3 | * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. | ||
4 | * | ||
5 | * The Elliptic Curve Public-Key Crypto Library (ECC Code) included | ||
6 | * herein is developed by SUN MICROSYSTEMS, INC., and is contributed | ||
7 | * to the OpenSSL project. | ||
8 | * | ||
9 | * The ECC Code is licensed pursuant to the OpenSSL open source | ||
10 | * license provided below. | ||
11 | * | ||
12 | * The ECDH software is originally written by Douglas Stebila of | ||
13 | * Sun Microsystems Laboratories. | ||
14 | * | ||
15 | */ | ||
16 | /* ==================================================================== | ||
17 | * Copyright (c) 2000-2002 The OpenSSL Project. All rights reserved. | ||
18 | * | ||
19 | * Redistribution and use in source and binary forms, with or without | ||
20 | * modification, are permitted provided that the following conditions | ||
21 | * are met: | ||
22 | * | ||
23 | * 1. Redistributions of source code must retain the above copyright | ||
24 | * notice, this list of conditions and the following disclaimer. | ||
25 | * | ||
26 | * 2. Redistributions in binary form must reproduce the above copyright | ||
27 | * notice, this list of conditions and the following disclaimer in | ||
28 | * the documentation and/or other materials provided with the | ||
29 | * distribution. | ||
30 | * | ||
31 | * 3. All advertising materials mentioning features or use of this | ||
32 | * software must display the following acknowledgment: | ||
33 | * "This product includes software developed by the OpenSSL Project | ||
34 | * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" | ||
35 | * | ||
36 | * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to | ||
37 | * endorse or promote products derived from this software without | ||
38 | * prior written permission. For written permission, please contact | ||
39 | * licensing@OpenSSL.org. | ||
40 | * | ||
41 | * 5. Products derived from this software may not be called "OpenSSL" | ||
42 | * nor may "OpenSSL" appear in their names without prior written | ||
43 | * permission of the OpenSSL Project. | ||
44 | * | ||
45 | * 6. Redistributions of any form whatsoever must retain the following | ||
46 | * acknowledgment: | ||
47 | * "This product includes software developed by the OpenSSL Project | ||
48 | * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" | ||
49 | * | ||
50 | * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY | ||
51 | * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
52 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | ||
53 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR | ||
54 | * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
55 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
56 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
57 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
58 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
59 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
60 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED | ||
61 | * OF THE POSSIBILITY OF SUCH DAMAGE. | ||
62 | * ==================================================================== | ||
63 | * | ||
64 | * This product includes cryptographic software written by Eric Young | ||
65 | * (eay@cryptsoft.com). This product includes software written by Tim | ||
66 | * Hudson (tjh@cryptsoft.com). | ||
67 | * | ||
68 | */ | ||
69 | #ifndef HEADER_ECDH_H | ||
70 | #define HEADER_ECDH_H | ||
71 | |||
72 | #include <openssl/opensslconf.h> | ||
73 | |||
74 | #ifdef OPENSSL_NO_ECDH | ||
75 | #error ECDH is disabled. | ||
76 | #endif | ||
77 | |||
78 | #include <openssl/ec.h> | ||
79 | #include <openssl/ossl_typ.h> | ||
80 | #ifndef OPENSSL_NO_DEPRECATED | ||
81 | #include <openssl/bn.h> | ||
82 | #endif | ||
83 | |||
84 | #ifdef __cplusplus | ||
85 | extern "C" { | ||
86 | #endif | ||
87 | |||
88 | const ECDH_METHOD *ECDH_OpenSSL(void); | ||
89 | |||
90 | void ECDH_set_default_method(const ECDH_METHOD *); | ||
91 | const ECDH_METHOD *ECDH_get_default_method(void); | ||
92 | int ECDH_set_method(EC_KEY *, const ECDH_METHOD *); | ||
93 | |||
94 | int ECDH_compute_key(void *out, size_t outlen, const EC_POINT *pub_key, EC_KEY *ecdh, | ||
95 | void *(*KDF)(const void *in, size_t inlen, void *out, size_t *outlen)); | ||
96 | |||
97 | int ECDH_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new | ||
98 | *new_func, CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func); | ||
99 | int ECDH_set_ex_data(EC_KEY *d, int idx, void *arg); | ||
100 | void *ECDH_get_ex_data(EC_KEY *d, int idx); | ||
101 | |||
102 | |||
103 | /* BEGIN ERROR CODES */ | ||
104 | /* The following lines are auto generated by the script mkerr.pl. Any changes | ||
105 | * made after this point may be overwritten when the script is next run. | ||
106 | */ | ||
107 | void ERR_load_ECDH_strings(void); | ||
108 | |||
109 | /* Error codes for the ECDH functions. */ | ||
110 | |||
111 | /* Function codes. */ | ||
112 | #define ECDH_F_ECDH_COMPUTE_KEY 100 | ||
113 | #define ECDH_F_ECDH_DATA_NEW_METHOD 101 | ||
114 | |||
115 | /* Reason codes. */ | ||
116 | #define ECDH_R_KDF_FAILED 102 | ||
117 | #define ECDH_R_NO_PRIVATE_VALUE 100 | ||
118 | #define ECDH_R_POINT_ARITHMETIC_FAILURE 101 | ||
119 | |||
120 | #ifdef __cplusplus | ||
121 | } | ||
122 | #endif | ||
123 | #endif | ||
diff --git a/src/lib/libcrypto/ecdh/ech_err.c b/src/lib/libcrypto/ecdh/ech_err.c new file mode 100644 index 0000000000..4d2ede75bd --- /dev/null +++ b/src/lib/libcrypto/ecdh/ech_err.c | |||
@@ -0,0 +1,98 @@ | |||
1 | /* crypto/ecdh/ech_err.c */ | ||
2 | /* ==================================================================== | ||
3 | * Copyright (c) 1999-2005 The OpenSSL Project. All rights reserved. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions | ||
7 | * are met: | ||
8 | * | ||
9 | * 1. Redistributions of source code must retain the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer. | ||
11 | * | ||
12 | * 2. Redistributions in binary form must reproduce the above copyright | ||
13 | * notice, this list of conditions and the following disclaimer in | ||
14 | * the documentation and/or other materials provided with the | ||
15 | * distribution. | ||
16 | * | ||
17 | * 3. All advertising materials mentioning features or use of this | ||
18 | * software must display the following acknowledgment: | ||
19 | * "This product includes software developed by the OpenSSL Project | ||
20 | * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" | ||
21 | * | ||
22 | * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to | ||
23 | * endorse or promote products derived from this software without | ||
24 | * prior written permission. For written permission, please contact | ||
25 | * openssl-core@OpenSSL.org. | ||
26 | * | ||
27 | * 5. Products derived from this software may not be called "OpenSSL" | ||
28 | * nor may "OpenSSL" appear in their names without prior written | ||
29 | * permission of the OpenSSL Project. | ||
30 | * | ||
31 | * 6. Redistributions of any form whatsoever must retain the following | ||
32 | * acknowledgment: | ||
33 | * "This product includes software developed by the OpenSSL Project | ||
34 | * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" | ||
35 | * | ||
36 | * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY | ||
37 | * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
38 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | ||
39 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR | ||
40 | * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
41 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
42 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
43 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
44 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
45 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
46 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED | ||
47 | * OF THE POSSIBILITY OF SUCH DAMAGE. | ||
48 | * ==================================================================== | ||
49 | * | ||
50 | * This product includes cryptographic software written by Eric Young | ||
51 | * (eay@cryptsoft.com). This product includes software written by Tim | ||
52 | * Hudson (tjh@cryptsoft.com). | ||
53 | * | ||
54 | */ | ||
55 | |||
56 | /* NOTE: this file was auto generated by the mkerr.pl script: any changes | ||
57 | * made to it will be overwritten when the script next updates this file, | ||
58 | * only reason strings will be preserved. | ||
59 | */ | ||
60 | |||
61 | #include <stdio.h> | ||
62 | #include <openssl/err.h> | ||
63 | #include <openssl/ecdh.h> | ||
64 | |||
65 | /* BEGIN ERROR CODES */ | ||
66 | #ifndef OPENSSL_NO_ERR | ||
67 | |||
68 | #define ERR_FUNC(func) ERR_PACK(ERR_LIB_ECDH,func,0) | ||
69 | #define ERR_REASON(reason) ERR_PACK(ERR_LIB_ECDH,0,reason) | ||
70 | |||
71 | static ERR_STRING_DATA ECDH_str_functs[]= | ||
72 | { | ||
73 | {ERR_FUNC(ECDH_F_ECDH_COMPUTE_KEY), "ECDH_compute_key"}, | ||
74 | {ERR_FUNC(ECDH_F_ECDH_DATA_NEW_METHOD), "ECDH_DATA_NEW_METHOD"}, | ||
75 | {0,NULL} | ||
76 | }; | ||
77 | |||
78 | static ERR_STRING_DATA ECDH_str_reasons[]= | ||
79 | { | ||
80 | {ERR_REASON(ECDH_R_KDF_FAILED) ,"KDF failed"}, | ||
81 | {ERR_REASON(ECDH_R_NO_PRIVATE_VALUE) ,"no private value"}, | ||
82 | {ERR_REASON(ECDH_R_POINT_ARITHMETIC_FAILURE),"point arithmetic failure"}, | ||
83 | {0,NULL} | ||
84 | }; | ||
85 | |||
86 | #endif | ||
87 | |||
88 | void ERR_load_ECDH_strings(void) | ||
89 | { | ||
90 | #ifndef OPENSSL_NO_ERR | ||
91 | |||
92 | if (ERR_func_error_string(ECDH_str_functs[0].error) == NULL) | ||
93 | { | ||
94 | ERR_load_strings(0,ECDH_str_functs); | ||
95 | ERR_load_strings(0,ECDH_str_reasons); | ||
96 | } | ||
97 | #endif | ||
98 | } | ||
diff --git a/src/lib/libcrypto/ecdh/ech_key.c b/src/lib/libcrypto/ecdh/ech_key.c new file mode 100644 index 0000000000..f44da9298b --- /dev/null +++ b/src/lib/libcrypto/ecdh/ech_key.c | |||
@@ -0,0 +1,83 @@ | |||
1 | /* crypto/ecdh/ecdh_key.c */ | ||
2 | /* ==================================================================== | ||
3 | * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. | ||
4 | * | ||
5 | * The Elliptic Curve Public-Key Crypto Library (ECC Code) included | ||
6 | * herein is developed by SUN MICROSYSTEMS, INC., and is contributed | ||
7 | * to the OpenSSL project. | ||
8 | * | ||
9 | * The ECC Code is licensed pursuant to the OpenSSL open source | ||
10 | * license provided below. | ||
11 | * | ||
12 | * The ECDH software is originally written by Douglas Stebila of | ||
13 | * Sun Microsystems Laboratories. | ||
14 | * | ||
15 | */ | ||
16 | /* ==================================================================== | ||
17 | * Copyright (c) 1998-2003 The OpenSSL Project. All rights reserved. | ||
18 | * | ||
19 | * Redistribution and use in source and binary forms, with or without | ||
20 | * modification, are permitted provided that the following conditions | ||
21 | * are met: | ||
22 | * | ||
23 | * 1. Redistributions of source code must retain the above copyright | ||
24 | * notice, this list of conditions and the following disclaimer. | ||
25 | * | ||
26 | * 2. Redistributions in binary form must reproduce the above copyright | ||
27 | * notice, this list of conditions and the following disclaimer in | ||
28 | * the documentation and/or other materials provided with the | ||
29 | * distribution. | ||
30 | * | ||
31 | * 3. All advertising materials mentioning features or use of this | ||
32 | * software must display the following acknowledgment: | ||
33 | * "This product includes software developed by the OpenSSL Project | ||
34 | * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" | ||
35 | * | ||
36 | * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to | ||
37 | * endorse or promote products derived from this software without | ||
38 | * prior written permission. For written permission, please contact | ||
39 | * openssl-core@OpenSSL.org. | ||
40 | * | ||
41 | * 5. Products derived from this software may not be called "OpenSSL" | ||
42 | * nor may "OpenSSL" appear in their names without prior written | ||
43 | * permission of the OpenSSL Project. | ||
44 | * | ||
45 | * 6. Redistributions of any form whatsoever must retain the following | ||
46 | * acknowledgment: | ||
47 | * "This product includes software developed by the OpenSSL Project | ||
48 | * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" | ||
49 | * | ||
50 | * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY | ||
51 | * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
52 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | ||
53 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR | ||
54 | * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
55 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
56 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
57 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
58 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
59 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
60 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED | ||
61 | * OF THE POSSIBILITY OF SUCH DAMAGE. | ||
62 | * ==================================================================== | ||
63 | * | ||
64 | * This product includes cryptographic software written by Eric Young | ||
65 | * (eay@cryptsoft.com). This product includes software written by Tim | ||
66 | * Hudson (tjh@cryptsoft.com). | ||
67 | * | ||
68 | */ | ||
69 | |||
70 | #include "ech_locl.h" | ||
71 | #ifndef OPENSSL_NO_ENGINE | ||
72 | #include <openssl/engine.h> | ||
73 | #endif | ||
74 | |||
75 | int ECDH_compute_key(void *out, size_t outlen, const EC_POINT *pub_key, | ||
76 | EC_KEY *eckey, | ||
77 | void *(*KDF)(const void *in, size_t inlen, void *out, size_t *outlen)) | ||
78 | { | ||
79 | ECDH_DATA *ecdh = ecdh_check(eckey); | ||
80 | if (ecdh == NULL) | ||
81 | return 0; | ||
82 | return ecdh->meth->compute_key(out, outlen, pub_key, eckey, KDF); | ||
83 | } | ||
diff --git a/src/lib/libcrypto/ecdh/ech_lib.c b/src/lib/libcrypto/ecdh/ech_lib.c new file mode 100644 index 0000000000..e89b1d4772 --- /dev/null +++ b/src/lib/libcrypto/ecdh/ech_lib.c | |||
@@ -0,0 +1,247 @@ | |||
1 | /* crypto/ecdh/ech_lib.c */ | ||
2 | /* ==================================================================== | ||
3 | * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. | ||
4 | * | ||
5 | * The Elliptic Curve Public-Key Crypto Library (ECC Code) included | ||
6 | * herein is developed by SUN MICROSYSTEMS, INC., and is contributed | ||
7 | * to the OpenSSL project. | ||
8 | * | ||
9 | * The ECC Code is licensed pursuant to the OpenSSL open source | ||
10 | * license provided below. | ||
11 | * | ||
12 | * The ECDH software is originally written by Douglas Stebila of | ||
13 | * Sun Microsystems Laboratories. | ||
14 | * | ||
15 | */ | ||
16 | /* ==================================================================== | ||
17 | * Copyright (c) 1998-2003 The OpenSSL Project. All rights reserved. | ||
18 | * | ||
19 | * Redistribution and use in source and binary forms, with or without | ||
20 | * modification, are permitted provided that the following conditions | ||
21 | * are met: | ||
22 | * | ||
23 | * 1. Redistributions of source code must retain the above copyright | ||
24 | * notice, this list of conditions and the following disclaimer. | ||
25 | * | ||
26 | * 2. Redistributions in binary form must reproduce the above copyright | ||
27 | * notice, this list of conditions and the following disclaimer in | ||
28 | * the documentation and/or other materials provided with the | ||
29 | * distribution. | ||
30 | * | ||
31 | * 3. All advertising materials mentioning features or use of this | ||
32 | * software must display the following acknowledgment: | ||
33 | * "This product includes software developed by the OpenSSL Project | ||
34 | * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" | ||
35 | * | ||
36 | * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to | ||
37 | * endorse or promote products derived from this software without | ||
38 | * prior written permission. For written permission, please contact | ||
39 | * openssl-core@OpenSSL.org. | ||
40 | * | ||
41 | * 5. Products derived from this software may not be called "OpenSSL" | ||
42 | * nor may "OpenSSL" appear in their names without prior written | ||
43 | * permission of the OpenSSL Project. | ||
44 | * | ||
45 | * 6. Redistributions of any form whatsoever must retain the following | ||
46 | * acknowledgment: | ||
47 | * "This product includes software developed by the OpenSSL Project | ||
48 | * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" | ||
49 | * | ||
50 | * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY | ||
51 | * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
52 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | ||
53 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR | ||
54 | * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
55 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
56 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
57 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
58 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
59 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
60 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED | ||
61 | * OF THE POSSIBILITY OF SUCH DAMAGE. | ||
62 | * ==================================================================== | ||
63 | * | ||
64 | * This product includes cryptographic software written by Eric Young | ||
65 | * (eay@cryptsoft.com). This product includes software written by Tim | ||
66 | * Hudson (tjh@cryptsoft.com). | ||
67 | * | ||
68 | */ | ||
69 | |||
70 | #include "ech_locl.h" | ||
71 | #include <string.h> | ||
72 | #ifndef OPENSSL_NO_ENGINE | ||
73 | #include <openssl/engine.h> | ||
74 | #endif | ||
75 | #include <openssl/err.h> | ||
76 | |||
77 | const char ECDH_version[]="ECDH" OPENSSL_VERSION_PTEXT; | ||
78 | |||
79 | static const ECDH_METHOD *default_ECDH_method = NULL; | ||
80 | |||
81 | static void *ecdh_data_new(void); | ||
82 | static void *ecdh_data_dup(void *); | ||
83 | static void ecdh_data_free(void *); | ||
84 | |||
85 | void ECDH_set_default_method(const ECDH_METHOD *meth) | ||
86 | { | ||
87 | default_ECDH_method = meth; | ||
88 | } | ||
89 | |||
90 | const ECDH_METHOD *ECDH_get_default_method(void) | ||
91 | { | ||
92 | if(!default_ECDH_method) | ||
93 | default_ECDH_method = ECDH_OpenSSL(); | ||
94 | return default_ECDH_method; | ||
95 | } | ||
96 | |||
97 | int ECDH_set_method(EC_KEY *eckey, const ECDH_METHOD *meth) | ||
98 | { | ||
99 | const ECDH_METHOD *mtmp; | ||
100 | ECDH_DATA *ecdh; | ||
101 | |||
102 | ecdh = ecdh_check(eckey); | ||
103 | |||
104 | if (ecdh == NULL) | ||
105 | return 0; | ||
106 | |||
107 | mtmp = ecdh->meth; | ||
108 | #if 0 | ||
109 | if (mtmp->finish) | ||
110 | mtmp->finish(eckey); | ||
111 | #endif | ||
112 | #ifndef OPENSSL_NO_ENGINE | ||
113 | if (ecdh->engine) | ||
114 | { | ||
115 | ENGINE_finish(ecdh->engine); | ||
116 | ecdh->engine = NULL; | ||
117 | } | ||
118 | #endif | ||
119 | ecdh->meth = meth; | ||
120 | #if 0 | ||
121 | if (meth->init) | ||
122 | meth->init(eckey); | ||
123 | #endif | ||
124 | return 1; | ||
125 | } | ||
126 | |||
127 | static ECDH_DATA *ECDH_DATA_new_method(ENGINE *engine) | ||
128 | { | ||
129 | ECDH_DATA *ret; | ||
130 | |||
131 | ret=(ECDH_DATA *)OPENSSL_malloc(sizeof(ECDH_DATA)); | ||
132 | if (ret == NULL) | ||
133 | { | ||
134 | ECDHerr(ECDH_F_ECDH_DATA_NEW_METHOD, ERR_R_MALLOC_FAILURE); | ||
135 | return(NULL); | ||
136 | } | ||
137 | |||
138 | ret->init = NULL; | ||
139 | |||
140 | ret->meth = ECDH_get_default_method(); | ||
141 | ret->engine = engine; | ||
142 | #ifndef OPENSSL_NO_ENGINE | ||
143 | if (!ret->engine) | ||
144 | ret->engine = ENGINE_get_default_ECDH(); | ||
145 | if (ret->engine) | ||
146 | { | ||
147 | ret->meth = ENGINE_get_ECDH(ret->engine); | ||
148 | if (!ret->meth) | ||
149 | { | ||
150 | ECDHerr(ECDH_F_ECDH_DATA_NEW_METHOD, ERR_R_ENGINE_LIB); | ||
151 | ENGINE_finish(ret->engine); | ||
152 | OPENSSL_free(ret); | ||
153 | return NULL; | ||
154 | } | ||
155 | } | ||
156 | #endif | ||
157 | |||
158 | ret->flags = ret->meth->flags; | ||
159 | CRYPTO_new_ex_data(CRYPTO_EX_INDEX_ECDH, ret, &ret->ex_data); | ||
160 | #if 0 | ||
161 | if ((ret->meth->init != NULL) && !ret->meth->init(ret)) | ||
162 | { | ||
163 | CRYPTO_free_ex_data(CRYPTO_EX_INDEX_ECDH, ret, &ret->ex_data); | ||
164 | OPENSSL_free(ret); | ||
165 | ret=NULL; | ||
166 | } | ||
167 | #endif | ||
168 | return(ret); | ||
169 | } | ||
170 | |||
171 | static void *ecdh_data_new(void) | ||
172 | { | ||
173 | return (void *)ECDH_DATA_new_method(NULL); | ||
174 | } | ||
175 | |||
176 | static void *ecdh_data_dup(void *data) | ||
177 | { | ||
178 | ECDH_DATA *r = (ECDH_DATA *)data; | ||
179 | |||
180 | /* XXX: dummy operation */ | ||
181 | if (r == NULL) | ||
182 | return NULL; | ||
183 | |||
184 | return (void *)ecdh_data_new(); | ||
185 | } | ||
186 | |||
187 | void ecdh_data_free(void *data) | ||
188 | { | ||
189 | ECDH_DATA *r = (ECDH_DATA *)data; | ||
190 | |||
191 | #ifndef OPENSSL_NO_ENGINE | ||
192 | if (r->engine) | ||
193 | ENGINE_finish(r->engine); | ||
194 | #endif | ||
195 | |||
196 | CRYPTO_free_ex_data(CRYPTO_EX_INDEX_ECDH, r, &r->ex_data); | ||
197 | |||
198 | OPENSSL_cleanse((void *)r, sizeof(ECDH_DATA)); | ||
199 | |||
200 | OPENSSL_free(r); | ||
201 | } | ||
202 | |||
203 | ECDH_DATA *ecdh_check(EC_KEY *key) | ||
204 | { | ||
205 | ECDH_DATA *ecdh_data; | ||
206 | |||
207 | void *data = EC_KEY_get_key_method_data(key, ecdh_data_dup, | ||
208 | ecdh_data_free, ecdh_data_free); | ||
209 | if (data == NULL) | ||
210 | { | ||
211 | ecdh_data = (ECDH_DATA *)ecdh_data_new(); | ||
212 | if (ecdh_data == NULL) | ||
213 | return NULL; | ||
214 | EC_KEY_insert_key_method_data(key, (void *)ecdh_data, | ||
215 | ecdh_data_dup, ecdh_data_free, ecdh_data_free); | ||
216 | } | ||
217 | else | ||
218 | ecdh_data = (ECDH_DATA *)data; | ||
219 | |||
220 | |||
221 | return ecdh_data; | ||
222 | } | ||
223 | |||
224 | int ECDH_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, | ||
225 | CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func) | ||
226 | { | ||
227 | return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_ECDH, argl, argp, | ||
228 | new_func, dup_func, free_func); | ||
229 | } | ||
230 | |||
231 | int ECDH_set_ex_data(EC_KEY *d, int idx, void *arg) | ||
232 | { | ||
233 | ECDH_DATA *ecdh; | ||
234 | ecdh = ecdh_check(d); | ||
235 | if (ecdh == NULL) | ||
236 | return 0; | ||
237 | return(CRYPTO_set_ex_data(&ecdh->ex_data,idx,arg)); | ||
238 | } | ||
239 | |||
240 | void *ECDH_get_ex_data(EC_KEY *d, int idx) | ||
241 | { | ||
242 | ECDH_DATA *ecdh; | ||
243 | ecdh = ecdh_check(d); | ||
244 | if (ecdh == NULL) | ||
245 | return NULL; | ||
246 | return(CRYPTO_get_ex_data(&ecdh->ex_data,idx)); | ||
247 | } | ||
diff --git a/src/lib/libcrypto/ecdh/ech_locl.h b/src/lib/libcrypto/ecdh/ech_locl.h new file mode 100644 index 0000000000..f658526a7e --- /dev/null +++ b/src/lib/libcrypto/ecdh/ech_locl.h | |||
@@ -0,0 +1,94 @@ | |||
1 | /* crypto/ecdh/ech_locl.h */ | ||
2 | /* ==================================================================== | ||
3 | * Copyright (c) 2000-2005 The OpenSSL Project. All rights reserved. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions | ||
7 | * are met: | ||
8 | * | ||
9 | * 1. Redistributions of source code must retain the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer. | ||
11 | * | ||
12 | * 2. Redistributions in binary form must reproduce the above copyright | ||
13 | * notice, this list of conditions and the following disclaimer in | ||
14 | * the documentation and/or other materials provided with the | ||
15 | * distribution. | ||
16 | * | ||
17 | * 3. All advertising materials mentioning features or use of this | ||
18 | * software must display the following acknowledgment: | ||
19 | * "This product includes software developed by the OpenSSL Project | ||
20 | * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" | ||
21 | * | ||
22 | * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to | ||
23 | * endorse or promote products derived from this software without | ||
24 | * prior written permission. For written permission, please contact | ||
25 | * licensing@OpenSSL.org. | ||
26 | * | ||
27 | * 5. Products derived from this software may not be called "OpenSSL" | ||
28 | * nor may "OpenSSL" appear in their names without prior written | ||
29 | * permission of the OpenSSL Project. | ||
30 | * | ||
31 | * 6. Redistributions of any form whatsoever must retain the following | ||
32 | * acknowledgment: | ||
33 | * "This product includes software developed by the OpenSSL Project | ||
34 | * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" | ||
35 | * | ||
36 | * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY | ||
37 | * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
38 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | ||
39 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR | ||
40 | * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
41 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
42 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
43 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
44 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
45 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
46 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED | ||
47 | * OF THE POSSIBILITY OF SUCH DAMAGE. | ||
48 | * ==================================================================== | ||
49 | * | ||
50 | * This product includes cryptographic software written by Eric Young | ||
51 | * (eay@cryptsoft.com). This product includes software written by Tim | ||
52 | * Hudson (tjh@cryptsoft.com). | ||
53 | * | ||
54 | */ | ||
55 | |||
56 | #ifndef HEADER_ECH_LOCL_H | ||
57 | #define HEADER_ECH_LOCL_H | ||
58 | |||
59 | #include <openssl/ecdh.h> | ||
60 | |||
61 | #ifdef __cplusplus | ||
62 | extern "C" { | ||
63 | #endif | ||
64 | |||
65 | struct ecdh_method | ||
66 | { | ||
67 | const char *name; | ||
68 | int (*compute_key)(void *key, size_t outlen, const EC_POINT *pub_key, EC_KEY *ecdh, | ||
69 | void *(*KDF)(const void *in, size_t inlen, void *out, size_t *outlen)); | ||
70 | #if 0 | ||
71 | int (*init)(EC_KEY *eckey); | ||
72 | int (*finish)(EC_KEY *eckey); | ||
73 | #endif | ||
74 | int flags; | ||
75 | char *app_data; | ||
76 | }; | ||
77 | |||
78 | typedef struct ecdh_data_st { | ||
79 | /* EC_KEY_METH_DATA part */ | ||
80 | int (*init)(EC_KEY *); | ||
81 | /* method specific part */ | ||
82 | ENGINE *engine; | ||
83 | int flags; | ||
84 | const ECDH_METHOD *meth; | ||
85 | CRYPTO_EX_DATA ex_data; | ||
86 | } ECDH_DATA; | ||
87 | |||
88 | ECDH_DATA *ecdh_check(EC_KEY *); | ||
89 | |||
90 | #ifdef __cplusplus | ||
91 | } | ||
92 | #endif | ||
93 | |||
94 | #endif /* HEADER_ECH_LOCL_H */ | ||
diff --git a/src/lib/libcrypto/ecdsa/ecdsa.h b/src/lib/libcrypto/ecdsa/ecdsa.h new file mode 100644 index 0000000000..f20c8ee738 --- /dev/null +++ b/src/lib/libcrypto/ecdsa/ecdsa.h | |||
@@ -0,0 +1,271 @@ | |||
1 | /* crypto/ecdsa/ecdsa.h */ | ||
2 | /** | ||
3 | * \file crypto/ecdsa/ecdsa.h Include file for the OpenSSL ECDSA functions | ||
4 | * \author Written by Nils Larsch for the OpenSSL project | ||
5 | */ | ||
6 | /* ==================================================================== | ||
7 | * Copyright (c) 2000-2003 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 | * This product includes cryptographic software written by Eric Young | ||
55 | * (eay@cryptsoft.com). This product includes software written by Tim | ||
56 | * Hudson (tjh@cryptsoft.com). | ||
57 | * | ||
58 | */ | ||
59 | #ifndef HEADER_ECDSA_H | ||
60 | #define HEADER_ECDSA_H | ||
61 | |||
62 | #include <openssl/opensslconf.h> | ||
63 | |||
64 | #ifdef OPENSSL_NO_ECDSA | ||
65 | #error ECDSA is disabled. | ||
66 | #endif | ||
67 | |||
68 | #include <openssl/ec.h> | ||
69 | #include <openssl/ossl_typ.h> | ||
70 | #ifndef OPENSSL_NO_DEPRECATED | ||
71 | #include <openssl/bn.h> | ||
72 | #endif | ||
73 | |||
74 | #ifdef __cplusplus | ||
75 | extern "C" { | ||
76 | #endif | ||
77 | |||
78 | typedef struct ECDSA_SIG_st | ||
79 | { | ||
80 | BIGNUM *r; | ||
81 | BIGNUM *s; | ||
82 | } ECDSA_SIG; | ||
83 | |||
84 | /** ECDSA_SIG *ECDSA_SIG_new(void) | ||
85 | * allocates and initialize a ECDSA_SIG structure | ||
86 | * \return pointer to a ECDSA_SIG structure or NULL if an error occurred | ||
87 | */ | ||
88 | ECDSA_SIG *ECDSA_SIG_new(void); | ||
89 | |||
90 | /** ECDSA_SIG_free | ||
91 | * frees a ECDSA_SIG structure | ||
92 | * \param a pointer to the ECDSA_SIG structure | ||
93 | */ | ||
94 | void ECDSA_SIG_free(ECDSA_SIG *a); | ||
95 | |||
96 | /** i2d_ECDSA_SIG | ||
97 | * DER encode content of ECDSA_SIG object (note: this function modifies *pp | ||
98 | * (*pp += length of the DER encoded signature)). | ||
99 | * \param a pointer to the ECDSA_SIG object | ||
100 | * \param pp pointer to a unsigned char pointer for the output or NULL | ||
101 | * \return the length of the DER encoded ECDSA_SIG object or 0 | ||
102 | */ | ||
103 | int i2d_ECDSA_SIG(const ECDSA_SIG *a, unsigned char **pp); | ||
104 | |||
105 | /** d2i_ECDSA_SIG | ||
106 | * decodes a DER encoded ECDSA signature (note: this function changes *pp | ||
107 | * (*pp += len)). | ||
108 | * \param v pointer to ECDSA_SIG pointer (may be NULL) | ||
109 | * \param pp buffer with the DER encoded signature | ||
110 | * \param len bufferlength | ||
111 | * \return pointer to the decoded ECDSA_SIG structure (or NULL) | ||
112 | */ | ||
113 | ECDSA_SIG *d2i_ECDSA_SIG(ECDSA_SIG **v, const unsigned char **pp, long len); | ||
114 | |||
115 | /** ECDSA_do_sign | ||
116 | * computes the ECDSA signature of the given hash value using | ||
117 | * the supplied private key and returns the created signature. | ||
118 | * \param dgst pointer to the hash value | ||
119 | * \param dgst_len length of the hash value | ||
120 | * \param eckey pointer to the EC_KEY object containing a private EC key | ||
121 | * \return pointer to a ECDSA_SIG structure or NULL | ||
122 | */ | ||
123 | ECDSA_SIG *ECDSA_do_sign(const unsigned char *dgst,int dgst_len,EC_KEY *eckey); | ||
124 | |||
125 | /** ECDSA_do_sign_ex | ||
126 | * computes ECDSA signature of a given hash value using the supplied | ||
127 | * private key (note: sig must point to ECDSA_size(eckey) bytes of memory). | ||
128 | * \param dgst pointer to the hash value to sign | ||
129 | * \param dgstlen length of the hash value | ||
130 | * \param kinv optional pointer to a pre-computed inverse k | ||
131 | * \param rp optional pointer to the pre-computed rp value (see | ||
132 | * ECDSA_sign_setup | ||
133 | * \param eckey pointer to the EC_KEY object containing a private EC key | ||
134 | * \return pointer to a ECDSA_SIG structure or NULL | ||
135 | */ | ||
136 | ECDSA_SIG *ECDSA_do_sign_ex(const unsigned char *dgst, int dgstlen, | ||
137 | const BIGNUM *kinv, const BIGNUM *rp, EC_KEY *eckey); | ||
138 | |||
139 | /** ECDSA_do_verify | ||
140 | * verifies that the supplied signature is a valid ECDSA | ||
141 | * signature of the supplied hash value using the supplied public key. | ||
142 | * \param dgst pointer to the hash value | ||
143 | * \param dgst_len length of the hash value | ||
144 | * \param sig pointer to the ECDSA_SIG structure | ||
145 | * \param eckey pointer to the EC_KEY object containing a public EC key | ||
146 | * \return 1 if the signature is valid, 0 if the signature is invalid and -1 on error | ||
147 | */ | ||
148 | int ECDSA_do_verify(const unsigned char *dgst, int dgst_len, | ||
149 | const ECDSA_SIG *sig, EC_KEY* eckey); | ||
150 | |||
151 | const ECDSA_METHOD *ECDSA_OpenSSL(void); | ||
152 | |||
153 | /** ECDSA_set_default_method | ||
154 | * sets the default ECDSA method | ||
155 | * \param meth the new default ECDSA_METHOD | ||
156 | */ | ||
157 | void ECDSA_set_default_method(const ECDSA_METHOD *meth); | ||
158 | |||
159 | /** ECDSA_get_default_method | ||
160 | * returns the default ECDSA method | ||
161 | * \return pointer to ECDSA_METHOD structure containing the default method | ||
162 | */ | ||
163 | const ECDSA_METHOD *ECDSA_get_default_method(void); | ||
164 | |||
165 | /** ECDSA_set_method | ||
166 | * sets method to be used for the ECDSA operations | ||
167 | * \param eckey pointer to the EC_KEY object | ||
168 | * \param meth pointer to the new method | ||
169 | * \return 1 on success and 0 otherwise | ||
170 | */ | ||
171 | int ECDSA_set_method(EC_KEY *eckey, const ECDSA_METHOD *meth); | ||
172 | |||
173 | /** ECDSA_size | ||
174 | * returns the maximum length of the DER encoded signature | ||
175 | * \param eckey pointer to a EC_KEY object | ||
176 | * \return numbers of bytes required for the DER encoded signature | ||
177 | */ | ||
178 | int ECDSA_size(const EC_KEY *eckey); | ||
179 | |||
180 | /** ECDSA_sign_setup | ||
181 | * precompute parts of the signing operation. | ||
182 | * \param eckey pointer to the EC_KEY object containing a private EC key | ||
183 | * \param ctx pointer to a BN_CTX object (may be NULL) | ||
184 | * \param kinv pointer to a BIGNUM pointer for the inverse of k | ||
185 | * \param rp pointer to a BIGNUM pointer for x coordinate of k * generator | ||
186 | * \return 1 on success and 0 otherwise | ||
187 | */ | ||
188 | int ECDSA_sign_setup(EC_KEY *eckey, BN_CTX *ctx, BIGNUM **kinv, | ||
189 | BIGNUM **rp); | ||
190 | |||
191 | /** ECDSA_sign | ||
192 | * computes ECDSA signature of a given hash value using the supplied | ||
193 | * private key (note: sig must point to ECDSA_size(eckey) bytes of memory). | ||
194 | * \param type this parameter is ignored | ||
195 | * \param dgst pointer to the hash value to sign | ||
196 | * \param dgstlen length of the hash value | ||
197 | * \param sig buffer to hold the DER encoded signature | ||
198 | * \param siglen pointer to the length of the returned signature | ||
199 | * \param eckey pointer to the EC_KEY object containing a private EC key | ||
200 | * \return 1 on success and 0 otherwise | ||
201 | */ | ||
202 | int ECDSA_sign(int type, const unsigned char *dgst, int dgstlen, | ||
203 | unsigned char *sig, unsigned int *siglen, EC_KEY *eckey); | ||
204 | |||
205 | |||
206 | /** ECDSA_sign_ex | ||
207 | * computes ECDSA signature of a given hash value using the supplied | ||
208 | * private key (note: sig must point to ECDSA_size(eckey) bytes of memory). | ||
209 | * \param type this parameter is ignored | ||
210 | * \param dgst pointer to the hash value to sign | ||
211 | * \param dgstlen length of the hash value | ||
212 | * \param sig buffer to hold the DER encoded signature | ||
213 | * \param siglen pointer to the length of the returned signature | ||
214 | * \param kinv optional pointer to a pre-computed inverse k | ||
215 | * \param rp optional pointer to the pre-computed rp value (see | ||
216 | * ECDSA_sign_setup | ||
217 | * \param eckey pointer to the EC_KEY object containing a private EC key | ||
218 | * \return 1 on success and 0 otherwise | ||
219 | */ | ||
220 | int ECDSA_sign_ex(int type, const unsigned char *dgst, int dgstlen, | ||
221 | unsigned char *sig, unsigned int *siglen, const BIGNUM *kinv, | ||
222 | const BIGNUM *rp, EC_KEY *eckey); | ||
223 | |||
224 | /** ECDSA_verify | ||
225 | * verifies that the given signature is valid ECDSA signature | ||
226 | * of the supplied hash value using the specified public key. | ||
227 | * \param type this parameter is ignored | ||
228 | * \param dgst pointer to the hash value | ||
229 | * \param dgstlen length of the hash value | ||
230 | * \param sig pointer to the DER encoded signature | ||
231 | * \param siglen length of the DER encoded signature | ||
232 | * \param eckey pointer to the EC_KEY object containing a public EC key | ||
233 | * \return 1 if the signature is valid, 0 if the signature is invalid and -1 on error | ||
234 | */ | ||
235 | int ECDSA_verify(int type, const unsigned char *dgst, int dgstlen, | ||
236 | const unsigned char *sig, int siglen, EC_KEY *eckey); | ||
237 | |||
238 | /* the standard ex_data functions */ | ||
239 | int ECDSA_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new | ||
240 | *new_func, CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func); | ||
241 | int ECDSA_set_ex_data(EC_KEY *d, int idx, void *arg); | ||
242 | void *ECDSA_get_ex_data(EC_KEY *d, int idx); | ||
243 | |||
244 | |||
245 | /* BEGIN ERROR CODES */ | ||
246 | /* The following lines are auto generated by the script mkerr.pl. Any changes | ||
247 | * made after this point may be overwritten when the script is next run. | ||
248 | */ | ||
249 | void ERR_load_ECDSA_strings(void); | ||
250 | |||
251 | /* Error codes for the ECDSA functions. */ | ||
252 | |||
253 | /* Function codes. */ | ||
254 | #define ECDSA_F_ECDSA_DATA_NEW_METHOD 100 | ||
255 | #define ECDSA_F_ECDSA_DO_SIGN 101 | ||
256 | #define ECDSA_F_ECDSA_DO_VERIFY 102 | ||
257 | #define ECDSA_F_ECDSA_SIGN_SETUP 103 | ||
258 | |||
259 | /* Reason codes. */ | ||
260 | #define ECDSA_R_BAD_SIGNATURE 100 | ||
261 | #define ECDSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE 101 | ||
262 | #define ECDSA_R_ERR_EC_LIB 102 | ||
263 | #define ECDSA_R_MISSING_PARAMETERS 103 | ||
264 | #define ECDSA_R_NEED_NEW_SETUP_VALUES 106 | ||
265 | #define ECDSA_R_RANDOM_NUMBER_GENERATION_FAILED 104 | ||
266 | #define ECDSA_R_SIGNATURE_MALLOC_FAILED 105 | ||
267 | |||
268 | #ifdef __cplusplus | ||
269 | } | ||
270 | #endif | ||
271 | #endif | ||
diff --git a/src/lib/libcrypto/ecdsa/ecs_asn1.c b/src/lib/libcrypto/ecdsa/ecs_asn1.c new file mode 100644 index 0000000000..b295489400 --- /dev/null +++ b/src/lib/libcrypto/ecdsa/ecs_asn1.c | |||
@@ -0,0 +1,67 @@ | |||
1 | /* crypto/ecdsa/ecs_asn1.c */ | ||
2 | /* ==================================================================== | ||
3 | * Copyright (c) 2000-2002 The OpenSSL Project. All rights reserved. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions | ||
7 | * are met: | ||
8 | * | ||
9 | * 1. Redistributions of source code must retain the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer. | ||
11 | * | ||
12 | * 2. Redistributions in binary form must reproduce the above copyright | ||
13 | * notice, this list of conditions and the following disclaimer in | ||
14 | * the documentation and/or other materials provided with the | ||
15 | * distribution. | ||
16 | * | ||
17 | * 3. All advertising materials mentioning features or use of this | ||
18 | * software must display the following acknowledgment: | ||
19 | * "This product includes software developed by the OpenSSL Project | ||
20 | * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" | ||
21 | * | ||
22 | * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to | ||
23 | * endorse or promote products derived from this software without | ||
24 | * prior written permission. For written permission, please contact | ||
25 | * licensing@OpenSSL.org. | ||
26 | * | ||
27 | * 5. Products derived from this software may not be called "OpenSSL" | ||
28 | * nor may "OpenSSL" appear in their names without prior written | ||
29 | * permission of the OpenSSL Project. | ||
30 | * | ||
31 | * 6. Redistributions of any form whatsoever must retain the following | ||
32 | * acknowledgment: | ||
33 | * "This product includes software developed by the OpenSSL Project | ||
34 | * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" | ||
35 | * | ||
36 | * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY | ||
37 | * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
38 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | ||
39 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR | ||
40 | * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
41 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
42 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
43 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
44 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
45 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
46 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED | ||
47 | * OF THE POSSIBILITY OF SUCH DAMAGE. | ||
48 | * ==================================================================== | ||
49 | * | ||
50 | * This product includes cryptographic software written by Eric Young | ||
51 | * (eay@cryptsoft.com). This product includes software written by Tim | ||
52 | * Hudson (tjh@cryptsoft.com). | ||
53 | * | ||
54 | */ | ||
55 | |||
56 | #include "ecs_locl.h" | ||
57 | #include <openssl/err.h> | ||
58 | #include <openssl/asn1t.h> | ||
59 | |||
60 | ASN1_SEQUENCE(ECDSA_SIG) = { | ||
61 | ASN1_SIMPLE(ECDSA_SIG, r, CBIGNUM), | ||
62 | ASN1_SIMPLE(ECDSA_SIG, s, CBIGNUM) | ||
63 | } ASN1_SEQUENCE_END(ECDSA_SIG) | ||
64 | |||
65 | DECLARE_ASN1_FUNCTIONS_const(ECDSA_SIG) | ||
66 | DECLARE_ASN1_ENCODE_FUNCTIONS_const(ECDSA_SIG, ECDSA_SIG) | ||
67 | IMPLEMENT_ASN1_FUNCTIONS_const(ECDSA_SIG) | ||
diff --git a/src/lib/libcrypto/ecdsa/ecs_err.c b/src/lib/libcrypto/ecdsa/ecs_err.c new file mode 100644 index 0000000000..d2a53730ea --- /dev/null +++ b/src/lib/libcrypto/ecdsa/ecs_err.c | |||
@@ -0,0 +1,104 @@ | |||
1 | /* crypto/ecdsa/ecs_err.c */ | ||
2 | /* ==================================================================== | ||
3 | * Copyright (c) 1999-2005 The OpenSSL Project. All rights reserved. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions | ||
7 | * are met: | ||
8 | * | ||
9 | * 1. Redistributions of source code must retain the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer. | ||
11 | * | ||
12 | * 2. Redistributions in binary form must reproduce the above copyright | ||
13 | * notice, this list of conditions and the following disclaimer in | ||
14 | * the documentation and/or other materials provided with the | ||
15 | * distribution. | ||
16 | * | ||
17 | * 3. All advertising materials mentioning features or use of this | ||
18 | * software must display the following acknowledgment: | ||
19 | * "This product includes software developed by the OpenSSL Project | ||
20 | * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" | ||
21 | * | ||
22 | * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to | ||
23 | * endorse or promote products derived from this software without | ||
24 | * prior written permission. For written permission, please contact | ||
25 | * openssl-core@OpenSSL.org. | ||
26 | * | ||
27 | * 5. Products derived from this software may not be called "OpenSSL" | ||
28 | * nor may "OpenSSL" appear in their names without prior written | ||
29 | * permission of the OpenSSL Project. | ||
30 | * | ||
31 | * 6. Redistributions of any form whatsoever must retain the following | ||
32 | * acknowledgment: | ||
33 | * "This product includes software developed by the OpenSSL Project | ||
34 | * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" | ||
35 | * | ||
36 | * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY | ||
37 | * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
38 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | ||
39 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR | ||
40 | * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
41 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
42 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
43 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
44 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
45 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
46 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED | ||
47 | * OF THE POSSIBILITY OF SUCH DAMAGE. | ||
48 | * ==================================================================== | ||
49 | * | ||
50 | * This product includes cryptographic software written by Eric Young | ||
51 | * (eay@cryptsoft.com). This product includes software written by Tim | ||
52 | * Hudson (tjh@cryptsoft.com). | ||
53 | * | ||
54 | */ | ||
55 | |||
56 | /* NOTE: this file was auto generated by the mkerr.pl script: any changes | ||
57 | * made to it will be overwritten when the script next updates this file, | ||
58 | * only reason strings will be preserved. | ||
59 | */ | ||
60 | |||
61 | #include <stdio.h> | ||
62 | #include <openssl/err.h> | ||
63 | #include <openssl/ecdsa.h> | ||
64 | |||
65 | /* BEGIN ERROR CODES */ | ||
66 | #ifndef OPENSSL_NO_ERR | ||
67 | |||
68 | #define ERR_FUNC(func) ERR_PACK(ERR_LIB_ECDSA,func,0) | ||
69 | #define ERR_REASON(reason) ERR_PACK(ERR_LIB_ECDSA,0,reason) | ||
70 | |||
71 | static ERR_STRING_DATA ECDSA_str_functs[]= | ||
72 | { | ||
73 | {ERR_FUNC(ECDSA_F_ECDSA_DATA_NEW_METHOD), "ECDSA_DATA_NEW_METHOD"}, | ||
74 | {ERR_FUNC(ECDSA_F_ECDSA_DO_SIGN), "ECDSA_do_sign"}, | ||
75 | {ERR_FUNC(ECDSA_F_ECDSA_DO_VERIFY), "ECDSA_do_verify"}, | ||
76 | {ERR_FUNC(ECDSA_F_ECDSA_SIGN_SETUP), "ECDSA_sign_setup"}, | ||
77 | {0,NULL} | ||
78 | }; | ||
79 | |||
80 | static ERR_STRING_DATA ECDSA_str_reasons[]= | ||
81 | { | ||
82 | {ERR_REASON(ECDSA_R_BAD_SIGNATURE) ,"bad signature"}, | ||
83 | {ERR_REASON(ECDSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE),"data too large for key size"}, | ||
84 | {ERR_REASON(ECDSA_R_ERR_EC_LIB) ,"err ec lib"}, | ||
85 | {ERR_REASON(ECDSA_R_MISSING_PARAMETERS) ,"missing parameters"}, | ||
86 | {ERR_REASON(ECDSA_R_NEED_NEW_SETUP_VALUES),"need new setup values"}, | ||
87 | {ERR_REASON(ECDSA_R_RANDOM_NUMBER_GENERATION_FAILED),"random number generation failed"}, | ||
88 | {ERR_REASON(ECDSA_R_SIGNATURE_MALLOC_FAILED),"signature malloc failed"}, | ||
89 | {0,NULL} | ||
90 | }; | ||
91 | |||
92 | #endif | ||
93 | |||
94 | void ERR_load_ECDSA_strings(void) | ||
95 | { | ||
96 | #ifndef OPENSSL_NO_ERR | ||
97 | |||
98 | if (ERR_func_error_string(ECDSA_str_functs[0].error) == NULL) | ||
99 | { | ||
100 | ERR_load_strings(0,ECDSA_str_functs); | ||
101 | ERR_load_strings(0,ECDSA_str_reasons); | ||
102 | } | ||
103 | #endif | ||
104 | } | ||
diff --git a/src/lib/libcrypto/ecdsa/ecs_lib.c b/src/lib/libcrypto/ecdsa/ecs_lib.c new file mode 100644 index 0000000000..85e8a3a7ed --- /dev/null +++ b/src/lib/libcrypto/ecdsa/ecs_lib.c | |||
@@ -0,0 +1,261 @@ | |||
1 | /* crypto/ecdsa/ecs_lib.c */ | ||
2 | /* ==================================================================== | ||
3 | * Copyright (c) 1998-2005 The OpenSSL Project. All rights reserved. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions | ||
7 | * are met: | ||
8 | * | ||
9 | * 1. Redistributions of source code must retain the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer. | ||
11 | * | ||
12 | * 2. Redistributions in binary form must reproduce the above copyright | ||
13 | * notice, this list of conditions and the following disclaimer in | ||
14 | * the documentation and/or other materials provided with the | ||
15 | * distribution. | ||
16 | * | ||
17 | * 3. All advertising materials mentioning features or use of this | ||
18 | * software must display the following acknowledgment: | ||
19 | * "This product includes software developed by the OpenSSL Project | ||
20 | * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" | ||
21 | * | ||
22 | * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to | ||
23 | * endorse or promote products derived from this software without | ||
24 | * prior written permission. For written permission, please contact | ||
25 | * openssl-core@OpenSSL.org. | ||
26 | * | ||
27 | * 5. Products derived from this software may not be called "OpenSSL" | ||
28 | * nor may "OpenSSL" appear in their names without prior written | ||
29 | * permission of the OpenSSL Project. | ||
30 | * | ||
31 | * 6. Redistributions of any form whatsoever must retain the following | ||
32 | * acknowledgment: | ||
33 | * "This product includes software developed by the OpenSSL Project | ||
34 | * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" | ||
35 | * | ||
36 | * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY | ||
37 | * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
38 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | ||
39 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR | ||
40 | * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
41 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
42 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
43 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
44 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
45 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
46 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED | ||
47 | * OF THE POSSIBILITY OF SUCH DAMAGE. | ||
48 | * ==================================================================== | ||
49 | * | ||
50 | * This product includes cryptographic software written by Eric Young | ||
51 | * (eay@cryptsoft.com). This product includes software written by Tim | ||
52 | * Hudson (tjh@cryptsoft.com). | ||
53 | * | ||
54 | */ | ||
55 | |||
56 | #include <string.h> | ||
57 | #include "ecs_locl.h" | ||
58 | #ifndef OPENSSL_NO_ENGINE | ||
59 | #include <openssl/engine.h> | ||
60 | #endif | ||
61 | #include <openssl/err.h> | ||
62 | #include <openssl/bn.h> | ||
63 | |||
64 | const char ECDSA_version[]="ECDSA" OPENSSL_VERSION_PTEXT; | ||
65 | |||
66 | static const ECDSA_METHOD *default_ECDSA_method = NULL; | ||
67 | |||
68 | static void *ecdsa_data_new(void); | ||
69 | static void *ecdsa_data_dup(void *); | ||
70 | static void ecdsa_data_free(void *); | ||
71 | |||
72 | void ECDSA_set_default_method(const ECDSA_METHOD *meth) | ||
73 | { | ||
74 | default_ECDSA_method = meth; | ||
75 | } | ||
76 | |||
77 | const ECDSA_METHOD *ECDSA_get_default_method(void) | ||
78 | { | ||
79 | if(!default_ECDSA_method) | ||
80 | default_ECDSA_method = ECDSA_OpenSSL(); | ||
81 | return default_ECDSA_method; | ||
82 | } | ||
83 | |||
84 | int ECDSA_set_method(EC_KEY *eckey, const ECDSA_METHOD *meth) | ||
85 | { | ||
86 | const ECDSA_METHOD *mtmp; | ||
87 | ECDSA_DATA *ecdsa; | ||
88 | |||
89 | ecdsa = ecdsa_check(eckey); | ||
90 | |||
91 | if (ecdsa == NULL) | ||
92 | return 0; | ||
93 | |||
94 | mtmp = ecdsa->meth; | ||
95 | #ifndef OPENSSL_NO_ENGINE | ||
96 | if (ecdsa->engine) | ||
97 | { | ||
98 | ENGINE_finish(ecdsa->engine); | ||
99 | ecdsa->engine = NULL; | ||
100 | } | ||
101 | #endif | ||
102 | ecdsa->meth = meth; | ||
103 | |||
104 | return 1; | ||
105 | } | ||
106 | |||
107 | static ECDSA_DATA *ECDSA_DATA_new_method(ENGINE *engine) | ||
108 | { | ||
109 | ECDSA_DATA *ret; | ||
110 | |||
111 | ret=(ECDSA_DATA *)OPENSSL_malloc(sizeof(ECDSA_DATA)); | ||
112 | if (ret == NULL) | ||
113 | { | ||
114 | ECDSAerr(ECDSA_F_ECDSA_DATA_NEW_METHOD, ERR_R_MALLOC_FAILURE); | ||
115 | return(NULL); | ||
116 | } | ||
117 | |||
118 | ret->init = NULL; | ||
119 | |||
120 | ret->meth = ECDSA_get_default_method(); | ||
121 | ret->engine = engine; | ||
122 | #ifndef OPENSSL_NO_ENGINE | ||
123 | if (!ret->engine) | ||
124 | ret->engine = ENGINE_get_default_ECDSA(); | ||
125 | if (ret->engine) | ||
126 | { | ||
127 | ret->meth = ENGINE_get_ECDSA(ret->engine); | ||
128 | if (!ret->meth) | ||
129 | { | ||
130 | ECDSAerr(ECDSA_F_ECDSA_DATA_NEW_METHOD, ERR_R_ENGINE_LIB); | ||
131 | ENGINE_finish(ret->engine); | ||
132 | OPENSSL_free(ret); | ||
133 | return NULL; | ||
134 | } | ||
135 | } | ||
136 | #endif | ||
137 | |||
138 | ret->flags = ret->meth->flags; | ||
139 | CRYPTO_new_ex_data(CRYPTO_EX_INDEX_ECDSA, ret, &ret->ex_data); | ||
140 | #if 0 | ||
141 | if ((ret->meth->init != NULL) && !ret->meth->init(ret)) | ||
142 | { | ||
143 | CRYPTO_free_ex_data(CRYPTO_EX_INDEX_ECDSA, ret, &ret->ex_data); | ||
144 | OPENSSL_free(ret); | ||
145 | ret=NULL; | ||
146 | } | ||
147 | #endif | ||
148 | return(ret); | ||
149 | } | ||
150 | |||
151 | static void *ecdsa_data_new(void) | ||
152 | { | ||
153 | return (void *)ECDSA_DATA_new_method(NULL); | ||
154 | } | ||
155 | |||
156 | static void *ecdsa_data_dup(void *data) | ||
157 | { | ||
158 | ECDSA_DATA *r = (ECDSA_DATA *)data; | ||
159 | |||
160 | /* XXX: dummy operation */ | ||
161 | if (r == NULL) | ||
162 | return NULL; | ||
163 | |||
164 | return ecdsa_data_new(); | ||
165 | } | ||
166 | |||
167 | static void ecdsa_data_free(void *data) | ||
168 | { | ||
169 | ECDSA_DATA *r = (ECDSA_DATA *)data; | ||
170 | |||
171 | #ifndef OPENSSL_NO_ENGINE | ||
172 | if (r->engine) | ||
173 | ENGINE_finish(r->engine); | ||
174 | #endif | ||
175 | CRYPTO_free_ex_data(CRYPTO_EX_INDEX_ECDSA, r, &r->ex_data); | ||
176 | |||
177 | OPENSSL_cleanse((void *)r, sizeof(ECDSA_DATA)); | ||
178 | |||
179 | OPENSSL_free(r); | ||
180 | } | ||
181 | |||
182 | ECDSA_DATA *ecdsa_check(EC_KEY *key) | ||
183 | { | ||
184 | ECDSA_DATA *ecdsa_data; | ||
185 | |||
186 | void *data = EC_KEY_get_key_method_data(key, ecdsa_data_dup, | ||
187 | ecdsa_data_free, ecdsa_data_free); | ||
188 | if (data == NULL) | ||
189 | { | ||
190 | ecdsa_data = (ECDSA_DATA *)ecdsa_data_new(); | ||
191 | if (ecdsa_data == NULL) | ||
192 | return NULL; | ||
193 | EC_KEY_insert_key_method_data(key, (void *)ecdsa_data, | ||
194 | ecdsa_data_dup, ecdsa_data_free, ecdsa_data_free); | ||
195 | } | ||
196 | else | ||
197 | ecdsa_data = (ECDSA_DATA *)data; | ||
198 | |||
199 | |||
200 | return ecdsa_data; | ||
201 | } | ||
202 | |||
203 | int ECDSA_size(const EC_KEY *r) | ||
204 | { | ||
205 | int ret,i; | ||
206 | ASN1_INTEGER bs; | ||
207 | BIGNUM *order=NULL; | ||
208 | unsigned char buf[4]; | ||
209 | const EC_GROUP *group; | ||
210 | |||
211 | if (r == NULL) | ||
212 | return 0; | ||
213 | group = EC_KEY_get0_group(r); | ||
214 | if (group == NULL) | ||
215 | return 0; | ||
216 | |||
217 | if ((order = BN_new()) == NULL) return 0; | ||
218 | if (!EC_GROUP_get_order(group,order,NULL)) | ||
219 | { | ||
220 | BN_clear_free(order); | ||
221 | return 0; | ||
222 | } | ||
223 | i=BN_num_bits(order); | ||
224 | bs.length=(i+7)/8; | ||
225 | bs.data=buf; | ||
226 | bs.type=V_ASN1_INTEGER; | ||
227 | /* If the top bit is set the asn1 encoding is 1 larger. */ | ||
228 | buf[0]=0xff; | ||
229 | |||
230 | i=i2d_ASN1_INTEGER(&bs,NULL); | ||
231 | i+=i; /* r and s */ | ||
232 | ret=ASN1_object_size(1,i,V_ASN1_SEQUENCE); | ||
233 | BN_clear_free(order); | ||
234 | return(ret); | ||
235 | } | ||
236 | |||
237 | |||
238 | int ECDSA_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, | ||
239 | CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func) | ||
240 | { | ||
241 | return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_ECDSA, argl, argp, | ||
242 | new_func, dup_func, free_func); | ||
243 | } | ||
244 | |||
245 | int ECDSA_set_ex_data(EC_KEY *d, int idx, void *arg) | ||
246 | { | ||
247 | ECDSA_DATA *ecdsa; | ||
248 | ecdsa = ecdsa_check(d); | ||
249 | if (ecdsa == NULL) | ||
250 | return 0; | ||
251 | return(CRYPTO_set_ex_data(&ecdsa->ex_data,idx,arg)); | ||
252 | } | ||
253 | |||
254 | void *ECDSA_get_ex_data(EC_KEY *d, int idx) | ||
255 | { | ||
256 | ECDSA_DATA *ecdsa; | ||
257 | ecdsa = ecdsa_check(d); | ||
258 | if (ecdsa == NULL) | ||
259 | return NULL; | ||
260 | return(CRYPTO_get_ex_data(&ecdsa->ex_data,idx)); | ||
261 | } | ||
diff --git a/src/lib/libcrypto/ecdsa/ecs_locl.h b/src/lib/libcrypto/ecdsa/ecs_locl.h new file mode 100644 index 0000000000..3a69a840e2 --- /dev/null +++ b/src/lib/libcrypto/ecdsa/ecs_locl.h | |||
@@ -0,0 +1,107 @@ | |||
1 | /* crypto/ecdsa/ecs_locl.h */ | ||
2 | /* | ||
3 | * Written by Nils Larsch for the OpenSSL project | ||
4 | */ | ||
5 | /* ==================================================================== | ||
6 | * Copyright (c) 2000-2005 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 | * This product includes cryptographic software written by Eric Young | ||
54 | * (eay@cryptsoft.com). This product includes software written by Tim | ||
55 | * Hudson (tjh@cryptsoft.com). | ||
56 | * | ||
57 | */ | ||
58 | |||
59 | #ifndef HEADER_ECS_LOCL_H | ||
60 | #define HEADER_ECS_LOCL_H | ||
61 | |||
62 | #include <openssl/ecdsa.h> | ||
63 | |||
64 | #ifdef __cplusplus | ||
65 | extern "C" { | ||
66 | #endif | ||
67 | |||
68 | struct ecdsa_method | ||
69 | { | ||
70 | const char *name; | ||
71 | ECDSA_SIG *(*ecdsa_do_sign)(const unsigned char *dgst, int dgst_len, | ||
72 | const BIGNUM *inv, const BIGNUM *rp, EC_KEY *eckey); | ||
73 | int (*ecdsa_sign_setup)(EC_KEY *eckey, BN_CTX *ctx, BIGNUM **kinv, | ||
74 | BIGNUM **r); | ||
75 | int (*ecdsa_do_verify)(const unsigned char *dgst, int dgst_len, | ||
76 | const ECDSA_SIG *sig, EC_KEY *eckey); | ||
77 | #if 0 | ||
78 | int (*init)(EC_KEY *eckey); | ||
79 | int (*finish)(EC_KEY *eckey); | ||
80 | #endif | ||
81 | int flags; | ||
82 | char *app_data; | ||
83 | }; | ||
84 | |||
85 | typedef struct ecdsa_data_st { | ||
86 | /* EC_KEY_METH_DATA part */ | ||
87 | int (*init)(EC_KEY *); | ||
88 | /* method (ECDSA) specific part */ | ||
89 | ENGINE *engine; | ||
90 | int flags; | ||
91 | const ECDSA_METHOD *meth; | ||
92 | CRYPTO_EX_DATA ex_data; | ||
93 | } ECDSA_DATA; | ||
94 | |||
95 | /** ecdsa_check | ||
96 | * checks whether ECKEY->meth_data is a pointer to a ECDSA_DATA structure | ||
97 | * and if not it removes the old meth_data and creates a ECDSA_DATA structure. | ||
98 | * \param eckey pointer to a EC_KEY object | ||
99 | * \return pointer to a ECDSA_DATA structure | ||
100 | */ | ||
101 | ECDSA_DATA *ecdsa_check(EC_KEY *eckey); | ||
102 | |||
103 | #ifdef __cplusplus | ||
104 | } | ||
105 | #endif | ||
106 | |||
107 | #endif /* HEADER_ECS_LOCL_H */ | ||
diff --git a/src/lib/libcrypto/ecdsa/ecs_ossl.c b/src/lib/libcrypto/ecdsa/ecs_ossl.c new file mode 100644 index 0000000000..3ead1af94e --- /dev/null +++ b/src/lib/libcrypto/ecdsa/ecs_ossl.c | |||
@@ -0,0 +1,478 @@ | |||
1 | /* crypto/ecdsa/ecs_ossl.c */ | ||
2 | /* | ||
3 | * Written by Nils Larsch for the OpenSSL project | ||
4 | */ | ||
5 | /* ==================================================================== | ||
6 | * Copyright (c) 1998-2004 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 | * openssl-core@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 | * This product includes cryptographic software written by Eric Young | ||
54 | * (eay@cryptsoft.com). This product includes software written by Tim | ||
55 | * Hudson (tjh@cryptsoft.com). | ||
56 | * | ||
57 | */ | ||
58 | |||
59 | #include "ecs_locl.h" | ||
60 | #include <openssl/err.h> | ||
61 | #include <openssl/obj_mac.h> | ||
62 | #include <openssl/bn.h> | ||
63 | |||
64 | static ECDSA_SIG *ecdsa_do_sign(const unsigned char *dgst, int dlen, | ||
65 | const BIGNUM *, const BIGNUM *, EC_KEY *eckey); | ||
66 | static int ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp, | ||
67 | BIGNUM **rp); | ||
68 | static int ecdsa_do_verify(const unsigned char *dgst, int dgst_len, | ||
69 | const ECDSA_SIG *sig, EC_KEY *eckey); | ||
70 | |||
71 | static ECDSA_METHOD openssl_ecdsa_meth = { | ||
72 | "OpenSSL ECDSA method", | ||
73 | ecdsa_do_sign, | ||
74 | ecdsa_sign_setup, | ||
75 | ecdsa_do_verify, | ||
76 | #if 0 | ||
77 | NULL, /* init */ | ||
78 | NULL, /* finish */ | ||
79 | #endif | ||
80 | 0, /* flags */ | ||
81 | NULL /* app_data */ | ||
82 | }; | ||
83 | |||
84 | const ECDSA_METHOD *ECDSA_OpenSSL(void) | ||
85 | { | ||
86 | return &openssl_ecdsa_meth; | ||
87 | } | ||
88 | |||
89 | static int ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp, | ||
90 | BIGNUM **rp) | ||
91 | { | ||
92 | BN_CTX *ctx = NULL; | ||
93 | BIGNUM *k = NULL, *r = NULL, *order = NULL, *X = NULL; | ||
94 | EC_POINT *tmp_point=NULL; | ||
95 | const EC_GROUP *group; | ||
96 | int ret = 0; | ||
97 | |||
98 | if (eckey == NULL || (group = EC_KEY_get0_group(eckey)) == NULL) | ||
99 | { | ||
100 | ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_PASSED_NULL_PARAMETER); | ||
101 | return 0; | ||
102 | } | ||
103 | |||
104 | if (ctx_in == NULL) | ||
105 | { | ||
106 | if ((ctx = BN_CTX_new()) == NULL) | ||
107 | { | ||
108 | ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP,ERR_R_MALLOC_FAILURE); | ||
109 | return 0; | ||
110 | } | ||
111 | } | ||
112 | else | ||
113 | ctx = ctx_in; | ||
114 | |||
115 | k = BN_new(); /* this value is later returned in *kinvp */ | ||
116 | r = BN_new(); /* this value is later returned in *rp */ | ||
117 | order = BN_new(); | ||
118 | X = BN_new(); | ||
119 | if (!k || !r || !order || !X) | ||
120 | { | ||
121 | ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_MALLOC_FAILURE); | ||
122 | goto err; | ||
123 | } | ||
124 | if ((tmp_point = EC_POINT_new(group)) == NULL) | ||
125 | { | ||
126 | ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_EC_LIB); | ||
127 | goto err; | ||
128 | } | ||
129 | if (!EC_GROUP_get_order(group, order, ctx)) | ||
130 | { | ||
131 | ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_EC_LIB); | ||
132 | goto err; | ||
133 | } | ||
134 | |||
135 | do | ||
136 | { | ||
137 | /* get random k */ | ||
138 | do | ||
139 | if (!BN_rand_range(k, order)) | ||
140 | { | ||
141 | ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, | ||
142 | ECDSA_R_RANDOM_NUMBER_GENERATION_FAILED); | ||
143 | goto err; | ||
144 | } | ||
145 | while (BN_is_zero(k)); | ||
146 | |||
147 | /* compute r the x-coordinate of generator * k */ | ||
148 | if (!EC_POINT_mul(group, tmp_point, k, NULL, NULL, ctx)) | ||
149 | { | ||
150 | ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_EC_LIB); | ||
151 | goto err; | ||
152 | } | ||
153 | if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) == NID_X9_62_prime_field) | ||
154 | { | ||
155 | if (!EC_POINT_get_affine_coordinates_GFp(group, | ||
156 | tmp_point, X, NULL, ctx)) | ||
157 | { | ||
158 | ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP,ERR_R_EC_LIB); | ||
159 | goto err; | ||
160 | } | ||
161 | } | ||
162 | else /* NID_X9_62_characteristic_two_field */ | ||
163 | { | ||
164 | if (!EC_POINT_get_affine_coordinates_GF2m(group, | ||
165 | tmp_point, X, NULL, ctx)) | ||
166 | { | ||
167 | ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP,ERR_R_EC_LIB); | ||
168 | goto err; | ||
169 | } | ||
170 | } | ||
171 | if (!BN_nnmod(r, X, order, ctx)) | ||
172 | { | ||
173 | ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_BN_LIB); | ||
174 | goto err; | ||
175 | } | ||
176 | } | ||
177 | while (BN_is_zero(r)); | ||
178 | |||
179 | /* compute the inverse of k */ | ||
180 | if (!BN_mod_inverse(k, k, order, ctx)) | ||
181 | { | ||
182 | ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_BN_LIB); | ||
183 | goto err; | ||
184 | } | ||
185 | /* clear old values if necessary */ | ||
186 | if (*rp != NULL) | ||
187 | BN_clear_free(*rp); | ||
188 | if (*kinvp != NULL) | ||
189 | BN_clear_free(*kinvp); | ||
190 | /* save the pre-computed values */ | ||
191 | *rp = r; | ||
192 | *kinvp = k; | ||
193 | ret = 1; | ||
194 | err: | ||
195 | if (!ret) | ||
196 | { | ||
197 | if (k != NULL) BN_clear_free(k); | ||
198 | if (r != NULL) BN_clear_free(r); | ||
199 | } | ||
200 | if (ctx_in == NULL) | ||
201 | BN_CTX_free(ctx); | ||
202 | if (order != NULL) | ||
203 | BN_free(order); | ||
204 | if (tmp_point != NULL) | ||
205 | EC_POINT_free(tmp_point); | ||
206 | if (X) | ||
207 | BN_clear_free(X); | ||
208 | return(ret); | ||
209 | } | ||
210 | |||
211 | |||
212 | static ECDSA_SIG *ecdsa_do_sign(const unsigned char *dgst, int dgst_len, | ||
213 | const BIGNUM *in_kinv, const BIGNUM *in_r, EC_KEY *eckey) | ||
214 | { | ||
215 | int ok = 0; | ||
216 | BIGNUM *kinv=NULL, *s, *m=NULL,*tmp=NULL,*order=NULL; | ||
217 | const BIGNUM *ckinv; | ||
218 | BN_CTX *ctx = NULL; | ||
219 | const EC_GROUP *group; | ||
220 | ECDSA_SIG *ret; | ||
221 | ECDSA_DATA *ecdsa; | ||
222 | const BIGNUM *priv_key; | ||
223 | |||
224 | ecdsa = ecdsa_check(eckey); | ||
225 | group = EC_KEY_get0_group(eckey); | ||
226 | priv_key = EC_KEY_get0_private_key(eckey); | ||
227 | |||
228 | if (group == NULL || priv_key == NULL || ecdsa == NULL) | ||
229 | { | ||
230 | ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_PASSED_NULL_PARAMETER); | ||
231 | return NULL; | ||
232 | } | ||
233 | |||
234 | ret = ECDSA_SIG_new(); | ||
235 | if (!ret) | ||
236 | { | ||
237 | ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE); | ||
238 | return NULL; | ||
239 | } | ||
240 | s = ret->s; | ||
241 | |||
242 | if ((ctx = BN_CTX_new()) == NULL || (order = BN_new()) == NULL || | ||
243 | (tmp = BN_new()) == NULL || (m = BN_new()) == NULL) | ||
244 | { | ||
245 | ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE); | ||
246 | goto err; | ||
247 | } | ||
248 | |||
249 | if (!EC_GROUP_get_order(group, order, ctx)) | ||
250 | { | ||
251 | ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_EC_LIB); | ||
252 | goto err; | ||
253 | } | ||
254 | if (8 * dgst_len > BN_num_bits(order)) | ||
255 | { | ||
256 | /* XXX | ||
257 | * | ||
258 | * Should provide for optional hash truncation: | ||
259 | * Keep the BN_num_bits(order) leftmost bits of dgst | ||
260 | * (see March 2006 FIPS 186-3 draft, which has a few | ||
261 | * confusing errors in this part though) | ||
262 | */ | ||
263 | |||
264 | ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, | ||
265 | ECDSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE); | ||
266 | goto err; | ||
267 | } | ||
268 | |||
269 | if (!BN_bin2bn(dgst, dgst_len, m)) | ||
270 | { | ||
271 | ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB); | ||
272 | goto err; | ||
273 | } | ||
274 | do | ||
275 | { | ||
276 | if (in_kinv == NULL || in_r == NULL) | ||
277 | { | ||
278 | if (!ECDSA_sign_setup(eckey, ctx, &kinv, &ret->r)) | ||
279 | { | ||
280 | ECDSAerr(ECDSA_F_ECDSA_DO_SIGN,ERR_R_ECDSA_LIB); | ||
281 | goto err; | ||
282 | } | ||
283 | ckinv = kinv; | ||
284 | } | ||
285 | else | ||
286 | { | ||
287 | ckinv = in_kinv; | ||
288 | if (BN_copy(ret->r, in_r) == NULL) | ||
289 | { | ||
290 | ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE); | ||
291 | goto err; | ||
292 | } | ||
293 | } | ||
294 | |||
295 | if (!BN_mod_mul(tmp, priv_key, ret->r, order, ctx)) | ||
296 | { | ||
297 | ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB); | ||
298 | goto err; | ||
299 | } | ||
300 | if (!BN_mod_add_quick(s, tmp, m, order)) | ||
301 | { | ||
302 | ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB); | ||
303 | goto err; | ||
304 | } | ||
305 | if (!BN_mod_mul(s, s, ckinv, order, ctx)) | ||
306 | { | ||
307 | ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB); | ||
308 | goto err; | ||
309 | } | ||
310 | if (BN_is_zero(s)) | ||
311 | { | ||
312 | /* if kinv and r have been supplied by the caller | ||
313 | * don't to generate new kinv and r values */ | ||
314 | if (in_kinv != NULL && in_r != NULL) | ||
315 | { | ||
316 | ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ECDSA_R_NEED_NEW_SETUP_VALUES); | ||
317 | goto err; | ||
318 | } | ||
319 | } | ||
320 | else | ||
321 | /* s != 0 => we have a valid signature */ | ||
322 | break; | ||
323 | } | ||
324 | while (1); | ||
325 | |||
326 | ok = 1; | ||
327 | err: | ||
328 | if (!ok) | ||
329 | { | ||
330 | ECDSA_SIG_free(ret); | ||
331 | ret = NULL; | ||
332 | } | ||
333 | if (ctx) | ||
334 | BN_CTX_free(ctx); | ||
335 | if (m) | ||
336 | BN_clear_free(m); | ||
337 | if (tmp) | ||
338 | BN_clear_free(tmp); | ||
339 | if (order) | ||
340 | BN_free(order); | ||
341 | if (kinv) | ||
342 | BN_clear_free(kinv); | ||
343 | return ret; | ||
344 | } | ||
345 | |||
346 | static int ecdsa_do_verify(const unsigned char *dgst, int dgst_len, | ||
347 | const ECDSA_SIG *sig, EC_KEY *eckey) | ||
348 | { | ||
349 | int ret = -1; | ||
350 | BN_CTX *ctx; | ||
351 | BIGNUM *order, *u1, *u2, *m, *X; | ||
352 | EC_POINT *point = NULL; | ||
353 | const EC_GROUP *group; | ||
354 | const EC_POINT *pub_key; | ||
355 | |||
356 | /* check input values */ | ||
357 | if (eckey == NULL || (group = EC_KEY_get0_group(eckey)) == NULL || | ||
358 | (pub_key = EC_KEY_get0_public_key(eckey)) == NULL || sig == NULL) | ||
359 | { | ||
360 | ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ECDSA_R_MISSING_PARAMETERS); | ||
361 | return -1; | ||
362 | } | ||
363 | |||
364 | ctx = BN_CTX_new(); | ||
365 | if (!ctx) | ||
366 | { | ||
367 | ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE); | ||
368 | return -1; | ||
369 | } | ||
370 | BN_CTX_start(ctx); | ||
371 | order = BN_CTX_get(ctx); | ||
372 | u1 = BN_CTX_get(ctx); | ||
373 | u2 = BN_CTX_get(ctx); | ||
374 | m = BN_CTX_get(ctx); | ||
375 | X = BN_CTX_get(ctx); | ||
376 | if (!X) | ||
377 | { | ||
378 | ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB); | ||
379 | goto err; | ||
380 | } | ||
381 | |||
382 | if (!EC_GROUP_get_order(group, order, ctx)) | ||
383 | { | ||
384 | ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB); | ||
385 | goto err; | ||
386 | } | ||
387 | if (8 * dgst_len > BN_num_bits(order)) | ||
388 | { | ||
389 | /* XXX | ||
390 | * | ||
391 | * Should provide for optional hash truncation: | ||
392 | * Keep the BN_num_bits(order) leftmost bits of dgst | ||
393 | * (see March 2006 FIPS 186-3 draft, which has a few | ||
394 | * confusing errors in this part though) | ||
395 | */ | ||
396 | |||
397 | ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, | ||
398 | ECDSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE); | ||
399 | ret = 0; | ||
400 | goto err; | ||
401 | } | ||
402 | |||
403 | if (BN_is_zero(sig->r) || BN_is_negative(sig->r) || | ||
404 | BN_ucmp(sig->r, order) >= 0 || BN_is_zero(sig->s) || | ||
405 | BN_is_negative(sig->s) || BN_ucmp(sig->s, order) >= 0) | ||
406 | { | ||
407 | ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ECDSA_R_BAD_SIGNATURE); | ||
408 | ret = 0; /* signature is invalid */ | ||
409 | goto err; | ||
410 | } | ||
411 | /* calculate tmp1 = inv(S) mod order */ | ||
412 | if (!BN_mod_inverse(u2, sig->s, order, ctx)) | ||
413 | { | ||
414 | ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB); | ||
415 | goto err; | ||
416 | } | ||
417 | /* digest -> m */ | ||
418 | if (!BN_bin2bn(dgst, dgst_len, m)) | ||
419 | { | ||
420 | ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB); | ||
421 | goto err; | ||
422 | } | ||
423 | /* u1 = m * tmp mod order */ | ||
424 | if (!BN_mod_mul(u1, m, u2, order, ctx)) | ||
425 | { | ||
426 | ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB); | ||
427 | goto err; | ||
428 | } | ||
429 | /* u2 = r * w mod q */ | ||
430 | if (!BN_mod_mul(u2, sig->r, u2, order, ctx)) | ||
431 | { | ||
432 | ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB); | ||
433 | goto err; | ||
434 | } | ||
435 | |||
436 | if ((point = EC_POINT_new(group)) == NULL) | ||
437 | { | ||
438 | ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE); | ||
439 | goto err; | ||
440 | } | ||
441 | if (!EC_POINT_mul(group, point, u1, pub_key, u2, ctx)) | ||
442 | { | ||
443 | ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB); | ||
444 | goto err; | ||
445 | } | ||
446 | if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) == NID_X9_62_prime_field) | ||
447 | { | ||
448 | if (!EC_POINT_get_affine_coordinates_GFp(group, | ||
449 | point, X, NULL, ctx)) | ||
450 | { | ||
451 | ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB); | ||
452 | goto err; | ||
453 | } | ||
454 | } | ||
455 | else /* NID_X9_62_characteristic_two_field */ | ||
456 | { | ||
457 | if (!EC_POINT_get_affine_coordinates_GF2m(group, | ||
458 | point, X, NULL, ctx)) | ||
459 | { | ||
460 | ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB); | ||
461 | goto err; | ||
462 | } | ||
463 | } | ||
464 | |||
465 | if (!BN_nnmod(u1, X, order, ctx)) | ||
466 | { | ||
467 | ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB); | ||
468 | goto err; | ||
469 | } | ||
470 | /* if the signature is correct u1 is equal to sig->r */ | ||
471 | ret = (BN_ucmp(u1, sig->r) == 0); | ||
472 | err: | ||
473 | BN_CTX_end(ctx); | ||
474 | BN_CTX_free(ctx); | ||
475 | if (point) | ||
476 | EC_POINT_free(point); | ||
477 | return ret; | ||
478 | } | ||
diff --git a/src/lib/libcrypto/ecdsa/ecs_sign.c b/src/lib/libcrypto/ecdsa/ecs_sign.c new file mode 100644 index 0000000000..74b1fe8caf --- /dev/null +++ b/src/lib/libcrypto/ecdsa/ecs_sign.c | |||
@@ -0,0 +1,104 @@ | |||
1 | /* crypto/ecdsa/ecdsa_sign.c */ | ||
2 | /* ==================================================================== | ||
3 | * Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions | ||
7 | * are met: | ||
8 | * | ||
9 | * 1. Redistributions of source code must retain the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer. | ||
11 | * | ||
12 | * 2. Redistributions in binary form must reproduce the above copyright | ||
13 | * notice, this list of conditions and the following disclaimer in | ||
14 | * the documentation and/or other materials provided with the | ||
15 | * distribution. | ||
16 | * | ||
17 | * 3. All advertising materials mentioning features or use of this | ||
18 | * software must display the following acknowledgment: | ||
19 | * "This product includes software developed by the OpenSSL Project | ||
20 | * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" | ||
21 | * | ||
22 | * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to | ||
23 | * endorse or promote products derived from this software without | ||
24 | * prior written permission. For written permission, please contact | ||
25 | * openssl-core@OpenSSL.org. | ||
26 | * | ||
27 | * 5. Products derived from this software may not be called "OpenSSL" | ||
28 | * nor may "OpenSSL" appear in their names without prior written | ||
29 | * permission of the OpenSSL Project. | ||
30 | * | ||
31 | * 6. Redistributions of any form whatsoever must retain the following | ||
32 | * acknowledgment: | ||
33 | * "This product includes software developed by the OpenSSL Project | ||
34 | * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" | ||
35 | * | ||
36 | * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY | ||
37 | * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
38 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | ||
39 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR | ||
40 | * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
41 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
42 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
43 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
44 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
45 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
46 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED | ||
47 | * OF THE POSSIBILITY OF SUCH DAMAGE. | ||
48 | * ==================================================================== | ||
49 | * | ||
50 | * This product includes cryptographic software written by Eric Young | ||
51 | * (eay@cryptsoft.com). This product includes software written by Tim | ||
52 | * Hudson (tjh@cryptsoft.com). | ||
53 | * | ||
54 | */ | ||
55 | |||
56 | #include "ecs_locl.h" | ||
57 | #ifndef OPENSSL_NO_ENGINE | ||
58 | #include <openssl/engine.h> | ||
59 | #endif | ||
60 | |||
61 | ECDSA_SIG *ECDSA_do_sign(const unsigned char *dgst, int dlen, EC_KEY *eckey) | ||
62 | { | ||
63 | return ECDSA_do_sign_ex(dgst, dlen, NULL, NULL, eckey); | ||
64 | } | ||
65 | |||
66 | ECDSA_SIG *ECDSA_do_sign_ex(const unsigned char *dgst, int dlen, | ||
67 | const BIGNUM *kinv, const BIGNUM *rp, EC_KEY *eckey) | ||
68 | { | ||
69 | ECDSA_DATA *ecdsa = ecdsa_check(eckey); | ||
70 | if (ecdsa == NULL) | ||
71 | return NULL; | ||
72 | return ecdsa->meth->ecdsa_do_sign(dgst, dlen, kinv, rp, eckey); | ||
73 | } | ||
74 | |||
75 | int ECDSA_sign(int type, const unsigned char *dgst, int dlen, unsigned char | ||
76 | *sig, unsigned int *siglen, EC_KEY *eckey) | ||
77 | { | ||
78 | return ECDSA_sign_ex(type, dgst, dlen, sig, siglen, NULL, NULL, eckey); | ||
79 | } | ||
80 | |||
81 | int ECDSA_sign_ex(int type, const unsigned char *dgst, int dlen, unsigned char | ||
82 | *sig, unsigned int *siglen, const BIGNUM *kinv, const BIGNUM *r, | ||
83 | EC_KEY *eckey) | ||
84 | { | ||
85 | ECDSA_SIG *s; | ||
86 | s = ECDSA_do_sign_ex(dgst, dlen, kinv, r, eckey); | ||
87 | if (s == NULL) | ||
88 | { | ||
89 | *siglen=0; | ||
90 | return 0; | ||
91 | } | ||
92 | *siglen = i2d_ECDSA_SIG(s, &sig); | ||
93 | ECDSA_SIG_free(s); | ||
94 | return 1; | ||
95 | } | ||
96 | |||
97 | int ECDSA_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp, | ||
98 | BIGNUM **rp) | ||
99 | { | ||
100 | ECDSA_DATA *ecdsa = ecdsa_check(eckey); | ||
101 | if (ecdsa == NULL) | ||
102 | return 0; | ||
103 | return ecdsa->meth->ecdsa_sign_setup(eckey, ctx_in, kinvp, rp); | ||
104 | } | ||
diff --git a/src/lib/libcrypto/ecdsa/ecs_vrf.c b/src/lib/libcrypto/ecdsa/ecs_vrf.c new file mode 100644 index 0000000000..ef9acf7b61 --- /dev/null +++ b/src/lib/libcrypto/ecdsa/ecs_vrf.c | |||
@@ -0,0 +1,96 @@ | |||
1 | /* crypto/ecdsa/ecdsa_vrf.c */ | ||
2 | /* | ||
3 | * Written by Nils Larsch for the OpenSSL project | ||
4 | */ | ||
5 | /* ==================================================================== | ||
6 | * Copyright (c) 1998-2002 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 | * openssl-core@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 | * This product includes cryptographic software written by Eric Young | ||
54 | * (eay@cryptsoft.com). This product includes software written by Tim | ||
55 | * Hudson (tjh@cryptsoft.com). | ||
56 | * | ||
57 | */ | ||
58 | |||
59 | #include "ecs_locl.h" | ||
60 | #ifndef OPENSSL_NO_ENGINE | ||
61 | #include <openssl/engine.h> | ||
62 | #endif | ||
63 | |||
64 | /* returns | ||
65 | * 1: correct signature | ||
66 | * 0: incorrect signature | ||
67 | * -1: error | ||
68 | */ | ||
69 | int ECDSA_do_verify(const unsigned char *dgst, int dgst_len, | ||
70 | const ECDSA_SIG *sig, EC_KEY *eckey) | ||
71 | { | ||
72 | ECDSA_DATA *ecdsa = ecdsa_check(eckey); | ||
73 | if (ecdsa == NULL) | ||
74 | return 0; | ||
75 | return ecdsa->meth->ecdsa_do_verify(dgst, dgst_len, sig, eckey); | ||
76 | } | ||
77 | |||
78 | /* returns | ||
79 | * 1: correct signature | ||
80 | * 0: incorrect signature | ||
81 | * -1: error | ||
82 | */ | ||
83 | int ECDSA_verify(int type, const unsigned char *dgst, int dgst_len, | ||
84 | const unsigned char *sigbuf, int sig_len, EC_KEY *eckey) | ||
85 | { | ||
86 | ECDSA_SIG *s; | ||
87 | int ret=-1; | ||
88 | |||
89 | s = ECDSA_SIG_new(); | ||
90 | if (s == NULL) return(ret); | ||
91 | if (d2i_ECDSA_SIG(&s, &sigbuf, sig_len) == NULL) goto err; | ||
92 | ret=ECDSA_do_verify(dgst, dgst_len, s, eckey); | ||
93 | err: | ||
94 | ECDSA_SIG_free(s); | ||
95 | return(ret); | ||
96 | } | ||
diff --git a/src/lib/libcrypto/engine/eng_padlock.c b/src/lib/libcrypto/engine/eng_padlock.c new file mode 100644 index 0000000000..1ba9d85db4 --- /dev/null +++ b/src/lib/libcrypto/engine/eng_padlock.c | |||
@@ -0,0 +1,1219 @@ | |||
1 | /* | ||
2 | * Support for VIA PadLock Advanced Cryptography Engine (ACE) | ||
3 | * Written by Michal Ludvig <michal@logix.cz> | ||
4 | * http://www.logix.cz/michal | ||
5 | * | ||
6 | * Big thanks to Andy Polyakov for a help with optimization, | ||
7 | * assembler fixes, port to MS Windows and a lot of other | ||
8 | * valuable work on this engine! | ||
9 | */ | ||
10 | |||
11 | /* ==================================================================== | ||
12 | * Copyright (c) 1999-2001 The OpenSSL Project. All rights reserved. | ||
13 | * | ||
14 | * Redistribution and use in source and binary forms, with or without | ||
15 | * modification, are permitted provided that the following conditions | ||
16 | * are met: | ||
17 | * | ||
18 | * 1. Redistributions of source code must retain the above copyright | ||
19 | * notice, this list of conditions and the following disclaimer. | ||
20 | * | ||
21 | * 2. Redistributions in binary form must reproduce the above copyright | ||
22 | * notice, this list of conditions and the following disclaimer in | ||
23 | * the documentation and/or other materials provided with the | ||
24 | * distribution. | ||
25 | * | ||
26 | * 3. All advertising materials mentioning features or use of this | ||
27 | * software must display the following acknowledgment: | ||
28 | * "This product includes software developed by the OpenSSL Project | ||
29 | * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" | ||
30 | * | ||
31 | * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to | ||
32 | * endorse or promote products derived from this software without | ||
33 | * prior written permission. For written permission, please contact | ||
34 | * licensing@OpenSSL.org. | ||
35 | * | ||
36 | * 5. Products derived from this software may not be called "OpenSSL" | ||
37 | * nor may "OpenSSL" appear in their names without prior written | ||
38 | * permission of the OpenSSL Project. | ||
39 | * | ||
40 | * 6. Redistributions of any form whatsoever must retain the following | ||
41 | * acknowledgment: | ||
42 | * "This product includes software developed by the OpenSSL Project | ||
43 | * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" | ||
44 | * | ||
45 | * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY | ||
46 | * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
47 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | ||
48 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR | ||
49 | * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
50 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
51 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
52 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
53 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
54 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
55 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED | ||
56 | * OF THE POSSIBILITY OF SUCH DAMAGE. | ||
57 | * ==================================================================== | ||
58 | * | ||
59 | * This product includes cryptographic software written by Eric Young | ||
60 | * (eay@cryptsoft.com). This product includes software written by Tim | ||
61 | * Hudson (tjh@cryptsoft.com). | ||
62 | * | ||
63 | */ | ||
64 | |||
65 | |||
66 | #include <stdio.h> | ||
67 | #include <string.h> | ||
68 | |||
69 | #include <openssl/opensslconf.h> | ||
70 | #include <openssl/crypto.h> | ||
71 | #include <openssl/dso.h> | ||
72 | #include <openssl/engine.h> | ||
73 | #include <openssl/evp.h> | ||
74 | #ifndef OPENSSL_NO_AES | ||
75 | #include <openssl/aes.h> | ||
76 | #endif | ||
77 | #include <openssl/rand.h> | ||
78 | #include <openssl/err.h> | ||
79 | |||
80 | #ifndef OPENSSL_NO_HW | ||
81 | #ifndef OPENSSL_NO_HW_PADLOCK | ||
82 | |||
83 | /* Attempt to have a single source for both 0.9.7 and 0.9.8 :-) */ | ||
84 | #if (OPENSSL_VERSION_NUMBER >= 0x00908000L) | ||
85 | # ifndef OPENSSL_NO_DYNAMIC_ENGINE | ||
86 | # define DYNAMIC_ENGINE | ||
87 | # endif | ||
88 | #elif (OPENSSL_VERSION_NUMBER >= 0x00907000L) | ||
89 | # ifdef ENGINE_DYNAMIC_SUPPORT | ||
90 | # define DYNAMIC_ENGINE | ||
91 | # endif | ||
92 | #else | ||
93 | # error "Only OpenSSL >= 0.9.7 is supported" | ||
94 | #endif | ||
95 | |||
96 | /* VIA PadLock AES is available *ONLY* on some x86 CPUs. | ||
97 | Not only that it doesn't exist elsewhere, but it | ||
98 | even can't be compiled on other platforms! | ||
99 | |||
100 | In addition, because of the heavy use of inline assembler, | ||
101 | compiler choice is limited to GCC and Microsoft C. */ | ||
102 | #undef COMPILE_HW_PADLOCK | ||
103 | #if !defined(I386_ONLY) && !defined(OPENSSL_NO_INLINE_ASM) | ||
104 | # if (defined(__GNUC__) && (defined(__i386__) || defined(__i386))) || \ | ||
105 | (defined(_MSC_VER) && defined(_M_IX86)) | ||
106 | # define COMPILE_HW_PADLOCK | ||
107 | static ENGINE *ENGINE_padlock (void); | ||
108 | # endif | ||
109 | #endif | ||
110 | |||
111 | void ENGINE_load_padlock (void) | ||
112 | { | ||
113 | /* On non-x86 CPUs it just returns. */ | ||
114 | #ifdef COMPILE_HW_PADLOCK | ||
115 | ENGINE *toadd = ENGINE_padlock (); | ||
116 | if (!toadd) return; | ||
117 | ENGINE_add (toadd); | ||
118 | ENGINE_free (toadd); | ||
119 | ERR_clear_error (); | ||
120 | #endif | ||
121 | } | ||
122 | |||
123 | #ifdef COMPILE_HW_PADLOCK | ||
124 | /* We do these includes here to avoid header problems on platforms that | ||
125 | do not have the VIA padlock anyway... */ | ||
126 | #ifdef _MSC_VER | ||
127 | # include <malloc.h> | ||
128 | # define alloca _alloca | ||
129 | #elif defined(NETWARE_CLIB) && defined(__GNUC__) | ||
130 | void *alloca(size_t); | ||
131 | # define alloca(s) __builtin_alloca(s) | ||
132 | #else | ||
133 | # include <stdlib.h> | ||
134 | #endif | ||
135 | |||
136 | /* Function for ENGINE detection and control */ | ||
137 | static int padlock_available(void); | ||
138 | static int padlock_init(ENGINE *e); | ||
139 | |||
140 | /* RNG Stuff */ | ||
141 | static RAND_METHOD padlock_rand; | ||
142 | |||
143 | /* Cipher Stuff */ | ||
144 | #ifndef OPENSSL_NO_AES | ||
145 | static int padlock_ciphers(ENGINE *e, const EVP_CIPHER **cipher, const int **nids, int nid); | ||
146 | #endif | ||
147 | |||
148 | /* Engine names */ | ||
149 | static const char *padlock_id = "padlock"; | ||
150 | static char padlock_name[100]; | ||
151 | |||
152 | /* Available features */ | ||
153 | static int padlock_use_ace = 0; /* Advanced Cryptography Engine */ | ||
154 | static int padlock_use_rng = 0; /* Random Number Generator */ | ||
155 | #ifndef OPENSSL_NO_AES | ||
156 | static int padlock_aes_align_required = 1; | ||
157 | #endif | ||
158 | |||
159 | /* ===== Engine "management" functions ===== */ | ||
160 | |||
161 | /* Prepare the ENGINE structure for registration */ | ||
162 | static int | ||
163 | padlock_bind_helper(ENGINE *e) | ||
164 | { | ||
165 | /* Check available features */ | ||
166 | padlock_available(); | ||
167 | |||
168 | #if 1 /* disable RNG for now, see commentary in vicinity of RNG code */ | ||
169 | padlock_use_rng=0; | ||
170 | #endif | ||
171 | |||
172 | /* Generate a nice engine name with available features */ | ||
173 | BIO_snprintf(padlock_name, sizeof(padlock_name), | ||
174 | "VIA PadLock (%s, %s)", | ||
175 | padlock_use_rng ? "RNG" : "no-RNG", | ||
176 | padlock_use_ace ? "ACE" : "no-ACE"); | ||
177 | |||
178 | /* Register everything or return with an error */ | ||
179 | if (!ENGINE_set_id(e, padlock_id) || | ||
180 | !ENGINE_set_name(e, padlock_name) || | ||
181 | |||
182 | !ENGINE_set_init_function(e, padlock_init) || | ||
183 | #ifndef OPENSSL_NO_AES | ||
184 | (padlock_use_ace && !ENGINE_set_ciphers (e, padlock_ciphers)) || | ||
185 | #endif | ||
186 | (padlock_use_rng && !ENGINE_set_RAND (e, &padlock_rand))) { | ||
187 | return 0; | ||
188 | } | ||
189 | |||
190 | /* Everything looks good */ | ||
191 | return 1; | ||
192 | } | ||
193 | |||
194 | /* Constructor */ | ||
195 | static ENGINE * | ||
196 | ENGINE_padlock(void) | ||
197 | { | ||
198 | ENGINE *eng = ENGINE_new(); | ||
199 | |||
200 | if (!eng) { | ||
201 | return NULL; | ||
202 | } | ||
203 | |||
204 | if (!padlock_bind_helper(eng)) { | ||
205 | ENGINE_free(eng); | ||
206 | return NULL; | ||
207 | } | ||
208 | |||
209 | return eng; | ||
210 | } | ||
211 | |||
212 | /* Check availability of the engine */ | ||
213 | static int | ||
214 | padlock_init(ENGINE *e) | ||
215 | { | ||
216 | return (padlock_use_rng || padlock_use_ace); | ||
217 | } | ||
218 | |||
219 | /* This stuff is needed if this ENGINE is being compiled into a self-contained | ||
220 | * shared-library. | ||
221 | */ | ||
222 | #ifdef DYNAMIC_ENGINE | ||
223 | static int | ||
224 | padlock_bind_fn(ENGINE *e, const char *id) | ||
225 | { | ||
226 | if (id && (strcmp(id, padlock_id) != 0)) { | ||
227 | return 0; | ||
228 | } | ||
229 | |||
230 | if (!padlock_bind_helper(e)) { | ||
231 | return 0; | ||
232 | } | ||
233 | |||
234 | return 1; | ||
235 | } | ||
236 | |||
237 | IMPLEMENT_DYNAMIC_CHECK_FN (); | ||
238 | IMPLEMENT_DYNAMIC_BIND_FN (padlock_bind_fn); | ||
239 | #endif /* DYNAMIC_ENGINE */ | ||
240 | |||
241 | /* ===== Here comes the "real" engine ===== */ | ||
242 | |||
243 | #ifndef OPENSSL_NO_AES | ||
244 | /* Some AES-related constants */ | ||
245 | #define AES_BLOCK_SIZE 16 | ||
246 | #define AES_KEY_SIZE_128 16 | ||
247 | #define AES_KEY_SIZE_192 24 | ||
248 | #define AES_KEY_SIZE_256 32 | ||
249 | |||
250 | /* Here we store the status information relevant to the | ||
251 | current context. */ | ||
252 | /* BIG FAT WARNING: | ||
253 | * Inline assembler in PADLOCK_XCRYPT_ASM() | ||
254 | * depends on the order of items in this structure. | ||
255 | * Don't blindly modify, reorder, etc! | ||
256 | */ | ||
257 | struct padlock_cipher_data | ||
258 | { | ||
259 | unsigned char iv[AES_BLOCK_SIZE]; /* Initialization vector */ | ||
260 | union { unsigned int pad[4]; | ||
261 | struct { | ||
262 | int rounds:4; | ||
263 | int dgst:1; /* n/a in C3 */ | ||
264 | int align:1; /* n/a in C3 */ | ||
265 | int ciphr:1; /* n/a in C3 */ | ||
266 | unsigned int keygen:1; | ||
267 | int interm:1; | ||
268 | unsigned int encdec:1; | ||
269 | int ksize:2; | ||
270 | } b; | ||
271 | } cword; /* Control word */ | ||
272 | AES_KEY ks; /* Encryption key */ | ||
273 | }; | ||
274 | |||
275 | /* | ||
276 | * Essentially this variable belongs in thread local storage. | ||
277 | * Having this variable global on the other hand can only cause | ||
278 | * few bogus key reloads [if any at all on single-CPU system], | ||
279 | * so we accept the penatly... | ||
280 | */ | ||
281 | static volatile struct padlock_cipher_data *padlock_saved_context; | ||
282 | #endif | ||
283 | |||
284 | /* | ||
285 | * ======================================================= | ||
286 | * Inline assembler section(s). | ||
287 | * ======================================================= | ||
288 | * Order of arguments is chosen to facilitate Windows port | ||
289 | * using __fastcall calling convention. If you wish to add | ||
290 | * more routines, keep in mind that first __fastcall | ||
291 | * argument is passed in %ecx and second - in %edx. | ||
292 | * ======================================================= | ||
293 | */ | ||
294 | #if defined(__GNUC__) && __GNUC__>=2 | ||
295 | /* | ||
296 | * As for excessive "push %ebx"/"pop %ebx" found all over. | ||
297 | * When generating position-independent code GCC won't let | ||
298 | * us use "b" in assembler templates nor even respect "ebx" | ||
299 | * in "clobber description." Therefore the trouble... | ||
300 | */ | ||
301 | |||
302 | /* Helper function - check if a CPUID instruction | ||
303 | is available on this CPU */ | ||
304 | static int | ||
305 | padlock_insn_cpuid_available(void) | ||
306 | { | ||
307 | int result = -1; | ||
308 | |||
309 | /* We're checking if the bit #21 of EFLAGS | ||
310 | can be toggled. If yes = CPUID is available. */ | ||
311 | asm volatile ( | ||
312 | "pushf\n" | ||
313 | "popl %%eax\n" | ||
314 | "xorl $0x200000, %%eax\n" | ||
315 | "movl %%eax, %%ecx\n" | ||
316 | "andl $0x200000, %%ecx\n" | ||
317 | "pushl %%eax\n" | ||
318 | "popf\n" | ||
319 | "pushf\n" | ||
320 | "popl %%eax\n" | ||
321 | "andl $0x200000, %%eax\n" | ||
322 | "xorl %%eax, %%ecx\n" | ||
323 | "movl %%ecx, %0\n" | ||
324 | : "=r" (result) : : "eax", "ecx"); | ||
325 | |||
326 | return (result == 0); | ||
327 | } | ||
328 | |||
329 | /* Load supported features of the CPU to see if | ||
330 | the PadLock is available. */ | ||
331 | static int | ||
332 | padlock_available(void) | ||
333 | { | ||
334 | char vendor_string[16]; | ||
335 | unsigned int eax, edx; | ||
336 | |||
337 | /* First check if the CPUID instruction is available at all... */ | ||
338 | if (! padlock_insn_cpuid_available()) | ||
339 | return 0; | ||
340 | |||
341 | /* Are we running on the Centaur (VIA) CPU? */ | ||
342 | eax = 0x00000000; | ||
343 | vendor_string[12] = 0; | ||
344 | asm volatile ( | ||
345 | "pushl %%ebx\n" | ||
346 | "cpuid\n" | ||
347 | "movl %%ebx,(%%edi)\n" | ||
348 | "movl %%edx,4(%%edi)\n" | ||
349 | "movl %%ecx,8(%%edi)\n" | ||
350 | "popl %%ebx" | ||
351 | : "+a"(eax) : "D"(vendor_string) : "ecx", "edx"); | ||
352 | if (strcmp(vendor_string, "CentaurHauls") != 0) | ||
353 | return 0; | ||
354 | |||
355 | /* Check for Centaur Extended Feature Flags presence */ | ||
356 | eax = 0xC0000000; | ||
357 | asm volatile ("pushl %%ebx; cpuid; popl %%ebx" | ||
358 | : "+a"(eax) : : "ecx", "edx"); | ||
359 | if (eax < 0xC0000001) | ||
360 | return 0; | ||
361 | |||
362 | /* Read the Centaur Extended Feature Flags */ | ||
363 | eax = 0xC0000001; | ||
364 | asm volatile ("pushl %%ebx; cpuid; popl %%ebx" | ||
365 | : "+a"(eax), "=d"(edx) : : "ecx"); | ||
366 | |||
367 | /* Fill up some flags */ | ||
368 | padlock_use_ace = ((edx & (0x3<<6)) == (0x3<<6)); | ||
369 | padlock_use_rng = ((edx & (0x3<<2)) == (0x3<<2)); | ||
370 | |||
371 | return padlock_use_ace + padlock_use_rng; | ||
372 | } | ||
373 | |||
374 | #ifndef OPENSSL_NO_AES | ||
375 | /* Our own htonl()/ntohl() */ | ||
376 | static inline void | ||
377 | padlock_bswapl(AES_KEY *ks) | ||
378 | { | ||
379 | size_t i = sizeof(ks->rd_key)/sizeof(ks->rd_key[0]); | ||
380 | unsigned int *key = ks->rd_key; | ||
381 | |||
382 | while (i--) { | ||
383 | asm volatile ("bswapl %0" : "+r"(*key)); | ||
384 | key++; | ||
385 | } | ||
386 | } | ||
387 | #endif | ||
388 | |||
389 | /* Force key reload from memory to the CPU microcode. | ||
390 | Loading EFLAGS from the stack clears EFLAGS[30] | ||
391 | which does the trick. */ | ||
392 | static inline void | ||
393 | padlock_reload_key(void) | ||
394 | { | ||
395 | asm volatile ("pushfl; popfl"); | ||
396 | } | ||
397 | |||
398 | #ifndef OPENSSL_NO_AES | ||
399 | /* | ||
400 | * This is heuristic key context tracing. At first one | ||
401 | * believes that one should use atomic swap instructions, | ||
402 | * but it's not actually necessary. Point is that if | ||
403 | * padlock_saved_context was changed by another thread | ||
404 | * after we've read it and before we compare it with cdata, | ||
405 | * our key *shall* be reloaded upon thread context switch | ||
406 | * and we are therefore set in either case... | ||
407 | */ | ||
408 | static inline void | ||
409 | padlock_verify_context(struct padlock_cipher_data *cdata) | ||
410 | { | ||
411 | asm volatile ( | ||
412 | "pushfl\n" | ||
413 | " btl $30,(%%esp)\n" | ||
414 | " jnc 1f\n" | ||
415 | " cmpl %2,%1\n" | ||
416 | " je 1f\n" | ||
417 | " popfl\n" | ||
418 | " subl $4,%%esp\n" | ||
419 | "1: addl $4,%%esp\n" | ||
420 | " movl %2,%0" | ||
421 | :"+m"(padlock_saved_context) | ||
422 | : "r"(padlock_saved_context), "r"(cdata) : "cc"); | ||
423 | } | ||
424 | |||
425 | /* Template for padlock_xcrypt_* modes */ | ||
426 | /* BIG FAT WARNING: | ||
427 | * The offsets used with 'leal' instructions | ||
428 | * describe items of the 'padlock_cipher_data' | ||
429 | * structure. | ||
430 | */ | ||
431 | #define PADLOCK_XCRYPT_ASM(name,rep_xcrypt) \ | ||
432 | static inline void *name(size_t cnt, \ | ||
433 | struct padlock_cipher_data *cdata, \ | ||
434 | void *out, const void *inp) \ | ||
435 | { void *iv; \ | ||
436 | asm volatile ( "pushl %%ebx\n" \ | ||
437 | " leal 16(%0),%%edx\n" \ | ||
438 | " leal 32(%0),%%ebx\n" \ | ||
439 | rep_xcrypt "\n" \ | ||
440 | " popl %%ebx" \ | ||
441 | : "=a"(iv), "=c"(cnt), "=D"(out), "=S"(inp) \ | ||
442 | : "0"(cdata), "1"(cnt), "2"(out), "3"(inp) \ | ||
443 | : "edx", "cc", "memory"); \ | ||
444 | return iv; \ | ||
445 | } | ||
446 | |||
447 | /* Generate all functions with appropriate opcodes */ | ||
448 | PADLOCK_XCRYPT_ASM(padlock_xcrypt_ecb, ".byte 0xf3,0x0f,0xa7,0xc8") /* rep xcryptecb */ | ||
449 | PADLOCK_XCRYPT_ASM(padlock_xcrypt_cbc, ".byte 0xf3,0x0f,0xa7,0xd0") /* rep xcryptcbc */ | ||
450 | PADLOCK_XCRYPT_ASM(padlock_xcrypt_cfb, ".byte 0xf3,0x0f,0xa7,0xe0") /* rep xcryptcfb */ | ||
451 | PADLOCK_XCRYPT_ASM(padlock_xcrypt_ofb, ".byte 0xf3,0x0f,0xa7,0xe8") /* rep xcryptofb */ | ||
452 | #endif | ||
453 | |||
454 | /* The RNG call itself */ | ||
455 | static inline unsigned int | ||
456 | padlock_xstore(void *addr, unsigned int edx_in) | ||
457 | { | ||
458 | unsigned int eax_out; | ||
459 | |||
460 | asm volatile (".byte 0x0f,0xa7,0xc0" /* xstore */ | ||
461 | : "=a"(eax_out),"=m"(*(unsigned *)addr) | ||
462 | : "D"(addr), "d" (edx_in) | ||
463 | ); | ||
464 | |||
465 | return eax_out; | ||
466 | } | ||
467 | |||
468 | /* Why not inline 'rep movsd'? I failed to find information on what | ||
469 | * value in Direction Flag one can expect and consequently have to | ||
470 | * apply "better-safe-than-sorry" approach and assume "undefined." | ||
471 | * I could explicitly clear it and restore the original value upon | ||
472 | * return from padlock_aes_cipher, but it's presumably too much | ||
473 | * trouble for too little gain... | ||
474 | * | ||
475 | * In case you wonder 'rep xcrypt*' instructions above are *not* | ||
476 | * affected by the Direction Flag and pointers advance toward | ||
477 | * larger addresses unconditionally. | ||
478 | */ | ||
479 | static inline unsigned char * | ||
480 | padlock_memcpy(void *dst,const void *src,size_t n) | ||
481 | { | ||
482 | long *d=dst; | ||
483 | const long *s=src; | ||
484 | |||
485 | n /= sizeof(*d); | ||
486 | do { *d++ = *s++; } while (--n); | ||
487 | |||
488 | return dst; | ||
489 | } | ||
490 | |||
491 | #elif defined(_MSC_VER) | ||
492 | /* | ||
493 | * Unlike GCC these are real functions. In order to minimize impact | ||
494 | * on performance we adhere to __fastcall calling convention in | ||
495 | * order to get two first arguments passed through %ecx and %edx. | ||
496 | * Which kind of suits very well, as instructions in question use | ||
497 | * both %ecx and %edx as input:-) | ||
498 | */ | ||
499 | #define REP_XCRYPT(code) \ | ||
500 | _asm _emit 0xf3 \ | ||
501 | _asm _emit 0x0f _asm _emit 0xa7 \ | ||
502 | _asm _emit code | ||
503 | |||
504 | /* BIG FAT WARNING: | ||
505 | * The offsets used with 'lea' instructions | ||
506 | * describe items of the 'padlock_cipher_data' | ||
507 | * structure. | ||
508 | */ | ||
509 | #define PADLOCK_XCRYPT_ASM(name,code) \ | ||
510 | static void * __fastcall \ | ||
511 | name (size_t cnt, void *cdata, \ | ||
512 | void *outp, const void *inp) \ | ||
513 | { _asm mov eax,edx \ | ||
514 | _asm lea edx,[eax+16] \ | ||
515 | _asm lea ebx,[eax+32] \ | ||
516 | _asm mov edi,outp \ | ||
517 | _asm mov esi,inp \ | ||
518 | REP_XCRYPT(code) \ | ||
519 | } | ||
520 | |||
521 | PADLOCK_XCRYPT_ASM(padlock_xcrypt_ecb,0xc8) | ||
522 | PADLOCK_XCRYPT_ASM(padlock_xcrypt_cbc,0xd0) | ||
523 | PADLOCK_XCRYPT_ASM(padlock_xcrypt_cfb,0xe0) | ||
524 | PADLOCK_XCRYPT_ASM(padlock_xcrypt_ofb,0xe8) | ||
525 | |||
526 | static int __fastcall | ||
527 | padlock_xstore(void *outp,unsigned int code) | ||
528 | { _asm mov edi,ecx | ||
529 | _asm _emit 0x0f _asm _emit 0xa7 _asm _emit 0xc0 | ||
530 | } | ||
531 | |||
532 | static void __fastcall | ||
533 | padlock_reload_key(void) | ||
534 | { _asm pushfd _asm popfd } | ||
535 | |||
536 | static void __fastcall | ||
537 | padlock_verify_context(void *cdata) | ||
538 | { _asm { | ||
539 | pushfd | ||
540 | bt DWORD PTR[esp],30 | ||
541 | jnc skip | ||
542 | cmp ecx,padlock_saved_context | ||
543 | je skip | ||
544 | popfd | ||
545 | sub esp,4 | ||
546 | skip: add esp,4 | ||
547 | mov padlock_saved_context,ecx | ||
548 | } | ||
549 | } | ||
550 | |||
551 | static int | ||
552 | padlock_available(void) | ||
553 | { _asm { | ||
554 | pushfd | ||
555 | pop eax | ||
556 | mov ecx,eax | ||
557 | xor eax,1<<21 | ||
558 | push eax | ||
559 | popfd | ||
560 | pushfd | ||
561 | pop eax | ||
562 | xor eax,ecx | ||
563 | bt eax,21 | ||
564 | jnc noluck | ||
565 | mov eax,0 | ||
566 | cpuid | ||
567 | xor eax,eax | ||
568 | cmp ebx,'tneC' | ||
569 | jne noluck | ||
570 | cmp edx,'Hrua' | ||
571 | jne noluck | ||
572 | cmp ecx,'slua' | ||
573 | jne noluck | ||
574 | mov eax,0xC0000000 | ||
575 | cpuid | ||
576 | mov edx,eax | ||
577 | xor eax,eax | ||
578 | cmp edx,0xC0000001 | ||
579 | jb noluck | ||
580 | mov eax,0xC0000001 | ||
581 | cpuid | ||
582 | xor eax,eax | ||
583 | bt edx,6 | ||
584 | jnc skip_a | ||
585 | bt edx,7 | ||
586 | jnc skip_a | ||
587 | mov padlock_use_ace,1 | ||
588 | inc eax | ||
589 | skip_a: bt edx,2 | ||
590 | jnc skip_r | ||
591 | bt edx,3 | ||
592 | jnc skip_r | ||
593 | mov padlock_use_rng,1 | ||
594 | inc eax | ||
595 | skip_r: | ||
596 | noluck: | ||
597 | } | ||
598 | } | ||
599 | |||
600 | static void __fastcall | ||
601 | padlock_bswapl(void *key) | ||
602 | { _asm { | ||
603 | pushfd | ||
604 | cld | ||
605 | mov esi,ecx | ||
606 | mov edi,ecx | ||
607 | mov ecx,60 | ||
608 | up: lodsd | ||
609 | bswap eax | ||
610 | stosd | ||
611 | loop up | ||
612 | popfd | ||
613 | } | ||
614 | } | ||
615 | |||
616 | /* MS actually specifies status of Direction Flag and compiler even | ||
617 | * manages to compile following as 'rep movsd' all by itself... | ||
618 | */ | ||
619 | #define padlock_memcpy(o,i,n) ((unsigned char *)memcpy((o),(i),(n)&~3U)) | ||
620 | #endif | ||
621 | |||
622 | /* ===== AES encryption/decryption ===== */ | ||
623 | #ifndef OPENSSL_NO_AES | ||
624 | |||
625 | #if defined(NID_aes_128_cfb128) && ! defined (NID_aes_128_cfb) | ||
626 | #define NID_aes_128_cfb NID_aes_128_cfb128 | ||
627 | #endif | ||
628 | |||
629 | #if defined(NID_aes_128_ofb128) && ! defined (NID_aes_128_ofb) | ||
630 | #define NID_aes_128_ofb NID_aes_128_ofb128 | ||
631 | #endif | ||
632 | |||
633 | #if defined(NID_aes_192_cfb128) && ! defined (NID_aes_192_cfb) | ||
634 | #define NID_aes_192_cfb NID_aes_192_cfb128 | ||
635 | #endif | ||
636 | |||
637 | #if defined(NID_aes_192_ofb128) && ! defined (NID_aes_192_ofb) | ||
638 | #define NID_aes_192_ofb NID_aes_192_ofb128 | ||
639 | #endif | ||
640 | |||
641 | #if defined(NID_aes_256_cfb128) && ! defined (NID_aes_256_cfb) | ||
642 | #define NID_aes_256_cfb NID_aes_256_cfb128 | ||
643 | #endif | ||
644 | |||
645 | #if defined(NID_aes_256_ofb128) && ! defined (NID_aes_256_ofb) | ||
646 | #define NID_aes_256_ofb NID_aes_256_ofb128 | ||
647 | #endif | ||
648 | |||
649 | /* List of supported ciphers. */ | ||
650 | static int padlock_cipher_nids[] = { | ||
651 | NID_aes_128_ecb, | ||
652 | NID_aes_128_cbc, | ||
653 | NID_aes_128_cfb, | ||
654 | NID_aes_128_ofb, | ||
655 | |||
656 | NID_aes_192_ecb, | ||
657 | NID_aes_192_cbc, | ||
658 | NID_aes_192_cfb, | ||
659 | NID_aes_192_ofb, | ||
660 | |||
661 | NID_aes_256_ecb, | ||
662 | NID_aes_256_cbc, | ||
663 | NID_aes_256_cfb, | ||
664 | NID_aes_256_ofb, | ||
665 | }; | ||
666 | static int padlock_cipher_nids_num = (sizeof(padlock_cipher_nids)/ | ||
667 | sizeof(padlock_cipher_nids[0])); | ||
668 | |||
669 | /* Function prototypes ... */ | ||
670 | static int padlock_aes_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, | ||
671 | const unsigned char *iv, int enc); | ||
672 | static int padlock_aes_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, | ||
673 | const unsigned char *in, size_t nbytes); | ||
674 | |||
675 | #define NEAREST_ALIGNED(ptr) ( (unsigned char *)(ptr) + \ | ||
676 | ( (0x10 - ((size_t)(ptr) & 0x0F)) & 0x0F ) ) | ||
677 | #define ALIGNED_CIPHER_DATA(ctx) ((struct padlock_cipher_data *)\ | ||
678 | NEAREST_ALIGNED(ctx->cipher_data)) | ||
679 | |||
680 | #define EVP_CIPHER_block_size_ECB AES_BLOCK_SIZE | ||
681 | #define EVP_CIPHER_block_size_CBC AES_BLOCK_SIZE | ||
682 | #define EVP_CIPHER_block_size_OFB 1 | ||
683 | #define EVP_CIPHER_block_size_CFB 1 | ||
684 | |||
685 | /* Declaring so many ciphers by hand would be a pain. | ||
686 | Instead introduce a bit of preprocessor magic :-) */ | ||
687 | #define DECLARE_AES_EVP(ksize,lmode,umode) \ | ||
688 | static const EVP_CIPHER padlock_aes_##ksize##_##lmode = { \ | ||
689 | NID_aes_##ksize##_##lmode, \ | ||
690 | EVP_CIPHER_block_size_##umode, \ | ||
691 | AES_KEY_SIZE_##ksize, \ | ||
692 | AES_BLOCK_SIZE, \ | ||
693 | 0 | EVP_CIPH_##umode##_MODE, \ | ||
694 | padlock_aes_init_key, \ | ||
695 | padlock_aes_cipher, \ | ||
696 | NULL, \ | ||
697 | sizeof(struct padlock_cipher_data) + 16, \ | ||
698 | EVP_CIPHER_set_asn1_iv, \ | ||
699 | EVP_CIPHER_get_asn1_iv, \ | ||
700 | NULL, \ | ||
701 | NULL \ | ||
702 | } | ||
703 | |||
704 | DECLARE_AES_EVP(128,ecb,ECB); | ||
705 | DECLARE_AES_EVP(128,cbc,CBC); | ||
706 | DECLARE_AES_EVP(128,cfb,CFB); | ||
707 | DECLARE_AES_EVP(128,ofb,OFB); | ||
708 | |||
709 | DECLARE_AES_EVP(192,ecb,ECB); | ||
710 | DECLARE_AES_EVP(192,cbc,CBC); | ||
711 | DECLARE_AES_EVP(192,cfb,CFB); | ||
712 | DECLARE_AES_EVP(192,ofb,OFB); | ||
713 | |||
714 | DECLARE_AES_EVP(256,ecb,ECB); | ||
715 | DECLARE_AES_EVP(256,cbc,CBC); | ||
716 | DECLARE_AES_EVP(256,cfb,CFB); | ||
717 | DECLARE_AES_EVP(256,ofb,OFB); | ||
718 | |||
719 | static int | ||
720 | padlock_ciphers (ENGINE *e, const EVP_CIPHER **cipher, const int **nids, int nid) | ||
721 | { | ||
722 | /* No specific cipher => return a list of supported nids ... */ | ||
723 | if (!cipher) { | ||
724 | *nids = padlock_cipher_nids; | ||
725 | return padlock_cipher_nids_num; | ||
726 | } | ||
727 | |||
728 | /* ... or the requested "cipher" otherwise */ | ||
729 | switch (nid) { | ||
730 | case NID_aes_128_ecb: | ||
731 | *cipher = &padlock_aes_128_ecb; | ||
732 | break; | ||
733 | case NID_aes_128_cbc: | ||
734 | *cipher = &padlock_aes_128_cbc; | ||
735 | break; | ||
736 | case NID_aes_128_cfb: | ||
737 | *cipher = &padlock_aes_128_cfb; | ||
738 | break; | ||
739 | case NID_aes_128_ofb: | ||
740 | *cipher = &padlock_aes_128_ofb; | ||
741 | break; | ||
742 | |||
743 | case NID_aes_192_ecb: | ||
744 | *cipher = &padlock_aes_192_ecb; | ||
745 | break; | ||
746 | case NID_aes_192_cbc: | ||
747 | *cipher = &padlock_aes_192_cbc; | ||
748 | break; | ||
749 | case NID_aes_192_cfb: | ||
750 | *cipher = &padlock_aes_192_cfb; | ||
751 | break; | ||
752 | case NID_aes_192_ofb: | ||
753 | *cipher = &padlock_aes_192_ofb; | ||
754 | break; | ||
755 | |||
756 | case NID_aes_256_ecb: | ||
757 | *cipher = &padlock_aes_256_ecb; | ||
758 | break; | ||
759 | case NID_aes_256_cbc: | ||
760 | *cipher = &padlock_aes_256_cbc; | ||
761 | break; | ||
762 | case NID_aes_256_cfb: | ||
763 | *cipher = &padlock_aes_256_cfb; | ||
764 | break; | ||
765 | case NID_aes_256_ofb: | ||
766 | *cipher = &padlock_aes_256_ofb; | ||
767 | break; | ||
768 | |||
769 | default: | ||
770 | /* Sorry, we don't support this NID */ | ||
771 | *cipher = NULL; | ||
772 | return 0; | ||
773 | } | ||
774 | |||
775 | return 1; | ||
776 | } | ||
777 | |||
778 | /* Prepare the encryption key for PadLock usage */ | ||
779 | static int | ||
780 | padlock_aes_init_key (EVP_CIPHER_CTX *ctx, const unsigned char *key, | ||
781 | const unsigned char *iv, int enc) | ||
782 | { | ||
783 | struct padlock_cipher_data *cdata; | ||
784 | int key_len = EVP_CIPHER_CTX_key_length(ctx) * 8; | ||
785 | |||
786 | if (key==NULL) return 0; /* ERROR */ | ||
787 | |||
788 | cdata = ALIGNED_CIPHER_DATA(ctx); | ||
789 | memset(cdata, 0, sizeof(struct padlock_cipher_data)); | ||
790 | |||
791 | /* Prepare Control word. */ | ||
792 | if (EVP_CIPHER_CTX_mode(ctx) == EVP_CIPH_OFB_MODE) | ||
793 | cdata->cword.b.encdec = 0; | ||
794 | else | ||
795 | cdata->cword.b.encdec = (ctx->encrypt == 0); | ||
796 | cdata->cword.b.rounds = 10 + (key_len - 128) / 32; | ||
797 | cdata->cword.b.ksize = (key_len - 128) / 64; | ||
798 | |||
799 | switch(key_len) { | ||
800 | case 128: | ||
801 | /* PadLock can generate an extended key for | ||
802 | AES128 in hardware */ | ||
803 | memcpy(cdata->ks.rd_key, key, AES_KEY_SIZE_128); | ||
804 | cdata->cword.b.keygen = 0; | ||
805 | break; | ||
806 | |||
807 | case 192: | ||
808 | case 256: | ||
809 | /* Generate an extended AES key in software. | ||
810 | Needed for AES192/AES256 */ | ||
811 | /* Well, the above applies to Stepping 8 CPUs | ||
812 | and is listed as hardware errata. They most | ||
813 | likely will fix it at some point and then | ||
814 | a check for stepping would be due here. */ | ||
815 | if (EVP_CIPHER_CTX_mode(ctx) == EVP_CIPH_CFB_MODE || | ||
816 | EVP_CIPHER_CTX_mode(ctx) == EVP_CIPH_OFB_MODE || | ||
817 | enc) | ||
818 | AES_set_encrypt_key(key, key_len, &cdata->ks); | ||
819 | else | ||
820 | AES_set_decrypt_key(key, key_len, &cdata->ks); | ||
821 | #ifndef AES_ASM | ||
822 | /* OpenSSL C functions use byte-swapped extended key. */ | ||
823 | padlock_bswapl(&cdata->ks); | ||
824 | #endif | ||
825 | cdata->cword.b.keygen = 1; | ||
826 | break; | ||
827 | |||
828 | default: | ||
829 | /* ERROR */ | ||
830 | return 0; | ||
831 | } | ||
832 | |||
833 | /* | ||
834 | * This is done to cover for cases when user reuses the | ||
835 | * context for new key. The catch is that if we don't do | ||
836 | * this, padlock_eas_cipher might proceed with old key... | ||
837 | */ | ||
838 | padlock_reload_key (); | ||
839 | |||
840 | return 1; | ||
841 | } | ||
842 | |||
843 | /* | ||
844 | * Simplified version of padlock_aes_cipher() used when | ||
845 | * 1) both input and output buffers are at aligned addresses. | ||
846 | * or when | ||
847 | * 2) running on a newer CPU that doesn't require aligned buffers. | ||
848 | */ | ||
849 | static int | ||
850 | padlock_aes_cipher_omnivorous(EVP_CIPHER_CTX *ctx, unsigned char *out_arg, | ||
851 | const unsigned char *in_arg, size_t nbytes) | ||
852 | { | ||
853 | struct padlock_cipher_data *cdata; | ||
854 | void *iv; | ||
855 | |||
856 | cdata = ALIGNED_CIPHER_DATA(ctx); | ||
857 | padlock_verify_context(cdata); | ||
858 | |||
859 | switch (EVP_CIPHER_CTX_mode(ctx)) { | ||
860 | case EVP_CIPH_ECB_MODE: | ||
861 | padlock_xcrypt_ecb(nbytes/AES_BLOCK_SIZE, cdata, out_arg, in_arg); | ||
862 | break; | ||
863 | |||
864 | case EVP_CIPH_CBC_MODE: | ||
865 | memcpy(cdata->iv, ctx->iv, AES_BLOCK_SIZE); | ||
866 | iv = padlock_xcrypt_cbc(nbytes/AES_BLOCK_SIZE, cdata, out_arg, in_arg); | ||
867 | memcpy(ctx->iv, iv, AES_BLOCK_SIZE); | ||
868 | break; | ||
869 | |||
870 | case EVP_CIPH_CFB_MODE: | ||
871 | memcpy(cdata->iv, ctx->iv, AES_BLOCK_SIZE); | ||
872 | iv = padlock_xcrypt_cfb(nbytes/AES_BLOCK_SIZE, cdata, out_arg, in_arg); | ||
873 | memcpy(ctx->iv, iv, AES_BLOCK_SIZE); | ||
874 | break; | ||
875 | |||
876 | case EVP_CIPH_OFB_MODE: | ||
877 | memcpy(cdata->iv, ctx->iv, AES_BLOCK_SIZE); | ||
878 | padlock_xcrypt_ofb(nbytes/AES_BLOCK_SIZE, cdata, out_arg, in_arg); | ||
879 | memcpy(ctx->iv, cdata->iv, AES_BLOCK_SIZE); | ||
880 | break; | ||
881 | |||
882 | default: | ||
883 | return 0; | ||
884 | } | ||
885 | |||
886 | memset(cdata->iv, 0, AES_BLOCK_SIZE); | ||
887 | |||
888 | return 1; | ||
889 | } | ||
890 | |||
891 | #ifndef PADLOCK_CHUNK | ||
892 | # define PADLOCK_CHUNK 512 /* Must be a power of 2 larger than 16 */ | ||
893 | #endif | ||
894 | #if PADLOCK_CHUNK<16 || PADLOCK_CHUNK&(PADLOCK_CHUNK-1) | ||
895 | # error "insane PADLOCK_CHUNK..." | ||
896 | #endif | ||
897 | |||
898 | /* Re-align the arguments to 16-Bytes boundaries and run the | ||
899 | encryption function itself. This function is not AES-specific. */ | ||
900 | static int | ||
901 | padlock_aes_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out_arg, | ||
902 | const unsigned char *in_arg, size_t nbytes) | ||
903 | { | ||
904 | struct padlock_cipher_data *cdata; | ||
905 | const void *inp; | ||
906 | unsigned char *out; | ||
907 | void *iv; | ||
908 | int inp_misaligned, out_misaligned, realign_in_loop; | ||
909 | size_t chunk, allocated=0; | ||
910 | |||
911 | /* ctx->num is maintained in byte-oriented modes, | ||
912 | such as CFB and OFB... */ | ||
913 | if ((chunk = ctx->num)) { /* borrow chunk variable */ | ||
914 | unsigned char *ivp=ctx->iv; | ||
915 | |||
916 | switch (EVP_CIPHER_CTX_mode(ctx)) { | ||
917 | case EVP_CIPH_CFB_MODE: | ||
918 | if (chunk >= AES_BLOCK_SIZE) | ||
919 | return 0; /* bogus value */ | ||
920 | |||
921 | if (ctx->encrypt) | ||
922 | while (chunk<AES_BLOCK_SIZE && nbytes!=0) { | ||
923 | ivp[chunk] = *(out_arg++) = *(in_arg++) ^ ivp[chunk]; | ||
924 | chunk++, nbytes--; | ||
925 | } | ||
926 | else while (chunk<AES_BLOCK_SIZE && nbytes!=0) { | ||
927 | unsigned char c = *(in_arg++); | ||
928 | *(out_arg++) = c ^ ivp[chunk]; | ||
929 | ivp[chunk++] = c, nbytes--; | ||
930 | } | ||
931 | |||
932 | ctx->num = chunk%AES_BLOCK_SIZE; | ||
933 | break; | ||
934 | case EVP_CIPH_OFB_MODE: | ||
935 | if (chunk >= AES_BLOCK_SIZE) | ||
936 | return 0; /* bogus value */ | ||
937 | |||
938 | while (chunk<AES_BLOCK_SIZE && nbytes!=0) { | ||
939 | *(out_arg++) = *(in_arg++) ^ ivp[chunk]; | ||
940 | chunk++, nbytes--; | ||
941 | } | ||
942 | |||
943 | ctx->num = chunk%AES_BLOCK_SIZE; | ||
944 | break; | ||
945 | } | ||
946 | } | ||
947 | |||
948 | if (nbytes == 0) | ||
949 | return 1; | ||
950 | #if 0 | ||
951 | if (nbytes % AES_BLOCK_SIZE) | ||
952 | return 0; /* are we expected to do tail processing? */ | ||
953 | #else | ||
954 | /* nbytes is always multiple of AES_BLOCK_SIZE in ECB and CBC | ||
955 | modes and arbitrary value in byte-oriented modes, such as | ||
956 | CFB and OFB... */ | ||
957 | #endif | ||
958 | |||
959 | /* VIA promises CPUs that won't require alignment in the future. | ||
960 | For now padlock_aes_align_required is initialized to 1 and | ||
961 | the condition is never met... */ | ||
962 | /* C7 core is capable to manage unaligned input in non-ECB[!] | ||
963 | mode, but performance penalties appear to be approximately | ||
964 | same as for software alignment below or ~3x. They promise to | ||
965 | improve it in the future, but for now we can just as well | ||
966 | pretend that it can only handle aligned input... */ | ||
967 | if (!padlock_aes_align_required && (nbytes%AES_BLOCK_SIZE)==0) | ||
968 | return padlock_aes_cipher_omnivorous(ctx, out_arg, in_arg, nbytes); | ||
969 | |||
970 | inp_misaligned = (((size_t)in_arg) & 0x0F); | ||
971 | out_misaligned = (((size_t)out_arg) & 0x0F); | ||
972 | |||
973 | /* Note that even if output is aligned and input not, | ||
974 | * I still prefer to loop instead of copy the whole | ||
975 | * input and then encrypt in one stroke. This is done | ||
976 | * in order to improve L1 cache utilization... */ | ||
977 | realign_in_loop = out_misaligned|inp_misaligned; | ||
978 | |||
979 | if (!realign_in_loop && (nbytes%AES_BLOCK_SIZE)==0) | ||
980 | return padlock_aes_cipher_omnivorous(ctx, out_arg, in_arg, nbytes); | ||
981 | |||
982 | /* this takes one "if" out of the loops */ | ||
983 | chunk = nbytes; | ||
984 | chunk %= PADLOCK_CHUNK; | ||
985 | if (chunk==0) chunk = PADLOCK_CHUNK; | ||
986 | |||
987 | if (out_misaligned) { | ||
988 | /* optmize for small input */ | ||
989 | allocated = (chunk<nbytes?PADLOCK_CHUNK:nbytes); | ||
990 | out = alloca(0x10 + allocated); | ||
991 | out = NEAREST_ALIGNED(out); | ||
992 | } | ||
993 | else | ||
994 | out = out_arg; | ||
995 | |||
996 | cdata = ALIGNED_CIPHER_DATA(ctx); | ||
997 | padlock_verify_context(cdata); | ||
998 | |||
999 | switch (EVP_CIPHER_CTX_mode(ctx)) { | ||
1000 | case EVP_CIPH_ECB_MODE: | ||
1001 | do { | ||
1002 | if (inp_misaligned) | ||
1003 | inp = padlock_memcpy(out, in_arg, chunk); | ||
1004 | else | ||
1005 | inp = in_arg; | ||
1006 | in_arg += chunk; | ||
1007 | |||
1008 | padlock_xcrypt_ecb(chunk/AES_BLOCK_SIZE, cdata, out, inp); | ||
1009 | |||
1010 | if (out_misaligned) | ||
1011 | out_arg = padlock_memcpy(out_arg, out, chunk) + chunk; | ||
1012 | else | ||
1013 | out = out_arg+=chunk; | ||
1014 | |||
1015 | nbytes -= chunk; | ||
1016 | chunk = PADLOCK_CHUNK; | ||
1017 | } while (nbytes); | ||
1018 | break; | ||
1019 | |||
1020 | case EVP_CIPH_CBC_MODE: | ||
1021 | memcpy(cdata->iv, ctx->iv, AES_BLOCK_SIZE); | ||
1022 | goto cbc_shortcut; | ||
1023 | do { | ||
1024 | if (iv != cdata->iv) | ||
1025 | memcpy(cdata->iv, iv, AES_BLOCK_SIZE); | ||
1026 | chunk = PADLOCK_CHUNK; | ||
1027 | cbc_shortcut: /* optimize for small input */ | ||
1028 | if (inp_misaligned) | ||
1029 | inp = padlock_memcpy(out, in_arg, chunk); | ||
1030 | else | ||
1031 | inp = in_arg; | ||
1032 | in_arg += chunk; | ||
1033 | |||
1034 | iv = padlock_xcrypt_cbc(chunk/AES_BLOCK_SIZE, cdata, out, inp); | ||
1035 | |||
1036 | if (out_misaligned) | ||
1037 | out_arg = padlock_memcpy(out_arg, out, chunk) + chunk; | ||
1038 | else | ||
1039 | out = out_arg+=chunk; | ||
1040 | |||
1041 | } while (nbytes -= chunk); | ||
1042 | memcpy(ctx->iv, iv, AES_BLOCK_SIZE); | ||
1043 | break; | ||
1044 | |||
1045 | case EVP_CIPH_CFB_MODE: | ||
1046 | memcpy (iv = cdata->iv, ctx->iv, AES_BLOCK_SIZE); | ||
1047 | chunk &= ~(AES_BLOCK_SIZE-1); | ||
1048 | if (chunk) goto cfb_shortcut; | ||
1049 | else goto cfb_skiploop; | ||
1050 | do { | ||
1051 | if (iv != cdata->iv) | ||
1052 | memcpy(cdata->iv, iv, AES_BLOCK_SIZE); | ||
1053 | chunk = PADLOCK_CHUNK; | ||
1054 | cfb_shortcut: /* optimize for small input */ | ||
1055 | if (inp_misaligned) | ||
1056 | inp = padlock_memcpy(out, in_arg, chunk); | ||
1057 | else | ||
1058 | inp = in_arg; | ||
1059 | in_arg += chunk; | ||
1060 | |||
1061 | iv = padlock_xcrypt_cfb(chunk/AES_BLOCK_SIZE, cdata, out, inp); | ||
1062 | |||
1063 | if (out_misaligned) | ||
1064 | out_arg = padlock_memcpy(out_arg, out, chunk) + chunk; | ||
1065 | else | ||
1066 | out = out_arg+=chunk; | ||
1067 | |||
1068 | nbytes -= chunk; | ||
1069 | } while (nbytes >= AES_BLOCK_SIZE); | ||
1070 | |||
1071 | cfb_skiploop: | ||
1072 | if (nbytes) { | ||
1073 | unsigned char *ivp = cdata->iv; | ||
1074 | |||
1075 | if (iv != ivp) { | ||
1076 | memcpy(ivp, iv, AES_BLOCK_SIZE); | ||
1077 | iv = ivp; | ||
1078 | } | ||
1079 | ctx->num = nbytes; | ||
1080 | if (cdata->cword.b.encdec) { | ||
1081 | cdata->cword.b.encdec=0; | ||
1082 | padlock_reload_key(); | ||
1083 | padlock_xcrypt_ecb(1,cdata,ivp,ivp); | ||
1084 | cdata->cword.b.encdec=1; | ||
1085 | padlock_reload_key(); | ||
1086 | while(nbytes) { | ||
1087 | unsigned char c = *(in_arg++); | ||
1088 | *(out_arg++) = c ^ *ivp; | ||
1089 | *(ivp++) = c, nbytes--; | ||
1090 | } | ||
1091 | } | ||
1092 | else { padlock_reload_key(); | ||
1093 | padlock_xcrypt_ecb(1,cdata,ivp,ivp); | ||
1094 | padlock_reload_key(); | ||
1095 | while (nbytes) { | ||
1096 | *ivp = *(out_arg++) = *(in_arg++) ^ *ivp; | ||
1097 | ivp++, nbytes--; | ||
1098 | } | ||
1099 | } | ||
1100 | } | ||
1101 | |||
1102 | memcpy(ctx->iv, iv, AES_BLOCK_SIZE); | ||
1103 | break; | ||
1104 | |||
1105 | case EVP_CIPH_OFB_MODE: | ||
1106 | memcpy(cdata->iv, ctx->iv, AES_BLOCK_SIZE); | ||
1107 | chunk &= ~(AES_BLOCK_SIZE-1); | ||
1108 | if (chunk) do { | ||
1109 | if (inp_misaligned) | ||
1110 | inp = padlock_memcpy(out, in_arg, chunk); | ||
1111 | else | ||
1112 | inp = in_arg; | ||
1113 | in_arg += chunk; | ||
1114 | |||
1115 | padlock_xcrypt_ofb(chunk/AES_BLOCK_SIZE, cdata, out, inp); | ||
1116 | |||
1117 | if (out_misaligned) | ||
1118 | out_arg = padlock_memcpy(out_arg, out, chunk) + chunk; | ||
1119 | else | ||
1120 | out = out_arg+=chunk; | ||
1121 | |||
1122 | nbytes -= chunk; | ||
1123 | chunk = PADLOCK_CHUNK; | ||
1124 | } while (nbytes >= AES_BLOCK_SIZE); | ||
1125 | |||
1126 | if (nbytes) { | ||
1127 | unsigned char *ivp = cdata->iv; | ||
1128 | |||
1129 | ctx->num = nbytes; | ||
1130 | padlock_reload_key(); /* empirically found */ | ||
1131 | padlock_xcrypt_ecb(1,cdata,ivp,ivp); | ||
1132 | padlock_reload_key(); /* empirically found */ | ||
1133 | while (nbytes) { | ||
1134 | *(out_arg++) = *(in_arg++) ^ *ivp; | ||
1135 | ivp++, nbytes--; | ||
1136 | } | ||
1137 | } | ||
1138 | |||
1139 | memcpy(ctx->iv, cdata->iv, AES_BLOCK_SIZE); | ||
1140 | break; | ||
1141 | |||
1142 | default: | ||
1143 | return 0; | ||
1144 | } | ||
1145 | |||
1146 | /* Clean the realign buffer if it was used */ | ||
1147 | if (out_misaligned) { | ||
1148 | volatile unsigned long *p=(void *)out; | ||
1149 | size_t n = allocated/sizeof(*p); | ||
1150 | while (n--) *p++=0; | ||
1151 | } | ||
1152 | |||
1153 | memset(cdata->iv, 0, AES_BLOCK_SIZE); | ||
1154 | |||
1155 | return 1; | ||
1156 | } | ||
1157 | |||
1158 | #endif /* OPENSSL_NO_AES */ | ||
1159 | |||
1160 | /* ===== Random Number Generator ===== */ | ||
1161 | /* | ||
1162 | * This code is not engaged. The reason is that it does not comply | ||
1163 | * with recommendations for VIA RNG usage for secure applications | ||
1164 | * (posted at http://www.via.com.tw/en/viac3/c3.jsp) nor does it | ||
1165 | * provide meaningful error control... | ||
1166 | */ | ||
1167 | /* Wrapper that provides an interface between the API and | ||
1168 | the raw PadLock RNG */ | ||
1169 | static int | ||
1170 | padlock_rand_bytes(unsigned char *output, int count) | ||
1171 | { | ||
1172 | unsigned int eax, buf; | ||
1173 | |||
1174 | while (count >= 8) { | ||
1175 | eax = padlock_xstore(output, 0); | ||
1176 | if (!(eax&(1<<6))) return 0; /* RNG disabled */ | ||
1177 | /* this ---vv--- covers DC bias, Raw Bits and String Filter */ | ||
1178 | if (eax&(0x1F<<10)) return 0; | ||
1179 | if ((eax&0x1F)==0) continue; /* no data, retry... */ | ||
1180 | if ((eax&0x1F)!=8) return 0; /* fatal failure... */ | ||
1181 | output += 8; | ||
1182 | count -= 8; | ||
1183 | } | ||
1184 | while (count > 0) { | ||
1185 | eax = padlock_xstore(&buf, 3); | ||
1186 | if (!(eax&(1<<6))) return 0; /* RNG disabled */ | ||
1187 | /* this ---vv--- covers DC bias, Raw Bits and String Filter */ | ||
1188 | if (eax&(0x1F<<10)) return 0; | ||
1189 | if ((eax&0x1F)==0) continue; /* no data, retry... */ | ||
1190 | if ((eax&0x1F)!=1) return 0; /* fatal failure... */ | ||
1191 | *output++ = (unsigned char)buf; | ||
1192 | count--; | ||
1193 | } | ||
1194 | *(volatile unsigned int *)&buf=0; | ||
1195 | |||
1196 | return 1; | ||
1197 | } | ||
1198 | |||
1199 | /* Dummy but necessary function */ | ||
1200 | static int | ||
1201 | padlock_rand_status(void) | ||
1202 | { | ||
1203 | return 1; | ||
1204 | } | ||
1205 | |||
1206 | /* Prepare structure for registration */ | ||
1207 | static RAND_METHOD padlock_rand = { | ||
1208 | NULL, /* seed */ | ||
1209 | padlock_rand_bytes, /* bytes */ | ||
1210 | NULL, /* cleanup */ | ||
1211 | NULL, /* add */ | ||
1212 | padlock_rand_bytes, /* pseudorand */ | ||
1213 | padlock_rand_status, /* rand status */ | ||
1214 | }; | ||
1215 | |||
1216 | #endif /* COMPILE_HW_PADLOCK */ | ||
1217 | |||
1218 | #endif /* !OPENSSL_NO_HW_PADLOCK */ | ||
1219 | #endif /* !OPENSSL_NO_HW */ | ||
diff --git a/src/lib/libcrypto/engine/tb_ecdh.c b/src/lib/libcrypto/engine/tb_ecdh.c new file mode 100644 index 0000000000..c8ec7812c5 --- /dev/null +++ b/src/lib/libcrypto/engine/tb_ecdh.c | |||
@@ -0,0 +1,133 @@ | |||
1 | /* crypto/engine/tb_ecdh.c */ | ||
2 | /* ==================================================================== | ||
3 | * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. | ||
4 | * | ||
5 | * The Elliptic Curve Public-Key Crypto Library (ECC Code) included | ||
6 | * herein is developed by SUN MICROSYSTEMS, INC., and is contributed | ||
7 | * to the OpenSSL project. | ||
8 | * | ||
9 | * The ECC Code is licensed pursuant to the OpenSSL open source | ||
10 | * license provided below. | ||
11 | * | ||
12 | * The ECDH engine software is originally written by Nils Gura and | ||
13 | * Douglas Stebila of Sun Microsystems Laboratories. | ||
14 | * | ||
15 | */ | ||
16 | /* ==================================================================== | ||
17 | * Copyright (c) 2000-2002 The OpenSSL Project. All rights reserved. | ||
18 | * | ||
19 | * Redistribution and use in source and binary forms, with or without | ||
20 | * modification, are permitted provided that the following conditions | ||
21 | * are met: | ||
22 | * | ||
23 | * 1. Redistributions of source code must retain the above copyright | ||
24 | * notice, this list of conditions and the following disclaimer. | ||
25 | * | ||
26 | * 2. Redistributions in binary form must reproduce the above copyright | ||
27 | * notice, this list of conditions and the following disclaimer in | ||
28 | * the documentation and/or other materials provided with the | ||
29 | * distribution. | ||
30 | * | ||
31 | * 3. All advertising materials mentioning features or use of this | ||
32 | * software must display the following acknowledgment: | ||
33 | * "This product includes software developed by the OpenSSL Project | ||
34 | * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" | ||
35 | * | ||
36 | * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to | ||
37 | * endorse or promote products derived from this software without | ||
38 | * prior written permission. For written permission, please contact | ||
39 | * licensing@OpenSSL.org. | ||
40 | * | ||
41 | * 5. Products derived from this software may not be called "OpenSSL" | ||
42 | * nor may "OpenSSL" appear in their names without prior written | ||
43 | * permission of the OpenSSL Project. | ||
44 | * | ||
45 | * 6. Redistributions of any form whatsoever must retain the following | ||
46 | * acknowledgment: | ||
47 | * "This product includes software developed by the OpenSSL Project | ||
48 | * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" | ||
49 | * | ||
50 | * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY | ||
51 | * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
52 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | ||
53 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR | ||
54 | * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
55 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
56 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
57 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
58 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
59 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
60 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED | ||
61 | * OF THE POSSIBILITY OF SUCH DAMAGE. | ||
62 | * ==================================================================== | ||
63 | * | ||
64 | * This product includes cryptographic software written by Eric Young | ||
65 | * (eay@cryptsoft.com). This product includes software written by Tim | ||
66 | * Hudson (tjh@cryptsoft.com). | ||
67 | * | ||
68 | */ | ||
69 | |||
70 | #include "eng_int.h" | ||
71 | |||
72 | /* If this symbol is defined then ENGINE_get_default_ECDH(), the function that is | ||
73 | * used by ECDH to hook in implementation code and cache defaults (etc), will | ||
74 | * display brief debugging summaries to stderr with the 'nid'. */ | ||
75 | /* #define ENGINE_ECDH_DEBUG */ | ||
76 | |||
77 | static ENGINE_TABLE *ecdh_table = NULL; | ||
78 | static const int dummy_nid = 1; | ||
79 | |||
80 | void ENGINE_unregister_ECDH(ENGINE *e) | ||
81 | { | ||
82 | engine_table_unregister(&ecdh_table, e); | ||
83 | } | ||
84 | |||
85 | static void engine_unregister_all_ECDH(void) | ||
86 | { | ||
87 | engine_table_cleanup(&ecdh_table); | ||
88 | } | ||
89 | |||
90 | int ENGINE_register_ECDH(ENGINE *e) | ||
91 | { | ||
92 | if(e->ecdh_meth) | ||
93 | return engine_table_register(&ecdh_table, | ||
94 | engine_unregister_all_ECDH, e, &dummy_nid, 1, 0); | ||
95 | return 1; | ||
96 | } | ||
97 | |||
98 | void ENGINE_register_all_ECDH() | ||
99 | { | ||
100 | ENGINE *e; | ||
101 | |||
102 | for(e=ENGINE_get_first() ; e ; e=ENGINE_get_next(e)) | ||
103 | ENGINE_register_ECDH(e); | ||
104 | } | ||
105 | |||
106 | int ENGINE_set_default_ECDH(ENGINE *e) | ||
107 | { | ||
108 | if(e->ecdh_meth) | ||
109 | return engine_table_register(&ecdh_table, | ||
110 | engine_unregister_all_ECDH, e, &dummy_nid, 1, 1); | ||
111 | return 1; | ||
112 | } | ||
113 | |||
114 | /* Exposed API function to get a functional reference from the implementation | ||
115 | * table (ie. try to get a functional reference from the tabled structural | ||
116 | * references). */ | ||
117 | ENGINE *ENGINE_get_default_ECDH(void) | ||
118 | { | ||
119 | return engine_table_select(&ecdh_table, dummy_nid); | ||
120 | } | ||
121 | |||
122 | /* Obtains an ECDH implementation from an ENGINE functional reference */ | ||
123 | const ECDH_METHOD *ENGINE_get_ECDH(const ENGINE *e) | ||
124 | { | ||
125 | return e->ecdh_meth; | ||
126 | } | ||
127 | |||
128 | /* Sets an ECDH implementation in an ENGINE structure */ | ||
129 | int ENGINE_set_ECDH(ENGINE *e, const ECDH_METHOD *ecdh_meth) | ||
130 | { | ||
131 | e->ecdh_meth = ecdh_meth; | ||
132 | return 1; | ||
133 | } | ||
diff --git a/src/lib/libcrypto/engine/tb_ecdsa.c b/src/lib/libcrypto/engine/tb_ecdsa.c new file mode 100644 index 0000000000..005ecb622c --- /dev/null +++ b/src/lib/libcrypto/engine/tb_ecdsa.c | |||
@@ -0,0 +1,118 @@ | |||
1 | /* ==================================================================== | ||
2 | * Copyright (c) 2000-2002 The OpenSSL Project. All rights reserved. | ||
3 | * | ||
4 | * Redistribution and use in source and binary forms, with or without | ||
5 | * modification, are permitted provided that the following conditions | ||
6 | * are met: | ||
7 | * | ||
8 | * 1. Redistributions of source code must retain the above copyright | ||
9 | * notice, this list of conditions and the following disclaimer. | ||
10 | * | ||
11 | * 2. Redistributions in binary form must reproduce the above copyright | ||
12 | * notice, this list of conditions and the following disclaimer in | ||
13 | * the documentation and/or other materials provided with the | ||
14 | * distribution. | ||
15 | * | ||
16 | * 3. All advertising materials mentioning features or use of this | ||
17 | * software must display the following acknowledgment: | ||
18 | * "This product includes software developed by the OpenSSL Project | ||
19 | * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" | ||
20 | * | ||
21 | * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to | ||
22 | * endorse or promote products derived from this software without | ||
23 | * prior written permission. For written permission, please contact | ||
24 | * licensing@OpenSSL.org. | ||
25 | * | ||
26 | * 5. Products derived from this software may not be called "OpenSSL" | ||
27 | * nor may "OpenSSL" appear in their names without prior written | ||
28 | * permission of the OpenSSL Project. | ||
29 | * | ||
30 | * 6. Redistributions of any form whatsoever must retain the following | ||
31 | * acknowledgment: | ||
32 | * "This product includes software developed by the OpenSSL Project | ||
33 | * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" | ||
34 | * | ||
35 | * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY | ||
36 | * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
37 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | ||
38 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR | ||
39 | * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
40 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
41 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
42 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
43 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
44 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
45 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED | ||
46 | * OF THE POSSIBILITY OF SUCH DAMAGE. | ||
47 | * ==================================================================== | ||
48 | * | ||
49 | * This product includes cryptographic software written by Eric Young | ||
50 | * (eay@cryptsoft.com). This product includes software written by Tim | ||
51 | * Hudson (tjh@cryptsoft.com). | ||
52 | * | ||
53 | */ | ||
54 | |||
55 | #include "eng_int.h" | ||
56 | |||
57 | /* If this symbol is defined then ENGINE_get_default_ECDSA(), the function that is | ||
58 | * used by ECDSA to hook in implementation code and cache defaults (etc), will | ||
59 | * display brief debugging summaries to stderr with the 'nid'. */ | ||
60 | /* #define ENGINE_ECDSA_DEBUG */ | ||
61 | |||
62 | static ENGINE_TABLE *ecdsa_table = NULL; | ||
63 | static const int dummy_nid = 1; | ||
64 | |||
65 | void ENGINE_unregister_ECDSA(ENGINE *e) | ||
66 | { | ||
67 | engine_table_unregister(&ecdsa_table, e); | ||
68 | } | ||
69 | |||
70 | static void engine_unregister_all_ECDSA(void) | ||
71 | { | ||
72 | engine_table_cleanup(&ecdsa_table); | ||
73 | } | ||
74 | |||
75 | int ENGINE_register_ECDSA(ENGINE *e) | ||
76 | { | ||
77 | if(e->ecdsa_meth) | ||
78 | return engine_table_register(&ecdsa_table, | ||
79 | engine_unregister_all_ECDSA, e, &dummy_nid, 1, 0); | ||
80 | return 1; | ||
81 | } | ||
82 | |||
83 | void ENGINE_register_all_ECDSA() | ||
84 | { | ||
85 | ENGINE *e; | ||
86 | |||
87 | for(e=ENGINE_get_first() ; e ; e=ENGINE_get_next(e)) | ||
88 | ENGINE_register_ECDSA(e); | ||
89 | } | ||
90 | |||
91 | int ENGINE_set_default_ECDSA(ENGINE *e) | ||
92 | { | ||
93 | if(e->ecdsa_meth) | ||
94 | return engine_table_register(&ecdsa_table, | ||
95 | engine_unregister_all_ECDSA, e, &dummy_nid, 1, 1); | ||
96 | return 1; | ||
97 | } | ||
98 | |||
99 | /* Exposed API function to get a functional reference from the implementation | ||
100 | * table (ie. try to get a functional reference from the tabled structural | ||
101 | * references). */ | ||
102 | ENGINE *ENGINE_get_default_ECDSA(void) | ||
103 | { | ||
104 | return engine_table_select(&ecdsa_table, dummy_nid); | ||
105 | } | ||
106 | |||
107 | /* Obtains an ECDSA implementation from an ENGINE functional reference */ | ||
108 | const ECDSA_METHOD *ENGINE_get_ECDSA(const ENGINE *e) | ||
109 | { | ||
110 | return e->ecdsa_meth; | ||
111 | } | ||
112 | |||
113 | /* Sets an ECDSA implementation in an ENGINE structure */ | ||
114 | int ENGINE_set_ECDSA(ENGINE *e, const ECDSA_METHOD *ecdsa_meth) | ||
115 | { | ||
116 | e->ecdsa_meth = ecdsa_meth; | ||
117 | return 1; | ||
118 | } | ||
diff --git a/src/lib/libcrypto/engine/tb_store.c b/src/lib/libcrypto/engine/tb_store.c new file mode 100644 index 0000000000..8cc435c935 --- /dev/null +++ b/src/lib/libcrypto/engine/tb_store.c | |||
@@ -0,0 +1,123 @@ | |||
1 | /* ==================================================================== | ||
2 | * Copyright (c) 2003 The OpenSSL Project. All rights reserved. | ||
3 | * | ||
4 | * Redistribution and use in source and binary forms, with or without | ||
5 | * modification, are permitted provided that the following conditions | ||
6 | * are met: | ||
7 | * | ||
8 | * 1. Redistributions of source code must retain the above copyright | ||
9 | * notice, this list of conditions and the following disclaimer. | ||
10 | * | ||
11 | * 2. Redistributions in binary form must reproduce the above copyright | ||
12 | * notice, this list of conditions and the following disclaimer in | ||
13 | * the documentation and/or other materials provided with the | ||
14 | * distribution. | ||
15 | * | ||
16 | * 3. All advertising materials mentioning features or use of this | ||
17 | * software must display the following acknowledgment: | ||
18 | * "This product includes software developed by the OpenSSL Project | ||
19 | * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" | ||
20 | * | ||
21 | * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to | ||
22 | * endorse or promote products derived from this software without | ||
23 | * prior written permission. For written permission, please contact | ||
24 | * licensing@OpenSSL.org. | ||
25 | * | ||
26 | * 5. Products derived from this software may not be called "OpenSSL" | ||
27 | * nor may "OpenSSL" appear in their names without prior written | ||
28 | * permission of the OpenSSL Project. | ||
29 | * | ||
30 | * 6. Redistributions of any form whatsoever must retain the following | ||
31 | * acknowledgment: | ||
32 | * "This product includes software developed by the OpenSSL Project | ||
33 | * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" | ||
34 | * | ||
35 | * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY | ||
36 | * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
37 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | ||
38 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR | ||
39 | * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
40 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
41 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
42 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
43 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
44 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
45 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED | ||
46 | * OF THE POSSIBILITY OF SUCH DAMAGE. | ||
47 | * ==================================================================== | ||
48 | * | ||
49 | * This product includes cryptographic software written by Eric Young | ||
50 | * (eay@cryptsoft.com). This product includes software written by Tim | ||
51 | * Hudson (tjh@cryptsoft.com). | ||
52 | * | ||
53 | */ | ||
54 | |||
55 | #include "eng_int.h" | ||
56 | |||
57 | /* If this symbol is defined then ENGINE_get_default_STORE(), the function that is | ||
58 | * used by STORE to hook in implementation code and cache defaults (etc), will | ||
59 | * display brief debugging summaries to stderr with the 'nid'. */ | ||
60 | /* #define ENGINE_STORE_DEBUG */ | ||
61 | |||
62 | static ENGINE_TABLE *store_table = NULL; | ||
63 | static const int dummy_nid = 1; | ||
64 | |||
65 | void ENGINE_unregister_STORE(ENGINE *e) | ||
66 | { | ||
67 | engine_table_unregister(&store_table, e); | ||
68 | } | ||
69 | |||
70 | static void engine_unregister_all_STORE(void) | ||
71 | { | ||
72 | engine_table_cleanup(&store_table); | ||
73 | } | ||
74 | |||
75 | int ENGINE_register_STORE(ENGINE *e) | ||
76 | { | ||
77 | if(e->store_meth) | ||
78 | return engine_table_register(&store_table, | ||
79 | engine_unregister_all_STORE, e, &dummy_nid, 1, 0); | ||
80 | return 1; | ||
81 | } | ||
82 | |||
83 | void ENGINE_register_all_STORE() | ||
84 | { | ||
85 | ENGINE *e; | ||
86 | |||
87 | for(e=ENGINE_get_first() ; e ; e=ENGINE_get_next(e)) | ||
88 | ENGINE_register_STORE(e); | ||
89 | } | ||
90 | |||
91 | /* The following two functions are removed because they're useless. */ | ||
92 | #if 0 | ||
93 | int ENGINE_set_default_STORE(ENGINE *e) | ||
94 | { | ||
95 | if(e->store_meth) | ||
96 | return engine_table_register(&store_table, | ||
97 | engine_unregister_all_STORE, e, &dummy_nid, 1, 1); | ||
98 | return 1; | ||
99 | } | ||
100 | #endif | ||
101 | |||
102 | #if 0 | ||
103 | /* Exposed API function to get a functional reference from the implementation | ||
104 | * table (ie. try to get a functional reference from the tabled structural | ||
105 | * references). */ | ||
106 | ENGINE *ENGINE_get_default_STORE(void) | ||
107 | { | ||
108 | return engine_table_select(&store_table, dummy_nid); | ||
109 | } | ||
110 | #endif | ||
111 | |||
112 | /* Obtains an STORE implementation from an ENGINE functional reference */ | ||
113 | const STORE_METHOD *ENGINE_get_STORE(const ENGINE *e) | ||
114 | { | ||
115 | return e->store_meth; | ||
116 | } | ||
117 | |||
118 | /* Sets an STORE implementation in an ENGINE structure */ | ||
119 | int ENGINE_set_STORE(ENGINE *e, const STORE_METHOD *store_meth) | ||
120 | { | ||
121 | e->store_meth = store_meth; | ||
122 | return 1; | ||
123 | } | ||
diff --git a/src/lib/libcrypto/evp/e_camellia.c b/src/lib/libcrypto/evp/e_camellia.c new file mode 100644 index 0000000000..a7b40d1c60 --- /dev/null +++ b/src/lib/libcrypto/evp/e_camellia.c | |||
@@ -0,0 +1,131 @@ | |||
1 | /* crypto/evp/e_camellia.c -*- mode:C; c-file-style: "eay" -*- */ | ||
2 | /* ==================================================================== | ||
3 | * Copyright (c) 2006 The OpenSSL Project. All rights reserved. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions | ||
7 | * are met: | ||
8 | * | ||
9 | * 1. Redistributions of source code must retain the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer. | ||
11 | * | ||
12 | * 2. Redistributions in binary form must reproduce the above copyright | ||
13 | * notice, this list of conditions and the following disclaimer in | ||
14 | * the documentation and/or other materials provided with the | ||
15 | * distribution. | ||
16 | * | ||
17 | * 3. All advertising materials mentioning features or use of this | ||
18 | * software must display the following acknowledgment: | ||
19 | * "This product includes software developed by the OpenSSL Project | ||
20 | * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" | ||
21 | * | ||
22 | * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to | ||
23 | * endorse or promote products derived from this software without | ||
24 | * prior written permission. For written permission, please contact | ||
25 | * openssl-core@openssl.org. | ||
26 | * | ||
27 | * 5. Products derived from this software may not be called "OpenSSL" | ||
28 | * nor may "OpenSSL" appear in their names without prior written | ||
29 | * permission of the OpenSSL Project. | ||
30 | * | ||
31 | * 6. Redistributions of any form whatsoever must retain the following | ||
32 | * acknowledgment: | ||
33 | * "This product includes software developed by the OpenSSL Project | ||
34 | * for use in the OpenSSL Toolkit (http://www.openssl.org/)" | ||
35 | * | ||
36 | * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY | ||
37 | * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
38 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | ||
39 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR | ||
40 | * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
41 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
42 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
43 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
44 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
45 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
46 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED | ||
47 | * OF THE POSSIBILITY OF SUCH DAMAGE. | ||
48 | * ==================================================================== | ||
49 | * | ||
50 | * This product includes cryptographic software written by Eric Young | ||
51 | * (eay@cryptsoft.com). This product includes software written by Tim | ||
52 | * Hudson (tjh@cryptsoft.com). | ||
53 | * | ||
54 | */ | ||
55 | |||
56 | #include <openssl/opensslconf.h> | ||
57 | #ifndef OPENSSL_NO_CAMELLIA | ||
58 | #include <openssl/evp.h> | ||
59 | #include <openssl/err.h> | ||
60 | #include <string.h> | ||
61 | #include <assert.h> | ||
62 | #include <openssl/camellia.h> | ||
63 | #include "evp_locl.h" | ||
64 | |||
65 | static int camellia_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, | ||
66 | const unsigned char *iv, int enc); | ||
67 | |||
68 | /* Camellia subkey Structure */ | ||
69 | typedef struct | ||
70 | { | ||
71 | CAMELLIA_KEY ks; | ||
72 | } EVP_CAMELLIA_KEY; | ||
73 | |||
74 | /* Attribute operation for Camellia */ | ||
75 | #define data(ctx) EVP_C_DATA(EVP_CAMELLIA_KEY,ctx) | ||
76 | |||
77 | IMPLEMENT_BLOCK_CIPHER(camellia_128, ks, Camellia, EVP_CAMELLIA_KEY, | ||
78 | NID_camellia_128, 16, 16, 16, 128, | ||
79 | 0, camellia_init_key, NULL, | ||
80 | EVP_CIPHER_set_asn1_iv, | ||
81 | EVP_CIPHER_get_asn1_iv, | ||
82 | NULL) | ||
83 | IMPLEMENT_BLOCK_CIPHER(camellia_192, ks, Camellia, EVP_CAMELLIA_KEY, | ||
84 | NID_camellia_192, 16, 24, 16, 128, | ||
85 | 0, camellia_init_key, NULL, | ||
86 | EVP_CIPHER_set_asn1_iv, | ||
87 | EVP_CIPHER_get_asn1_iv, | ||
88 | NULL) | ||
89 | IMPLEMENT_BLOCK_CIPHER(camellia_256, ks, Camellia, EVP_CAMELLIA_KEY, | ||
90 | NID_camellia_256, 16, 32, 16, 128, | ||
91 | 0, camellia_init_key, NULL, | ||
92 | EVP_CIPHER_set_asn1_iv, | ||
93 | EVP_CIPHER_get_asn1_iv, | ||
94 | NULL) | ||
95 | |||
96 | #define IMPLEMENT_CAMELLIA_CFBR(ksize,cbits) IMPLEMENT_CFBR(camellia,Camellia,EVP_CAMELLIA_KEY,ks,ksize,cbits,16) | ||
97 | |||
98 | IMPLEMENT_CAMELLIA_CFBR(128,1) | ||
99 | IMPLEMENT_CAMELLIA_CFBR(192,1) | ||
100 | IMPLEMENT_CAMELLIA_CFBR(256,1) | ||
101 | |||
102 | IMPLEMENT_CAMELLIA_CFBR(128,8) | ||
103 | IMPLEMENT_CAMELLIA_CFBR(192,8) | ||
104 | IMPLEMENT_CAMELLIA_CFBR(256,8) | ||
105 | |||
106 | |||
107 | |||
108 | /* The subkey for Camellia is generated. */ | ||
109 | static int camellia_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, | ||
110 | const unsigned char *iv, int enc) | ||
111 | { | ||
112 | int ret; | ||
113 | |||
114 | ret=Camellia_set_key(key, ctx->key_len * 8, ctx->cipher_data); | ||
115 | |||
116 | if(ret < 0) | ||
117 | { | ||
118 | EVPerr(EVP_F_CAMELLIA_INIT_KEY,EVP_R_CAMELLIA_KEY_SETUP_FAILED); | ||
119 | return 0; | ||
120 | } | ||
121 | |||
122 | return 1; | ||
123 | } | ||
124 | |||
125 | #else | ||
126 | |||
127 | # ifdef PEDANTIC | ||
128 | static void *dummy=&dummy; | ||
129 | # endif | ||
130 | |||
131 | #endif | ||
diff --git a/src/lib/libcrypto/evp/e_old.c b/src/lib/libcrypto/evp/e_old.c index 92dc498945..1642af4869 100644 --- a/src/lib/libcrypto/evp/e_old.c +++ b/src/lib/libcrypto/evp/e_old.c | |||
@@ -56,6 +56,10 @@ | |||
56 | * | 56 | * |
57 | */ | 57 | */ |
58 | 58 | ||
59 | #ifdef OPENSSL_NO_DEPRECATED | ||
60 | static void *dummy = &dummy; | ||
61 | #else | ||
62 | |||
59 | #include <openssl/evp.h> | 63 | #include <openssl/evp.h> |
60 | 64 | ||
61 | /* Define some deprecated functions, so older programs | 65 | /* Define some deprecated functions, so older programs |
@@ -66,43 +70,56 @@ | |||
66 | 70 | ||
67 | #ifndef OPENSSL_NO_BF | 71 | #ifndef OPENSSL_NO_BF |
68 | #undef EVP_bf_cfb | 72 | #undef EVP_bf_cfb |
73 | const EVP_CIPHER *EVP_bf_cfb(void); | ||
69 | const EVP_CIPHER *EVP_bf_cfb(void) { return EVP_bf_cfb64(); } | 74 | const EVP_CIPHER *EVP_bf_cfb(void) { return EVP_bf_cfb64(); } |
70 | #endif | 75 | #endif |
71 | 76 | ||
72 | #ifndef OPENSSL_NO_DES | 77 | #ifndef OPENSSL_NO_DES |
73 | #undef EVP_des_cfb | 78 | #undef EVP_des_cfb |
79 | const EVP_CIPHER *EVP_des_cfb(void); | ||
74 | const EVP_CIPHER *EVP_des_cfb(void) { return EVP_des_cfb64(); } | 80 | const EVP_CIPHER *EVP_des_cfb(void) { return EVP_des_cfb64(); } |
75 | #undef EVP_des_ede3_cfb | 81 | #undef EVP_des_ede3_cfb |
82 | const EVP_CIPHER *EVP_des_ede3_cfb(void); | ||
76 | const EVP_CIPHER *EVP_des_ede3_cfb(void) { return EVP_des_ede3_cfb64(); } | 83 | const EVP_CIPHER *EVP_des_ede3_cfb(void) { return EVP_des_ede3_cfb64(); } |
77 | #undef EVP_des_ede_cfb | 84 | #undef EVP_des_ede_cfb |
85 | const EVP_CIPHER *EVP_des_ede_cfb(void); | ||
78 | const EVP_CIPHER *EVP_des_ede_cfb(void) { return EVP_des_ede_cfb64(); } | 86 | const EVP_CIPHER *EVP_des_ede_cfb(void) { return EVP_des_ede_cfb64(); } |
79 | #endif | 87 | #endif |
80 | 88 | ||
81 | #ifndef OPENSSL_NO_IDEA | 89 | #ifndef OPENSSL_NO_IDEA |
82 | #undef EVP_idea_cfb | 90 | #undef EVP_idea_cfb |
91 | const EVP_CIPHER *EVP_idea_cfb(void); | ||
83 | const EVP_CIPHER *EVP_idea_cfb(void) { return EVP_idea_cfb64(); } | 92 | const EVP_CIPHER *EVP_idea_cfb(void) { return EVP_idea_cfb64(); } |
84 | #endif | 93 | #endif |
85 | 94 | ||
86 | #ifndef OPENSSL_NO_RC2 | 95 | #ifndef OPENSSL_NO_RC2 |
87 | #undef EVP_rc2_cfb | 96 | #undef EVP_rc2_cfb |
97 | const EVP_CIPHER *EVP_rc2_cfb(void); | ||
88 | const EVP_CIPHER *EVP_rc2_cfb(void) { return EVP_rc2_cfb64(); } | 98 | const EVP_CIPHER *EVP_rc2_cfb(void) { return EVP_rc2_cfb64(); } |
89 | #endif | 99 | #endif |
90 | 100 | ||
91 | #ifndef OPENSSL_NO_CAST | 101 | #ifndef OPENSSL_NO_CAST |
92 | #undef EVP_cast5_cfb | 102 | #undef EVP_cast5_cfb |
103 | const EVP_CIPHER *EVP_cast5_cfb(void); | ||
93 | const EVP_CIPHER *EVP_cast5_cfb(void) { return EVP_cast5_cfb64(); } | 104 | const EVP_CIPHER *EVP_cast5_cfb(void) { return EVP_cast5_cfb64(); } |
94 | #endif | 105 | #endif |
95 | 106 | ||
96 | #ifndef OPENSSL_NO_RC5 | 107 | #ifndef OPENSSL_NO_RC5 |
97 | #undef EVP_rc5_32_12_16_cfb | 108 | #undef EVP_rc5_32_12_16_cfb |
109 | const EVP_CIPHER *EVP_rc5_32_12_16_cfb(void); | ||
98 | const EVP_CIPHER *EVP_rc5_32_12_16_cfb(void) { return EVP_rc5_32_12_16_cfb64(); } | 110 | const EVP_CIPHER *EVP_rc5_32_12_16_cfb(void) { return EVP_rc5_32_12_16_cfb64(); } |
99 | #endif | 111 | #endif |
100 | 112 | ||
101 | #ifndef OPENSSL_NO_AES | 113 | #ifndef OPENSSL_NO_AES |
102 | #undef EVP_aes_128_cfb | 114 | #undef EVP_aes_128_cfb |
115 | const EVP_CIPHER *EVP_aes_128_cfb(void); | ||
103 | const EVP_CIPHER *EVP_aes_128_cfb(void) { return EVP_aes_128_cfb128(); } | 116 | const EVP_CIPHER *EVP_aes_128_cfb(void) { return EVP_aes_128_cfb128(); } |
104 | #undef EVP_aes_192_cfb | 117 | #undef EVP_aes_192_cfb |
118 | const EVP_CIPHER *EVP_aes_192_cfb(void); | ||
105 | const EVP_CIPHER *EVP_aes_192_cfb(void) { return EVP_aes_192_cfb128(); } | 119 | const EVP_CIPHER *EVP_aes_192_cfb(void) { return EVP_aes_192_cfb128(); } |
106 | #undef EVP_aes_256_cfb | 120 | #undef EVP_aes_256_cfb |
121 | const EVP_CIPHER *EVP_aes_256_cfb(void); | ||
107 | const EVP_CIPHER *EVP_aes_256_cfb(void) { return EVP_aes_256_cfb128(); } | 122 | const EVP_CIPHER *EVP_aes_256_cfb(void) { return EVP_aes_256_cfb128(); } |
108 | #endif | 123 | #endif |
124 | |||
125 | #endif | ||
diff --git a/src/lib/libcrypto/evp/m_ecdsa.c b/src/lib/libcrypto/evp/m_ecdsa.c new file mode 100644 index 0000000000..fad270faca --- /dev/null +++ b/src/lib/libcrypto/evp/m_ecdsa.c | |||
@@ -0,0 +1,148 @@ | |||
1 | /* crypto/evp/m_ecdsa.c */ | ||
2 | /* ==================================================================== | ||
3 | * Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions | ||
7 | * are met: | ||
8 | * | ||
9 | * 1. Redistributions of source code must retain the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer. | ||
11 | * | ||
12 | * 2. Redistributions in binary form must reproduce the above copyright | ||
13 | * notice, this list of conditions and the following disclaimer in | ||
14 | * the documentation and/or other materials provided with the | ||
15 | * distribution. | ||
16 | * | ||
17 | * 3. All advertising materials mentioning features or use of this | ||
18 | * software must display the following acknowledgment: | ||
19 | * "This product includes software developed by the OpenSSL Project | ||
20 | * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" | ||
21 | * | ||
22 | * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to | ||
23 | * endorse or promote products derived from this software without | ||
24 | * prior written permission. For written permission, please contact | ||
25 | * openssl-core@openssl.org. | ||
26 | * | ||
27 | * 5. Products derived from this software may not be called "OpenSSL" | ||
28 | * nor may "OpenSSL" appear in their names without prior written | ||
29 | * permission of the OpenSSL Project. | ||
30 | * | ||
31 | * 6. Redistributions of any form whatsoever must retain the following | ||
32 | * acknowledgment: | ||
33 | * "This product includes software developed by the OpenSSL Project | ||
34 | * for use in the OpenSSL Toolkit (http://www.openssl.org/)" | ||
35 | * | ||
36 | * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY | ||
37 | * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
38 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | ||
39 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR | ||
40 | * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
41 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
42 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
43 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
44 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
45 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
46 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED | ||
47 | * OF THE POSSIBILITY OF SUCH DAMAGE. | ||
48 | * ==================================================================== | ||
49 | * | ||
50 | * This product includes cryptographic software written by Eric Young | ||
51 | * (eay@cryptsoft.com). This product includes software written by Tim | ||
52 | * Hudson (tjh@cryptsoft.com). | ||
53 | * | ||
54 | */ | ||
55 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) | ||
56 | * All rights reserved. | ||
57 | * | ||
58 | * This package is an SSL implementation written | ||
59 | * by Eric Young (eay@cryptsoft.com). | ||
60 | * The implementation was written so as to conform with Netscapes SSL. | ||
61 | * | ||
62 | * This library is free for commercial and non-commercial use as long as | ||
63 | * the following conditions are aheared to. The following conditions | ||
64 | * apply to all code found in this distribution, be it the RC4, RSA, | ||
65 | * lhash, DES, etc., code; not just the SSL code. The SSL documentation | ||
66 | * included with this distribution is covered by the same copyright terms | ||
67 | * except that the holder is Tim Hudson (tjh@cryptsoft.com). | ||
68 | * | ||
69 | * Copyright remains Eric Young's, and as such any Copyright notices in | ||
70 | * the code are not to be removed. | ||
71 | * If this package is used in a product, Eric Young should be given attribution | ||
72 | * as the author of the parts of the library used. | ||
73 | * This can be in the form of a textual message at program startup or | ||
74 | * in documentation (online or textual) provided with the package. | ||
75 | * | ||
76 | * Redistribution and use in source and binary forms, with or without | ||
77 | * modification, are permitted provided that the following conditions | ||
78 | * are met: | ||
79 | * 1. Redistributions of source code must retain the copyright | ||
80 | * notice, this list of conditions and the following disclaimer. | ||
81 | * 2. Redistributions in binary form must reproduce the above copyright | ||
82 | * notice, this list of conditions and the following disclaimer in the | ||
83 | * documentation and/or other materials provided with the distribution. | ||
84 | * 3. All advertising materials mentioning features or use of this software | ||
85 | * must display the following acknowledgement: | ||
86 | * "This product includes cryptographic software written by | ||
87 | * Eric Young (eay@cryptsoft.com)" | ||
88 | * The word 'cryptographic' can be left out if the rouines from the library | ||
89 | * being used are not cryptographic related :-). | ||
90 | * 4. If you include any Windows specific code (or a derivative thereof) from | ||
91 | * the apps directory (application code) you must include an acknowledgement: | ||
92 | * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" | ||
93 | * | ||
94 | * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND | ||
95 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
96 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
97 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | ||
98 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
99 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
100 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
101 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
102 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
103 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
104 | * SUCH DAMAGE. | ||
105 | * | ||
106 | * The licence and distribution terms for any publically available version or | ||
107 | * derivative of this code cannot be changed. i.e. this code cannot simply be | ||
108 | * copied and put under another distribution licence | ||
109 | * [including the GNU Public Licence.] | ||
110 | */ | ||
111 | |||
112 | #include <stdio.h> | ||
113 | #include "cryptlib.h" | ||
114 | #include <openssl/evp.h> | ||
115 | #include <openssl/objects.h> | ||
116 | #include <openssl/x509.h> | ||
117 | |||
118 | #ifndef OPENSSL_NO_SHA | ||
119 | static int init(EVP_MD_CTX *ctx) | ||
120 | { return SHA1_Init(ctx->md_data); } | ||
121 | |||
122 | static int update(EVP_MD_CTX *ctx,const void *data,size_t count) | ||
123 | { return SHA1_Update(ctx->md_data,data,count); } | ||
124 | |||
125 | static int final(EVP_MD_CTX *ctx,unsigned char *md) | ||
126 | { return SHA1_Final(md,ctx->md_data); } | ||
127 | |||
128 | static const EVP_MD ecdsa_md= | ||
129 | { | ||
130 | NID_ecdsa_with_SHA1, | ||
131 | NID_ecdsa_with_SHA1, | ||
132 | SHA_DIGEST_LENGTH, | ||
133 | 0, | ||
134 | init, | ||
135 | update, | ||
136 | final, | ||
137 | NULL, | ||
138 | NULL, | ||
139 | EVP_PKEY_ECDSA_method, | ||
140 | SHA_CBLOCK, | ||
141 | sizeof(EVP_MD *)+sizeof(SHA_CTX), | ||
142 | }; | ||
143 | |||
144 | const EVP_MD *EVP_ecdsa(void) | ||
145 | { | ||
146 | return(&ecdsa_md); | ||
147 | } | ||
148 | #endif | ||
diff --git a/src/lib/libcrypto/ia64cpuid.S b/src/lib/libcrypto/ia64cpuid.S new file mode 100644 index 0000000000..04fbb3439e --- /dev/null +++ b/src/lib/libcrypto/ia64cpuid.S | |||
@@ -0,0 +1,121 @@ | |||
1 | // Works on all IA-64 platforms: Linux, HP-UX, Win64i... | ||
2 | // On Win64i compile with ias.exe. | ||
3 | .text | ||
4 | .global OPENSSL_rdtsc# | ||
5 | .proc OPENSSL_rdtsc# | ||
6 | OPENSSL_rdtsc: | ||
7 | { .mib; mov r8=ar.itc | ||
8 | br.ret.sptk.many b0 };; | ||
9 | .endp OPENSSL_rdtsc# | ||
10 | |||
11 | .global OPENSSL_atomic_add# | ||
12 | .proc OPENSSL_atomic_add# | ||
13 | .align 32 | ||
14 | OPENSSL_atomic_add: | ||
15 | { .mii; ld4 r2=[r32] | ||
16 | nop.i 0 | ||
17 | nop.i 0 };; | ||
18 | .Lspin: | ||
19 | { .mii; mov ar.ccv=r2 | ||
20 | add r8=r2,r33 | ||
21 | mov r3=r2 };; | ||
22 | { .mmi; mf | ||
23 | cmpxchg4.acq r2=[r32],r8,ar.ccv | ||
24 | nop.i 0 };; | ||
25 | { .mib; cmp.ne p6,p0=r2,r3 | ||
26 | nop.i 0 | ||
27 | (p6) br.dpnt .Lspin };; | ||
28 | { .mib; nop.m 0 | ||
29 | sxt4 r8=r8 | ||
30 | br.ret.sptk.many b0 };; | ||
31 | .endp OPENSSL_atomic_add# | ||
32 | |||
33 | // Returns a structure comprising pointer to the top of stack of | ||
34 | // the caller and pointer beyond backing storage for the current | ||
35 | // register frame. The latter is required, because it might be | ||
36 | // insufficient to wipe backing storage for the current frame | ||
37 | // (as this procedure does), one might have to go further, toward | ||
38 | // higher addresses to reach for whole "retroactively" saved | ||
39 | // context... | ||
40 | .global OPENSSL_wipe_cpu# | ||
41 | .proc OPENSSL_wipe_cpu# | ||
42 | .align 32 | ||
43 | OPENSSL_wipe_cpu: | ||
44 | .prologue | ||
45 | .fframe 0 | ||
46 | .save ar.pfs,r2 | ||
47 | .save ar.lc,r3 | ||
48 | { .mib; alloc r2=ar.pfs,0,96,0,96 | ||
49 | mov r3=ar.lc | ||
50 | brp.loop.imp .L_wipe_top,.L_wipe_end-16 | ||
51 | };; | ||
52 | { .mii; mov r9=ar.bsp | ||
53 | mov r8=pr | ||
54 | mov ar.lc=96 };; | ||
55 | .body | ||
56 | { .mii; add r9=96*8-8,r9 | ||
57 | mov ar.ec=1 };; | ||
58 | |||
59 | // One can sweep double as fast, but then we can't quarantee | ||
60 | // that backing storage is wiped... | ||
61 | .L_wipe_top: | ||
62 | { .mfi; st8 [r9]=r0,-8 | ||
63 | mov f127=f0 | ||
64 | mov r127=r0 } | ||
65 | { .mfb; nop.m 0 | ||
66 | nop.f 0 | ||
67 | br.ctop.sptk .L_wipe_top };; | ||
68 | .L_wipe_end: | ||
69 | |||
70 | { .mfi; mov r11=r0 | ||
71 | mov f6=f0 | ||
72 | mov r14=r0 } | ||
73 | { .mfi; mov r15=r0 | ||
74 | mov f7=f0 | ||
75 | mov r16=r0 } | ||
76 | { .mfi; mov r17=r0 | ||
77 | mov f8=f0 | ||
78 | mov r18=r0 } | ||
79 | { .mfi; mov r19=r0 | ||
80 | mov f9=f0 | ||
81 | mov r20=r0 } | ||
82 | { .mfi; mov r21=r0 | ||
83 | mov f10=f0 | ||
84 | mov r22=r0 } | ||
85 | { .mfi; mov r23=r0 | ||
86 | mov f11=f0 | ||
87 | mov r24=r0 } | ||
88 | { .mfi; mov r25=r0 | ||
89 | mov f12=f0 | ||
90 | mov r26=r0 } | ||
91 | { .mfi; mov r27=r0 | ||
92 | mov f13=f0 | ||
93 | mov r28=r0 } | ||
94 | { .mfi; mov r29=r0 | ||
95 | mov f14=f0 | ||
96 | mov r30=r0 } | ||
97 | { .mfi; mov r31=r0 | ||
98 | mov f15=f0 | ||
99 | nop.i 0 } | ||
100 | { .mfi; mov f16=f0 } | ||
101 | { .mfi; mov f17=f0 } | ||
102 | { .mfi; mov f18=f0 } | ||
103 | { .mfi; mov f19=f0 } | ||
104 | { .mfi; mov f20=f0 } | ||
105 | { .mfi; mov f21=f0 } | ||
106 | { .mfi; mov f22=f0 } | ||
107 | { .mfi; mov f23=f0 } | ||
108 | { .mfi; mov f24=f0 } | ||
109 | { .mfi; mov f25=f0 } | ||
110 | { .mfi; mov f26=f0 } | ||
111 | { .mfi; mov f27=f0 } | ||
112 | { .mfi; mov f28=f0 } | ||
113 | { .mfi; mov f29=f0 } | ||
114 | { .mfi; mov f30=f0 } | ||
115 | { .mfi; add r9=96*8+8,r9 | ||
116 | mov f31=f0 | ||
117 | mov pr=r8,0x1ffff } | ||
118 | { .mib; mov r8=sp | ||
119 | mov ar.lc=r3 | ||
120 | br.ret.sptk b0 };; | ||
121 | .endp OPENSSL_wipe_cpu# | ||
diff --git a/src/lib/libcrypto/md5/asm/md5-x86_64.pl b/src/lib/libcrypto/md5/asm/md5-x86_64.pl new file mode 100755 index 0000000000..9a6fa67224 --- /dev/null +++ b/src/lib/libcrypto/md5/asm/md5-x86_64.pl | |||
@@ -0,0 +1,245 @@ | |||
1 | #!/usr/bin/perl -w | ||
2 | # | ||
3 | # MD5 optimized for AMD64. | ||
4 | # | ||
5 | # Author: Marc Bevand <bevand_m (at) epita.fr> | ||
6 | # Licence: I hereby disclaim the copyright on this code and place it | ||
7 | # in the public domain. | ||
8 | # | ||
9 | |||
10 | use strict; | ||
11 | |||
12 | my $code; | ||
13 | |||
14 | # round1_step() does: | ||
15 | # dst = x + ((dst + F(x,y,z) + X[k] + T_i) <<< s) | ||
16 | # %r10d = X[k_next] | ||
17 | # %r11d = z' (copy of z for the next step) | ||
18 | # Each round1_step() takes about 5.71 clocks (9 instructions, 1.58 IPC) | ||
19 | sub round1_step | ||
20 | { | ||
21 | my ($pos, $dst, $x, $y, $z, $k_next, $T_i, $s) = @_; | ||
22 | $code .= " mov 0*4(%rsi), %r10d /* (NEXT STEP) X[0] */\n" if ($pos == -1); | ||
23 | $code .= " mov %edx, %r11d /* (NEXT STEP) z' = %edx */\n" if ($pos == -1); | ||
24 | $code .= <<EOF; | ||
25 | xor $y, %r11d /* y ^ ... */ | ||
26 | lea $T_i($dst,%r10d),$dst /* Const + dst + ... */ | ||
27 | and $x, %r11d /* x & ... */ | ||
28 | xor $z, %r11d /* z ^ ... */ | ||
29 | mov $k_next*4(%rsi),%r10d /* (NEXT STEP) X[$k_next] */ | ||
30 | add %r11d, $dst /* dst += ... */ | ||
31 | rol \$$s, $dst /* dst <<< s */ | ||
32 | mov $y, %r11d /* (NEXT STEP) z' = $y */ | ||
33 | add $x, $dst /* dst += x */ | ||
34 | EOF | ||
35 | } | ||
36 | |||
37 | # round2_step() does: | ||
38 | # dst = x + ((dst + G(x,y,z) + X[k] + T_i) <<< s) | ||
39 | # %r10d = X[k_next] | ||
40 | # %r11d = y' (copy of y for the next step) | ||
41 | # Each round2_step() takes about 6.22 clocks (9 instructions, 1.45 IPC) | ||
42 | sub round2_step | ||
43 | { | ||
44 | my ($pos, $dst, $x, $y, $z, $k_next, $T_i, $s) = @_; | ||
45 | $code .= " mov 1*4(%rsi), %r10d /* (NEXT STEP) X[1] */\n" if ($pos == -1); | ||
46 | $code .= " mov %ecx, %r11d /* (NEXT STEP) y' = %ecx */\n" if ($pos == -1); | ||
47 | $code .= <<EOF; | ||
48 | xor $x, %r11d /* x ^ ... */ | ||
49 | lea $T_i($dst,%r10d),$dst /* Const + dst + ... */ | ||
50 | and $z, %r11d /* z & ... */ | ||
51 | xor $y, %r11d /* y ^ ... */ | ||
52 | mov $k_next*4(%rsi),%r10d /* (NEXT STEP) X[$k_next] */ | ||
53 | add %r11d, $dst /* dst += ... */ | ||
54 | rol \$$s, $dst /* dst <<< s */ | ||
55 | mov $x, %r11d /* (NEXT STEP) y' = $x */ | ||
56 | add $x, $dst /* dst += x */ | ||
57 | EOF | ||
58 | } | ||
59 | |||
60 | # round3_step() does: | ||
61 | # dst = x + ((dst + H(x,y,z) + X[k] + T_i) <<< s) | ||
62 | # %r10d = X[k_next] | ||
63 | # %r11d = y' (copy of y for the next step) | ||
64 | # Each round3_step() takes about 4.26 clocks (8 instructions, 1.88 IPC) | ||
65 | sub round3_step | ||
66 | { | ||
67 | my ($pos, $dst, $x, $y, $z, $k_next, $T_i, $s) = @_; | ||
68 | $code .= " mov 5*4(%rsi), %r10d /* (NEXT STEP) X[5] */\n" if ($pos == -1); | ||
69 | $code .= " mov %ecx, %r11d /* (NEXT STEP) y' = %ecx */\n" if ($pos == -1); | ||
70 | $code .= <<EOF; | ||
71 | lea $T_i($dst,%r10d),$dst /* Const + dst + ... */ | ||
72 | mov $k_next*4(%rsi),%r10d /* (NEXT STEP) X[$k_next] */ | ||
73 | xor $z, %r11d /* z ^ ... */ | ||
74 | xor $x, %r11d /* x ^ ... */ | ||
75 | add %r11d, $dst /* dst += ... */ | ||
76 | rol \$$s, $dst /* dst <<< s */ | ||
77 | mov $x, %r11d /* (NEXT STEP) y' = $x */ | ||
78 | add $x, $dst /* dst += x */ | ||
79 | EOF | ||
80 | } | ||
81 | |||
82 | # round4_step() does: | ||
83 | # dst = x + ((dst + I(x,y,z) + X[k] + T_i) <<< s) | ||
84 | # %r10d = X[k_next] | ||
85 | # %r11d = not z' (copy of not z for the next step) | ||
86 | # Each round4_step() takes about 5.27 clocks (9 instructions, 1.71 IPC) | ||
87 | sub round4_step | ||
88 | { | ||
89 | my ($pos, $dst, $x, $y, $z, $k_next, $T_i, $s) = @_; | ||
90 | $code .= " mov 0*4(%rsi), %r10d /* (NEXT STEP) X[0] */\n" if ($pos == -1); | ||
91 | $code .= " mov \$0xffffffff, %r11d\n" if ($pos == -1); | ||
92 | $code .= " xor %edx, %r11d /* (NEXT STEP) not z' = not %edx*/\n" | ||
93 | if ($pos == -1); | ||
94 | $code .= <<EOF; | ||
95 | lea $T_i($dst,%r10d),$dst /* Const + dst + ... */ | ||
96 | or $x, %r11d /* x | ... */ | ||
97 | xor $y, %r11d /* y ^ ... */ | ||
98 | add %r11d, $dst /* dst += ... */ | ||
99 | mov $k_next*4(%rsi),%r10d /* (NEXT STEP) X[$k_next] */ | ||
100 | mov \$0xffffffff, %r11d | ||
101 | rol \$$s, $dst /* dst <<< s */ | ||
102 | xor $y, %r11d /* (NEXT STEP) not z' = not $y */ | ||
103 | add $x, $dst /* dst += x */ | ||
104 | EOF | ||
105 | } | ||
106 | |||
107 | my $output = shift; | ||
108 | open STDOUT,"| $^X ../perlasm/x86_64-xlate.pl $output"; | ||
109 | |||
110 | $code .= <<EOF; | ||
111 | .text | ||
112 | .align 16 | ||
113 | |||
114 | .globl md5_block_asm_data_order | ||
115 | .type md5_block_asm_data_order,\@function,3 | ||
116 | md5_block_asm_data_order: | ||
117 | push %rbp | ||
118 | push %rbx | ||
119 | push %r14 | ||
120 | push %r15 | ||
121 | |||
122 | # rdi = arg #1 (ctx, MD5_CTX pointer) | ||
123 | # rsi = arg #2 (ptr, data pointer) | ||
124 | # rdx = arg #3 (nbr, number of 16-word blocks to process) | ||
125 | mov %rdi, %rbp # rbp = ctx | ||
126 | shl \$6, %rdx # rdx = nbr in bytes | ||
127 | lea (%rsi,%rdx), %rdi # rdi = end | ||
128 | mov 0*4(%rbp), %eax # eax = ctx->A | ||
129 | mov 1*4(%rbp), %ebx # ebx = ctx->B | ||
130 | mov 2*4(%rbp), %ecx # ecx = ctx->C | ||
131 | mov 3*4(%rbp), %edx # edx = ctx->D | ||
132 | # end is 'rdi' | ||
133 | # ptr is 'rsi' | ||
134 | # A is 'eax' | ||
135 | # B is 'ebx' | ||
136 | # C is 'ecx' | ||
137 | # D is 'edx' | ||
138 | |||
139 | cmp %rdi, %rsi # cmp end with ptr | ||
140 | je .Lend # jmp if ptr == end | ||
141 | |||
142 | # BEGIN of loop over 16-word blocks | ||
143 | .Lloop: # save old values of A, B, C, D | ||
144 | mov %eax, %r8d | ||
145 | mov %ebx, %r9d | ||
146 | mov %ecx, %r14d | ||
147 | mov %edx, %r15d | ||
148 | EOF | ||
149 | round1_step(-1,'%eax','%ebx','%ecx','%edx', '1','0xd76aa478', '7'); | ||
150 | round1_step( 0,'%edx','%eax','%ebx','%ecx', '2','0xe8c7b756','12'); | ||
151 | round1_step( 0,'%ecx','%edx','%eax','%ebx', '3','0x242070db','17'); | ||
152 | round1_step( 0,'%ebx','%ecx','%edx','%eax', '4','0xc1bdceee','22'); | ||
153 | round1_step( 0,'%eax','%ebx','%ecx','%edx', '5','0xf57c0faf', '7'); | ||
154 | round1_step( 0,'%edx','%eax','%ebx','%ecx', '6','0x4787c62a','12'); | ||
155 | round1_step( 0,'%ecx','%edx','%eax','%ebx', '7','0xa8304613','17'); | ||
156 | round1_step( 0,'%ebx','%ecx','%edx','%eax', '8','0xfd469501','22'); | ||
157 | round1_step( 0,'%eax','%ebx','%ecx','%edx', '9','0x698098d8', '7'); | ||
158 | round1_step( 0,'%edx','%eax','%ebx','%ecx','10','0x8b44f7af','12'); | ||
159 | round1_step( 0,'%ecx','%edx','%eax','%ebx','11','0xffff5bb1','17'); | ||
160 | round1_step( 0,'%ebx','%ecx','%edx','%eax','12','0x895cd7be','22'); | ||
161 | round1_step( 0,'%eax','%ebx','%ecx','%edx','13','0x6b901122', '7'); | ||
162 | round1_step( 0,'%edx','%eax','%ebx','%ecx','14','0xfd987193','12'); | ||
163 | round1_step( 0,'%ecx','%edx','%eax','%ebx','15','0xa679438e','17'); | ||
164 | round1_step( 1,'%ebx','%ecx','%edx','%eax', '0','0x49b40821','22'); | ||
165 | |||
166 | round2_step(-1,'%eax','%ebx','%ecx','%edx', '6','0xf61e2562', '5'); | ||
167 | round2_step( 0,'%edx','%eax','%ebx','%ecx','11','0xc040b340', '9'); | ||
168 | round2_step( 0,'%ecx','%edx','%eax','%ebx', '0','0x265e5a51','14'); | ||
169 | round2_step( 0,'%ebx','%ecx','%edx','%eax', '5','0xe9b6c7aa','20'); | ||
170 | round2_step( 0,'%eax','%ebx','%ecx','%edx','10','0xd62f105d', '5'); | ||
171 | round2_step( 0,'%edx','%eax','%ebx','%ecx','15', '0x2441453', '9'); | ||
172 | round2_step( 0,'%ecx','%edx','%eax','%ebx', '4','0xd8a1e681','14'); | ||
173 | round2_step( 0,'%ebx','%ecx','%edx','%eax', '9','0xe7d3fbc8','20'); | ||
174 | round2_step( 0,'%eax','%ebx','%ecx','%edx','14','0x21e1cde6', '5'); | ||
175 | round2_step( 0,'%edx','%eax','%ebx','%ecx', '3','0xc33707d6', '9'); | ||
176 | round2_step( 0,'%ecx','%edx','%eax','%ebx', '8','0xf4d50d87','14'); | ||
177 | round2_step( 0,'%ebx','%ecx','%edx','%eax','13','0x455a14ed','20'); | ||
178 | round2_step( 0,'%eax','%ebx','%ecx','%edx', '2','0xa9e3e905', '5'); | ||
179 | round2_step( 0,'%edx','%eax','%ebx','%ecx', '7','0xfcefa3f8', '9'); | ||
180 | round2_step( 0,'%ecx','%edx','%eax','%ebx','12','0x676f02d9','14'); | ||
181 | round2_step( 1,'%ebx','%ecx','%edx','%eax', '0','0x8d2a4c8a','20'); | ||
182 | |||
183 | round3_step(-1,'%eax','%ebx','%ecx','%edx', '8','0xfffa3942', '4'); | ||
184 | round3_step( 0,'%edx','%eax','%ebx','%ecx','11','0x8771f681','11'); | ||
185 | round3_step( 0,'%ecx','%edx','%eax','%ebx','14','0x6d9d6122','16'); | ||
186 | round3_step( 0,'%ebx','%ecx','%edx','%eax', '1','0xfde5380c','23'); | ||
187 | round3_step( 0,'%eax','%ebx','%ecx','%edx', '4','0xa4beea44', '4'); | ||
188 | round3_step( 0,'%edx','%eax','%ebx','%ecx', '7','0x4bdecfa9','11'); | ||
189 | round3_step( 0,'%ecx','%edx','%eax','%ebx','10','0xf6bb4b60','16'); | ||
190 | round3_step( 0,'%ebx','%ecx','%edx','%eax','13','0xbebfbc70','23'); | ||
191 | round3_step( 0,'%eax','%ebx','%ecx','%edx', '0','0x289b7ec6', '4'); | ||
192 | round3_step( 0,'%edx','%eax','%ebx','%ecx', '3','0xeaa127fa','11'); | ||
193 | round3_step( 0,'%ecx','%edx','%eax','%ebx', '6','0xd4ef3085','16'); | ||
194 | round3_step( 0,'%ebx','%ecx','%edx','%eax', '9', '0x4881d05','23'); | ||
195 | round3_step( 0,'%eax','%ebx','%ecx','%edx','12','0xd9d4d039', '4'); | ||
196 | round3_step( 0,'%edx','%eax','%ebx','%ecx','15','0xe6db99e5','11'); | ||
197 | round3_step( 0,'%ecx','%edx','%eax','%ebx', '2','0x1fa27cf8','16'); | ||
198 | round3_step( 1,'%ebx','%ecx','%edx','%eax', '0','0xc4ac5665','23'); | ||
199 | |||
200 | round4_step(-1,'%eax','%ebx','%ecx','%edx', '7','0xf4292244', '6'); | ||
201 | round4_step( 0,'%edx','%eax','%ebx','%ecx','14','0x432aff97','10'); | ||
202 | round4_step( 0,'%ecx','%edx','%eax','%ebx', '5','0xab9423a7','15'); | ||
203 | round4_step( 0,'%ebx','%ecx','%edx','%eax','12','0xfc93a039','21'); | ||
204 | round4_step( 0,'%eax','%ebx','%ecx','%edx', '3','0x655b59c3', '6'); | ||
205 | round4_step( 0,'%edx','%eax','%ebx','%ecx','10','0x8f0ccc92','10'); | ||
206 | round4_step( 0,'%ecx','%edx','%eax','%ebx', '1','0xffeff47d','15'); | ||
207 | round4_step( 0,'%ebx','%ecx','%edx','%eax', '8','0x85845dd1','21'); | ||
208 | round4_step( 0,'%eax','%ebx','%ecx','%edx','15','0x6fa87e4f', '6'); | ||
209 | round4_step( 0,'%edx','%eax','%ebx','%ecx', '6','0xfe2ce6e0','10'); | ||
210 | round4_step( 0,'%ecx','%edx','%eax','%ebx','13','0xa3014314','15'); | ||
211 | round4_step( 0,'%ebx','%ecx','%edx','%eax', '4','0x4e0811a1','21'); | ||
212 | round4_step( 0,'%eax','%ebx','%ecx','%edx','11','0xf7537e82', '6'); | ||
213 | round4_step( 0,'%edx','%eax','%ebx','%ecx', '2','0xbd3af235','10'); | ||
214 | round4_step( 0,'%ecx','%edx','%eax','%ebx', '9','0x2ad7d2bb','15'); | ||
215 | round4_step( 1,'%ebx','%ecx','%edx','%eax', '0','0xeb86d391','21'); | ||
216 | $code .= <<EOF; | ||
217 | # add old values of A, B, C, D | ||
218 | add %r8d, %eax | ||
219 | add %r9d, %ebx | ||
220 | add %r14d, %ecx | ||
221 | add %r15d, %edx | ||
222 | |||
223 | # loop control | ||
224 | add \$64, %rsi # ptr += 64 | ||
225 | cmp %rdi, %rsi # cmp end with ptr | ||
226 | jb .Lloop # jmp if ptr < end | ||
227 | # END of loop over 16-word blocks | ||
228 | |||
229 | .Lend: | ||
230 | mov %eax, 0*4(%rbp) # ctx->A = A | ||
231 | mov %ebx, 1*4(%rbp) # ctx->B = B | ||
232 | mov %ecx, 2*4(%rbp) # ctx->C = C | ||
233 | mov %edx, 3*4(%rbp) # ctx->D = D | ||
234 | |||
235 | pop %r15 | ||
236 | pop %r14 | ||
237 | pop %rbx | ||
238 | pop %rbp | ||
239 | ret | ||
240 | .size md5_block_asm_data_order,.-md5_block_asm_data_order | ||
241 | EOF | ||
242 | |||
243 | print $code; | ||
244 | |||
245 | close STDOUT; | ||
diff --git a/src/lib/libcrypto/mem_clr.c b/src/lib/libcrypto/mem_clr.c index e4b7f540b0..add1f78020 100644 --- a/src/lib/libcrypto/mem_clr.c +++ b/src/lib/libcrypto/mem_clr.c | |||
@@ -64,12 +64,14 @@ unsigned char cleanse_ctr = 0; | |||
64 | void OPENSSL_cleanse(void *ptr, size_t len) | 64 | void OPENSSL_cleanse(void *ptr, size_t len) |
65 | { | 65 | { |
66 | unsigned char *p = ptr; | 66 | unsigned char *p = ptr; |
67 | size_t loop = len; | 67 | size_t loop = len, ctr = cleanse_ctr; |
68 | while(loop--) | 68 | while(loop--) |
69 | { | 69 | { |
70 | *(p++) = cleanse_ctr; | 70 | *(p++) = (unsigned char)ctr; |
71 | cleanse_ctr += (17 + (unsigned char)((int)p & 0xF)); | 71 | ctr += (17 + ((size_t)p & 0xF)); |
72 | } | 72 | } |
73 | if(memchr(ptr, cleanse_ctr, len)) | 73 | p=memchr(ptr, (unsigned char)ctr, len); |
74 | cleanse_ctr += 63; | 74 | if(p) |
75 | ctr += (63 + (size_t)p); | ||
76 | cleanse_ctr = (unsigned char)ctr; | ||
75 | } | 77 | } |
diff --git a/src/lib/libcrypto/o_str.c b/src/lib/libcrypto/o_str.c index da8860491d..59cc25094b 100644 --- a/src/lib/libcrypto/o_str.c +++ b/src/lib/libcrypto/o_str.c | |||
@@ -60,6 +60,10 @@ | |||
60 | #include <e_os.h> | 60 | #include <e_os.h> |
61 | #include "o_str.h" | 61 | #include "o_str.h" |
62 | 62 | ||
63 | #if !defined(OPENSSL_IMPLEMENTS_strncasecmp) && !defined(OPENSSL_SYSNAME_WIN32) | ||
64 | # include <strings.h> | ||
65 | #endif | ||
66 | |||
63 | int OPENSSL_strncasecmp(const char *str1, const char *str2, size_t n) | 67 | int OPENSSL_strncasecmp(const char *str1, const char *str2, size_t n) |
64 | { | 68 | { |
65 | #if defined(OPENSSL_IMPLEMENTS_strncasecmp) | 69 | #if defined(OPENSSL_IMPLEMENTS_strncasecmp) |
@@ -94,3 +98,12 @@ int OPENSSL_strcasecmp(const char *str1, const char *str2) | |||
94 | #endif | 98 | #endif |
95 | } | 99 | } |
96 | 100 | ||
101 | int OPENSSL_memcmp(const void *v1,const void *v2,size_t n) | ||
102 | { | ||
103 | const unsigned char *c1=v1,*c2=v2; | ||
104 | int ret=0; | ||
105 | |||
106 | while(n && (ret=*c1-*c2)==0) n--,c1++,c2++; | ||
107 | |||
108 | return ret; | ||
109 | } | ||
diff --git a/src/lib/libcrypto/perlasm/x86_64-xlate.pl b/src/lib/libcrypto/perlasm/x86_64-xlate.pl new file mode 100755 index 0000000000..a4af769b4a --- /dev/null +++ b/src/lib/libcrypto/perlasm/x86_64-xlate.pl | |||
@@ -0,0 +1,554 @@ | |||
1 | #!/usr/bin/env perl | ||
2 | |||
3 | # Ascetic x86_64 AT&T to MASM assembler translator by <appro>. | ||
4 | # | ||
5 | # Why AT&T to MASM and not vice versa? Several reasons. Because AT&T | ||
6 | # format is way easier to parse. Because it's simpler to "gear" from | ||
7 | # Unix ABI to Windows one [see cross-reference "card" at the end of | ||
8 | # file]. Because Linux targets were available first... | ||
9 | # | ||
10 | # In addition the script also "distills" code suitable for GNU | ||
11 | # assembler, so that it can be compiled with more rigid assemblers, | ||
12 | # such as Solaris /usr/ccs/bin/as. | ||
13 | # | ||
14 | # This translator is not designed to convert *arbitrary* assembler | ||
15 | # code from AT&T format to MASM one. It's designed to convert just | ||
16 | # enough to provide for dual-ABI OpenSSL modules development... | ||
17 | # There *are* limitations and you might have to modify your assembler | ||
18 | # code or this script to achieve the desired result... | ||
19 | # | ||
20 | # Currently recognized limitations: | ||
21 | # | ||
22 | # - can't use multiple ops per line; | ||
23 | # - indirect calls and jumps are not supported; | ||
24 | # | ||
25 | # Dual-ABI styling rules. | ||
26 | # | ||
27 | # 1. Adhere to Unix register and stack layout [see the end for | ||
28 | # explanation]. | ||
29 | # 2. Forget about "red zone," stick to more traditional blended | ||
30 | # stack frame allocation. If volatile storage is actually required | ||
31 | # that is. If not, just leave the stack as is. | ||
32 | # 3. Functions tagged with ".type name,@function" get crafted with | ||
33 | # unified Win64 prologue and epilogue automatically. If you want | ||
34 | # to take care of ABI differences yourself, tag functions as | ||
35 | # ".type name,@abi-omnipotent" instead. | ||
36 | # 4. To optimize the Win64 prologue you can specify number of input | ||
37 | # arguments as ".type name,@function,N." Keep in mind that if N is | ||
38 | # larger than 6, then you *have to* write "abi-omnipotent" code, | ||
39 | # because >6 cases can't be addressed with unified prologue. | ||
40 | # 5. Name local labels as .L*, do *not* use dynamic labels such as 1: | ||
41 | # (sorry about latter). | ||
42 | # 6. Don't use [or hand-code with .byte] "rep ret." "ret" mnemonic is | ||
43 | # required to identify the spots, where to inject Win64 epilogue! | ||
44 | # But on the pros, it's then prefixed with rep automatically:-) | ||
45 | # 7. Due to MASM limitations [and certain general counter-intuitivity | ||
46 | # of ip-relative addressing] generation of position-independent | ||
47 | # code is assisted by synthetic directive, .picmeup, which puts | ||
48 | # address of the *next* instruction into target register. | ||
49 | # | ||
50 | # Example 1: | ||
51 | # .picmeup %rax | ||
52 | # lea .Label-.(%rax),%rax | ||
53 | # Example 2: | ||
54 | # .picmeup %rcx | ||
55 | # .Lpic_point: | ||
56 | # ... | ||
57 | # lea .Label-.Lpic_point(%rcx),%rbp | ||
58 | |||
59 | my $output = shift; | ||
60 | |||
61 | { my ($stddev,$stdino,@junk)=stat(STDOUT); | ||
62 | my ($outdev,$outino,@junk)=stat($output); | ||
63 | |||
64 | open STDOUT,">$output" || die "can't open $output: $!" | ||
65 | if ($stddev!=$outdev || $stdino!=$outino); | ||
66 | } | ||
67 | |||
68 | my $masmref=8 + 50727*2**-32; # 8.00.50727 shipped with VS2005 | ||
69 | my $masm=$masmref if ($output =~ /\.asm/); | ||
70 | if ($masm && `ml64 2>&1` =~ m/Version ([0-9]+)\.([0-9]+)(\.([0-9]+))?/) | ||
71 | { $masm=$1 + $2*2**-16 + $4*2**-32; } | ||
72 | |||
73 | my $current_segment; | ||
74 | my $current_function; | ||
75 | |||
76 | { package opcode; # pick up opcodes | ||
77 | sub re { | ||
78 | my $self = shift; # single instance in enough... | ||
79 | local *line = shift; | ||
80 | undef $ret; | ||
81 | |||
82 | if ($line =~ /^([a-z][a-z0-9]*)/i) { | ||
83 | $self->{op} = $1; | ||
84 | $ret = $self; | ||
85 | $line = substr($line,@+[0]); $line =~ s/^\s+//; | ||
86 | |||
87 | undef $self->{sz}; | ||
88 | if ($self->{op} =~ /^(movz)b.*/) { # movz is pain... | ||
89 | $self->{op} = $1; | ||
90 | $self->{sz} = "b"; | ||
91 | } elsif ($self->{op} =~ /call/) { | ||
92 | $self->{sz} = "" | ||
93 | } elsif ($self->{op} =~ /([a-z]{3,})([qlwb])$/) { | ||
94 | $self->{op} = $1; | ||
95 | $self->{sz} = $2; | ||
96 | } | ||
97 | } | ||
98 | $ret; | ||
99 | } | ||
100 | sub size { | ||
101 | my $self = shift; | ||
102 | my $sz = shift; | ||
103 | $self->{sz} = $sz if (defined($sz) && !defined($self->{sz})); | ||
104 | $self->{sz}; | ||
105 | } | ||
106 | sub out { | ||
107 | my $self = shift; | ||
108 | if (!$masm) { | ||
109 | if ($self->{op} eq "movz") { # movz is pain... | ||
110 | sprintf "%s%s%s",$self->{op},$self->{sz},shift; | ||
111 | } elsif ($self->{op} =~ /^set/) { | ||
112 | "$self->{op}"; | ||
113 | } elsif ($self->{op} eq "ret") { | ||
114 | ".byte 0xf3,0xc3"; | ||
115 | } else { | ||
116 | "$self->{op}$self->{sz}"; | ||
117 | } | ||
118 | } else { | ||
119 | $self->{op} =~ s/^movz/movzx/; | ||
120 | if ($self->{op} eq "ret") { | ||
121 | $self->{op} = ""; | ||
122 | if ($current_function->{abi} eq "svr4") { | ||
123 | $self->{op} = "mov rdi,QWORD PTR 8[rsp]\t;WIN64 epilogue\n\t". | ||
124 | "mov rsi,QWORD PTR 16[rsp]\n\t"; | ||
125 | } | ||
126 | $self->{op} .= "DB\t0F3h,0C3h\t\t;repret"; | ||
127 | } | ||
128 | $self->{op}; | ||
129 | } | ||
130 | } | ||
131 | } | ||
132 | { package const; # pick up constants, which start with $ | ||
133 | sub re { | ||
134 | my $self = shift; # single instance in enough... | ||
135 | local *line = shift; | ||
136 | undef $ret; | ||
137 | |||
138 | if ($line =~ /^\$([^,]+)/) { | ||
139 | $self->{value} = $1; | ||
140 | $ret = $self; | ||
141 | $line = substr($line,@+[0]); $line =~ s/^\s+//; | ||
142 | } | ||
143 | $ret; | ||
144 | } | ||
145 | sub out { | ||
146 | my $self = shift; | ||
147 | |||
148 | if (!$masm) { | ||
149 | # Solaris /usr/ccs/bin/as can't handle multiplications | ||
150 | # in $self->{value} | ||
151 | $self->{value} =~ s/(?<![0-9a-f])(0[x0-9a-f]+)/oct($1)/egi; | ||
152 | $self->{value} =~ s/([0-9]+\s*[\*\/\%]\s*[0-9]+)/eval($1)/eg; | ||
153 | sprintf "\$%s",$self->{value}; | ||
154 | } else { | ||
155 | $self->{value} =~ s/0x([0-9a-f]+)/0$1h/ig; | ||
156 | sprintf "%s",$self->{value}; | ||
157 | } | ||
158 | } | ||
159 | } | ||
160 | { package ea; # pick up effective addresses: expr(%reg,%reg,scale) | ||
161 | sub re { | ||
162 | my $self = shift; # single instance in enough... | ||
163 | local *line = shift; | ||
164 | undef $ret; | ||
165 | |||
166 | if ($line =~ /^([^\(,]*)\(([%\w,]+)\)/) { | ||
167 | $self->{label} = $1; | ||
168 | ($self->{base},$self->{index},$self->{scale})=split(/,/,$2); | ||
169 | $self->{scale} = 1 if (!defined($self->{scale})); | ||
170 | $ret = $self; | ||
171 | $line = substr($line,@+[0]); $line =~ s/^\s+//; | ||
172 | |||
173 | $self->{base} =~ s/^%//; | ||
174 | $self->{index} =~ s/^%// if (defined($self->{index})); | ||
175 | } | ||
176 | $ret; | ||
177 | } | ||
178 | sub size {} | ||
179 | sub out { | ||
180 | my $self = shift; | ||
181 | my $sz = shift; | ||
182 | |||
183 | # Silently convert all EAs to 64-bit. This is required for | ||
184 | # elder GNU assembler and results in more compact code, | ||
185 | # *but* most importantly AES module depends on this feature! | ||
186 | $self->{index} =~ s/^[er](.?[0-9xpi])[d]?$/r\1/; | ||
187 | $self->{base} =~ s/^[er](.?[0-9xpi])[d]?$/r\1/; | ||
188 | |||
189 | if (!$masm) { | ||
190 | # Solaris /usr/ccs/bin/as can't handle multiplications | ||
191 | # in $self->{label} | ||
192 | $self->{label} =~ s/(?<![0-9a-f])(0[x0-9a-f]+)/oct($1)/egi; | ||
193 | $self->{label} =~ s/([0-9]+\s*[\*\/\%]\s*[0-9]+)/eval($1)/eg; | ||
194 | |||
195 | if (defined($self->{index})) { | ||
196 | sprintf "%s(%%%s,%%%s,%d)", | ||
197 | $self->{label},$self->{base}, | ||
198 | $self->{index},$self->{scale}; | ||
199 | } else { | ||
200 | sprintf "%s(%%%s)", $self->{label},$self->{base}; | ||
201 | } | ||
202 | } else { | ||
203 | %szmap = ( b=>"BYTE", w=>"WORD", l=>"DWORD", q=>"QWORD" ); | ||
204 | |||
205 | $self->{label} =~ s/\./\$/g; | ||
206 | $self->{label} =~ s/0x([0-9a-f]+)/0$1h/ig; | ||
207 | $self->{label} = "($self->{label})" if ($self->{label} =~ /[\*\+\-\/]/); | ||
208 | |||
209 | if (defined($self->{index})) { | ||
210 | sprintf "%s PTR %s[%s*%d+%s]",$szmap{$sz}, | ||
211 | $self->{label}, | ||
212 | $self->{index},$self->{scale}, | ||
213 | $self->{base}; | ||
214 | } elsif ($self->{base} eq "rip") { | ||
215 | sprintf "%s PTR %s",$szmap{$sz},$self->{label}; | ||
216 | } else { | ||
217 | sprintf "%s PTR %s[%s]",$szmap{$sz}, | ||
218 | $self->{label},$self->{base}; | ||
219 | } | ||
220 | } | ||
221 | } | ||
222 | } | ||
223 | { package register; # pick up registers, which start with %. | ||
224 | sub re { | ||
225 | my $class = shift; # muliple instances... | ||
226 | my $self = {}; | ||
227 | local *line = shift; | ||
228 | undef $ret; | ||
229 | |||
230 | if ($line =~ /^%(\w+)/) { | ||
231 | bless $self,$class; | ||
232 | $self->{value} = $1; | ||
233 | $ret = $self; | ||
234 | $line = substr($line,@+[0]); $line =~ s/^\s+//; | ||
235 | } | ||
236 | $ret; | ||
237 | } | ||
238 | sub size { | ||
239 | my $self = shift; | ||
240 | undef $ret; | ||
241 | |||
242 | if ($self->{value} =~ /^r[\d]+b$/i) { $ret="b"; } | ||
243 | elsif ($self->{value} =~ /^r[\d]+w$/i) { $ret="w"; } | ||
244 | elsif ($self->{value} =~ /^r[\d]+d$/i) { $ret="l"; } | ||
245 | elsif ($self->{value} =~ /^r[\w]+$/i) { $ret="q"; } | ||
246 | elsif ($self->{value} =~ /^[a-d][hl]$/i){ $ret="b"; } | ||
247 | elsif ($self->{value} =~ /^[\w]{2}l$/i) { $ret="b"; } | ||
248 | elsif ($self->{value} =~ /^[\w]{2}$/i) { $ret="w"; } | ||
249 | elsif ($self->{value} =~ /^e[a-z]{2}$/i){ $ret="l"; } | ||
250 | |||
251 | $ret; | ||
252 | } | ||
253 | sub out { | ||
254 | my $self = shift; | ||
255 | sprintf $masm?"%s":"%%%s",$self->{value}; | ||
256 | } | ||
257 | } | ||
258 | { package label; # pick up labels, which end with : | ||
259 | sub re { | ||
260 | my $self = shift; # single instance is enough... | ||
261 | local *line = shift; | ||
262 | undef $ret; | ||
263 | |||
264 | if ($line =~ /(^[\.\w]+\:)/) { | ||
265 | $self->{value} = $1; | ||
266 | $ret = $self; | ||
267 | $line = substr($line,@+[0]); $line =~ s/^\s+//; | ||
268 | |||
269 | $self->{value} =~ s/\.L/\$L/ if ($masm); | ||
270 | } | ||
271 | $ret; | ||
272 | } | ||
273 | sub out { | ||
274 | my $self = shift; | ||
275 | |||
276 | if (!$masm) { | ||
277 | $self->{value}; | ||
278 | } elsif ($self->{value} ne "$current_function->{name}:") { | ||
279 | $self->{value}; | ||
280 | } elsif ($current_function->{abi} eq "svr4") { | ||
281 | my $func = "$current_function->{name} PROC\n". | ||
282 | " mov QWORD PTR 8[rsp],rdi\t;WIN64 prologue\n". | ||
283 | " mov QWORD PTR 16[rsp],rsi\n"; | ||
284 | my $narg = $current_function->{narg}; | ||
285 | $narg=6 if (!defined($narg)); | ||
286 | $func .= " mov rdi,rcx\n" if ($narg>0); | ||
287 | $func .= " mov rsi,rdx\n" if ($narg>1); | ||
288 | $func .= " mov rdx,r8\n" if ($narg>2); | ||
289 | $func .= " mov rcx,r9\n" if ($narg>3); | ||
290 | $func .= " mov r8,QWORD PTR 40[rsp]\n" if ($narg>4); | ||
291 | $func .= " mov r9,QWORD PTR 48[rsp]\n" if ($narg>5); | ||
292 | $func .= "\n"; | ||
293 | } else { | ||
294 | "$current_function->{name} PROC"; | ||
295 | } | ||
296 | } | ||
297 | } | ||
298 | { package expr; # pick up expressioins | ||
299 | sub re { | ||
300 | my $self = shift; # single instance is enough... | ||
301 | local *line = shift; | ||
302 | undef $ret; | ||
303 | |||
304 | if ($line =~ /(^[^,]+)/) { | ||
305 | $self->{value} = $1; | ||
306 | $ret = $self; | ||
307 | $line = substr($line,@+[0]); $line =~ s/^\s+//; | ||
308 | |||
309 | $self->{value} =~ s/\.L/\$L/g if ($masm); | ||
310 | } | ||
311 | $ret; | ||
312 | } | ||
313 | sub out { | ||
314 | my $self = shift; | ||
315 | $self->{value}; | ||
316 | } | ||
317 | } | ||
318 | { package directive; # pick up directives, which start with . | ||
319 | sub re { | ||
320 | my $self = shift; # single instance is enough... | ||
321 | local *line = shift; | ||
322 | undef $ret; | ||
323 | my $dir; | ||
324 | my %opcode = # lea 2f-1f(%rip),%dst; 1: nop; 2: | ||
325 | ( "%rax"=>0x01058d48, "%rcx"=>0x010d8d48, | ||
326 | "%rdx"=>0x01158d48, "%rbx"=>0x011d8d48, | ||
327 | "%rsp"=>0x01258d48, "%rbp"=>0x012d8d48, | ||
328 | "%rsi"=>0x01358d48, "%rdi"=>0x013d8d48, | ||
329 | "%r8" =>0x01058d4c, "%r9" =>0x010d8d4c, | ||
330 | "%r10"=>0x01158d4c, "%r11"=>0x011d8d4c, | ||
331 | "%r12"=>0x01258d4c, "%r13"=>0x012d8d4c, | ||
332 | "%r14"=>0x01358d4c, "%r15"=>0x013d8d4c ); | ||
333 | |||
334 | if ($line =~ /^\s*(\.\w+)/) { | ||
335 | if (!$masm) { | ||
336 | $self->{value} = $1; | ||
337 | $line =~ s/\@abi\-omnipotent/\@function/; | ||
338 | $line =~ s/\@function.*/\@function/; | ||
339 | if ($line =~ /\.picmeup\s+(%r[\w]+)/i) { | ||
340 | $self->{value} = sprintf "\t.long\t0x%x,0x90000000",$opcode{$1}; | ||
341 | } elsif ($line =~ /\.asciz\s+"(.*)"$/) { | ||
342 | $self->{value} = ".byte\t".join(",",unpack("C*",$1),0); | ||
343 | } elsif ($line =~ /\.extern/) { | ||
344 | $self->{value} = ""; # swallow extern | ||
345 | } else { | ||
346 | $self->{value} = $line; | ||
347 | } | ||
348 | $line = ""; | ||
349 | return $self; | ||
350 | } | ||
351 | |||
352 | $dir = $1; | ||
353 | $ret = $self; | ||
354 | undef $self->{value}; | ||
355 | $line = substr($line,@+[0]); $line =~ s/^\s+//; | ||
356 | SWITCH: for ($dir) { | ||
357 | /\.(text)/ | ||
358 | && do { my $v=undef; | ||
359 | $v="$current_segment\tENDS\n" if ($current_segment); | ||
360 | $current_segment = "_$1\$"; | ||
361 | $current_segment =~ tr/[a-z]/[A-Z]/; | ||
362 | $v.="$current_segment\tSEGMENT "; | ||
363 | $v.=$masm>=$masmref ? "ALIGN(64)" : "PAGE"; | ||
364 | $v.=" 'CODE'"; | ||
365 | $self->{value} = $v; | ||
366 | last; | ||
367 | }; | ||
368 | /\.extern/ && do { $self->{value} = "EXTRN\t".$line.":BYTE"; last; }; | ||
369 | /\.globl/ && do { $self->{value} = "PUBLIC\t".$line; last; }; | ||
370 | /\.type/ && do { ($sym,$type,$narg) = split(',',$line); | ||
371 | if ($type eq "\@function") { | ||
372 | undef $current_function; | ||
373 | $current_function->{name} = $sym; | ||
374 | $current_function->{abi} = "svr4"; | ||
375 | $current_function->{narg} = $narg; | ||
376 | } elsif ($type eq "\@abi-omnipotent") { | ||
377 | undef $current_function; | ||
378 | $current_function->{name} = $sym; | ||
379 | } | ||
380 | last; | ||
381 | }; | ||
382 | /\.size/ && do { if (defined($current_function)) { | ||
383 | $self->{value}="$current_function->{name}\tENDP"; | ||
384 | undef $current_function; | ||
385 | } | ||
386 | last; | ||
387 | }; | ||
388 | /\.align/ && do { $self->{value} = "ALIGN\t".$line; last; }; | ||
389 | /\.(byte|value|long|quad)/ | ||
390 | && do { my @arr = split(',',$line); | ||
391 | my $sz = substr($1,0,1); | ||
392 | my $last = pop(@arr); | ||
393 | my $conv = sub { my $var=shift; | ||
394 | if ($var=~s/0x([0-9a-f]+)/0$1h/i) { $var; } | ||
395 | else { sprintf"0%Xh",$var; } | ||
396 | }; | ||
397 | |||
398 | $sz =~ tr/bvlq/BWDQ/; | ||
399 | $self->{value} = "\tD$sz\t"; | ||
400 | for (@arr) { $self->{value} .= &$conv($_).","; } | ||
401 | $self->{value} .= &$conv($last); | ||
402 | last; | ||
403 | }; | ||
404 | /\.picmeup/ && do { $self->{value} = sprintf"\tDD\t 0%Xh,090000000h",$opcode{$line}; | ||
405 | last; | ||
406 | }; | ||
407 | /\.asciz/ && do { if ($line =~ /^"(.*)"$/) { | ||
408 | my @str=unpack("C*",$1); | ||
409 | push @str,0; | ||
410 | while ($#str>15) { | ||
411 | $self->{value}.="DB\t" | ||
412 | .join(",",@str[0..15])."\n"; | ||
413 | foreach (0..15) { shift @str; } | ||
414 | } | ||
415 | $self->{value}.="DB\t" | ||
416 | .join(",",@str) if (@str); | ||
417 | } | ||
418 | last; | ||
419 | }; | ||
420 | } | ||
421 | $line = ""; | ||
422 | } | ||
423 | |||
424 | $ret; | ||
425 | } | ||
426 | sub out { | ||
427 | my $self = shift; | ||
428 | $self->{value}; | ||
429 | } | ||
430 | } | ||
431 | |||
432 | while($line=<>) { | ||
433 | |||
434 | chomp($line); | ||
435 | |||
436 | $line =~ s|[#!].*$||; # get rid of asm-style comments... | ||
437 | $line =~ s|/\*.*\*/||; # ... and C-style comments... | ||
438 | $line =~ s|^\s+||; # ... and skip white spaces in beginning | ||
439 | |||
440 | undef $label; | ||
441 | undef $opcode; | ||
442 | undef $dst; | ||
443 | undef $src; | ||
444 | undef $sz; | ||
445 | |||
446 | if ($label=label->re(\$line)) { print $label->out(); } | ||
447 | |||
448 | if (directive->re(\$line)) { | ||
449 | printf "%s",directive->out(); | ||
450 | } elsif ($opcode=opcode->re(\$line)) { ARGUMENT: { | ||
451 | |||
452 | if ($src=register->re(\$line)) { opcode->size($src->size()); } | ||
453 | elsif ($src=const->re(\$line)) { } | ||
454 | elsif ($src=ea->re(\$line)) { } | ||
455 | elsif ($src=expr->re(\$line)) { } | ||
456 | |||
457 | last ARGUMENT if ($line !~ /^,/); | ||
458 | |||
459 | $line = substr($line,1); $line =~ s/^\s+//; | ||
460 | |||
461 | if ($dst=register->re(\$line)) { opcode->size($dst->size()); } | ||
462 | elsif ($dst=const->re(\$line)) { } | ||
463 | elsif ($dst=ea->re(\$line)) { } | ||
464 | |||
465 | } # ARGUMENT: | ||
466 | |||
467 | $sz=opcode->size(); | ||
468 | |||
469 | if (defined($dst)) { | ||
470 | if (!$masm) { | ||
471 | printf "\t%s\t%s,%s", $opcode->out($dst->size()), | ||
472 | $src->out($sz),$dst->out($sz); | ||
473 | } else { | ||
474 | printf "\t%s\t%s,%s", $opcode->out(), | ||
475 | $dst->out($sz),$src->out($sz); | ||
476 | } | ||
477 | } elsif (defined($src)) { | ||
478 | printf "\t%s\t%s",$opcode->out(),$src->out($sz); | ||
479 | } else { | ||
480 | printf "\t%s",$opcode->out(); | ||
481 | } | ||
482 | } | ||
483 | |||
484 | print $line,"\n"; | ||
485 | } | ||
486 | |||
487 | print "\n$current_segment\tENDS\nEND\n" if ($masm); | ||
488 | |||
489 | close STDOUT; | ||
490 | |||
491 | ################################################# | ||
492 | # Cross-reference x86_64 ABI "card" | ||
493 | # | ||
494 | # Unix Win64 | ||
495 | # %rax * * | ||
496 | # %rbx - - | ||
497 | # %rcx #4 #1 | ||
498 | # %rdx #3 #2 | ||
499 | # %rsi #2 - | ||
500 | # %rdi #1 - | ||
501 | # %rbp - - | ||
502 | # %rsp - - | ||
503 | # %r8 #5 #3 | ||
504 | # %r9 #6 #4 | ||
505 | # %r10 * * | ||
506 | # %r11 * * | ||
507 | # %r12 - - | ||
508 | # %r13 - - | ||
509 | # %r14 - - | ||
510 | # %r15 - - | ||
511 | # | ||
512 | # (*) volatile register | ||
513 | # (-) preserved by callee | ||
514 | # (#) Nth argument, volatile | ||
515 | # | ||
516 | # In Unix terms top of stack is argument transfer area for arguments | ||
517 | # which could not be accomodated in registers. Or in other words 7th | ||
518 | # [integer] argument resides at 8(%rsp) upon function entry point. | ||
519 | # 128 bytes above %rsp constitute a "red zone" which is not touched | ||
520 | # by signal handlers and can be used as temporal storage without | ||
521 | # allocating a frame. | ||
522 | # | ||
523 | # In Win64 terms N*8 bytes on top of stack is argument transfer area, | ||
524 | # which belongs to/can be overwritten by callee. N is the number of | ||
525 | # arguments passed to callee, *but* not less than 4! This means that | ||
526 | # upon function entry point 5th argument resides at 40(%rsp), as well | ||
527 | # as that 32 bytes from 8(%rsp) can always be used as temporal | ||
528 | # storage [without allocating a frame]. One can actually argue that | ||
529 | # one can assume a "red zone" above stack pointer under Win64 as well. | ||
530 | # Point is that at apparently no occasion Windows kernel would alter | ||
531 | # the area above user stack pointer in true asynchronous manner... | ||
532 | # | ||
533 | # All the above means that if assembler programmer adheres to Unix | ||
534 | # register and stack layout, but disregards the "red zone" existense, | ||
535 | # it's possible to use following prologue and epilogue to "gear" from | ||
536 | # Unix to Win64 ABI in leaf functions with not more than 6 arguments. | ||
537 | # | ||
538 | # omnipotent_function: | ||
539 | # ifdef WIN64 | ||
540 | # movq %rdi,8(%rsp) | ||
541 | # movq %rsi,16(%rsp) | ||
542 | # movq %rcx,%rdi ; if 1st argument is actually present | ||
543 | # movq %rdx,%rsi ; if 2nd argument is actually ... | ||
544 | # movq %r8,%rdx ; if 3rd argument is ... | ||
545 | # movq %r9,%rcx ; if 4th argument ... | ||
546 | # movq 40(%rsp),%r8 ; if 5th ... | ||
547 | # movq 48(%rsp),%r9 ; if 6th ... | ||
548 | # endif | ||
549 | # ... | ||
550 | # ifdef WIN64 | ||
551 | # movq 8(%rsp),%rdi | ||
552 | # movq 16(%rsp),%rsi | ||
553 | # endif | ||
554 | # ret | ||
diff --git a/src/lib/libcrypto/rc4/asm/rc4-x86_64.pl b/src/lib/libcrypto/rc4/asm/rc4-x86_64.pl index b628daca70..2d47320485 100755 --- a/src/lib/libcrypto/rc4/asm/rc4-x86_64.pl +++ b/src/lib/libcrypto/rc4/asm/rc4-x86_64.pl | |||
@@ -2,29 +2,70 @@ | |||
2 | # | 2 | # |
3 | # ==================================================================== | 3 | # ==================================================================== |
4 | # Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL | 4 | # Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL |
5 | # project. Rights for redistribution and usage in source and binary | 5 | # project. The module is, however, dual licensed under OpenSSL and |
6 | # forms are granted according to the OpenSSL license. | 6 | # CRYPTOGAMS licenses depending on where you obtain it. For further |
7 | # details see http://www.openssl.org/~appro/cryptogams/. | ||
7 | # ==================================================================== | 8 | # ==================================================================== |
8 | # | 9 | # |
9 | # Unlike 0.9.7f this code expects RC4_CHAR back in config line! See | 10 | # 2.22x RC4 tune-up:-) It should be noted though that my hand [as in |
10 | # commentary section in corresponding script in development branch | 11 | # "hand-coded assembler"] doesn't stand for the whole improvement |
11 | # for background information about this option carousel. For those | 12 | # coefficient. It turned out that eliminating RC4_CHAR from config |
12 | # who don't have energy to figure out these gory details, here is | 13 | # line results in ~40% improvement (yes, even for C implementation). |
13 | # basis in form of performance matrix relative to the original | 14 | # Presumably it has everything to do with AMD cache architecture and |
14 | # 0.9.7e C code-base: | 15 | # RAW or whatever penalties. Once again! The module *requires* config |
15 | # | 16 | # line *without* RC4_CHAR! As for coding "secret," I bet on partial |
16 | # 0.9.7e 0.9.7f this | 17 | # register arithmetics. For example instead of 'inc %r8; and $255,%r8' |
17 | # AMD64 1x 3.3x 2.4x | 18 | # I simply 'inc %r8b'. Even though optimization manual discourages |
18 | # EM64T 1x 0.8x 1.5x | 19 | # to operate on partial registers, it turned out to be the best bet. |
19 | # | 20 | # At least for AMD... How IA32E would perform remains to be seen... |
20 | # In other words idea is to trade -25% AMD64 performance to compensate | 21 | |
21 | # for deterioration and gain +90% on EM64T core. Development branch | 22 | # As was shown by Marc Bevand reordering of couple of load operations |
22 | # maintains best performance for either target, i.e. 3.3x for AMD64 | 23 | # results in even higher performance gain of 3.3x:-) At least on |
23 | # and 1.5x for EM64T. | 24 | # Opteron... For reference, 1x in this case is RC4_CHAR C-code |
25 | # compiled with gcc 3.3.2, which performs at ~54MBps per 1GHz clock. | ||
26 | # Latter means that if you want to *estimate* what to expect from | ||
27 | # *your* Opteron, then multiply 54 by 3.3 and clock frequency in GHz. | ||
28 | |||
29 | # Intel P4 EM64T core was found to run the AMD64 code really slow... | ||
30 | # The only way to achieve comparable performance on P4 was to keep | ||
31 | # RC4_CHAR. Kind of ironic, huh? As it's apparently impossible to | ||
32 | # compose blended code, which would perform even within 30% marginal | ||
33 | # on either AMD and Intel platforms, I implement both cases. See | ||
34 | # rc4_skey.c for further details... | ||
35 | |||
36 | # P4 EM64T core appears to be "allergic" to 64-bit inc/dec. Replacing | ||
37 | # those with add/sub results in 50% performance improvement of folded | ||
38 | # loop... | ||
39 | |||
40 | # As was shown by Zou Nanhai loop unrolling can improve Intel EM64T | ||
41 | # performance by >30% [unlike P4 32-bit case that is]. But this is | ||
42 | # provided that loads are reordered even more aggressively! Both code | ||
43 | # pathes, AMD64 and EM64T, reorder loads in essentially same manner | ||
44 | # as my IA-64 implementation. On Opteron this resulted in modest 5% | ||
45 | # improvement [I had to test it], while final Intel P4 performance | ||
46 | # achieves respectful 432MBps on 2.8GHz processor now. For reference. | ||
47 | # If executed on Xeon, current RC4_CHAR code-path is 2.7x faster than | ||
48 | # RC4_INT code-path. While if executed on Opteron, it's only 25% | ||
49 | # slower than the RC4_INT one [meaning that if CPU µ-arch detection | ||
50 | # is not implemented, then this final RC4_CHAR code-path should be | ||
51 | # preferred, as it provides better *all-round* performance]. | ||
52 | |||
53 | # Intel Core2 was observed to perform poorly on both code paths:-( It | ||
54 | # apparently suffers from some kind of partial register stall, which | ||
55 | # occurs in 64-bit mode only [as virtually identical 32-bit loop was | ||
56 | # observed to outperform 64-bit one by almost 50%]. Adding two movzb to | ||
57 | # cloop1 boosts its performance by 80%! This loop appears to be optimal | ||
58 | # fit for Core2 and therefore the code was modified to skip cloop8 on | ||
59 | # this CPU. | ||
24 | 60 | ||
25 | $output=shift; | 61 | $output=shift; |
26 | 62 | ||
27 | open STDOUT,">$output" || die "can't open $output: $!"; | 63 | $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; |
64 | ( $xlate="${dir}x86_64-xlate.pl" and -f $xlate ) or | ||
65 | ( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or | ||
66 | die "can't locate x86_64-xlate.pl"; | ||
67 | |||
68 | open STDOUT,"| $^X $xlate $output"; | ||
28 | 69 | ||
29 | $dat="%rdi"; # arg1 | 70 | $dat="%rdi"; # arg1 |
30 | $len="%rsi"; # arg2 | 71 | $len="%rsi"; # arg2 |
@@ -36,29 +77,101 @@ $out="%rcx"; # arg4 | |||
36 | $YY="%r12"; | 77 | $YY="%r12"; |
37 | $TY="%r13"; | 78 | $TY="%r13"; |
38 | 79 | ||
39 | $code=<<___;; | 80 | $code=<<___; |
40 | .text | 81 | .text |
41 | 82 | ||
42 | .globl RC4 | 83 | .globl RC4 |
43 | .type RC4,\@function | 84 | .type RC4,\@function,4 |
44 | .align 16 | 85 | .align 16 |
45 | RC4: or $len,$len | 86 | RC4: or $len,$len |
46 | jne .Lentry | 87 | jne .Lentry |
47 | repret | 88 | ret |
48 | .Lentry: | 89 | .Lentry: |
49 | push %r12 | 90 | push %r12 |
50 | push %r13 | 91 | push %r13 |
51 | 92 | ||
52 | add \$2,$dat | 93 | add \$8,$dat |
53 | movzb -2($dat),$XX[0]#d | 94 | movl -8($dat),$XX[0]#d |
54 | movzb -1($dat),$YY#d | 95 | movl -4($dat),$YY#d |
96 | cmpl \$-1,256($dat) | ||
97 | je .LRC4_CHAR | ||
98 | inc $XX[0]#b | ||
99 | movl ($dat,$XX[0],4),$TX[0]#d | ||
100 | test \$-8,$len | ||
101 | jz .Lloop1 | ||
102 | jmp .Lloop8 | ||
103 | .align 16 | ||
104 | .Lloop8: | ||
105 | ___ | ||
106 | for ($i=0;$i<8;$i++) { | ||
107 | $code.=<<___; | ||
108 | add $TX[0]#b,$YY#b | ||
109 | mov $XX[0],$XX[1] | ||
110 | movl ($dat,$YY,4),$TY#d | ||
111 | ror \$8,%rax # ror is redundant when $i=0 | ||
112 | inc $XX[1]#b | ||
113 | movl ($dat,$XX[1],4),$TX[1]#d | ||
114 | cmp $XX[1],$YY | ||
115 | movl $TX[0]#d,($dat,$YY,4) | ||
116 | cmove $TX[0],$TX[1] | ||
117 | movl $TY#d,($dat,$XX[0],4) | ||
118 | add $TX[0]#b,$TY#b | ||
119 | movb ($dat,$TY,4),%al | ||
120 | ___ | ||
121 | push(@TX,shift(@TX)); push(@XX,shift(@XX)); # "rotate" registers | ||
122 | } | ||
123 | $code.=<<___; | ||
124 | ror \$8,%rax | ||
125 | sub \$8,$len | ||
126 | |||
127 | xor ($inp),%rax | ||
128 | add \$8,$inp | ||
129 | mov %rax,($out) | ||
130 | add \$8,$out | ||
55 | 131 | ||
132 | test \$-8,$len | ||
133 | jnz .Lloop8 | ||
134 | cmp \$0,$len | ||
135 | jne .Lloop1 | ||
136 | ___ | ||
137 | $code.=<<___; | ||
138 | .Lexit: | ||
139 | sub \$1,$XX[0]#b | ||
140 | movl $XX[0]#d,-8($dat) | ||
141 | movl $YY#d,-4($dat) | ||
142 | |||
143 | pop %r13 | ||
144 | pop %r12 | ||
145 | ret | ||
146 | .align 16 | ||
147 | .Lloop1: | ||
148 | add $TX[0]#b,$YY#b | ||
149 | movl ($dat,$YY,4),$TY#d | ||
150 | movl $TX[0]#d,($dat,$YY,4) | ||
151 | movl $TY#d,($dat,$XX[0],4) | ||
152 | add $TY#b,$TX[0]#b | ||
153 | inc $XX[0]#b | ||
154 | movl ($dat,$TX[0],4),$TY#d | ||
155 | movl ($dat,$XX[0],4),$TX[0]#d | ||
156 | xorb ($inp),$TY#b | ||
157 | inc $inp | ||
158 | movb $TY#b,($out) | ||
159 | inc $out | ||
160 | dec $len | ||
161 | jnz .Lloop1 | ||
162 | jmp .Lexit | ||
163 | |||
164 | .align 16 | ||
165 | .LRC4_CHAR: | ||
56 | add \$1,$XX[0]#b | 166 | add \$1,$XX[0]#b |
57 | movzb ($dat,$XX[0]),$TX[0]#d | 167 | movzb ($dat,$XX[0]),$TX[0]#d |
58 | test \$-8,$len | 168 | test \$-8,$len |
59 | jz .Lcloop1 | 169 | jz .Lcloop1 |
170 | cmp \$0,260($dat) | ||
171 | jnz .Lcloop1 | ||
60 | push %rbx | 172 | push %rbx |
61 | .align 16 # incidentally aligned already | 173 | jmp .Lcloop8 |
174 | .align 16 | ||
62 | .Lcloop8: | 175 | .Lcloop8: |
63 | mov ($inp),%eax | 176 | mov ($inp),%eax |
64 | mov 4($inp),%ebx | 177 | mov 4($inp),%ebx |
@@ -114,15 +227,9 @@ $code.=<<___; | |||
114 | pop %rbx | 227 | pop %rbx |
115 | cmp \$0,$len | 228 | cmp \$0,$len |
116 | jne .Lcloop1 | 229 | jne .Lcloop1 |
117 | .Lexit: | 230 | jmp .Lexit |
118 | sub \$1,$XX[0]#b | 231 | ___ |
119 | movb $XX[0]#b,-2($dat) | 232 | $code.=<<___; |
120 | movb $YY#b,-1($dat) | ||
121 | |||
122 | pop %r13 | ||
123 | pop %r12 | ||
124 | repret | ||
125 | |||
126 | .align 16 | 233 | .align 16 |
127 | .Lcloop1: | 234 | .Lcloop1: |
128 | add $TX[0]#b,$YY#b | 235 | add $TX[0]#b,$YY#b |
@@ -131,6 +238,8 @@ $code.=<<___; | |||
131 | movb $TY#b,($dat,$XX[0]) | 238 | movb $TY#b,($dat,$XX[0]) |
132 | add $TX[0]#b,$TY#b | 239 | add $TX[0]#b,$TY#b |
133 | add \$1,$XX[0]#b | 240 | add \$1,$XX[0]#b |
241 | movzb $TY#b,$TY#d | ||
242 | movzb $XX[0]#b,$XX[0]#d | ||
134 | movzb ($dat,$TY),$TY#d | 243 | movzb ($dat,$TY),$TY#d |
135 | movzb ($dat,$XX[0]),$TX[0]#d | 244 | movzb ($dat,$XX[0]),$TX[0]#d |
136 | xorb ($inp),$TY#b | 245 | xorb ($inp),$TY#b |
@@ -143,8 +252,113 @@ $code.=<<___; | |||
143 | .size RC4,.-RC4 | 252 | .size RC4,.-RC4 |
144 | ___ | 253 | ___ |
145 | 254 | ||
146 | $code =~ s/#([bwd])/$1/gm; | 255 | $idx="%r8"; |
256 | $ido="%r9"; | ||
257 | |||
258 | $code.=<<___; | ||
259 | .extern OPENSSL_ia32cap_P | ||
260 | .globl RC4_set_key | ||
261 | .type RC4_set_key,\@function,3 | ||
262 | .align 16 | ||
263 | RC4_set_key: | ||
264 | lea 8($dat),$dat | ||
265 | lea ($inp,$len),$inp | ||
266 | neg $len | ||
267 | mov $len,%rcx | ||
268 | xor %eax,%eax | ||
269 | xor $ido,$ido | ||
270 | xor %r10,%r10 | ||
271 | xor %r11,%r11 | ||
147 | 272 | ||
148 | $code =~ s/repret/.byte\t0xF3,0xC3/gm; | 273 | mov OPENSSL_ia32cap_P(%rip),$idx#d |
274 | bt \$20,$idx#d | ||
275 | jnc .Lw1stloop | ||
276 | bt \$30,$idx#d | ||
277 | setc $ido#b | ||
278 | mov $ido#d,260($dat) | ||
279 | jmp .Lc1stloop | ||
280 | |||
281 | .align 16 | ||
282 | .Lw1stloop: | ||
283 | mov %eax,($dat,%rax,4) | ||
284 | add \$1,%al | ||
285 | jnc .Lw1stloop | ||
286 | |||
287 | xor $ido,$ido | ||
288 | xor $idx,$idx | ||
289 | .align 16 | ||
290 | .Lw2ndloop: | ||
291 | mov ($dat,$ido,4),%r10d | ||
292 | add ($inp,$len,1),$idx#b | ||
293 | add %r10b,$idx#b | ||
294 | add \$1,$len | ||
295 | mov ($dat,$idx,4),%r11d | ||
296 | cmovz %rcx,$len | ||
297 | mov %r10d,($dat,$idx,4) | ||
298 | mov %r11d,($dat,$ido,4) | ||
299 | add \$1,$ido#b | ||
300 | jnc .Lw2ndloop | ||
301 | jmp .Lexit_key | ||
302 | |||
303 | .align 16 | ||
304 | .Lc1stloop: | ||
305 | mov %al,($dat,%rax) | ||
306 | add \$1,%al | ||
307 | jnc .Lc1stloop | ||
308 | |||
309 | xor $ido,$ido | ||
310 | xor $idx,$idx | ||
311 | .align 16 | ||
312 | .Lc2ndloop: | ||
313 | mov ($dat,$ido),%r10b | ||
314 | add ($inp,$len),$idx#b | ||
315 | add %r10b,$idx#b | ||
316 | add \$1,$len | ||
317 | mov ($dat,$idx),%r11b | ||
318 | jnz .Lcnowrap | ||
319 | mov %rcx,$len | ||
320 | .Lcnowrap: | ||
321 | mov %r10b,($dat,$idx) | ||
322 | mov %r11b,($dat,$ido) | ||
323 | add \$1,$ido#b | ||
324 | jnc .Lc2ndloop | ||
325 | movl \$-1,256($dat) | ||
326 | |||
327 | .align 16 | ||
328 | .Lexit_key: | ||
329 | xor %eax,%eax | ||
330 | mov %eax,-8($dat) | ||
331 | mov %eax,-4($dat) | ||
332 | ret | ||
333 | .size RC4_set_key,.-RC4_set_key | ||
334 | |||
335 | .globl RC4_options | ||
336 | .type RC4_options,\@function,0 | ||
337 | .align 16 | ||
338 | RC4_options: | ||
339 | .picmeup %rax | ||
340 | lea .Lopts-.(%rax),%rax | ||
341 | mov OPENSSL_ia32cap_P(%rip),%edx | ||
342 | bt \$20,%edx | ||
343 | jnc .Ldone | ||
344 | add \$12,%rax | ||
345 | bt \$30,%edx | ||
346 | jnc .Ldone | ||
347 | add \$13,%rax | ||
348 | .Ldone: | ||
349 | ret | ||
350 | .align 64 | ||
351 | .Lopts: | ||
352 | .asciz "rc4(8x,int)" | ||
353 | .asciz "rc4(8x,char)" | ||
354 | .asciz "rc4(1x,char)" | ||
355 | .asciz "RC4 for x86_64, CRYPTOGAMS by <appro\@openssl.org>" | ||
356 | .align 64 | ||
357 | .size RC4_options,.-RC4_options | ||
358 | ___ | ||
359 | |||
360 | $code =~ s/#([bwd])/$1/gm; | ||
149 | 361 | ||
150 | print $code; | 362 | print $code; |
363 | |||
364 | close STDOUT; | ||
diff --git a/src/lib/libcrypto/rsa/rsa_depr.c b/src/lib/libcrypto/rsa/rsa_depr.c new file mode 100644 index 0000000000..a859ded987 --- /dev/null +++ b/src/lib/libcrypto/rsa/rsa_depr.c | |||
@@ -0,0 +1,101 @@ | |||
1 | /* crypto/rsa/rsa_depr.c */ | ||
2 | /* ==================================================================== | ||
3 | * Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions | ||
7 | * are met: | ||
8 | * | ||
9 | * 1. Redistributions of source code must retain the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer. | ||
11 | * | ||
12 | * 2. Redistributions in binary form must reproduce the above copyright | ||
13 | * notice, this list of conditions and the following disclaimer in | ||
14 | * the documentation and/or other materials provided with the | ||
15 | * distribution. | ||
16 | * | ||
17 | * 3. All advertising materials mentioning features or use of this | ||
18 | * software must display the following acknowledgment: | ||
19 | * "This product includes software developed by the OpenSSL Project | ||
20 | * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" | ||
21 | * | ||
22 | * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to | ||
23 | * endorse or promote products derived from this software without | ||
24 | * prior written permission. For written permission, please contact | ||
25 | * openssl-core@openssl.org. | ||
26 | * | ||
27 | * 5. Products derived from this software may not be called "OpenSSL" | ||
28 | * nor may "OpenSSL" appear in their names without prior written | ||
29 | * permission of the OpenSSL Project. | ||
30 | * | ||
31 | * 6. Redistributions of any form whatsoever must retain the following | ||
32 | * acknowledgment: | ||
33 | * "This product includes software developed by the OpenSSL Project | ||
34 | * for use in the OpenSSL Toolkit (http://www.openssl.org/)" | ||
35 | * | ||
36 | * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY | ||
37 | * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
38 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | ||
39 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR | ||
40 | * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
41 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
42 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
43 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
44 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
45 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
46 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED | ||
47 | * OF THE POSSIBILITY OF SUCH DAMAGE. | ||
48 | * ==================================================================== | ||
49 | * | ||
50 | * This product includes cryptographic software written by Eric Young | ||
51 | * (eay@cryptsoft.com). This product includes software written by Tim | ||
52 | * Hudson (tjh@cryptsoft.com). | ||
53 | * | ||
54 | */ | ||
55 | |||
56 | /* NB: This file contains deprecated functions (compatibility wrappers to the | ||
57 | * "new" versions). */ | ||
58 | |||
59 | #include <stdio.h> | ||
60 | #include <time.h> | ||
61 | #include "cryptlib.h" | ||
62 | #include <openssl/bn.h> | ||
63 | #include <openssl/rsa.h> | ||
64 | |||
65 | #ifdef OPENSSL_NO_DEPRECATED | ||
66 | |||
67 | static void *dummy=&dummy; | ||
68 | |||
69 | #else | ||
70 | |||
71 | RSA *RSA_generate_key(int bits, unsigned long e_value, | ||
72 | void (*callback)(int,int,void *), void *cb_arg) | ||
73 | { | ||
74 | BN_GENCB cb; | ||
75 | int i; | ||
76 | RSA *rsa = RSA_new(); | ||
77 | BIGNUM *e = BN_new(); | ||
78 | |||
79 | if(!rsa || !e) goto err; | ||
80 | |||
81 | /* The problem is when building with 8, 16, or 32 BN_ULONG, | ||
82 | * unsigned long can be larger */ | ||
83 | for (i=0; i<(int)sizeof(unsigned long)*8; i++) | ||
84 | { | ||
85 | if (e_value & (1UL<<i)) | ||
86 | if (BN_set_bit(e,i) == 0) | ||
87 | goto err; | ||
88 | } | ||
89 | |||
90 | BN_GENCB_set_old(&cb, callback, cb_arg); | ||
91 | |||
92 | if(RSA_generate_key_ex(rsa, bits, e, &cb)) { | ||
93 | BN_free(e); | ||
94 | return rsa; | ||
95 | } | ||
96 | err: | ||
97 | if(e) BN_free(e); | ||
98 | if(rsa) RSA_free(rsa); | ||
99 | return 0; | ||
100 | } | ||
101 | #endif | ||
diff --git a/src/lib/libcrypto/rsa/rsa_pss.c b/src/lib/libcrypto/rsa/rsa_pss.c index 2815628f5f..e19d18c5b9 100644 --- a/src/lib/libcrypto/rsa/rsa_pss.c +++ b/src/lib/libcrypto/rsa/rsa_pss.c | |||
@@ -64,7 +64,11 @@ | |||
64 | #include <openssl/rand.h> | 64 | #include <openssl/rand.h> |
65 | #include <openssl/sha.h> | 65 | #include <openssl/sha.h> |
66 | 66 | ||
67 | const static unsigned char zeroes[] = {0,0,0,0,0,0,0,0}; | 67 | static const unsigned char zeroes[] = {0,0,0,0,0,0,0,0}; |
68 | |||
69 | #if defined(_MSC_VER) && defined(_ARM_) | ||
70 | #pragma optimize("g", off) | ||
71 | #endif | ||
68 | 72 | ||
69 | int RSA_verify_PKCS1_PSS(RSA *rsa, const unsigned char *mHash, | 73 | int RSA_verify_PKCS1_PSS(RSA *rsa, const unsigned char *mHash, |
70 | const EVP_MD *Hash, const unsigned char *EM, int sLen) | 74 | const EVP_MD *Hash, const unsigned char *EM, int sLen) |
@@ -259,3 +263,7 @@ int RSA_padding_add_PKCS1_PSS(RSA *rsa, unsigned char *EM, | |||
259 | return ret; | 263 | return ret; |
260 | 264 | ||
261 | } | 265 | } |
266 | |||
267 | #if defined(_MSC_VER) | ||
268 | #pragma optimize("",on) | ||
269 | #endif | ||
diff --git a/src/lib/libcrypto/rsa/rsa_x931.c b/src/lib/libcrypto/rsa/rsa_x931.c index df3c45f802..e918654176 100644 --- a/src/lib/libcrypto/rsa/rsa_x931.c +++ b/src/lib/libcrypto/rsa/rsa_x931.c | |||
@@ -105,7 +105,7 @@ int RSA_padding_add_X931(unsigned char *to, int tlen, | |||
105 | int RSA_padding_check_X931(unsigned char *to, int tlen, | 105 | int RSA_padding_check_X931(unsigned char *to, int tlen, |
106 | const unsigned char *from, int flen, int num) | 106 | const unsigned char *from, int flen, int num) |
107 | { | 107 | { |
108 | int i,j; | 108 | int i = 0,j; |
109 | const unsigned char *p; | 109 | const unsigned char *p; |
110 | 110 | ||
111 | p=from; | 111 | p=from; |
diff --git a/src/lib/libcrypto/sha/asm/sha1-ia64.pl b/src/lib/libcrypto/sha/asm/sha1-ia64.pl index cb9dfad124..aa18c1089b 100644 --- a/src/lib/libcrypto/sha/asm/sha1-ia64.pl +++ b/src/lib/libcrypto/sha/asm/sha1-ia64.pl | |||
@@ -2,8 +2,9 @@ | |||
2 | # | 2 | # |
3 | # ==================================================================== | 3 | # ==================================================================== |
4 | # Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL | 4 | # Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL |
5 | # project. Rights for redistribution and usage in source and binary | 5 | # project. The module is, however, dual licensed under OpenSSL and |
6 | # forms are granted according to the OpenSSL license. | 6 | # CRYPTOGAMS licenses depending on where you obtain it. For further |
7 | # details see http://www.openssl.org/~appro/cryptogams/. | ||
7 | # ==================================================================== | 8 | # ==================================================================== |
8 | # | 9 | # |
9 | # Eternal question is what's wrong with compiler generated code? The | 10 | # Eternal question is what's wrong with compiler generated code? The |
@@ -11,15 +12,10 @@ | |||
11 | # to perform rotations by maintaining copy of 32-bit value in upper | 12 | # to perform rotations by maintaining copy of 32-bit value in upper |
12 | # bits of 64-bit register. Just follow mux2 and shrp instructions... | 13 | # bits of 64-bit register. Just follow mux2 and shrp instructions... |
13 | # Performance under big-endian OS such as HP-UX is 179MBps*1GHz, which | 14 | # Performance under big-endian OS such as HP-UX is 179MBps*1GHz, which |
14 | # is >50% better than HP C and >2x better than gcc. As of this moment | 15 | # is >50% better than HP C and >2x better than gcc. |
15 | # performance under little-endian OS such as Linux and Windows will be | ||
16 | # a bit lower, because data has to be picked in reverse byte-order. | ||
17 | # It's possible to resolve this issue by implementing third function, | ||
18 | # sha1_block_asm_data_order_aligned, which would temporarily flip | ||
19 | # BE field in User Mask register... | ||
20 | 16 | ||
21 | $code=<<___; | 17 | $code=<<___; |
22 | .ident \"sha1-ia64.s, version 1.0\" | 18 | .ident \"sha1-ia64.s, version 1.2\" |
23 | .ident \"IA-64 ISA artwork by Andy Polyakov <appro\@fy.chalmers.se>\" | 19 | .ident \"IA-64 ISA artwork by Andy Polyakov <appro\@fy.chalmers.se>\" |
24 | .explicit | 20 | .explicit |
25 | 21 | ||
@@ -55,63 +51,55 @@ else { | |||
55 | 51 | ||
56 | sub BODY_00_15 { | 52 | sub BODY_00_15 { |
57 | local *code=shift; | 53 | local *code=shift; |
58 | local ($i,$a,$b,$c,$d,$e,$f,$unaligned)=@_; | 54 | local ($i,$a,$b,$c,$d,$e,$f)=@_; |
59 | 55 | ||
60 | if ($unaligned) { | 56 | $code.=<<___ if ($i==0); |
61 | $code.=<<___; | 57 | { .mmi; ld1 $X[$i&0xf]=[inp],2 // MSB |
62 | { .mmi; ld1 tmp0=[inp],2 // MSB | 58 | ld1 tmp2=[tmp3],2 };; |
63 | ld1 tmp1=[tmp3],2 };; | 59 | { .mmi; ld1 tmp0=[inp],2 |
64 | { .mmi; ld1 tmp2=[inp],2 | 60 | ld1 tmp4=[tmp3],2 // LSB |
65 | ld1 $X[$i&0xf]=[tmp3],2 // LSB | 61 | dep $X[$i&0xf]=$X[$i&0xf],tmp2,8,8 };; |
66 | dep tmp1=tmp0,tmp1,8,8 };; | ||
67 | { .mii; cmp.ne p16,p0=r0,r0 // no misaligned prefetch | ||
68 | dep $X[$i&0xf]=tmp2,$X[$i&0xf],8,8;; | ||
69 | dep $X[$i&0xf]=tmp1,$X[$i&0xf],16,16 };; | ||
70 | { .mmi; nop.m 0 | ||
71 | ___ | ||
72 | } | ||
73 | elsif ($i<15) { | ||
74 | $code.=<<___; | ||
75 | { .mmi; ld4 $X[($i+1)&0xf]=[inp],4 // prefetch | ||
76 | ___ | ||
77 | } | ||
78 | else { | ||
79 | $code.=<<___; | ||
80 | { .mmi; nop.m 0 | ||
81 | ___ | 62 | ___ |
82 | } | ||
83 | if ($i<15) { | 63 | if ($i<15) { |
84 | $code.=<<___; | 64 | $code.=<<___; |
85 | and tmp0=$c,$b | 65 | { .mmi; ld1 $X[($i+1)&0xf]=[inp],2 // +1 |
86 | dep.z tmp5=$a,5,27 } // a<<5 | 66 | dep tmp1=tmp0,tmp4,8,8 };; |
67 | { .mmi; ld1 tmp2=[tmp3],2 // +1 | ||
68 | and tmp4=$c,$b | ||
69 | dep $X[$i&0xf]=$X[$i&0xf],tmp1,16,16 } //;; | ||
87 | { .mmi; andcm tmp1=$d,$b | 70 | { .mmi; andcm tmp1=$d,$b |
88 | add tmp4=$e,$K_00_19 };; | 71 | add tmp0=$e,$K_00_19 |
89 | { .mmi; or tmp0=tmp0,tmp1 // F_00_19(b,c,d)=(b&c)|(~b&d) | 72 | dep.z tmp5=$a,5,27 };; // a<<5 |
90 | add $f=tmp4,$X[$i&0xf] // f=xi+e+K_00_19 | 73 | { .mmi; or tmp4=tmp4,tmp1 // F_00_19(b,c,d)=(b&c)|(~b&d) |
74 | add $f=tmp0,$X[$i&0xf] // f=xi+e+K_00_19 | ||
91 | extr.u tmp1=$a,27,5 };; // a>>27 | 75 | extr.u tmp1=$a,27,5 };; // a>>27 |
92 | { .mib; add $f=$f,tmp0 // f+=F_00_19(b,c,d) | 76 | { .mmi; ld1 tmp0=[inp],2 // +1 |
77 | add $f=$f,tmp4 // f+=F_00_19(b,c,d) | ||
93 | shrp $b=tmp6,tmp6,2 } // b=ROTATE(b,30) | 78 | shrp $b=tmp6,tmp6,2 } // b=ROTATE(b,30) |
94 | { .mib; or tmp1=tmp1,tmp5 // ROTATE(a,5) | 79 | { .mmi; ld1 tmp4=[tmp3],2 // +1 |
80 | or tmp5=tmp1,tmp5 // ROTATE(a,5) | ||
95 | mux2 tmp6=$a,0x44 };; // see b in next iteration | 81 | mux2 tmp6=$a,0x44 };; // see b in next iteration |
96 | { .mii; add $f=$f,tmp1 // f+=ROTATE(a,5) | 82 | { .mii; add $f=$f,tmp5 // f+=ROTATE(a,5) |
97 | mux2 $X[$i&0xf]=$X[$i&0xf],0x44 | 83 | dep $X[($i+1)&0xf]=$X[($i+1)&0xf],tmp2,8,8 // +1 |
98 | nop.i 0 };; | 84 | mux2 $X[$i&0xf]=$X[$i&0xf],0x44 } //;; |
99 | 85 | ||
100 | ___ | 86 | ___ |
101 | } | 87 | } |
102 | else { | 88 | else { |
103 | $code.=<<___; | 89 | $code.=<<___; |
104 | and tmp0=$c,$b | 90 | { .mii; and tmp3=$c,$b |
105 | dep.z tmp5=$a,5,27 } // a<<5 ;;? | 91 | dep tmp1=tmp0,tmp4,8,8;; |
92 | dep $X[$i&0xf]=$X[$i&0xf],tmp1,16,16 } //;; | ||
106 | { .mmi; andcm tmp1=$d,$b | 93 | { .mmi; andcm tmp1=$d,$b |
107 | add tmp4=$e,$K_00_19 };; | 94 | add tmp0=$e,$K_00_19 |
108 | { .mmi; or tmp0=tmp0,tmp1 // F_00_19(b,c,d)=(b&c)|(~b&d) | 95 | dep.z tmp5=$a,5,27 };; // a<<5 |
109 | add $f=tmp4,$X[$i&0xf] // f=xi+e+K_00_19 | 96 | { .mmi; or tmp4=tmp3,tmp1 // F_00_19(b,c,d)=(b&c)|(~b&d) |
97 | add $f=tmp0,$X[$i&0xf] // f=xi+e+K_00_19 | ||
110 | extr.u tmp1=$a,27,5 } // a>>27 | 98 | extr.u tmp1=$a,27,5 } // a>>27 |
111 | { .mmi; xor tmp2=$X[($i+0+1)&0xf],$X[($i+2+1)&0xf] // +1 | 99 | { .mmi; xor tmp2=$X[($i+0+1)&0xf],$X[($i+2+1)&0xf] // +1 |
112 | xor tmp3=$X[($i+8+1)&0xf],$X[($i+13+1)&0xf] // +1 | 100 | xor tmp3=$X[($i+8+1)&0xf],$X[($i+13+1)&0xf] // +1 |
113 | nop.i 0 };; | 101 | nop.i 0 };; |
114 | { .mmi; add $f=$f,tmp0 // f+=F_00_19(b,c,d) | 102 | { .mmi; add $f=$f,tmp4 // f+=F_00_19(b,c,d) |
115 | xor tmp2=tmp2,tmp3 // +1 | 103 | xor tmp2=tmp2,tmp3 // +1 |
116 | shrp $b=tmp6,tmp6,2 } // b=ROTATE(b,30) | 104 | shrp $b=tmp6,tmp6,2 } // b=ROTATE(b,30) |
117 | { .mmi; or tmp1=tmp1,tmp5 // ROTATE(a,5) | 105 | { .mmi; or tmp1=tmp1,tmp5 // ROTATE(a,5) |
@@ -190,9 +178,7 @@ $code.=<<___; | |||
190 | extr.u tmp1=$a,27,5 } // a>>27 | 178 | extr.u tmp1=$a,27,5 } // a>>27 |
191 | { .mib; add $f=$f,tmp4 // f+=e+K_20_39 | 179 | { .mib; add $f=$f,tmp4 // f+=e+K_20_39 |
192 | add $h1=$h1,$a };; // wrap up | 180 | add $h1=$h1,$a };; // wrap up |
193 | { .mmi; | 181 | { .mmi; add $f=$f,tmp0 // f+=F_20_39(b,c,d) |
194 | (p16) ld4.s $X[0]=[inp],4 // non-faulting prefetch | ||
195 | add $f=$f,tmp0 // f+=F_20_39(b,c,d) | ||
196 | shrp $b=tmp6,tmp6,2 } // b=ROTATE(b,30) ;;? | 182 | shrp $b=tmp6,tmp6,2 } // b=ROTATE(b,30) ;;? |
197 | { .mmi; or tmp1=tmp1,tmp5 // ROTATE(a,5) | 183 | { .mmi; or tmp1=tmp1,tmp5 // ROTATE(a,5) |
198 | add $h3=$h3,$c };; // wrap up | 184 | add $h3=$h3,$c };; // wrap up |
@@ -245,172 +231,15 @@ tmp3=r11; | |||
245 | ctx=r32; // in0 | 231 | ctx=r32; // in0 |
246 | inp=r33; // in1 | 232 | inp=r33; // in1 |
247 | 233 | ||
248 | // void sha1_block_asm_host_order(SHA_CTX *c,const void *p,size_t num); | 234 | // void sha1_block_data_order(SHA_CTX *c,const void *p,size_t num); |
249 | .global sha1_block_asm_host_order# | 235 | .global sha1_block_data_order# |
250 | .proc sha1_block_asm_host_order# | 236 | .proc sha1_block_data_order# |
251 | .align 32 | 237 | .align 32 |
252 | sha1_block_asm_host_order: | 238 | sha1_block_data_order: |
253 | .prologue | 239 | .prologue |
254 | .fframe 0 | ||
255 | .save ar.pfs,r0 | ||
256 | .save ar.lc,r3 | ||
257 | { .mmi; alloc tmp1=ar.pfs,3,15,0,0 | 240 | { .mmi; alloc tmp1=ar.pfs,3,15,0,0 |
258 | $ADDP tmp0=4,ctx | 241 | $ADDP tmp0=4,ctx |
259 | mov r3=ar.lc } | ||
260 | { .mmi; $ADDP ctx=0,ctx | ||
261 | $ADDP inp=0,inp | ||
262 | mov r2=pr };; | ||
263 | tmp4=in2; | ||
264 | tmp5=loc13; | ||
265 | tmp6=loc14; | ||
266 | .body | ||
267 | { .mlx; ld4 $h0=[ctx],8 | ||
268 | movl $K_00_19=0x5a827999 } | ||
269 | { .mlx; ld4 $h1=[tmp0],8 | ||
270 | movl $K_20_39=0x6ed9eba1 };; | ||
271 | { .mlx; ld4 $h2=[ctx],8 | ||
272 | movl $K_40_59=0x8f1bbcdc } | ||
273 | { .mlx; ld4 $h3=[tmp0] | ||
274 | movl $K_60_79=0xca62c1d6 };; | ||
275 | { .mmi; ld4 $h4=[ctx],-16 | ||
276 | add in2=-1,in2 // adjust num for ar.lc | ||
277 | mov ar.ec=1 };; | ||
278 | { .mmi; ld4 $X[0]=[inp],4 // prefetch | ||
279 | cmp.ne p16,p0=r0,in2 // prefecth at loop end | ||
280 | mov ar.lc=in2 };; // brp.loop.imp: too far | ||
281 | |||
282 | .Lhtop: | ||
283 | { .mmi; mov $A=$h0 | ||
284 | mov $B=$h1 | ||
285 | mux2 tmp6=$h1,0x44 } | ||
286 | { .mmi; mov $C=$h2 | ||
287 | mov $D=$h3 | ||
288 | mov $E=$h4 };; | ||
289 | |||
290 | ___ | ||
291 | |||
292 | &BODY_00_15(\$code, 0,$A,$B,$C,$D,$E,$T); | ||
293 | &BODY_00_15(\$code, 1,$T,$A,$B,$C,$D,$E); | ||
294 | &BODY_00_15(\$code, 2,$E,$T,$A,$B,$C,$D); | ||
295 | &BODY_00_15(\$code, 3,$D,$E,$T,$A,$B,$C); | ||
296 | &BODY_00_15(\$code, 4,$C,$D,$E,$T,$A,$B); | ||
297 | &BODY_00_15(\$code, 5,$B,$C,$D,$E,$T,$A); | ||
298 | &BODY_00_15(\$code, 6,$A,$B,$C,$D,$E,$T); | ||
299 | &BODY_00_15(\$code, 7,$T,$A,$B,$C,$D,$E); | ||
300 | &BODY_00_15(\$code, 8,$E,$T,$A,$B,$C,$D); | ||
301 | &BODY_00_15(\$code, 9,$D,$E,$T,$A,$B,$C); | ||
302 | &BODY_00_15(\$code,10,$C,$D,$E,$T,$A,$B); | ||
303 | &BODY_00_15(\$code,11,$B,$C,$D,$E,$T,$A); | ||
304 | &BODY_00_15(\$code,12,$A,$B,$C,$D,$E,$T); | ||
305 | &BODY_00_15(\$code,13,$T,$A,$B,$C,$D,$E); | ||
306 | &BODY_00_15(\$code,14,$E,$T,$A,$B,$C,$D); | ||
307 | &BODY_00_15(\$code,15,$D,$E,$T,$A,$B,$C); | ||
308 | |||
309 | &BODY_16_19(\$code,16,$C,$D,$E,$T,$A,$B); | ||
310 | &BODY_16_19(\$code,17,$B,$C,$D,$E,$T,$A); | ||
311 | &BODY_16_19(\$code,18,$A,$B,$C,$D,$E,$T); | ||
312 | &BODY_16_19(\$code,19,$T,$A,$B,$C,$D,$E); | ||
313 | |||
314 | &BODY_20_39(\$code,20,$E,$T,$A,$B,$C,$D); | ||
315 | &BODY_20_39(\$code,21,$D,$E,$T,$A,$B,$C); | ||
316 | &BODY_20_39(\$code,22,$C,$D,$E,$T,$A,$B); | ||
317 | &BODY_20_39(\$code,23,$B,$C,$D,$E,$T,$A); | ||
318 | &BODY_20_39(\$code,24,$A,$B,$C,$D,$E,$T); | ||
319 | &BODY_20_39(\$code,25,$T,$A,$B,$C,$D,$E); | ||
320 | &BODY_20_39(\$code,26,$E,$T,$A,$B,$C,$D); | ||
321 | &BODY_20_39(\$code,27,$D,$E,$T,$A,$B,$C); | ||
322 | &BODY_20_39(\$code,28,$C,$D,$E,$T,$A,$B); | ||
323 | &BODY_20_39(\$code,29,$B,$C,$D,$E,$T,$A); | ||
324 | &BODY_20_39(\$code,30,$A,$B,$C,$D,$E,$T); | ||
325 | &BODY_20_39(\$code,31,$T,$A,$B,$C,$D,$E); | ||
326 | &BODY_20_39(\$code,32,$E,$T,$A,$B,$C,$D); | ||
327 | &BODY_20_39(\$code,33,$D,$E,$T,$A,$B,$C); | ||
328 | &BODY_20_39(\$code,34,$C,$D,$E,$T,$A,$B); | ||
329 | &BODY_20_39(\$code,35,$B,$C,$D,$E,$T,$A); | ||
330 | &BODY_20_39(\$code,36,$A,$B,$C,$D,$E,$T); | ||
331 | &BODY_20_39(\$code,37,$T,$A,$B,$C,$D,$E); | ||
332 | &BODY_20_39(\$code,38,$E,$T,$A,$B,$C,$D); | ||
333 | &BODY_20_39(\$code,39,$D,$E,$T,$A,$B,$C); | ||
334 | |||
335 | &BODY_40_59(\$code,40,$C,$D,$E,$T,$A,$B); | ||
336 | &BODY_40_59(\$code,41,$B,$C,$D,$E,$T,$A); | ||
337 | &BODY_40_59(\$code,42,$A,$B,$C,$D,$E,$T); | ||
338 | &BODY_40_59(\$code,43,$T,$A,$B,$C,$D,$E); | ||
339 | &BODY_40_59(\$code,44,$E,$T,$A,$B,$C,$D); | ||
340 | &BODY_40_59(\$code,45,$D,$E,$T,$A,$B,$C); | ||
341 | &BODY_40_59(\$code,46,$C,$D,$E,$T,$A,$B); | ||
342 | &BODY_40_59(\$code,47,$B,$C,$D,$E,$T,$A); | ||
343 | &BODY_40_59(\$code,48,$A,$B,$C,$D,$E,$T); | ||
344 | &BODY_40_59(\$code,49,$T,$A,$B,$C,$D,$E); | ||
345 | &BODY_40_59(\$code,50,$E,$T,$A,$B,$C,$D); | ||
346 | &BODY_40_59(\$code,51,$D,$E,$T,$A,$B,$C); | ||
347 | &BODY_40_59(\$code,52,$C,$D,$E,$T,$A,$B); | ||
348 | &BODY_40_59(\$code,53,$B,$C,$D,$E,$T,$A); | ||
349 | &BODY_40_59(\$code,54,$A,$B,$C,$D,$E,$T); | ||
350 | &BODY_40_59(\$code,55,$T,$A,$B,$C,$D,$E); | ||
351 | &BODY_40_59(\$code,56,$E,$T,$A,$B,$C,$D); | ||
352 | &BODY_40_59(\$code,57,$D,$E,$T,$A,$B,$C); | ||
353 | &BODY_40_59(\$code,58,$C,$D,$E,$T,$A,$B); | ||
354 | &BODY_40_59(\$code,59,$B,$C,$D,$E,$T,$A); | ||
355 | |||
356 | &BODY_60_79(\$code,60,$A,$B,$C,$D,$E,$T); | ||
357 | &BODY_60_79(\$code,61,$T,$A,$B,$C,$D,$E); | ||
358 | &BODY_60_79(\$code,62,$E,$T,$A,$B,$C,$D); | ||
359 | &BODY_60_79(\$code,63,$D,$E,$T,$A,$B,$C); | ||
360 | &BODY_60_79(\$code,64,$C,$D,$E,$T,$A,$B); | ||
361 | &BODY_60_79(\$code,65,$B,$C,$D,$E,$T,$A); | ||
362 | &BODY_60_79(\$code,66,$A,$B,$C,$D,$E,$T); | ||
363 | &BODY_60_79(\$code,67,$T,$A,$B,$C,$D,$E); | ||
364 | &BODY_60_79(\$code,68,$E,$T,$A,$B,$C,$D); | ||
365 | &BODY_60_79(\$code,69,$D,$E,$T,$A,$B,$C); | ||
366 | &BODY_60_79(\$code,70,$C,$D,$E,$T,$A,$B); | ||
367 | &BODY_60_79(\$code,71,$B,$C,$D,$E,$T,$A); | ||
368 | &BODY_60_79(\$code,72,$A,$B,$C,$D,$E,$T); | ||
369 | &BODY_60_79(\$code,73,$T,$A,$B,$C,$D,$E); | ||
370 | &BODY_60_79(\$code,74,$E,$T,$A,$B,$C,$D); | ||
371 | &BODY_60_79(\$code,75,$D,$E,$T,$A,$B,$C); | ||
372 | &BODY_60_79(\$code,76,$C,$D,$E,$T,$A,$B); | ||
373 | &BODY_60_79(\$code,77,$B,$C,$D,$E,$T,$A); | ||
374 | &BODY_60_79(\$code,78,$A,$B,$C,$D,$E,$T); | ||
375 | &BODY_60_79(\$code,79,$T,$A,$B,$C,$D,$E); | ||
376 | |||
377 | $code.=<<___; | ||
378 | { .mmb; add $h0=$h0,$E | ||
379 | nop.m 0 | ||
380 | br.ctop.dptk.many .Lhtop };; | ||
381 | .Lhend: | ||
382 | { .mmi; add tmp0=4,ctx | ||
383 | mov ar.lc=r3 };; | ||
384 | { .mmi; st4 [ctx]=$h0,8 | ||
385 | st4 [tmp0]=$h1,8 };; | ||
386 | { .mmi; st4 [ctx]=$h2,8 | ||
387 | st4 [tmp0]=$h3 };; | ||
388 | { .mib; st4 [ctx]=$h4,-16 | ||
389 | mov pr=r2,0x1ffff | ||
390 | br.ret.sptk.many b0 };; | ||
391 | .endp sha1_block_asm_host_order# | ||
392 | ___ | ||
393 | |||
394 | |||
395 | $code.=<<___; | ||
396 | // void sha1_block_asm_data_order(SHA_CTX *c,const void *p,size_t num); | ||
397 | .global sha1_block_asm_data_order# | ||
398 | .proc sha1_block_asm_data_order# | ||
399 | .align 32 | ||
400 | sha1_block_asm_data_order: | ||
401 | ___ | ||
402 | $code.=<<___ if ($big_endian); | ||
403 | { .mmi; and r2=3,inp };; | ||
404 | { .mib; cmp.eq p6,p0=r0,r2 | ||
405 | (p6) br.dptk.many sha1_block_asm_host_order };; | ||
406 | ___ | ||
407 | $code.=<<___; | ||
408 | .prologue | ||
409 | .fframe 0 | ||
410 | .save ar.pfs,r0 | ||
411 | .save ar.lc,r3 | 242 | .save ar.lc,r3 |
412 | { .mmi; alloc tmp1=ar.pfs,3,15,0,0 | ||
413 | $ADDP tmp0=4,ctx | ||
414 | mov r3=ar.lc } | 243 | mov r3=ar.lc } |
415 | { .mmi; $ADDP ctx=0,ctx | 244 | { .mmi; $ADDP ctx=0,ctx |
416 | $ADDP inp=0,inp | 245 | $ADDP inp=0,inp |
@@ -444,90 +273,16 @@ tmp6=loc14; | |||
444 | 273 | ||
445 | ___ | 274 | ___ |
446 | 275 | ||
447 | &BODY_00_15(\$code, 0,$A,$B,$C,$D,$E,$T,1); | 276 | { my $i,@V=($A,$B,$C,$D,$E,$T); |
448 | &BODY_00_15(\$code, 1,$T,$A,$B,$C,$D,$E,1); | ||
449 | &BODY_00_15(\$code, 2,$E,$T,$A,$B,$C,$D,1); | ||
450 | &BODY_00_15(\$code, 3,$D,$E,$T,$A,$B,$C,1); | ||
451 | &BODY_00_15(\$code, 4,$C,$D,$E,$T,$A,$B,1); | ||
452 | &BODY_00_15(\$code, 5,$B,$C,$D,$E,$T,$A,1); | ||
453 | &BODY_00_15(\$code, 6,$A,$B,$C,$D,$E,$T,1); | ||
454 | &BODY_00_15(\$code, 7,$T,$A,$B,$C,$D,$E,1); | ||
455 | &BODY_00_15(\$code, 8,$E,$T,$A,$B,$C,$D,1); | ||
456 | &BODY_00_15(\$code, 9,$D,$E,$T,$A,$B,$C,1); | ||
457 | &BODY_00_15(\$code,10,$C,$D,$E,$T,$A,$B,1); | ||
458 | &BODY_00_15(\$code,11,$B,$C,$D,$E,$T,$A,1); | ||
459 | &BODY_00_15(\$code,12,$A,$B,$C,$D,$E,$T,1); | ||
460 | &BODY_00_15(\$code,13,$T,$A,$B,$C,$D,$E,1); | ||
461 | &BODY_00_15(\$code,14,$E,$T,$A,$B,$C,$D,1); | ||
462 | &BODY_00_15(\$code,15,$D,$E,$T,$A,$B,$C,1); | ||
463 | |||
464 | &BODY_16_19(\$code,16,$C,$D,$E,$T,$A,$B); | ||
465 | &BODY_16_19(\$code,17,$B,$C,$D,$E,$T,$A); | ||
466 | &BODY_16_19(\$code,18,$A,$B,$C,$D,$E,$T); | ||
467 | &BODY_16_19(\$code,19,$T,$A,$B,$C,$D,$E); | ||
468 | 277 | ||
469 | &BODY_20_39(\$code,20,$E,$T,$A,$B,$C,$D); | 278 | for($i=0;$i<16;$i++) { &BODY_00_15(\$code,$i,@V); unshift(@V,pop(@V)); } |
470 | &BODY_20_39(\$code,21,$D,$E,$T,$A,$B,$C); | 279 | for(;$i<20;$i++) { &BODY_16_19(\$code,$i,@V); unshift(@V,pop(@V)); } |
471 | &BODY_20_39(\$code,22,$C,$D,$E,$T,$A,$B); | 280 | for(;$i<40;$i++) { &BODY_20_39(\$code,$i,@V); unshift(@V,pop(@V)); } |
472 | &BODY_20_39(\$code,23,$B,$C,$D,$E,$T,$A); | 281 | for(;$i<60;$i++) { &BODY_40_59(\$code,$i,@V); unshift(@V,pop(@V)); } |
473 | &BODY_20_39(\$code,24,$A,$B,$C,$D,$E,$T); | 282 | for(;$i<80;$i++) { &BODY_60_79(\$code,$i,@V); unshift(@V,pop(@V)); } |
474 | &BODY_20_39(\$code,25,$T,$A,$B,$C,$D,$E); | ||
475 | &BODY_20_39(\$code,26,$E,$T,$A,$B,$C,$D); | ||
476 | &BODY_20_39(\$code,27,$D,$E,$T,$A,$B,$C); | ||
477 | &BODY_20_39(\$code,28,$C,$D,$E,$T,$A,$B); | ||
478 | &BODY_20_39(\$code,29,$B,$C,$D,$E,$T,$A); | ||
479 | &BODY_20_39(\$code,30,$A,$B,$C,$D,$E,$T); | ||
480 | &BODY_20_39(\$code,31,$T,$A,$B,$C,$D,$E); | ||
481 | &BODY_20_39(\$code,32,$E,$T,$A,$B,$C,$D); | ||
482 | &BODY_20_39(\$code,33,$D,$E,$T,$A,$B,$C); | ||
483 | &BODY_20_39(\$code,34,$C,$D,$E,$T,$A,$B); | ||
484 | &BODY_20_39(\$code,35,$B,$C,$D,$E,$T,$A); | ||
485 | &BODY_20_39(\$code,36,$A,$B,$C,$D,$E,$T); | ||
486 | &BODY_20_39(\$code,37,$T,$A,$B,$C,$D,$E); | ||
487 | &BODY_20_39(\$code,38,$E,$T,$A,$B,$C,$D); | ||
488 | &BODY_20_39(\$code,39,$D,$E,$T,$A,$B,$C); | ||
489 | 283 | ||
490 | &BODY_40_59(\$code,40,$C,$D,$E,$T,$A,$B); | 284 | (($V[5] eq $D) and ($V[0] eq $E)) or die; # double-check |
491 | &BODY_40_59(\$code,41,$B,$C,$D,$E,$T,$A); | 285 | } |
492 | &BODY_40_59(\$code,42,$A,$B,$C,$D,$E,$T); | ||
493 | &BODY_40_59(\$code,43,$T,$A,$B,$C,$D,$E); | ||
494 | &BODY_40_59(\$code,44,$E,$T,$A,$B,$C,$D); | ||
495 | &BODY_40_59(\$code,45,$D,$E,$T,$A,$B,$C); | ||
496 | &BODY_40_59(\$code,46,$C,$D,$E,$T,$A,$B); | ||
497 | &BODY_40_59(\$code,47,$B,$C,$D,$E,$T,$A); | ||
498 | &BODY_40_59(\$code,48,$A,$B,$C,$D,$E,$T); | ||
499 | &BODY_40_59(\$code,49,$T,$A,$B,$C,$D,$E); | ||
500 | &BODY_40_59(\$code,50,$E,$T,$A,$B,$C,$D); | ||
501 | &BODY_40_59(\$code,51,$D,$E,$T,$A,$B,$C); | ||
502 | &BODY_40_59(\$code,52,$C,$D,$E,$T,$A,$B); | ||
503 | &BODY_40_59(\$code,53,$B,$C,$D,$E,$T,$A); | ||
504 | &BODY_40_59(\$code,54,$A,$B,$C,$D,$E,$T); | ||
505 | &BODY_40_59(\$code,55,$T,$A,$B,$C,$D,$E); | ||
506 | &BODY_40_59(\$code,56,$E,$T,$A,$B,$C,$D); | ||
507 | &BODY_40_59(\$code,57,$D,$E,$T,$A,$B,$C); | ||
508 | &BODY_40_59(\$code,58,$C,$D,$E,$T,$A,$B); | ||
509 | &BODY_40_59(\$code,59,$B,$C,$D,$E,$T,$A); | ||
510 | |||
511 | &BODY_60_79(\$code,60,$A,$B,$C,$D,$E,$T); | ||
512 | &BODY_60_79(\$code,61,$T,$A,$B,$C,$D,$E); | ||
513 | &BODY_60_79(\$code,62,$E,$T,$A,$B,$C,$D); | ||
514 | &BODY_60_79(\$code,63,$D,$E,$T,$A,$B,$C); | ||
515 | &BODY_60_79(\$code,64,$C,$D,$E,$T,$A,$B); | ||
516 | &BODY_60_79(\$code,65,$B,$C,$D,$E,$T,$A); | ||
517 | &BODY_60_79(\$code,66,$A,$B,$C,$D,$E,$T); | ||
518 | &BODY_60_79(\$code,67,$T,$A,$B,$C,$D,$E); | ||
519 | &BODY_60_79(\$code,68,$E,$T,$A,$B,$C,$D); | ||
520 | &BODY_60_79(\$code,69,$D,$E,$T,$A,$B,$C); | ||
521 | &BODY_60_79(\$code,70,$C,$D,$E,$T,$A,$B); | ||
522 | &BODY_60_79(\$code,71,$B,$C,$D,$E,$T,$A); | ||
523 | &BODY_60_79(\$code,72,$A,$B,$C,$D,$E,$T); | ||
524 | &BODY_60_79(\$code,73,$T,$A,$B,$C,$D,$E); | ||
525 | &BODY_60_79(\$code,74,$E,$T,$A,$B,$C,$D); | ||
526 | &BODY_60_79(\$code,75,$D,$E,$T,$A,$B,$C); | ||
527 | &BODY_60_79(\$code,76,$C,$D,$E,$T,$A,$B); | ||
528 | &BODY_60_79(\$code,77,$B,$C,$D,$E,$T,$A); | ||
529 | &BODY_60_79(\$code,78,$A,$B,$C,$D,$E,$T); | ||
530 | &BODY_60_79(\$code,79,$T,$A,$B,$C,$D,$E); | ||
531 | 286 | ||
532 | $code.=<<___; | 287 | $code.=<<___; |
533 | { .mmb; add $h0=$h0,$E | 288 | { .mmb; add $h0=$h0,$E |
@@ -543,7 +298,8 @@ $code.=<<___; | |||
543 | { .mib; st4 [ctx]=$h4,-16 | 298 | { .mib; st4 [ctx]=$h4,-16 |
544 | mov pr=r2,0x1ffff | 299 | mov pr=r2,0x1ffff |
545 | br.ret.sptk.many b0 };; | 300 | br.ret.sptk.many b0 };; |
546 | .endp sha1_block_asm_data_order# | 301 | .endp sha1_block_data_order# |
302 | stringz "SHA1 block transform for IA64, CRYPTOGAMS by <appro\@openssl.org>" | ||
547 | ___ | 303 | ___ |
548 | 304 | ||
549 | print $code; | 305 | print $code; |
diff --git a/src/lib/libcrypto/sha/asm/sha1-x86_64.pl b/src/lib/libcrypto/sha/asm/sha1-x86_64.pl new file mode 100755 index 0000000000..f7ed67a726 --- /dev/null +++ b/src/lib/libcrypto/sha/asm/sha1-x86_64.pl | |||
@@ -0,0 +1,242 @@ | |||
1 | #!/usr/bin/env perl | ||
2 | # | ||
3 | # ==================================================================== | ||
4 | # Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL | ||
5 | # project. The module is, however, dual licensed under OpenSSL and | ||
6 | # CRYPTOGAMS licenses depending on where you obtain it. For further | ||
7 | # details see http://www.openssl.org/~appro/cryptogams/. | ||
8 | # ==================================================================== | ||
9 | # | ||
10 | # sha1_block procedure for x86_64. | ||
11 | # | ||
12 | # It was brought to my attention that on EM64T compiler-generated code | ||
13 | # was far behind 32-bit assembler implementation. This is unlike on | ||
14 | # Opteron where compiler-generated code was only 15% behind 32-bit | ||
15 | # assembler, which originally made it hard to motivate the effort. | ||
16 | # There was suggestion to mechanically translate 32-bit code, but I | ||
17 | # dismissed it, reasoning that x86_64 offers enough register bank | ||
18 | # capacity to fully utilize SHA-1 parallelism. Therefore this fresh | ||
19 | # implementation:-) However! While 64-bit code does performs better | ||
20 | # on Opteron, I failed to beat 32-bit assembler on EM64T core. Well, | ||
21 | # x86_64 does offer larger *addressable* bank, but out-of-order core | ||
22 | # reaches for even more registers through dynamic aliasing, and EM64T | ||
23 | # core must have managed to run-time optimize even 32-bit code just as | ||
24 | # good as 64-bit one. Performance improvement is summarized in the | ||
25 | # following table: | ||
26 | # | ||
27 | # gcc 3.4 32-bit asm cycles/byte | ||
28 | # Opteron +45% +20% 6.8 | ||
29 | # Xeon P4 +65% +0% 9.9 | ||
30 | # Core2 +60% +10% 7.0 | ||
31 | |||
32 | $output=shift; | ||
33 | |||
34 | $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; | ||
35 | ( $xlate="${dir}x86_64-xlate.pl" and -f $xlate ) or | ||
36 | ( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or | ||
37 | die "can't locate x86_64-xlate.pl"; | ||
38 | |||
39 | open STDOUT,"| $^X $xlate $output"; | ||
40 | |||
41 | $ctx="%rdi"; # 1st arg | ||
42 | $inp="%rsi"; # 2nd arg | ||
43 | $num="%rdx"; # 3rd arg | ||
44 | |||
45 | # reassign arguments in order to produce more compact code | ||
46 | $ctx="%r8"; | ||
47 | $inp="%r9"; | ||
48 | $num="%r10"; | ||
49 | |||
50 | $xi="%eax"; | ||
51 | $t0="%ebx"; | ||
52 | $t1="%ecx"; | ||
53 | $A="%edx"; | ||
54 | $B="%esi"; | ||
55 | $C="%edi"; | ||
56 | $D="%ebp"; | ||
57 | $E="%r11d"; | ||
58 | $T="%r12d"; | ||
59 | |||
60 | @V=($A,$B,$C,$D,$E,$T); | ||
61 | |||
62 | sub PROLOGUE { | ||
63 | my $func=shift; | ||
64 | $code.=<<___; | ||
65 | .globl $func | ||
66 | .type $func,\@function,3 | ||
67 | .align 16 | ||
68 | $func: | ||
69 | push %rbx | ||
70 | push %rbp | ||
71 | push %r12 | ||
72 | mov %rsp,%rax | ||
73 | mov %rdi,$ctx # reassigned argument | ||
74 | sub \$`8+16*4`,%rsp | ||
75 | mov %rsi,$inp # reassigned argument | ||
76 | and \$-64,%rsp | ||
77 | mov %rdx,$num # reassigned argument | ||
78 | mov %rax,`16*4`(%rsp) | ||
79 | |||
80 | mov 0($ctx),$A | ||
81 | mov 4($ctx),$B | ||
82 | mov 8($ctx),$C | ||
83 | mov 12($ctx),$D | ||
84 | mov 16($ctx),$E | ||
85 | ___ | ||
86 | } | ||
87 | |||
88 | sub EPILOGUE { | ||
89 | my $func=shift; | ||
90 | $code.=<<___; | ||
91 | mov `16*4`(%rsp),%rsp | ||
92 | pop %r12 | ||
93 | pop %rbp | ||
94 | pop %rbx | ||
95 | ret | ||
96 | .size $func,.-$func | ||
97 | ___ | ||
98 | } | ||
99 | |||
100 | sub BODY_00_19 { | ||
101 | my ($i,$a,$b,$c,$d,$e,$f,$host)=@_; | ||
102 | my $j=$i+1; | ||
103 | $code.=<<___ if ($i==0); | ||
104 | mov `4*$i`($inp),$xi | ||
105 | `"bswap $xi" if(!defined($host))` | ||
106 | mov $xi,`4*$i`(%rsp) | ||
107 | ___ | ||
108 | $code.=<<___ if ($i<15); | ||
109 | lea 0x5a827999($xi,$e),$f | ||
110 | mov $c,$t0 | ||
111 | mov `4*$j`($inp),$xi | ||
112 | mov $a,$e | ||
113 | xor $d,$t0 | ||
114 | `"bswap $xi" if(!defined($host))` | ||
115 | rol \$5,$e | ||
116 | and $b,$t0 | ||
117 | mov $xi,`4*$j`(%rsp) | ||
118 | add $e,$f | ||
119 | xor $d,$t0 | ||
120 | rol \$30,$b | ||
121 | add $t0,$f | ||
122 | ___ | ||
123 | $code.=<<___ if ($i>=15); | ||
124 | lea 0x5a827999($xi,$e),$f | ||
125 | mov `4*($j%16)`(%rsp),$xi | ||
126 | mov $c,$t0 | ||
127 | mov $a,$e | ||
128 | xor `4*(($j+2)%16)`(%rsp),$xi | ||
129 | xor $d,$t0 | ||
130 | rol \$5,$e | ||
131 | xor `4*(($j+8)%16)`(%rsp),$xi | ||
132 | and $b,$t0 | ||
133 | add $e,$f | ||
134 | xor `4*(($j+13)%16)`(%rsp),$xi | ||
135 | xor $d,$t0 | ||
136 | rol \$30,$b | ||
137 | add $t0,$f | ||
138 | rol \$1,$xi | ||
139 | mov $xi,`4*($j%16)`(%rsp) | ||
140 | ___ | ||
141 | } | ||
142 | |||
143 | sub BODY_20_39 { | ||
144 | my ($i,$a,$b,$c,$d,$e,$f)=@_; | ||
145 | my $j=$i+1; | ||
146 | my $K=($i<40)?0x6ed9eba1:0xca62c1d6; | ||
147 | $code.=<<___ if ($i<79); | ||
148 | lea $K($xi,$e),$f | ||
149 | mov `4*($j%16)`(%rsp),$xi | ||
150 | mov $c,$t0 | ||
151 | mov $a,$e | ||
152 | xor `4*(($j+2)%16)`(%rsp),$xi | ||
153 | xor $b,$t0 | ||
154 | rol \$5,$e | ||
155 | xor `4*(($j+8)%16)`(%rsp),$xi | ||
156 | xor $d,$t0 | ||
157 | add $e,$f | ||
158 | xor `4*(($j+13)%16)`(%rsp),$xi | ||
159 | rol \$30,$b | ||
160 | add $t0,$f | ||
161 | rol \$1,$xi | ||
162 | ___ | ||
163 | $code.=<<___ if ($i<76); | ||
164 | mov $xi,`4*($j%16)`(%rsp) | ||
165 | ___ | ||
166 | $code.=<<___ if ($i==79); | ||
167 | lea $K($xi,$e),$f | ||
168 | mov $c,$t0 | ||
169 | mov $a,$e | ||
170 | xor $b,$t0 | ||
171 | rol \$5,$e | ||
172 | xor $d,$t0 | ||
173 | add $e,$f | ||
174 | rol \$30,$b | ||
175 | add $t0,$f | ||
176 | ___ | ||
177 | } | ||
178 | |||
179 | sub BODY_40_59 { | ||
180 | my ($i,$a,$b,$c,$d,$e,$f)=@_; | ||
181 | my $j=$i+1; | ||
182 | $code.=<<___; | ||
183 | lea 0x8f1bbcdc($xi,$e),$f | ||
184 | mov `4*($j%16)`(%rsp),$xi | ||
185 | mov $b,$t0 | ||
186 | mov $b,$t1 | ||
187 | xor `4*(($j+2)%16)`(%rsp),$xi | ||
188 | mov $a,$e | ||
189 | and $c,$t0 | ||
190 | xor `4*(($j+8)%16)`(%rsp),$xi | ||
191 | or $c,$t1 | ||
192 | rol \$5,$e | ||
193 | xor `4*(($j+13)%16)`(%rsp),$xi | ||
194 | and $d,$t1 | ||
195 | add $e,$f | ||
196 | rol \$1,$xi | ||
197 | or $t1,$t0 | ||
198 | rol \$30,$b | ||
199 | mov $xi,`4*($j%16)`(%rsp) | ||
200 | add $t0,$f | ||
201 | ___ | ||
202 | } | ||
203 | |||
204 | $code=".text\n"; | ||
205 | |||
206 | &PROLOGUE("sha1_block_data_order"); | ||
207 | $code.=".align 4\n.Lloop:\n"; | ||
208 | for($i=0;$i<20;$i++) { &BODY_00_19($i,@V); unshift(@V,pop(@V)); } | ||
209 | for(;$i<40;$i++) { &BODY_20_39($i,@V); unshift(@V,pop(@V)); } | ||
210 | for(;$i<60;$i++) { &BODY_40_59($i,@V); unshift(@V,pop(@V)); } | ||
211 | for(;$i<80;$i++) { &BODY_20_39($i,@V); unshift(@V,pop(@V)); } | ||
212 | $code.=<<___; | ||
213 | add 0($ctx),$E | ||
214 | add 4($ctx),$T | ||
215 | add 8($ctx),$A | ||
216 | add 12($ctx),$B | ||
217 | add 16($ctx),$C | ||
218 | mov $E,0($ctx) | ||
219 | mov $T,4($ctx) | ||
220 | mov $A,8($ctx) | ||
221 | mov $B,12($ctx) | ||
222 | mov $C,16($ctx) | ||
223 | |||
224 | xchg $E,$A # mov $E,$A | ||
225 | xchg $T,$B # mov $T,$B | ||
226 | xchg $E,$C # mov $A,$C | ||
227 | xchg $T,$D # mov $B,$D | ||
228 | # mov $C,$E | ||
229 | lea `16*4`($inp),$inp | ||
230 | sub \$1,$num | ||
231 | jnz .Lloop | ||
232 | ___ | ||
233 | &EPILOGUE("sha1_block_data_order"); | ||
234 | $code.=<<___; | ||
235 | .asciz "SHA1 block transform for x86_64, CRYPTOGAMS by <appro\@openssl.org>" | ||
236 | ___ | ||
237 | |||
238 | #################################################################### | ||
239 | |||
240 | $code =~ s/\`([^\`]*)\`/eval $1/gem; | ||
241 | print $code; | ||
242 | close STDOUT; | ||
diff --git a/src/lib/libcrypto/sha/asm/sha512-ia64.pl b/src/lib/libcrypto/sha/asm/sha512-ia64.pl new file mode 100755 index 0000000000..1c6ce56522 --- /dev/null +++ b/src/lib/libcrypto/sha/asm/sha512-ia64.pl | |||
@@ -0,0 +1,672 @@ | |||
1 | #!/usr/bin/env perl | ||
2 | # | ||
3 | # ==================================================================== | ||
4 | # Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL | ||
5 | # project. The module is, however, dual licensed under OpenSSL and | ||
6 | # CRYPTOGAMS licenses depending on where you obtain it. For further | ||
7 | # details see http://www.openssl.org/~appro/cryptogams/. | ||
8 | # ==================================================================== | ||
9 | # | ||
10 | # SHA256/512_Transform for Itanium. | ||
11 | # | ||
12 | # sha512_block runs in 1003 cycles on Itanium 2, which is almost 50% | ||
13 | # faster than gcc and >60%(!) faster than code generated by HP-UX | ||
14 | # compiler (yes, HP-UX is generating slower code, because unlike gcc, | ||
15 | # it failed to deploy "shift right pair," 'shrp' instruction, which | ||
16 | # substitutes for 64-bit rotate). | ||
17 | # | ||
18 | # 924 cycles long sha256_block outperforms gcc by over factor of 2(!) | ||
19 | # and HP-UX compiler - by >40% (yes, gcc won sha512_block, but lost | ||
20 | # this one big time). Note that "formally" 924 is about 100 cycles | ||
21 | # too much. I mean it's 64 32-bit rounds vs. 80 virtually identical | ||
22 | # 64-bit ones and 1003*64/80 gives 802. Extra cycles, 2 per round, | ||
23 | # are spent on extra work to provide for 32-bit rotations. 32-bit | ||
24 | # rotations are still handled by 'shrp' instruction and for this | ||
25 | # reason lower 32 bits are deposited to upper half of 64-bit register | ||
26 | # prior 'shrp' issue. And in order to minimize the amount of such | ||
27 | # operations, X[16] values are *maintained* with copies of lower | ||
28 | # halves in upper halves, which is why you'll spot such instructions | ||
29 | # as custom 'mux2', "parallel 32-bit add," 'padd4' and "parallel | ||
30 | # 32-bit unsigned right shift," 'pshr4.u' instructions here. | ||
31 | # | ||
32 | # Rules of engagement. | ||
33 | # | ||
34 | # There is only one integer shifter meaning that if I have two rotate, | ||
35 | # deposit or extract instructions in adjacent bundles, they shall | ||
36 | # split [at run-time if they have to]. But note that variable and | ||
37 | # parallel shifts are performed by multi-media ALU and *are* pairable | ||
38 | # with rotates [and alike]. On the backside MMALU is rather slow: it | ||
39 | # takes 2 extra cycles before the result of integer operation is | ||
40 | # available *to* MMALU and 2(*) extra cycles before the result of MM | ||
41 | # operation is available "back" *to* integer ALU, not to mention that | ||
42 | # MMALU itself has 2 cycles latency. However! I explicitly scheduled | ||
43 | # these MM instructions to avoid MM stalls, so that all these extra | ||
44 | # latencies get "hidden" in instruction-level parallelism. | ||
45 | # | ||
46 | # (*) 2 cycles on Itanium 1 and 1 cycle on Itanium 2. But I schedule | ||
47 | # for 2 in order to provide for best *overall* performance, | ||
48 | # because on Itanium 1 stall on MM result is accompanied by | ||
49 | # pipeline flush, which takes 6 cycles:-( | ||
50 | # | ||
51 | # Resulting performance numbers for 900MHz Itanium 2 system: | ||
52 | # | ||
53 | # The 'numbers' are in 1000s of bytes per second processed. | ||
54 | # type 16 bytes 64 bytes 256 bytes 1024 bytes 8192 bytes | ||
55 | # sha1(*) 6210.14k 20376.30k 52447.83k 85870.05k 105478.12k | ||
56 | # sha256 7476.45k 20572.05k 41538.34k 56062.29k 62093.18k | ||
57 | # sha512 4996.56k 20026.28k 47597.20k 85278.79k 111501.31k | ||
58 | # | ||
59 | # (*) SHA1 numbers are for HP-UX compiler and are presented purely | ||
60 | # for reference purposes. I bet it can improved too... | ||
61 | # | ||
62 | # To generate code, pass the file name with either 256 or 512 in its | ||
63 | # name and compiler flags. | ||
64 | |||
65 | $output=shift; | ||
66 | |||
67 | if ($output =~ /512.*\.[s|asm]/) { | ||
68 | $SZ=8; | ||
69 | $BITS=8*$SZ; | ||
70 | $LDW="ld8"; | ||
71 | $STW="st8"; | ||
72 | $ADD="add"; | ||
73 | $SHRU="shr.u"; | ||
74 | $TABLE="K512"; | ||
75 | $func="sha512_block_data_order"; | ||
76 | @Sigma0=(28,34,39); | ||
77 | @Sigma1=(14,18,41); | ||
78 | @sigma0=(1, 8, 7); | ||
79 | @sigma1=(19,61, 6); | ||
80 | $rounds=80; | ||
81 | } elsif ($output =~ /256.*\.[s|asm]/) { | ||
82 | $SZ=4; | ||
83 | $BITS=8*$SZ; | ||
84 | $LDW="ld4"; | ||
85 | $STW="st4"; | ||
86 | $ADD="padd4"; | ||
87 | $SHRU="pshr4.u"; | ||
88 | $TABLE="K256"; | ||
89 | $func="sha256_block_data_order"; | ||
90 | @Sigma0=( 2,13,22); | ||
91 | @Sigma1=( 6,11,25); | ||
92 | @sigma0=( 7,18, 3); | ||
93 | @sigma1=(17,19,10); | ||
94 | $rounds=64; | ||
95 | } else { die "nonsense $output"; } | ||
96 | |||
97 | open STDOUT,">$output" || die "can't open $output: $!"; | ||
98 | |||
99 | if ($^O eq "hpux") { | ||
100 | $ADDP="addp4"; | ||
101 | for (@ARGV) { $ADDP="add" if (/[\+DD|\-mlp]64/); } | ||
102 | } else { $ADDP="add"; } | ||
103 | for (@ARGV) { $big_endian=1 if (/\-DB_ENDIAN/); | ||
104 | $big_endian=0 if (/\-DL_ENDIAN/); } | ||
105 | if (!defined($big_endian)) | ||
106 | { $big_endian=(unpack('L',pack('N',1))==1); } | ||
107 | |||
108 | $code=<<___; | ||
109 | .ident \"$output, version 1.1\" | ||
110 | .ident \"IA-64 ISA artwork by Andy Polyakov <appro\@fy.chalmers.se>\" | ||
111 | .explicit | ||
112 | .text | ||
113 | |||
114 | pfssave=r2; | ||
115 | lcsave=r3; | ||
116 | prsave=r14; | ||
117 | K=r15; | ||
118 | A=r16; B=r17; C=r18; D=r19; | ||
119 | E=r20; F=r21; G=r22; H=r23; | ||
120 | T1=r24; T2=r25; | ||
121 | s0=r26; s1=r27; t0=r28; t1=r29; | ||
122 | Ktbl=r30; | ||
123 | ctx=r31; // 1st arg | ||
124 | input=r48; // 2nd arg | ||
125 | num=r49; // 3rd arg | ||
126 | sgm0=r50; sgm1=r51; // small constants | ||
127 | A_=r54; B_=r55; C_=r56; D_=r57; | ||
128 | E_=r58; F_=r59; G_=r60; H_=r61; | ||
129 | |||
130 | // void $func (SHA_CTX *ctx, const void *in,size_t num[,int host]) | ||
131 | .global $func# | ||
132 | .proc $func# | ||
133 | .align 32 | ||
134 | $func: | ||
135 | .prologue | ||
136 | .save ar.pfs,pfssave | ||
137 | { .mmi; alloc pfssave=ar.pfs,3,27,0,16 | ||
138 | $ADDP ctx=0,r32 // 1st arg | ||
139 | .save ar.lc,lcsave | ||
140 | mov lcsave=ar.lc } | ||
141 | { .mmi; $ADDP input=0,r33 // 2nd arg | ||
142 | mov num=r34 // 3rd arg | ||
143 | .save pr,prsave | ||
144 | mov prsave=pr };; | ||
145 | |||
146 | .body | ||
147 | { .mib; add r8=0*$SZ,ctx | ||
148 | add r9=1*$SZ,ctx | ||
149 | brp.loop.imp .L_first16,.L_first16_end-16 } | ||
150 | { .mib; add r10=2*$SZ,ctx | ||
151 | add r11=3*$SZ,ctx | ||
152 | brp.loop.imp .L_rest,.L_rest_end-16 };; | ||
153 | |||
154 | // load A-H | ||
155 | .Lpic_point: | ||
156 | { .mmi; $LDW A_=[r8],4*$SZ | ||
157 | $LDW B_=[r9],4*$SZ | ||
158 | mov Ktbl=ip } | ||
159 | { .mmi; $LDW C_=[r10],4*$SZ | ||
160 | $LDW D_=[r11],4*$SZ | ||
161 | mov sgm0=$sigma0[2] };; | ||
162 | { .mmi; $LDW E_=[r8] | ||
163 | $LDW F_=[r9] | ||
164 | add Ktbl=($TABLE#-.Lpic_point),Ktbl } | ||
165 | { .mmi; $LDW G_=[r10] | ||
166 | $LDW H_=[r11] | ||
167 | cmp.ne p0,p16=0,r0 };; // used in sha256_block | ||
168 | ___ | ||
169 | $code.=<<___ if ($BITS==64); | ||
170 | { .mii; and r8=7,input | ||
171 | and input=~7,input;; | ||
172 | cmp.eq p9,p0=1,r8 } | ||
173 | { .mmi; cmp.eq p10,p0=2,r8 | ||
174 | cmp.eq p11,p0=3,r8 | ||
175 | cmp.eq p12,p0=4,r8 } | ||
176 | { .mmi; cmp.eq p13,p0=5,r8 | ||
177 | cmp.eq p14,p0=6,r8 | ||
178 | cmp.eq p15,p0=7,r8 };; | ||
179 | ___ | ||
180 | $code.=<<___; | ||
181 | .L_outer: | ||
182 | .rotr X[16] | ||
183 | { .mmi; mov A=A_ | ||
184 | mov B=B_ | ||
185 | mov ar.lc=14 } | ||
186 | { .mmi; mov C=C_ | ||
187 | mov D=D_ | ||
188 | mov E=E_ } | ||
189 | { .mmi; mov F=F_ | ||
190 | mov G=G_ | ||
191 | mov ar.ec=2 } | ||
192 | { .mmi; ld1 X[15]=[input],$SZ // eliminated in 64-bit | ||
193 | mov H=H_ | ||
194 | mov sgm1=$sigma1[2] };; | ||
195 | |||
196 | ___ | ||
197 | $t0="t0", $t1="t1", $code.=<<___ if ($BITS==32); | ||
198 | .align 32 | ||
199 | .L_first16: | ||
200 | { .mmi; add r9=1-$SZ,input | ||
201 | add r10=2-$SZ,input | ||
202 | add r11=3-$SZ,input };; | ||
203 | { .mmi; ld1 r9=[r9] | ||
204 | ld1 r10=[r10] | ||
205 | dep.z $t1=E,32,32 } | ||
206 | { .mmi; $LDW K=[Ktbl],$SZ | ||
207 | ld1 r11=[r11] | ||
208 | zxt4 E=E };; | ||
209 | { .mii; or $t1=$t1,E | ||
210 | dep X[15]=X[15],r9,8,8 | ||
211 | dep r11=r10,r11,8,8 };; | ||
212 | { .mmi; and T1=F,E | ||
213 | and T2=A,B | ||
214 | dep X[15]=X[15],r11,16,16 } | ||
215 | { .mmi; andcm r8=G,E | ||
216 | and r9=A,C | ||
217 | mux2 $t0=A,0x44 };; // copy lower half to upper | ||
218 | { .mmi; (p16) ld1 X[15-1]=[input],$SZ // prefetch | ||
219 | xor T1=T1,r8 // T1=((e & f) ^ (~e & g)) | ||
220 | _rotr r11=$t1,$Sigma1[0] } // ROTR(e,14) | ||
221 | { .mib; and r10=B,C | ||
222 | xor T2=T2,r9 };; | ||
223 | ___ | ||
224 | $t0="A", $t1="E", $code.=<<___ if ($BITS==64); | ||
225 | // in 64-bit mode I load whole X[16] at once and take care of alignment... | ||
226 | { .mmi; add r8=1*$SZ,input | ||
227 | add r9=2*$SZ,input | ||
228 | add r10=3*$SZ,input };; | ||
229 | { .mmb; $LDW X[15]=[input],4*$SZ | ||
230 | $LDW X[14]=[r8],4*$SZ | ||
231 | (p9) br.cond.dpnt.many .L1byte };; | ||
232 | { .mmb; $LDW X[13]=[r9],4*$SZ | ||
233 | $LDW X[12]=[r10],4*$SZ | ||
234 | (p10) br.cond.dpnt.many .L2byte };; | ||
235 | { .mmb; $LDW X[11]=[input],4*$SZ | ||
236 | $LDW X[10]=[r8],4*$SZ | ||
237 | (p11) br.cond.dpnt.many .L3byte };; | ||
238 | { .mmb; $LDW X[ 9]=[r9],4*$SZ | ||
239 | $LDW X[ 8]=[r10],4*$SZ | ||
240 | (p12) br.cond.dpnt.many .L4byte };; | ||
241 | { .mmb; $LDW X[ 7]=[input],4*$SZ | ||
242 | $LDW X[ 6]=[r8],4*$SZ | ||
243 | (p13) br.cond.dpnt.many .L5byte };; | ||
244 | { .mmb; $LDW X[ 5]=[r9],4*$SZ | ||
245 | $LDW X[ 4]=[r10],4*$SZ | ||
246 | (p14) br.cond.dpnt.many .L6byte };; | ||
247 | { .mmb; $LDW X[ 3]=[input],4*$SZ | ||
248 | $LDW X[ 2]=[r8],4*$SZ | ||
249 | (p15) br.cond.dpnt.many .L7byte };; | ||
250 | { .mmb; $LDW X[ 1]=[r9],4*$SZ | ||
251 | $LDW X[ 0]=[r10],4*$SZ | ||
252 | br.many .L_first16 };; | ||
253 | .L1byte: | ||
254 | { .mmi; $LDW X[13]=[r9],4*$SZ | ||
255 | $LDW X[12]=[r10],4*$SZ | ||
256 | shrp X[15]=X[15],X[14],56 };; | ||
257 | { .mmi; $LDW X[11]=[input],4*$SZ | ||
258 | $LDW X[10]=[r8],4*$SZ | ||
259 | shrp X[14]=X[14],X[13],56 } | ||
260 | { .mmi; $LDW X[ 9]=[r9],4*$SZ | ||
261 | $LDW X[ 8]=[r10],4*$SZ | ||
262 | shrp X[13]=X[13],X[12],56 };; | ||
263 | { .mmi; $LDW X[ 7]=[input],4*$SZ | ||
264 | $LDW X[ 6]=[r8],4*$SZ | ||
265 | shrp X[12]=X[12],X[11],56 } | ||
266 | { .mmi; $LDW X[ 5]=[r9],4*$SZ | ||
267 | $LDW X[ 4]=[r10],4*$SZ | ||
268 | shrp X[11]=X[11],X[10],56 };; | ||
269 | { .mmi; $LDW X[ 3]=[input],4*$SZ | ||
270 | $LDW X[ 2]=[r8],4*$SZ | ||
271 | shrp X[10]=X[10],X[ 9],56 } | ||
272 | { .mmi; $LDW X[ 1]=[r9],4*$SZ | ||
273 | $LDW X[ 0]=[r10],4*$SZ | ||
274 | shrp X[ 9]=X[ 9],X[ 8],56 };; | ||
275 | { .mii; $LDW T1=[input] | ||
276 | shrp X[ 8]=X[ 8],X[ 7],56 | ||
277 | shrp X[ 7]=X[ 7],X[ 6],56 } | ||
278 | { .mii; shrp X[ 6]=X[ 6],X[ 5],56 | ||
279 | shrp X[ 5]=X[ 5],X[ 4],56 };; | ||
280 | { .mii; shrp X[ 4]=X[ 4],X[ 3],56 | ||
281 | shrp X[ 3]=X[ 3],X[ 2],56 } | ||
282 | { .mii; shrp X[ 2]=X[ 2],X[ 1],56 | ||
283 | shrp X[ 1]=X[ 1],X[ 0],56 } | ||
284 | { .mib; shrp X[ 0]=X[ 0],T1,56 | ||
285 | br.many .L_first16 };; | ||
286 | .L2byte: | ||
287 | { .mmi; $LDW X[11]=[input],4*$SZ | ||
288 | $LDW X[10]=[r8],4*$SZ | ||
289 | shrp X[15]=X[15],X[14],48 } | ||
290 | { .mmi; $LDW X[ 9]=[r9],4*$SZ | ||
291 | $LDW X[ 8]=[r10],4*$SZ | ||
292 | shrp X[14]=X[14],X[13],48 };; | ||
293 | { .mmi; $LDW X[ 7]=[input],4*$SZ | ||
294 | $LDW X[ 6]=[r8],4*$SZ | ||
295 | shrp X[13]=X[13],X[12],48 } | ||
296 | { .mmi; $LDW X[ 5]=[r9],4*$SZ | ||
297 | $LDW X[ 4]=[r10],4*$SZ | ||
298 | shrp X[12]=X[12],X[11],48 };; | ||
299 | { .mmi; $LDW X[ 3]=[input],4*$SZ | ||
300 | $LDW X[ 2]=[r8],4*$SZ | ||
301 | shrp X[11]=X[11],X[10],48 } | ||
302 | { .mmi; $LDW X[ 1]=[r9],4*$SZ | ||
303 | $LDW X[ 0]=[r10],4*$SZ | ||
304 | shrp X[10]=X[10],X[ 9],48 };; | ||
305 | { .mii; $LDW T1=[input] | ||
306 | shrp X[ 9]=X[ 9],X[ 8],48 | ||
307 | shrp X[ 8]=X[ 8],X[ 7],48 } | ||
308 | { .mii; shrp X[ 7]=X[ 7],X[ 6],48 | ||
309 | shrp X[ 6]=X[ 6],X[ 5],48 };; | ||
310 | { .mii; shrp X[ 5]=X[ 5],X[ 4],48 | ||
311 | shrp X[ 4]=X[ 4],X[ 3],48 } | ||
312 | { .mii; shrp X[ 3]=X[ 3],X[ 2],48 | ||
313 | shrp X[ 2]=X[ 2],X[ 1],48 } | ||
314 | { .mii; shrp X[ 1]=X[ 1],X[ 0],48 | ||
315 | shrp X[ 0]=X[ 0],T1,48 } | ||
316 | { .mfb; br.many .L_first16 };; | ||
317 | .L3byte: | ||
318 | { .mmi; $LDW X[ 9]=[r9],4*$SZ | ||
319 | $LDW X[ 8]=[r10],4*$SZ | ||
320 | shrp X[15]=X[15],X[14],40 };; | ||
321 | { .mmi; $LDW X[ 7]=[input],4*$SZ | ||
322 | $LDW X[ 6]=[r8],4*$SZ | ||
323 | shrp X[14]=X[14],X[13],40 } | ||
324 | { .mmi; $LDW X[ 5]=[r9],4*$SZ | ||
325 | $LDW X[ 4]=[r10],4*$SZ | ||
326 | shrp X[13]=X[13],X[12],40 };; | ||
327 | { .mmi; $LDW X[ 3]=[input],4*$SZ | ||
328 | $LDW X[ 2]=[r8],4*$SZ | ||
329 | shrp X[12]=X[12],X[11],40 } | ||
330 | { .mmi; $LDW X[ 1]=[r9],4*$SZ | ||
331 | $LDW X[ 0]=[r10],4*$SZ | ||
332 | shrp X[11]=X[11],X[10],40 };; | ||
333 | { .mii; $LDW T1=[input] | ||
334 | shrp X[10]=X[10],X[ 9],40 | ||
335 | shrp X[ 9]=X[ 9],X[ 8],40 } | ||
336 | { .mii; shrp X[ 8]=X[ 8],X[ 7],40 | ||
337 | shrp X[ 7]=X[ 7],X[ 6],40 };; | ||
338 | { .mii; shrp X[ 6]=X[ 6],X[ 5],40 | ||
339 | shrp X[ 5]=X[ 5],X[ 4],40 } | ||
340 | { .mii; shrp X[ 4]=X[ 4],X[ 3],40 | ||
341 | shrp X[ 3]=X[ 3],X[ 2],40 } | ||
342 | { .mii; shrp X[ 2]=X[ 2],X[ 1],40 | ||
343 | shrp X[ 1]=X[ 1],X[ 0],40 } | ||
344 | { .mib; shrp X[ 0]=X[ 0],T1,40 | ||
345 | br.many .L_first16 };; | ||
346 | .L4byte: | ||
347 | { .mmi; $LDW X[ 7]=[input],4*$SZ | ||
348 | $LDW X[ 6]=[r8],4*$SZ | ||
349 | shrp X[15]=X[15],X[14],32 } | ||
350 | { .mmi; $LDW X[ 5]=[r9],4*$SZ | ||
351 | $LDW X[ 4]=[r10],4*$SZ | ||
352 | shrp X[14]=X[14],X[13],32 };; | ||
353 | { .mmi; $LDW X[ 3]=[input],4*$SZ | ||
354 | $LDW X[ 2]=[r8],4*$SZ | ||
355 | shrp X[13]=X[13],X[12],32 } | ||
356 | { .mmi; $LDW X[ 1]=[r9],4*$SZ | ||
357 | $LDW X[ 0]=[r10],4*$SZ | ||
358 | shrp X[12]=X[12],X[11],32 };; | ||
359 | { .mii; $LDW T1=[input] | ||
360 | shrp X[11]=X[11],X[10],32 | ||
361 | shrp X[10]=X[10],X[ 9],32 } | ||
362 | { .mii; shrp X[ 9]=X[ 9],X[ 8],32 | ||
363 | shrp X[ 8]=X[ 8],X[ 7],32 };; | ||
364 | { .mii; shrp X[ 7]=X[ 7],X[ 6],32 | ||
365 | shrp X[ 6]=X[ 6],X[ 5],32 } | ||
366 | { .mii; shrp X[ 5]=X[ 5],X[ 4],32 | ||
367 | shrp X[ 4]=X[ 4],X[ 3],32 } | ||
368 | { .mii; shrp X[ 3]=X[ 3],X[ 2],32 | ||
369 | shrp X[ 2]=X[ 2],X[ 1],32 } | ||
370 | { .mii; shrp X[ 1]=X[ 1],X[ 0],32 | ||
371 | shrp X[ 0]=X[ 0],T1,32 } | ||
372 | { .mfb; br.many .L_first16 };; | ||
373 | .L5byte: | ||
374 | { .mmi; $LDW X[ 5]=[r9],4*$SZ | ||
375 | $LDW X[ 4]=[r10],4*$SZ | ||
376 | shrp X[15]=X[15],X[14],24 };; | ||
377 | { .mmi; $LDW X[ 3]=[input],4*$SZ | ||
378 | $LDW X[ 2]=[r8],4*$SZ | ||
379 | shrp X[14]=X[14],X[13],24 } | ||
380 | { .mmi; $LDW X[ 1]=[r9],4*$SZ | ||
381 | $LDW X[ 0]=[r10],4*$SZ | ||
382 | shrp X[13]=X[13],X[12],24 };; | ||
383 | { .mii; $LDW T1=[input] | ||
384 | shrp X[12]=X[12],X[11],24 | ||
385 | shrp X[11]=X[11],X[10],24 } | ||
386 | { .mii; shrp X[10]=X[10],X[ 9],24 | ||
387 | shrp X[ 9]=X[ 9],X[ 8],24 };; | ||
388 | { .mii; shrp X[ 8]=X[ 8],X[ 7],24 | ||
389 | shrp X[ 7]=X[ 7],X[ 6],24 } | ||
390 | { .mii; shrp X[ 6]=X[ 6],X[ 5],24 | ||
391 | shrp X[ 5]=X[ 5],X[ 4],24 } | ||
392 | { .mii; shrp X[ 4]=X[ 4],X[ 3],24 | ||
393 | shrp X[ 3]=X[ 3],X[ 2],24 } | ||
394 | { .mii; shrp X[ 2]=X[ 2],X[ 1],24 | ||
395 | shrp X[ 1]=X[ 1],X[ 0],24 } | ||
396 | { .mib; shrp X[ 0]=X[ 0],T1,24 | ||
397 | br.many .L_first16 };; | ||
398 | .L6byte: | ||
399 | { .mmi; $LDW X[ 3]=[input],4*$SZ | ||
400 | $LDW X[ 2]=[r8],4*$SZ | ||
401 | shrp X[15]=X[15],X[14],16 } | ||
402 | { .mmi; $LDW X[ 1]=[r9],4*$SZ | ||
403 | $LDW X[ 0]=[r10],4*$SZ | ||
404 | shrp X[14]=X[14],X[13],16 };; | ||
405 | { .mii; $LDW T1=[input] | ||
406 | shrp X[13]=X[13],X[12],16 | ||
407 | shrp X[12]=X[12],X[11],16 } | ||
408 | { .mii; shrp X[11]=X[11],X[10],16 | ||
409 | shrp X[10]=X[10],X[ 9],16 };; | ||
410 | { .mii; shrp X[ 9]=X[ 9],X[ 8],16 | ||
411 | shrp X[ 8]=X[ 8],X[ 7],16 } | ||
412 | { .mii; shrp X[ 7]=X[ 7],X[ 6],16 | ||
413 | shrp X[ 6]=X[ 6],X[ 5],16 } | ||
414 | { .mii; shrp X[ 5]=X[ 5],X[ 4],16 | ||
415 | shrp X[ 4]=X[ 4],X[ 3],16 } | ||
416 | { .mii; shrp X[ 3]=X[ 3],X[ 2],16 | ||
417 | shrp X[ 2]=X[ 2],X[ 1],16 } | ||
418 | { .mii; shrp X[ 1]=X[ 1],X[ 0],16 | ||
419 | shrp X[ 0]=X[ 0],T1,16 } | ||
420 | { .mfb; br.many .L_first16 };; | ||
421 | .L7byte: | ||
422 | { .mmi; $LDW X[ 1]=[r9],4*$SZ | ||
423 | $LDW X[ 0]=[r10],4*$SZ | ||
424 | shrp X[15]=X[15],X[14],8 };; | ||
425 | { .mii; $LDW T1=[input] | ||
426 | shrp X[14]=X[14],X[13],8 | ||
427 | shrp X[13]=X[13],X[12],8 } | ||
428 | { .mii; shrp X[12]=X[12],X[11],8 | ||
429 | shrp X[11]=X[11],X[10],8 };; | ||
430 | { .mii; shrp X[10]=X[10],X[ 9],8 | ||
431 | shrp X[ 9]=X[ 9],X[ 8],8 } | ||
432 | { .mii; shrp X[ 8]=X[ 8],X[ 7],8 | ||
433 | shrp X[ 7]=X[ 7],X[ 6],8 } | ||
434 | { .mii; shrp X[ 6]=X[ 6],X[ 5],8 | ||
435 | shrp X[ 5]=X[ 5],X[ 4],8 } | ||
436 | { .mii; shrp X[ 4]=X[ 4],X[ 3],8 | ||
437 | shrp X[ 3]=X[ 3],X[ 2],8 } | ||
438 | { .mii; shrp X[ 2]=X[ 2],X[ 1],8 | ||
439 | shrp X[ 1]=X[ 1],X[ 0],8 } | ||
440 | { .mib; shrp X[ 0]=X[ 0],T1,8 | ||
441 | br.many .L_first16 };; | ||
442 | |||
443 | .align 32 | ||
444 | .L_first16: | ||
445 | { .mmi; $LDW K=[Ktbl],$SZ | ||
446 | and T1=F,E | ||
447 | and T2=A,B } | ||
448 | { .mmi; //$LDW X[15]=[input],$SZ // X[i]=*input++ | ||
449 | andcm r8=G,E | ||
450 | and r9=A,C };; | ||
451 | { .mmi; xor T1=T1,r8 //T1=((e & f) ^ (~e & g)) | ||
452 | and r10=B,C | ||
453 | _rotr r11=$t1,$Sigma1[0] } // ROTR(e,14) | ||
454 | { .mmi; xor T2=T2,r9 | ||
455 | mux1 X[15]=X[15],\@rev };; // eliminated in big-endian | ||
456 | ___ | ||
457 | $code.=<<___; | ||
458 | { .mib; add T1=T1,H // T1=Ch(e,f,g)+h | ||
459 | _rotr r8=$t1,$Sigma1[1] } // ROTR(e,18) | ||
460 | { .mib; xor T2=T2,r10 // T2=((a & b) ^ (a & c) ^ (b & c)) | ||
461 | mov H=G };; | ||
462 | { .mib; xor r11=r8,r11 | ||
463 | _rotr r9=$t1,$Sigma1[2] } // ROTR(e,41) | ||
464 | { .mib; mov G=F | ||
465 | mov F=E };; | ||
466 | { .mib; xor r9=r9,r11 // r9=Sigma1(e) | ||
467 | _rotr r10=$t0,$Sigma0[0] } // ROTR(a,28) | ||
468 | { .mib; add T1=T1,K // T1=Ch(e,f,g)+h+K512[i] | ||
469 | mov E=D };; | ||
470 | { .mib; add T1=T1,r9 // T1+=Sigma1(e) | ||
471 | _rotr r11=$t0,$Sigma0[1] } // ROTR(a,34) | ||
472 | { .mib; mov D=C | ||
473 | mov C=B };; | ||
474 | { .mib; add T1=T1,X[15] // T1+=X[i] | ||
475 | _rotr r8=$t0,$Sigma0[2] } // ROTR(a,39) | ||
476 | { .mib; xor r10=r10,r11 | ||
477 | mux2 X[15]=X[15],0x44 };; // eliminated in 64-bit | ||
478 | { .mmi; xor r10=r8,r10 // r10=Sigma0(a) | ||
479 | mov B=A | ||
480 | add A=T1,T2 };; | ||
481 | { .mib; add E=E,T1 | ||
482 | add A=A,r10 // T2=Maj(a,b,c)+Sigma0(a) | ||
483 | br.ctop.sptk .L_first16 };; | ||
484 | .L_first16_end: | ||
485 | |||
486 | { .mii; mov ar.lc=$rounds-17 | ||
487 | mov ar.ec=1 };; | ||
488 | |||
489 | .align 32 | ||
490 | .L_rest: | ||
491 | .rotr X[16] | ||
492 | { .mib; $LDW K=[Ktbl],$SZ | ||
493 | _rotr r8=X[15-1],$sigma0[0] } // ROTR(s0,1) | ||
494 | { .mib; $ADD X[15]=X[15],X[15-9] // X[i&0xF]+=X[(i+9)&0xF] | ||
495 | $SHRU s0=X[15-1],sgm0 };; // s0=X[(i+1)&0xF]>>7 | ||
496 | { .mib; and T1=F,E | ||
497 | _rotr r9=X[15-1],$sigma0[1] } // ROTR(s0,8) | ||
498 | { .mib; andcm r10=G,E | ||
499 | $SHRU s1=X[15-14],sgm1 };; // s1=X[(i+14)&0xF]>>6 | ||
500 | { .mmi; xor T1=T1,r10 // T1=((e & f) ^ (~e & g)) | ||
501 | xor r9=r8,r9 | ||
502 | _rotr r10=X[15-14],$sigma1[0] };;// ROTR(s1,19) | ||
503 | { .mib; and T2=A,B | ||
504 | _rotr r11=X[15-14],$sigma1[1] }// ROTR(s1,61) | ||
505 | { .mib; and r8=A,C };; | ||
506 | ___ | ||
507 | $t0="t0", $t1="t1", $code.=<<___ if ($BITS==32); | ||
508 | // I adhere to mmi; in order to hold Itanium 1 back and avoid 6 cycle | ||
509 | // pipeline flush in last bundle. Note that even on Itanium2 the | ||
510 | // latter stalls for one clock cycle... | ||
511 | { .mmi; xor s0=s0,r9 // s0=sigma0(X[(i+1)&0xF]) | ||
512 | dep.z $t1=E,32,32 } | ||
513 | { .mmi; xor r10=r11,r10 | ||
514 | zxt4 E=E };; | ||
515 | { .mmi; or $t1=$t1,E | ||
516 | xor s1=s1,r10 // s1=sigma1(X[(i+14)&0xF]) | ||
517 | mux2 $t0=A,0x44 };; // copy lower half to upper | ||
518 | { .mmi; xor T2=T2,r8 | ||
519 | _rotr r9=$t1,$Sigma1[0] } // ROTR(e,14) | ||
520 | { .mmi; and r10=B,C | ||
521 | add T1=T1,H // T1=Ch(e,f,g)+h | ||
522 | $ADD X[15]=X[15],s0 };; // X[i&0xF]+=sigma0(X[(i+1)&0xF]) | ||
523 | ___ | ||
524 | $t0="A", $t1="E", $code.=<<___ if ($BITS==64); | ||
525 | { .mib; xor s0=s0,r9 // s0=sigma0(X[(i+1)&0xF]) | ||
526 | _rotr r9=$t1,$Sigma1[0] } // ROTR(e,14) | ||
527 | { .mib; xor r10=r11,r10 | ||
528 | xor T2=T2,r8 };; | ||
529 | { .mib; xor s1=s1,r10 // s1=sigma1(X[(i+14)&0xF]) | ||
530 | add T1=T1,H } | ||
531 | { .mib; and r10=B,C | ||
532 | $ADD X[15]=X[15],s0 };; // X[i&0xF]+=sigma0(X[(i+1)&0xF]) | ||
533 | ___ | ||
534 | $code.=<<___; | ||
535 | { .mmi; xor T2=T2,r10 // T2=((a & b) ^ (a & c) ^ (b & c)) | ||
536 | mov H=G | ||
537 | _rotr r8=$t1,$Sigma1[1] };; // ROTR(e,18) | ||
538 | { .mmi; xor r11=r8,r9 | ||
539 | $ADD X[15]=X[15],s1 // X[i&0xF]+=sigma1(X[(i+14)&0xF]) | ||
540 | _rotr r9=$t1,$Sigma1[2] } // ROTR(e,41) | ||
541 | { .mmi; mov G=F | ||
542 | mov F=E };; | ||
543 | { .mib; xor r9=r9,r11 // r9=Sigma1(e) | ||
544 | _rotr r10=$t0,$Sigma0[0] } // ROTR(a,28) | ||
545 | { .mib; add T1=T1,K // T1=Ch(e,f,g)+h+K512[i] | ||
546 | mov E=D };; | ||
547 | { .mib; add T1=T1,r9 // T1+=Sigma1(e) | ||
548 | _rotr r11=$t0,$Sigma0[1] } // ROTR(a,34) | ||
549 | { .mib; mov D=C | ||
550 | mov C=B };; | ||
551 | { .mmi; add T1=T1,X[15] // T1+=X[i] | ||
552 | xor r10=r10,r11 | ||
553 | _rotr r8=$t0,$Sigma0[2] };; // ROTR(a,39) | ||
554 | { .mmi; xor r10=r8,r10 // r10=Sigma0(a) | ||
555 | mov B=A | ||
556 | add A=T1,T2 };; | ||
557 | { .mib; add E=E,T1 | ||
558 | add A=A,r10 // T2=Maj(a,b,c)+Sigma0(a) | ||
559 | br.ctop.sptk .L_rest };; | ||
560 | .L_rest_end: | ||
561 | |||
562 | { .mmi; add A_=A_,A | ||
563 | add B_=B_,B | ||
564 | add C_=C_,C } | ||
565 | { .mmi; add D_=D_,D | ||
566 | add E_=E_,E | ||
567 | cmp.ltu p16,p0=1,num };; | ||
568 | { .mmi; add F_=F_,F | ||
569 | add G_=G_,G | ||
570 | add H_=H_,H } | ||
571 | { .mmb; add Ktbl=-$SZ*$rounds,Ktbl | ||
572 | (p16) add num=-1,num | ||
573 | (p16) br.dptk.many .L_outer };; | ||
574 | |||
575 | { .mib; add r8=0*$SZ,ctx | ||
576 | add r9=1*$SZ,ctx } | ||
577 | { .mib; add r10=2*$SZ,ctx | ||
578 | add r11=3*$SZ,ctx };; | ||
579 | { .mmi; $STW [r8]=A_,4*$SZ | ||
580 | $STW [r9]=B_,4*$SZ | ||
581 | mov ar.lc=lcsave } | ||
582 | { .mmi; $STW [r10]=C_,4*$SZ | ||
583 | $STW [r11]=D_,4*$SZ | ||
584 | mov pr=prsave,0x1ffff };; | ||
585 | { .mmb; $STW [r8]=E_ | ||
586 | $STW [r9]=F_ } | ||
587 | { .mmb; $STW [r10]=G_ | ||
588 | $STW [r11]=H_ | ||
589 | br.ret.sptk.many b0 };; | ||
590 | .endp $func# | ||
591 | ___ | ||
592 | |||
593 | $code =~ s/\`([^\`]*)\`/eval $1/gem; | ||
594 | $code =~ s/_rotr(\s+)([^=]+)=([^,]+),([0-9]+)/shrp$1$2=$3,$3,$4/gm; | ||
595 | if ($BITS==64) { | ||
596 | $code =~ s/mux2(\s+)\S+/nop.i$1 0x0/gm; | ||
597 | $code =~ s/mux1(\s+)\S+/nop.i$1 0x0/gm if ($big_endian); | ||
598 | $code =~ s/(shrp\s+X\[[^=]+)=([^,]+),([^,]+),([1-9]+)/$1=$3,$2,64-$4/gm | ||
599 | if (!$big_endian); | ||
600 | $code =~ s/ld1(\s+)X\[\S+/nop.m$1 0x0/gm; | ||
601 | } | ||
602 | |||
603 | print $code; | ||
604 | |||
605 | print<<___ if ($BITS==32); | ||
606 | .align 64 | ||
607 | .type K256#,\@object | ||
608 | K256: data4 0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5 | ||
609 | data4 0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5 | ||
610 | data4 0xd807aa98,0x12835b01,0x243185be,0x550c7dc3 | ||
611 | data4 0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174 | ||
612 | data4 0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc | ||
613 | data4 0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da | ||
614 | data4 0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7 | ||
615 | data4 0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967 | ||
616 | data4 0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13 | ||
617 | data4 0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85 | ||
618 | data4 0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3 | ||
619 | data4 0xd192e819,0xd6990624,0xf40e3585,0x106aa070 | ||
620 | data4 0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5 | ||
621 | data4 0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3 | ||
622 | data4 0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208 | ||
623 | data4 0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2 | ||
624 | .size K256#,$SZ*$rounds | ||
625 | stringz "SHA256 block transform for IA64, CRYPTOGAMS by <appro\@openssl.org>" | ||
626 | ___ | ||
627 | print<<___ if ($BITS==64); | ||
628 | .align 64 | ||
629 | .type K512#,\@object | ||
630 | K512: data8 0x428a2f98d728ae22,0x7137449123ef65cd | ||
631 | data8 0xb5c0fbcfec4d3b2f,0xe9b5dba58189dbbc | ||
632 | data8 0x3956c25bf348b538,0x59f111f1b605d019 | ||
633 | data8 0x923f82a4af194f9b,0xab1c5ed5da6d8118 | ||
634 | data8 0xd807aa98a3030242,0x12835b0145706fbe | ||
635 | data8 0x243185be4ee4b28c,0x550c7dc3d5ffb4e2 | ||
636 | data8 0x72be5d74f27b896f,0x80deb1fe3b1696b1 | ||
637 | data8 0x9bdc06a725c71235,0xc19bf174cf692694 | ||
638 | data8 0xe49b69c19ef14ad2,0xefbe4786384f25e3 | ||
639 | data8 0x0fc19dc68b8cd5b5,0x240ca1cc77ac9c65 | ||
640 | data8 0x2de92c6f592b0275,0x4a7484aa6ea6e483 | ||
641 | data8 0x5cb0a9dcbd41fbd4,0x76f988da831153b5 | ||
642 | data8 0x983e5152ee66dfab,0xa831c66d2db43210 | ||
643 | data8 0xb00327c898fb213f,0xbf597fc7beef0ee4 | ||
644 | data8 0xc6e00bf33da88fc2,0xd5a79147930aa725 | ||
645 | data8 0x06ca6351e003826f,0x142929670a0e6e70 | ||
646 | data8 0x27b70a8546d22ffc,0x2e1b21385c26c926 | ||
647 | data8 0x4d2c6dfc5ac42aed,0x53380d139d95b3df | ||
648 | data8 0x650a73548baf63de,0x766a0abb3c77b2a8 | ||
649 | data8 0x81c2c92e47edaee6,0x92722c851482353b | ||
650 | data8 0xa2bfe8a14cf10364,0xa81a664bbc423001 | ||
651 | data8 0xc24b8b70d0f89791,0xc76c51a30654be30 | ||
652 | data8 0xd192e819d6ef5218,0xd69906245565a910 | ||
653 | data8 0xf40e35855771202a,0x106aa07032bbd1b8 | ||
654 | data8 0x19a4c116b8d2d0c8,0x1e376c085141ab53 | ||
655 | data8 0x2748774cdf8eeb99,0x34b0bcb5e19b48a8 | ||
656 | data8 0x391c0cb3c5c95a63,0x4ed8aa4ae3418acb | ||
657 | data8 0x5b9cca4f7763e373,0x682e6ff3d6b2b8a3 | ||
658 | data8 0x748f82ee5defb2fc,0x78a5636f43172f60 | ||
659 | data8 0x84c87814a1f0ab72,0x8cc702081a6439ec | ||
660 | data8 0x90befffa23631e28,0xa4506cebde82bde9 | ||
661 | data8 0xbef9a3f7b2c67915,0xc67178f2e372532b | ||
662 | data8 0xca273eceea26619c,0xd186b8c721c0c207 | ||
663 | data8 0xeada7dd6cde0eb1e,0xf57d4f7fee6ed178 | ||
664 | data8 0x06f067aa72176fba,0x0a637dc5a2c898a6 | ||
665 | data8 0x113f9804bef90dae,0x1b710b35131c471b | ||
666 | data8 0x28db77f523047d84,0x32caab7b40c72493 | ||
667 | data8 0x3c9ebe0a15c9bebc,0x431d67c49c100d4c | ||
668 | data8 0x4cc5d4becb3e42b6,0x597f299cfc657e2a | ||
669 | data8 0x5fcb6fab3ad6faec,0x6c44198c4a475817 | ||
670 | .size K512#,$SZ*$rounds | ||
671 | stringz "SHA512 block transform for IA64, CRYPTOGAMS by <appro\@openssl.org>" | ||
672 | ___ | ||
diff --git a/src/lib/libcrypto/sha/asm/sha512-x86_64.pl b/src/lib/libcrypto/sha/asm/sha512-x86_64.pl new file mode 100755 index 0000000000..b6252d31ec --- /dev/null +++ b/src/lib/libcrypto/sha/asm/sha512-x86_64.pl | |||
@@ -0,0 +1,344 @@ | |||
1 | #!/usr/bin/env perl | ||
2 | # | ||
3 | # ==================================================================== | ||
4 | # Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL | ||
5 | # project. Rights for redistribution and usage in source and binary | ||
6 | # forms are granted according to the OpenSSL license. | ||
7 | # ==================================================================== | ||
8 | # | ||
9 | # sha256/512_block procedure for x86_64. | ||
10 | # | ||
11 | # 40% improvement over compiler-generated code on Opteron. On EM64T | ||
12 | # sha256 was observed to run >80% faster and sha512 - >40%. No magical | ||
13 | # tricks, just straight implementation... I really wonder why gcc | ||
14 | # [being armed with inline assembler] fails to generate as fast code. | ||
15 | # The only thing which is cool about this module is that it's very | ||
16 | # same instruction sequence used for both SHA-256 and SHA-512. In | ||
17 | # former case the instructions operate on 32-bit operands, while in | ||
18 | # latter - on 64-bit ones. All I had to do is to get one flavor right, | ||
19 | # the other one passed the test right away:-) | ||
20 | # | ||
21 | # sha256_block runs in ~1005 cycles on Opteron, which gives you | ||
22 | # asymptotic performance of 64*1000/1005=63.7MBps times CPU clock | ||
23 | # frequency in GHz. sha512_block runs in ~1275 cycles, which results | ||
24 | # in 128*1000/1275=100MBps per GHz. Is there room for improvement? | ||
25 | # Well, if you compare it to IA-64 implementation, which maintains | ||
26 | # X[16] in register bank[!], tends to 4 instructions per CPU clock | ||
27 | # cycle and runs in 1003 cycles, 1275 is very good result for 3-way | ||
28 | # issue Opteron pipeline and X[16] maintained in memory. So that *if* | ||
29 | # there is a way to improve it, *then* the only way would be to try to | ||
30 | # offload X[16] updates to SSE unit, but that would require "deeper" | ||
31 | # loop unroll, which in turn would naturally cause size blow-up, not | ||
32 | # to mention increased complexity! And once again, only *if* it's | ||
33 | # actually possible to noticeably improve overall ILP, instruction | ||
34 | # level parallelism, on a given CPU implementation in this case. | ||
35 | # | ||
36 | # Special note on Intel EM64T. While Opteron CPU exhibits perfect | ||
37 | # perfromance ratio of 1.5 between 64- and 32-bit flavors [see above], | ||
38 | # [currently available] EM64T CPUs apparently are far from it. On the | ||
39 | # contrary, 64-bit version, sha512_block, is ~30% *slower* than 32-bit | ||
40 | # sha256_block:-( This is presumably because 64-bit shifts/rotates | ||
41 | # apparently are not atomic instructions, but implemented in microcode. | ||
42 | |||
43 | $output=shift; | ||
44 | |||
45 | $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; | ||
46 | ( $xlate="${dir}x86_64-xlate.pl" and -f $xlate ) or | ||
47 | ( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or | ||
48 | die "can't locate x86_64-xlate.pl"; | ||
49 | |||
50 | open STDOUT,"| $^X $xlate $output"; | ||
51 | |||
52 | if ($output =~ /512/) { | ||
53 | $func="sha512_block_data_order"; | ||
54 | $TABLE="K512"; | ||
55 | $SZ=8; | ||
56 | @ROT=($A,$B,$C,$D,$E,$F,$G,$H)=("%rax","%rbx","%rcx","%rdx", | ||
57 | "%r8", "%r9", "%r10","%r11"); | ||
58 | ($T1,$a0,$a1,$a2)=("%r12","%r13","%r14","%r15"); | ||
59 | @Sigma0=(28,34,39); | ||
60 | @Sigma1=(14,18,41); | ||
61 | @sigma0=(1, 8, 7); | ||
62 | @sigma1=(19,61, 6); | ||
63 | $rounds=80; | ||
64 | } else { | ||
65 | $func="sha256_block_data_order"; | ||
66 | $TABLE="K256"; | ||
67 | $SZ=4; | ||
68 | @ROT=($A,$B,$C,$D,$E,$F,$G,$H)=("%eax","%ebx","%ecx","%edx", | ||
69 | "%r8d","%r9d","%r10d","%r11d"); | ||
70 | ($T1,$a0,$a1,$a2)=("%r12d","%r13d","%r14d","%r15d"); | ||
71 | @Sigma0=( 2,13,22); | ||
72 | @Sigma1=( 6,11,25); | ||
73 | @sigma0=( 7,18, 3); | ||
74 | @sigma1=(17,19,10); | ||
75 | $rounds=64; | ||
76 | } | ||
77 | |||
78 | $ctx="%rdi"; # 1st arg | ||
79 | $round="%rdi"; # zaps $ctx | ||
80 | $inp="%rsi"; # 2nd arg | ||
81 | $Tbl="%rbp"; | ||
82 | |||
83 | $_ctx="16*$SZ+0*8(%rsp)"; | ||
84 | $_inp="16*$SZ+1*8(%rsp)"; | ||
85 | $_end="16*$SZ+2*8(%rsp)"; | ||
86 | $_rsp="16*$SZ+3*8(%rsp)"; | ||
87 | $framesz="16*$SZ+4*8"; | ||
88 | |||
89 | |||
90 | sub ROUND_00_15() | ||
91 | { my ($i,$a,$b,$c,$d,$e,$f,$g,$h) = @_; | ||
92 | |||
93 | $code.=<<___; | ||
94 | mov $e,$a0 | ||
95 | mov $e,$a1 | ||
96 | mov $f,$a2 | ||
97 | |||
98 | ror \$$Sigma1[0],$a0 | ||
99 | ror \$$Sigma1[1],$a1 | ||
100 | xor $g,$a2 # f^g | ||
101 | |||
102 | xor $a1,$a0 | ||
103 | ror \$`$Sigma1[2]-$Sigma1[1]`,$a1 | ||
104 | and $e,$a2 # (f^g)&e | ||
105 | mov $T1,`$SZ*($i&0xf)`(%rsp) | ||
106 | |||
107 | xor $a1,$a0 # Sigma1(e) | ||
108 | xor $g,$a2 # Ch(e,f,g)=((f^g)&e)^g | ||
109 | add $h,$T1 # T1+=h | ||
110 | |||
111 | mov $a,$h | ||
112 | add $a0,$T1 # T1+=Sigma1(e) | ||
113 | |||
114 | add $a2,$T1 # T1+=Ch(e,f,g) | ||
115 | mov $a,$a0 | ||
116 | mov $a,$a1 | ||
117 | |||
118 | ror \$$Sigma0[0],$h | ||
119 | ror \$$Sigma0[1],$a0 | ||
120 | mov $a,$a2 | ||
121 | add ($Tbl,$round,$SZ),$T1 # T1+=K[round] | ||
122 | |||
123 | xor $a0,$h | ||
124 | ror \$`$Sigma0[2]-$Sigma0[1]`,$a0 | ||
125 | or $c,$a1 # a|c | ||
126 | |||
127 | xor $a0,$h # h=Sigma0(a) | ||
128 | and $c,$a2 # a&c | ||
129 | add $T1,$d # d+=T1 | ||
130 | |||
131 | and $b,$a1 # (a|c)&b | ||
132 | add $T1,$h # h+=T1 | ||
133 | |||
134 | or $a2,$a1 # Maj(a,b,c)=((a|c)&b)|(a&c) | ||
135 | lea 1($round),$round # round++ | ||
136 | |||
137 | add $a1,$h # h+=Maj(a,b,c) | ||
138 | ___ | ||
139 | } | ||
140 | |||
141 | sub ROUND_16_XX() | ||
142 | { my ($i,$a,$b,$c,$d,$e,$f,$g,$h) = @_; | ||
143 | |||
144 | $code.=<<___; | ||
145 | mov `$SZ*(($i+1)&0xf)`(%rsp),$a0 | ||
146 | mov `$SZ*(($i+14)&0xf)`(%rsp),$T1 | ||
147 | |||
148 | mov $a0,$a2 | ||
149 | |||
150 | shr \$$sigma0[2],$a0 | ||
151 | ror \$$sigma0[0],$a2 | ||
152 | |||
153 | xor $a2,$a0 | ||
154 | ror \$`$sigma0[1]-$sigma0[0]`,$a2 | ||
155 | |||
156 | xor $a2,$a0 # sigma0(X[(i+1)&0xf]) | ||
157 | mov $T1,$a1 | ||
158 | |||
159 | shr \$$sigma1[2],$T1 | ||
160 | ror \$$sigma1[0],$a1 | ||
161 | |||
162 | xor $a1,$T1 | ||
163 | ror \$`$sigma1[1]-$sigma1[0]`,$a1 | ||
164 | |||
165 | xor $a1,$T1 # sigma1(X[(i+14)&0xf]) | ||
166 | |||
167 | add $a0,$T1 | ||
168 | |||
169 | add `$SZ*(($i+9)&0xf)`(%rsp),$T1 | ||
170 | |||
171 | add `$SZ*($i&0xf)`(%rsp),$T1 | ||
172 | ___ | ||
173 | &ROUND_00_15(@_); | ||
174 | } | ||
175 | |||
176 | $code=<<___; | ||
177 | .text | ||
178 | |||
179 | .globl $func | ||
180 | .type $func,\@function,4 | ||
181 | .align 16 | ||
182 | $func: | ||
183 | push %rbx | ||
184 | push %rbp | ||
185 | push %r12 | ||
186 | push %r13 | ||
187 | push %r14 | ||
188 | push %r15 | ||
189 | mov %rsp,%rbp # copy %rsp | ||
190 | shl \$4,%rdx # num*16 | ||
191 | sub \$$framesz,%rsp | ||
192 | lea ($inp,%rdx,$SZ),%rdx # inp+num*16*$SZ | ||
193 | and \$-64,%rsp # align stack frame | ||
194 | mov $ctx,$_ctx # save ctx, 1st arg | ||
195 | mov $inp,$_inp # save inp, 2nd arh | ||
196 | mov %rdx,$_end # save end pointer, "3rd" arg | ||
197 | mov %rbp,$_rsp # save copy of %rsp | ||
198 | |||
199 | .picmeup $Tbl | ||
200 | lea $TABLE-.($Tbl),$Tbl | ||
201 | |||
202 | mov $SZ*0($ctx),$A | ||
203 | mov $SZ*1($ctx),$B | ||
204 | mov $SZ*2($ctx),$C | ||
205 | mov $SZ*3($ctx),$D | ||
206 | mov $SZ*4($ctx),$E | ||
207 | mov $SZ*5($ctx),$F | ||
208 | mov $SZ*6($ctx),$G | ||
209 | mov $SZ*7($ctx),$H | ||
210 | jmp .Lloop | ||
211 | |||
212 | .align 16 | ||
213 | .Lloop: | ||
214 | xor $round,$round | ||
215 | ___ | ||
216 | for($i=0;$i<16;$i++) { | ||
217 | $code.=" mov $SZ*$i($inp),$T1\n"; | ||
218 | $code.=" bswap $T1\n"; | ||
219 | &ROUND_00_15($i,@ROT); | ||
220 | unshift(@ROT,pop(@ROT)); | ||
221 | } | ||
222 | $code.=<<___; | ||
223 | jmp .Lrounds_16_xx | ||
224 | .align 16 | ||
225 | .Lrounds_16_xx: | ||
226 | ___ | ||
227 | for(;$i<32;$i++) { | ||
228 | &ROUND_16_XX($i,@ROT); | ||
229 | unshift(@ROT,pop(@ROT)); | ||
230 | } | ||
231 | |||
232 | $code.=<<___; | ||
233 | cmp \$$rounds,$round | ||
234 | jb .Lrounds_16_xx | ||
235 | |||
236 | mov $_ctx,$ctx | ||
237 | lea 16*$SZ($inp),$inp | ||
238 | |||
239 | add $SZ*0($ctx),$A | ||
240 | add $SZ*1($ctx),$B | ||
241 | add $SZ*2($ctx),$C | ||
242 | add $SZ*3($ctx),$D | ||
243 | add $SZ*4($ctx),$E | ||
244 | add $SZ*5($ctx),$F | ||
245 | add $SZ*6($ctx),$G | ||
246 | add $SZ*7($ctx),$H | ||
247 | |||
248 | cmp $_end,$inp | ||
249 | |||
250 | mov $A,$SZ*0($ctx) | ||
251 | mov $B,$SZ*1($ctx) | ||
252 | mov $C,$SZ*2($ctx) | ||
253 | mov $D,$SZ*3($ctx) | ||
254 | mov $E,$SZ*4($ctx) | ||
255 | mov $F,$SZ*5($ctx) | ||
256 | mov $G,$SZ*6($ctx) | ||
257 | mov $H,$SZ*7($ctx) | ||
258 | jb .Lloop | ||
259 | |||
260 | mov $_rsp,%rsp | ||
261 | pop %r15 | ||
262 | pop %r14 | ||
263 | pop %r13 | ||
264 | pop %r12 | ||
265 | pop %rbp | ||
266 | pop %rbx | ||
267 | |||
268 | ret | ||
269 | .size $func,.-$func | ||
270 | ___ | ||
271 | |||
272 | if ($SZ==4) { | ||
273 | $code.=<<___; | ||
274 | .align 64 | ||
275 | .type $TABLE,\@object | ||
276 | $TABLE: | ||
277 | .long 0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5 | ||
278 | .long 0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5 | ||
279 | .long 0xd807aa98,0x12835b01,0x243185be,0x550c7dc3 | ||
280 | .long 0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174 | ||
281 | .long 0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc | ||
282 | .long 0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da | ||
283 | .long 0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7 | ||
284 | .long 0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967 | ||
285 | .long 0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13 | ||
286 | .long 0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85 | ||
287 | .long 0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3 | ||
288 | .long 0xd192e819,0xd6990624,0xf40e3585,0x106aa070 | ||
289 | .long 0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5 | ||
290 | .long 0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3 | ||
291 | .long 0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208 | ||
292 | .long 0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2 | ||
293 | ___ | ||
294 | } else { | ||
295 | $code.=<<___; | ||
296 | .align 64 | ||
297 | .type $TABLE,\@object | ||
298 | $TABLE: | ||
299 | .quad 0x428a2f98d728ae22,0x7137449123ef65cd | ||
300 | .quad 0xb5c0fbcfec4d3b2f,0xe9b5dba58189dbbc | ||
301 | .quad 0x3956c25bf348b538,0x59f111f1b605d019 | ||
302 | .quad 0x923f82a4af194f9b,0xab1c5ed5da6d8118 | ||
303 | .quad 0xd807aa98a3030242,0x12835b0145706fbe | ||
304 | .quad 0x243185be4ee4b28c,0x550c7dc3d5ffb4e2 | ||
305 | .quad 0x72be5d74f27b896f,0x80deb1fe3b1696b1 | ||
306 | .quad 0x9bdc06a725c71235,0xc19bf174cf692694 | ||
307 | .quad 0xe49b69c19ef14ad2,0xefbe4786384f25e3 | ||
308 | .quad 0x0fc19dc68b8cd5b5,0x240ca1cc77ac9c65 | ||
309 | .quad 0x2de92c6f592b0275,0x4a7484aa6ea6e483 | ||
310 | .quad 0x5cb0a9dcbd41fbd4,0x76f988da831153b5 | ||
311 | .quad 0x983e5152ee66dfab,0xa831c66d2db43210 | ||
312 | .quad 0xb00327c898fb213f,0xbf597fc7beef0ee4 | ||
313 | .quad 0xc6e00bf33da88fc2,0xd5a79147930aa725 | ||
314 | .quad 0x06ca6351e003826f,0x142929670a0e6e70 | ||
315 | .quad 0x27b70a8546d22ffc,0x2e1b21385c26c926 | ||
316 | .quad 0x4d2c6dfc5ac42aed,0x53380d139d95b3df | ||
317 | .quad 0x650a73548baf63de,0x766a0abb3c77b2a8 | ||
318 | .quad 0x81c2c92e47edaee6,0x92722c851482353b | ||
319 | .quad 0xa2bfe8a14cf10364,0xa81a664bbc423001 | ||
320 | .quad 0xc24b8b70d0f89791,0xc76c51a30654be30 | ||
321 | .quad 0xd192e819d6ef5218,0xd69906245565a910 | ||
322 | .quad 0xf40e35855771202a,0x106aa07032bbd1b8 | ||
323 | .quad 0x19a4c116b8d2d0c8,0x1e376c085141ab53 | ||
324 | .quad 0x2748774cdf8eeb99,0x34b0bcb5e19b48a8 | ||
325 | .quad 0x391c0cb3c5c95a63,0x4ed8aa4ae3418acb | ||
326 | .quad 0x5b9cca4f7763e373,0x682e6ff3d6b2b8a3 | ||
327 | .quad 0x748f82ee5defb2fc,0x78a5636f43172f60 | ||
328 | .quad 0x84c87814a1f0ab72,0x8cc702081a6439ec | ||
329 | .quad 0x90befffa23631e28,0xa4506cebde82bde9 | ||
330 | .quad 0xbef9a3f7b2c67915,0xc67178f2e372532b | ||
331 | .quad 0xca273eceea26619c,0xd186b8c721c0c207 | ||
332 | .quad 0xeada7dd6cde0eb1e,0xf57d4f7fee6ed178 | ||
333 | .quad 0x06f067aa72176fba,0x0a637dc5a2c898a6 | ||
334 | .quad 0x113f9804bef90dae,0x1b710b35131c471b | ||
335 | .quad 0x28db77f523047d84,0x32caab7b40c72493 | ||
336 | .quad 0x3c9ebe0a15c9bebc,0x431d67c49c100d4c | ||
337 | .quad 0x4cc5d4becb3e42b6,0x597f299cfc657e2a | ||
338 | .quad 0x5fcb6fab3ad6faec,0x6c44198c4a475817 | ||
339 | ___ | ||
340 | } | ||
341 | |||
342 | $code =~ s/\`([^\`]*)\`/eval $1/gem; | ||
343 | print $code; | ||
344 | close STDOUT; | ||
diff --git a/src/lib/libcrypto/sha/sha256.c b/src/lib/libcrypto/sha/sha256.c new file mode 100644 index 0000000000..867f90cc97 --- /dev/null +++ b/src/lib/libcrypto/sha/sha256.c | |||
@@ -0,0 +1,282 @@ | |||
1 | /* crypto/sha/sha256.c */ | ||
2 | /* ==================================================================== | ||
3 | * Copyright (c) 2004 The OpenSSL Project. All rights reserved | ||
4 | * according to the OpenSSL license [found in ../../LICENSE]. | ||
5 | * ==================================================================== | ||
6 | */ | ||
7 | #include <openssl/opensslconf.h> | ||
8 | #if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA256) | ||
9 | |||
10 | #include <stdlib.h> | ||
11 | #include <string.h> | ||
12 | |||
13 | #include <openssl/crypto.h> | ||
14 | #include <openssl/sha.h> | ||
15 | #include <openssl/opensslv.h> | ||
16 | |||
17 | const char SHA256_version[]="SHA-256" OPENSSL_VERSION_PTEXT; | ||
18 | |||
19 | int SHA224_Init (SHA256_CTX *c) | ||
20 | { | ||
21 | c->h[0]=0xc1059ed8UL; c->h[1]=0x367cd507UL; | ||
22 | c->h[2]=0x3070dd17UL; c->h[3]=0xf70e5939UL; | ||
23 | c->h[4]=0xffc00b31UL; c->h[5]=0x68581511UL; | ||
24 | c->h[6]=0x64f98fa7UL; c->h[7]=0xbefa4fa4UL; | ||
25 | c->Nl=0; c->Nh=0; | ||
26 | c->num=0; c->md_len=SHA224_DIGEST_LENGTH; | ||
27 | return 1; | ||
28 | } | ||
29 | |||
30 | int SHA256_Init (SHA256_CTX *c) | ||
31 | { | ||
32 | c->h[0]=0x6a09e667UL; c->h[1]=0xbb67ae85UL; | ||
33 | c->h[2]=0x3c6ef372UL; c->h[3]=0xa54ff53aUL; | ||
34 | c->h[4]=0x510e527fUL; c->h[5]=0x9b05688cUL; | ||
35 | c->h[6]=0x1f83d9abUL; c->h[7]=0x5be0cd19UL; | ||
36 | c->Nl=0; c->Nh=0; | ||
37 | c->num=0; c->md_len=SHA256_DIGEST_LENGTH; | ||
38 | return 1; | ||
39 | } | ||
40 | |||
41 | unsigned char *SHA224(const unsigned char *d, size_t n, unsigned char *md) | ||
42 | { | ||
43 | SHA256_CTX c; | ||
44 | static unsigned char m[SHA224_DIGEST_LENGTH]; | ||
45 | |||
46 | if (md == NULL) md=m; | ||
47 | SHA224_Init(&c); | ||
48 | SHA256_Update(&c,d,n); | ||
49 | SHA256_Final(md,&c); | ||
50 | OPENSSL_cleanse(&c,sizeof(c)); | ||
51 | return(md); | ||
52 | } | ||
53 | |||
54 | unsigned char *SHA256(const unsigned char *d, size_t n, unsigned char *md) | ||
55 | { | ||
56 | SHA256_CTX c; | ||
57 | static unsigned char m[SHA256_DIGEST_LENGTH]; | ||
58 | |||
59 | if (md == NULL) md=m; | ||
60 | SHA256_Init(&c); | ||
61 | SHA256_Update(&c,d,n); | ||
62 | SHA256_Final(md,&c); | ||
63 | OPENSSL_cleanse(&c,sizeof(c)); | ||
64 | return(md); | ||
65 | } | ||
66 | |||
67 | int SHA224_Update(SHA256_CTX *c, const void *data, size_t len) | ||
68 | { return SHA256_Update (c,data,len); } | ||
69 | int SHA224_Final (unsigned char *md, SHA256_CTX *c) | ||
70 | { return SHA256_Final (md,c); } | ||
71 | |||
72 | #define DATA_ORDER_IS_BIG_ENDIAN | ||
73 | |||
74 | #define HASH_LONG SHA_LONG | ||
75 | #define HASH_CTX SHA256_CTX | ||
76 | #define HASH_CBLOCK SHA_CBLOCK | ||
77 | /* | ||
78 | * Note that FIPS180-2 discusses "Truncation of the Hash Function Output." | ||
79 | * default: case below covers for it. It's not clear however if it's | ||
80 | * permitted to truncate to amount of bytes not divisible by 4. I bet not, | ||
81 | * but if it is, then default: case shall be extended. For reference. | ||
82 | * Idea behind separate cases for pre-defined lenghts is to let the | ||
83 | * compiler decide if it's appropriate to unroll small loops. | ||
84 | */ | ||
85 | #define HASH_MAKE_STRING(c,s) do { \ | ||
86 | unsigned long ll; \ | ||
87 | unsigned int xn; \ | ||
88 | switch ((c)->md_len) \ | ||
89 | { case SHA224_DIGEST_LENGTH: \ | ||
90 | for (xn=0;xn<SHA224_DIGEST_LENGTH/4;xn++) \ | ||
91 | { ll=(c)->h[xn]; HOST_l2c(ll,(s)); } \ | ||
92 | break; \ | ||
93 | case SHA256_DIGEST_LENGTH: \ | ||
94 | for (xn=0;xn<SHA256_DIGEST_LENGTH/4;xn++) \ | ||
95 | { ll=(c)->h[xn]; HOST_l2c(ll,(s)); } \ | ||
96 | break; \ | ||
97 | default: \ | ||
98 | if ((c)->md_len > SHA256_DIGEST_LENGTH) \ | ||
99 | return 0; \ | ||
100 | for (xn=0;xn<(c)->md_len/4;xn++) \ | ||
101 | { ll=(c)->h[xn]; HOST_l2c(ll,(s)); } \ | ||
102 | break; \ | ||
103 | } \ | ||
104 | } while (0) | ||
105 | |||
106 | #define HASH_UPDATE SHA256_Update | ||
107 | #define HASH_TRANSFORM SHA256_Transform | ||
108 | #define HASH_FINAL SHA256_Final | ||
109 | #define HASH_BLOCK_DATA_ORDER sha256_block_data_order | ||
110 | #ifndef SHA256_ASM | ||
111 | static | ||
112 | #endif | ||
113 | void sha256_block_data_order (SHA256_CTX *ctx, const void *in, size_t num); | ||
114 | |||
115 | #include "md32_common.h" | ||
116 | |||
117 | #ifndef SHA256_ASM | ||
118 | static const SHA_LONG K256[64] = { | ||
119 | 0x428a2f98UL,0x71374491UL,0xb5c0fbcfUL,0xe9b5dba5UL, | ||
120 | 0x3956c25bUL,0x59f111f1UL,0x923f82a4UL,0xab1c5ed5UL, | ||
121 | 0xd807aa98UL,0x12835b01UL,0x243185beUL,0x550c7dc3UL, | ||
122 | 0x72be5d74UL,0x80deb1feUL,0x9bdc06a7UL,0xc19bf174UL, | ||
123 | 0xe49b69c1UL,0xefbe4786UL,0x0fc19dc6UL,0x240ca1ccUL, | ||
124 | 0x2de92c6fUL,0x4a7484aaUL,0x5cb0a9dcUL,0x76f988daUL, | ||
125 | 0x983e5152UL,0xa831c66dUL,0xb00327c8UL,0xbf597fc7UL, | ||
126 | 0xc6e00bf3UL,0xd5a79147UL,0x06ca6351UL,0x14292967UL, | ||
127 | 0x27b70a85UL,0x2e1b2138UL,0x4d2c6dfcUL,0x53380d13UL, | ||
128 | 0x650a7354UL,0x766a0abbUL,0x81c2c92eUL,0x92722c85UL, | ||
129 | 0xa2bfe8a1UL,0xa81a664bUL,0xc24b8b70UL,0xc76c51a3UL, | ||
130 | 0xd192e819UL,0xd6990624UL,0xf40e3585UL,0x106aa070UL, | ||
131 | 0x19a4c116UL,0x1e376c08UL,0x2748774cUL,0x34b0bcb5UL, | ||
132 | 0x391c0cb3UL,0x4ed8aa4aUL,0x5b9cca4fUL,0x682e6ff3UL, | ||
133 | 0x748f82eeUL,0x78a5636fUL,0x84c87814UL,0x8cc70208UL, | ||
134 | 0x90befffaUL,0xa4506cebUL,0xbef9a3f7UL,0xc67178f2UL }; | ||
135 | |||
136 | /* | ||
137 | * FIPS specification refers to right rotations, while our ROTATE macro | ||
138 | * is left one. This is why you might notice that rotation coefficients | ||
139 | * differ from those observed in FIPS document by 32-N... | ||
140 | */ | ||
141 | #define Sigma0(x) (ROTATE((x),30) ^ ROTATE((x),19) ^ ROTATE((x),10)) | ||
142 | #define Sigma1(x) (ROTATE((x),26) ^ ROTATE((x),21) ^ ROTATE((x),7)) | ||
143 | #define sigma0(x) (ROTATE((x),25) ^ ROTATE((x),14) ^ ((x)>>3)) | ||
144 | #define sigma1(x) (ROTATE((x),15) ^ ROTATE((x),13) ^ ((x)>>10)) | ||
145 | |||
146 | #define Ch(x,y,z) (((x) & (y)) ^ ((~(x)) & (z))) | ||
147 | #define Maj(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z))) | ||
148 | |||
149 | #ifdef OPENSSL_SMALL_FOOTPRINT | ||
150 | |||
151 | static void sha256_block_data_order (SHA256_CTX *ctx, const void *in, size_t num) | ||
152 | { | ||
153 | unsigned MD32_REG_T a,b,c,d,e,f,g,h,s0,s1,T1,T2; | ||
154 | SHA_LONG X[16],l; | ||
155 | int i; | ||
156 | const unsigned char *data=in; | ||
157 | |||
158 | while (num--) { | ||
159 | |||
160 | a = ctx->h[0]; b = ctx->h[1]; c = ctx->h[2]; d = ctx->h[3]; | ||
161 | e = ctx->h[4]; f = ctx->h[5]; g = ctx->h[6]; h = ctx->h[7]; | ||
162 | |||
163 | for (i=0;i<16;i++) | ||
164 | { | ||
165 | HOST_c2l(data,l); T1 = X[i] = l; | ||
166 | T1 += h + Sigma1(e) + Ch(e,f,g) + K256[i]; | ||
167 | T2 = Sigma0(a) + Maj(a,b,c); | ||
168 | h = g; g = f; f = e; e = d + T1; | ||
169 | d = c; c = b; b = a; a = T1 + T2; | ||
170 | } | ||
171 | |||
172 | for (;i<64;i++) | ||
173 | { | ||
174 | s0 = X[(i+1)&0x0f]; s0 = sigma0(s0); | ||
175 | s1 = X[(i+14)&0x0f]; s1 = sigma1(s1); | ||
176 | |||
177 | T1 = X[i&0xf] += s0 + s1 + X[(i+9)&0xf]; | ||
178 | T1 += h + Sigma1(e) + Ch(e,f,g) + K256[i]; | ||
179 | T2 = Sigma0(a) + Maj(a,b,c); | ||
180 | h = g; g = f; f = e; e = d + T1; | ||
181 | d = c; c = b; b = a; a = T1 + T2; | ||
182 | } | ||
183 | |||
184 | ctx->h[0] += a; ctx->h[1] += b; ctx->h[2] += c; ctx->h[3] += d; | ||
185 | ctx->h[4] += e; ctx->h[5] += f; ctx->h[6] += g; ctx->h[7] += h; | ||
186 | |||
187 | } | ||
188 | } | ||
189 | |||
190 | #else | ||
191 | |||
192 | #define ROUND_00_15(i,a,b,c,d,e,f,g,h) do { \ | ||
193 | T1 += h + Sigma1(e) + Ch(e,f,g) + K256[i]; \ | ||
194 | h = Sigma0(a) + Maj(a,b,c); \ | ||
195 | d += T1; h += T1; } while (0) | ||
196 | |||
197 | #define ROUND_16_63(i,a,b,c,d,e,f,g,h,X) do { \ | ||
198 | s0 = X[(i+1)&0x0f]; s0 = sigma0(s0); \ | ||
199 | s1 = X[(i+14)&0x0f]; s1 = sigma1(s1); \ | ||
200 | T1 = X[(i)&0x0f] += s0 + s1 + X[(i+9)&0x0f]; \ | ||
201 | ROUND_00_15(i,a,b,c,d,e,f,g,h); } while (0) | ||
202 | |||
203 | static void sha256_block_data_order (SHA256_CTX *ctx, const void *in, size_t num) | ||
204 | { | ||
205 | unsigned MD32_REG_T a,b,c,d,e,f,g,h,s0,s1,T1; | ||
206 | SHA_LONG X[16]; | ||
207 | int i; | ||
208 | const unsigned char *data=in; | ||
209 | const union { long one; char little; } is_endian = {1}; | ||
210 | |||
211 | while (num--) { | ||
212 | |||
213 | a = ctx->h[0]; b = ctx->h[1]; c = ctx->h[2]; d = ctx->h[3]; | ||
214 | e = ctx->h[4]; f = ctx->h[5]; g = ctx->h[6]; h = ctx->h[7]; | ||
215 | |||
216 | if (!is_endian.little && sizeof(SHA_LONG)==4 && ((size_t)in%4)==0) | ||
217 | { | ||
218 | const SHA_LONG *W=(const SHA_LONG *)data; | ||
219 | |||
220 | T1 = X[0] = W[0]; ROUND_00_15(0,a,b,c,d,e,f,g,h); | ||
221 | T1 = X[1] = W[1]; ROUND_00_15(1,h,a,b,c,d,e,f,g); | ||
222 | T1 = X[2] = W[2]; ROUND_00_15(2,g,h,a,b,c,d,e,f); | ||
223 | T1 = X[3] = W[3]; ROUND_00_15(3,f,g,h,a,b,c,d,e); | ||
224 | T1 = X[4] = W[4]; ROUND_00_15(4,e,f,g,h,a,b,c,d); | ||
225 | T1 = X[5] = W[5]; ROUND_00_15(5,d,e,f,g,h,a,b,c); | ||
226 | T1 = X[6] = W[6]; ROUND_00_15(6,c,d,e,f,g,h,a,b); | ||
227 | T1 = X[7] = W[7]; ROUND_00_15(7,b,c,d,e,f,g,h,a); | ||
228 | T1 = X[8] = W[8]; ROUND_00_15(8,a,b,c,d,e,f,g,h); | ||
229 | T1 = X[9] = W[9]; ROUND_00_15(9,h,a,b,c,d,e,f,g); | ||
230 | T1 = X[10] = W[10]; ROUND_00_15(10,g,h,a,b,c,d,e,f); | ||
231 | T1 = X[11] = W[11]; ROUND_00_15(11,f,g,h,a,b,c,d,e); | ||
232 | T1 = X[12] = W[12]; ROUND_00_15(12,e,f,g,h,a,b,c,d); | ||
233 | T1 = X[13] = W[13]; ROUND_00_15(13,d,e,f,g,h,a,b,c); | ||
234 | T1 = X[14] = W[14]; ROUND_00_15(14,c,d,e,f,g,h,a,b); | ||
235 | T1 = X[15] = W[15]; ROUND_00_15(15,b,c,d,e,f,g,h,a); | ||
236 | |||
237 | data += SHA256_CBLOCK; | ||
238 | } | ||
239 | else | ||
240 | { | ||
241 | SHA_LONG l; | ||
242 | |||
243 | HOST_c2l(data,l); T1 = X[0] = l; ROUND_00_15(0,a,b,c,d,e,f,g,h); | ||
244 | HOST_c2l(data,l); T1 = X[1] = l; ROUND_00_15(1,h,a,b,c,d,e,f,g); | ||
245 | HOST_c2l(data,l); T1 = X[2] = l; ROUND_00_15(2,g,h,a,b,c,d,e,f); | ||
246 | HOST_c2l(data,l); T1 = X[3] = l; ROUND_00_15(3,f,g,h,a,b,c,d,e); | ||
247 | HOST_c2l(data,l); T1 = X[4] = l; ROUND_00_15(4,e,f,g,h,a,b,c,d); | ||
248 | HOST_c2l(data,l); T1 = X[5] = l; ROUND_00_15(5,d,e,f,g,h,a,b,c); | ||
249 | HOST_c2l(data,l); T1 = X[6] = l; ROUND_00_15(6,c,d,e,f,g,h,a,b); | ||
250 | HOST_c2l(data,l); T1 = X[7] = l; ROUND_00_15(7,b,c,d,e,f,g,h,a); | ||
251 | HOST_c2l(data,l); T1 = X[8] = l; ROUND_00_15(8,a,b,c,d,e,f,g,h); | ||
252 | HOST_c2l(data,l); T1 = X[9] = l; ROUND_00_15(9,h,a,b,c,d,e,f,g); | ||
253 | HOST_c2l(data,l); T1 = X[10] = l; ROUND_00_15(10,g,h,a,b,c,d,e,f); | ||
254 | HOST_c2l(data,l); T1 = X[11] = l; ROUND_00_15(11,f,g,h,a,b,c,d,e); | ||
255 | HOST_c2l(data,l); T1 = X[12] = l; ROUND_00_15(12,e,f,g,h,a,b,c,d); | ||
256 | HOST_c2l(data,l); T1 = X[13] = l; ROUND_00_15(13,d,e,f,g,h,a,b,c); | ||
257 | HOST_c2l(data,l); T1 = X[14] = l; ROUND_00_15(14,c,d,e,f,g,h,a,b); | ||
258 | HOST_c2l(data,l); T1 = X[15] = l; ROUND_00_15(15,b,c,d,e,f,g,h,a); | ||
259 | } | ||
260 | |||
261 | for (i=16;i<64;i+=8) | ||
262 | { | ||
263 | ROUND_16_63(i+0,a,b,c,d,e,f,g,h,X); | ||
264 | ROUND_16_63(i+1,h,a,b,c,d,e,f,g,X); | ||
265 | ROUND_16_63(i+2,g,h,a,b,c,d,e,f,X); | ||
266 | ROUND_16_63(i+3,f,g,h,a,b,c,d,e,X); | ||
267 | ROUND_16_63(i+4,e,f,g,h,a,b,c,d,X); | ||
268 | ROUND_16_63(i+5,d,e,f,g,h,a,b,c,X); | ||
269 | ROUND_16_63(i+6,c,d,e,f,g,h,a,b,X); | ||
270 | ROUND_16_63(i+7,b,c,d,e,f,g,h,a,X); | ||
271 | } | ||
272 | |||
273 | ctx->h[0] += a; ctx->h[1] += b; ctx->h[2] += c; ctx->h[3] += d; | ||
274 | ctx->h[4] += e; ctx->h[5] += f; ctx->h[6] += g; ctx->h[7] += h; | ||
275 | |||
276 | } | ||
277 | } | ||
278 | |||
279 | #endif | ||
280 | #endif /* SHA256_ASM */ | ||
281 | |||
282 | #endif /* OPENSSL_NO_SHA256 */ | ||
diff --git a/src/lib/libcrypto/sha/sha512.c b/src/lib/libcrypto/sha/sha512.c new file mode 100644 index 0000000000..987fc07c99 --- /dev/null +++ b/src/lib/libcrypto/sha/sha512.c | |||
@@ -0,0 +1,537 @@ | |||
1 | /* crypto/sha/sha512.c */ | ||
2 | /* ==================================================================== | ||
3 | * Copyright (c) 2004 The OpenSSL Project. All rights reserved | ||
4 | * according to the OpenSSL license [found in ../../LICENSE]. | ||
5 | * ==================================================================== | ||
6 | */ | ||
7 | #include <openssl/opensslconf.h> | ||
8 | #if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA512) | ||
9 | /* | ||
10 | * IMPLEMENTATION NOTES. | ||
11 | * | ||
12 | * As you might have noticed 32-bit hash algorithms: | ||
13 | * | ||
14 | * - permit SHA_LONG to be wider than 32-bit (case on CRAY); | ||
15 | * - optimized versions implement two transform functions: one operating | ||
16 | * on [aligned] data in host byte order and one - on data in input | ||
17 | * stream byte order; | ||
18 | * - share common byte-order neutral collector and padding function | ||
19 | * implementations, ../md32_common.h; | ||
20 | * | ||
21 | * Neither of the above applies to this SHA-512 implementations. Reasons | ||
22 | * [in reverse order] are: | ||
23 | * | ||
24 | * - it's the only 64-bit hash algorithm for the moment of this writing, | ||
25 | * there is no need for common collector/padding implementation [yet]; | ||
26 | * - by supporting only one transform function [which operates on | ||
27 | * *aligned* data in input stream byte order, big-endian in this case] | ||
28 | * we minimize burden of maintenance in two ways: a) collector/padding | ||
29 | * function is simpler; b) only one transform function to stare at; | ||
30 | * - SHA_LONG64 is required to be exactly 64-bit in order to be able to | ||
31 | * apply a number of optimizations to mitigate potential performance | ||
32 | * penalties caused by previous design decision; | ||
33 | * | ||
34 | * Caveat lector. | ||
35 | * | ||
36 | * Implementation relies on the fact that "long long" is 64-bit on | ||
37 | * both 32- and 64-bit platforms. If some compiler vendor comes up | ||
38 | * with 128-bit long long, adjustment to sha.h would be required. | ||
39 | * As this implementation relies on 64-bit integer type, it's totally | ||
40 | * inappropriate for platforms which don't support it, most notably | ||
41 | * 16-bit platforms. | ||
42 | * <appro@fy.chalmers.se> | ||
43 | */ | ||
44 | #include <stdlib.h> | ||
45 | #include <string.h> | ||
46 | |||
47 | #include <openssl/crypto.h> | ||
48 | #include <openssl/sha.h> | ||
49 | #include <openssl/opensslv.h> | ||
50 | |||
51 | #include "cryptlib.h" | ||
52 | |||
53 | const char SHA512_version[]="SHA-512" OPENSSL_VERSION_PTEXT; | ||
54 | |||
55 | #if defined(__i386) || defined(__i386__) || defined(_M_IX86) || \ | ||
56 | defined(__x86_64) || defined(_M_AMD64) || defined(_M_X64) || \ | ||
57 | defined(__s390__) || defined(__s390x__) || \ | ||
58 | defined(SHA512_ASM) | ||
59 | #define SHA512_BLOCK_CAN_MANAGE_UNALIGNED_DATA | ||
60 | #endif | ||
61 | |||
62 | int SHA384_Init (SHA512_CTX *c) | ||
63 | { | ||
64 | c->h[0]=U64(0xcbbb9d5dc1059ed8); | ||
65 | c->h[1]=U64(0x629a292a367cd507); | ||
66 | c->h[2]=U64(0x9159015a3070dd17); | ||
67 | c->h[3]=U64(0x152fecd8f70e5939); | ||
68 | c->h[4]=U64(0x67332667ffc00b31); | ||
69 | c->h[5]=U64(0x8eb44a8768581511); | ||
70 | c->h[6]=U64(0xdb0c2e0d64f98fa7); | ||
71 | c->h[7]=U64(0x47b5481dbefa4fa4); | ||
72 | c->Nl=0; c->Nh=0; | ||
73 | c->num=0; c->md_len=SHA384_DIGEST_LENGTH; | ||
74 | return 1; | ||
75 | } | ||
76 | |||
77 | int SHA512_Init (SHA512_CTX *c) | ||
78 | { | ||
79 | c->h[0]=U64(0x6a09e667f3bcc908); | ||
80 | c->h[1]=U64(0xbb67ae8584caa73b); | ||
81 | c->h[2]=U64(0x3c6ef372fe94f82b); | ||
82 | c->h[3]=U64(0xa54ff53a5f1d36f1); | ||
83 | c->h[4]=U64(0x510e527fade682d1); | ||
84 | c->h[5]=U64(0x9b05688c2b3e6c1f); | ||
85 | c->h[6]=U64(0x1f83d9abfb41bd6b); | ||
86 | c->h[7]=U64(0x5be0cd19137e2179); | ||
87 | c->Nl=0; c->Nh=0; | ||
88 | c->num=0; c->md_len=SHA512_DIGEST_LENGTH; | ||
89 | return 1; | ||
90 | } | ||
91 | |||
92 | #ifndef SHA512_ASM | ||
93 | static | ||
94 | #endif | ||
95 | void sha512_block_data_order (SHA512_CTX *ctx, const void *in, size_t num); | ||
96 | |||
97 | int SHA512_Final (unsigned char *md, SHA512_CTX *c) | ||
98 | { | ||
99 | unsigned char *p=(unsigned char *)c->u.p; | ||
100 | size_t n=c->num; | ||
101 | |||
102 | p[n]=0x80; /* There always is a room for one */ | ||
103 | n++; | ||
104 | if (n > (sizeof(c->u)-16)) | ||
105 | memset (p+n,0,sizeof(c->u)-n), n=0, | ||
106 | sha512_block_data_order (c,p,1); | ||
107 | |||
108 | memset (p+n,0,sizeof(c->u)-16-n); | ||
109 | #ifdef B_ENDIAN | ||
110 | c->u.d[SHA_LBLOCK-2] = c->Nh; | ||
111 | c->u.d[SHA_LBLOCK-1] = c->Nl; | ||
112 | #else | ||
113 | p[sizeof(c->u)-1] = (unsigned char)(c->Nl); | ||
114 | p[sizeof(c->u)-2] = (unsigned char)(c->Nl>>8); | ||
115 | p[sizeof(c->u)-3] = (unsigned char)(c->Nl>>16); | ||
116 | p[sizeof(c->u)-4] = (unsigned char)(c->Nl>>24); | ||
117 | p[sizeof(c->u)-5] = (unsigned char)(c->Nl>>32); | ||
118 | p[sizeof(c->u)-6] = (unsigned char)(c->Nl>>40); | ||
119 | p[sizeof(c->u)-7] = (unsigned char)(c->Nl>>48); | ||
120 | p[sizeof(c->u)-8] = (unsigned char)(c->Nl>>56); | ||
121 | p[sizeof(c->u)-9] = (unsigned char)(c->Nh); | ||
122 | p[sizeof(c->u)-10] = (unsigned char)(c->Nh>>8); | ||
123 | p[sizeof(c->u)-11] = (unsigned char)(c->Nh>>16); | ||
124 | p[sizeof(c->u)-12] = (unsigned char)(c->Nh>>24); | ||
125 | p[sizeof(c->u)-13] = (unsigned char)(c->Nh>>32); | ||
126 | p[sizeof(c->u)-14] = (unsigned char)(c->Nh>>40); | ||
127 | p[sizeof(c->u)-15] = (unsigned char)(c->Nh>>48); | ||
128 | p[sizeof(c->u)-16] = (unsigned char)(c->Nh>>56); | ||
129 | #endif | ||
130 | |||
131 | sha512_block_data_order (c,p,1); | ||
132 | |||
133 | if (md==0) return 0; | ||
134 | |||
135 | switch (c->md_len) | ||
136 | { | ||
137 | /* Let compiler decide if it's appropriate to unroll... */ | ||
138 | case SHA384_DIGEST_LENGTH: | ||
139 | for (n=0;n<SHA384_DIGEST_LENGTH/8;n++) | ||
140 | { | ||
141 | SHA_LONG64 t = c->h[n]; | ||
142 | |||
143 | *(md++) = (unsigned char)(t>>56); | ||
144 | *(md++) = (unsigned char)(t>>48); | ||
145 | *(md++) = (unsigned char)(t>>40); | ||
146 | *(md++) = (unsigned char)(t>>32); | ||
147 | *(md++) = (unsigned char)(t>>24); | ||
148 | *(md++) = (unsigned char)(t>>16); | ||
149 | *(md++) = (unsigned char)(t>>8); | ||
150 | *(md++) = (unsigned char)(t); | ||
151 | } | ||
152 | break; | ||
153 | case SHA512_DIGEST_LENGTH: | ||
154 | for (n=0;n<SHA512_DIGEST_LENGTH/8;n++) | ||
155 | { | ||
156 | SHA_LONG64 t = c->h[n]; | ||
157 | |||
158 | *(md++) = (unsigned char)(t>>56); | ||
159 | *(md++) = (unsigned char)(t>>48); | ||
160 | *(md++) = (unsigned char)(t>>40); | ||
161 | *(md++) = (unsigned char)(t>>32); | ||
162 | *(md++) = (unsigned char)(t>>24); | ||
163 | *(md++) = (unsigned char)(t>>16); | ||
164 | *(md++) = (unsigned char)(t>>8); | ||
165 | *(md++) = (unsigned char)(t); | ||
166 | } | ||
167 | break; | ||
168 | /* ... as well as make sure md_len is not abused. */ | ||
169 | default: return 0; | ||
170 | } | ||
171 | |||
172 | return 1; | ||
173 | } | ||
174 | |||
175 | int SHA384_Final (unsigned char *md,SHA512_CTX *c) | ||
176 | { return SHA512_Final (md,c); } | ||
177 | |||
178 | int SHA512_Update (SHA512_CTX *c, const void *_data, size_t len) | ||
179 | { | ||
180 | SHA_LONG64 l; | ||
181 | unsigned char *p=c->u.p; | ||
182 | const unsigned char *data=(const unsigned char *)_data; | ||
183 | |||
184 | if (len==0) return 1; | ||
185 | |||
186 | l = (c->Nl+(((SHA_LONG64)len)<<3))&U64(0xffffffffffffffff); | ||
187 | if (l < c->Nl) c->Nh++; | ||
188 | if (sizeof(len)>=8) c->Nh+=(((SHA_LONG64)len)>>61); | ||
189 | c->Nl=l; | ||
190 | |||
191 | if (c->num != 0) | ||
192 | { | ||
193 | size_t n = sizeof(c->u) - c->num; | ||
194 | |||
195 | if (len < n) | ||
196 | { | ||
197 | memcpy (p+c->num,data,len), c->num += len; | ||
198 | return 1; | ||
199 | } | ||
200 | else { | ||
201 | memcpy (p+c->num,data,n), c->num = 0; | ||
202 | len-=n, data+=n; | ||
203 | sha512_block_data_order (c,p,1); | ||
204 | } | ||
205 | } | ||
206 | |||
207 | if (len >= sizeof(c->u)) | ||
208 | { | ||
209 | #ifndef SHA512_BLOCK_CAN_MANAGE_UNALIGNED_DATA | ||
210 | if ((size_t)data%sizeof(c->u.d[0]) != 0) | ||
211 | while (len >= sizeof(c->u)) | ||
212 | memcpy (p,data,sizeof(c->u)), | ||
213 | sha512_block_data_order (c,p,1), | ||
214 | len -= sizeof(c->u), | ||
215 | data += sizeof(c->u); | ||
216 | else | ||
217 | #endif | ||
218 | sha512_block_data_order (c,data,len/sizeof(c->u)), | ||
219 | data += len, | ||
220 | len %= sizeof(c->u), | ||
221 | data -= len; | ||
222 | } | ||
223 | |||
224 | if (len != 0) memcpy (p,data,len), c->num = (int)len; | ||
225 | |||
226 | return 1; | ||
227 | } | ||
228 | |||
229 | int SHA384_Update (SHA512_CTX *c, const void *data, size_t len) | ||
230 | { return SHA512_Update (c,data,len); } | ||
231 | |||
232 | void SHA512_Transform (SHA512_CTX *c, const unsigned char *data) | ||
233 | { sha512_block_data_order (c,data,1); } | ||
234 | |||
235 | unsigned char *SHA384(const unsigned char *d, size_t n, unsigned char *md) | ||
236 | { | ||
237 | SHA512_CTX c; | ||
238 | static unsigned char m[SHA384_DIGEST_LENGTH]; | ||
239 | |||
240 | if (md == NULL) md=m; | ||
241 | SHA384_Init(&c); | ||
242 | SHA512_Update(&c,d,n); | ||
243 | SHA512_Final(md,&c); | ||
244 | OPENSSL_cleanse(&c,sizeof(c)); | ||
245 | return(md); | ||
246 | } | ||
247 | |||
248 | unsigned char *SHA512(const unsigned char *d, size_t n, unsigned char *md) | ||
249 | { | ||
250 | SHA512_CTX c; | ||
251 | static unsigned char m[SHA512_DIGEST_LENGTH]; | ||
252 | |||
253 | if (md == NULL) md=m; | ||
254 | SHA512_Init(&c); | ||
255 | SHA512_Update(&c,d,n); | ||
256 | SHA512_Final(md,&c); | ||
257 | OPENSSL_cleanse(&c,sizeof(c)); | ||
258 | return(md); | ||
259 | } | ||
260 | |||
261 | #ifndef SHA512_ASM | ||
262 | static const SHA_LONG64 K512[80] = { | ||
263 | U64(0x428a2f98d728ae22),U64(0x7137449123ef65cd), | ||
264 | U64(0xb5c0fbcfec4d3b2f),U64(0xe9b5dba58189dbbc), | ||
265 | U64(0x3956c25bf348b538),U64(0x59f111f1b605d019), | ||
266 | U64(0x923f82a4af194f9b),U64(0xab1c5ed5da6d8118), | ||
267 | U64(0xd807aa98a3030242),U64(0x12835b0145706fbe), | ||
268 | U64(0x243185be4ee4b28c),U64(0x550c7dc3d5ffb4e2), | ||
269 | U64(0x72be5d74f27b896f),U64(0x80deb1fe3b1696b1), | ||
270 | U64(0x9bdc06a725c71235),U64(0xc19bf174cf692694), | ||
271 | U64(0xe49b69c19ef14ad2),U64(0xefbe4786384f25e3), | ||
272 | U64(0x0fc19dc68b8cd5b5),U64(0x240ca1cc77ac9c65), | ||
273 | U64(0x2de92c6f592b0275),U64(0x4a7484aa6ea6e483), | ||
274 | U64(0x5cb0a9dcbd41fbd4),U64(0x76f988da831153b5), | ||
275 | U64(0x983e5152ee66dfab),U64(0xa831c66d2db43210), | ||
276 | U64(0xb00327c898fb213f),U64(0xbf597fc7beef0ee4), | ||
277 | U64(0xc6e00bf33da88fc2),U64(0xd5a79147930aa725), | ||
278 | U64(0x06ca6351e003826f),U64(0x142929670a0e6e70), | ||
279 | U64(0x27b70a8546d22ffc),U64(0x2e1b21385c26c926), | ||
280 | U64(0x4d2c6dfc5ac42aed),U64(0x53380d139d95b3df), | ||
281 | U64(0x650a73548baf63de),U64(0x766a0abb3c77b2a8), | ||
282 | U64(0x81c2c92e47edaee6),U64(0x92722c851482353b), | ||
283 | U64(0xa2bfe8a14cf10364),U64(0xa81a664bbc423001), | ||
284 | U64(0xc24b8b70d0f89791),U64(0xc76c51a30654be30), | ||
285 | U64(0xd192e819d6ef5218),U64(0xd69906245565a910), | ||
286 | U64(0xf40e35855771202a),U64(0x106aa07032bbd1b8), | ||
287 | U64(0x19a4c116b8d2d0c8),U64(0x1e376c085141ab53), | ||
288 | U64(0x2748774cdf8eeb99),U64(0x34b0bcb5e19b48a8), | ||
289 | U64(0x391c0cb3c5c95a63),U64(0x4ed8aa4ae3418acb), | ||
290 | U64(0x5b9cca4f7763e373),U64(0x682e6ff3d6b2b8a3), | ||
291 | U64(0x748f82ee5defb2fc),U64(0x78a5636f43172f60), | ||
292 | U64(0x84c87814a1f0ab72),U64(0x8cc702081a6439ec), | ||
293 | U64(0x90befffa23631e28),U64(0xa4506cebde82bde9), | ||
294 | U64(0xbef9a3f7b2c67915),U64(0xc67178f2e372532b), | ||
295 | U64(0xca273eceea26619c),U64(0xd186b8c721c0c207), | ||
296 | U64(0xeada7dd6cde0eb1e),U64(0xf57d4f7fee6ed178), | ||
297 | U64(0x06f067aa72176fba),U64(0x0a637dc5a2c898a6), | ||
298 | U64(0x113f9804bef90dae),U64(0x1b710b35131c471b), | ||
299 | U64(0x28db77f523047d84),U64(0x32caab7b40c72493), | ||
300 | U64(0x3c9ebe0a15c9bebc),U64(0x431d67c49c100d4c), | ||
301 | U64(0x4cc5d4becb3e42b6),U64(0x597f299cfc657e2a), | ||
302 | U64(0x5fcb6fab3ad6faec),U64(0x6c44198c4a475817) }; | ||
303 | |||
304 | #ifndef PEDANTIC | ||
305 | # if defined(__GNUC__) && __GNUC__>=2 && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM) | ||
306 | # if defined(__x86_64) || defined(__x86_64__) | ||
307 | # define ROTR(a,n) ({ unsigned long ret; \ | ||
308 | asm ("rorq %1,%0" \ | ||
309 | : "=r"(ret) \ | ||
310 | : "J"(n),"0"(a) \ | ||
311 | : "cc"); ret; }) | ||
312 | # if !defined(B_ENDIAN) | ||
313 | # define PULL64(x) ({ SHA_LONG64 ret=*((const SHA_LONG64 *)(&(x))); \ | ||
314 | asm ("bswapq %0" \ | ||
315 | : "=r"(ret) \ | ||
316 | : "0"(ret)); ret; }) | ||
317 | # endif | ||
318 | # elif (defined(__i386) || defined(__i386__)) && !defined(B_ENDIAN) | ||
319 | # if defined(I386_ONLY) | ||
320 | # define PULL64(x) ({ const unsigned int *p=(const unsigned int *)(&(x));\ | ||
321 | unsigned int hi=p[0],lo=p[1]; \ | ||
322 | asm("xchgb %%ah,%%al;xchgb %%dh,%%dl;"\ | ||
323 | "roll $16,%%eax; roll $16,%%edx; "\ | ||
324 | "xchgb %%ah,%%al;xchgb %%dh,%%dl;" \ | ||
325 | : "=a"(lo),"=d"(hi) \ | ||
326 | : "0"(lo),"1"(hi) : "cc"); \ | ||
327 | ((SHA_LONG64)hi)<<32|lo; }) | ||
328 | # else | ||
329 | # define PULL64(x) ({ const unsigned int *p=(const unsigned int *)(&(x));\ | ||
330 | unsigned int hi=p[0],lo=p[1]; \ | ||
331 | asm ("bswapl %0; bswapl %1;" \ | ||
332 | : "=r"(lo),"=r"(hi) \ | ||
333 | : "0"(lo),"1"(hi)); \ | ||
334 | ((SHA_LONG64)hi)<<32|lo; }) | ||
335 | # endif | ||
336 | # elif (defined(_ARCH_PPC) && defined(__64BIT__)) || defined(_ARCH_PPC64) | ||
337 | # define ROTR(a,n) ({ unsigned long ret; \ | ||
338 | asm ("rotrdi %0,%1,%2" \ | ||
339 | : "=r"(ret) \ | ||
340 | : "r"(a),"K"(n)); ret; }) | ||
341 | # endif | ||
342 | # elif defined(_MSC_VER) | ||
343 | # if defined(_WIN64) /* applies to both IA-64 and AMD64 */ | ||
344 | # define ROTR(a,n) _rotr64((a),n) | ||
345 | # endif | ||
346 | # if defined(_M_IX86) && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM) | ||
347 | # if defined(I386_ONLY) | ||
348 | static SHA_LONG64 __fastcall __pull64be(const void *x) | ||
349 | { _asm mov edx, [ecx + 0] | ||
350 | _asm mov eax, [ecx + 4] | ||
351 | _asm xchg dh,dl | ||
352 | _asm xchg ah,al | ||
353 | _asm rol edx,16 | ||
354 | _asm rol eax,16 | ||
355 | _asm xchg dh,dl | ||
356 | _asm xchg ah,al | ||
357 | } | ||
358 | # else | ||
359 | static SHA_LONG64 __fastcall __pull64be(const void *x) | ||
360 | { _asm mov edx, [ecx + 0] | ||
361 | _asm mov eax, [ecx + 4] | ||
362 | _asm bswap edx | ||
363 | _asm bswap eax | ||
364 | } | ||
365 | # endif | ||
366 | # define PULL64(x) __pull64be(&(x)) | ||
367 | # if _MSC_VER<=1200 | ||
368 | # pragma inline_depth(0) | ||
369 | # endif | ||
370 | # endif | ||
371 | # endif | ||
372 | #endif | ||
373 | |||
374 | #ifndef PULL64 | ||
375 | #define B(x,j) (((SHA_LONG64)(*(((const unsigned char *)(&x))+j)))<<((7-j)*8)) | ||
376 | #define PULL64(x) (B(x,0)|B(x,1)|B(x,2)|B(x,3)|B(x,4)|B(x,5)|B(x,6)|B(x,7)) | ||
377 | #endif | ||
378 | |||
379 | #ifndef ROTR | ||
380 | #define ROTR(x,s) (((x)>>s) | (x)<<(64-s)) | ||
381 | #endif | ||
382 | |||
383 | #define Sigma0(x) (ROTR((x),28) ^ ROTR((x),34) ^ ROTR((x),39)) | ||
384 | #define Sigma1(x) (ROTR((x),14) ^ ROTR((x),18) ^ ROTR((x),41)) | ||
385 | #define sigma0(x) (ROTR((x),1) ^ ROTR((x),8) ^ ((x)>>7)) | ||
386 | #define sigma1(x) (ROTR((x),19) ^ ROTR((x),61) ^ ((x)>>6)) | ||
387 | |||
388 | #define Ch(x,y,z) (((x) & (y)) ^ ((~(x)) & (z))) | ||
389 | #define Maj(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z))) | ||
390 | |||
391 | #if defined(OPENSSL_IA32_SSE2) && !defined(OPENSSL_NO_ASM) && !defined(I386_ONLY) | ||
392 | #define GO_FOR_SSE2(ctx,in,num) do { \ | ||
393 | void sha512_block_sse2(void *,const void *,size_t); \ | ||
394 | if (!(OPENSSL_ia32cap_P & (1<<26))) break; \ | ||
395 | sha512_block_sse2(ctx->h,in,num); return; \ | ||
396 | } while (0) | ||
397 | #endif | ||
398 | |||
399 | #ifdef OPENSSL_SMALL_FOOTPRINT | ||
400 | |||
401 | static void sha512_block_data_order (SHA512_CTX *ctx, const void *in, size_t num) | ||
402 | { | ||
403 | const SHA_LONG64 *W=in; | ||
404 | SHA_LONG64 a,b,c,d,e,f,g,h,s0,s1,T1,T2; | ||
405 | SHA_LONG64 X[16]; | ||
406 | int i; | ||
407 | |||
408 | #ifdef GO_FOR_SSE2 | ||
409 | GO_FOR_SSE2(ctx,in,num); | ||
410 | #endif | ||
411 | |||
412 | while (num--) { | ||
413 | |||
414 | a = ctx->h[0]; b = ctx->h[1]; c = ctx->h[2]; d = ctx->h[3]; | ||
415 | e = ctx->h[4]; f = ctx->h[5]; g = ctx->h[6]; h = ctx->h[7]; | ||
416 | |||
417 | for (i=0;i<16;i++) | ||
418 | { | ||
419 | #ifdef B_ENDIAN | ||
420 | T1 = X[i] = W[i]; | ||
421 | #else | ||
422 | T1 = X[i] = PULL64(W[i]); | ||
423 | #endif | ||
424 | T1 += h + Sigma1(e) + Ch(e,f,g) + K512[i]; | ||
425 | T2 = Sigma0(a) + Maj(a,b,c); | ||
426 | h = g; g = f; f = e; e = d + T1; | ||
427 | d = c; c = b; b = a; a = T1 + T2; | ||
428 | } | ||
429 | |||
430 | for (;i<80;i++) | ||
431 | { | ||
432 | s0 = X[(i+1)&0x0f]; s0 = sigma0(s0); | ||
433 | s1 = X[(i+14)&0x0f]; s1 = sigma1(s1); | ||
434 | |||
435 | T1 = X[i&0xf] += s0 + s1 + X[(i+9)&0xf]; | ||
436 | T1 += h + Sigma1(e) + Ch(e,f,g) + K512[i]; | ||
437 | T2 = Sigma0(a) + Maj(a,b,c); | ||
438 | h = g; g = f; f = e; e = d + T1; | ||
439 | d = c; c = b; b = a; a = T1 + T2; | ||
440 | } | ||
441 | |||
442 | ctx->h[0] += a; ctx->h[1] += b; ctx->h[2] += c; ctx->h[3] += d; | ||
443 | ctx->h[4] += e; ctx->h[5] += f; ctx->h[6] += g; ctx->h[7] += h; | ||
444 | |||
445 | W+=SHA_LBLOCK; | ||
446 | } | ||
447 | } | ||
448 | |||
449 | #else | ||
450 | |||
451 | #define ROUND_00_15(i,a,b,c,d,e,f,g,h) do { \ | ||
452 | T1 += h + Sigma1(e) + Ch(e,f,g) + K512[i]; \ | ||
453 | h = Sigma0(a) + Maj(a,b,c); \ | ||
454 | d += T1; h += T1; } while (0) | ||
455 | |||
456 | #define ROUND_16_80(i,a,b,c,d,e,f,g,h,X) do { \ | ||
457 | s0 = X[(i+1)&0x0f]; s0 = sigma0(s0); \ | ||
458 | s1 = X[(i+14)&0x0f]; s1 = sigma1(s1); \ | ||
459 | T1 = X[(i)&0x0f] += s0 + s1 + X[(i+9)&0x0f]; \ | ||
460 | ROUND_00_15(i,a,b,c,d,e,f,g,h); } while (0) | ||
461 | |||
462 | static void sha512_block_data_order (SHA512_CTX *ctx, const void *in, size_t num) | ||
463 | { | ||
464 | const SHA_LONG64 *W=in; | ||
465 | SHA_LONG64 a,b,c,d,e,f,g,h,s0,s1,T1; | ||
466 | SHA_LONG64 X[16]; | ||
467 | int i; | ||
468 | |||
469 | #ifdef GO_FOR_SSE2 | ||
470 | GO_FOR_SSE2(ctx,in,num); | ||
471 | #endif | ||
472 | |||
473 | while (num--) { | ||
474 | |||
475 | a = ctx->h[0]; b = ctx->h[1]; c = ctx->h[2]; d = ctx->h[3]; | ||
476 | e = ctx->h[4]; f = ctx->h[5]; g = ctx->h[6]; h = ctx->h[7]; | ||
477 | |||
478 | #ifdef B_ENDIAN | ||
479 | T1 = X[0] = W[0]; ROUND_00_15(0,a,b,c,d,e,f,g,h); | ||
480 | T1 = X[1] = W[1]; ROUND_00_15(1,h,a,b,c,d,e,f,g); | ||
481 | T1 = X[2] = W[2]; ROUND_00_15(2,g,h,a,b,c,d,e,f); | ||
482 | T1 = X[3] = W[3]; ROUND_00_15(3,f,g,h,a,b,c,d,e); | ||
483 | T1 = X[4] = W[4]; ROUND_00_15(4,e,f,g,h,a,b,c,d); | ||
484 | T1 = X[5] = W[5]; ROUND_00_15(5,d,e,f,g,h,a,b,c); | ||
485 | T1 = X[6] = W[6]; ROUND_00_15(6,c,d,e,f,g,h,a,b); | ||
486 | T1 = X[7] = W[7]; ROUND_00_15(7,b,c,d,e,f,g,h,a); | ||
487 | T1 = X[8] = W[8]; ROUND_00_15(8,a,b,c,d,e,f,g,h); | ||
488 | T1 = X[9] = W[9]; ROUND_00_15(9,h,a,b,c,d,e,f,g); | ||
489 | T1 = X[10] = W[10]; ROUND_00_15(10,g,h,a,b,c,d,e,f); | ||
490 | T1 = X[11] = W[11]; ROUND_00_15(11,f,g,h,a,b,c,d,e); | ||
491 | T1 = X[12] = W[12]; ROUND_00_15(12,e,f,g,h,a,b,c,d); | ||
492 | T1 = X[13] = W[13]; ROUND_00_15(13,d,e,f,g,h,a,b,c); | ||
493 | T1 = X[14] = W[14]; ROUND_00_15(14,c,d,e,f,g,h,a,b); | ||
494 | T1 = X[15] = W[15]; ROUND_00_15(15,b,c,d,e,f,g,h,a); | ||
495 | #else | ||
496 | T1 = X[0] = PULL64(W[0]); ROUND_00_15(0,a,b,c,d,e,f,g,h); | ||
497 | T1 = X[1] = PULL64(W[1]); ROUND_00_15(1,h,a,b,c,d,e,f,g); | ||
498 | T1 = X[2] = PULL64(W[2]); ROUND_00_15(2,g,h,a,b,c,d,e,f); | ||
499 | T1 = X[3] = PULL64(W[3]); ROUND_00_15(3,f,g,h,a,b,c,d,e); | ||
500 | T1 = X[4] = PULL64(W[4]); ROUND_00_15(4,e,f,g,h,a,b,c,d); | ||
501 | T1 = X[5] = PULL64(W[5]); ROUND_00_15(5,d,e,f,g,h,a,b,c); | ||
502 | T1 = X[6] = PULL64(W[6]); ROUND_00_15(6,c,d,e,f,g,h,a,b); | ||
503 | T1 = X[7] = PULL64(W[7]); ROUND_00_15(7,b,c,d,e,f,g,h,a); | ||
504 | T1 = X[8] = PULL64(W[8]); ROUND_00_15(8,a,b,c,d,e,f,g,h); | ||
505 | T1 = X[9] = PULL64(W[9]); ROUND_00_15(9,h,a,b,c,d,e,f,g); | ||
506 | T1 = X[10] = PULL64(W[10]); ROUND_00_15(10,g,h,a,b,c,d,e,f); | ||
507 | T1 = X[11] = PULL64(W[11]); ROUND_00_15(11,f,g,h,a,b,c,d,e); | ||
508 | T1 = X[12] = PULL64(W[12]); ROUND_00_15(12,e,f,g,h,a,b,c,d); | ||
509 | T1 = X[13] = PULL64(W[13]); ROUND_00_15(13,d,e,f,g,h,a,b,c); | ||
510 | T1 = X[14] = PULL64(W[14]); ROUND_00_15(14,c,d,e,f,g,h,a,b); | ||
511 | T1 = X[15] = PULL64(W[15]); ROUND_00_15(15,b,c,d,e,f,g,h,a); | ||
512 | #endif | ||
513 | |||
514 | for (i=16;i<80;i+=8) | ||
515 | { | ||
516 | ROUND_16_80(i+0,a,b,c,d,e,f,g,h,X); | ||
517 | ROUND_16_80(i+1,h,a,b,c,d,e,f,g,X); | ||
518 | ROUND_16_80(i+2,g,h,a,b,c,d,e,f,X); | ||
519 | ROUND_16_80(i+3,f,g,h,a,b,c,d,e,X); | ||
520 | ROUND_16_80(i+4,e,f,g,h,a,b,c,d,X); | ||
521 | ROUND_16_80(i+5,d,e,f,g,h,a,b,c,X); | ||
522 | ROUND_16_80(i+6,c,d,e,f,g,h,a,b,X); | ||
523 | ROUND_16_80(i+7,b,c,d,e,f,g,h,a,X); | ||
524 | } | ||
525 | |||
526 | ctx->h[0] += a; ctx->h[1] += b; ctx->h[2] += c; ctx->h[3] += d; | ||
527 | ctx->h[4] += e; ctx->h[5] += f; ctx->h[6] += g; ctx->h[7] += h; | ||
528 | |||
529 | W+=SHA_LBLOCK; | ||
530 | } | ||
531 | } | ||
532 | |||
533 | #endif | ||
534 | |||
535 | #endif /* SHA512_ASM */ | ||
536 | |||
537 | #endif /* OPENSSL_NO_SHA512 */ | ||
diff --git a/src/lib/libcrypto/sparccpuid.S b/src/lib/libcrypto/sparccpuid.S new file mode 100644 index 0000000000..c17350fc89 --- /dev/null +++ b/src/lib/libcrypto/sparccpuid.S | |||
@@ -0,0 +1,239 @@ | |||
1 | #if defined(__SUNPRO_C) && defined(__sparcv9) | ||
2 | # define ABI64 /* They've said -xarch=v9 at command line */ | ||
3 | #elif defined(__GNUC__) && defined(__arch64__) | ||
4 | # define ABI64 /* They've said -m64 at command line */ | ||
5 | #endif | ||
6 | |||
7 | #ifdef ABI64 | ||
8 | .register %g2,#scratch | ||
9 | .register %g3,#scratch | ||
10 | # define FRAME -192 | ||
11 | # define BIAS 2047 | ||
12 | #else | ||
13 | # define FRAME -96 | ||
14 | # define BIAS 0 | ||
15 | #endif | ||
16 | |||
17 | .text | ||
18 | .align 32 | ||
19 | .global OPENSSL_wipe_cpu | ||
20 | .type OPENSSL_wipe_cpu,#function | ||
21 | ! Keep in mind that this does not excuse us from wiping the stack! | ||
22 | ! This routine wipes registers, but not the backing store [which | ||
23 | ! resides on the stack, toward lower addresses]. To facilitate for | ||
24 | ! stack wiping I return pointer to the top of stack of the *caller*. | ||
25 | OPENSSL_wipe_cpu: | ||
26 | save %sp,FRAME,%sp | ||
27 | nop | ||
28 | #ifdef __sun | ||
29 | #include <sys/trap.h> | ||
30 | ta ST_CLEAN_WINDOWS | ||
31 | #else | ||
32 | call .walk.reg.wins | ||
33 | #endif | ||
34 | nop | ||
35 | call .PIC.zero.up | ||
36 | mov .zero-(.-4),%o0 | ||
37 | ldd [%o0],%f0 | ||
38 | |||
39 | subcc %g0,1,%o0 | ||
40 | ! Following is V9 "rd %ccr,%o0" instruction. However! V8 | ||
41 | ! specification says that it ("rd %asr2,%o0" in V8 terms) does | ||
42 | ! not cause illegal_instruction trap. It therefore can be used | ||
43 | ! to determine if the CPU the code is executing on is V8- or | ||
44 | ! V9-compliant, as V9 returns a distinct value of 0x99, | ||
45 | ! "negative" and "borrow" bits set in both %icc and %xcc. | ||
46 | .word 0x91408000 !rd %ccr,%o0 | ||
47 | cmp %o0,0x99 | ||
48 | bne .v8 | ||
49 | nop | ||
50 | ! Even though we do not use %fp register bank, | ||
51 | ! we wipe it as memcpy might have used it... | ||
52 | .word 0xbfa00040 !fmovd %f0,%f62 | ||
53 | .word 0xbba00040 !... | ||
54 | .word 0xb7a00040 | ||
55 | .word 0xb3a00040 | ||
56 | .word 0xafa00040 | ||
57 | .word 0xaba00040 | ||
58 | .word 0xa7a00040 | ||
59 | .word 0xa3a00040 | ||
60 | .word 0x9fa00040 | ||
61 | .word 0x9ba00040 | ||
62 | .word 0x97a00040 | ||
63 | .word 0x93a00040 | ||
64 | .word 0x8fa00040 | ||
65 | .word 0x8ba00040 | ||
66 | .word 0x87a00040 | ||
67 | .word 0x83a00040 !fmovd %f0,%f32 | ||
68 | .v8: fmovs %f1,%f31 | ||
69 | clr %o0 | ||
70 | fmovs %f0,%f30 | ||
71 | clr %o1 | ||
72 | fmovs %f1,%f29 | ||
73 | clr %o2 | ||
74 | fmovs %f0,%f28 | ||
75 | clr %o3 | ||
76 | fmovs %f1,%f27 | ||
77 | clr %o4 | ||
78 | fmovs %f0,%f26 | ||
79 | clr %o5 | ||
80 | fmovs %f1,%f25 | ||
81 | clr %o7 | ||
82 | fmovs %f0,%f24 | ||
83 | clr %l0 | ||
84 | fmovs %f1,%f23 | ||
85 | clr %l1 | ||
86 | fmovs %f0,%f22 | ||
87 | clr %l2 | ||
88 | fmovs %f1,%f21 | ||
89 | clr %l3 | ||
90 | fmovs %f0,%f20 | ||
91 | clr %l4 | ||
92 | fmovs %f1,%f19 | ||
93 | clr %l5 | ||
94 | fmovs %f0,%f18 | ||
95 | clr %l6 | ||
96 | fmovs %f1,%f17 | ||
97 | clr %l7 | ||
98 | fmovs %f0,%f16 | ||
99 | clr %i0 | ||
100 | fmovs %f1,%f15 | ||
101 | clr %i1 | ||
102 | fmovs %f0,%f14 | ||
103 | clr %i2 | ||
104 | fmovs %f1,%f13 | ||
105 | clr %i3 | ||
106 | fmovs %f0,%f12 | ||
107 | clr %i4 | ||
108 | fmovs %f1,%f11 | ||
109 | clr %i5 | ||
110 | fmovs %f0,%f10 | ||
111 | clr %g1 | ||
112 | fmovs %f1,%f9 | ||
113 | clr %g2 | ||
114 | fmovs %f0,%f8 | ||
115 | clr %g3 | ||
116 | fmovs %f1,%f7 | ||
117 | clr %g4 | ||
118 | fmovs %f0,%f6 | ||
119 | clr %g5 | ||
120 | fmovs %f1,%f5 | ||
121 | fmovs %f0,%f4 | ||
122 | fmovs %f1,%f3 | ||
123 | fmovs %f0,%f2 | ||
124 | |||
125 | add %fp,BIAS,%i0 ! return pointer to caller´s top of stack | ||
126 | |||
127 | ret | ||
128 | restore | ||
129 | |||
130 | .zero: .long 0x0,0x0 | ||
131 | .PIC.zero.up: | ||
132 | retl | ||
133 | add %o0,%o7,%o0 | ||
134 | #ifdef DEBUG | ||
135 | .global walk_reg_wins | ||
136 | .type walk_reg_wins,#function | ||
137 | walk_reg_wins: | ||
138 | #endif | ||
139 | .walk.reg.wins: | ||
140 | save %sp,FRAME,%sp | ||
141 | cmp %i7,%o7 | ||
142 | be 2f | ||
143 | clr %o0 | ||
144 | cmp %o7,0 ! compiler never cleans %o7... | ||
145 | be 1f ! could have been a leaf function... | ||
146 | clr %o1 | ||
147 | call .walk.reg.wins | ||
148 | nop | ||
149 | 1: clr %o2 | ||
150 | clr %o3 | ||
151 | clr %o4 | ||
152 | clr %o5 | ||
153 | clr %o7 | ||
154 | clr %l0 | ||
155 | clr %l1 | ||
156 | clr %l2 | ||
157 | clr %l3 | ||
158 | clr %l4 | ||
159 | clr %l5 | ||
160 | clr %l6 | ||
161 | clr %l7 | ||
162 | add %o0,1,%i0 ! used for debugging | ||
163 | 2: ret | ||
164 | restore | ||
165 | .size OPENSSL_wipe_cpu,.-OPENSSL_wipe_cpu | ||
166 | |||
167 | .global OPENSSL_atomic_add | ||
168 | .type OPENSSL_atomic_add,#function | ||
169 | OPENSSL_atomic_add: | ||
170 | #ifndef ABI64 | ||
171 | subcc %g0,1,%o2 | ||
172 | .word 0x95408000 !rd %ccr,%o2, see comment above | ||
173 | cmp %o2,0x99 | ||
174 | be .v9 | ||
175 | nop | ||
176 | save %sp,FRAME,%sp | ||
177 | ba .enter | ||
178 | nop | ||
179 | #ifdef __sun | ||
180 | ! Note that you don't have to link with libthread to call thr_yield, | ||
181 | ! as libc provides a stub, which is overloaded the moment you link | ||
182 | ! with *either* libpthread or libthread... | ||
183 | #define YIELD_CPU thr_yield | ||
184 | #else | ||
185 | ! applies at least to Linux and FreeBSD... Feedback expected... | ||
186 | #define YIELD_CPU sched_yield | ||
187 | #endif | ||
188 | .spin: call YIELD_CPU | ||
189 | nop | ||
190 | .enter: ld [%i0],%i2 | ||
191 | cmp %i2,-4096 | ||
192 | be .spin | ||
193 | mov -1,%i2 | ||
194 | swap [%i0],%i2 | ||
195 | cmp %i2,-1 | ||
196 | be .spin | ||
197 | add %i2,%i1,%i2 | ||
198 | stbar | ||
199 | st %i2,[%i0] | ||
200 | sra %i2,%g0,%i0 | ||
201 | ret | ||
202 | restore | ||
203 | .v9: | ||
204 | #endif | ||
205 | ld [%o0],%o2 | ||
206 | 1: add %o1,%o2,%o3 | ||
207 | .word 0xd7e2100a !cas [%o0],%o2,%o3, compare [%o0] with %o2 and swap %o3 | ||
208 | cmp %o2,%o3 | ||
209 | bne 1b | ||
210 | mov %o3,%o2 ! cas is always fetching to dest. register | ||
211 | add %o1,%o2,%o0 ! OpenSSL expects the new value | ||
212 | retl | ||
213 | sra %o0,%g0,%o0 ! we return signed int, remember? | ||
214 | .size OPENSSL_atomic_add,.-OPENSSL_atomic_add | ||
215 | |||
216 | .global OPENSSL_rdtsc | ||
217 | subcc %g0,1,%o0 | ||
218 | .word 0x91408000 !rd %ccr,%o0 | ||
219 | cmp %o0,0x99 | ||
220 | bne .notsc | ||
221 | xor %o0,%o0,%o0 | ||
222 | save %sp,FRAME-16,%sp | ||
223 | mov 513,%o0 !SI_PLATFORM | ||
224 | add %sp,BIAS+16,%o1 | ||
225 | call sysinfo | ||
226 | mov 256,%o2 | ||
227 | |||
228 | add %sp,BIAS-16,%o1 | ||
229 | ld [%o1],%l0 | ||
230 | ld [%o1+4],%l1 | ||
231 | ld [%o1+8],%l2 | ||
232 | mov %lo('SUNW'),%l3 | ||
233 | ret | ||
234 | restore | ||
235 | .notsc: | ||
236 | retl | ||
237 | nop | ||
238 | .type OPENSSL_rdtsc,#function | ||
239 | .size OPENSSL_rdtsc,.-OPENSSL_atomic_add | ||
diff --git a/src/lib/libcrypto/x509/x509_vpm.c b/src/lib/libcrypto/x509/x509_vpm.c new file mode 100644 index 0000000000..e9db6d62a7 --- /dev/null +++ b/src/lib/libcrypto/x509/x509_vpm.c | |||
@@ -0,0 +1,420 @@ | |||
1 | /* x509_vpm.c */ | ||
2 | /* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL | ||
3 | * project 2004. | ||
4 | */ | ||
5 | /* ==================================================================== | ||
6 | * Copyright (c) 2004 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 | * This product includes cryptographic software written by Eric Young | ||
54 | * (eay@cryptsoft.com). This product includes software written by Tim | ||
55 | * Hudson (tjh@cryptsoft.com). | ||
56 | * | ||
57 | */ | ||
58 | |||
59 | #include <stdio.h> | ||
60 | |||
61 | #include "cryptlib.h" | ||
62 | #include <openssl/crypto.h> | ||
63 | #include <openssl/lhash.h> | ||
64 | #include <openssl/buffer.h> | ||
65 | #include <openssl/x509.h> | ||
66 | #include <openssl/x509v3.h> | ||
67 | |||
68 | /* X509_VERIFY_PARAM functions */ | ||
69 | |||
70 | static void x509_verify_param_zero(X509_VERIFY_PARAM *param) | ||
71 | { | ||
72 | if (!param) | ||
73 | return; | ||
74 | param->name = NULL; | ||
75 | param->purpose = 0; | ||
76 | param->trust = 0; | ||
77 | param->inh_flags = X509_VP_FLAG_DEFAULT; | ||
78 | param->flags = 0; | ||
79 | param->depth = -1; | ||
80 | if (param->policies) | ||
81 | { | ||
82 | sk_ASN1_OBJECT_pop_free(param->policies, ASN1_OBJECT_free); | ||
83 | param->policies = NULL; | ||
84 | } | ||
85 | } | ||
86 | |||
87 | X509_VERIFY_PARAM *X509_VERIFY_PARAM_new(void) | ||
88 | { | ||
89 | X509_VERIFY_PARAM *param; | ||
90 | param = OPENSSL_malloc(sizeof(X509_VERIFY_PARAM)); | ||
91 | memset(param, 0, sizeof(X509_VERIFY_PARAM)); | ||
92 | x509_verify_param_zero(param); | ||
93 | return param; | ||
94 | } | ||
95 | |||
96 | void X509_VERIFY_PARAM_free(X509_VERIFY_PARAM *param) | ||
97 | { | ||
98 | x509_verify_param_zero(param); | ||
99 | OPENSSL_free(param); | ||
100 | } | ||
101 | |||
102 | /* This function determines how parameters are "inherited" from one structure | ||
103 | * to another. There are several different ways this can happen. | ||
104 | * | ||
105 | * 1. If a child structure needs to have its values initialized from a parent | ||
106 | * they are simply copied across. For example SSL_CTX copied to SSL. | ||
107 | * 2. If the structure should take on values only if they are currently unset. | ||
108 | * For example the values in an SSL structure will take appropriate value | ||
109 | * for SSL servers or clients but only if the application has not set new | ||
110 | * ones. | ||
111 | * | ||
112 | * The "inh_flags" field determines how this function behaves. | ||
113 | * | ||
114 | * Normally any values which are set in the default are not copied from the | ||
115 | * destination and verify flags are ORed together. | ||
116 | * | ||
117 | * If X509_VP_FLAG_DEFAULT is set then anything set in the source is copied | ||
118 | * to the destination. Effectively the values in "to" become default values | ||
119 | * which will be used only if nothing new is set in "from". | ||
120 | * | ||
121 | * If X509_VP_FLAG_OVERWRITE is set then all value are copied across whether | ||
122 | * they are set or not. Flags is still Ored though. | ||
123 | * | ||
124 | * If X509_VP_FLAG_RESET_FLAGS is set then the flags value is copied instead | ||
125 | * of ORed. | ||
126 | * | ||
127 | * If X509_VP_FLAG_LOCKED is set then no values are copied. | ||
128 | * | ||
129 | * If X509_VP_FLAG_ONCE is set then the current inh_flags setting is zeroed | ||
130 | * after the next call. | ||
131 | */ | ||
132 | |||
133 | /* Macro to test if a field should be copied from src to dest */ | ||
134 | |||
135 | #define test_x509_verify_param_copy(field, def) \ | ||
136 | (to_overwrite || \ | ||
137 | ((src->field != def) && (to_default || (dest->field == def)))) | ||
138 | |||
139 | /* Macro to test and copy a field if necessary */ | ||
140 | |||
141 | #define x509_verify_param_copy(field, def) \ | ||
142 | if (test_x509_verify_param_copy(field, def)) \ | ||
143 | dest->field = src->field | ||
144 | |||
145 | |||
146 | int X509_VERIFY_PARAM_inherit(X509_VERIFY_PARAM *dest, | ||
147 | const X509_VERIFY_PARAM *src) | ||
148 | { | ||
149 | unsigned long inh_flags; | ||
150 | int to_default, to_overwrite; | ||
151 | if (!src) | ||
152 | return 1; | ||
153 | inh_flags = dest->inh_flags | src->inh_flags; | ||
154 | |||
155 | if (inh_flags & X509_VP_FLAG_ONCE) | ||
156 | dest->inh_flags = 0; | ||
157 | |||
158 | if (inh_flags & X509_VP_FLAG_LOCKED) | ||
159 | return 1; | ||
160 | |||
161 | if (inh_flags & X509_VP_FLAG_DEFAULT) | ||
162 | to_default = 1; | ||
163 | else | ||
164 | to_default = 0; | ||
165 | |||
166 | if (inh_flags & X509_VP_FLAG_OVERWRITE) | ||
167 | to_overwrite = 1; | ||
168 | else | ||
169 | to_overwrite = 0; | ||
170 | |||
171 | x509_verify_param_copy(purpose, 0); | ||
172 | x509_verify_param_copy(trust, 0); | ||
173 | x509_verify_param_copy(depth, -1); | ||
174 | |||
175 | /* If overwrite or check time not set, copy across */ | ||
176 | |||
177 | if (to_overwrite || !(dest->flags & X509_V_FLAG_USE_CHECK_TIME)) | ||
178 | { | ||
179 | dest->check_time = src->check_time; | ||
180 | dest->flags &= ~X509_V_FLAG_USE_CHECK_TIME; | ||
181 | /* Don't need to copy flag: that is done below */ | ||
182 | } | ||
183 | |||
184 | if (inh_flags & X509_VP_FLAG_RESET_FLAGS) | ||
185 | dest->flags = 0; | ||
186 | |||
187 | dest->flags |= src->flags; | ||
188 | |||
189 | if (test_x509_verify_param_copy(policies, NULL)) | ||
190 | { | ||
191 | if (!X509_VERIFY_PARAM_set1_policies(dest, src->policies)) | ||
192 | return 0; | ||
193 | } | ||
194 | |||
195 | return 1; | ||
196 | } | ||
197 | |||
198 | int X509_VERIFY_PARAM_set1(X509_VERIFY_PARAM *to, | ||
199 | const X509_VERIFY_PARAM *from) | ||
200 | { | ||
201 | to->inh_flags |= X509_VP_FLAG_DEFAULT; | ||
202 | return X509_VERIFY_PARAM_inherit(to, from); | ||
203 | } | ||
204 | |||
205 | int X509_VERIFY_PARAM_set1_name(X509_VERIFY_PARAM *param, const char *name) | ||
206 | { | ||
207 | if (param->name) | ||
208 | OPENSSL_free(param->name); | ||
209 | param->name = BUF_strdup(name); | ||
210 | if (param->name) | ||
211 | return 1; | ||
212 | return 0; | ||
213 | } | ||
214 | |||
215 | int X509_VERIFY_PARAM_set_flags(X509_VERIFY_PARAM *param, unsigned long flags) | ||
216 | { | ||
217 | param->flags |= flags; | ||
218 | if (flags & X509_V_FLAG_POLICY_MASK) | ||
219 | param->flags |= X509_V_FLAG_POLICY_CHECK; | ||
220 | return 1; | ||
221 | } | ||
222 | |||
223 | int X509_VERIFY_PARAM_clear_flags(X509_VERIFY_PARAM *param, unsigned long flags) | ||
224 | { | ||
225 | param->flags &= ~flags; | ||
226 | return 1; | ||
227 | } | ||
228 | |||
229 | unsigned long X509_VERIFY_PARAM_get_flags(X509_VERIFY_PARAM *param) | ||
230 | { | ||
231 | return param->flags; | ||
232 | } | ||
233 | |||
234 | int X509_VERIFY_PARAM_set_purpose(X509_VERIFY_PARAM *param, int purpose) | ||
235 | { | ||
236 | return X509_PURPOSE_set(¶m->purpose, purpose); | ||
237 | } | ||
238 | |||
239 | int X509_VERIFY_PARAM_set_trust(X509_VERIFY_PARAM *param, int trust) | ||
240 | { | ||
241 | return X509_TRUST_set(¶m->trust, trust); | ||
242 | } | ||
243 | |||
244 | void X509_VERIFY_PARAM_set_depth(X509_VERIFY_PARAM *param, int depth) | ||
245 | { | ||
246 | param->depth = depth; | ||
247 | } | ||
248 | |||
249 | void X509_VERIFY_PARAM_set_time(X509_VERIFY_PARAM *param, time_t t) | ||
250 | { | ||
251 | param->check_time = t; | ||
252 | param->flags |= X509_V_FLAG_USE_CHECK_TIME; | ||
253 | } | ||
254 | |||
255 | int X509_VERIFY_PARAM_add0_policy(X509_VERIFY_PARAM *param, ASN1_OBJECT *policy) | ||
256 | { | ||
257 | if (!param->policies) | ||
258 | { | ||
259 | param->policies = sk_ASN1_OBJECT_new_null(); | ||
260 | if (!param->policies) | ||
261 | return 0; | ||
262 | } | ||
263 | if (!sk_ASN1_OBJECT_push(param->policies, policy)) | ||
264 | return 0; | ||
265 | return 1; | ||
266 | } | ||
267 | |||
268 | int X509_VERIFY_PARAM_set1_policies(X509_VERIFY_PARAM *param, | ||
269 | STACK_OF(ASN1_OBJECT) *policies) | ||
270 | { | ||
271 | int i; | ||
272 | ASN1_OBJECT *oid, *doid; | ||
273 | if (!param) | ||
274 | return 0; | ||
275 | if (param->policies) | ||
276 | sk_ASN1_OBJECT_pop_free(param->policies, ASN1_OBJECT_free); | ||
277 | |||
278 | if (!policies) | ||
279 | { | ||
280 | param->policies = NULL; | ||
281 | return 1; | ||
282 | } | ||
283 | |||
284 | param->policies = sk_ASN1_OBJECT_new_null(); | ||
285 | if (!param->policies) | ||
286 | return 0; | ||
287 | |||
288 | for (i = 0; i < sk_ASN1_OBJECT_num(policies); i++) | ||
289 | { | ||
290 | oid = sk_ASN1_OBJECT_value(policies, i); | ||
291 | doid = OBJ_dup(oid); | ||
292 | if (!doid) | ||
293 | return 0; | ||
294 | if (!sk_ASN1_OBJECT_push(param->policies, doid)) | ||
295 | { | ||
296 | ASN1_OBJECT_free(doid); | ||
297 | return 0; | ||
298 | } | ||
299 | } | ||
300 | param->flags |= X509_V_FLAG_POLICY_CHECK; | ||
301 | return 1; | ||
302 | } | ||
303 | |||
304 | int X509_VERIFY_PARAM_get_depth(const X509_VERIFY_PARAM *param) | ||
305 | { | ||
306 | return param->depth; | ||
307 | } | ||
308 | |||
309 | /* Default verify parameters: these are used for various | ||
310 | * applications and can be overridden by the user specified table. | ||
311 | * NB: the 'name' field *must* be in alphabetical order because it | ||
312 | * will be searched using OBJ_search. | ||
313 | */ | ||
314 | |||
315 | static const X509_VERIFY_PARAM default_table[] = { | ||
316 | { | ||
317 | "default", /* X509 default parameters */ | ||
318 | 0, /* Check time */ | ||
319 | 0, /* internal flags */ | ||
320 | 0, /* flags */ | ||
321 | 0, /* purpose */ | ||
322 | 0, /* trust */ | ||
323 | 9, /* depth */ | ||
324 | NULL /* policies */ | ||
325 | }, | ||
326 | { | ||
327 | "pkcs7", /* SSL/TLS client parameters */ | ||
328 | 0, /* Check time */ | ||
329 | 0, /* internal flags */ | ||
330 | 0, /* flags */ | ||
331 | X509_PURPOSE_SMIME_SIGN, /* purpose */ | ||
332 | X509_TRUST_EMAIL, /* trust */ | ||
333 | -1, /* depth */ | ||
334 | NULL /* policies */ | ||
335 | }, | ||
336 | { | ||
337 | "ssl_client", /* SSL/TLS client parameters */ | ||
338 | 0, /* Check time */ | ||
339 | 0, /* internal flags */ | ||
340 | 0, /* flags */ | ||
341 | X509_PURPOSE_SSL_CLIENT, /* purpose */ | ||
342 | X509_TRUST_SSL_CLIENT, /* trust */ | ||
343 | -1, /* depth */ | ||
344 | NULL /* policies */ | ||
345 | }, | ||
346 | { | ||
347 | "ssl_server", /* SSL/TLS server parameters */ | ||
348 | 0, /* Check time */ | ||
349 | 0, /* internal flags */ | ||
350 | 0, /* flags */ | ||
351 | X509_PURPOSE_SSL_SERVER, /* purpose */ | ||
352 | X509_TRUST_SSL_SERVER, /* trust */ | ||
353 | -1, /* depth */ | ||
354 | NULL /* policies */ | ||
355 | }}; | ||
356 | |||
357 | static STACK_OF(X509_VERIFY_PARAM) *param_table = NULL; | ||
358 | |||
359 | static int table_cmp(const void *pa, const void *pb) | ||
360 | { | ||
361 | const X509_VERIFY_PARAM *a = pa, *b = pb; | ||
362 | return strcmp(a->name, b->name); | ||
363 | } | ||
364 | |||
365 | static int param_cmp(const X509_VERIFY_PARAM * const *a, | ||
366 | const X509_VERIFY_PARAM * const *b) | ||
367 | { | ||
368 | return strcmp((*a)->name, (*b)->name); | ||
369 | } | ||
370 | |||
371 | int X509_VERIFY_PARAM_add0_table(X509_VERIFY_PARAM *param) | ||
372 | { | ||
373 | int idx; | ||
374 | X509_VERIFY_PARAM *ptmp; | ||
375 | if (!param_table) | ||
376 | { | ||
377 | param_table = sk_X509_VERIFY_PARAM_new(param_cmp); | ||
378 | if (!param_table) | ||
379 | return 0; | ||
380 | } | ||
381 | else | ||
382 | { | ||
383 | idx = sk_X509_VERIFY_PARAM_find(param_table, param); | ||
384 | if (idx != -1) | ||
385 | { | ||
386 | ptmp = sk_X509_VERIFY_PARAM_value(param_table, idx); | ||
387 | X509_VERIFY_PARAM_free(ptmp); | ||
388 | (void)sk_X509_VERIFY_PARAM_delete(param_table, idx); | ||
389 | } | ||
390 | } | ||
391 | if (!sk_X509_VERIFY_PARAM_push(param_table, param)) | ||
392 | return 0; | ||
393 | return 1; | ||
394 | } | ||
395 | |||
396 | const X509_VERIFY_PARAM *X509_VERIFY_PARAM_lookup(const char *name) | ||
397 | { | ||
398 | int idx; | ||
399 | X509_VERIFY_PARAM pm; | ||
400 | pm.name = (char *)name; | ||
401 | if (param_table) | ||
402 | { | ||
403 | idx = sk_X509_VERIFY_PARAM_find(param_table, &pm); | ||
404 | if (idx != -1) | ||
405 | return sk_X509_VERIFY_PARAM_value(param_table, idx); | ||
406 | } | ||
407 | return (const X509_VERIFY_PARAM *) OBJ_bsearch((char *)&pm, | ||
408 | (char *)&default_table, | ||
409 | sizeof(default_table)/sizeof(X509_VERIFY_PARAM), | ||
410 | sizeof(X509_VERIFY_PARAM), | ||
411 | table_cmp); | ||
412 | } | ||
413 | |||
414 | void X509_VERIFY_PARAM_table_cleanup(void) | ||
415 | { | ||
416 | if (param_table) | ||
417 | sk_X509_VERIFY_PARAM_pop_free(param_table, | ||
418 | X509_VERIFY_PARAM_free); | ||
419 | param_table = NULL; | ||
420 | } | ||
diff --git a/src/lib/libcrypto/x509v3/pcy_cache.c b/src/lib/libcrypto/x509v3/pcy_cache.c new file mode 100644 index 0000000000..c18beb89f5 --- /dev/null +++ b/src/lib/libcrypto/x509v3/pcy_cache.c | |||
@@ -0,0 +1,287 @@ | |||
1 | /* pcy_cache.c */ | ||
2 | /* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL | ||
3 | * project 2004. | ||
4 | */ | ||
5 | /* ==================================================================== | ||
6 | * Copyright (c) 2004 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 | * This product includes cryptographic software written by Eric Young | ||
54 | * (eay@cryptsoft.com). This product includes software written by Tim | ||
55 | * Hudson (tjh@cryptsoft.com). | ||
56 | * | ||
57 | */ | ||
58 | |||
59 | #include "cryptlib.h" | ||
60 | #include <openssl/x509.h> | ||
61 | #include <openssl/x509v3.h> | ||
62 | |||
63 | #include "pcy_int.h" | ||
64 | |||
65 | static int policy_data_cmp(const X509_POLICY_DATA * const *a, | ||
66 | const X509_POLICY_DATA * const *b); | ||
67 | static int policy_cache_set_int(long *out, ASN1_INTEGER *value); | ||
68 | |||
69 | /* Set cache entry according to CertificatePolicies extension. | ||
70 | * Note: this destroys the passed CERTIFICATEPOLICIES structure. | ||
71 | */ | ||
72 | |||
73 | static int policy_cache_create(X509 *x, | ||
74 | CERTIFICATEPOLICIES *policies, int crit) | ||
75 | { | ||
76 | int i; | ||
77 | int ret = 0; | ||
78 | X509_POLICY_CACHE *cache = x->policy_cache; | ||
79 | X509_POLICY_DATA *data = NULL; | ||
80 | POLICYINFO *policy; | ||
81 | if (sk_POLICYINFO_num(policies) == 0) | ||
82 | goto bad_policy; | ||
83 | cache->data = sk_X509_POLICY_DATA_new(policy_data_cmp); | ||
84 | if (!cache->data) | ||
85 | goto bad_policy; | ||
86 | for (i = 0; i < sk_POLICYINFO_num(policies); i++) | ||
87 | { | ||
88 | policy = sk_POLICYINFO_value(policies, i); | ||
89 | data = policy_data_new(policy, NULL, crit); | ||
90 | if (!data) | ||
91 | goto bad_policy; | ||
92 | /* Duplicate policy OIDs are illegal: reject if matches | ||
93 | * found. | ||
94 | */ | ||
95 | if (OBJ_obj2nid(data->valid_policy) == NID_any_policy) | ||
96 | { | ||
97 | if (cache->anyPolicy) | ||
98 | { | ||
99 | ret = -1; | ||
100 | goto bad_policy; | ||
101 | } | ||
102 | cache->anyPolicy = data; | ||
103 | } | ||
104 | else if (sk_X509_POLICY_DATA_find(cache->data, data) != -1) | ||
105 | { | ||
106 | ret = -1; | ||
107 | goto bad_policy; | ||
108 | } | ||
109 | else if (!sk_X509_POLICY_DATA_push(cache->data, data)) | ||
110 | goto bad_policy; | ||
111 | data = NULL; | ||
112 | } | ||
113 | ret = 1; | ||
114 | bad_policy: | ||
115 | if (ret == -1) | ||
116 | x->ex_flags |= EXFLAG_INVALID_POLICY; | ||
117 | if (data) | ||
118 | policy_data_free(data); | ||
119 | sk_POLICYINFO_pop_free(policies, POLICYINFO_free); | ||
120 | if (ret <= 0) | ||
121 | { | ||
122 | sk_X509_POLICY_DATA_pop_free(cache->data, policy_data_free); | ||
123 | cache->data = NULL; | ||
124 | } | ||
125 | return ret; | ||
126 | } | ||
127 | |||
128 | |||
129 | static int policy_cache_new(X509 *x) | ||
130 | { | ||
131 | X509_POLICY_CACHE *cache; | ||
132 | ASN1_INTEGER *ext_any = NULL; | ||
133 | POLICY_CONSTRAINTS *ext_pcons = NULL; | ||
134 | CERTIFICATEPOLICIES *ext_cpols = NULL; | ||
135 | POLICY_MAPPINGS *ext_pmaps = NULL; | ||
136 | int i; | ||
137 | cache = OPENSSL_malloc(sizeof(X509_POLICY_CACHE)); | ||
138 | if (!cache) | ||
139 | return 0; | ||
140 | cache->anyPolicy = NULL; | ||
141 | cache->data = NULL; | ||
142 | cache->maps = NULL; | ||
143 | cache->any_skip = -1; | ||
144 | cache->explicit_skip = -1; | ||
145 | cache->map_skip = -1; | ||
146 | |||
147 | x->policy_cache = cache; | ||
148 | |||
149 | /* Handle requireExplicitPolicy *first*. Need to process this | ||
150 | * even if we don't have any policies. | ||
151 | */ | ||
152 | ext_pcons = X509_get_ext_d2i(x, NID_policy_constraints, &i, NULL); | ||
153 | |||
154 | if (!ext_pcons) | ||
155 | { | ||
156 | if (i != -1) | ||
157 | goto bad_cache; | ||
158 | } | ||
159 | else | ||
160 | { | ||
161 | if (!ext_pcons->requireExplicitPolicy | ||
162 | && !ext_pcons->inhibitPolicyMapping) | ||
163 | goto bad_cache; | ||
164 | if (!policy_cache_set_int(&cache->explicit_skip, | ||
165 | ext_pcons->requireExplicitPolicy)) | ||
166 | goto bad_cache; | ||
167 | if (!policy_cache_set_int(&cache->map_skip, | ||
168 | ext_pcons->inhibitPolicyMapping)) | ||
169 | goto bad_cache; | ||
170 | } | ||
171 | |||
172 | /* Process CertificatePolicies */ | ||
173 | |||
174 | ext_cpols = X509_get_ext_d2i(x, NID_certificate_policies, &i, NULL); | ||
175 | /* If no CertificatePolicies extension or problem decoding then | ||
176 | * there is no point continuing because the valid policies will be | ||
177 | * NULL. | ||
178 | */ | ||
179 | if (!ext_cpols) | ||
180 | { | ||
181 | /* If not absent some problem with extension */ | ||
182 | if (i != -1) | ||
183 | goto bad_cache; | ||
184 | return 1; | ||
185 | } | ||
186 | |||
187 | i = policy_cache_create(x, ext_cpols, i); | ||
188 | |||
189 | /* NB: ext_cpols freed by policy_cache_set_policies */ | ||
190 | |||
191 | if (i <= 0) | ||
192 | return i; | ||
193 | |||
194 | ext_pmaps = X509_get_ext_d2i(x, NID_policy_mappings, &i, NULL); | ||
195 | |||
196 | if (!ext_pmaps) | ||
197 | { | ||
198 | /* If not absent some problem with extension */ | ||
199 | if (i != -1) | ||
200 | goto bad_cache; | ||
201 | } | ||
202 | else | ||
203 | { | ||
204 | i = policy_cache_set_mapping(x, ext_pmaps); | ||
205 | if (i <= 0) | ||
206 | goto bad_cache; | ||
207 | } | ||
208 | |||
209 | ext_any = X509_get_ext_d2i(x, NID_inhibit_any_policy, &i, NULL); | ||
210 | |||
211 | if (!ext_any) | ||
212 | { | ||
213 | if (i != -1) | ||
214 | goto bad_cache; | ||
215 | } | ||
216 | else if (!policy_cache_set_int(&cache->any_skip, ext_any)) | ||
217 | goto bad_cache; | ||
218 | |||
219 | if (0) | ||
220 | { | ||
221 | bad_cache: | ||
222 | x->ex_flags |= EXFLAG_INVALID_POLICY; | ||
223 | } | ||
224 | |||
225 | if(ext_pcons) | ||
226 | POLICY_CONSTRAINTS_free(ext_pcons); | ||
227 | |||
228 | if (ext_any) | ||
229 | ASN1_INTEGER_free(ext_any); | ||
230 | |||
231 | return 1; | ||
232 | |||
233 | |||
234 | } | ||
235 | |||
236 | void policy_cache_free(X509_POLICY_CACHE *cache) | ||
237 | { | ||
238 | if (!cache) | ||
239 | return; | ||
240 | if (cache->anyPolicy) | ||
241 | policy_data_free(cache->anyPolicy); | ||
242 | if (cache->data) | ||
243 | sk_X509_POLICY_DATA_pop_free(cache->data, policy_data_free); | ||
244 | OPENSSL_free(cache); | ||
245 | } | ||
246 | |||
247 | const X509_POLICY_CACHE *policy_cache_set(X509 *x) | ||
248 | { | ||
249 | |||
250 | if (x->policy_cache == NULL) | ||
251 | { | ||
252 | CRYPTO_w_lock(CRYPTO_LOCK_X509); | ||
253 | policy_cache_new(x); | ||
254 | CRYPTO_w_unlock(CRYPTO_LOCK_X509); | ||
255 | } | ||
256 | |||
257 | return x->policy_cache; | ||
258 | |||
259 | } | ||
260 | |||
261 | X509_POLICY_DATA *policy_cache_find_data(const X509_POLICY_CACHE *cache, | ||
262 | const ASN1_OBJECT *id) | ||
263 | { | ||
264 | int idx; | ||
265 | X509_POLICY_DATA tmp; | ||
266 | tmp.valid_policy = (ASN1_OBJECT *)id; | ||
267 | idx = sk_X509_POLICY_DATA_find(cache->data, &tmp); | ||
268 | if (idx == -1) | ||
269 | return NULL; | ||
270 | return sk_X509_POLICY_DATA_value(cache->data, idx); | ||
271 | } | ||
272 | |||
273 | static int policy_data_cmp(const X509_POLICY_DATA * const *a, | ||
274 | const X509_POLICY_DATA * const *b) | ||
275 | { | ||
276 | return OBJ_cmp((*a)->valid_policy, (*b)->valid_policy); | ||
277 | } | ||
278 | |||
279 | static int policy_cache_set_int(long *out, ASN1_INTEGER *value) | ||
280 | { | ||
281 | if (value == NULL) | ||
282 | return 1; | ||
283 | if (value->type == V_ASN1_NEG_INTEGER) | ||
284 | return 0; | ||
285 | *out = ASN1_INTEGER_get(value); | ||
286 | return 1; | ||
287 | } | ||
diff --git a/src/lib/libcrypto/x509v3/pcy_data.c b/src/lib/libcrypto/x509v3/pcy_data.c new file mode 100644 index 0000000000..614d2b4935 --- /dev/null +++ b/src/lib/libcrypto/x509v3/pcy_data.c | |||
@@ -0,0 +1,123 @@ | |||
1 | /* pcy_data.c */ | ||
2 | /* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL | ||
3 | * project 2004. | ||
4 | */ | ||
5 | /* ==================================================================== | ||
6 | * Copyright (c) 2004 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 | * This product includes cryptographic software written by Eric Young | ||
54 | * (eay@cryptsoft.com). This product includes software written by Tim | ||
55 | * Hudson (tjh@cryptsoft.com). | ||
56 | * | ||
57 | */ | ||
58 | |||
59 | #include "cryptlib.h" | ||
60 | #include <openssl/x509.h> | ||
61 | #include <openssl/x509v3.h> | ||
62 | |||
63 | #include "pcy_int.h" | ||
64 | |||
65 | /* Policy Node routines */ | ||
66 | |||
67 | void policy_data_free(X509_POLICY_DATA *data) | ||
68 | { | ||
69 | ASN1_OBJECT_free(data->valid_policy); | ||
70 | /* Don't free qualifiers if shared */ | ||
71 | if (!(data->flags & POLICY_DATA_FLAG_SHARED_QUALIFIERS)) | ||
72 | sk_POLICYQUALINFO_pop_free(data->qualifier_set, | ||
73 | POLICYQUALINFO_free); | ||
74 | sk_ASN1_OBJECT_pop_free(data->expected_policy_set, ASN1_OBJECT_free); | ||
75 | OPENSSL_free(data); | ||
76 | } | ||
77 | |||
78 | /* Create a data based on an existing policy. If 'id' is NULL use the | ||
79 | * oid in the policy, otherwise use 'id'. This behaviour covers the two | ||
80 | * types of data in RFC3280: data with from a CertificatePolcies extension | ||
81 | * and additional data with just the qualifiers of anyPolicy and ID from | ||
82 | * another source. | ||
83 | */ | ||
84 | |||
85 | X509_POLICY_DATA *policy_data_new(POLICYINFO *policy, ASN1_OBJECT *id, int crit) | ||
86 | { | ||
87 | X509_POLICY_DATA *ret; | ||
88 | if (!policy && !id) | ||
89 | return NULL; | ||
90 | ret = OPENSSL_malloc(sizeof(X509_POLICY_DATA)); | ||
91 | if (!ret) | ||
92 | return NULL; | ||
93 | ret->expected_policy_set = sk_ASN1_OBJECT_new_null(); | ||
94 | if (!ret->expected_policy_set) | ||
95 | { | ||
96 | OPENSSL_free(ret); | ||
97 | return NULL; | ||
98 | } | ||
99 | |||
100 | if (crit) | ||
101 | ret->flags = POLICY_DATA_FLAG_CRITICAL; | ||
102 | else | ||
103 | ret->flags = 0; | ||
104 | |||
105 | if (id) | ||
106 | ret->valid_policy = id; | ||
107 | else | ||
108 | { | ||
109 | ret->valid_policy = policy->policyid; | ||
110 | policy->policyid = NULL; | ||
111 | } | ||
112 | |||
113 | if (policy) | ||
114 | { | ||
115 | ret->qualifier_set = policy->qualifiers; | ||
116 | policy->qualifiers = NULL; | ||
117 | } | ||
118 | else | ||
119 | ret->qualifier_set = NULL; | ||
120 | |||
121 | return ret; | ||
122 | } | ||
123 | |||
diff --git a/src/lib/libcrypto/x509v3/pcy_int.h b/src/lib/libcrypto/x509v3/pcy_int.h new file mode 100644 index 0000000000..ba62a209da --- /dev/null +++ b/src/lib/libcrypto/x509v3/pcy_int.h | |||
@@ -0,0 +1,223 @@ | |||
1 | /* pcy_int.h */ | ||
2 | /* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL | ||
3 | * project 2004. | ||
4 | */ | ||
5 | /* ==================================================================== | ||
6 | * Copyright (c) 2004 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 | * This product includes cryptographic software written by Eric Young | ||
54 | * (eay@cryptsoft.com). This product includes software written by Tim | ||
55 | * Hudson (tjh@cryptsoft.com). | ||
56 | * | ||
57 | */ | ||
58 | |||
59 | DECLARE_STACK_OF(X509_POLICY_DATA) | ||
60 | DECLARE_STACK_OF(X509_POLICY_REF) | ||
61 | DECLARE_STACK_OF(X509_POLICY_NODE) | ||
62 | |||
63 | typedef struct X509_POLICY_DATA_st X509_POLICY_DATA; | ||
64 | typedef struct X509_POLICY_REF_st X509_POLICY_REF; | ||
65 | |||
66 | /* Internal structures */ | ||
67 | |||
68 | /* This structure and the field names correspond to the Policy 'node' of | ||
69 | * RFC3280. NB this structure contains no pointers to parent or child | ||
70 | * data: X509_POLICY_NODE contains that. This means that the main policy data | ||
71 | * can be kept static and cached with the certificate. | ||
72 | */ | ||
73 | |||
74 | struct X509_POLICY_DATA_st | ||
75 | { | ||
76 | unsigned int flags; | ||
77 | /* Policy OID and qualifiers for this data */ | ||
78 | ASN1_OBJECT *valid_policy; | ||
79 | STACK_OF(POLICYQUALINFO) *qualifier_set; | ||
80 | STACK_OF(ASN1_OBJECT) *expected_policy_set; | ||
81 | }; | ||
82 | |||
83 | /* X509_POLICY_DATA flags values */ | ||
84 | |||
85 | /* This flag indicates the structure has been mapped using a policy mapping | ||
86 | * extension. If policy mapping is not active its references get deleted. | ||
87 | */ | ||
88 | |||
89 | #define POLICY_DATA_FLAG_MAPPED 0x1 | ||
90 | |||
91 | /* This flag indicates the data doesn't correspond to a policy in Certificate | ||
92 | * Policies: it has been mapped to any policy. | ||
93 | */ | ||
94 | |||
95 | #define POLICY_DATA_FLAG_MAPPED_ANY 0x2 | ||
96 | |||
97 | /* AND with flags to see if any mapping has occurred */ | ||
98 | |||
99 | #define POLICY_DATA_FLAG_MAP_MASK 0x3 | ||
100 | |||
101 | /* qualifiers are shared and shouldn't be freed */ | ||
102 | |||
103 | #define POLICY_DATA_FLAG_SHARED_QUALIFIERS 0x4 | ||
104 | |||
105 | /* Parent node is an extra node and should be freed */ | ||
106 | |||
107 | #define POLICY_DATA_FLAG_EXTRA_NODE 0x8 | ||
108 | |||
109 | /* Corresponding CertificatePolicies is critical */ | ||
110 | |||
111 | #define POLICY_DATA_FLAG_CRITICAL 0x10 | ||
112 | |||
113 | /* This structure is an entry from a table of mapped policies which | ||
114 | * cross reference the policy it refers to. | ||
115 | */ | ||
116 | |||
117 | struct X509_POLICY_REF_st | ||
118 | { | ||
119 | ASN1_OBJECT *subjectDomainPolicy; | ||
120 | const X509_POLICY_DATA *data; | ||
121 | }; | ||
122 | |||
123 | /* This structure is cached with a certificate */ | ||
124 | |||
125 | struct X509_POLICY_CACHE_st { | ||
126 | /* anyPolicy data or NULL if no anyPolicy */ | ||
127 | X509_POLICY_DATA *anyPolicy; | ||
128 | /* other policy data */ | ||
129 | STACK_OF(X509_POLICY_DATA) *data; | ||
130 | /* If policyMappings extension present a table of mapped policies */ | ||
131 | STACK_OF(X509_POLICY_REF) *maps; | ||
132 | /* If InhibitAnyPolicy present this is its value or -1 if absent. */ | ||
133 | long any_skip; | ||
134 | /* If policyConstraints and requireExplicitPolicy present this is its | ||
135 | * value or -1 if absent. | ||
136 | */ | ||
137 | long explicit_skip; | ||
138 | /* If policyConstraints and policyMapping present this is its | ||
139 | * value or -1 if absent. | ||
140 | */ | ||
141 | long map_skip; | ||
142 | }; | ||
143 | |||
144 | /*#define POLICY_CACHE_FLAG_CRITICAL POLICY_DATA_FLAG_CRITICAL*/ | ||
145 | |||
146 | /* This structure represents the relationship between nodes */ | ||
147 | |||
148 | struct X509_POLICY_NODE_st | ||
149 | { | ||
150 | /* node data this refers to */ | ||
151 | const X509_POLICY_DATA *data; | ||
152 | /* Parent node */ | ||
153 | X509_POLICY_NODE *parent; | ||
154 | /* Number of child nodes */ | ||
155 | int nchild; | ||
156 | }; | ||
157 | |||
158 | struct X509_POLICY_LEVEL_st | ||
159 | { | ||
160 | /* Cert for this level */ | ||
161 | X509 *cert; | ||
162 | /* nodes at this level */ | ||
163 | STACK_OF(X509_POLICY_NODE) *nodes; | ||
164 | /* anyPolicy node */ | ||
165 | X509_POLICY_NODE *anyPolicy; | ||
166 | /* Extra data */ | ||
167 | /*STACK_OF(X509_POLICY_DATA) *extra_data;*/ | ||
168 | unsigned int flags; | ||
169 | }; | ||
170 | |||
171 | struct X509_POLICY_TREE_st | ||
172 | { | ||
173 | /* This is the tree 'level' data */ | ||
174 | X509_POLICY_LEVEL *levels; | ||
175 | int nlevel; | ||
176 | /* Extra policy data when additional nodes (not from the certificate) | ||
177 | * are required. | ||
178 | */ | ||
179 | STACK_OF(X509_POLICY_DATA) *extra_data; | ||
180 | /* This is the authority constained policy set */ | ||
181 | STACK_OF(X509_POLICY_NODE) *auth_policies; | ||
182 | STACK_OF(X509_POLICY_NODE) *user_policies; | ||
183 | unsigned int flags; | ||
184 | }; | ||
185 | |||
186 | /* Set if anyPolicy present in user policies */ | ||
187 | #define POLICY_FLAG_ANY_POLICY 0x2 | ||
188 | |||
189 | /* Useful macros */ | ||
190 | |||
191 | #define node_data_critical(data) (data->flags & POLICY_DATA_FLAG_CRITICAL) | ||
192 | #define node_critical(node) node_data_critical(node->data) | ||
193 | |||
194 | /* Internal functions */ | ||
195 | |||
196 | X509_POLICY_DATA *policy_data_new(POLICYINFO *policy, ASN1_OBJECT *id, | ||
197 | int crit); | ||
198 | void policy_data_free(X509_POLICY_DATA *data); | ||
199 | |||
200 | X509_POLICY_DATA *policy_cache_find_data(const X509_POLICY_CACHE *cache, | ||
201 | const ASN1_OBJECT *id); | ||
202 | int policy_cache_set_mapping(X509 *x, POLICY_MAPPINGS *maps); | ||
203 | |||
204 | |||
205 | STACK_OF(X509_POLICY_NODE) *policy_node_cmp_new(void); | ||
206 | |||
207 | void policy_cache_init(void); | ||
208 | |||
209 | void policy_cache_free(X509_POLICY_CACHE *cache); | ||
210 | |||
211 | X509_POLICY_NODE *level_find_node(const X509_POLICY_LEVEL *level, | ||
212 | const ASN1_OBJECT *id); | ||
213 | |||
214 | X509_POLICY_NODE *tree_find_sk(STACK_OF(X509_POLICY_NODE) *sk, | ||
215 | const ASN1_OBJECT *id); | ||
216 | |||
217 | X509_POLICY_NODE *level_add_node(X509_POLICY_LEVEL *level, | ||
218 | X509_POLICY_DATA *data, | ||
219 | X509_POLICY_NODE *parent, | ||
220 | X509_POLICY_TREE *tree); | ||
221 | void policy_node_free(X509_POLICY_NODE *node); | ||
222 | |||
223 | const X509_POLICY_CACHE *policy_cache_set(X509 *x); | ||
diff --git a/src/lib/libcrypto/x509v3/pcy_lib.c b/src/lib/libcrypto/x509v3/pcy_lib.c new file mode 100644 index 0000000000..dae4840bc5 --- /dev/null +++ b/src/lib/libcrypto/x509v3/pcy_lib.c | |||
@@ -0,0 +1,167 @@ | |||
1 | /* pcy_lib.c */ | ||
2 | /* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL | ||
3 | * project 2004. | ||
4 | */ | ||
5 | /* ==================================================================== | ||
6 | * Copyright (c) 2004 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 | * This product includes cryptographic software written by Eric Young | ||
54 | * (eay@cryptsoft.com). This product includes software written by Tim | ||
55 | * Hudson (tjh@cryptsoft.com). | ||
56 | * | ||
57 | */ | ||
58 | |||
59 | |||
60 | #include "cryptlib.h" | ||
61 | #include <openssl/x509.h> | ||
62 | #include <openssl/x509v3.h> | ||
63 | |||
64 | #include "pcy_int.h" | ||
65 | |||
66 | /* accessor functions */ | ||
67 | |||
68 | /* X509_POLICY_TREE stuff */ | ||
69 | |||
70 | int X509_policy_tree_level_count(const X509_POLICY_TREE *tree) | ||
71 | { | ||
72 | if (!tree) | ||
73 | return 0; | ||
74 | return tree->nlevel; | ||
75 | } | ||
76 | |||
77 | X509_POLICY_LEVEL * | ||
78 | X509_policy_tree_get0_level(const X509_POLICY_TREE *tree, int i) | ||
79 | { | ||
80 | if (!tree || (i < 0) || (i >= tree->nlevel)) | ||
81 | return NULL; | ||
82 | return tree->levels + i; | ||
83 | } | ||
84 | |||
85 | STACK_OF(X509_POLICY_NODE) * | ||
86 | X509_policy_tree_get0_policies(const X509_POLICY_TREE *tree) | ||
87 | { | ||
88 | if (!tree) | ||
89 | return NULL; | ||
90 | return tree->auth_policies; | ||
91 | } | ||
92 | |||
93 | STACK_OF(X509_POLICY_NODE) * | ||
94 | X509_policy_tree_get0_user_policies(const X509_POLICY_TREE *tree) | ||
95 | { | ||
96 | if (!tree) | ||
97 | return NULL; | ||
98 | if (tree->flags & POLICY_FLAG_ANY_POLICY) | ||
99 | return tree->auth_policies; | ||
100 | else | ||
101 | return tree->user_policies; | ||
102 | } | ||
103 | |||
104 | /* X509_POLICY_LEVEL stuff */ | ||
105 | |||
106 | int X509_policy_level_node_count(X509_POLICY_LEVEL *level) | ||
107 | { | ||
108 | int n; | ||
109 | if (!level) | ||
110 | return 0; | ||
111 | if (level->anyPolicy) | ||
112 | n = 1; | ||
113 | else | ||
114 | n = 0; | ||
115 | if (level->nodes) | ||
116 | n += sk_X509_POLICY_NODE_num(level->nodes); | ||
117 | return n; | ||
118 | } | ||
119 | |||
120 | X509_POLICY_NODE *X509_policy_level_get0_node(X509_POLICY_LEVEL *level, int i) | ||
121 | { | ||
122 | if (!level) | ||
123 | return NULL; | ||
124 | if (level->anyPolicy) | ||
125 | { | ||
126 | if (i == 0) | ||
127 | return level->anyPolicy; | ||
128 | i--; | ||
129 | } | ||
130 | return sk_X509_POLICY_NODE_value(level->nodes, i); | ||
131 | } | ||
132 | |||
133 | /* X509_POLICY_NODE stuff */ | ||
134 | |||
135 | const ASN1_OBJECT *X509_policy_node_get0_policy(const X509_POLICY_NODE *node) | ||
136 | { | ||
137 | if (!node) | ||
138 | return NULL; | ||
139 | return node->data->valid_policy; | ||
140 | } | ||
141 | |||
142 | #if 0 | ||
143 | int X509_policy_node_get_critical(const X509_POLICY_NODE *node) | ||
144 | { | ||
145 | if (node_critical(node)) | ||
146 | return 1; | ||
147 | return 0; | ||
148 | } | ||
149 | #endif | ||
150 | |||
151 | STACK_OF(POLICYQUALINFO) * | ||
152 | X509_policy_node_get0_qualifiers(const X509_POLICY_NODE *node) | ||
153 | { | ||
154 | if (!node) | ||
155 | return NULL; | ||
156 | return node->data->qualifier_set; | ||
157 | } | ||
158 | |||
159 | const X509_POLICY_NODE * | ||
160 | X509_policy_node_get0_parent(const X509_POLICY_NODE *node) | ||
161 | { | ||
162 | if (!node) | ||
163 | return NULL; | ||
164 | return node->parent; | ||
165 | } | ||
166 | |||
167 | |||
diff --git a/src/lib/libcrypto/x509v3/pcy_map.c b/src/lib/libcrypto/x509v3/pcy_map.c new file mode 100644 index 0000000000..35221e8ba8 --- /dev/null +++ b/src/lib/libcrypto/x509v3/pcy_map.c | |||
@@ -0,0 +1,186 @@ | |||
1 | /* pcy_map.c */ | ||
2 | /* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL | ||
3 | * project 2004. | ||
4 | */ | ||
5 | /* ==================================================================== | ||
6 | * Copyright (c) 2004 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 | * This product includes cryptographic software written by Eric Young | ||
54 | * (eay@cryptsoft.com). This product includes software written by Tim | ||
55 | * Hudson (tjh@cryptsoft.com). | ||
56 | * | ||
57 | */ | ||
58 | |||
59 | #include "cryptlib.h" | ||
60 | #include <openssl/x509.h> | ||
61 | #include <openssl/x509v3.h> | ||
62 | |||
63 | #include "pcy_int.h" | ||
64 | |||
65 | static int ref_cmp(const X509_POLICY_REF * const *a, | ||
66 | const X509_POLICY_REF * const *b) | ||
67 | { | ||
68 | return OBJ_cmp((*a)->subjectDomainPolicy, (*b)->subjectDomainPolicy); | ||
69 | } | ||
70 | |||
71 | static void policy_map_free(X509_POLICY_REF *map) | ||
72 | { | ||
73 | if (map->subjectDomainPolicy) | ||
74 | ASN1_OBJECT_free(map->subjectDomainPolicy); | ||
75 | OPENSSL_free(map); | ||
76 | } | ||
77 | |||
78 | static X509_POLICY_REF *policy_map_find(X509_POLICY_CACHE *cache, ASN1_OBJECT *id) | ||
79 | { | ||
80 | X509_POLICY_REF tmp; | ||
81 | int idx; | ||
82 | tmp.subjectDomainPolicy = id; | ||
83 | |||
84 | idx = sk_X509_POLICY_REF_find(cache->maps, &tmp); | ||
85 | if (idx == -1) | ||
86 | return NULL; | ||
87 | return sk_X509_POLICY_REF_value(cache->maps, idx); | ||
88 | } | ||
89 | |||
90 | /* Set policy mapping entries in cache. | ||
91 | * Note: this modifies the passed POLICY_MAPPINGS structure | ||
92 | */ | ||
93 | |||
94 | int policy_cache_set_mapping(X509 *x, POLICY_MAPPINGS *maps) | ||
95 | { | ||
96 | POLICY_MAPPING *map; | ||
97 | X509_POLICY_REF *ref = NULL; | ||
98 | X509_POLICY_DATA *data; | ||
99 | X509_POLICY_CACHE *cache = x->policy_cache; | ||
100 | int i; | ||
101 | int ret = 0; | ||
102 | if (sk_POLICY_MAPPING_num(maps) == 0) | ||
103 | { | ||
104 | ret = -1; | ||
105 | goto bad_mapping; | ||
106 | } | ||
107 | cache->maps = sk_X509_POLICY_REF_new(ref_cmp); | ||
108 | for (i = 0; i < sk_POLICY_MAPPING_num(maps); i++) | ||
109 | { | ||
110 | map = sk_POLICY_MAPPING_value(maps, i); | ||
111 | /* Reject if map to or from anyPolicy */ | ||
112 | if ((OBJ_obj2nid(map->subjectDomainPolicy) == NID_any_policy) | ||
113 | || (OBJ_obj2nid(map->issuerDomainPolicy) == NID_any_policy)) | ||
114 | { | ||
115 | ret = -1; | ||
116 | goto bad_mapping; | ||
117 | } | ||
118 | |||
119 | /* If we've already mapped from this OID bad mapping */ | ||
120 | if (policy_map_find(cache, map->subjectDomainPolicy) != NULL) | ||
121 | { | ||
122 | ret = -1; | ||
123 | goto bad_mapping; | ||
124 | } | ||
125 | |||
126 | /* Attempt to find matching policy data */ | ||
127 | data = policy_cache_find_data(cache, map->issuerDomainPolicy); | ||
128 | /* If we don't have anyPolicy can't map */ | ||
129 | if (!data && !cache->anyPolicy) | ||
130 | continue; | ||
131 | |||
132 | /* Create a NODE from anyPolicy */ | ||
133 | if (!data) | ||
134 | { | ||
135 | data = policy_data_new(NULL, map->issuerDomainPolicy, | ||
136 | cache->anyPolicy->flags | ||
137 | & POLICY_DATA_FLAG_CRITICAL); | ||
138 | if (!data) | ||
139 | goto bad_mapping; | ||
140 | data->qualifier_set = cache->anyPolicy->qualifier_set; | ||
141 | map->issuerDomainPolicy = NULL; | ||
142 | data->flags |= POLICY_DATA_FLAG_MAPPED_ANY; | ||
143 | data->flags |= POLICY_DATA_FLAG_SHARED_QUALIFIERS; | ||
144 | if (!sk_X509_POLICY_DATA_push(cache->data, data)) | ||
145 | { | ||
146 | policy_data_free(data); | ||
147 | goto bad_mapping; | ||
148 | } | ||
149 | } | ||
150 | else | ||
151 | data->flags |= POLICY_DATA_FLAG_MAPPED; | ||
152 | |||
153 | if (!sk_ASN1_OBJECT_push(data->expected_policy_set, | ||
154 | map->subjectDomainPolicy)) | ||
155 | goto bad_mapping; | ||
156 | |||
157 | ref = OPENSSL_malloc(sizeof(X509_POLICY_REF)); | ||
158 | if (!ref) | ||
159 | goto bad_mapping; | ||
160 | |||
161 | ref->subjectDomainPolicy = map->subjectDomainPolicy; | ||
162 | map->subjectDomainPolicy = NULL; | ||
163 | ref->data = data; | ||
164 | |||
165 | if (!sk_X509_POLICY_REF_push(cache->maps, ref)) | ||
166 | goto bad_mapping; | ||
167 | |||
168 | ref = NULL; | ||
169 | |||
170 | } | ||
171 | |||
172 | ret = 1; | ||
173 | bad_mapping: | ||
174 | if (ret == -1) | ||
175 | x->ex_flags |= EXFLAG_INVALID_POLICY; | ||
176 | if (ref) | ||
177 | policy_map_free(ref); | ||
178 | if (ret <= 0) | ||
179 | { | ||
180 | sk_X509_POLICY_REF_pop_free(cache->maps, policy_map_free); | ||
181 | cache->maps = NULL; | ||
182 | } | ||
183 | sk_POLICY_MAPPING_pop_free(maps, POLICY_MAPPING_free); | ||
184 | return ret; | ||
185 | |||
186 | } | ||
diff --git a/src/lib/libcrypto/x509v3/pcy_node.c b/src/lib/libcrypto/x509v3/pcy_node.c new file mode 100644 index 0000000000..dcc1554e29 --- /dev/null +++ b/src/lib/libcrypto/x509v3/pcy_node.c | |||
@@ -0,0 +1,158 @@ | |||
1 | /* pcy_node.c */ | ||
2 | /* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL | ||
3 | * project 2004. | ||
4 | */ | ||
5 | /* ==================================================================== | ||
6 | * Copyright (c) 2004 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 | * This product includes cryptographic software written by Eric Young | ||
54 | * (eay@cryptsoft.com). This product includes software written by Tim | ||
55 | * Hudson (tjh@cryptsoft.com). | ||
56 | * | ||
57 | */ | ||
58 | |||
59 | #include <openssl/asn1.h> | ||
60 | #include <openssl/x509.h> | ||
61 | #include <openssl/x509v3.h> | ||
62 | |||
63 | #include "pcy_int.h" | ||
64 | |||
65 | static int node_cmp(const X509_POLICY_NODE * const *a, | ||
66 | const X509_POLICY_NODE * const *b) | ||
67 | { | ||
68 | return OBJ_cmp((*a)->data->valid_policy, (*b)->data->valid_policy); | ||
69 | } | ||
70 | |||
71 | STACK_OF(X509_POLICY_NODE) *policy_node_cmp_new(void) | ||
72 | { | ||
73 | return sk_X509_POLICY_NODE_new(node_cmp); | ||
74 | } | ||
75 | |||
76 | X509_POLICY_NODE *tree_find_sk(STACK_OF(X509_POLICY_NODE) *nodes, | ||
77 | const ASN1_OBJECT *id) | ||
78 | { | ||
79 | X509_POLICY_DATA n; | ||
80 | X509_POLICY_NODE l; | ||
81 | int idx; | ||
82 | |||
83 | n.valid_policy = (ASN1_OBJECT *)id; | ||
84 | l.data = &n; | ||
85 | |||
86 | idx = sk_X509_POLICY_NODE_find(nodes, &l); | ||
87 | if (idx == -1) | ||
88 | return NULL; | ||
89 | |||
90 | return sk_X509_POLICY_NODE_value(nodes, idx); | ||
91 | |||
92 | } | ||
93 | |||
94 | X509_POLICY_NODE *level_find_node(const X509_POLICY_LEVEL *level, | ||
95 | const ASN1_OBJECT *id) | ||
96 | { | ||
97 | return tree_find_sk(level->nodes, id); | ||
98 | } | ||
99 | |||
100 | X509_POLICY_NODE *level_add_node(X509_POLICY_LEVEL *level, | ||
101 | X509_POLICY_DATA *data, | ||
102 | X509_POLICY_NODE *parent, | ||
103 | X509_POLICY_TREE *tree) | ||
104 | { | ||
105 | X509_POLICY_NODE *node; | ||
106 | node = OPENSSL_malloc(sizeof(X509_POLICY_NODE)); | ||
107 | if (!node) | ||
108 | return NULL; | ||
109 | node->data = data; | ||
110 | node->parent = parent; | ||
111 | node->nchild = 0; | ||
112 | if (level) | ||
113 | { | ||
114 | if (OBJ_obj2nid(data->valid_policy) == NID_any_policy) | ||
115 | { | ||
116 | if (level->anyPolicy) | ||
117 | goto node_error; | ||
118 | level->anyPolicy = node; | ||
119 | } | ||
120 | else | ||
121 | { | ||
122 | |||
123 | if (!level->nodes) | ||
124 | level->nodes = policy_node_cmp_new(); | ||
125 | if (!level->nodes) | ||
126 | goto node_error; | ||
127 | if (!sk_X509_POLICY_NODE_push(level->nodes, node)) | ||
128 | goto node_error; | ||
129 | } | ||
130 | } | ||
131 | |||
132 | if (tree) | ||
133 | { | ||
134 | if (!tree->extra_data) | ||
135 | tree->extra_data = sk_X509_POLICY_DATA_new_null(); | ||
136 | if (!tree->extra_data) | ||
137 | goto node_error; | ||
138 | if (!sk_X509_POLICY_DATA_push(tree->extra_data, data)) | ||
139 | goto node_error; | ||
140 | } | ||
141 | |||
142 | if (parent) | ||
143 | parent->nchild++; | ||
144 | |||
145 | return node; | ||
146 | |||
147 | node_error: | ||
148 | policy_node_free(node); | ||
149 | return 0; | ||
150 | |||
151 | } | ||
152 | |||
153 | void policy_node_free(X509_POLICY_NODE *node) | ||
154 | { | ||
155 | OPENSSL_free(node); | ||
156 | } | ||
157 | |||
158 | |||
diff --git a/src/lib/libcrypto/x509v3/pcy_tree.c b/src/lib/libcrypto/x509v3/pcy_tree.c new file mode 100644 index 0000000000..4fda1d419a --- /dev/null +++ b/src/lib/libcrypto/x509v3/pcy_tree.c | |||
@@ -0,0 +1,692 @@ | |||
1 | /* pcy_tree.c */ | ||
2 | /* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL | ||
3 | * project 2004. | ||
4 | */ | ||
5 | /* ==================================================================== | ||
6 | * Copyright (c) 2004 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 | * This product includes cryptographic software written by Eric Young | ||
54 | * (eay@cryptsoft.com). This product includes software written by Tim | ||
55 | * Hudson (tjh@cryptsoft.com). | ||
56 | * | ||
57 | */ | ||
58 | |||
59 | #include "cryptlib.h" | ||
60 | #include <openssl/x509.h> | ||
61 | #include <openssl/x509v3.h> | ||
62 | |||
63 | #include "pcy_int.h" | ||
64 | |||
65 | /* Initialize policy tree. Return values: | ||
66 | * 0 Some internal error occured. | ||
67 | * -1 Inconsistent or invalid extensions in certificates. | ||
68 | * 1 Tree initialized OK. | ||
69 | * 2 Policy tree is empty. | ||
70 | * 5 Tree OK and requireExplicitPolicy true. | ||
71 | * 6 Tree empty and requireExplicitPolicy true. | ||
72 | */ | ||
73 | |||
74 | static int tree_init(X509_POLICY_TREE **ptree, STACK_OF(X509) *certs, | ||
75 | unsigned int flags) | ||
76 | { | ||
77 | X509_POLICY_TREE *tree; | ||
78 | X509_POLICY_LEVEL *level; | ||
79 | const X509_POLICY_CACHE *cache; | ||
80 | X509_POLICY_DATA *data = NULL; | ||
81 | X509 *x; | ||
82 | int ret = 1; | ||
83 | int i, n; | ||
84 | int explicit_policy; | ||
85 | int any_skip; | ||
86 | int map_skip; | ||
87 | *ptree = NULL; | ||
88 | n = sk_X509_num(certs); | ||
89 | |||
90 | /* Disable policy mapping for now... */ | ||
91 | flags |= X509_V_FLAG_INHIBIT_MAP; | ||
92 | |||
93 | if (flags & X509_V_FLAG_EXPLICIT_POLICY) | ||
94 | explicit_policy = 0; | ||
95 | else | ||
96 | explicit_policy = n + 1; | ||
97 | |||
98 | if (flags & X509_V_FLAG_INHIBIT_ANY) | ||
99 | any_skip = 0; | ||
100 | else | ||
101 | any_skip = n + 1; | ||
102 | |||
103 | if (flags & X509_V_FLAG_INHIBIT_MAP) | ||
104 | map_skip = 0; | ||
105 | else | ||
106 | map_skip = n + 1; | ||
107 | |||
108 | /* Can't do anything with just a trust anchor */ | ||
109 | if (n == 1) | ||
110 | return 1; | ||
111 | /* First setup policy cache in all certificates apart from the | ||
112 | * trust anchor. Note any bad cache results on the way. Also can | ||
113 | * calculate explicit_policy value at this point. | ||
114 | */ | ||
115 | for (i = n - 2; i >= 0; i--) | ||
116 | { | ||
117 | x = sk_X509_value(certs, i); | ||
118 | X509_check_purpose(x, -1, -1); | ||
119 | cache = policy_cache_set(x); | ||
120 | /* If cache NULL something bad happened: return immediately */ | ||
121 | if (cache == NULL) | ||
122 | return 0; | ||
123 | /* If inconsistent extensions keep a note of it but continue */ | ||
124 | if (x->ex_flags & EXFLAG_INVALID_POLICY) | ||
125 | ret = -1; | ||
126 | /* Otherwise if we have no data (hence no CertificatePolicies) | ||
127 | * and haven't already set an inconsistent code note it. | ||
128 | */ | ||
129 | else if ((ret == 1) && !cache->data) | ||
130 | ret = 2; | ||
131 | if (explicit_policy > 0) | ||
132 | { | ||
133 | explicit_policy--; | ||
134 | if (!(x->ex_flags & EXFLAG_SS) | ||
135 | && (cache->explicit_skip != -1) | ||
136 | && (cache->explicit_skip < explicit_policy)) | ||
137 | explicit_policy = cache->explicit_skip; | ||
138 | } | ||
139 | } | ||
140 | |||
141 | if (ret != 1) | ||
142 | { | ||
143 | if (ret == 2 && !explicit_policy) | ||
144 | return 6; | ||
145 | return ret; | ||
146 | } | ||
147 | |||
148 | |||
149 | /* If we get this far initialize the tree */ | ||
150 | |||
151 | tree = OPENSSL_malloc(sizeof(X509_POLICY_TREE)); | ||
152 | |||
153 | if (!tree) | ||
154 | return 0; | ||
155 | |||
156 | tree->flags = 0; | ||
157 | tree->levels = OPENSSL_malloc(sizeof(X509_POLICY_LEVEL) * n); | ||
158 | tree->nlevel = 0; | ||
159 | tree->extra_data = NULL; | ||
160 | tree->auth_policies = NULL; | ||
161 | tree->user_policies = NULL; | ||
162 | |||
163 | if (!tree) | ||
164 | { | ||
165 | OPENSSL_free(tree); | ||
166 | return 0; | ||
167 | } | ||
168 | |||
169 | memset(tree->levels, 0, n * sizeof(X509_POLICY_LEVEL)); | ||
170 | |||
171 | tree->nlevel = n; | ||
172 | |||
173 | level = tree->levels; | ||
174 | |||
175 | /* Root data: initialize to anyPolicy */ | ||
176 | |||
177 | data = policy_data_new(NULL, OBJ_nid2obj(NID_any_policy), 0); | ||
178 | |||
179 | if (!data || !level_add_node(level, data, NULL, tree)) | ||
180 | goto bad_tree; | ||
181 | |||
182 | for (i = n - 2; i >= 0; i--) | ||
183 | { | ||
184 | level++; | ||
185 | x = sk_X509_value(certs, i); | ||
186 | cache = policy_cache_set(x); | ||
187 | |||
188 | CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509); | ||
189 | level->cert = x; | ||
190 | |||
191 | if (!cache->anyPolicy) | ||
192 | level->flags |= X509_V_FLAG_INHIBIT_ANY; | ||
193 | |||
194 | /* Determine inhibit any and inhibit map flags */ | ||
195 | if (any_skip == 0) | ||
196 | { | ||
197 | /* Any matching allowed if certificate is self | ||
198 | * issued and not the last in the chain. | ||
199 | */ | ||
200 | if (!(x->ex_flags & EXFLAG_SS) || (i == 0)) | ||
201 | level->flags |= X509_V_FLAG_INHIBIT_ANY; | ||
202 | } | ||
203 | else | ||
204 | { | ||
205 | any_skip--; | ||
206 | if ((cache->any_skip > 0) | ||
207 | && (cache->any_skip < any_skip)) | ||
208 | any_skip = cache->any_skip; | ||
209 | } | ||
210 | |||
211 | if (map_skip == 0) | ||
212 | level->flags |= X509_V_FLAG_INHIBIT_MAP; | ||
213 | else | ||
214 | { | ||
215 | map_skip--; | ||
216 | if ((cache->map_skip > 0) | ||
217 | && (cache->map_skip < map_skip)) | ||
218 | map_skip = cache->map_skip; | ||
219 | } | ||
220 | |||
221 | |||
222 | } | ||
223 | |||
224 | *ptree = tree; | ||
225 | |||
226 | if (explicit_policy) | ||
227 | return 1; | ||
228 | else | ||
229 | return 5; | ||
230 | |||
231 | bad_tree: | ||
232 | |||
233 | X509_policy_tree_free(tree); | ||
234 | |||
235 | return 0; | ||
236 | |||
237 | } | ||
238 | |||
239 | /* This corresponds to RFC3280 XXXX XXXXX: | ||
240 | * link any data from CertificatePolicies onto matching parent | ||
241 | * or anyPolicy if no match. | ||
242 | */ | ||
243 | |||
244 | static int tree_link_nodes(X509_POLICY_LEVEL *curr, | ||
245 | const X509_POLICY_CACHE *cache) | ||
246 | { | ||
247 | int i; | ||
248 | X509_POLICY_LEVEL *last; | ||
249 | X509_POLICY_DATA *data; | ||
250 | X509_POLICY_NODE *parent; | ||
251 | last = curr - 1; | ||
252 | for (i = 0; i < sk_X509_POLICY_DATA_num(cache->data); i++) | ||
253 | { | ||
254 | data = sk_X509_POLICY_DATA_value(cache->data, i); | ||
255 | /* If a node is mapped any it doesn't have a corresponding | ||
256 | * CertificatePolicies entry. | ||
257 | * However such an identical node would be created | ||
258 | * if anyPolicy matching is enabled because there would be | ||
259 | * no match with the parent valid_policy_set. So we create | ||
260 | * link because then it will have the mapping flags | ||
261 | * right and we can prune it later. | ||
262 | */ | ||
263 | if ((data->flags & POLICY_DATA_FLAG_MAPPED_ANY) | ||
264 | && !(curr->flags & X509_V_FLAG_INHIBIT_ANY)) | ||
265 | continue; | ||
266 | /* Look for matching node in parent */ | ||
267 | parent = level_find_node(last, data->valid_policy); | ||
268 | /* If no match link to anyPolicy */ | ||
269 | if (!parent) | ||
270 | parent = last->anyPolicy; | ||
271 | if (parent && !level_add_node(curr, data, parent, NULL)) | ||
272 | return 0; | ||
273 | } | ||
274 | return 1; | ||
275 | } | ||
276 | |||
277 | /* This corresponds to RFC3280 XXXX XXXXX: | ||
278 | * Create new data for any unmatched policies in the parent and link | ||
279 | * to anyPolicy. | ||
280 | */ | ||
281 | |||
282 | static int tree_link_any(X509_POLICY_LEVEL *curr, | ||
283 | const X509_POLICY_CACHE *cache, | ||
284 | X509_POLICY_TREE *tree) | ||
285 | { | ||
286 | int i; | ||
287 | X509_POLICY_DATA *data; | ||
288 | X509_POLICY_NODE *node; | ||
289 | X509_POLICY_LEVEL *last; | ||
290 | |||
291 | last = curr - 1; | ||
292 | |||
293 | for (i = 0; i < sk_X509_POLICY_NODE_num(last->nodes); i++) | ||
294 | { | ||
295 | node = sk_X509_POLICY_NODE_value(last->nodes, i); | ||
296 | |||
297 | /* Skip any node with any children: we only want unmathced | ||
298 | * nodes. | ||
299 | * | ||
300 | * Note: need something better for policy mapping | ||
301 | * because each node may have multiple children | ||
302 | */ | ||
303 | if (node->nchild) | ||
304 | continue; | ||
305 | /* Create a new node with qualifiers from anyPolicy and | ||
306 | * id from unmatched node. | ||
307 | */ | ||
308 | data = policy_data_new(NULL, node->data->valid_policy, | ||
309 | node_critical(node)); | ||
310 | |||
311 | if (data == NULL) | ||
312 | return 0; | ||
313 | data->qualifier_set = curr->anyPolicy->data->qualifier_set; | ||
314 | data->flags |= POLICY_DATA_FLAG_SHARED_QUALIFIERS; | ||
315 | if (!level_add_node(curr, data, node, tree)) | ||
316 | { | ||
317 | policy_data_free(data); | ||
318 | return 0; | ||
319 | } | ||
320 | } | ||
321 | /* Finally add link to anyPolicy */ | ||
322 | if (last->anyPolicy) | ||
323 | { | ||
324 | if (!level_add_node(curr, cache->anyPolicy, | ||
325 | last->anyPolicy, NULL)) | ||
326 | return 0; | ||
327 | } | ||
328 | return 1; | ||
329 | } | ||
330 | |||
331 | /* Prune the tree: delete any child mapped child data on the current level | ||
332 | * then proceed up the tree deleting any data with no children. If we ever | ||
333 | * have no data on a level we can halt because the tree will be empty. | ||
334 | */ | ||
335 | |||
336 | static int tree_prune(X509_POLICY_TREE *tree, X509_POLICY_LEVEL *curr) | ||
337 | { | ||
338 | X509_POLICY_NODE *node; | ||
339 | int i; | ||
340 | for (i = sk_X509_POLICY_NODE_num(curr->nodes) - 1; i >= 0; i--) | ||
341 | { | ||
342 | node = sk_X509_POLICY_NODE_value(curr->nodes, i); | ||
343 | /* Delete any mapped data: see RFC3280 XXXX */ | ||
344 | if (node->data->flags & POLICY_DATA_FLAG_MAP_MASK) | ||
345 | { | ||
346 | node->parent->nchild--; | ||
347 | OPENSSL_free(node); | ||
348 | (void)sk_X509_POLICY_NODE_delete(curr->nodes, i); | ||
349 | } | ||
350 | } | ||
351 | |||
352 | for(;;) { | ||
353 | --curr; | ||
354 | for (i = sk_X509_POLICY_NODE_num(curr->nodes) - 1; i >= 0; i--) | ||
355 | { | ||
356 | node = sk_X509_POLICY_NODE_value(curr->nodes, i); | ||
357 | if (node->nchild == 0) | ||
358 | { | ||
359 | node->parent->nchild--; | ||
360 | OPENSSL_free(node); | ||
361 | (void)sk_X509_POLICY_NODE_delete(curr->nodes, i); | ||
362 | } | ||
363 | } | ||
364 | if (curr->anyPolicy && !curr->anyPolicy->nchild) | ||
365 | { | ||
366 | if (curr->anyPolicy->parent) | ||
367 | curr->anyPolicy->parent->nchild--; | ||
368 | OPENSSL_free(curr->anyPolicy); | ||
369 | curr->anyPolicy = NULL; | ||
370 | } | ||
371 | if (curr == tree->levels) | ||
372 | { | ||
373 | /* If we zapped anyPolicy at top then tree is empty */ | ||
374 | if (!curr->anyPolicy) | ||
375 | return 2; | ||
376 | return 1; | ||
377 | } | ||
378 | } | ||
379 | |||
380 | return 1; | ||
381 | |||
382 | } | ||
383 | |||
384 | static int tree_add_auth_node(STACK_OF(X509_POLICY_NODE) **pnodes, | ||
385 | X509_POLICY_NODE *pcy) | ||
386 | { | ||
387 | if (!*pnodes) | ||
388 | { | ||
389 | *pnodes = policy_node_cmp_new(); | ||
390 | if (!*pnodes) | ||
391 | return 0; | ||
392 | } | ||
393 | else if (sk_X509_POLICY_NODE_find(*pnodes, pcy) != -1) | ||
394 | return 1; | ||
395 | |||
396 | if (!sk_X509_POLICY_NODE_push(*pnodes, pcy)) | ||
397 | return 0; | ||
398 | |||
399 | return 1; | ||
400 | |||
401 | } | ||
402 | |||
403 | /* Calculate the authority set based on policy tree. | ||
404 | * The 'pnodes' parameter is used as a store for the set of policy nodes | ||
405 | * used to calculate the user set. If the authority set is not anyPolicy | ||
406 | * then pnodes will just point to the authority set. If however the authority | ||
407 | * set is anyPolicy then the set of valid policies (other than anyPolicy) | ||
408 | * is store in pnodes. The return value of '2' is used in this case to indicate | ||
409 | * that pnodes should be freed. | ||
410 | */ | ||
411 | |||
412 | static int tree_calculate_authority_set(X509_POLICY_TREE *tree, | ||
413 | STACK_OF(X509_POLICY_NODE) **pnodes) | ||
414 | { | ||
415 | X509_POLICY_LEVEL *curr; | ||
416 | X509_POLICY_NODE *node, *anyptr; | ||
417 | STACK_OF(X509_POLICY_NODE) **addnodes; | ||
418 | int i, j; | ||
419 | curr = tree->levels + tree->nlevel - 1; | ||
420 | |||
421 | /* If last level contains anyPolicy set is anyPolicy */ | ||
422 | if (curr->anyPolicy) | ||
423 | { | ||
424 | if (!tree_add_auth_node(&tree->auth_policies, curr->anyPolicy)) | ||
425 | return 0; | ||
426 | addnodes = pnodes; | ||
427 | } | ||
428 | else | ||
429 | /* Add policies to authority set */ | ||
430 | addnodes = &tree->auth_policies; | ||
431 | |||
432 | curr = tree->levels; | ||
433 | for (i = 1; i < tree->nlevel; i++) | ||
434 | { | ||
435 | /* If no anyPolicy node on this this level it can't | ||
436 | * appear on lower levels so end search. | ||
437 | */ | ||
438 | if (!(anyptr = curr->anyPolicy)) | ||
439 | break; | ||
440 | curr++; | ||
441 | for (j = 0; j < sk_X509_POLICY_NODE_num(curr->nodes); j++) | ||
442 | { | ||
443 | node = sk_X509_POLICY_NODE_value(curr->nodes, j); | ||
444 | if ((node->parent == anyptr) | ||
445 | && !tree_add_auth_node(addnodes, node)) | ||
446 | return 0; | ||
447 | } | ||
448 | } | ||
449 | |||
450 | if (addnodes == pnodes) | ||
451 | return 2; | ||
452 | |||
453 | *pnodes = tree->auth_policies; | ||
454 | |||
455 | return 1; | ||
456 | } | ||
457 | |||
458 | static int tree_calculate_user_set(X509_POLICY_TREE *tree, | ||
459 | STACK_OF(ASN1_OBJECT) *policy_oids, | ||
460 | STACK_OF(X509_POLICY_NODE) *auth_nodes) | ||
461 | { | ||
462 | int i; | ||
463 | X509_POLICY_NODE *node; | ||
464 | ASN1_OBJECT *oid; | ||
465 | |||
466 | X509_POLICY_NODE *anyPolicy; | ||
467 | X509_POLICY_DATA *extra; | ||
468 | |||
469 | /* Check if anyPolicy present in authority constrained policy set: | ||
470 | * this will happen if it is a leaf node. | ||
471 | */ | ||
472 | |||
473 | if (sk_ASN1_OBJECT_num(policy_oids) <= 0) | ||
474 | return 1; | ||
475 | |||
476 | anyPolicy = tree->levels[tree->nlevel - 1].anyPolicy; | ||
477 | |||
478 | for (i = 0; i < sk_ASN1_OBJECT_num(policy_oids); i++) | ||
479 | { | ||
480 | oid = sk_ASN1_OBJECT_value(policy_oids, i); | ||
481 | if (OBJ_obj2nid(oid) == NID_any_policy) | ||
482 | { | ||
483 | tree->flags |= POLICY_FLAG_ANY_POLICY; | ||
484 | return 1; | ||
485 | } | ||
486 | } | ||
487 | |||
488 | for (i = 0; i < sk_ASN1_OBJECT_num(policy_oids); i++) | ||
489 | { | ||
490 | oid = sk_ASN1_OBJECT_value(policy_oids, i); | ||
491 | node = tree_find_sk(auth_nodes, oid); | ||
492 | if (!node) | ||
493 | { | ||
494 | if (!anyPolicy) | ||
495 | continue; | ||
496 | /* Create a new node with policy ID from user set | ||
497 | * and qualifiers from anyPolicy. | ||
498 | */ | ||
499 | extra = policy_data_new(NULL, oid, | ||
500 | node_critical(anyPolicy)); | ||
501 | if (!extra) | ||
502 | return 0; | ||
503 | extra->qualifier_set = anyPolicy->data->qualifier_set; | ||
504 | extra->flags = POLICY_DATA_FLAG_SHARED_QUALIFIERS | ||
505 | | POLICY_DATA_FLAG_EXTRA_NODE; | ||
506 | node = level_add_node(NULL, extra, anyPolicy->parent, | ||
507 | tree); | ||
508 | } | ||
509 | if (!tree->user_policies) | ||
510 | { | ||
511 | tree->user_policies = sk_X509_POLICY_NODE_new_null(); | ||
512 | if (!tree->user_policies) | ||
513 | return 1; | ||
514 | } | ||
515 | if (!sk_X509_POLICY_NODE_push(tree->user_policies, node)) | ||
516 | return 0; | ||
517 | } | ||
518 | return 1; | ||
519 | |||
520 | } | ||
521 | |||
522 | static int tree_evaluate(X509_POLICY_TREE *tree) | ||
523 | { | ||
524 | int ret, i; | ||
525 | X509_POLICY_LEVEL *curr = tree->levels + 1; | ||
526 | const X509_POLICY_CACHE *cache; | ||
527 | |||
528 | for(i = 1; i < tree->nlevel; i++, curr++) | ||
529 | { | ||
530 | cache = policy_cache_set(curr->cert); | ||
531 | if (!tree_link_nodes(curr, cache)) | ||
532 | return 0; | ||
533 | |||
534 | if (!(curr->flags & X509_V_FLAG_INHIBIT_ANY) | ||
535 | && !tree_link_any(curr, cache, tree)) | ||
536 | return 0; | ||
537 | ret = tree_prune(tree, curr); | ||
538 | if (ret != 1) | ||
539 | return ret; | ||
540 | } | ||
541 | |||
542 | return 1; | ||
543 | |||
544 | } | ||
545 | |||
546 | static void exnode_free(X509_POLICY_NODE *node) | ||
547 | { | ||
548 | if (node->data && (node->data->flags & POLICY_DATA_FLAG_EXTRA_NODE)) | ||
549 | OPENSSL_free(node); | ||
550 | } | ||
551 | |||
552 | |||
553 | void X509_policy_tree_free(X509_POLICY_TREE *tree) | ||
554 | { | ||
555 | X509_POLICY_LEVEL *curr; | ||
556 | int i; | ||
557 | |||
558 | if (!tree) | ||
559 | return; | ||
560 | |||
561 | sk_X509_POLICY_NODE_free(tree->auth_policies); | ||
562 | sk_X509_POLICY_NODE_pop_free(tree->user_policies, exnode_free); | ||
563 | |||
564 | for(i = 0, curr = tree->levels; i < tree->nlevel; i++, curr++) | ||
565 | { | ||
566 | if (curr->cert) | ||
567 | X509_free(curr->cert); | ||
568 | if (curr->nodes) | ||
569 | sk_X509_POLICY_NODE_pop_free(curr->nodes, | ||
570 | policy_node_free); | ||
571 | if (curr->anyPolicy) | ||
572 | policy_node_free(curr->anyPolicy); | ||
573 | } | ||
574 | |||
575 | if (tree->extra_data) | ||
576 | sk_X509_POLICY_DATA_pop_free(tree->extra_data, | ||
577 | policy_data_free); | ||
578 | |||
579 | OPENSSL_free(tree->levels); | ||
580 | OPENSSL_free(tree); | ||
581 | |||
582 | } | ||
583 | |||
584 | /* Application policy checking function. | ||
585 | * Return codes: | ||
586 | * 0 Internal Error. | ||
587 | * 1 Successful. | ||
588 | * -1 One or more certificates contain invalid or inconsistent extensions | ||
589 | * -2 User constrained policy set empty and requireExplicit true. | ||
590 | */ | ||
591 | |||
592 | int X509_policy_check(X509_POLICY_TREE **ptree, int *pexplicit_policy, | ||
593 | STACK_OF(X509) *certs, | ||
594 | STACK_OF(ASN1_OBJECT) *policy_oids, | ||
595 | unsigned int flags) | ||
596 | { | ||
597 | int ret; | ||
598 | X509_POLICY_TREE *tree = NULL; | ||
599 | STACK_OF(X509_POLICY_NODE) *nodes, *auth_nodes = NULL; | ||
600 | *ptree = NULL; | ||
601 | |||
602 | *pexplicit_policy = 0; | ||
603 | ret = tree_init(&tree, certs, flags); | ||
604 | |||
605 | |||
606 | switch (ret) | ||
607 | { | ||
608 | |||
609 | /* Tree empty requireExplicit False: OK */ | ||
610 | case 2: | ||
611 | return 1; | ||
612 | |||
613 | /* Some internal error */ | ||
614 | case 0: | ||
615 | return 0; | ||
616 | |||
617 | /* Tree empty requireExplicit True: Error */ | ||
618 | |||
619 | case 6: | ||
620 | *pexplicit_policy = 1; | ||
621 | return -2; | ||
622 | |||
623 | /* Tree OK requireExplicit True: OK and continue */ | ||
624 | case 5: | ||
625 | *pexplicit_policy = 1; | ||
626 | break; | ||
627 | |||
628 | /* Tree OK: continue */ | ||
629 | |||
630 | case 1: | ||
631 | if (!tree) | ||
632 | /* | ||
633 | * tree_init() returns success and a null tree | ||
634 | * if it's just looking at a trust anchor. | ||
635 | * I'm not sure that returning success here is | ||
636 | * correct, but I'm sure that reporting this | ||
637 | * as an internal error which our caller | ||
638 | * interprets as a malloc failure is wrong. | ||
639 | */ | ||
640 | return 1; | ||
641 | break; | ||
642 | } | ||
643 | |||
644 | if (!tree) goto error; | ||
645 | ret = tree_evaluate(tree); | ||
646 | |||
647 | if (ret <= 0) | ||
648 | goto error; | ||
649 | |||
650 | /* Return value 2 means tree empty */ | ||
651 | if (ret == 2) | ||
652 | { | ||
653 | X509_policy_tree_free(tree); | ||
654 | if (*pexplicit_policy) | ||
655 | return -2; | ||
656 | else | ||
657 | return 1; | ||
658 | } | ||
659 | |||
660 | /* Tree is not empty: continue */ | ||
661 | |||
662 | ret = tree_calculate_authority_set(tree, &auth_nodes); | ||
663 | |||
664 | if (!ret) | ||
665 | goto error; | ||
666 | |||
667 | if (!tree_calculate_user_set(tree, policy_oids, auth_nodes)) | ||
668 | goto error; | ||
669 | |||
670 | if (ret == 2) | ||
671 | sk_X509_POLICY_NODE_free(auth_nodes); | ||
672 | |||
673 | if (tree) | ||
674 | *ptree = tree; | ||
675 | |||
676 | if (*pexplicit_policy) | ||
677 | { | ||
678 | nodes = X509_policy_tree_get0_user_policies(tree); | ||
679 | if (sk_X509_POLICY_NODE_num(nodes) <= 0) | ||
680 | return -2; | ||
681 | } | ||
682 | |||
683 | return 1; | ||
684 | |||
685 | error: | ||
686 | |||
687 | X509_policy_tree_free(tree); | ||
688 | |||
689 | return 0; | ||
690 | |||
691 | } | ||
692 | |||
diff --git a/src/lib/libcrypto/x509v3/v3_ncons.c b/src/lib/libcrypto/x509v3/v3_ncons.c new file mode 100644 index 0000000000..42e7f5a879 --- /dev/null +++ b/src/lib/libcrypto/x509v3/v3_ncons.c | |||
@@ -0,0 +1,220 @@ | |||
1 | /* v3_ncons.c */ | ||
2 | /* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL | ||
3 | * project. | ||
4 | */ | ||
5 | /* ==================================================================== | ||
6 | * Copyright (c) 2003 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 | * This product includes cryptographic software written by Eric Young | ||
54 | * (eay@cryptsoft.com). This product includes software written by Tim | ||
55 | * Hudson (tjh@cryptsoft.com). | ||
56 | * | ||
57 | */ | ||
58 | |||
59 | |||
60 | #include <stdio.h> | ||
61 | #include "cryptlib.h" | ||
62 | #include <openssl/asn1t.h> | ||
63 | #include <openssl/conf.h> | ||
64 | #include <openssl/x509v3.h> | ||
65 | |||
66 | static void *v2i_NAME_CONSTRAINTS(X509V3_EXT_METHOD *method, | ||
67 | X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval); | ||
68 | static int i2r_NAME_CONSTRAINTS(X509V3_EXT_METHOD *method, | ||
69 | void *a, BIO *bp, int ind); | ||
70 | static int do_i2r_name_constraints(X509V3_EXT_METHOD *method, | ||
71 | STACK_OF(GENERAL_SUBTREE) *trees, | ||
72 | BIO *bp, int ind, char *name); | ||
73 | static int print_nc_ipadd(BIO *bp, ASN1_OCTET_STRING *ip); | ||
74 | |||
75 | const X509V3_EXT_METHOD v3_name_constraints = { | ||
76 | NID_name_constraints, 0, | ||
77 | ASN1_ITEM_ref(NAME_CONSTRAINTS), | ||
78 | 0,0,0,0, | ||
79 | 0,0, | ||
80 | 0, v2i_NAME_CONSTRAINTS, | ||
81 | i2r_NAME_CONSTRAINTS,0, | ||
82 | NULL | ||
83 | }; | ||
84 | |||
85 | ASN1_SEQUENCE(GENERAL_SUBTREE) = { | ||
86 | ASN1_SIMPLE(GENERAL_SUBTREE, base, GENERAL_NAME), | ||
87 | ASN1_IMP_OPT(GENERAL_SUBTREE, minimum, ASN1_INTEGER, 0), | ||
88 | ASN1_IMP_OPT(GENERAL_SUBTREE, maximum, ASN1_INTEGER, 1) | ||
89 | } ASN1_SEQUENCE_END(GENERAL_SUBTREE) | ||
90 | |||
91 | ASN1_SEQUENCE(NAME_CONSTRAINTS) = { | ||
92 | ASN1_IMP_SEQUENCE_OF_OPT(NAME_CONSTRAINTS, permittedSubtrees, | ||
93 | GENERAL_SUBTREE, 0), | ||
94 | ASN1_IMP_SEQUENCE_OF_OPT(NAME_CONSTRAINTS, excludedSubtrees, | ||
95 | GENERAL_SUBTREE, 1), | ||
96 | } ASN1_SEQUENCE_END(NAME_CONSTRAINTS) | ||
97 | |||
98 | |||
99 | IMPLEMENT_ASN1_ALLOC_FUNCTIONS(GENERAL_SUBTREE) | ||
100 | IMPLEMENT_ASN1_ALLOC_FUNCTIONS(NAME_CONSTRAINTS) | ||
101 | |||
102 | static void *v2i_NAME_CONSTRAINTS(X509V3_EXT_METHOD *method, | ||
103 | X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval) | ||
104 | { | ||
105 | int i; | ||
106 | CONF_VALUE tval, *val; | ||
107 | STACK_OF(GENERAL_SUBTREE) **ptree = NULL; | ||
108 | NAME_CONSTRAINTS *ncons = NULL; | ||
109 | GENERAL_SUBTREE *sub = NULL; | ||
110 | ncons = NAME_CONSTRAINTS_new(); | ||
111 | if (!ncons) | ||
112 | goto memerr; | ||
113 | for(i = 0; i < sk_CONF_VALUE_num(nval); i++) | ||
114 | { | ||
115 | val = sk_CONF_VALUE_value(nval, i); | ||
116 | if (!strncmp(val->name, "permitted", 9) && val->name[9]) | ||
117 | { | ||
118 | ptree = &ncons->permittedSubtrees; | ||
119 | tval.name = val->name + 10; | ||
120 | } | ||
121 | else if (!strncmp(val->name, "excluded", 8) && val->name[8]) | ||
122 | { | ||
123 | ptree = &ncons->excludedSubtrees; | ||
124 | tval.name = val->name + 9; | ||
125 | } | ||
126 | else | ||
127 | { | ||
128 | X509V3err(X509V3_F_V2I_NAME_CONSTRAINTS, X509V3_R_INVALID_SYNTAX); | ||
129 | goto err; | ||
130 | } | ||
131 | tval.value = val->value; | ||
132 | sub = GENERAL_SUBTREE_new(); | ||
133 | if (!v2i_GENERAL_NAME_ex(sub->base, method, ctx, &tval, 1)) | ||
134 | goto err; | ||
135 | if (!*ptree) | ||
136 | *ptree = sk_GENERAL_SUBTREE_new_null(); | ||
137 | if (!*ptree || !sk_GENERAL_SUBTREE_push(*ptree, sub)) | ||
138 | goto memerr; | ||
139 | sub = NULL; | ||
140 | } | ||
141 | |||
142 | return ncons; | ||
143 | |||
144 | memerr: | ||
145 | X509V3err(X509V3_F_V2I_NAME_CONSTRAINTS, ERR_R_MALLOC_FAILURE); | ||
146 | err: | ||
147 | if (ncons) | ||
148 | NAME_CONSTRAINTS_free(ncons); | ||
149 | if (sub) | ||
150 | GENERAL_SUBTREE_free(sub); | ||
151 | |||
152 | return NULL; | ||
153 | } | ||
154 | |||
155 | |||
156 | |||
157 | |||
158 | static int i2r_NAME_CONSTRAINTS(X509V3_EXT_METHOD *method, | ||
159 | void *a, BIO *bp, int ind) | ||
160 | { | ||
161 | NAME_CONSTRAINTS *ncons = a; | ||
162 | do_i2r_name_constraints(method, ncons->permittedSubtrees, | ||
163 | bp, ind, "Permitted"); | ||
164 | do_i2r_name_constraints(method, ncons->excludedSubtrees, | ||
165 | bp, ind, "Excluded"); | ||
166 | return 1; | ||
167 | } | ||
168 | |||
169 | static int do_i2r_name_constraints(X509V3_EXT_METHOD *method, | ||
170 | STACK_OF(GENERAL_SUBTREE) *trees, | ||
171 | BIO *bp, int ind, char *name) | ||
172 | { | ||
173 | GENERAL_SUBTREE *tree; | ||
174 | int i; | ||
175 | if (sk_GENERAL_SUBTREE_num(trees) > 0) | ||
176 | BIO_printf(bp, "%*s%s:\n", ind, "", name); | ||
177 | for(i = 0; i < sk_GENERAL_SUBTREE_num(trees); i++) | ||
178 | { | ||
179 | tree = sk_GENERAL_SUBTREE_value(trees, i); | ||
180 | BIO_printf(bp, "%*s", ind + 2, ""); | ||
181 | if (tree->base->type == GEN_IPADD) | ||
182 | print_nc_ipadd(bp, tree->base->d.ip); | ||
183 | else | ||
184 | GENERAL_NAME_print(bp, tree->base); | ||
185 | tree = sk_GENERAL_SUBTREE_value(trees, i); | ||
186 | BIO_puts(bp, "\n"); | ||
187 | } | ||
188 | return 1; | ||
189 | } | ||
190 | |||
191 | static int print_nc_ipadd(BIO *bp, ASN1_OCTET_STRING *ip) | ||
192 | { | ||
193 | int i, len; | ||
194 | unsigned char *p; | ||
195 | p = ip->data; | ||
196 | len = ip->length; | ||
197 | BIO_puts(bp, "IP:"); | ||
198 | if(len == 8) | ||
199 | { | ||
200 | BIO_printf(bp, "%d.%d.%d.%d/%d.%d.%d.%d", | ||
201 | p[0], p[1], p[2], p[3], | ||
202 | p[4], p[5], p[6], p[7]); | ||
203 | } | ||
204 | else if(len == 32) | ||
205 | { | ||
206 | for (i = 0; i < 16; i++) | ||
207 | { | ||
208 | BIO_printf(bp, "%X", p[0] << 8 | p[1]); | ||
209 | p += 2; | ||
210 | if (i == 7) | ||
211 | BIO_puts(bp, "/"); | ||
212 | else if (i != 15) | ||
213 | BIO_puts(bp, ":"); | ||
214 | } | ||
215 | } | ||
216 | else | ||
217 | BIO_printf(bp, "IP Address:<invalid>"); | ||
218 | return 1; | ||
219 | } | ||
220 | |||
diff --git a/src/lib/libcrypto/x509v3/v3_pci.c b/src/lib/libcrypto/x509v3/v3_pci.c index b32d968619..601211f416 100644 --- a/src/lib/libcrypto/x509v3/v3_pci.c +++ b/src/lib/libcrypto/x509v3/v3_pci.c | |||
@@ -44,7 +44,7 @@ static int i2r_pci(X509V3_EXT_METHOD *method, PROXY_CERT_INFO_EXTENSION *ext, | |||
44 | static PROXY_CERT_INFO_EXTENSION *r2i_pci(X509V3_EXT_METHOD *method, | 44 | static PROXY_CERT_INFO_EXTENSION *r2i_pci(X509V3_EXT_METHOD *method, |
45 | X509V3_CTX *ctx, char *str); | 45 | X509V3_CTX *ctx, char *str); |
46 | 46 | ||
47 | X509V3_EXT_METHOD v3_pci = | 47 | const X509V3_EXT_METHOD v3_pci = |
48 | { NID_proxyCertInfo, 0, ASN1_ITEM_ref(PROXY_CERT_INFO_EXTENSION), | 48 | { NID_proxyCertInfo, 0, ASN1_ITEM_ref(PROXY_CERT_INFO_EXTENSION), |
49 | 0,0,0,0, | 49 | 0,0,0,0, |
50 | 0,0, | 50 | 0,0, |
@@ -82,13 +82,13 @@ static int process_pci_value(CONF_VALUE *val, | |||
82 | { | 82 | { |
83 | if (*language) | 83 | if (*language) |
84 | { | 84 | { |
85 | X509V3err(X509V3_F_R2I_PCI,X509V3_R_POLICY_LANGUAGE_ALREADTY_DEFINED); | 85 | X509V3err(X509V3_F_PROCESS_PCI_VALUE,X509V3_R_POLICY_LANGUAGE_ALREADTY_DEFINED); |
86 | X509V3_conf_err(val); | 86 | X509V3_conf_err(val); |
87 | return 0; | 87 | return 0; |
88 | } | 88 | } |
89 | if (!(*language = OBJ_txt2obj(val->value, 0))) | 89 | if (!(*language = OBJ_txt2obj(val->value, 0))) |
90 | { | 90 | { |
91 | X509V3err(X509V3_F_R2I_PCI,X509V3_R_INVALID_OBJECT_IDENTIFIER); | 91 | X509V3err(X509V3_F_PROCESS_PCI_VALUE,X509V3_R_INVALID_OBJECT_IDENTIFIER); |
92 | X509V3_conf_err(val); | 92 | X509V3_conf_err(val); |
93 | return 0; | 93 | return 0; |
94 | } | 94 | } |
@@ -97,13 +97,13 @@ static int process_pci_value(CONF_VALUE *val, | |||
97 | { | 97 | { |
98 | if (*pathlen) | 98 | if (*pathlen) |
99 | { | 99 | { |
100 | X509V3err(X509V3_F_R2I_PCI,X509V3_R_POLICY_PATH_LENGTH_ALREADTY_DEFINED); | 100 | X509V3err(X509V3_F_PROCESS_PCI_VALUE,X509V3_R_POLICY_PATH_LENGTH_ALREADTY_DEFINED); |
101 | X509V3_conf_err(val); | 101 | X509V3_conf_err(val); |
102 | return 0; | 102 | return 0; |
103 | } | 103 | } |
104 | if (!X509V3_get_value_int(val, pathlen)) | 104 | if (!X509V3_get_value_int(val, pathlen)) |
105 | { | 105 | { |
106 | X509V3err(X509V3_F_R2I_PCI,X509V3_R_POLICY_PATH_LENGTH); | 106 | X509V3err(X509V3_F_PROCESS_PCI_VALUE,X509V3_R_POLICY_PATH_LENGTH); |
107 | X509V3_conf_err(val); | 107 | X509V3_conf_err(val); |
108 | return 0; | 108 | return 0; |
109 | } | 109 | } |
@@ -117,7 +117,7 @@ static int process_pci_value(CONF_VALUE *val, | |||
117 | *policy = ASN1_OCTET_STRING_new(); | 117 | *policy = ASN1_OCTET_STRING_new(); |
118 | if (!*policy) | 118 | if (!*policy) |
119 | { | 119 | { |
120 | X509V3err(X509V3_F_R2I_PCI,ERR_R_MALLOC_FAILURE); | 120 | X509V3err(X509V3_F_PROCESS_PCI_VALUE,ERR_R_MALLOC_FAILURE); |
121 | X509V3_conf_err(val); | 121 | X509V3_conf_err(val); |
122 | return 0; | 122 | return 0; |
123 | } | 123 | } |
@@ -148,7 +148,7 @@ static int process_pci_value(CONF_VALUE *val, | |||
148 | BIO *b = BIO_new_file(val->value + 5, "r"); | 148 | BIO *b = BIO_new_file(val->value + 5, "r"); |
149 | if (!b) | 149 | if (!b) |
150 | { | 150 | { |
151 | X509V3err(X509V3_F_R2I_PCI,ERR_R_BIO_LIB); | 151 | X509V3err(X509V3_F_PROCESS_PCI_VALUE,ERR_R_BIO_LIB); |
152 | X509V3_conf_err(val); | 152 | X509V3_conf_err(val); |
153 | goto err; | 153 | goto err; |
154 | } | 154 | } |
@@ -172,7 +172,7 @@ static int process_pci_value(CONF_VALUE *val, | |||
172 | 172 | ||
173 | if (n < 0) | 173 | if (n < 0) |
174 | { | 174 | { |
175 | X509V3err(X509V3_F_R2I_PCI,ERR_R_BIO_LIB); | 175 | X509V3err(X509V3_F_PROCESS_PCI_VALUE,ERR_R_BIO_LIB); |
176 | X509V3_conf_err(val); | 176 | X509V3_conf_err(val); |
177 | goto err; | 177 | goto err; |
178 | } | 178 | } |
@@ -193,13 +193,13 @@ static int process_pci_value(CONF_VALUE *val, | |||
193 | } | 193 | } |
194 | else | 194 | else |
195 | { | 195 | { |
196 | X509V3err(X509V3_F_R2I_PCI,X509V3_R_INCORRECT_POLICY_SYNTAX_TAG); | 196 | X509V3err(X509V3_F_PROCESS_PCI_VALUE,X509V3_R_INCORRECT_POLICY_SYNTAX_TAG); |
197 | X509V3_conf_err(val); | 197 | X509V3_conf_err(val); |
198 | goto err; | 198 | goto err; |
199 | } | 199 | } |
200 | if (!tmp_data) | 200 | if (!tmp_data) |
201 | { | 201 | { |
202 | X509V3err(X509V3_F_R2I_PCI,ERR_R_MALLOC_FAILURE); | 202 | X509V3err(X509V3_F_PROCESS_PCI_VALUE,ERR_R_MALLOC_FAILURE); |
203 | X509V3_conf_err(val); | 203 | X509V3_conf_err(val); |
204 | goto err; | 204 | goto err; |
205 | } | 205 | } |
@@ -286,12 +286,6 @@ static PROXY_CERT_INFO_EXTENSION *r2i_pci(X509V3_EXT_METHOD *method, | |||
286 | X509V3err(X509V3_F_R2I_PCI,ERR_R_MALLOC_FAILURE); | 286 | X509V3err(X509V3_F_R2I_PCI,ERR_R_MALLOC_FAILURE); |
287 | goto err; | 287 | goto err; |
288 | } | 288 | } |
289 | pci->proxyPolicy = PROXY_POLICY_new(); | ||
290 | if (!pci->proxyPolicy) | ||
291 | { | ||
292 | X509V3err(X509V3_F_R2I_PCI,ERR_R_MALLOC_FAILURE); | ||
293 | goto err; | ||
294 | } | ||
295 | 289 | ||
296 | pci->proxyPolicy->policyLanguage = language; language = NULL; | 290 | pci->proxyPolicy->policyLanguage = language; language = NULL; |
297 | pci->proxyPolicy->policy = policy; policy = NULL; | 291 | pci->proxyPolicy->policy = policy; policy = NULL; |
@@ -301,11 +295,6 @@ err: | |||
301 | if (language) { ASN1_OBJECT_free(language); language = NULL; } | 295 | if (language) { ASN1_OBJECT_free(language); language = NULL; } |
302 | if (pathlen) { ASN1_INTEGER_free(pathlen); pathlen = NULL; } | 296 | if (pathlen) { ASN1_INTEGER_free(pathlen); pathlen = NULL; } |
303 | if (policy) { ASN1_OCTET_STRING_free(policy); policy = NULL; } | 297 | if (policy) { ASN1_OCTET_STRING_free(policy); policy = NULL; } |
304 | if (pci && pci->proxyPolicy) | ||
305 | { | ||
306 | PROXY_POLICY_free(pci->proxyPolicy); | ||
307 | pci->proxyPolicy = NULL; | ||
308 | } | ||
309 | if (pci) { PROXY_CERT_INFO_EXTENSION_free(pci); pci = NULL; } | 298 | if (pci) { PROXY_CERT_INFO_EXTENSION_free(pci); pci = NULL; } |
310 | end: | 299 | end: |
311 | sk_CONF_VALUE_pop_free(vals, X509V3_conf_free); | 300 | sk_CONF_VALUE_pop_free(vals, X509V3_conf_free); |
diff --git a/src/lib/libcrypto/x509v3/v3_pcons.c b/src/lib/libcrypto/x509v3/v3_pcons.c new file mode 100644 index 0000000000..13248c2ada --- /dev/null +++ b/src/lib/libcrypto/x509v3/v3_pcons.c | |||
@@ -0,0 +1,136 @@ | |||
1 | /* v3_pcons.c */ | ||
2 | /* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL | ||
3 | * project. | ||
4 | */ | ||
5 | /* ==================================================================== | ||
6 | * Copyright (c) 2003 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 | * This product includes cryptographic software written by Eric Young | ||
54 | * (eay@cryptsoft.com). This product includes software written by Tim | ||
55 | * Hudson (tjh@cryptsoft.com). | ||
56 | * | ||
57 | */ | ||
58 | |||
59 | |||
60 | #include <stdio.h> | ||
61 | #include "cryptlib.h" | ||
62 | #include <openssl/asn1.h> | ||
63 | #include <openssl/asn1t.h> | ||
64 | #include <openssl/conf.h> | ||
65 | #include <openssl/x509v3.h> | ||
66 | |||
67 | static STACK_OF(CONF_VALUE) *i2v_POLICY_CONSTRAINTS(X509V3_EXT_METHOD *method, | ||
68 | void *bcons, STACK_OF(CONF_VALUE) *extlist); | ||
69 | static void *v2i_POLICY_CONSTRAINTS(X509V3_EXT_METHOD *method, | ||
70 | X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *values); | ||
71 | |||
72 | const X509V3_EXT_METHOD v3_policy_constraints = { | ||
73 | NID_policy_constraints, 0, | ||
74 | ASN1_ITEM_ref(POLICY_CONSTRAINTS), | ||
75 | 0,0,0,0, | ||
76 | 0,0, | ||
77 | i2v_POLICY_CONSTRAINTS, | ||
78 | v2i_POLICY_CONSTRAINTS, | ||
79 | NULL,NULL, | ||
80 | NULL | ||
81 | }; | ||
82 | |||
83 | ASN1_SEQUENCE(POLICY_CONSTRAINTS) = { | ||
84 | ASN1_IMP_OPT(POLICY_CONSTRAINTS, requireExplicitPolicy, ASN1_INTEGER,0), | ||
85 | ASN1_IMP_OPT(POLICY_CONSTRAINTS, inhibitPolicyMapping, ASN1_INTEGER,1) | ||
86 | } ASN1_SEQUENCE_END(POLICY_CONSTRAINTS) | ||
87 | |||
88 | IMPLEMENT_ASN1_ALLOC_FUNCTIONS(POLICY_CONSTRAINTS) | ||
89 | |||
90 | |||
91 | static STACK_OF(CONF_VALUE) *i2v_POLICY_CONSTRAINTS(X509V3_EXT_METHOD *method, | ||
92 | void *a, STACK_OF(CONF_VALUE) *extlist) | ||
93 | { | ||
94 | POLICY_CONSTRAINTS *pcons = a; | ||
95 | X509V3_add_value_int("Require Explicit Policy", | ||
96 | pcons->requireExplicitPolicy, &extlist); | ||
97 | X509V3_add_value_int("Inhibit Policy Mapping", | ||
98 | pcons->inhibitPolicyMapping, &extlist); | ||
99 | return extlist; | ||
100 | } | ||
101 | |||
102 | static void *v2i_POLICY_CONSTRAINTS(X509V3_EXT_METHOD *method, | ||
103 | X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *values) | ||
104 | { | ||
105 | POLICY_CONSTRAINTS *pcons=NULL; | ||
106 | CONF_VALUE *val; | ||
107 | int i; | ||
108 | if(!(pcons = POLICY_CONSTRAINTS_new())) { | ||
109 | X509V3err(X509V3_F_V2I_POLICY_CONSTRAINTS, ERR_R_MALLOC_FAILURE); | ||
110 | return NULL; | ||
111 | } | ||
112 | for(i = 0; i < sk_CONF_VALUE_num(values); i++) { | ||
113 | val = sk_CONF_VALUE_value(values, i); | ||
114 | if(!strcmp(val->name, "requireExplicitPolicy")) { | ||
115 | if(!X509V3_get_value_int(val, | ||
116 | &pcons->requireExplicitPolicy)) goto err; | ||
117 | } else if(!strcmp(val->name, "inhibitPolicyMapping")) { | ||
118 | if(!X509V3_get_value_int(val, | ||
119 | &pcons->inhibitPolicyMapping)) goto err; | ||
120 | } else { | ||
121 | X509V3err(X509V3_F_V2I_POLICY_CONSTRAINTS, X509V3_R_INVALID_NAME); | ||
122 | X509V3_conf_err(val); | ||
123 | goto err; | ||
124 | } | ||
125 | } | ||
126 | if (!pcons->inhibitPolicyMapping && !pcons->requireExplicitPolicy) { | ||
127 | X509V3err(X509V3_F_V2I_POLICY_CONSTRAINTS, X509V3_R_ILLEGAL_EMPTY_EXTENSION); | ||
128 | goto err; | ||
129 | } | ||
130 | |||
131 | return pcons; | ||
132 | err: | ||
133 | POLICY_CONSTRAINTS_free(pcons); | ||
134 | return NULL; | ||
135 | } | ||
136 | |||
diff --git a/src/lib/libcrypto/x509v3/v3_pmaps.c b/src/lib/libcrypto/x509v3/v3_pmaps.c new file mode 100644 index 0000000000..626303264f --- /dev/null +++ b/src/lib/libcrypto/x509v3/v3_pmaps.c | |||
@@ -0,0 +1,153 @@ | |||
1 | /* v3_pmaps.c */ | ||
2 | /* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL | ||
3 | * project. | ||
4 | */ | ||
5 | /* ==================================================================== | ||
6 | * Copyright (c) 2003 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 | * This product includes cryptographic software written by Eric Young | ||
54 | * (eay@cryptsoft.com). This product includes software written by Tim | ||
55 | * Hudson (tjh@cryptsoft.com). | ||
56 | * | ||
57 | */ | ||
58 | |||
59 | |||
60 | #include <stdio.h> | ||
61 | #include "cryptlib.h" | ||
62 | #include <openssl/asn1t.h> | ||
63 | #include <openssl/conf.h> | ||
64 | #include <openssl/x509v3.h> | ||
65 | |||
66 | static void *v2i_POLICY_MAPPINGS(X509V3_EXT_METHOD *method, | ||
67 | X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval); | ||
68 | static STACK_OF(CONF_VALUE) *i2v_POLICY_MAPPINGS(X509V3_EXT_METHOD *method, | ||
69 | void *pmps, STACK_OF(CONF_VALUE) *extlist); | ||
70 | |||
71 | const X509V3_EXT_METHOD v3_policy_mappings = { | ||
72 | NID_policy_mappings, 0, | ||
73 | ASN1_ITEM_ref(POLICY_MAPPINGS), | ||
74 | 0,0,0,0, | ||
75 | 0,0, | ||
76 | i2v_POLICY_MAPPINGS, | ||
77 | v2i_POLICY_MAPPINGS, | ||
78 | 0,0, | ||
79 | NULL | ||
80 | }; | ||
81 | |||
82 | ASN1_SEQUENCE(POLICY_MAPPING) = { | ||
83 | ASN1_SIMPLE(POLICY_MAPPING, issuerDomainPolicy, ASN1_OBJECT), | ||
84 | ASN1_SIMPLE(POLICY_MAPPING, subjectDomainPolicy, ASN1_OBJECT) | ||
85 | } ASN1_SEQUENCE_END(POLICY_MAPPING) | ||
86 | |||
87 | ASN1_ITEM_TEMPLATE(POLICY_MAPPINGS) = | ||
88 | ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, POLICY_MAPPINGS, | ||
89 | POLICY_MAPPING) | ||
90 | ASN1_ITEM_TEMPLATE_END(POLICY_MAPPINGS) | ||
91 | |||
92 | IMPLEMENT_ASN1_ALLOC_FUNCTIONS(POLICY_MAPPING) | ||
93 | |||
94 | |||
95 | static STACK_OF(CONF_VALUE) *i2v_POLICY_MAPPINGS(X509V3_EXT_METHOD *method, | ||
96 | void *a, STACK_OF(CONF_VALUE) *ext_list) | ||
97 | { | ||
98 | POLICY_MAPPINGS *pmaps = a; | ||
99 | POLICY_MAPPING *pmap; | ||
100 | int i; | ||
101 | char obj_tmp1[80]; | ||
102 | char obj_tmp2[80]; | ||
103 | for(i = 0; i < sk_POLICY_MAPPING_num(pmaps); i++) { | ||
104 | pmap = sk_POLICY_MAPPING_value(pmaps, i); | ||
105 | i2t_ASN1_OBJECT(obj_tmp1, 80, pmap->issuerDomainPolicy); | ||
106 | i2t_ASN1_OBJECT(obj_tmp2, 80, pmap->subjectDomainPolicy); | ||
107 | X509V3_add_value(obj_tmp1, obj_tmp2, &ext_list); | ||
108 | } | ||
109 | return ext_list; | ||
110 | } | ||
111 | |||
112 | static void *v2i_POLICY_MAPPINGS(X509V3_EXT_METHOD *method, | ||
113 | X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval) | ||
114 | { | ||
115 | POLICY_MAPPINGS *pmaps; | ||
116 | POLICY_MAPPING *pmap; | ||
117 | ASN1_OBJECT *obj1, *obj2; | ||
118 | CONF_VALUE *val; | ||
119 | int i; | ||
120 | |||
121 | if(!(pmaps = sk_POLICY_MAPPING_new_null())) { | ||
122 | X509V3err(X509V3_F_V2I_POLICY_MAPPINGS,ERR_R_MALLOC_FAILURE); | ||
123 | return NULL; | ||
124 | } | ||
125 | |||
126 | for(i = 0; i < sk_CONF_VALUE_num(nval); i++) { | ||
127 | val = sk_CONF_VALUE_value(nval, i); | ||
128 | if(!val->value || !val->name) { | ||
129 | sk_POLICY_MAPPING_pop_free(pmaps, POLICY_MAPPING_free); | ||
130 | X509V3err(X509V3_F_V2I_POLICY_MAPPINGS,X509V3_R_INVALID_OBJECT_IDENTIFIER); | ||
131 | X509V3_conf_err(val); | ||
132 | return NULL; | ||
133 | } | ||
134 | obj1 = OBJ_txt2obj(val->name, 0); | ||
135 | obj2 = OBJ_txt2obj(val->value, 0); | ||
136 | if(!obj1 || !obj2) { | ||
137 | sk_POLICY_MAPPING_pop_free(pmaps, POLICY_MAPPING_free); | ||
138 | X509V3err(X509V3_F_V2I_POLICY_MAPPINGS,X509V3_R_INVALID_OBJECT_IDENTIFIER); | ||
139 | X509V3_conf_err(val); | ||
140 | return NULL; | ||
141 | } | ||
142 | pmap = POLICY_MAPPING_new(); | ||
143 | if (!pmap) { | ||
144 | sk_POLICY_MAPPING_pop_free(pmaps, POLICY_MAPPING_free); | ||
145 | X509V3err(X509V3_F_V2I_POLICY_MAPPINGS,ERR_R_MALLOC_FAILURE); | ||
146 | return NULL; | ||
147 | } | ||
148 | pmap->issuerDomainPolicy = obj1; | ||
149 | pmap->subjectDomainPolicy = obj2; | ||
150 | sk_POLICY_MAPPING_push(pmaps, pmap); | ||
151 | } | ||
152 | return pmaps; | ||
153 | } | ||
diff --git a/src/lib/libcrypto/x86_64cpuid.pl b/src/lib/libcrypto/x86_64cpuid.pl new file mode 100644 index 0000000000..2616a03da6 --- /dev/null +++ b/src/lib/libcrypto/x86_64cpuid.pl | |||
@@ -0,0 +1,159 @@ | |||
1 | #!/usr/bin/env perl | ||
2 | |||
3 | $output=shift; | ||
4 | $masm=1 if ($output =~ /\.asm/); | ||
5 | open STDOUT,">$output" || die "can't open $output: $!"; | ||
6 | |||
7 | print<<___ if(defined($masm)); | ||
8 | _TEXT SEGMENT | ||
9 | PUBLIC OPENSSL_rdtsc | ||
10 | |||
11 | PUBLIC OPENSSL_atomic_add | ||
12 | ALIGN 16 | ||
13 | OPENSSL_atomic_add PROC | ||
14 | mov eax,DWORD PTR[rcx] | ||
15 | \$Lspin: lea r8,DWORD PTR[rdx+rax] | ||
16 | lock cmpxchg DWORD PTR[rcx],r8d | ||
17 | jne \$Lspin | ||
18 | mov eax,r8d | ||
19 | cdqe | ||
20 | ret | ||
21 | OPENSSL_atomic_add ENDP | ||
22 | |||
23 | PUBLIC OPENSSL_wipe_cpu | ||
24 | ALIGN 16 | ||
25 | OPENSSL_wipe_cpu PROC | ||
26 | pxor xmm0,xmm0 | ||
27 | pxor xmm1,xmm1 | ||
28 | pxor xmm2,xmm2 | ||
29 | pxor xmm3,xmm3 | ||
30 | pxor xmm4,xmm4 | ||
31 | pxor xmm5,xmm5 | ||
32 | xor rcx,rcx | ||
33 | xor rdx,rdx | ||
34 | xor r8,r8 | ||
35 | xor r9,r9 | ||
36 | xor r10,r10 | ||
37 | xor r11,r11 | ||
38 | lea rax,QWORD PTR[rsp+8] | ||
39 | ret | ||
40 | OPENSSL_wipe_cpu ENDP | ||
41 | _TEXT ENDS | ||
42 | |||
43 | CRT\$XIU SEGMENT | ||
44 | EXTRN OPENSSL_cpuid_setup:PROC | ||
45 | DQ OPENSSL_cpuid_setup | ||
46 | CRT\$XIU ENDS | ||
47 | |||
48 | ___ | ||
49 | print<<___ if(!defined($masm)); | ||
50 | .text | ||
51 | |||
52 | .globl OPENSSL_atomic_add | ||
53 | .type OPENSSL_atomic_add,\@function | ||
54 | .align 16 | ||
55 | OPENSSL_atomic_add: | ||
56 | movl (%rdi),%eax | ||
57 | .Lspin: leaq (%rsi,%rax),%r8 | ||
58 | lock; cmpxchgl %r8d,(%rdi) | ||
59 | jne .Lspin | ||
60 | movl %r8d,%eax | ||
61 | .byte 0x48,0x98 | ||
62 | ret | ||
63 | .size OPENSSL_atomic_add,.-OPENSSL_atomic_add | ||
64 | |||
65 | .globl OPENSSL_wipe_cpu | ||
66 | .type OPENSSL_wipe_cpu,\@function | ||
67 | .align 16 | ||
68 | OPENSSL_wipe_cpu: | ||
69 | pxor %xmm0,%xmm0 | ||
70 | pxor %xmm1,%xmm1 | ||
71 | pxor %xmm2,%xmm2 | ||
72 | pxor %xmm3,%xmm3 | ||
73 | pxor %xmm4,%xmm4 | ||
74 | pxor %xmm5,%xmm5 | ||
75 | pxor %xmm6,%xmm6 | ||
76 | pxor %xmm7,%xmm7 | ||
77 | pxor %xmm8,%xmm8 | ||
78 | pxor %xmm9,%xmm9 | ||
79 | pxor %xmm10,%xmm10 | ||
80 | pxor %xmm11,%xmm11 | ||
81 | pxor %xmm12,%xmm12 | ||
82 | pxor %xmm13,%xmm13 | ||
83 | pxor %xmm14,%xmm14 | ||
84 | pxor %xmm15,%xmm15 | ||
85 | xorq %rcx,%rcx | ||
86 | xorq %rdx,%rdx | ||
87 | xorq %rsi,%rsi | ||
88 | xorq %rdi,%rdi | ||
89 | xorq %r8,%r8 | ||
90 | xorq %r9,%r9 | ||
91 | xorq %r10,%r10 | ||
92 | xorq %r11,%r11 | ||
93 | leaq 8(%rsp),%rax | ||
94 | ret | ||
95 | .size OPENSSL_wipe_cpu,.-OPENSSL_wipe_cpu | ||
96 | |||
97 | .section .init | ||
98 | call OPENSSL_cpuid_setup | ||
99 | |||
100 | ___ | ||
101 | |||
102 | open STDOUT,"| $^X perlasm/x86_64-xlate.pl $output"; | ||
103 | print<<___; | ||
104 | .text | ||
105 | |||
106 | .globl OPENSSL_rdtsc | ||
107 | .type OPENSSL_rdtsc,\@abi-omnipotent | ||
108 | .align 16 | ||
109 | OPENSSL_rdtsc: | ||
110 | rdtsc | ||
111 | shl \$32,%rdx | ||
112 | or %rdx,%rax | ||
113 | ret | ||
114 | .size OPENSSL_rdtsc,.-OPENSSL_rdtsc | ||
115 | |||
116 | .globl OPENSSL_ia32_cpuid | ||
117 | .type OPENSSL_ia32_cpuid,\@abi-omnipotent | ||
118 | .align 16 | ||
119 | OPENSSL_ia32_cpuid: | ||
120 | mov %rbx,%r8 | ||
121 | |||
122 | xor %eax,%eax | ||
123 | cpuid | ||
124 | xor %eax,%eax | ||
125 | cmp \$0x756e6547,%ebx # "Genu" | ||
126 | setne %al | ||
127 | mov %eax,%r9d | ||
128 | cmp \$0x49656e69,%edx # "ineI" | ||
129 | setne %al | ||
130 | or %eax,%r9d | ||
131 | cmp \$0x6c65746e,%ecx # "ntel" | ||
132 | setne %al | ||
133 | or %eax,%r9d | ||
134 | |||
135 | mov \$1,%eax | ||
136 | cpuid | ||
137 | cmp \$0,%r9d | ||
138 | jne .Lnotintel | ||
139 | or \$0x00100000,%edx # use reserved 20th bit to engage RC4_CHAR | ||
140 | and \$15,%ah | ||
141 | cmp \$15,%ah # examine Family ID | ||
142 | je .Lnotintel | ||
143 | or \$0x40000000,%edx # use reserved bit to skip unrolled loop | ||
144 | .Lnotintel: | ||
145 | bt \$28,%edx # test hyper-threading bit | ||
146 | jnc .Ldone | ||
147 | shr \$16,%ebx | ||
148 | cmp \$1,%bl # see if cache is shared | ||
149 | ja .Ldone | ||
150 | and \$0xefffffff,%edx # ~(1<<28) | ||
151 | .Ldone: | ||
152 | shl \$32,%rcx | ||
153 | mov %edx,%eax | ||
154 | mov %r8,%rbx | ||
155 | or %rcx,%rax | ||
156 | ret | ||
157 | .size OPENSSL_ia32_cpuid,.-OPENSSL_ia32_cpuid | ||
158 | ___ | ||
159 | close STDOUT; # flush | ||
diff --git a/src/lib/libcrypto/x86cpuid.pl b/src/lib/libcrypto/x86cpuid.pl new file mode 100644 index 0000000000..4408ef2936 --- /dev/null +++ b/src/lib/libcrypto/x86cpuid.pl | |||
@@ -0,0 +1,225 @@ | |||
1 | #!/usr/bin/env perl | ||
2 | |||
3 | push(@INC,"perlasm"); | ||
4 | require "x86asm.pl"; | ||
5 | |||
6 | &asm_init($ARGV[0],"x86cpuid"); | ||
7 | |||
8 | for (@ARGV) { $sse2=1 if (/-DOPENSSL_IA32_SSE2/); } | ||
9 | |||
10 | &function_begin("OPENSSL_ia32_cpuid"); | ||
11 | &xor ("edx","edx"); | ||
12 | &pushf (); | ||
13 | &pop ("eax"); | ||
14 | &mov ("ecx","eax"); | ||
15 | &xor ("eax",1<<21); | ||
16 | &push ("eax"); | ||
17 | &popf (); | ||
18 | &pushf (); | ||
19 | &pop ("eax"); | ||
20 | &xor ("ecx","eax"); | ||
21 | &bt ("ecx",21); | ||
22 | &jnc (&label("done")); | ||
23 | &xor ("eax","eax"); | ||
24 | &cpuid (); | ||
25 | &xor ("eax","eax"); | ||
26 | &cmp ("ebx",0x756e6547); # "Genu" | ||
27 | &data_byte(0x0f,0x95,0xc0); #&setne (&LB("eax")); | ||
28 | &mov ("ebp","eax"); | ||
29 | &cmp ("edx",0x49656e69); # "ineI" | ||
30 | &data_byte(0x0f,0x95,0xc0); #&setne (&LB("eax")); | ||
31 | &or ("ebp","eax"); | ||
32 | &cmp ("ecx",0x6c65746e); # "ntel" | ||
33 | &data_byte(0x0f,0x95,0xc0); #&setne (&LB("eax")); | ||
34 | &or ("ebp","eax"); | ||
35 | &mov ("eax",1); | ||
36 | &cpuid (); | ||
37 | &cmp ("ebp",0); | ||
38 | &jne (&label("notP4")); | ||
39 | &and ("eax",15<<8); # familiy ID | ||
40 | &cmp ("eax",15<<8); # P4? | ||
41 | &jne (&label("notP4")); | ||
42 | &or ("edx",1<<20); # use reserved bit to engage RC4_CHAR | ||
43 | &set_label("notP4"); | ||
44 | &bt ("edx",28); # test hyper-threading bit | ||
45 | &jnc (&label("done")); | ||
46 | &shr ("ebx",16); | ||
47 | &and ("ebx",0xff); | ||
48 | &cmp ("ebx",1); # see if cache is shared(*) | ||
49 | &ja (&label("done")); | ||
50 | &and ("edx",0xefffffff); # clear hyper-threading bit if not | ||
51 | &set_label("done"); | ||
52 | &mov ("eax","edx"); | ||
53 | &mov ("edx","ecx"); | ||
54 | &function_end("OPENSSL_ia32_cpuid"); | ||
55 | # (*) on Core2 this value is set to 2 denoting the fact that L2 | ||
56 | # cache is shared between cores. | ||
57 | |||
58 | &external_label("OPENSSL_ia32cap_P"); | ||
59 | |||
60 | &function_begin_B("OPENSSL_rdtsc","EXTRN\t_OPENSSL_ia32cap_P:DWORD"); | ||
61 | &xor ("eax","eax"); | ||
62 | &xor ("edx","edx"); | ||
63 | &picmeup("ecx","OPENSSL_ia32cap_P"); | ||
64 | &bt (&DWP(0,"ecx"),4); | ||
65 | &jnc (&label("notsc")); | ||
66 | &rdtsc (); | ||
67 | &set_label("notsc"); | ||
68 | &ret (); | ||
69 | &function_end_B("OPENSSL_rdtsc"); | ||
70 | |||
71 | # This works in Ring 0 only [read DJGPP+MS-DOS+privileged DPMI host], | ||
72 | # but it's safe to call it on any [supported] 32-bit platform... | ||
73 | # Just check for [non-]zero return value... | ||
74 | &function_begin_B("OPENSSL_instrument_halt","EXTRN\t_OPENSSL_ia32cap_P:DWORD"); | ||
75 | &picmeup("ecx","OPENSSL_ia32cap_P"); | ||
76 | &bt (&DWP(0,"ecx"),4); | ||
77 | &jnc (&label("nohalt")); # no TSC | ||
78 | |||
79 | &data_word(0x9058900e); # push %cs; pop %eax | ||
80 | &and ("eax",3); | ||
81 | &jnz (&label("nohalt")); # not enough privileges | ||
82 | |||
83 | &pushf (); | ||
84 | &pop ("eax") | ||
85 | &bt ("eax",9); | ||
86 | &jnc (&label("nohalt")); # interrupts are disabled | ||
87 | |||
88 | &rdtsc (); | ||
89 | &push ("edx"); | ||
90 | &push ("eax"); | ||
91 | &halt (); | ||
92 | &rdtsc (); | ||
93 | |||
94 | &sub ("eax",&DWP(0,"esp")); | ||
95 | &sbb ("edx",&DWP(4,"esp")); | ||
96 | &add ("esp",8); | ||
97 | &ret (); | ||
98 | |||
99 | &set_label("nohalt"); | ||
100 | &xor ("eax","eax"); | ||
101 | &xor ("edx","edx"); | ||
102 | &ret (); | ||
103 | &function_end_B("OPENSSL_instrument_halt"); | ||
104 | |||
105 | # Essentially there is only one use for this function. Under DJGPP: | ||
106 | # | ||
107 | # #include <go32.h> | ||
108 | # ... | ||
109 | # i=OPENSSL_far_spin(_dos_ds,0x46c); | ||
110 | # ... | ||
111 | # to obtain the number of spins till closest timer interrupt. | ||
112 | |||
113 | &function_begin_B("OPENSSL_far_spin"); | ||
114 | &pushf (); | ||
115 | &pop ("eax") | ||
116 | &bt ("eax",9); | ||
117 | &jnc (&label("nospin")); # interrupts are disabled | ||
118 | |||
119 | &mov ("eax",&DWP(4,"esp")); | ||
120 | &mov ("ecx",&DWP(8,"esp")); | ||
121 | &data_word (0x90d88e1e); # push %ds, mov %eax,%ds | ||
122 | &xor ("eax","eax"); | ||
123 | &mov ("edx",&DWP(0,"ecx")); | ||
124 | &jmp (&label("spin")); | ||
125 | |||
126 | &align (16); | ||
127 | &set_label("spin"); | ||
128 | &inc ("eax"); | ||
129 | &cmp ("edx",&DWP(0,"ecx")); | ||
130 | &je (&label("spin")); | ||
131 | |||
132 | &data_word (0x1f909090); # pop %ds | ||
133 | &ret (); | ||
134 | |||
135 | &set_label("nospin"); | ||
136 | &xor ("eax","eax"); | ||
137 | &xor ("edx","edx"); | ||
138 | &ret (); | ||
139 | &function_end_B("OPENSSL_far_spin"); | ||
140 | |||
141 | &function_begin_B("OPENSSL_wipe_cpu","EXTRN\t_OPENSSL_ia32cap_P:DWORD"); | ||
142 | &xor ("eax","eax"); | ||
143 | &xor ("edx","edx"); | ||
144 | &picmeup("ecx","OPENSSL_ia32cap_P"); | ||
145 | &mov ("ecx",&DWP(0,"ecx")); | ||
146 | &bt (&DWP(0,"ecx"),1); | ||
147 | &jnc (&label("no_x87")); | ||
148 | if ($sse2) { | ||
149 | &bt (&DWP(0,"ecx"),26); | ||
150 | &jnc (&label("no_sse2")); | ||
151 | &pxor ("xmm0","xmm0"); | ||
152 | &pxor ("xmm1","xmm1"); | ||
153 | &pxor ("xmm2","xmm2"); | ||
154 | &pxor ("xmm3","xmm3"); | ||
155 | &pxor ("xmm4","xmm4"); | ||
156 | &pxor ("xmm5","xmm5"); | ||
157 | &pxor ("xmm6","xmm6"); | ||
158 | &pxor ("xmm7","xmm7"); | ||
159 | &set_label("no_sse2"); | ||
160 | } | ||
161 | # just a bunch of fldz to zap the fp/mm bank followed by finit... | ||
162 | &data_word(0xeed9eed9,0xeed9eed9,0xeed9eed9,0xeed9eed9,0x90e3db9b); | ||
163 | &set_label("no_x87"); | ||
164 | &lea ("eax",&DWP(4,"esp")); | ||
165 | &ret (); | ||
166 | &function_end_B("OPENSSL_wipe_cpu"); | ||
167 | |||
168 | &function_begin_B("OPENSSL_atomic_add"); | ||
169 | &mov ("edx",&DWP(4,"esp")); # fetch the pointer, 1st arg | ||
170 | &mov ("ecx",&DWP(8,"esp")); # fetch the increment, 2nd arg | ||
171 | &push ("ebx"); | ||
172 | &nop (); | ||
173 | &mov ("eax",&DWP(0,"edx")); | ||
174 | &set_label("spin"); | ||
175 | &lea ("ebx",&DWP(0,"eax","ecx")); | ||
176 | &nop (); | ||
177 | &data_word(0x1ab10ff0); # lock; cmpxchg %ebx,(%edx) # %eax is envolved and is always reloaded | ||
178 | &jne (&label("spin")); | ||
179 | &mov ("eax","ebx"); # OpenSSL expects the new value | ||
180 | &pop ("ebx"); | ||
181 | &ret (); | ||
182 | &function_end_B("OPENSSL_atomic_add"); | ||
183 | |||
184 | # This function can become handy under Win32 in situations when | ||
185 | # we don't know which calling convention, __stdcall or __cdecl(*), | ||
186 | # indirect callee is using. In C it can be deployed as | ||
187 | # | ||
188 | #ifdef OPENSSL_CPUID_OBJ | ||
189 | # type OPENSSL_indirect_call(void *f,...); | ||
190 | # ... | ||
191 | # OPENSSL_indirect_call(func,[up to $max arguments]); | ||
192 | #endif | ||
193 | # | ||
194 | # (*) it's designed to work even for __fastcall if number of | ||
195 | # arguments is 1 or 2! | ||
196 | &function_begin_B("OPENSSL_indirect_call"); | ||
197 | { | ||
198 | my $i,$max=7; # $max has to be chosen as 4*n-1 | ||
199 | # in order to preserve eventual | ||
200 | # stack alignment | ||
201 | &push ("ebp"); | ||
202 | &mov ("ebp","esp"); | ||
203 | &sub ("esp",$max*4); | ||
204 | &mov ("ecx",&DWP(12,"ebp")); | ||
205 | &mov (&DWP(0,"esp"),"ecx"); | ||
206 | &mov ("edx",&DWP(16,"ebp")); | ||
207 | &mov (&DWP(4,"esp"),"edx"); | ||
208 | for($i=2;$i<$max;$i++) | ||
209 | { | ||
210 | # Some copies will be redundant/bogus... | ||
211 | &mov ("eax",&DWP(12+$i*4,"ebp")); | ||
212 | &mov (&DWP(0+$i*4,"esp"),"eax"); | ||
213 | } | ||
214 | &call_ptr (&DWP(8,"ebp"));# make the call... | ||
215 | &mov ("esp","ebp"); # ... and just restore the stack pointer | ||
216 | # without paying attention to what we called, | ||
217 | # (__cdecl *func) or (__stdcall *one). | ||
218 | &pop ("ebp"); | ||
219 | &ret (); | ||
220 | } | ||
221 | &function_end_B("OPENSSL_indirect_call"); | ||
222 | |||
223 | &initseg("OPENSSL_cpuid_setup"); | ||
224 | |||
225 | &asm_finish(); | ||
diff --git a/src/lib/libssl/d1_both.c b/src/lib/libssl/d1_both.c new file mode 100644 index 0000000000..15a201a25c --- /dev/null +++ b/src/lib/libssl/d1_both.c | |||
@@ -0,0 +1,1193 @@ | |||
1 | /* ssl/d1_both.c */ | ||
2 | /* | ||
3 | * DTLS implementation written by Nagendra Modadugu | ||
4 | * (nagendra@cs.stanford.edu) for the OpenSSL project 2005. | ||
5 | */ | ||
6 | /* ==================================================================== | ||
7 | * Copyright (c) 1998-2005 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 | * openssl-core@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 | * This product includes cryptographic software written by Eric Young | ||
55 | * (eay@cryptsoft.com). This product includes software written by Tim | ||
56 | * Hudson (tjh@cryptsoft.com). | ||
57 | * | ||
58 | */ | ||
59 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) | ||
60 | * All rights reserved. | ||
61 | * | ||
62 | * This package is an SSL implementation written | ||
63 | * by Eric Young (eay@cryptsoft.com). | ||
64 | * The implementation was written so as to conform with Netscapes SSL. | ||
65 | * | ||
66 | * This library is free for commercial and non-commercial use as long as | ||
67 | * the following conditions are aheared to. The following conditions | ||
68 | * apply to all code found in this distribution, be it the RC4, RSA, | ||
69 | * lhash, DES, etc., code; not just the SSL code. The SSL documentation | ||
70 | * included with this distribution is covered by the same copyright terms | ||
71 | * except that the holder is Tim Hudson (tjh@cryptsoft.com). | ||
72 | * | ||
73 | * Copyright remains Eric Young's, and as such any Copyright notices in | ||
74 | * the code are not to be removed. | ||
75 | * If this package is used in a product, Eric Young should be given attribution | ||
76 | * as the author of the parts of the library used. | ||
77 | * This can be in the form of a textual message at program startup or | ||
78 | * in documentation (online or textual) provided with the package. | ||
79 | * | ||
80 | * Redistribution and use in source and binary forms, with or without | ||
81 | * modification, are permitted provided that the following conditions | ||
82 | * are met: | ||
83 | * 1. Redistributions of source code must retain the copyright | ||
84 | * notice, this list of conditions and the following disclaimer. | ||
85 | * 2. Redistributions in binary form must reproduce the above copyright | ||
86 | * notice, this list of conditions and the following disclaimer in the | ||
87 | * documentation and/or other materials provided with the distribution. | ||
88 | * 3. All advertising materials mentioning features or use of this software | ||
89 | * must display the following acknowledgement: | ||
90 | * "This product includes cryptographic software written by | ||
91 | * Eric Young (eay@cryptsoft.com)" | ||
92 | * The word 'cryptographic' can be left out if the rouines from the library | ||
93 | * being used are not cryptographic related :-). | ||
94 | * 4. If you include any Windows specific code (or a derivative thereof) from | ||
95 | * the apps directory (application code) you must include an acknowledgement: | ||
96 | * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" | ||
97 | * | ||
98 | * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND | ||
99 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
100 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
101 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | ||
102 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
103 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
104 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
105 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
106 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
107 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
108 | * SUCH DAMAGE. | ||
109 | * | ||
110 | * The licence and distribution terms for any publically available version or | ||
111 | * derivative of this code cannot be changed. i.e. this code cannot simply be | ||
112 | * copied and put under another distribution licence | ||
113 | * [including the GNU Public Licence.] | ||
114 | */ | ||
115 | |||
116 | #include <limits.h> | ||
117 | #include <string.h> | ||
118 | #include <stdio.h> | ||
119 | #include "ssl_locl.h" | ||
120 | #include <openssl/buffer.h> | ||
121 | #include <openssl/rand.h> | ||
122 | #include <openssl/objects.h> | ||
123 | #include <openssl/evp.h> | ||
124 | #include <openssl/x509.h> | ||
125 | |||
126 | |||
127 | /* XDTLS: figure out the right values */ | ||
128 | static unsigned int g_probable_mtu[] = {1500 - 28, 512 - 28, 256 - 28}; | ||
129 | |||
130 | static unsigned int dtls1_min_mtu(void); | ||
131 | static unsigned int dtls1_guess_mtu(unsigned int curr_mtu); | ||
132 | static void dtls1_fix_message_header(SSL *s, unsigned long frag_off, | ||
133 | unsigned long frag_len); | ||
134 | static unsigned char *dtls1_write_message_header(SSL *s, | ||
135 | unsigned char *p); | ||
136 | static void dtls1_set_message_header_int(SSL *s, unsigned char mt, | ||
137 | unsigned long len, unsigned short seq_num, unsigned long frag_off, | ||
138 | unsigned long frag_len); | ||
139 | static int dtls1_retransmit_buffered_messages(SSL *s); | ||
140 | static long dtls1_get_message_fragment(SSL *s, int st1, int stn, | ||
141 | long max, int *ok); | ||
142 | |||
143 | static hm_fragment * | ||
144 | dtls1_hm_fragment_new(unsigned long frag_len) | ||
145 | { | ||
146 | hm_fragment *frag = NULL; | ||
147 | unsigned char *buf = NULL; | ||
148 | |||
149 | frag = (hm_fragment *)OPENSSL_malloc(sizeof(hm_fragment)); | ||
150 | if ( frag == NULL) | ||
151 | return NULL; | ||
152 | |||
153 | if (frag_len) | ||
154 | { | ||
155 | buf = (unsigned char *)OPENSSL_malloc(frag_len); | ||
156 | if ( buf == NULL) | ||
157 | { | ||
158 | OPENSSL_free(frag); | ||
159 | return NULL; | ||
160 | } | ||
161 | } | ||
162 | |||
163 | /* zero length fragment gets zero frag->fragment */ | ||
164 | frag->fragment = buf; | ||
165 | |||
166 | return frag; | ||
167 | } | ||
168 | |||
169 | static void | ||
170 | dtls1_hm_fragment_free(hm_fragment *frag) | ||
171 | { | ||
172 | if (frag->fragment) OPENSSL_free(frag->fragment); | ||
173 | OPENSSL_free(frag); | ||
174 | } | ||
175 | |||
176 | /* send s->init_buf in records of type 'type' (SSL3_RT_HANDSHAKE or SSL3_RT_CHANGE_CIPHER_SPEC) */ | ||
177 | int dtls1_do_write(SSL *s, int type) | ||
178 | { | ||
179 | int ret; | ||
180 | int curr_mtu; | ||
181 | unsigned int len, frag_off; | ||
182 | |||
183 | /* AHA! Figure out the MTU, and stick to the right size */ | ||
184 | if ( ! (SSL_get_options(s) & SSL_OP_NO_QUERY_MTU)) | ||
185 | { | ||
186 | s->d1->mtu = | ||
187 | BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_QUERY_MTU, 0, NULL); | ||
188 | |||
189 | /* I've seen the kernel return bogus numbers when it doesn't know | ||
190 | * (initial write), so just make sure we have a reasonable number */ | ||
191 | if ( s->d1->mtu < dtls1_min_mtu()) | ||
192 | { | ||
193 | s->d1->mtu = 0; | ||
194 | s->d1->mtu = dtls1_guess_mtu(s->d1->mtu); | ||
195 | BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SET_MTU, | ||
196 | s->d1->mtu, NULL); | ||
197 | } | ||
198 | } | ||
199 | #if 0 | ||
200 | mtu = s->d1->mtu; | ||
201 | |||
202 | fprintf(stderr, "using MTU = %d\n", mtu); | ||
203 | |||
204 | mtu -= (DTLS1_HM_HEADER_LENGTH + DTLS1_RT_HEADER_LENGTH); | ||
205 | |||
206 | curr_mtu = mtu - BIO_wpending(SSL_get_wbio(s)); | ||
207 | |||
208 | if ( curr_mtu > 0) | ||
209 | mtu = curr_mtu; | ||
210 | else if ( ( ret = BIO_flush(SSL_get_wbio(s))) <= 0) | ||
211 | return ret; | ||
212 | |||
213 | if ( BIO_wpending(SSL_get_wbio(s)) + s->init_num >= mtu) | ||
214 | { | ||
215 | ret = BIO_flush(SSL_get_wbio(s)); | ||
216 | if ( ret <= 0) | ||
217 | return ret; | ||
218 | mtu = s->d1->mtu - (DTLS1_HM_HEADER_LENGTH + DTLS1_RT_HEADER_LENGTH); | ||
219 | } | ||
220 | |||
221 | OPENSSL_assert(mtu > 0); /* should have something reasonable now */ | ||
222 | |||
223 | #endif | ||
224 | |||
225 | if ( s->init_off == 0 && type == SSL3_RT_HANDSHAKE) | ||
226 | OPENSSL_assert(s->init_num == | ||
227 | (int)s->d1->w_msg_hdr.msg_len + DTLS1_HM_HEADER_LENGTH); | ||
228 | |||
229 | frag_off = 0; | ||
230 | while( s->init_num) | ||
231 | { | ||
232 | curr_mtu = s->d1->mtu - BIO_wpending(SSL_get_wbio(s)) - | ||
233 | DTLS1_RT_HEADER_LENGTH; | ||
234 | |||
235 | if ( curr_mtu <= DTLS1_HM_HEADER_LENGTH) | ||
236 | { | ||
237 | /* grr.. we could get an error if MTU picked was wrong */ | ||
238 | ret = BIO_flush(SSL_get_wbio(s)); | ||
239 | if ( ret <= 0) | ||
240 | return ret; | ||
241 | curr_mtu = s->d1->mtu - DTLS1_RT_HEADER_LENGTH; | ||
242 | } | ||
243 | |||
244 | if ( s->init_num > curr_mtu) | ||
245 | len = curr_mtu; | ||
246 | else | ||
247 | len = s->init_num; | ||
248 | |||
249 | |||
250 | /* XDTLS: this function is too long. split out the CCS part */ | ||
251 | if ( type == SSL3_RT_HANDSHAKE) | ||
252 | { | ||
253 | if ( s->init_off != 0) | ||
254 | { | ||
255 | OPENSSL_assert(s->init_off > DTLS1_HM_HEADER_LENGTH); | ||
256 | s->init_off -= DTLS1_HM_HEADER_LENGTH; | ||
257 | s->init_num += DTLS1_HM_HEADER_LENGTH; | ||
258 | |||
259 | /* write atleast DTLS1_HM_HEADER_LENGTH bytes */ | ||
260 | if ( len <= DTLS1_HM_HEADER_LENGTH) | ||
261 | len += DTLS1_HM_HEADER_LENGTH; | ||
262 | } | ||
263 | |||
264 | dtls1_fix_message_header(s, frag_off, | ||
265 | len - DTLS1_HM_HEADER_LENGTH); | ||
266 | |||
267 | dtls1_write_message_header(s, (unsigned char *)&s->init_buf->data[s->init_off]); | ||
268 | |||
269 | OPENSSL_assert(len >= DTLS1_HM_HEADER_LENGTH); | ||
270 | } | ||
271 | |||
272 | ret=dtls1_write_bytes(s,type,&s->init_buf->data[s->init_off], | ||
273 | len); | ||
274 | if (ret < 0) | ||
275 | { | ||
276 | /* might need to update MTU here, but we don't know | ||
277 | * which previous packet caused the failure -- so can't | ||
278 | * really retransmit anything. continue as if everything | ||
279 | * is fine and wait for an alert to handle the | ||
280 | * retransmit | ||
281 | */ | ||
282 | if ( BIO_ctrl(SSL_get_wbio(s), | ||
283 | BIO_CTRL_DGRAM_MTU_EXCEEDED, 0, NULL)) | ||
284 | s->d1->mtu = BIO_ctrl(SSL_get_wbio(s), | ||
285 | BIO_CTRL_DGRAM_QUERY_MTU, 0, NULL); | ||
286 | else | ||
287 | return(-1); | ||
288 | } | ||
289 | else | ||
290 | { | ||
291 | |||
292 | /* bad if this assert fails, only part of the handshake | ||
293 | * message got sent. but why would this happen? */ | ||
294 | OPENSSL_assert(len == (unsigned int)ret); | ||
295 | |||
296 | if (type == SSL3_RT_HANDSHAKE && ! s->d1->retransmitting) | ||
297 | { | ||
298 | /* should not be done for 'Hello Request's, but in that case | ||
299 | * we'll ignore the result anyway */ | ||
300 | unsigned char *p = (unsigned char *)&s->init_buf->data[s->init_off]; | ||
301 | const struct hm_header_st *msg_hdr = &s->d1->w_msg_hdr; | ||
302 | int xlen; | ||
303 | |||
304 | if (frag_off == 0 && s->client_version != DTLS1_BAD_VER) | ||
305 | { | ||
306 | /* reconstruct message header is if it | ||
307 | * is being sent in single fragment */ | ||
308 | *p++ = msg_hdr->type; | ||
309 | l2n3(msg_hdr->msg_len,p); | ||
310 | s2n (msg_hdr->seq,p); | ||
311 | l2n3(0,p); | ||
312 | l2n3(msg_hdr->msg_len,p); | ||
313 | p -= DTLS1_HM_HEADER_LENGTH; | ||
314 | xlen = ret; | ||
315 | } | ||
316 | else | ||
317 | { | ||
318 | p += DTLS1_HM_HEADER_LENGTH; | ||
319 | xlen = ret - DTLS1_HM_HEADER_LENGTH; | ||
320 | } | ||
321 | |||
322 | ssl3_finish_mac(s, p, xlen); | ||
323 | } | ||
324 | |||
325 | if (ret == s->init_num) | ||
326 | { | ||
327 | if (s->msg_callback) | ||
328 | s->msg_callback(1, s->version, type, s->init_buf->data, | ||
329 | (size_t)(s->init_off + s->init_num), s, | ||
330 | s->msg_callback_arg); | ||
331 | |||
332 | s->init_off = 0; /* done writing this message */ | ||
333 | s->init_num = 0; | ||
334 | |||
335 | return(1); | ||
336 | } | ||
337 | s->init_off+=ret; | ||
338 | s->init_num-=ret; | ||
339 | frag_off += (ret -= DTLS1_HM_HEADER_LENGTH); | ||
340 | } | ||
341 | } | ||
342 | return(0); | ||
343 | } | ||
344 | |||
345 | |||
346 | /* Obtain handshake message of message type 'mt' (any if mt == -1), | ||
347 | * maximum acceptable body length 'max'. | ||
348 | * Read an entire handshake message. Handshake messages arrive in | ||
349 | * fragments. | ||
350 | */ | ||
351 | long dtls1_get_message(SSL *s, int st1, int stn, int mt, long max, int *ok) | ||
352 | { | ||
353 | int i, al; | ||
354 | struct hm_header_st *msg_hdr; | ||
355 | |||
356 | /* s3->tmp is used to store messages that are unexpected, caused | ||
357 | * by the absence of an optional handshake message */ | ||
358 | if (s->s3->tmp.reuse_message) | ||
359 | { | ||
360 | s->s3->tmp.reuse_message=0; | ||
361 | if ((mt >= 0) && (s->s3->tmp.message_type != mt)) | ||
362 | { | ||
363 | al=SSL_AD_UNEXPECTED_MESSAGE; | ||
364 | SSLerr(SSL_F_DTLS1_GET_MESSAGE,SSL_R_UNEXPECTED_MESSAGE); | ||
365 | goto f_err; | ||
366 | } | ||
367 | *ok=1; | ||
368 | s->init_msg = s->init_buf->data + DTLS1_HM_HEADER_LENGTH; | ||
369 | s->init_num = (int)s->s3->tmp.message_size; | ||
370 | return s->init_num; | ||
371 | } | ||
372 | |||
373 | msg_hdr = &s->d1->r_msg_hdr; | ||
374 | do | ||
375 | { | ||
376 | if ( msg_hdr->frag_off == 0) | ||
377 | { | ||
378 | /* s->d1->r_message_header.msg_len = 0; */ | ||
379 | memset(msg_hdr, 0x00, sizeof(struct hm_header_st)); | ||
380 | } | ||
381 | |||
382 | i = dtls1_get_message_fragment(s, st1, stn, max, ok); | ||
383 | if ( i == DTLS1_HM_BAD_FRAGMENT || | ||
384 | i == DTLS1_HM_FRAGMENT_RETRY) /* bad fragment received */ | ||
385 | continue; | ||
386 | else if ( i <= 0 && !*ok) | ||
387 | return i; | ||
388 | |||
389 | /* Note that s->init_sum is used as a counter summing | ||
390 | * up fragments' lengths: as soon as they sum up to | ||
391 | * handshake packet length, we assume we have got all | ||
392 | * the fragments. Overlapping fragments would cause | ||
393 | * premature termination, so we don't expect overlaps. | ||
394 | * Well, handling overlaps would require something more | ||
395 | * drastic. Indeed, as it is now there is no way to | ||
396 | * tell if out-of-order fragment from the middle was | ||
397 | * the last. '>=' is the best/least we can do to control | ||
398 | * the potential damage caused by malformed overlaps. */ | ||
399 | if ((unsigned int)s->init_num >= msg_hdr->msg_len) | ||
400 | { | ||
401 | unsigned char *p = (unsigned char *)s->init_buf->data; | ||
402 | unsigned long msg_len = msg_hdr->msg_len; | ||
403 | |||
404 | /* reconstruct message header as if it was | ||
405 | * sent in single fragment */ | ||
406 | *(p++) = msg_hdr->type; | ||
407 | l2n3(msg_len,p); | ||
408 | s2n (msg_hdr->seq,p); | ||
409 | l2n3(0,p); | ||
410 | l2n3(msg_len,p); | ||
411 | if (s->client_version != DTLS1_BAD_VER) | ||
412 | p -= DTLS1_HM_HEADER_LENGTH, | ||
413 | msg_len += DTLS1_HM_HEADER_LENGTH; | ||
414 | |||
415 | ssl3_finish_mac(s, p, msg_len); | ||
416 | if (s->msg_callback) | ||
417 | s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE, | ||
418 | p, msg_len, | ||
419 | s, s->msg_callback_arg); | ||
420 | |||
421 | memset(msg_hdr, 0x00, sizeof(struct hm_header_st)); | ||
422 | |||
423 | s->d1->handshake_read_seq++; | ||
424 | /* we just read a handshake message from the other side: | ||
425 | * this means that we don't need to retransmit of the | ||
426 | * buffered messages. | ||
427 | * XDTLS: may be able clear out this | ||
428 | * buffer a little sooner (i.e if an out-of-order | ||
429 | * handshake message/record is received at the record | ||
430 | * layer. | ||
431 | * XDTLS: exception is that the server needs to | ||
432 | * know that change cipher spec and finished messages | ||
433 | * have been received by the client before clearing this | ||
434 | * buffer. this can simply be done by waiting for the | ||
435 | * first data segment, but is there a better way? */ | ||
436 | dtls1_clear_record_buffer(s); | ||
437 | |||
438 | s->init_msg = s->init_buf->data + DTLS1_HM_HEADER_LENGTH; | ||
439 | return s->init_num; | ||
440 | } | ||
441 | else | ||
442 | msg_hdr->frag_off = i; | ||
443 | } while(1) ; | ||
444 | |||
445 | f_err: | ||
446 | ssl3_send_alert(s,SSL3_AL_FATAL,al); | ||
447 | *ok = 0; | ||
448 | return -1; | ||
449 | } | ||
450 | |||
451 | |||
452 | static int dtls1_preprocess_fragment(SSL *s,struct hm_header_st *msg_hdr,int max) | ||
453 | { | ||
454 | size_t frag_off,frag_len,msg_len; | ||
455 | |||
456 | msg_len = msg_hdr->msg_len; | ||
457 | frag_off = msg_hdr->frag_off; | ||
458 | frag_len = msg_hdr->frag_len; | ||
459 | |||
460 | /* sanity checking */ | ||
461 | if ( (frag_off+frag_len) > msg_len) | ||
462 | { | ||
463 | SSLerr(SSL_F_DTLS1_PREPROCESS_FRAGMENT,SSL_R_EXCESSIVE_MESSAGE_SIZE); | ||
464 | return SSL_AD_ILLEGAL_PARAMETER; | ||
465 | } | ||
466 | |||
467 | if ( (frag_off+frag_len) > (unsigned long)max) | ||
468 | { | ||
469 | SSLerr(SSL_F_DTLS1_PREPROCESS_FRAGMENT,SSL_R_EXCESSIVE_MESSAGE_SIZE); | ||
470 | return SSL_AD_ILLEGAL_PARAMETER; | ||
471 | } | ||
472 | |||
473 | if ( s->d1->r_msg_hdr.frag_off == 0) /* first fragment */ | ||
474 | { | ||
475 | /* msg_len is limited to 2^24, but is effectively checked | ||
476 | * against max above */ | ||
477 | if (!BUF_MEM_grow_clean(s->init_buf,(int)msg_len+DTLS1_HM_HEADER_LENGTH)) | ||
478 | { | ||
479 | SSLerr(SSL_F_DTLS1_PREPROCESS_FRAGMENT,ERR_R_BUF_LIB); | ||
480 | return SSL_AD_INTERNAL_ERROR; | ||
481 | } | ||
482 | |||
483 | s->s3->tmp.message_size = msg_len; | ||
484 | s->d1->r_msg_hdr.msg_len = msg_len; | ||
485 | s->s3->tmp.message_type = msg_hdr->type; | ||
486 | s->d1->r_msg_hdr.type = msg_hdr->type; | ||
487 | s->d1->r_msg_hdr.seq = msg_hdr->seq; | ||
488 | } | ||
489 | else if (msg_len != s->d1->r_msg_hdr.msg_len) | ||
490 | { | ||
491 | /* They must be playing with us! BTW, failure to enforce | ||
492 | * upper limit would open possibility for buffer overrun. */ | ||
493 | SSLerr(SSL_F_DTLS1_PREPROCESS_FRAGMENT,SSL_R_EXCESSIVE_MESSAGE_SIZE); | ||
494 | return SSL_AD_ILLEGAL_PARAMETER; | ||
495 | } | ||
496 | |||
497 | return 0; /* no error */ | ||
498 | } | ||
499 | |||
500 | |||
501 | static int | ||
502 | dtls1_retrieve_buffered_fragment(SSL *s, long max, int *ok) | ||
503 | { | ||
504 | /* (0) check whether the desired fragment is available | ||
505 | * if so: | ||
506 | * (1) copy over the fragment to s->init_buf->data[] | ||
507 | * (2) update s->init_num | ||
508 | */ | ||
509 | pitem *item; | ||
510 | hm_fragment *frag; | ||
511 | int al; | ||
512 | |||
513 | *ok = 0; | ||
514 | item = pqueue_peek(s->d1->buffered_messages); | ||
515 | if ( item == NULL) | ||
516 | return 0; | ||
517 | |||
518 | frag = (hm_fragment *)item->data; | ||
519 | |||
520 | if ( s->d1->handshake_read_seq == frag->msg_header.seq) | ||
521 | { | ||
522 | pqueue_pop(s->d1->buffered_messages); | ||
523 | |||
524 | al=dtls1_preprocess_fragment(s,&frag->msg_header,max); | ||
525 | |||
526 | if (al==0) /* no alert */ | ||
527 | { | ||
528 | unsigned char *p = (unsigned char *)s->init_buf->data+DTLS1_HM_HEADER_LENGTH; | ||
529 | memcpy(&p[frag->msg_header.frag_off], | ||
530 | frag->fragment,frag->msg_header.frag_len); | ||
531 | } | ||
532 | |||
533 | dtls1_hm_fragment_free(frag); | ||
534 | pitem_free(item); | ||
535 | |||
536 | if (al==0) | ||
537 | { | ||
538 | *ok = 1; | ||
539 | return frag->msg_header.frag_len; | ||
540 | } | ||
541 | |||
542 | ssl3_send_alert(s,SSL3_AL_FATAL,al); | ||
543 | s->init_num = 0; | ||
544 | *ok = 0; | ||
545 | return -1; | ||
546 | } | ||
547 | else | ||
548 | return 0; | ||
549 | } | ||
550 | |||
551 | |||
552 | static int | ||
553 | dtls1_process_out_of_seq_message(SSL *s, struct hm_header_st* msg_hdr, int *ok) | ||
554 | { | ||
555 | int i=-1; | ||
556 | hm_fragment *frag = NULL; | ||
557 | pitem *item = NULL; | ||
558 | PQ_64BIT seq64; | ||
559 | unsigned long frag_len = msg_hdr->frag_len; | ||
560 | |||
561 | if ((msg_hdr->frag_off+frag_len) > msg_hdr->msg_len) | ||
562 | goto err; | ||
563 | |||
564 | if (msg_hdr->seq <= s->d1->handshake_read_seq) | ||
565 | { | ||
566 | unsigned char devnull [256]; | ||
567 | |||
568 | while (frag_len) | ||
569 | { | ||
570 | i = s->method->ssl_read_bytes(s,SSL3_RT_HANDSHAKE, | ||
571 | devnull, | ||
572 | frag_len>sizeof(devnull)?sizeof(devnull):frag_len,0); | ||
573 | if (i<=0) goto err; | ||
574 | frag_len -= i; | ||
575 | } | ||
576 | } | ||
577 | |||
578 | frag = dtls1_hm_fragment_new(frag_len); | ||
579 | if ( frag == NULL) | ||
580 | goto err; | ||
581 | |||
582 | memcpy(&(frag->msg_header), msg_hdr, sizeof(*msg_hdr)); | ||
583 | |||
584 | if (frag_len) | ||
585 | { | ||
586 | /* read the body of the fragment (header has already been read */ | ||
587 | i = s->method->ssl_read_bytes(s,SSL3_RT_HANDSHAKE, | ||
588 | frag->fragment,frag_len,0); | ||
589 | if (i<=0 || (unsigned long)i!=frag_len) | ||
590 | goto err; | ||
591 | } | ||
592 | |||
593 | pq_64bit_init(&seq64); | ||
594 | pq_64bit_assign_word(&seq64, msg_hdr->seq); | ||
595 | |||
596 | item = pitem_new(seq64, frag); | ||
597 | pq_64bit_free(&seq64); | ||
598 | if ( item == NULL) | ||
599 | goto err; | ||
600 | |||
601 | pqueue_insert(s->d1->buffered_messages, item); | ||
602 | return DTLS1_HM_FRAGMENT_RETRY; | ||
603 | |||
604 | err: | ||
605 | if ( frag != NULL) dtls1_hm_fragment_free(frag); | ||
606 | if ( item != NULL) OPENSSL_free(item); | ||
607 | *ok = 0; | ||
608 | return i; | ||
609 | } | ||
610 | |||
611 | |||
612 | static long | ||
613 | dtls1_get_message_fragment(SSL *s, int st1, int stn, long max, int *ok) | ||
614 | { | ||
615 | unsigned char wire[DTLS1_HM_HEADER_LENGTH]; | ||
616 | unsigned long l, frag_off, frag_len; | ||
617 | int i,al; | ||
618 | struct hm_header_st msg_hdr; | ||
619 | |||
620 | /* see if we have the required fragment already */ | ||
621 | if ((frag_len = dtls1_retrieve_buffered_fragment(s,max,ok)) || *ok) | ||
622 | { | ||
623 | if (*ok) s->init_num += frag_len; | ||
624 | return frag_len; | ||
625 | } | ||
626 | |||
627 | /* read handshake message header */ | ||
628 | i=s->method->ssl_read_bytes(s,SSL3_RT_HANDSHAKE,wire, | ||
629 | DTLS1_HM_HEADER_LENGTH, 0); | ||
630 | if (i <= 0) /* nbio, or an error */ | ||
631 | { | ||
632 | s->rwstate=SSL_READING; | ||
633 | *ok = 0; | ||
634 | return i; | ||
635 | } | ||
636 | OPENSSL_assert(i == DTLS1_HM_HEADER_LENGTH); | ||
637 | |||
638 | /* parse the message fragment header */ | ||
639 | dtls1_get_message_header(wire, &msg_hdr); | ||
640 | |||
641 | /* | ||
642 | * if this is a future (or stale) message it gets buffered | ||
643 | * (or dropped)--no further processing at this time | ||
644 | */ | ||
645 | if ( msg_hdr.seq != s->d1->handshake_read_seq) | ||
646 | return dtls1_process_out_of_seq_message(s, &msg_hdr, ok); | ||
647 | |||
648 | l = msg_hdr.msg_len; | ||
649 | frag_off = msg_hdr.frag_off; | ||
650 | frag_len = msg_hdr.frag_len; | ||
651 | |||
652 | if (!s->server && s->d1->r_msg_hdr.frag_off == 0 && | ||
653 | wire[0] == SSL3_MT_HELLO_REQUEST) | ||
654 | { | ||
655 | /* The server may always send 'Hello Request' messages -- | ||
656 | * we are doing a handshake anyway now, so ignore them | ||
657 | * if their format is correct. Does not count for | ||
658 | * 'Finished' MAC. */ | ||
659 | if (wire[1] == 0 && wire[2] == 0 && wire[3] == 0) | ||
660 | { | ||
661 | if (s->msg_callback) | ||
662 | s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE, | ||
663 | wire, DTLS1_HM_HEADER_LENGTH, s, | ||
664 | s->msg_callback_arg); | ||
665 | |||
666 | s->init_num = 0; | ||
667 | return dtls1_get_message_fragment(s, st1, stn, | ||
668 | max, ok); | ||
669 | } | ||
670 | else /* Incorrectly formated Hello request */ | ||
671 | { | ||
672 | al=SSL_AD_UNEXPECTED_MESSAGE; | ||
673 | SSLerr(SSL_F_DTLS1_GET_MESSAGE_FRAGMENT,SSL_R_UNEXPECTED_MESSAGE); | ||
674 | goto f_err; | ||
675 | } | ||
676 | } | ||
677 | |||
678 | if ((al=dtls1_preprocess_fragment(s,&msg_hdr,max))) | ||
679 | goto f_err; | ||
680 | |||
681 | /* XDTLS: ressurect this when restart is in place */ | ||
682 | s->state=stn; | ||
683 | |||
684 | if ( frag_len > 0) | ||
685 | { | ||
686 | unsigned char *p=(unsigned char *)s->init_buf->data+DTLS1_HM_HEADER_LENGTH; | ||
687 | |||
688 | i=s->method->ssl_read_bytes(s,SSL3_RT_HANDSHAKE, | ||
689 | &p[frag_off],frag_len,0); | ||
690 | /* XDTLS: fix this--message fragments cannot span multiple packets */ | ||
691 | if (i <= 0) | ||
692 | { | ||
693 | s->rwstate=SSL_READING; | ||
694 | *ok = 0; | ||
695 | return i; | ||
696 | } | ||
697 | } | ||
698 | else | ||
699 | i = 0; | ||
700 | |||
701 | /* XDTLS: an incorrectly formatted fragment should cause the | ||
702 | * handshake to fail */ | ||
703 | OPENSSL_assert(i == (int)frag_len); | ||
704 | |||
705 | *ok = 1; | ||
706 | |||
707 | /* Note that s->init_num is *not* used as current offset in | ||
708 | * s->init_buf->data, but as a counter summing up fragments' | ||
709 | * lengths: as soon as they sum up to handshake packet | ||
710 | * length, we assume we have got all the fragments. */ | ||
711 | s->init_num += frag_len; | ||
712 | return frag_len; | ||
713 | |||
714 | f_err: | ||
715 | ssl3_send_alert(s,SSL3_AL_FATAL,al); | ||
716 | s->init_num = 0; | ||
717 | |||
718 | *ok=0; | ||
719 | return(-1); | ||
720 | } | ||
721 | |||
722 | int dtls1_send_finished(SSL *s, int a, int b, const char *sender, int slen) | ||
723 | { | ||
724 | unsigned char *p,*d; | ||
725 | int i; | ||
726 | unsigned long l; | ||
727 | |||
728 | if (s->state == a) | ||
729 | { | ||
730 | d=(unsigned char *)s->init_buf->data; | ||
731 | p= &(d[DTLS1_HM_HEADER_LENGTH]); | ||
732 | |||
733 | i=s->method->ssl3_enc->final_finish_mac(s, | ||
734 | &(s->s3->finish_dgst1), | ||
735 | &(s->s3->finish_dgst2), | ||
736 | sender,slen,s->s3->tmp.finish_md); | ||
737 | s->s3->tmp.finish_md_len = i; | ||
738 | memcpy(p, s->s3->tmp.finish_md, i); | ||
739 | p+=i; | ||
740 | l=i; | ||
741 | |||
742 | #ifdef OPENSSL_SYS_WIN16 | ||
743 | /* MSVC 1.5 does not clear the top bytes of the word unless | ||
744 | * I do this. | ||
745 | */ | ||
746 | l&=0xffff; | ||
747 | #endif | ||
748 | |||
749 | d = dtls1_set_message_header(s, d, SSL3_MT_FINISHED, l, 0, l); | ||
750 | s->init_num=(int)l+DTLS1_HM_HEADER_LENGTH; | ||
751 | s->init_off=0; | ||
752 | |||
753 | /* buffer the message to handle re-xmits */ | ||
754 | dtls1_buffer_message(s, 0); | ||
755 | |||
756 | s->state=b; | ||
757 | } | ||
758 | |||
759 | /* SSL3_ST_SEND_xxxxxx_HELLO_B */ | ||
760 | return(dtls1_do_write(s,SSL3_RT_HANDSHAKE)); | ||
761 | } | ||
762 | |||
763 | /* for these 2 messages, we need to | ||
764 | * ssl->enc_read_ctx re-init | ||
765 | * ssl->s3->read_sequence zero | ||
766 | * ssl->s3->read_mac_secret re-init | ||
767 | * ssl->session->read_sym_enc assign | ||
768 | * ssl->session->read_compression assign | ||
769 | * ssl->session->read_hash assign | ||
770 | */ | ||
771 | int dtls1_send_change_cipher_spec(SSL *s, int a, int b) | ||
772 | { | ||
773 | unsigned char *p; | ||
774 | |||
775 | if (s->state == a) | ||
776 | { | ||
777 | p=(unsigned char *)s->init_buf->data; | ||
778 | *p++=SSL3_MT_CCS; | ||
779 | s->d1->handshake_write_seq = s->d1->next_handshake_write_seq; | ||
780 | s->init_num=DTLS1_CCS_HEADER_LENGTH; | ||
781 | |||
782 | if (s->client_version == DTLS1_BAD_VER) | ||
783 | { | ||
784 | s->d1->next_handshake_write_seq++; | ||
785 | s2n(s->d1->handshake_write_seq,p); | ||
786 | s->init_num+=2; | ||
787 | } | ||
788 | |||
789 | s->init_off=0; | ||
790 | |||
791 | dtls1_set_message_header_int(s, SSL3_MT_CCS, 0, | ||
792 | s->d1->handshake_write_seq, 0, 0); | ||
793 | |||
794 | /* buffer the message to handle re-xmits */ | ||
795 | dtls1_buffer_message(s, 1); | ||
796 | |||
797 | s->state=b; | ||
798 | } | ||
799 | |||
800 | /* SSL3_ST_CW_CHANGE_B */ | ||
801 | return(dtls1_do_write(s,SSL3_RT_CHANGE_CIPHER_SPEC)); | ||
802 | } | ||
803 | |||
804 | unsigned long dtls1_output_cert_chain(SSL *s, X509 *x) | ||
805 | { | ||
806 | unsigned char *p; | ||
807 | int n,i; | ||
808 | unsigned long l= 3 + DTLS1_HM_HEADER_LENGTH; | ||
809 | BUF_MEM *buf; | ||
810 | X509_STORE_CTX xs_ctx; | ||
811 | X509_OBJECT obj; | ||
812 | |||
813 | /* TLSv1 sends a chain with nothing in it, instead of an alert */ | ||
814 | buf=s->init_buf; | ||
815 | if (!BUF_MEM_grow_clean(buf,10)) | ||
816 | { | ||
817 | SSLerr(SSL_F_DTLS1_OUTPUT_CERT_CHAIN,ERR_R_BUF_LIB); | ||
818 | return(0); | ||
819 | } | ||
820 | if (x != NULL) | ||
821 | { | ||
822 | if(!X509_STORE_CTX_init(&xs_ctx,s->ctx->cert_store,NULL,NULL)) | ||
823 | { | ||
824 | SSLerr(SSL_F_DTLS1_OUTPUT_CERT_CHAIN,ERR_R_X509_LIB); | ||
825 | return(0); | ||
826 | } | ||
827 | |||
828 | for (;;) | ||
829 | { | ||
830 | n=i2d_X509(x,NULL); | ||
831 | if (!BUF_MEM_grow_clean(buf,(int)(n+l+3))) | ||
832 | { | ||
833 | SSLerr(SSL_F_DTLS1_OUTPUT_CERT_CHAIN,ERR_R_BUF_LIB); | ||
834 | return(0); | ||
835 | } | ||
836 | p=(unsigned char *)&(buf->data[l]); | ||
837 | l2n3(n,p); | ||
838 | i2d_X509(x,&p); | ||
839 | l+=n+3; | ||
840 | if (X509_NAME_cmp(X509_get_subject_name(x), | ||
841 | X509_get_issuer_name(x)) == 0) break; | ||
842 | |||
843 | i=X509_STORE_get_by_subject(&xs_ctx,X509_LU_X509, | ||
844 | X509_get_issuer_name(x),&obj); | ||
845 | if (i <= 0) break; | ||
846 | x=obj.data.x509; | ||
847 | /* Count is one too high since the X509_STORE_get uped the | ||
848 | * ref count */ | ||
849 | X509_free(x); | ||
850 | } | ||
851 | |||
852 | X509_STORE_CTX_cleanup(&xs_ctx); | ||
853 | } | ||
854 | |||
855 | /* Thawte special :-) */ | ||
856 | if (s->ctx->extra_certs != NULL) | ||
857 | for (i=0; i<sk_X509_num(s->ctx->extra_certs); i++) | ||
858 | { | ||
859 | x=sk_X509_value(s->ctx->extra_certs,i); | ||
860 | n=i2d_X509(x,NULL); | ||
861 | if (!BUF_MEM_grow_clean(buf,(int)(n+l+3))) | ||
862 | { | ||
863 | SSLerr(SSL_F_DTLS1_OUTPUT_CERT_CHAIN,ERR_R_BUF_LIB); | ||
864 | return(0); | ||
865 | } | ||
866 | p=(unsigned char *)&(buf->data[l]); | ||
867 | l2n3(n,p); | ||
868 | i2d_X509(x,&p); | ||
869 | l+=n+3; | ||
870 | } | ||
871 | |||
872 | l-= (3 + DTLS1_HM_HEADER_LENGTH); | ||
873 | |||
874 | p=(unsigned char *)&(buf->data[DTLS1_HM_HEADER_LENGTH]); | ||
875 | l2n3(l,p); | ||
876 | l+=3; | ||
877 | p=(unsigned char *)&(buf->data[0]); | ||
878 | p = dtls1_set_message_header(s, p, SSL3_MT_CERTIFICATE, l, 0, l); | ||
879 | |||
880 | l+=DTLS1_HM_HEADER_LENGTH; | ||
881 | return(l); | ||
882 | } | ||
883 | |||
884 | int dtls1_read_failed(SSL *s, int code) | ||
885 | { | ||
886 | DTLS1_STATE *state; | ||
887 | BIO *bio; | ||
888 | int send_alert = 0; | ||
889 | |||
890 | if ( code > 0) | ||
891 | { | ||
892 | fprintf( stderr, "invalid state reached %s:%d", __FILE__, __LINE__); | ||
893 | return 1; | ||
894 | } | ||
895 | |||
896 | bio = SSL_get_rbio(s); | ||
897 | if ( ! BIO_dgram_recv_timedout(bio)) | ||
898 | { | ||
899 | /* not a timeout, none of our business, | ||
900 | let higher layers handle this. in fact it's probably an error */ | ||
901 | return code; | ||
902 | } | ||
903 | |||
904 | if ( ! SSL_in_init(s)) /* done, no need to send a retransmit */ | ||
905 | { | ||
906 | BIO_set_flags(SSL_get_rbio(s), BIO_FLAGS_READ); | ||
907 | return code; | ||
908 | } | ||
909 | |||
910 | state = s->d1; | ||
911 | state->timeout.num_alerts++; | ||
912 | if ( state->timeout.num_alerts > DTLS1_TMO_ALERT_COUNT) | ||
913 | { | ||
914 | /* fail the connection, enough alerts have been sent */ | ||
915 | SSLerr(SSL_F_DTLS1_READ_FAILED,SSL_R_READ_TIMEOUT_EXPIRED); | ||
916 | return 0; | ||
917 | } | ||
918 | |||
919 | state->timeout.read_timeouts++; | ||
920 | if ( state->timeout.read_timeouts > DTLS1_TMO_READ_COUNT) | ||
921 | { | ||
922 | send_alert = 1; | ||
923 | state->timeout.read_timeouts = 1; | ||
924 | } | ||
925 | |||
926 | |||
927 | #if 0 /* for now, each alert contains only one record number */ | ||
928 | item = pqueue_peek(state->rcvd_records); | ||
929 | if ( item ) | ||
930 | { | ||
931 | /* send an alert immediately for all the missing records */ | ||
932 | } | ||
933 | else | ||
934 | #endif | ||
935 | |||
936 | #if 0 /* no more alert sending, just retransmit the last set of messages */ | ||
937 | if ( send_alert) | ||
938 | ssl3_send_alert(s,SSL3_AL_WARNING, | ||
939 | DTLS1_AD_MISSING_HANDSHAKE_MESSAGE); | ||
940 | #endif | ||
941 | |||
942 | return dtls1_retransmit_buffered_messages(s) ; | ||
943 | } | ||
944 | |||
945 | |||
946 | static int | ||
947 | dtls1_retransmit_buffered_messages(SSL *s) | ||
948 | { | ||
949 | pqueue sent = s->d1->sent_messages; | ||
950 | piterator iter; | ||
951 | pitem *item; | ||
952 | hm_fragment *frag; | ||
953 | int found = 0; | ||
954 | |||
955 | iter = pqueue_iterator(sent); | ||
956 | |||
957 | for ( item = pqueue_next(&iter); item != NULL; item = pqueue_next(&iter)) | ||
958 | { | ||
959 | frag = (hm_fragment *)item->data; | ||
960 | if ( dtls1_retransmit_message(s, frag->msg_header.seq, 0, &found) <= 0 && | ||
961 | found) | ||
962 | { | ||
963 | fprintf(stderr, "dtls1_retransmit_message() failed\n"); | ||
964 | return -1; | ||
965 | } | ||
966 | } | ||
967 | |||
968 | return 1; | ||
969 | } | ||
970 | |||
971 | int | ||
972 | dtls1_buffer_message(SSL *s, int is_ccs) | ||
973 | { | ||
974 | pitem *item; | ||
975 | hm_fragment *frag; | ||
976 | PQ_64BIT seq64; | ||
977 | unsigned int epoch = s->d1->w_epoch; | ||
978 | |||
979 | /* this function is called immediately after a message has | ||
980 | * been serialized */ | ||
981 | OPENSSL_assert(s->init_off == 0); | ||
982 | |||
983 | frag = dtls1_hm_fragment_new(s->init_num); | ||
984 | |||
985 | memcpy(frag->fragment, s->init_buf->data, s->init_num); | ||
986 | |||
987 | if ( is_ccs) | ||
988 | { | ||
989 | OPENSSL_assert(s->d1->w_msg_hdr.msg_len + | ||
990 | DTLS1_CCS_HEADER_LENGTH <= (unsigned int)s->init_num); | ||
991 | epoch++; | ||
992 | } | ||
993 | else | ||
994 | { | ||
995 | OPENSSL_assert(s->d1->w_msg_hdr.msg_len + | ||
996 | DTLS1_HM_HEADER_LENGTH == (unsigned int)s->init_num); | ||
997 | } | ||
998 | |||
999 | frag->msg_header.msg_len = s->d1->w_msg_hdr.msg_len; | ||
1000 | frag->msg_header.seq = s->d1->w_msg_hdr.seq; | ||
1001 | frag->msg_header.type = s->d1->w_msg_hdr.type; | ||
1002 | frag->msg_header.frag_off = 0; | ||
1003 | frag->msg_header.frag_len = s->d1->w_msg_hdr.msg_len; | ||
1004 | frag->msg_header.is_ccs = is_ccs; | ||
1005 | |||
1006 | pq_64bit_init(&seq64); | ||
1007 | pq_64bit_assign_word(&seq64, epoch<<16 | frag->msg_header.seq); | ||
1008 | |||
1009 | item = pitem_new(seq64, frag); | ||
1010 | pq_64bit_free(&seq64); | ||
1011 | if ( item == NULL) | ||
1012 | { | ||
1013 | dtls1_hm_fragment_free(frag); | ||
1014 | return 0; | ||
1015 | } | ||
1016 | |||
1017 | #if 0 | ||
1018 | fprintf( stderr, "buffered messge: \ttype = %xx\n", msg_buf->type); | ||
1019 | fprintf( stderr, "\t\t\t\t\tlen = %d\n", msg_buf->len); | ||
1020 | fprintf( stderr, "\t\t\t\t\tseq_num = %d\n", msg_buf->seq_num); | ||
1021 | #endif | ||
1022 | |||
1023 | pqueue_insert(s->d1->sent_messages, item); | ||
1024 | return 1; | ||
1025 | } | ||
1026 | |||
1027 | int | ||
1028 | dtls1_retransmit_message(SSL *s, unsigned short seq, unsigned long frag_off, | ||
1029 | int *found) | ||
1030 | { | ||
1031 | int ret; | ||
1032 | /* XDTLS: for now assuming that read/writes are blocking */ | ||
1033 | pitem *item; | ||
1034 | hm_fragment *frag ; | ||
1035 | unsigned long header_length; | ||
1036 | PQ_64BIT seq64; | ||
1037 | |||
1038 | /* | ||
1039 | OPENSSL_assert(s->init_num == 0); | ||
1040 | OPENSSL_assert(s->init_off == 0); | ||
1041 | */ | ||
1042 | |||
1043 | /* XDTLS: the requested message ought to be found, otherwise error */ | ||
1044 | pq_64bit_init(&seq64); | ||
1045 | pq_64bit_assign_word(&seq64, seq); | ||
1046 | |||
1047 | item = pqueue_find(s->d1->sent_messages, seq64); | ||
1048 | pq_64bit_free(&seq64); | ||
1049 | if ( item == NULL) | ||
1050 | { | ||
1051 | fprintf(stderr, "retransmit: message %d non-existant\n", seq); | ||
1052 | *found = 0; | ||
1053 | return 0; | ||
1054 | } | ||
1055 | |||
1056 | *found = 1; | ||
1057 | frag = (hm_fragment *)item->data; | ||
1058 | |||
1059 | if ( frag->msg_header.is_ccs) | ||
1060 | header_length = DTLS1_CCS_HEADER_LENGTH; | ||
1061 | else | ||
1062 | header_length = DTLS1_HM_HEADER_LENGTH; | ||
1063 | |||
1064 | memcpy(s->init_buf->data, frag->fragment, | ||
1065 | frag->msg_header.msg_len + header_length); | ||
1066 | s->init_num = frag->msg_header.msg_len + header_length; | ||
1067 | |||
1068 | dtls1_set_message_header_int(s, frag->msg_header.type, | ||
1069 | frag->msg_header.msg_len, frag->msg_header.seq, 0, | ||
1070 | frag->msg_header.frag_len); | ||
1071 | |||
1072 | s->d1->retransmitting = 1; | ||
1073 | ret = dtls1_do_write(s, frag->msg_header.is_ccs ? | ||
1074 | SSL3_RT_CHANGE_CIPHER_SPEC : SSL3_RT_HANDSHAKE); | ||
1075 | s->d1->retransmitting = 0; | ||
1076 | |||
1077 | (void)BIO_flush(SSL_get_wbio(s)); | ||
1078 | return ret; | ||
1079 | } | ||
1080 | |||
1081 | /* call this function when the buffered messages are no longer needed */ | ||
1082 | void | ||
1083 | dtls1_clear_record_buffer(SSL *s) | ||
1084 | { | ||
1085 | pitem *item; | ||
1086 | |||
1087 | for(item = pqueue_pop(s->d1->sent_messages); | ||
1088 | item != NULL; item = pqueue_pop(s->d1->sent_messages)) | ||
1089 | { | ||
1090 | dtls1_hm_fragment_free((hm_fragment *)item->data); | ||
1091 | pitem_free(item); | ||
1092 | } | ||
1093 | } | ||
1094 | |||
1095 | |||
1096 | unsigned char * | ||
1097 | dtls1_set_message_header(SSL *s, unsigned char *p, unsigned char mt, | ||
1098 | unsigned long len, unsigned long frag_off, unsigned long frag_len) | ||
1099 | { | ||
1100 | if ( frag_off == 0) | ||
1101 | { | ||
1102 | s->d1->handshake_write_seq = s->d1->next_handshake_write_seq; | ||
1103 | s->d1->next_handshake_write_seq++; | ||
1104 | } | ||
1105 | |||
1106 | dtls1_set_message_header_int(s, mt, len, s->d1->handshake_write_seq, | ||
1107 | frag_off, frag_len); | ||
1108 | |||
1109 | return p += DTLS1_HM_HEADER_LENGTH; | ||
1110 | } | ||
1111 | |||
1112 | |||
1113 | /* don't actually do the writing, wait till the MTU has been retrieved */ | ||
1114 | static void | ||
1115 | dtls1_set_message_header_int(SSL *s, unsigned char mt, | ||
1116 | unsigned long len, unsigned short seq_num, unsigned long frag_off, | ||
1117 | unsigned long frag_len) | ||
1118 | { | ||
1119 | struct hm_header_st *msg_hdr = &s->d1->w_msg_hdr; | ||
1120 | |||
1121 | msg_hdr->type = mt; | ||
1122 | msg_hdr->msg_len = len; | ||
1123 | msg_hdr->seq = seq_num; | ||
1124 | msg_hdr->frag_off = frag_off; | ||
1125 | msg_hdr->frag_len = frag_len; | ||
1126 | } | ||
1127 | |||
1128 | static void | ||
1129 | dtls1_fix_message_header(SSL *s, unsigned long frag_off, | ||
1130 | unsigned long frag_len) | ||
1131 | { | ||
1132 | struct hm_header_st *msg_hdr = &s->d1->w_msg_hdr; | ||
1133 | |||
1134 | msg_hdr->frag_off = frag_off; | ||
1135 | msg_hdr->frag_len = frag_len; | ||
1136 | } | ||
1137 | |||
1138 | static unsigned char * | ||
1139 | dtls1_write_message_header(SSL *s, unsigned char *p) | ||
1140 | { | ||
1141 | struct hm_header_st *msg_hdr = &s->d1->w_msg_hdr; | ||
1142 | |||
1143 | *p++ = msg_hdr->type; | ||
1144 | l2n3(msg_hdr->msg_len, p); | ||
1145 | |||
1146 | s2n(msg_hdr->seq, p); | ||
1147 | l2n3(msg_hdr->frag_off, p); | ||
1148 | l2n3(msg_hdr->frag_len, p); | ||
1149 | |||
1150 | return p; | ||
1151 | } | ||
1152 | |||
1153 | static unsigned int | ||
1154 | dtls1_min_mtu(void) | ||
1155 | { | ||
1156 | return (g_probable_mtu[(sizeof(g_probable_mtu) / | ||
1157 | sizeof(g_probable_mtu[0])) - 1]); | ||
1158 | } | ||
1159 | |||
1160 | static unsigned int | ||
1161 | dtls1_guess_mtu(unsigned int curr_mtu) | ||
1162 | { | ||
1163 | size_t i; | ||
1164 | |||
1165 | if ( curr_mtu == 0 ) | ||
1166 | return g_probable_mtu[0] ; | ||
1167 | |||
1168 | for ( i = 0; i < sizeof(g_probable_mtu)/sizeof(g_probable_mtu[0]); i++) | ||
1169 | if ( curr_mtu > g_probable_mtu[i]) | ||
1170 | return g_probable_mtu[i]; | ||
1171 | |||
1172 | return curr_mtu; | ||
1173 | } | ||
1174 | |||
1175 | void | ||
1176 | dtls1_get_message_header(unsigned char *data, struct hm_header_st *msg_hdr) | ||
1177 | { | ||
1178 | memset(msg_hdr, 0x00, sizeof(struct hm_header_st)); | ||
1179 | msg_hdr->type = *(data++); | ||
1180 | n2l3(data, msg_hdr->msg_len); | ||
1181 | |||
1182 | n2s(data, msg_hdr->seq); | ||
1183 | n2l3(data, msg_hdr->frag_off); | ||
1184 | n2l3(data, msg_hdr->frag_len); | ||
1185 | } | ||
1186 | |||
1187 | void | ||
1188 | dtls1_get_ccs_header(unsigned char *data, struct ccs_header_st *ccs_hdr) | ||
1189 | { | ||
1190 | memset(ccs_hdr, 0x00, sizeof(struct ccs_header_st)); | ||
1191 | |||
1192 | ccs_hdr->type = *(data++); | ||
1193 | } | ||
diff --git a/src/lib/libssl/d1_clnt.c b/src/lib/libssl/d1_clnt.c new file mode 100644 index 0000000000..5e59dc845a --- /dev/null +++ b/src/lib/libssl/d1_clnt.c | |||
@@ -0,0 +1,1156 @@ | |||
1 | /* ssl/d1_clnt.c */ | ||
2 | /* | ||
3 | * DTLS implementation written by Nagendra Modadugu | ||
4 | * (nagendra@cs.stanford.edu) for the OpenSSL project 2005. | ||
5 | */ | ||
6 | /* ==================================================================== | ||
7 | * Copyright (c) 1999-2005 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 | * openssl-core@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 | * This product includes cryptographic software written by Eric Young | ||
55 | * (eay@cryptsoft.com). This product includes software written by Tim | ||
56 | * Hudson (tjh@cryptsoft.com). | ||
57 | * | ||
58 | */ | ||
59 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) | ||
60 | * All rights reserved. | ||
61 | * | ||
62 | * This package is an SSL implementation written | ||
63 | * by Eric Young (eay@cryptsoft.com). | ||
64 | * The implementation was written so as to conform with Netscapes SSL. | ||
65 | * | ||
66 | * This library is free for commercial and non-commercial use as long as | ||
67 | * the following conditions are aheared to. The following conditions | ||
68 | * apply to all code found in this distribution, be it the RC4, RSA, | ||
69 | * lhash, DES, etc., code; not just the SSL code. The SSL documentation | ||
70 | * included with this distribution is covered by the same copyright terms | ||
71 | * except that the holder is Tim Hudson (tjh@cryptsoft.com). | ||
72 | * | ||
73 | * Copyright remains Eric Young's, and as such any Copyright notices in | ||
74 | * the code are not to be removed. | ||
75 | * If this package is used in a product, Eric Young should be given attribution | ||
76 | * as the author of the parts of the library used. | ||
77 | * This can be in the form of a textual message at program startup or | ||
78 | * in documentation (online or textual) provided with the package. | ||
79 | * | ||
80 | * Redistribution and use in source and binary forms, with or without | ||
81 | * modification, are permitted provided that the following conditions | ||
82 | * are met: | ||
83 | * 1. Redistributions of source code must retain the copyright | ||
84 | * notice, this list of conditions and the following disclaimer. | ||
85 | * 2. Redistributions in binary form must reproduce the above copyright | ||
86 | * notice, this list of conditions and the following disclaimer in the | ||
87 | * documentation and/or other materials provided with the distribution. | ||
88 | * 3. All advertising materials mentioning features or use of this software | ||
89 | * must display the following acknowledgement: | ||
90 | * "This product includes cryptographic software written by | ||
91 | * Eric Young (eay@cryptsoft.com)" | ||
92 | * The word 'cryptographic' can be left out if the rouines from the library | ||
93 | * being used are not cryptographic related :-). | ||
94 | * 4. If you include any Windows specific code (or a derivative thereof) from | ||
95 | * the apps directory (application code) you must include an acknowledgement: | ||
96 | * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" | ||
97 | * | ||
98 | * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND | ||
99 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
100 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
101 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | ||
102 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
103 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
104 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
105 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
106 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
107 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
108 | * SUCH DAMAGE. | ||
109 | * | ||
110 | * The licence and distribution terms for any publically available version or | ||
111 | * derivative of this code cannot be changed. i.e. this code cannot simply be | ||
112 | * copied and put under another distribution licence | ||
113 | * [including the GNU Public Licence.] | ||
114 | */ | ||
115 | |||
116 | #include <stdio.h> | ||
117 | #include "ssl_locl.h" | ||
118 | #include "kssl_lcl.h" | ||
119 | #include <openssl/buffer.h> | ||
120 | #include <openssl/rand.h> | ||
121 | #include <openssl/objects.h> | ||
122 | #include <openssl/evp.h> | ||
123 | #include <openssl/md5.h> | ||
124 | #ifndef OPENSSL_NO_DH | ||
125 | #include <openssl/dh.h> | ||
126 | #endif | ||
127 | |||
128 | static SSL_METHOD *dtls1_get_client_method(int ver); | ||
129 | static int dtls1_get_hello_verify(SSL *s); | ||
130 | |||
131 | static SSL_METHOD *dtls1_get_client_method(int ver) | ||
132 | { | ||
133 | if (ver == DTLS1_VERSION) | ||
134 | return(DTLSv1_client_method()); | ||
135 | else | ||
136 | return(NULL); | ||
137 | } | ||
138 | |||
139 | IMPLEMENT_dtls1_meth_func(DTLSv1_client_method, | ||
140 | ssl_undefined_function, | ||
141 | dtls1_connect, | ||
142 | dtls1_get_client_method) | ||
143 | |||
144 | int dtls1_connect(SSL *s) | ||
145 | { | ||
146 | BUF_MEM *buf=NULL; | ||
147 | unsigned long Time=(unsigned long)time(NULL),l; | ||
148 | long num1; | ||
149 | void (*cb)(const SSL *ssl,int type,int val)=NULL; | ||
150 | int ret= -1; | ||
151 | int new_state,state,skip=0;; | ||
152 | |||
153 | RAND_add(&Time,sizeof(Time),0); | ||
154 | ERR_clear_error(); | ||
155 | clear_sys_error(); | ||
156 | |||
157 | if (s->info_callback != NULL) | ||
158 | cb=s->info_callback; | ||
159 | else if (s->ctx->info_callback != NULL) | ||
160 | cb=s->ctx->info_callback; | ||
161 | |||
162 | s->in_handshake++; | ||
163 | if (!SSL_in_init(s) || SSL_in_before(s)) SSL_clear(s); | ||
164 | |||
165 | for (;;) | ||
166 | { | ||
167 | state=s->state; | ||
168 | |||
169 | switch(s->state) | ||
170 | { | ||
171 | case SSL_ST_RENEGOTIATE: | ||
172 | s->new_session=1; | ||
173 | s->state=SSL_ST_CONNECT; | ||
174 | s->ctx->stats.sess_connect_renegotiate++; | ||
175 | /* break */ | ||
176 | case SSL_ST_BEFORE: | ||
177 | case SSL_ST_CONNECT: | ||
178 | case SSL_ST_BEFORE|SSL_ST_CONNECT: | ||
179 | case SSL_ST_OK|SSL_ST_CONNECT: | ||
180 | |||
181 | s->server=0; | ||
182 | if (cb != NULL) cb(s,SSL_CB_HANDSHAKE_START,1); | ||
183 | |||
184 | if ((s->version & 0xff00 ) != (DTLS1_VERSION & 0xff00)) | ||
185 | { | ||
186 | SSLerr(SSL_F_DTLS1_CONNECT, ERR_R_INTERNAL_ERROR); | ||
187 | ret = -1; | ||
188 | goto end; | ||
189 | } | ||
190 | |||
191 | /* s->version=SSL3_VERSION; */ | ||
192 | s->type=SSL_ST_CONNECT; | ||
193 | |||
194 | if (s->init_buf == NULL) | ||
195 | { | ||
196 | if ((buf=BUF_MEM_new()) == NULL) | ||
197 | { | ||
198 | ret= -1; | ||
199 | goto end; | ||
200 | } | ||
201 | if (!BUF_MEM_grow(buf,SSL3_RT_MAX_PLAIN_LENGTH)) | ||
202 | { | ||
203 | ret= -1; | ||
204 | goto end; | ||
205 | } | ||
206 | s->init_buf=buf; | ||
207 | buf=NULL; | ||
208 | } | ||
209 | |||
210 | if (!ssl3_setup_buffers(s)) { ret= -1; goto end; } | ||
211 | |||
212 | /* setup buffing BIO */ | ||
213 | if (!ssl_init_wbio_buffer(s,0)) { ret= -1; goto end; } | ||
214 | |||
215 | /* don't push the buffering BIO quite yet */ | ||
216 | |||
217 | s->state=SSL3_ST_CW_CLNT_HELLO_A; | ||
218 | s->ctx->stats.sess_connect++; | ||
219 | s->init_num=0; | ||
220 | /* mark client_random uninitialized */ | ||
221 | memset(s->s3->client_random,0,sizeof(s->s3->client_random)); | ||
222 | break; | ||
223 | |||
224 | case SSL3_ST_CW_CLNT_HELLO_A: | ||
225 | case SSL3_ST_CW_CLNT_HELLO_B: | ||
226 | |||
227 | s->shutdown=0; | ||
228 | |||
229 | /* every DTLS ClientHello resets Finished MAC */ | ||
230 | ssl3_init_finished_mac(s); | ||
231 | |||
232 | ret=dtls1_client_hello(s); | ||
233 | if (ret <= 0) goto end; | ||
234 | |||
235 | if ( s->d1->send_cookie) | ||
236 | { | ||
237 | s->state=SSL3_ST_CW_FLUSH; | ||
238 | s->s3->tmp.next_state=SSL3_ST_CR_SRVR_HELLO_A; | ||
239 | } | ||
240 | else | ||
241 | s->state=SSL3_ST_CR_SRVR_HELLO_A; | ||
242 | |||
243 | s->init_num=0; | ||
244 | |||
245 | /* turn on buffering for the next lot of output */ | ||
246 | if (s->bbio != s->wbio) | ||
247 | s->wbio=BIO_push(s->bbio,s->wbio); | ||
248 | |||
249 | break; | ||
250 | |||
251 | case SSL3_ST_CR_SRVR_HELLO_A: | ||
252 | case SSL3_ST_CR_SRVR_HELLO_B: | ||
253 | ret=ssl3_get_server_hello(s); | ||
254 | if (ret <= 0) goto end; | ||
255 | else | ||
256 | { | ||
257 | if (s->hit) | ||
258 | s->state=SSL3_ST_CR_FINISHED_A; | ||
259 | else | ||
260 | s->state=DTLS1_ST_CR_HELLO_VERIFY_REQUEST_A; | ||
261 | } | ||
262 | s->init_num=0; | ||
263 | break; | ||
264 | |||
265 | case DTLS1_ST_CR_HELLO_VERIFY_REQUEST_A: | ||
266 | case DTLS1_ST_CR_HELLO_VERIFY_REQUEST_B: | ||
267 | |||
268 | ret = dtls1_get_hello_verify(s); | ||
269 | if ( ret <= 0) | ||
270 | goto end; | ||
271 | if ( s->d1->send_cookie) /* start again, with a cookie */ | ||
272 | s->state=SSL3_ST_CW_CLNT_HELLO_A; | ||
273 | else | ||
274 | s->state = SSL3_ST_CR_CERT_A; | ||
275 | s->init_num = 0; | ||
276 | break; | ||
277 | |||
278 | case SSL3_ST_CR_CERT_A: | ||
279 | case SSL3_ST_CR_CERT_B: | ||
280 | /* Check if it is anon DH */ | ||
281 | if (!(s->s3->tmp.new_cipher->algorithms & SSL_aNULL)) | ||
282 | { | ||
283 | ret=ssl3_get_server_certificate(s); | ||
284 | if (ret <= 0) goto end; | ||
285 | } | ||
286 | else | ||
287 | skip=1; | ||
288 | s->state=SSL3_ST_CR_KEY_EXCH_A; | ||
289 | s->init_num=0; | ||
290 | break; | ||
291 | |||
292 | case SSL3_ST_CR_KEY_EXCH_A: | ||
293 | case SSL3_ST_CR_KEY_EXCH_B: | ||
294 | ret=ssl3_get_key_exchange(s); | ||
295 | if (ret <= 0) goto end; | ||
296 | s->state=SSL3_ST_CR_CERT_REQ_A; | ||
297 | s->init_num=0; | ||
298 | |||
299 | /* at this point we check that we have the | ||
300 | * required stuff from the server */ | ||
301 | if (!ssl3_check_cert_and_algorithm(s)) | ||
302 | { | ||
303 | ret= -1; | ||
304 | goto end; | ||
305 | } | ||
306 | break; | ||
307 | |||
308 | case SSL3_ST_CR_CERT_REQ_A: | ||
309 | case SSL3_ST_CR_CERT_REQ_B: | ||
310 | ret=ssl3_get_certificate_request(s); | ||
311 | if (ret <= 0) goto end; | ||
312 | s->state=SSL3_ST_CR_SRVR_DONE_A; | ||
313 | s->init_num=0; | ||
314 | break; | ||
315 | |||
316 | case SSL3_ST_CR_SRVR_DONE_A: | ||
317 | case SSL3_ST_CR_SRVR_DONE_B: | ||
318 | ret=ssl3_get_server_done(s); | ||
319 | if (ret <= 0) goto end; | ||
320 | if (s->s3->tmp.cert_req) | ||
321 | s->state=SSL3_ST_CW_CERT_A; | ||
322 | else | ||
323 | s->state=SSL3_ST_CW_KEY_EXCH_A; | ||
324 | s->init_num=0; | ||
325 | |||
326 | break; | ||
327 | |||
328 | case SSL3_ST_CW_CERT_A: | ||
329 | case SSL3_ST_CW_CERT_B: | ||
330 | case SSL3_ST_CW_CERT_C: | ||
331 | case SSL3_ST_CW_CERT_D: | ||
332 | ret=dtls1_send_client_certificate(s); | ||
333 | if (ret <= 0) goto end; | ||
334 | s->state=SSL3_ST_CW_KEY_EXCH_A; | ||
335 | s->init_num=0; | ||
336 | break; | ||
337 | |||
338 | case SSL3_ST_CW_KEY_EXCH_A: | ||
339 | case SSL3_ST_CW_KEY_EXCH_B: | ||
340 | ret=dtls1_send_client_key_exchange(s); | ||
341 | if (ret <= 0) goto end; | ||
342 | l=s->s3->tmp.new_cipher->algorithms; | ||
343 | /* EAY EAY EAY need to check for DH fix cert | ||
344 | * sent back */ | ||
345 | /* For TLS, cert_req is set to 2, so a cert chain | ||
346 | * of nothing is sent, but no verify packet is sent */ | ||
347 | if (s->s3->tmp.cert_req == 1) | ||
348 | { | ||
349 | s->state=SSL3_ST_CW_CERT_VRFY_A; | ||
350 | } | ||
351 | else | ||
352 | { | ||
353 | s->state=SSL3_ST_CW_CHANGE_A; | ||
354 | s->s3->change_cipher_spec=0; | ||
355 | } | ||
356 | |||
357 | s->init_num=0; | ||
358 | break; | ||
359 | |||
360 | case SSL3_ST_CW_CERT_VRFY_A: | ||
361 | case SSL3_ST_CW_CERT_VRFY_B: | ||
362 | ret=dtls1_send_client_verify(s); | ||
363 | if (ret <= 0) goto end; | ||
364 | s->state=SSL3_ST_CW_CHANGE_A; | ||
365 | s->init_num=0; | ||
366 | s->s3->change_cipher_spec=0; | ||
367 | break; | ||
368 | |||
369 | case SSL3_ST_CW_CHANGE_A: | ||
370 | case SSL3_ST_CW_CHANGE_B: | ||
371 | ret=dtls1_send_change_cipher_spec(s, | ||
372 | SSL3_ST_CW_CHANGE_A,SSL3_ST_CW_CHANGE_B); | ||
373 | if (ret <= 0) goto end; | ||
374 | s->state=SSL3_ST_CW_FINISHED_A; | ||
375 | s->init_num=0; | ||
376 | |||
377 | s->session->cipher=s->s3->tmp.new_cipher; | ||
378 | #ifdef OPENSSL_NO_COMP | ||
379 | s->session->compress_meth=0; | ||
380 | #else | ||
381 | if (s->s3->tmp.new_compression == NULL) | ||
382 | s->session->compress_meth=0; | ||
383 | else | ||
384 | s->session->compress_meth= | ||
385 | s->s3->tmp.new_compression->id; | ||
386 | #endif | ||
387 | if (!s->method->ssl3_enc->setup_key_block(s)) | ||
388 | { | ||
389 | ret= -1; | ||
390 | goto end; | ||
391 | } | ||
392 | |||
393 | if (!s->method->ssl3_enc->change_cipher_state(s, | ||
394 | SSL3_CHANGE_CIPHER_CLIENT_WRITE)) | ||
395 | { | ||
396 | ret= -1; | ||
397 | goto end; | ||
398 | } | ||
399 | |||
400 | dtls1_reset_seq_numbers(s, SSL3_CC_WRITE); | ||
401 | break; | ||
402 | |||
403 | case SSL3_ST_CW_FINISHED_A: | ||
404 | case SSL3_ST_CW_FINISHED_B: | ||
405 | ret=dtls1_send_finished(s, | ||
406 | SSL3_ST_CW_FINISHED_A,SSL3_ST_CW_FINISHED_B, | ||
407 | s->method->ssl3_enc->client_finished_label, | ||
408 | s->method->ssl3_enc->client_finished_label_len); | ||
409 | if (ret <= 0) goto end; | ||
410 | s->state=SSL3_ST_CW_FLUSH; | ||
411 | |||
412 | /* clear flags */ | ||
413 | s->s3->flags&= ~SSL3_FLAGS_POP_BUFFER; | ||
414 | if (s->hit) | ||
415 | { | ||
416 | s->s3->tmp.next_state=SSL_ST_OK; | ||
417 | if (s->s3->flags & SSL3_FLAGS_DELAY_CLIENT_FINISHED) | ||
418 | { | ||
419 | s->state=SSL_ST_OK; | ||
420 | s->s3->flags|=SSL3_FLAGS_POP_BUFFER; | ||
421 | s->s3->delay_buf_pop_ret=0; | ||
422 | } | ||
423 | } | ||
424 | else | ||
425 | { | ||
426 | s->s3->tmp.next_state=SSL3_ST_CR_FINISHED_A; | ||
427 | } | ||
428 | s->init_num=0; | ||
429 | /* mark client_random uninitialized */ | ||
430 | memset (s->s3->client_random,0,sizeof(s->s3->client_random)); | ||
431 | |||
432 | break; | ||
433 | |||
434 | case SSL3_ST_CR_FINISHED_A: | ||
435 | case SSL3_ST_CR_FINISHED_B: | ||
436 | |||
437 | ret=ssl3_get_finished(s,SSL3_ST_CR_FINISHED_A, | ||
438 | SSL3_ST_CR_FINISHED_B); | ||
439 | if (ret <= 0) goto end; | ||
440 | |||
441 | if (s->hit) | ||
442 | s->state=SSL3_ST_CW_CHANGE_A; | ||
443 | else | ||
444 | s->state=SSL_ST_OK; | ||
445 | s->init_num=0; | ||
446 | break; | ||
447 | |||
448 | case SSL3_ST_CW_FLUSH: | ||
449 | /* number of bytes to be flushed */ | ||
450 | num1=BIO_ctrl(s->wbio,BIO_CTRL_INFO,0,NULL); | ||
451 | if (num1 > 0) | ||
452 | { | ||
453 | s->rwstate=SSL_WRITING; | ||
454 | num1=BIO_flush(s->wbio); | ||
455 | if (num1 <= 0) { ret= -1; goto end; } | ||
456 | s->rwstate=SSL_NOTHING; | ||
457 | } | ||
458 | |||
459 | s->state=s->s3->tmp.next_state; | ||
460 | break; | ||
461 | |||
462 | case SSL_ST_OK: | ||
463 | /* clean a few things up */ | ||
464 | ssl3_cleanup_key_block(s); | ||
465 | |||
466 | #if 0 | ||
467 | if (s->init_buf != NULL) | ||
468 | { | ||
469 | BUF_MEM_free(s->init_buf); | ||
470 | s->init_buf=NULL; | ||
471 | } | ||
472 | #endif | ||
473 | |||
474 | /* If we are not 'joining' the last two packets, | ||
475 | * remove the buffering now */ | ||
476 | if (!(s->s3->flags & SSL3_FLAGS_POP_BUFFER)) | ||
477 | ssl_free_wbio_buffer(s); | ||
478 | /* else do it later in ssl3_write */ | ||
479 | |||
480 | s->init_num=0; | ||
481 | s->new_session=0; | ||
482 | |||
483 | ssl_update_cache(s,SSL_SESS_CACHE_CLIENT); | ||
484 | if (s->hit) s->ctx->stats.sess_hit++; | ||
485 | |||
486 | ret=1; | ||
487 | /* s->server=0; */ | ||
488 | s->handshake_func=dtls1_connect; | ||
489 | s->ctx->stats.sess_connect_good++; | ||
490 | |||
491 | if (cb != NULL) cb(s,SSL_CB_HANDSHAKE_DONE,1); | ||
492 | |||
493 | /* done with handshaking */ | ||
494 | s->d1->handshake_read_seq = 0; | ||
495 | goto end; | ||
496 | /* break; */ | ||
497 | |||
498 | default: | ||
499 | SSLerr(SSL_F_DTLS1_CONNECT,SSL_R_UNKNOWN_STATE); | ||
500 | ret= -1; | ||
501 | goto end; | ||
502 | /* break; */ | ||
503 | } | ||
504 | |||
505 | /* did we do anything */ | ||
506 | if (!s->s3->tmp.reuse_message && !skip) | ||
507 | { | ||
508 | if (s->debug) | ||
509 | { | ||
510 | if ((ret=BIO_flush(s->wbio)) <= 0) | ||
511 | goto end; | ||
512 | } | ||
513 | |||
514 | if ((cb != NULL) && (s->state != state)) | ||
515 | { | ||
516 | new_state=s->state; | ||
517 | s->state=state; | ||
518 | cb(s,SSL_CB_CONNECT_LOOP,1); | ||
519 | s->state=new_state; | ||
520 | } | ||
521 | } | ||
522 | skip=0; | ||
523 | } | ||
524 | end: | ||
525 | s->in_handshake--; | ||
526 | if (buf != NULL) | ||
527 | BUF_MEM_free(buf); | ||
528 | if (cb != NULL) | ||
529 | cb(s,SSL_CB_CONNECT_EXIT,ret); | ||
530 | return(ret); | ||
531 | } | ||
532 | |||
533 | int dtls1_client_hello(SSL *s) | ||
534 | { | ||
535 | unsigned char *buf; | ||
536 | unsigned char *p,*d; | ||
537 | unsigned int i,j; | ||
538 | unsigned long Time,l; | ||
539 | SSL_COMP *comp; | ||
540 | |||
541 | buf=(unsigned char *)s->init_buf->data; | ||
542 | if (s->state == SSL3_ST_CW_CLNT_HELLO_A) | ||
543 | { | ||
544 | if ((s->session == NULL) || | ||
545 | (s->session->ssl_version != s->version) || | ||
546 | (s->session->not_resumable)) | ||
547 | { | ||
548 | if (!ssl_get_new_session(s,0)) | ||
549 | goto err; | ||
550 | } | ||
551 | /* else use the pre-loaded session */ | ||
552 | |||
553 | p=s->s3->client_random; | ||
554 | /* if client_random is initialized, reuse it, we are | ||
555 | * required to use same upon reply to HelloVerify */ | ||
556 | for (i=0;p[i]=='\0' && i<sizeof(s->s3->client_random);i++) ; | ||
557 | if (i==sizeof(s->s3->client_random)) | ||
558 | { | ||
559 | Time=(unsigned long)time(NULL); /* Time */ | ||
560 | l2n(Time,p); | ||
561 | RAND_pseudo_bytes(p,SSL3_RANDOM_SIZE-4); | ||
562 | } | ||
563 | |||
564 | /* Do the message type and length last */ | ||
565 | d=p= &(buf[DTLS1_HM_HEADER_LENGTH]); | ||
566 | |||
567 | *(p++)=s->version>>8; | ||
568 | *(p++)=s->version&0xff; | ||
569 | s->client_version=s->version; | ||
570 | |||
571 | /* Random stuff */ | ||
572 | memcpy(p,s->s3->client_random,SSL3_RANDOM_SIZE); | ||
573 | p+=SSL3_RANDOM_SIZE; | ||
574 | |||
575 | /* Session ID */ | ||
576 | if (s->new_session) | ||
577 | i=0; | ||
578 | else | ||
579 | i=s->session->session_id_length; | ||
580 | *(p++)=i; | ||
581 | if (i != 0) | ||
582 | { | ||
583 | if (i > sizeof s->session->session_id) | ||
584 | { | ||
585 | SSLerr(SSL_F_DTLS1_CLIENT_HELLO, ERR_R_INTERNAL_ERROR); | ||
586 | goto err; | ||
587 | } | ||
588 | memcpy(p,s->session->session_id,i); | ||
589 | p+=i; | ||
590 | } | ||
591 | |||
592 | /* cookie stuff */ | ||
593 | if ( s->d1->cookie_len > sizeof(s->d1->cookie)) | ||
594 | { | ||
595 | SSLerr(SSL_F_DTLS1_CLIENT_HELLO, ERR_R_INTERNAL_ERROR); | ||
596 | goto err; | ||
597 | } | ||
598 | *(p++) = s->d1->cookie_len; | ||
599 | memcpy(p, s->d1->cookie, s->d1->cookie_len); | ||
600 | p += s->d1->cookie_len; | ||
601 | |||
602 | /* Ciphers supported */ | ||
603 | i=ssl_cipher_list_to_bytes(s,SSL_get_ciphers(s),&(p[2]),0); | ||
604 | if (i == 0) | ||
605 | { | ||
606 | SSLerr(SSL_F_DTLS1_CLIENT_HELLO,SSL_R_NO_CIPHERS_AVAILABLE); | ||
607 | goto err; | ||
608 | } | ||
609 | s2n(i,p); | ||
610 | p+=i; | ||
611 | |||
612 | /* COMPRESSION */ | ||
613 | if (s->ctx->comp_methods == NULL) | ||
614 | j=0; | ||
615 | else | ||
616 | j=sk_SSL_COMP_num(s->ctx->comp_methods); | ||
617 | *(p++)=1+j; | ||
618 | for (i=0; i<j; i++) | ||
619 | { | ||
620 | comp=sk_SSL_COMP_value(s->ctx->comp_methods,i); | ||
621 | *(p++)=comp->id; | ||
622 | } | ||
623 | *(p++)=0; /* Add the NULL method */ | ||
624 | |||
625 | l=(p-d); | ||
626 | d=buf; | ||
627 | |||
628 | d = dtls1_set_message_header(s, d, SSL3_MT_CLIENT_HELLO, l, 0, l); | ||
629 | |||
630 | s->state=SSL3_ST_CW_CLNT_HELLO_B; | ||
631 | /* number of bytes to write */ | ||
632 | s->init_num=p-buf; | ||
633 | s->init_off=0; | ||
634 | |||
635 | /* buffer the message to handle re-xmits */ | ||
636 | dtls1_buffer_message(s, 0); | ||
637 | } | ||
638 | |||
639 | /* SSL3_ST_CW_CLNT_HELLO_B */ | ||
640 | return(dtls1_do_write(s,SSL3_RT_HANDSHAKE)); | ||
641 | err: | ||
642 | return(-1); | ||
643 | } | ||
644 | |||
645 | static int dtls1_get_hello_verify(SSL *s) | ||
646 | { | ||
647 | int n, al, ok = 0; | ||
648 | unsigned char *data; | ||
649 | unsigned int cookie_len; | ||
650 | |||
651 | n=s->method->ssl_get_message(s, | ||
652 | DTLS1_ST_CR_HELLO_VERIFY_REQUEST_A, | ||
653 | DTLS1_ST_CR_HELLO_VERIFY_REQUEST_B, | ||
654 | -1, | ||
655 | s->max_cert_list, | ||
656 | &ok); | ||
657 | |||
658 | if (!ok) return((int)n); | ||
659 | |||
660 | if (s->s3->tmp.message_type != DTLS1_MT_HELLO_VERIFY_REQUEST) | ||
661 | { | ||
662 | s->d1->send_cookie = 0; | ||
663 | s->s3->tmp.reuse_message=1; | ||
664 | return(1); | ||
665 | } | ||
666 | |||
667 | data = (unsigned char *)s->init_msg; | ||
668 | |||
669 | if ((data[0] != (s->version>>8)) || (data[1] != (s->version&0xff))) | ||
670 | { | ||
671 | SSLerr(SSL_F_DTLS1_GET_HELLO_VERIFY,SSL_R_WRONG_SSL_VERSION); | ||
672 | s->version=(s->version&0xff00)|data[1]; | ||
673 | al = SSL_AD_PROTOCOL_VERSION; | ||
674 | goto f_err; | ||
675 | } | ||
676 | data+=2; | ||
677 | |||
678 | cookie_len = *(data++); | ||
679 | if ( cookie_len > sizeof(s->d1->cookie)) | ||
680 | { | ||
681 | al=SSL_AD_ILLEGAL_PARAMETER; | ||
682 | goto f_err; | ||
683 | } | ||
684 | |||
685 | memcpy(s->d1->cookie, data, cookie_len); | ||
686 | s->d1->cookie_len = cookie_len; | ||
687 | |||
688 | s->d1->send_cookie = 1; | ||
689 | return 1; | ||
690 | |||
691 | f_err: | ||
692 | ssl3_send_alert(s, SSL3_AL_FATAL, al); | ||
693 | return -1; | ||
694 | } | ||
695 | |||
696 | int dtls1_send_client_key_exchange(SSL *s) | ||
697 | { | ||
698 | unsigned char *p,*d; | ||
699 | int n; | ||
700 | unsigned long l; | ||
701 | #ifndef OPENSSL_NO_RSA | ||
702 | unsigned char *q; | ||
703 | EVP_PKEY *pkey=NULL; | ||
704 | #endif | ||
705 | #ifndef OPENSSL_NO_KRB5 | ||
706 | KSSL_ERR kssl_err; | ||
707 | #endif /* OPENSSL_NO_KRB5 */ | ||
708 | |||
709 | if (s->state == SSL3_ST_CW_KEY_EXCH_A) | ||
710 | { | ||
711 | d=(unsigned char *)s->init_buf->data; | ||
712 | p= &(d[DTLS1_HM_HEADER_LENGTH]); | ||
713 | |||
714 | l=s->s3->tmp.new_cipher->algorithms; | ||
715 | |||
716 | /* Fool emacs indentation */ | ||
717 | if (0) {} | ||
718 | #ifndef OPENSSL_NO_RSA | ||
719 | else if (l & SSL_kRSA) | ||
720 | { | ||
721 | RSA *rsa; | ||
722 | unsigned char tmp_buf[SSL_MAX_MASTER_KEY_LENGTH]; | ||
723 | |||
724 | if (s->session->sess_cert->peer_rsa_tmp != NULL) | ||
725 | rsa=s->session->sess_cert->peer_rsa_tmp; | ||
726 | else | ||
727 | { | ||
728 | pkey=X509_get_pubkey(s->session->sess_cert->peer_pkeys[SSL_PKEY_RSA_ENC].x509); | ||
729 | if ((pkey == NULL) || | ||
730 | (pkey->type != EVP_PKEY_RSA) || | ||
731 | (pkey->pkey.rsa == NULL)) | ||
732 | { | ||
733 | SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE,ERR_R_INTERNAL_ERROR); | ||
734 | goto err; | ||
735 | } | ||
736 | rsa=pkey->pkey.rsa; | ||
737 | EVP_PKEY_free(pkey); | ||
738 | } | ||
739 | |||
740 | tmp_buf[0]=s->client_version>>8; | ||
741 | tmp_buf[1]=s->client_version&0xff; | ||
742 | if (RAND_bytes(&(tmp_buf[2]),sizeof tmp_buf-2) <= 0) | ||
743 | goto err; | ||
744 | |||
745 | s->session->master_key_length=sizeof tmp_buf; | ||
746 | |||
747 | q=p; | ||
748 | /* Fix buf for TLS and [incidentally] DTLS */ | ||
749 | if (s->version > SSL3_VERSION) | ||
750 | p+=2; | ||
751 | n=RSA_public_encrypt(sizeof tmp_buf, | ||
752 | tmp_buf,p,rsa,RSA_PKCS1_PADDING); | ||
753 | #ifdef PKCS1_CHECK | ||
754 | if (s->options & SSL_OP_PKCS1_CHECK_1) p[1]++; | ||
755 | if (s->options & SSL_OP_PKCS1_CHECK_2) tmp_buf[0]=0x70; | ||
756 | #endif | ||
757 | if (n <= 0) | ||
758 | { | ||
759 | SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE,SSL_R_BAD_RSA_ENCRYPT); | ||
760 | goto err; | ||
761 | } | ||
762 | |||
763 | /* Fix buf for TLS and [incidentally] DTLS */ | ||
764 | if (s->version > SSL3_VERSION) | ||
765 | { | ||
766 | s2n(n,q); | ||
767 | n+=2; | ||
768 | } | ||
769 | |||
770 | s->session->master_key_length= | ||
771 | s->method->ssl3_enc->generate_master_secret(s, | ||
772 | s->session->master_key, | ||
773 | tmp_buf,sizeof tmp_buf); | ||
774 | OPENSSL_cleanse(tmp_buf,sizeof tmp_buf); | ||
775 | } | ||
776 | #endif | ||
777 | #ifndef OPENSSL_NO_KRB5 | ||
778 | else if (l & SSL_kKRB5) | ||
779 | { | ||
780 | krb5_error_code krb5rc; | ||
781 | KSSL_CTX *kssl_ctx = s->kssl_ctx; | ||
782 | /* krb5_data krb5_ap_req; */ | ||
783 | krb5_data *enc_ticket; | ||
784 | krb5_data authenticator, *authp = NULL; | ||
785 | EVP_CIPHER_CTX ciph_ctx; | ||
786 | EVP_CIPHER *enc = NULL; | ||
787 | unsigned char iv[EVP_MAX_IV_LENGTH]; | ||
788 | unsigned char tmp_buf[SSL_MAX_MASTER_KEY_LENGTH]; | ||
789 | unsigned char epms[SSL_MAX_MASTER_KEY_LENGTH | ||
790 | + EVP_MAX_IV_LENGTH]; | ||
791 | int padl, outl = sizeof(epms); | ||
792 | |||
793 | EVP_CIPHER_CTX_init(&ciph_ctx); | ||
794 | |||
795 | #ifdef KSSL_DEBUG | ||
796 | printf("ssl3_send_client_key_exchange(%lx & %lx)\n", | ||
797 | l, SSL_kKRB5); | ||
798 | #endif /* KSSL_DEBUG */ | ||
799 | |||
800 | authp = NULL; | ||
801 | #ifdef KRB5SENDAUTH | ||
802 | if (KRB5SENDAUTH) authp = &authenticator; | ||
803 | #endif /* KRB5SENDAUTH */ | ||
804 | |||
805 | krb5rc = kssl_cget_tkt(kssl_ctx, &enc_ticket, authp, | ||
806 | &kssl_err); | ||
807 | enc = kssl_map_enc(kssl_ctx->enctype); | ||
808 | if (enc == NULL) | ||
809 | goto err; | ||
810 | #ifdef KSSL_DEBUG | ||
811 | { | ||
812 | printf("kssl_cget_tkt rtn %d\n", krb5rc); | ||
813 | if (krb5rc && kssl_err.text) | ||
814 | printf("kssl_cget_tkt kssl_err=%s\n", kssl_err.text); | ||
815 | } | ||
816 | #endif /* KSSL_DEBUG */ | ||
817 | |||
818 | if (krb5rc) | ||
819 | { | ||
820 | ssl3_send_alert(s,SSL3_AL_FATAL, | ||
821 | SSL_AD_HANDSHAKE_FAILURE); | ||
822 | SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE, | ||
823 | kssl_err.reason); | ||
824 | goto err; | ||
825 | } | ||
826 | |||
827 | /* 20010406 VRS - Earlier versions used KRB5 AP_REQ | ||
828 | ** in place of RFC 2712 KerberosWrapper, as in: | ||
829 | ** | ||
830 | ** Send ticket (copy to *p, set n = length) | ||
831 | ** n = krb5_ap_req.length; | ||
832 | ** memcpy(p, krb5_ap_req.data, krb5_ap_req.length); | ||
833 | ** if (krb5_ap_req.data) | ||
834 | ** kssl_krb5_free_data_contents(NULL,&krb5_ap_req); | ||
835 | ** | ||
836 | ** Now using real RFC 2712 KerberosWrapper | ||
837 | ** (Thanks to Simon Wilkinson <sxw@sxw.org.uk>) | ||
838 | ** Note: 2712 "opaque" types are here replaced | ||
839 | ** with a 2-byte length followed by the value. | ||
840 | ** Example: | ||
841 | ** KerberosWrapper= xx xx asn1ticket 0 0 xx xx encpms | ||
842 | ** Where "xx xx" = length bytes. Shown here with | ||
843 | ** optional authenticator omitted. | ||
844 | */ | ||
845 | |||
846 | /* KerberosWrapper.Ticket */ | ||
847 | s2n(enc_ticket->length,p); | ||
848 | memcpy(p, enc_ticket->data, enc_ticket->length); | ||
849 | p+= enc_ticket->length; | ||
850 | n = enc_ticket->length + 2; | ||
851 | |||
852 | /* KerberosWrapper.Authenticator */ | ||
853 | if (authp && authp->length) | ||
854 | { | ||
855 | s2n(authp->length,p); | ||
856 | memcpy(p, authp->data, authp->length); | ||
857 | p+= authp->length; | ||
858 | n+= authp->length + 2; | ||
859 | |||
860 | free(authp->data); | ||
861 | authp->data = NULL; | ||
862 | authp->length = 0; | ||
863 | } | ||
864 | else | ||
865 | { | ||
866 | s2n(0,p);/* null authenticator length */ | ||
867 | n+=2; | ||
868 | } | ||
869 | |||
870 | if (RAND_bytes(tmp_buf,sizeof tmp_buf) <= 0) | ||
871 | goto err; | ||
872 | |||
873 | /* 20010420 VRS. Tried it this way; failed. | ||
874 | ** EVP_EncryptInit_ex(&ciph_ctx,enc, NULL,NULL); | ||
875 | ** EVP_CIPHER_CTX_set_key_length(&ciph_ctx, | ||
876 | ** kssl_ctx->length); | ||
877 | ** EVP_EncryptInit_ex(&ciph_ctx,NULL, key,iv); | ||
878 | */ | ||
879 | |||
880 | memset(iv, 0, sizeof iv); /* per RFC 1510 */ | ||
881 | EVP_EncryptInit_ex(&ciph_ctx,enc, NULL, | ||
882 | kssl_ctx->key,iv); | ||
883 | EVP_EncryptUpdate(&ciph_ctx,epms,&outl,tmp_buf, | ||
884 | sizeof tmp_buf); | ||
885 | EVP_EncryptFinal_ex(&ciph_ctx,&(epms[outl]),&padl); | ||
886 | outl += padl; | ||
887 | if (outl > sizeof epms) | ||
888 | { | ||
889 | SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR); | ||
890 | goto err; | ||
891 | } | ||
892 | EVP_CIPHER_CTX_cleanup(&ciph_ctx); | ||
893 | |||
894 | /* KerberosWrapper.EncryptedPreMasterSecret */ | ||
895 | s2n(outl,p); | ||
896 | memcpy(p, epms, outl); | ||
897 | p+=outl; | ||
898 | n+=outl + 2; | ||
899 | |||
900 | s->session->master_key_length= | ||
901 | s->method->ssl3_enc->generate_master_secret(s, | ||
902 | s->session->master_key, | ||
903 | tmp_buf, sizeof tmp_buf); | ||
904 | |||
905 | OPENSSL_cleanse(tmp_buf, sizeof tmp_buf); | ||
906 | OPENSSL_cleanse(epms, outl); | ||
907 | } | ||
908 | #endif | ||
909 | #ifndef OPENSSL_NO_DH | ||
910 | else if (l & (SSL_kEDH|SSL_kDHr|SSL_kDHd)) | ||
911 | { | ||
912 | DH *dh_srvr,*dh_clnt; | ||
913 | |||
914 | if (s->session->sess_cert->peer_dh_tmp != NULL) | ||
915 | dh_srvr=s->session->sess_cert->peer_dh_tmp; | ||
916 | else | ||
917 | { | ||
918 | /* we get them from the cert */ | ||
919 | ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_HANDSHAKE_FAILURE); | ||
920 | SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE,SSL_R_UNABLE_TO_FIND_DH_PARAMETERS); | ||
921 | goto err; | ||
922 | } | ||
923 | |||
924 | /* generate a new random key */ | ||
925 | if ((dh_clnt=DHparams_dup(dh_srvr)) == NULL) | ||
926 | { | ||
927 | SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE,ERR_R_DH_LIB); | ||
928 | goto err; | ||
929 | } | ||
930 | if (!DH_generate_key(dh_clnt)) | ||
931 | { | ||
932 | SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE,ERR_R_DH_LIB); | ||
933 | goto err; | ||
934 | } | ||
935 | |||
936 | /* use the 'p' output buffer for the DH key, but | ||
937 | * make sure to clear it out afterwards */ | ||
938 | |||
939 | n=DH_compute_key(p,dh_srvr->pub_key,dh_clnt); | ||
940 | |||
941 | if (n <= 0) | ||
942 | { | ||
943 | SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE,ERR_R_DH_LIB); | ||
944 | goto err; | ||
945 | } | ||
946 | |||
947 | /* generate master key from the result */ | ||
948 | s->session->master_key_length= | ||
949 | s->method->ssl3_enc->generate_master_secret(s, | ||
950 | s->session->master_key,p,n); | ||
951 | /* clean up */ | ||
952 | memset(p,0,n); | ||
953 | |||
954 | /* send off the data */ | ||
955 | n=BN_num_bytes(dh_clnt->pub_key); | ||
956 | s2n(n,p); | ||
957 | BN_bn2bin(dh_clnt->pub_key,p); | ||
958 | n+=2; | ||
959 | |||
960 | DH_free(dh_clnt); | ||
961 | |||
962 | /* perhaps clean things up a bit EAY EAY EAY EAY*/ | ||
963 | } | ||
964 | #endif | ||
965 | else | ||
966 | { | ||
967 | ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_HANDSHAKE_FAILURE); | ||
968 | SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE,ERR_R_INTERNAL_ERROR); | ||
969 | goto err; | ||
970 | } | ||
971 | |||
972 | d = dtls1_set_message_header(s, d, | ||
973 | SSL3_MT_CLIENT_KEY_EXCHANGE, n, 0, n); | ||
974 | /* | ||
975 | *(d++)=SSL3_MT_CLIENT_KEY_EXCHANGE; | ||
976 | l2n3(n,d); | ||
977 | l2n(s->d1->handshake_write_seq,d); | ||
978 | s->d1->handshake_write_seq++; | ||
979 | */ | ||
980 | |||
981 | s->state=SSL3_ST_CW_KEY_EXCH_B; | ||
982 | /* number of bytes to write */ | ||
983 | s->init_num=n+DTLS1_HM_HEADER_LENGTH; | ||
984 | s->init_off=0; | ||
985 | |||
986 | /* buffer the message to handle re-xmits */ | ||
987 | dtls1_buffer_message(s, 0); | ||
988 | } | ||
989 | |||
990 | /* SSL3_ST_CW_KEY_EXCH_B */ | ||
991 | return(dtls1_do_write(s,SSL3_RT_HANDSHAKE)); | ||
992 | err: | ||
993 | return(-1); | ||
994 | } | ||
995 | |||
996 | int dtls1_send_client_verify(SSL *s) | ||
997 | { | ||
998 | unsigned char *p,*d; | ||
999 | unsigned char data[MD5_DIGEST_LENGTH+SHA_DIGEST_LENGTH]; | ||
1000 | EVP_PKEY *pkey; | ||
1001 | #ifndef OPENSSL_NO_RSA | ||
1002 | unsigned u=0; | ||
1003 | #endif | ||
1004 | unsigned long n; | ||
1005 | #ifndef OPENSSL_NO_DSA | ||
1006 | int j; | ||
1007 | #endif | ||
1008 | |||
1009 | if (s->state == SSL3_ST_CW_CERT_VRFY_A) | ||
1010 | { | ||
1011 | d=(unsigned char *)s->init_buf->data; | ||
1012 | p= &(d[DTLS1_HM_HEADER_LENGTH]); | ||
1013 | pkey=s->cert->key->privatekey; | ||
1014 | |||
1015 | s->method->ssl3_enc->cert_verify_mac(s,&(s->s3->finish_dgst2), | ||
1016 | &(data[MD5_DIGEST_LENGTH])); | ||
1017 | |||
1018 | #ifndef OPENSSL_NO_RSA | ||
1019 | if (pkey->type == EVP_PKEY_RSA) | ||
1020 | { | ||
1021 | s->method->ssl3_enc->cert_verify_mac(s, | ||
1022 | &(s->s3->finish_dgst1),&(data[0])); | ||
1023 | if (RSA_sign(NID_md5_sha1, data, | ||
1024 | MD5_DIGEST_LENGTH+SHA_DIGEST_LENGTH, | ||
1025 | &(p[2]), &u, pkey->pkey.rsa) <= 0 ) | ||
1026 | { | ||
1027 | SSLerr(SSL_F_DTLS1_SEND_CLIENT_VERIFY,ERR_R_RSA_LIB); | ||
1028 | goto err; | ||
1029 | } | ||
1030 | s2n(u,p); | ||
1031 | n=u+2; | ||
1032 | } | ||
1033 | else | ||
1034 | #endif | ||
1035 | #ifndef OPENSSL_NO_DSA | ||
1036 | if (pkey->type == EVP_PKEY_DSA) | ||
1037 | { | ||
1038 | if (!DSA_sign(pkey->save_type, | ||
1039 | &(data[MD5_DIGEST_LENGTH]), | ||
1040 | SHA_DIGEST_LENGTH,&(p[2]), | ||
1041 | (unsigned int *)&j,pkey->pkey.dsa)) | ||
1042 | { | ||
1043 | SSLerr(SSL_F_DTLS1_SEND_CLIENT_VERIFY,ERR_R_DSA_LIB); | ||
1044 | goto err; | ||
1045 | } | ||
1046 | s2n(j,p); | ||
1047 | n=j+2; | ||
1048 | } | ||
1049 | else | ||
1050 | #endif | ||
1051 | { | ||
1052 | SSLerr(SSL_F_DTLS1_SEND_CLIENT_VERIFY,ERR_R_INTERNAL_ERROR); | ||
1053 | goto err; | ||
1054 | } | ||
1055 | |||
1056 | d = dtls1_set_message_header(s, d, | ||
1057 | SSL3_MT_CERTIFICATE_VERIFY, n, 0, n) ; | ||
1058 | |||
1059 | s->init_num=(int)n+DTLS1_HM_HEADER_LENGTH; | ||
1060 | s->init_off=0; | ||
1061 | |||
1062 | /* buffer the message to handle re-xmits */ | ||
1063 | dtls1_buffer_message(s, 0); | ||
1064 | |||
1065 | s->state = SSL3_ST_CW_CERT_VRFY_B; | ||
1066 | } | ||
1067 | |||
1068 | /* s->state = SSL3_ST_CW_CERT_VRFY_B */ | ||
1069 | return(dtls1_do_write(s,SSL3_RT_HANDSHAKE)); | ||
1070 | err: | ||
1071 | return(-1); | ||
1072 | } | ||
1073 | |||
1074 | int dtls1_send_client_certificate(SSL *s) | ||
1075 | { | ||
1076 | X509 *x509=NULL; | ||
1077 | EVP_PKEY *pkey=NULL; | ||
1078 | int i; | ||
1079 | unsigned long l; | ||
1080 | |||
1081 | if (s->state == SSL3_ST_CW_CERT_A) | ||
1082 | { | ||
1083 | if ((s->cert == NULL) || | ||
1084 | (s->cert->key->x509 == NULL) || | ||
1085 | (s->cert->key->privatekey == NULL)) | ||
1086 | s->state=SSL3_ST_CW_CERT_B; | ||
1087 | else | ||
1088 | s->state=SSL3_ST_CW_CERT_C; | ||
1089 | } | ||
1090 | |||
1091 | /* We need to get a client cert */ | ||
1092 | if (s->state == SSL3_ST_CW_CERT_B) | ||
1093 | { | ||
1094 | /* If we get an error, we need to | ||
1095 | * ssl->rwstate=SSL_X509_LOOKUP; return(-1); | ||
1096 | * We then get retied later */ | ||
1097 | i=0; | ||
1098 | if (s->ctx->client_cert_cb != NULL) | ||
1099 | i=s->ctx->client_cert_cb(s,&(x509),&(pkey)); | ||
1100 | if (i < 0) | ||
1101 | { | ||
1102 | s->rwstate=SSL_X509_LOOKUP; | ||
1103 | return(-1); | ||
1104 | } | ||
1105 | s->rwstate=SSL_NOTHING; | ||
1106 | if ((i == 1) && (pkey != NULL) && (x509 != NULL)) | ||
1107 | { | ||
1108 | s->state=SSL3_ST_CW_CERT_B; | ||
1109 | if ( !SSL_use_certificate(s,x509) || | ||
1110 | !SSL_use_PrivateKey(s,pkey)) | ||
1111 | i=0; | ||
1112 | } | ||
1113 | else if (i == 1) | ||
1114 | { | ||
1115 | i=0; | ||
1116 | SSLerr(SSL_F_DTLS1_SEND_CLIENT_CERTIFICATE,SSL_R_BAD_DATA_RETURNED_BY_CALLBACK); | ||
1117 | } | ||
1118 | |||
1119 | if (x509 != NULL) X509_free(x509); | ||
1120 | if (pkey != NULL) EVP_PKEY_free(pkey); | ||
1121 | if (i == 0) | ||
1122 | { | ||
1123 | if (s->version == SSL3_VERSION) | ||
1124 | { | ||
1125 | s->s3->tmp.cert_req=0; | ||
1126 | ssl3_send_alert(s,SSL3_AL_WARNING,SSL_AD_NO_CERTIFICATE); | ||
1127 | return(1); | ||
1128 | } | ||
1129 | else | ||
1130 | { | ||
1131 | s->s3->tmp.cert_req=2; | ||
1132 | } | ||
1133 | } | ||
1134 | |||
1135 | /* Ok, we have a cert */ | ||
1136 | s->state=SSL3_ST_CW_CERT_C; | ||
1137 | } | ||
1138 | |||
1139 | if (s->state == SSL3_ST_CW_CERT_C) | ||
1140 | { | ||
1141 | s->state=SSL3_ST_CW_CERT_D; | ||
1142 | l=dtls1_output_cert_chain(s, | ||
1143 | (s->s3->tmp.cert_req == 2)?NULL:s->cert->key->x509); | ||
1144 | s->init_num=(int)l; | ||
1145 | s->init_off=0; | ||
1146 | |||
1147 | /* set header called by dtls1_output_cert_chain() */ | ||
1148 | |||
1149 | /* buffer the message to handle re-xmits */ | ||
1150 | dtls1_buffer_message(s, 0); | ||
1151 | } | ||
1152 | /* SSL3_ST_CW_CERT_D */ | ||
1153 | return(dtls1_do_write(s,SSL3_RT_HANDSHAKE)); | ||
1154 | } | ||
1155 | |||
1156 | |||
diff --git a/src/lib/libssl/d1_enc.c b/src/lib/libssl/d1_enc.c new file mode 100644 index 0000000000..cbff7495c5 --- /dev/null +++ b/src/lib/libssl/d1_enc.c | |||
@@ -0,0 +1,281 @@ | |||
1 | /* ssl/d1_enc.c */ | ||
2 | /* | ||
3 | * DTLS implementation written by Nagendra Modadugu | ||
4 | * (nagendra@cs.stanford.edu) for the OpenSSL project 2005. | ||
5 | */ | ||
6 | /* ==================================================================== | ||
7 | * Copyright (c) 1998-2005 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 | * openssl-core@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 | * This product includes cryptographic software written by Eric Young | ||
55 | * (eay@cryptsoft.com). This product includes software written by Tim | ||
56 | * Hudson (tjh@cryptsoft.com). | ||
57 | * | ||
58 | */ | ||
59 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) | ||
60 | * All rights reserved. | ||
61 | * | ||
62 | * This package is an SSL implementation written | ||
63 | * by Eric Young (eay@cryptsoft.com). | ||
64 | * The implementation was written so as to conform with Netscapes SSL. | ||
65 | * | ||
66 | * This library is free for commercial and non-commercial use as long as | ||
67 | * the following conditions are aheared to. The following conditions | ||
68 | * apply to all code found in this distribution, be it the RC4, RSA, | ||
69 | * lhash, DES, etc., code; not just the SSL code. The SSL documentation | ||
70 | * included with this distribution is covered by the same copyright terms | ||
71 | * except that the holder is Tim Hudson (tjh@cryptsoft.com). | ||
72 | * | ||
73 | * Copyright remains Eric Young's, and as such any Copyright notices in | ||
74 | * the code are not to be removed. | ||
75 | * If this package is used in a product, Eric Young should be given attribution | ||
76 | * as the author of the parts of the library used. | ||
77 | * This can be in the form of a textual message at program startup or | ||
78 | * in documentation (online or textual) provided with the package. | ||
79 | * | ||
80 | * Redistribution and use in source and binary forms, with or without | ||
81 | * modification, are permitted provided that the following conditions | ||
82 | * are met: | ||
83 | * 1. Redistributions of source code must retain the copyright | ||
84 | * notice, this list of conditions and the following disclaimer. | ||
85 | * 2. Redistributions in binary form must reproduce the above copyright | ||
86 | * notice, this list of conditions and the following disclaimer in the | ||
87 | * documentation and/or other materials provided with the distribution. | ||
88 | * 3. All advertising materials mentioning features or use of this software | ||
89 | * must display the following acknowledgement: | ||
90 | * "This product includes cryptographic software written by | ||
91 | * Eric Young (eay@cryptsoft.com)" | ||
92 | * The word 'cryptographic' can be left out if the rouines from the library | ||
93 | * being used are not cryptographic related :-). | ||
94 | * 4. If you include any Windows specific code (or a derivative thereof) from | ||
95 | * the apps directory (application code) you must include an acknowledgement: | ||
96 | * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" | ||
97 | * | ||
98 | * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND | ||
99 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
100 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
101 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | ||
102 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
103 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
104 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
105 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
106 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
107 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
108 | * SUCH DAMAGE. | ||
109 | * | ||
110 | * The licence and distribution terms for any publically available version or | ||
111 | * derivative of this code cannot be changed. i.e. this code cannot simply be | ||
112 | * copied and put under another distribution licence | ||
113 | * [including the GNU Public Licence.] | ||
114 | */ | ||
115 | |||
116 | #include <stdio.h> | ||
117 | #include "ssl_locl.h" | ||
118 | #include <openssl/comp.h> | ||
119 | #include <openssl/evp.h> | ||
120 | #include <openssl/hmac.h> | ||
121 | #include <openssl/md5.h> | ||
122 | #include <openssl/rand.h> | ||
123 | |||
124 | |||
125 | int dtls1_enc(SSL *s, int send) | ||
126 | { | ||
127 | SSL3_RECORD *rec; | ||
128 | EVP_CIPHER_CTX *ds; | ||
129 | unsigned long l; | ||
130 | int bs,i,ii,j,k,n=0; | ||
131 | const EVP_CIPHER *enc; | ||
132 | |||
133 | if (send) | ||
134 | { | ||
135 | if (s->write_hash != NULL) | ||
136 | n=EVP_MD_size(s->write_hash); | ||
137 | ds=s->enc_write_ctx; | ||
138 | rec= &(s->s3->wrec); | ||
139 | if (s->enc_write_ctx == NULL) | ||
140 | enc=NULL; | ||
141 | else | ||
142 | { | ||
143 | enc=EVP_CIPHER_CTX_cipher(s->enc_write_ctx); | ||
144 | if ( rec->data != rec->input) | ||
145 | /* we can't write into the input stream */ | ||
146 | fprintf(stderr, "%s:%d: rec->data != rec->input\n", | ||
147 | __FILE__, __LINE__); | ||
148 | else if ( EVP_CIPHER_block_size(ds->cipher) > 1) | ||
149 | { | ||
150 | if (!RAND_bytes(rec->input, EVP_CIPHER_block_size(ds->cipher))) | ||
151 | return -1; | ||
152 | } | ||
153 | } | ||
154 | } | ||
155 | else | ||
156 | { | ||
157 | if (s->read_hash != NULL) | ||
158 | n=EVP_MD_size(s->read_hash); | ||
159 | ds=s->enc_read_ctx; | ||
160 | rec= &(s->s3->rrec); | ||
161 | if (s->enc_read_ctx == NULL) | ||
162 | enc=NULL; | ||
163 | else | ||
164 | enc=EVP_CIPHER_CTX_cipher(s->enc_read_ctx); | ||
165 | } | ||
166 | |||
167 | #ifdef KSSL_DEBUG | ||
168 | printf("dtls1_enc(%d)\n", send); | ||
169 | #endif /* KSSL_DEBUG */ | ||
170 | |||
171 | if ((s->session == NULL) || (ds == NULL) || | ||
172 | (enc == NULL)) | ||
173 | { | ||
174 | memmove(rec->data,rec->input,rec->length); | ||
175 | rec->input=rec->data; | ||
176 | } | ||
177 | else | ||
178 | { | ||
179 | l=rec->length; | ||
180 | bs=EVP_CIPHER_block_size(ds->cipher); | ||
181 | |||
182 | if ((bs != 1) && send) | ||
183 | { | ||
184 | i=bs-((int)l%bs); | ||
185 | |||
186 | /* Add weird padding of upto 256 bytes */ | ||
187 | |||
188 | /* we need to add 'i' padding bytes of value j */ | ||
189 | j=i-1; | ||
190 | if (s->options & SSL_OP_TLS_BLOCK_PADDING_BUG) | ||
191 | { | ||
192 | if (s->s3->flags & TLS1_FLAGS_TLS_PADDING_BUG) | ||
193 | j++; | ||
194 | } | ||
195 | for (k=(int)l; k<(int)(l+i); k++) | ||
196 | rec->input[k]=j; | ||
197 | l+=i; | ||
198 | rec->length+=i; | ||
199 | } | ||
200 | |||
201 | #ifdef KSSL_DEBUG | ||
202 | { | ||
203 | unsigned long ui; | ||
204 | printf("EVP_Cipher(ds=%p,rec->data=%p,rec->input=%p,l=%ld) ==>\n", | ||
205 | ds,rec->data,rec->input,l); | ||
206 | printf("\tEVP_CIPHER_CTX: %d buf_len, %d key_len [%d %d], %d iv_len\n", | ||
207 | ds->buf_len, ds->cipher->key_len, | ||
208 | DES_KEY_SZ, DES_SCHEDULE_SZ, | ||
209 | ds->cipher->iv_len); | ||
210 | printf("\t\tIV: "); | ||
211 | for (i=0; i<ds->cipher->iv_len; i++) printf("%02X", ds->iv[i]); | ||
212 | printf("\n"); | ||
213 | printf("\trec->input="); | ||
214 | for (ui=0; ui<l; ui++) printf(" %02x", rec->input[ui]); | ||
215 | printf("\n"); | ||
216 | } | ||
217 | #endif /* KSSL_DEBUG */ | ||
218 | |||
219 | if (!send) | ||
220 | { | ||
221 | if (l == 0 || l%bs != 0) | ||
222 | { | ||
223 | SSLerr(SSL_F_DTLS1_ENC,SSL_R_BLOCK_CIPHER_PAD_IS_WRONG); | ||
224 | ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_DECRYPTION_FAILED); | ||
225 | return 0; | ||
226 | } | ||
227 | } | ||
228 | |||
229 | EVP_Cipher(ds,rec->data,rec->input,l); | ||
230 | |||
231 | #ifdef KSSL_DEBUG | ||
232 | { | ||
233 | unsigned long i; | ||
234 | printf("\trec->data="); | ||
235 | for (i=0; i<l; i++) | ||
236 | printf(" %02x", rec->data[i]); printf("\n"); | ||
237 | } | ||
238 | #endif /* KSSL_DEBUG */ | ||
239 | |||
240 | if ((bs != 1) && !send) | ||
241 | { | ||
242 | ii=i=rec->data[l-1]; /* padding_length */ | ||
243 | i++; | ||
244 | if (s->options&SSL_OP_TLS_BLOCK_PADDING_BUG) | ||
245 | { | ||
246 | /* First packet is even in size, so check */ | ||
247 | if ((memcmp(s->s3->read_sequence, | ||
248 | "\0\0\0\0\0\0\0\0",8) == 0) && !(ii & 1)) | ||
249 | s->s3->flags|=TLS1_FLAGS_TLS_PADDING_BUG; | ||
250 | if (s->s3->flags & TLS1_FLAGS_TLS_PADDING_BUG) | ||
251 | i--; | ||
252 | } | ||
253 | /* TLS 1.0 does not bound the number of padding bytes by the block size. | ||
254 | * All of them must have value 'padding_length'. */ | ||
255 | if (i > (int)rec->length) | ||
256 | { | ||
257 | /* Incorrect padding. SSLerr() and ssl3_alert are done | ||
258 | * by caller: we don't want to reveal whether this is | ||
259 | * a decryption error or a MAC verification failure | ||
260 | * (see http://www.openssl.org/~bodo/tls-cbc.txt) | ||
261 | */ | ||
262 | return -1; | ||
263 | } | ||
264 | for (j=(int)(l-i); j<(int)l; j++) | ||
265 | { | ||
266 | if (rec->data[j] != ii) | ||
267 | { | ||
268 | /* Incorrect padding */ | ||
269 | return -1; | ||
270 | } | ||
271 | } | ||
272 | rec->length-=i; | ||
273 | |||
274 | rec->data += bs; /* skip the implicit IV */ | ||
275 | rec->input += bs; | ||
276 | rec->length -= bs; | ||
277 | } | ||
278 | } | ||
279 | return(1); | ||
280 | } | ||
281 | |||
diff --git a/src/lib/libssl/d1_lib.c b/src/lib/libssl/d1_lib.c new file mode 100644 index 0000000000..fc088b4148 --- /dev/null +++ b/src/lib/libssl/d1_lib.c | |||
@@ -0,0 +1,210 @@ | |||
1 | /* ssl/d1_lib.c */ | ||
2 | /* | ||
3 | * DTLS implementation written by Nagendra Modadugu | ||
4 | * (nagendra@cs.stanford.edu) for the OpenSSL project 2005. | ||
5 | */ | ||
6 | /* ==================================================================== | ||
7 | * Copyright (c) 1999-2005 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 | * openssl-core@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 | * This product includes cryptographic software written by Eric Young | ||
55 | * (eay@cryptsoft.com). This product includes software written by Tim | ||
56 | * Hudson (tjh@cryptsoft.com). | ||
57 | * | ||
58 | */ | ||
59 | |||
60 | #include <stdio.h> | ||
61 | #include <openssl/objects.h> | ||
62 | #include "ssl_locl.h" | ||
63 | |||
64 | const char dtls1_version_str[]="DTLSv1" OPENSSL_VERSION_PTEXT; | ||
65 | |||
66 | SSL3_ENC_METHOD DTLSv1_enc_data={ | ||
67 | dtls1_enc, | ||
68 | tls1_mac, | ||
69 | tls1_setup_key_block, | ||
70 | tls1_generate_master_secret, | ||
71 | tls1_change_cipher_state, | ||
72 | tls1_final_finish_mac, | ||
73 | TLS1_FINISH_MAC_LENGTH, | ||
74 | tls1_cert_verify_mac, | ||
75 | TLS_MD_CLIENT_FINISH_CONST,TLS_MD_CLIENT_FINISH_CONST_SIZE, | ||
76 | TLS_MD_SERVER_FINISH_CONST,TLS_MD_SERVER_FINISH_CONST_SIZE, | ||
77 | tls1_alert_code, | ||
78 | }; | ||
79 | |||
80 | long dtls1_default_timeout(void) | ||
81 | { | ||
82 | /* 2 hours, the 24 hours mentioned in the DTLSv1 spec | ||
83 | * is way too long for http, the cache would over fill */ | ||
84 | return(60*60*2); | ||
85 | } | ||
86 | |||
87 | IMPLEMENT_dtls1_meth_func(dtlsv1_base_method, | ||
88 | ssl_undefined_function, | ||
89 | ssl_undefined_function, | ||
90 | ssl_bad_method) | ||
91 | |||
92 | int dtls1_new(SSL *s) | ||
93 | { | ||
94 | DTLS1_STATE *d1; | ||
95 | |||
96 | if (!ssl3_new(s)) return(0); | ||
97 | if ((d1=OPENSSL_malloc(sizeof *d1)) == NULL) return (0); | ||
98 | memset(d1,0, sizeof *d1); | ||
99 | |||
100 | /* d1->handshake_epoch=0; */ | ||
101 | #if defined(OPENSSL_SYS_VMS) || defined(VMS_TEST) | ||
102 | d1->bitmap.length=64; | ||
103 | #else | ||
104 | d1->bitmap.length=sizeof(d1->bitmap.map) * 8; | ||
105 | #endif | ||
106 | pq_64bit_init(&(d1->bitmap.map)); | ||
107 | pq_64bit_init(&(d1->bitmap.max_seq_num)); | ||
108 | |||
109 | pq_64bit_init(&(d1->next_bitmap.map)); | ||
110 | pq_64bit_init(&(d1->next_bitmap.max_seq_num)); | ||
111 | |||
112 | d1->unprocessed_rcds.q=pqueue_new(); | ||
113 | d1->processed_rcds.q=pqueue_new(); | ||
114 | d1->buffered_messages = pqueue_new(); | ||
115 | d1->sent_messages=pqueue_new(); | ||
116 | |||
117 | if ( s->server) | ||
118 | { | ||
119 | d1->cookie_len = sizeof(s->d1->cookie); | ||
120 | } | ||
121 | |||
122 | if( ! d1->unprocessed_rcds.q || ! d1->processed_rcds.q | ||
123 | || ! d1->buffered_messages || ! d1->sent_messages) | ||
124 | { | ||
125 | if ( d1->unprocessed_rcds.q) pqueue_free(d1->unprocessed_rcds.q); | ||
126 | if ( d1->processed_rcds.q) pqueue_free(d1->processed_rcds.q); | ||
127 | if ( d1->buffered_messages) pqueue_free(d1->buffered_messages); | ||
128 | if ( d1->sent_messages) pqueue_free(d1->sent_messages); | ||
129 | OPENSSL_free(d1); | ||
130 | return (0); | ||
131 | } | ||
132 | |||
133 | s->d1=d1; | ||
134 | s->method->ssl_clear(s); | ||
135 | return(1); | ||
136 | } | ||
137 | |||
138 | void dtls1_free(SSL *s) | ||
139 | { | ||
140 | pitem *item = NULL; | ||
141 | hm_fragment *frag = NULL; | ||
142 | |||
143 | ssl3_free(s); | ||
144 | |||
145 | while( (item = pqueue_pop(s->d1->unprocessed_rcds.q)) != NULL) | ||
146 | { | ||
147 | OPENSSL_free(item->data); | ||
148 | pitem_free(item); | ||
149 | } | ||
150 | pqueue_free(s->d1->unprocessed_rcds.q); | ||
151 | |||
152 | while( (item = pqueue_pop(s->d1->processed_rcds.q)) != NULL) | ||
153 | { | ||
154 | OPENSSL_free(item->data); | ||
155 | pitem_free(item); | ||
156 | } | ||
157 | pqueue_free(s->d1->processed_rcds.q); | ||
158 | |||
159 | while( (item = pqueue_pop(s->d1->buffered_messages)) != NULL) | ||
160 | { | ||
161 | frag = (hm_fragment *)item->data; | ||
162 | OPENSSL_free(frag->fragment); | ||
163 | OPENSSL_free(frag); | ||
164 | pitem_free(item); | ||
165 | } | ||
166 | pqueue_free(s->d1->buffered_messages); | ||
167 | |||
168 | while ( (item = pqueue_pop(s->d1->sent_messages)) != NULL) | ||
169 | { | ||
170 | frag = (hm_fragment *)item->data; | ||
171 | OPENSSL_free(frag->fragment); | ||
172 | OPENSSL_free(frag); | ||
173 | pitem_free(item); | ||
174 | } | ||
175 | pqueue_free(s->d1->sent_messages); | ||
176 | |||
177 | pq_64bit_free(&(s->d1->bitmap.map)); | ||
178 | pq_64bit_free(&(s->d1->bitmap.max_seq_num)); | ||
179 | |||
180 | pq_64bit_free(&(s->d1->next_bitmap.map)); | ||
181 | pq_64bit_free(&(s->d1->next_bitmap.max_seq_num)); | ||
182 | |||
183 | OPENSSL_free(s->d1); | ||
184 | } | ||
185 | |||
186 | void dtls1_clear(SSL *s) | ||
187 | { | ||
188 | ssl3_clear(s); | ||
189 | s->version=DTLS1_VERSION; | ||
190 | } | ||
191 | |||
192 | /* | ||
193 | * As it's impossible to use stream ciphers in "datagram" mode, this | ||
194 | * simple filter is designed to disengage them in DTLS. Unfortunately | ||
195 | * there is no universal way to identify stream SSL_CIPHER, so we have | ||
196 | * to explicitly list their SSL_* codes. Currently RC4 is the only one | ||
197 | * available, but if new ones emerge, they will have to be added... | ||
198 | */ | ||
199 | SSL_CIPHER *dtls1_get_cipher(unsigned int u) | ||
200 | { | ||
201 | SSL_CIPHER *ciph = ssl3_get_cipher(u); | ||
202 | |||
203 | if (ciph != NULL) | ||
204 | { | ||
205 | if ((ciph->algorithms&SSL_ENC_MASK) == SSL_RC4) | ||
206 | return NULL; | ||
207 | } | ||
208 | |||
209 | return ciph; | ||
210 | } | ||
diff --git a/src/lib/libssl/d1_meth.c b/src/lib/libssl/d1_meth.c new file mode 100644 index 0000000000..8a6cf31947 --- /dev/null +++ b/src/lib/libssl/d1_meth.c | |||
@@ -0,0 +1,77 @@ | |||
1 | /* ssl/d1_meth.h */ | ||
2 | /* | ||
3 | * DTLS implementation written by Nagendra Modadugu | ||
4 | * (nagendra@cs.stanford.edu) for the OpenSSL project 2005. | ||
5 | */ | ||
6 | /* ==================================================================== | ||
7 | * Copyright (c) 1999-2005 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 | * openssl-core@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 | * This product includes cryptographic software written by Eric Young | ||
55 | * (eay@cryptsoft.com). This product includes software written by Tim | ||
56 | * Hudson (tjh@cryptsoft.com). | ||
57 | * | ||
58 | */ | ||
59 | |||
60 | #include <stdio.h> | ||
61 | #include <openssl/objects.h> | ||
62 | #include "ssl_locl.h" | ||
63 | |||
64 | static SSL_METHOD *dtls1_get_method(int ver); | ||
65 | static SSL_METHOD *dtls1_get_method(int ver) | ||
66 | { | ||
67 | if (ver == DTLS1_VERSION) | ||
68 | return(DTLSv1_method()); | ||
69 | else | ||
70 | return(NULL); | ||
71 | } | ||
72 | |||
73 | IMPLEMENT_dtls1_meth_func(DTLSv1_method, | ||
74 | dtls1_accept, | ||
75 | dtls1_connect, | ||
76 | dtls1_get_method) | ||
77 | |||
diff --git a/src/lib/libssl/d1_pkt.c b/src/lib/libssl/d1_pkt.c new file mode 100644 index 0000000000..377696deac --- /dev/null +++ b/src/lib/libssl/d1_pkt.c | |||
@@ -0,0 +1,1778 @@ | |||
1 | /* ssl/d1_pkt.c */ | ||
2 | /* | ||
3 | * DTLS implementation written by Nagendra Modadugu | ||
4 | * (nagendra@cs.stanford.edu) for the OpenSSL project 2005. | ||
5 | */ | ||
6 | /* ==================================================================== | ||
7 | * Copyright (c) 1998-2005 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 | * openssl-core@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 | * This product includes cryptographic software written by Eric Young | ||
55 | * (eay@cryptsoft.com). This product includes software written by Tim | ||
56 | * Hudson (tjh@cryptsoft.com). | ||
57 | * | ||
58 | */ | ||
59 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) | ||
60 | * All rights reserved. | ||
61 | * | ||
62 | * This package is an SSL implementation written | ||
63 | * by Eric Young (eay@cryptsoft.com). | ||
64 | * The implementation was written so as to conform with Netscapes SSL. | ||
65 | * | ||
66 | * This library is free for commercial and non-commercial use as long as | ||
67 | * the following conditions are aheared to. The following conditions | ||
68 | * apply to all code found in this distribution, be it the RC4, RSA, | ||
69 | * lhash, DES, etc., code; not just the SSL code. The SSL documentation | ||
70 | * included with this distribution is covered by the same copyright terms | ||
71 | * except that the holder is Tim Hudson (tjh@cryptsoft.com). | ||
72 | * | ||
73 | * Copyright remains Eric Young's, and as such any Copyright notices in | ||
74 | * the code are not to be removed. | ||
75 | * If this package is used in a product, Eric Young should be given attribution | ||
76 | * as the author of the parts of the library used. | ||
77 | * This can be in the form of a textual message at program startup or | ||
78 | * in documentation (online or textual) provided with the package. | ||
79 | * | ||
80 | * Redistribution and use in source and binary forms, with or without | ||
81 | * modification, are permitted provided that the following conditions | ||
82 | * are met: | ||
83 | * 1. Redistributions of source code must retain the copyright | ||
84 | * notice, this list of conditions and the following disclaimer. | ||
85 | * 2. Redistributions in binary form must reproduce the above copyright | ||
86 | * notice, this list of conditions and the following disclaimer in the | ||
87 | * documentation and/or other materials provided with the distribution. | ||
88 | * 3. All advertising materials mentioning features or use of this software | ||
89 | * must display the following acknowledgement: | ||
90 | * "This product includes cryptographic software written by | ||
91 | * Eric Young (eay@cryptsoft.com)" | ||
92 | * The word 'cryptographic' can be left out if the rouines from the library | ||
93 | * being used are not cryptographic related :-). | ||
94 | * 4. If you include any Windows specific code (or a derivative thereof) from | ||
95 | * the apps directory (application code) you must include an acknowledgement: | ||
96 | * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" | ||
97 | * | ||
98 | * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND | ||
99 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
100 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
101 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | ||
102 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
103 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
104 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
105 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
106 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
107 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
108 | * SUCH DAMAGE. | ||
109 | * | ||
110 | * The licence and distribution terms for any publically available version or | ||
111 | * derivative of this code cannot be changed. i.e. this code cannot simply be | ||
112 | * copied and put under another distribution licence | ||
113 | * [including the GNU Public Licence.] | ||
114 | */ | ||
115 | |||
116 | #include <stdio.h> | ||
117 | #include <errno.h> | ||
118 | #define USE_SOCKETS | ||
119 | #include "ssl_locl.h" | ||
120 | #include <openssl/evp.h> | ||
121 | #include <openssl/buffer.h> | ||
122 | #include <openssl/pqueue.h> | ||
123 | #include <openssl/rand.h> | ||
124 | |||
125 | static int have_handshake_fragment(SSL *s, int type, unsigned char *buf, | ||
126 | int len, int peek); | ||
127 | static int dtls1_record_replay_check(SSL *s, DTLS1_BITMAP *bitmap, | ||
128 | PQ_64BIT *seq_num); | ||
129 | static void dtls1_record_bitmap_update(SSL *s, DTLS1_BITMAP *bitmap); | ||
130 | static DTLS1_BITMAP *dtls1_get_bitmap(SSL *s, SSL3_RECORD *rr, | ||
131 | unsigned int *is_next_epoch); | ||
132 | #if 0 | ||
133 | static int dtls1_record_needs_buffering(SSL *s, SSL3_RECORD *rr, | ||
134 | unsigned short *priority, unsigned long *offset); | ||
135 | #endif | ||
136 | static int dtls1_buffer_record(SSL *s, record_pqueue *q, | ||
137 | PQ_64BIT priority); | ||
138 | static int dtls1_process_record(SSL *s); | ||
139 | #if PQ_64BIT_IS_INTEGER | ||
140 | static PQ_64BIT bytes_to_long_long(unsigned char *bytes, PQ_64BIT *num); | ||
141 | #endif | ||
142 | static void dtls1_clear_timeouts(SSL *s); | ||
143 | |||
144 | /* copy buffered record into SSL structure */ | ||
145 | static int | ||
146 | dtls1_copy_record(SSL *s, pitem *item) | ||
147 | { | ||
148 | DTLS1_RECORD_DATA *rdata; | ||
149 | |||
150 | rdata = (DTLS1_RECORD_DATA *)item->data; | ||
151 | |||
152 | if (s->s3->rbuf.buf != NULL) | ||
153 | OPENSSL_free(s->s3->rbuf.buf); | ||
154 | |||
155 | s->packet = rdata->packet; | ||
156 | s->packet_length = rdata->packet_length; | ||
157 | memcpy(&(s->s3->rbuf), &(rdata->rbuf), sizeof(SSL3_BUFFER)); | ||
158 | memcpy(&(s->s3->rrec), &(rdata->rrec), sizeof(SSL3_RECORD)); | ||
159 | |||
160 | return(1); | ||
161 | } | ||
162 | |||
163 | |||
164 | static int | ||
165 | dtls1_buffer_record(SSL *s, record_pqueue *queue, PQ_64BIT priority) | ||
166 | { | ||
167 | DTLS1_RECORD_DATA *rdata; | ||
168 | pitem *item; | ||
169 | |||
170 | rdata = OPENSSL_malloc(sizeof(DTLS1_RECORD_DATA)); | ||
171 | item = pitem_new(priority, rdata); | ||
172 | if (rdata == NULL || item == NULL) | ||
173 | { | ||
174 | if (rdata != NULL) OPENSSL_free(rdata); | ||
175 | if (item != NULL) pitem_free(item); | ||
176 | |||
177 | SSLerr(SSL_F_DTLS1_BUFFER_RECORD, ERR_R_INTERNAL_ERROR); | ||
178 | return(0); | ||
179 | } | ||
180 | |||
181 | rdata->packet = s->packet; | ||
182 | rdata->packet_length = s->packet_length; | ||
183 | memcpy(&(rdata->rbuf), &(s->s3->rbuf), sizeof(SSL3_BUFFER)); | ||
184 | memcpy(&(rdata->rrec), &(s->s3->rrec), sizeof(SSL3_RECORD)); | ||
185 | |||
186 | item->data = rdata; | ||
187 | |||
188 | /* insert should not fail, since duplicates are dropped */ | ||
189 | if (pqueue_insert(queue->q, item) == NULL) | ||
190 | { | ||
191 | OPENSSL_free(rdata); | ||
192 | pitem_free(item); | ||
193 | return(0); | ||
194 | } | ||
195 | |||
196 | s->packet = NULL; | ||
197 | s->packet_length = 0; | ||
198 | memset(&(s->s3->rbuf), 0, sizeof(SSL3_BUFFER)); | ||
199 | memset(&(s->s3->rrec), 0, sizeof(SSL3_RECORD)); | ||
200 | |||
201 | if (!ssl3_setup_buffers(s)) | ||
202 | { | ||
203 | SSLerr(SSL_F_DTLS1_BUFFER_RECORD, ERR_R_INTERNAL_ERROR); | ||
204 | OPENSSL_free(rdata); | ||
205 | pitem_free(item); | ||
206 | return(0); | ||
207 | } | ||
208 | |||
209 | return(1); | ||
210 | } | ||
211 | |||
212 | |||
213 | static int | ||
214 | dtls1_retrieve_buffered_record(SSL *s, record_pqueue *queue) | ||
215 | { | ||
216 | pitem *item; | ||
217 | |||
218 | item = pqueue_pop(queue->q); | ||
219 | if (item) | ||
220 | { | ||
221 | dtls1_copy_record(s, item); | ||
222 | |||
223 | OPENSSL_free(item->data); | ||
224 | pitem_free(item); | ||
225 | |||
226 | return(1); | ||
227 | } | ||
228 | |||
229 | return(0); | ||
230 | } | ||
231 | |||
232 | |||
233 | /* retrieve a buffered record that belongs to the new epoch, i.e., not processed | ||
234 | * yet */ | ||
235 | #define dtls1_get_unprocessed_record(s) \ | ||
236 | dtls1_retrieve_buffered_record((s), \ | ||
237 | &((s)->d1->unprocessed_rcds)) | ||
238 | |||
239 | /* retrieve a buffered record that belongs to the current epoch, ie, processed */ | ||
240 | #define dtls1_get_processed_record(s) \ | ||
241 | dtls1_retrieve_buffered_record((s), \ | ||
242 | &((s)->d1->processed_rcds)) | ||
243 | |||
244 | static int | ||
245 | dtls1_process_buffered_records(SSL *s) | ||
246 | { | ||
247 | pitem *item; | ||
248 | |||
249 | item = pqueue_peek(s->d1->unprocessed_rcds.q); | ||
250 | if (item) | ||
251 | { | ||
252 | DTLS1_RECORD_DATA *rdata; | ||
253 | rdata = (DTLS1_RECORD_DATA *)item->data; | ||
254 | |||
255 | /* Check if epoch is current. */ | ||
256 | if (s->d1->unprocessed_rcds.epoch != s->d1->r_epoch) | ||
257 | return(1); /* Nothing to do. */ | ||
258 | |||
259 | /* Process all the records. */ | ||
260 | while (pqueue_peek(s->d1->unprocessed_rcds.q)) | ||
261 | { | ||
262 | dtls1_get_unprocessed_record(s); | ||
263 | if ( ! dtls1_process_record(s)) | ||
264 | return(0); | ||
265 | dtls1_buffer_record(s, &(s->d1->processed_rcds), | ||
266 | s->s3->rrec.seq_num); | ||
267 | } | ||
268 | } | ||
269 | |||
270 | /* sync epoch numbers once all the unprocessed records | ||
271 | * have been processed */ | ||
272 | s->d1->processed_rcds.epoch = s->d1->r_epoch; | ||
273 | s->d1->unprocessed_rcds.epoch = s->d1->r_epoch + 1; | ||
274 | |||
275 | return(1); | ||
276 | } | ||
277 | |||
278 | |||
279 | #if 0 | ||
280 | |||
281 | static int | ||
282 | dtls1_get_buffered_record(SSL *s) | ||
283 | { | ||
284 | pitem *item; | ||
285 | PQ_64BIT priority = | ||
286 | (((PQ_64BIT)s->d1->handshake_read_seq) << 32) | | ||
287 | ((PQ_64BIT)s->d1->r_msg_hdr.frag_off); | ||
288 | |||
289 | if ( ! SSL_in_init(s)) /* if we're not (re)negotiating, | ||
290 | nothing buffered */ | ||
291 | return 0; | ||
292 | |||
293 | |||
294 | item = pqueue_peek(s->d1->rcvd_records); | ||
295 | if (item && item->priority == priority) | ||
296 | { | ||
297 | /* Check if we've received the record of interest. It must be | ||
298 | * a handshake record, since data records as passed up without | ||
299 | * buffering */ | ||
300 | DTLS1_RECORD_DATA *rdata; | ||
301 | item = pqueue_pop(s->d1->rcvd_records); | ||
302 | rdata = (DTLS1_RECORD_DATA *)item->data; | ||
303 | |||
304 | if (s->s3->rbuf.buf != NULL) | ||
305 | OPENSSL_free(s->s3->rbuf.buf); | ||
306 | |||
307 | s->packet = rdata->packet; | ||
308 | s->packet_length = rdata->packet_length; | ||
309 | memcpy(&(s->s3->rbuf), &(rdata->rbuf), sizeof(SSL3_BUFFER)); | ||
310 | memcpy(&(s->s3->rrec), &(rdata->rrec), sizeof(SSL3_RECORD)); | ||
311 | |||
312 | OPENSSL_free(item->data); | ||
313 | pitem_free(item); | ||
314 | |||
315 | /* s->d1->next_expected_seq_num++; */ | ||
316 | return(1); | ||
317 | } | ||
318 | |||
319 | return 0; | ||
320 | } | ||
321 | |||
322 | #endif | ||
323 | |||
324 | static int | ||
325 | dtls1_process_record(SSL *s) | ||
326 | { | ||
327 | int i,al; | ||
328 | int clear=0; | ||
329 | int enc_err; | ||
330 | SSL_SESSION *sess; | ||
331 | SSL3_RECORD *rr; | ||
332 | unsigned int mac_size; | ||
333 | unsigned char md[EVP_MAX_MD_SIZE]; | ||
334 | |||
335 | |||
336 | rr= &(s->s3->rrec); | ||
337 | sess = s->session; | ||
338 | |||
339 | /* At this point, s->packet_length == SSL3_RT_HEADER_LNGTH + rr->length, | ||
340 | * and we have that many bytes in s->packet | ||
341 | */ | ||
342 | rr->input= &(s->packet[DTLS1_RT_HEADER_LENGTH]); | ||
343 | |||
344 | /* ok, we can now read from 's->packet' data into 'rr' | ||
345 | * rr->input points at rr->length bytes, which | ||
346 | * need to be copied into rr->data by either | ||
347 | * the decryption or by the decompression | ||
348 | * When the data is 'copied' into the rr->data buffer, | ||
349 | * rr->input will be pointed at the new buffer */ | ||
350 | |||
351 | /* We now have - encrypted [ MAC [ compressed [ plain ] ] ] | ||
352 | * rr->length bytes of encrypted compressed stuff. */ | ||
353 | |||
354 | /* check is not needed I believe */ | ||
355 | if (rr->length > SSL3_RT_MAX_ENCRYPTED_LENGTH) | ||
356 | { | ||
357 | al=SSL_AD_RECORD_OVERFLOW; | ||
358 | SSLerr(SSL_F_DTLS1_PROCESS_RECORD,SSL_R_ENCRYPTED_LENGTH_TOO_LONG); | ||
359 | goto f_err; | ||
360 | } | ||
361 | |||
362 | /* decrypt in place in 'rr->input' */ | ||
363 | rr->data=rr->input; | ||
364 | |||
365 | enc_err = s->method->ssl3_enc->enc(s,0); | ||
366 | if (enc_err <= 0) | ||
367 | { | ||
368 | if (enc_err == 0) | ||
369 | /* SSLerr() and ssl3_send_alert() have been called */ | ||
370 | goto err; | ||
371 | |||
372 | /* otherwise enc_err == -1 */ | ||
373 | goto decryption_failed_or_bad_record_mac; | ||
374 | } | ||
375 | |||
376 | #ifdef TLS_DEBUG | ||
377 | printf("dec %d\n",rr->length); | ||
378 | { unsigned int z; for (z=0; z<rr->length; z++) printf("%02X%c",rr->data[z],((z+1)%16)?' ':'\n'); } | ||
379 | printf("\n"); | ||
380 | #endif | ||
381 | |||
382 | /* r->length is now the compressed data plus mac */ | ||
383 | if ( (sess == NULL) || | ||
384 | (s->enc_read_ctx == NULL) || | ||
385 | (s->read_hash == NULL)) | ||
386 | clear=1; | ||
387 | |||
388 | if (!clear) | ||
389 | { | ||
390 | mac_size=EVP_MD_size(s->read_hash); | ||
391 | |||
392 | if (rr->length > SSL3_RT_MAX_COMPRESSED_LENGTH+mac_size) | ||
393 | { | ||
394 | #if 0 /* OK only for stream ciphers (then rr->length is visible from ciphertext anyway) */ | ||
395 | al=SSL_AD_RECORD_OVERFLOW; | ||
396 | SSLerr(SSL_F_DTLS1_PROCESS_RECORD,SSL_R_PRE_MAC_LENGTH_TOO_LONG); | ||
397 | goto f_err; | ||
398 | #else | ||
399 | goto decryption_failed_or_bad_record_mac; | ||
400 | #endif | ||
401 | } | ||
402 | /* check the MAC for rr->input (it's in mac_size bytes at the tail) */ | ||
403 | if (rr->length < mac_size) | ||
404 | { | ||
405 | #if 0 /* OK only for stream ciphers */ | ||
406 | al=SSL_AD_DECODE_ERROR; | ||
407 | SSLerr(SSL_F_DTLS1_PROCESS_RECORD,SSL_R_LENGTH_TOO_SHORT); | ||
408 | goto f_err; | ||
409 | #else | ||
410 | goto decryption_failed_or_bad_record_mac; | ||
411 | #endif | ||
412 | } | ||
413 | rr->length-=mac_size; | ||
414 | i=s->method->ssl3_enc->mac(s,md,0); | ||
415 | if (memcmp(md,&(rr->data[rr->length]),mac_size) != 0) | ||
416 | { | ||
417 | goto decryption_failed_or_bad_record_mac; | ||
418 | } | ||
419 | } | ||
420 | |||
421 | /* r->length is now just compressed */ | ||
422 | if (s->expand != NULL) | ||
423 | { | ||
424 | if (rr->length > SSL3_RT_MAX_COMPRESSED_LENGTH) | ||
425 | { | ||
426 | al=SSL_AD_RECORD_OVERFLOW; | ||
427 | SSLerr(SSL_F_DTLS1_PROCESS_RECORD,SSL_R_COMPRESSED_LENGTH_TOO_LONG); | ||
428 | goto f_err; | ||
429 | } | ||
430 | if (!ssl3_do_uncompress(s)) | ||
431 | { | ||
432 | al=SSL_AD_DECOMPRESSION_FAILURE; | ||
433 | SSLerr(SSL_F_DTLS1_PROCESS_RECORD,SSL_R_BAD_DECOMPRESSION); | ||
434 | goto f_err; | ||
435 | } | ||
436 | } | ||
437 | |||
438 | if (rr->length > SSL3_RT_MAX_PLAIN_LENGTH) | ||
439 | { | ||
440 | al=SSL_AD_RECORD_OVERFLOW; | ||
441 | SSLerr(SSL_F_DTLS1_PROCESS_RECORD,SSL_R_DATA_LENGTH_TOO_LONG); | ||
442 | goto f_err; | ||
443 | } | ||
444 | |||
445 | rr->off=0; | ||
446 | /* So at this point the following is true | ||
447 | * ssl->s3->rrec.type is the type of record | ||
448 | * ssl->s3->rrec.length == number of bytes in record | ||
449 | * ssl->s3->rrec.off == offset to first valid byte | ||
450 | * ssl->s3->rrec.data == where to take bytes from, increment | ||
451 | * after use :-). | ||
452 | */ | ||
453 | |||
454 | /* we have pulled in a full packet so zero things */ | ||
455 | s->packet_length=0; | ||
456 | dtls1_record_bitmap_update(s, &(s->d1->bitmap));/* Mark receipt of record. */ | ||
457 | return(1); | ||
458 | |||
459 | decryption_failed_or_bad_record_mac: | ||
460 | /* Separate 'decryption_failed' alert was introduced with TLS 1.0, | ||
461 | * SSL 3.0 only has 'bad_record_mac'. But unless a decryption | ||
462 | * failure is directly visible from the ciphertext anyway, | ||
463 | * we should not reveal which kind of error occured -- this | ||
464 | * might become visible to an attacker (e.g. via logfile) */ | ||
465 | al=SSL_AD_BAD_RECORD_MAC; | ||
466 | SSLerr(SSL_F_DTLS1_PROCESS_RECORD,SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC); | ||
467 | f_err: | ||
468 | ssl3_send_alert(s,SSL3_AL_FATAL,al); | ||
469 | err: | ||
470 | return(0); | ||
471 | } | ||
472 | |||
473 | |||
474 | /* Call this to get a new input record. | ||
475 | * It will return <= 0 if more data is needed, normally due to an error | ||
476 | * or non-blocking IO. | ||
477 | * When it finishes, one packet has been decoded and can be found in | ||
478 | * ssl->s3->rrec.type - is the type of record | ||
479 | * ssl->s3->rrec.data, - data | ||
480 | * ssl->s3->rrec.length, - number of bytes | ||
481 | */ | ||
482 | /* used only by dtls1_read_bytes */ | ||
483 | int dtls1_get_record(SSL *s) | ||
484 | { | ||
485 | int ssl_major,ssl_minor,al; | ||
486 | int i,n; | ||
487 | SSL3_RECORD *rr; | ||
488 | SSL_SESSION *sess; | ||
489 | unsigned char *p; | ||
490 | unsigned short version; | ||
491 | DTLS1_BITMAP *bitmap; | ||
492 | unsigned int is_next_epoch; | ||
493 | |||
494 | rr= &(s->s3->rrec); | ||
495 | sess=s->session; | ||
496 | |||
497 | /* The epoch may have changed. If so, process all the | ||
498 | * pending records. This is a non-blocking operation. */ | ||
499 | if ( ! dtls1_process_buffered_records(s)) | ||
500 | return 0; | ||
501 | |||
502 | /* if we're renegotiating, then there may be buffered records */ | ||
503 | if (dtls1_get_processed_record(s)) | ||
504 | return 1; | ||
505 | |||
506 | /* get something from the wire */ | ||
507 | again: | ||
508 | /* check if we have the header */ | ||
509 | if ( (s->rstate != SSL_ST_READ_BODY) || | ||
510 | (s->packet_length < DTLS1_RT_HEADER_LENGTH)) | ||
511 | { | ||
512 | n=ssl3_read_n(s, DTLS1_RT_HEADER_LENGTH, s->s3->rbuf.len, 0); | ||
513 | /* read timeout is handled by dtls1_read_bytes */ | ||
514 | if (n <= 0) return(n); /* error or non-blocking */ | ||
515 | |||
516 | OPENSSL_assert(s->packet_length == DTLS1_RT_HEADER_LENGTH); | ||
517 | |||
518 | s->rstate=SSL_ST_READ_BODY; | ||
519 | |||
520 | p=s->packet; | ||
521 | |||
522 | /* Pull apart the header into the DTLS1_RECORD */ | ||
523 | rr->type= *(p++); | ||
524 | ssl_major= *(p++); | ||
525 | ssl_minor= *(p++); | ||
526 | version=(ssl_major<<8)|ssl_minor; | ||
527 | |||
528 | /* sequence number is 64 bits, with top 2 bytes = epoch */ | ||
529 | n2s(p,rr->epoch); | ||
530 | |||
531 | memcpy(&(s->s3->read_sequence[2]), p, 6); | ||
532 | p+=6; | ||
533 | |||
534 | n2s(p,rr->length); | ||
535 | |||
536 | /* Lets check version */ | ||
537 | if (!s->first_packet) | ||
538 | { | ||
539 | if (version != s->version && version != DTLS1_BAD_VER) | ||
540 | { | ||
541 | SSLerr(SSL_F_DTLS1_GET_RECORD,SSL_R_WRONG_VERSION_NUMBER); | ||
542 | /* Send back error using their | ||
543 | * version number :-) */ | ||
544 | s->version=version; | ||
545 | al=SSL_AD_PROTOCOL_VERSION; | ||
546 | goto f_err; | ||
547 | } | ||
548 | } | ||
549 | |||
550 | if ((version & 0xff00) != (DTLS1_VERSION & 0xff00) && | ||
551 | (version & 0xff00) != (DTLS1_BAD_VER & 0xff00)) | ||
552 | { | ||
553 | SSLerr(SSL_F_DTLS1_GET_RECORD,SSL_R_WRONG_VERSION_NUMBER); | ||
554 | goto err; | ||
555 | } | ||
556 | |||
557 | if (rr->length > SSL3_RT_MAX_ENCRYPTED_LENGTH) | ||
558 | { | ||
559 | al=SSL_AD_RECORD_OVERFLOW; | ||
560 | SSLerr(SSL_F_DTLS1_GET_RECORD,SSL_R_PACKET_LENGTH_TOO_LONG); | ||
561 | goto f_err; | ||
562 | } | ||
563 | |||
564 | s->client_version = version; | ||
565 | /* now s->rstate == SSL_ST_READ_BODY */ | ||
566 | } | ||
567 | |||
568 | /* s->rstate == SSL_ST_READ_BODY, get and decode the data */ | ||
569 | |||
570 | if (rr->length > s->packet_length-DTLS1_RT_HEADER_LENGTH) | ||
571 | { | ||
572 | /* now s->packet_length == DTLS1_RT_HEADER_LENGTH */ | ||
573 | i=rr->length; | ||
574 | n=ssl3_read_n(s,i,i,1); | ||
575 | if (n <= 0) return(n); /* error or non-blocking io */ | ||
576 | |||
577 | /* this packet contained a partial record, dump it */ | ||
578 | if ( n != i) | ||
579 | { | ||
580 | s->packet_length = 0; | ||
581 | goto again; | ||
582 | } | ||
583 | |||
584 | /* now n == rr->length, | ||
585 | * and s->packet_length == DTLS1_RT_HEADER_LENGTH + rr->length */ | ||
586 | } | ||
587 | s->rstate=SSL_ST_READ_HEADER; /* set state for later operations */ | ||
588 | |||
589 | /* match epochs. NULL means the packet is dropped on the floor */ | ||
590 | bitmap = dtls1_get_bitmap(s, rr, &is_next_epoch); | ||
591 | if ( bitmap == NULL) | ||
592 | { | ||
593 | s->packet_length = 0; /* dump this record */ | ||
594 | goto again; /* get another record */ | ||
595 | } | ||
596 | |||
597 | /* check whether this is a repeat, or aged record */ | ||
598 | if ( ! dtls1_record_replay_check(s, bitmap, &(rr->seq_num))) | ||
599 | { | ||
600 | s->packet_length=0; /* dump this record */ | ||
601 | goto again; /* get another record */ | ||
602 | } | ||
603 | |||
604 | /* just read a 0 length packet */ | ||
605 | if (rr->length == 0) goto again; | ||
606 | |||
607 | /* If this record is from the next epoch (either HM or ALERT), buffer it | ||
608 | * since it cannot be processed at this time. | ||
609 | * Records from the next epoch are marked as received even though they are | ||
610 | * not processed, so as to prevent any potential resource DoS attack */ | ||
611 | if (is_next_epoch) | ||
612 | { | ||
613 | dtls1_record_bitmap_update(s, bitmap); | ||
614 | dtls1_buffer_record(s, &(s->d1->unprocessed_rcds), rr->seq_num); | ||
615 | s->packet_length = 0; | ||
616 | goto again; | ||
617 | } | ||
618 | |||
619 | if ( ! dtls1_process_record(s)) | ||
620 | return(0); | ||
621 | |||
622 | dtls1_clear_timeouts(s); /* done waiting */ | ||
623 | return(1); | ||
624 | |||
625 | f_err: | ||
626 | ssl3_send_alert(s,SSL3_AL_FATAL,al); | ||
627 | err: | ||
628 | return(0); | ||
629 | } | ||
630 | |||
631 | /* Return up to 'len' payload bytes received in 'type' records. | ||
632 | * 'type' is one of the following: | ||
633 | * | ||
634 | * - SSL3_RT_HANDSHAKE (when ssl3_get_message calls us) | ||
635 | * - SSL3_RT_APPLICATION_DATA (when ssl3_read calls us) | ||
636 | * - 0 (during a shutdown, no data has to be returned) | ||
637 | * | ||
638 | * If we don't have stored data to work from, read a SSL/TLS record first | ||
639 | * (possibly multiple records if we still don't have anything to return). | ||
640 | * | ||
641 | * This function must handle any surprises the peer may have for us, such as | ||
642 | * Alert records (e.g. close_notify), ChangeCipherSpec records (not really | ||
643 | * a surprise, but handled as if it were), or renegotiation requests. | ||
644 | * Also if record payloads contain fragments too small to process, we store | ||
645 | * them until there is enough for the respective protocol (the record protocol | ||
646 | * may use arbitrary fragmentation and even interleaving): | ||
647 | * Change cipher spec protocol | ||
648 | * just 1 byte needed, no need for keeping anything stored | ||
649 | * Alert protocol | ||
650 | * 2 bytes needed (AlertLevel, AlertDescription) | ||
651 | * Handshake protocol | ||
652 | * 4 bytes needed (HandshakeType, uint24 length) -- we just have | ||
653 | * to detect unexpected Client Hello and Hello Request messages | ||
654 | * here, anything else is handled by higher layers | ||
655 | * Application data protocol | ||
656 | * none of our business | ||
657 | */ | ||
658 | int dtls1_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek) | ||
659 | { | ||
660 | int al,i,j,ret; | ||
661 | unsigned int n; | ||
662 | SSL3_RECORD *rr; | ||
663 | void (*cb)(const SSL *ssl,int type2,int val)=NULL; | ||
664 | |||
665 | if (s->s3->rbuf.buf == NULL) /* Not initialized yet */ | ||
666 | if (!ssl3_setup_buffers(s)) | ||
667 | return(-1); | ||
668 | |||
669 | /* XXX: check what the second '&& type' is about */ | ||
670 | if ((type && (type != SSL3_RT_APPLICATION_DATA) && | ||
671 | (type != SSL3_RT_HANDSHAKE) && type) || | ||
672 | (peek && (type != SSL3_RT_APPLICATION_DATA))) | ||
673 | { | ||
674 | SSLerr(SSL_F_DTLS1_READ_BYTES, ERR_R_INTERNAL_ERROR); | ||
675 | return -1; | ||
676 | } | ||
677 | |||
678 | /* check whether there's a handshake message (client hello?) waiting */ | ||
679 | if ( (ret = have_handshake_fragment(s, type, buf, len, peek))) | ||
680 | return ret; | ||
681 | |||
682 | /* Now s->d1->handshake_fragment_len == 0 if type == SSL3_RT_HANDSHAKE. */ | ||
683 | |||
684 | if (!s->in_handshake && SSL_in_init(s)) | ||
685 | { | ||
686 | /* type == SSL3_RT_APPLICATION_DATA */ | ||
687 | i=s->handshake_func(s); | ||
688 | if (i < 0) return(i); | ||
689 | if (i == 0) | ||
690 | { | ||
691 | SSLerr(SSL_F_DTLS1_READ_BYTES,SSL_R_SSL_HANDSHAKE_FAILURE); | ||
692 | return(-1); | ||
693 | } | ||
694 | } | ||
695 | |||
696 | start: | ||
697 | s->rwstate=SSL_NOTHING; | ||
698 | |||
699 | /* s->s3->rrec.type - is the type of record | ||
700 | * s->s3->rrec.data, - data | ||
701 | * s->s3->rrec.off, - offset into 'data' for next read | ||
702 | * s->s3->rrec.length, - number of bytes. */ | ||
703 | rr = &(s->s3->rrec); | ||
704 | |||
705 | /* get new packet if necessary */ | ||
706 | if ((rr->length == 0) || (s->rstate == SSL_ST_READ_BODY)) | ||
707 | { | ||
708 | ret=dtls1_get_record(s); | ||
709 | if (ret <= 0) | ||
710 | { | ||
711 | ret = dtls1_read_failed(s, ret); | ||
712 | /* anything other than a timeout is an error */ | ||
713 | if (ret <= 0) | ||
714 | return(ret); | ||
715 | else | ||
716 | goto start; | ||
717 | } | ||
718 | } | ||
719 | |||
720 | /* we now have a packet which can be read and processed */ | ||
721 | |||
722 | if (s->s3->change_cipher_spec /* set when we receive ChangeCipherSpec, | ||
723 | * reset by ssl3_get_finished */ | ||
724 | && (rr->type != SSL3_RT_HANDSHAKE)) | ||
725 | { | ||
726 | al=SSL_AD_UNEXPECTED_MESSAGE; | ||
727 | SSLerr(SSL_F_DTLS1_READ_BYTES,SSL_R_DATA_BETWEEN_CCS_AND_FINISHED); | ||
728 | goto err; | ||
729 | } | ||
730 | |||
731 | /* If the other end has shut down, throw anything we read away | ||
732 | * (even in 'peek' mode) */ | ||
733 | if (s->shutdown & SSL_RECEIVED_SHUTDOWN) | ||
734 | { | ||
735 | rr->length=0; | ||
736 | s->rwstate=SSL_NOTHING; | ||
737 | return(0); | ||
738 | } | ||
739 | |||
740 | |||
741 | if (type == rr->type) /* SSL3_RT_APPLICATION_DATA or SSL3_RT_HANDSHAKE */ | ||
742 | { | ||
743 | /* make sure that we are not getting application data when we | ||
744 | * are doing a handshake for the first time */ | ||
745 | if (SSL_in_init(s) && (type == SSL3_RT_APPLICATION_DATA) && | ||
746 | (s->enc_read_ctx == NULL)) | ||
747 | { | ||
748 | al=SSL_AD_UNEXPECTED_MESSAGE; | ||
749 | SSLerr(SSL_F_DTLS1_READ_BYTES,SSL_R_APP_DATA_IN_HANDSHAKE); | ||
750 | goto f_err; | ||
751 | } | ||
752 | |||
753 | if (len <= 0) return(len); | ||
754 | |||
755 | if ((unsigned int)len > rr->length) | ||
756 | n = rr->length; | ||
757 | else | ||
758 | n = (unsigned int)len; | ||
759 | |||
760 | memcpy(buf,&(rr->data[rr->off]),n); | ||
761 | if (!peek) | ||
762 | { | ||
763 | rr->length-=n; | ||
764 | rr->off+=n; | ||
765 | if (rr->length == 0) | ||
766 | { | ||
767 | s->rstate=SSL_ST_READ_HEADER; | ||
768 | rr->off=0; | ||
769 | } | ||
770 | } | ||
771 | return(n); | ||
772 | } | ||
773 | |||
774 | |||
775 | /* If we get here, then type != rr->type; if we have a handshake | ||
776 | * message, then it was unexpected (Hello Request or Client Hello). */ | ||
777 | |||
778 | /* In case of record types for which we have 'fragment' storage, | ||
779 | * fill that so that we can process the data at a fixed place. | ||
780 | */ | ||
781 | { | ||
782 | unsigned int k, dest_maxlen = 0; | ||
783 | unsigned char *dest = NULL; | ||
784 | unsigned int *dest_len = NULL; | ||
785 | |||
786 | if (rr->type == SSL3_RT_HANDSHAKE) | ||
787 | { | ||
788 | dest_maxlen = sizeof s->d1->handshake_fragment; | ||
789 | dest = s->d1->handshake_fragment; | ||
790 | dest_len = &s->d1->handshake_fragment_len; | ||
791 | } | ||
792 | else if (rr->type == SSL3_RT_ALERT) | ||
793 | { | ||
794 | dest_maxlen = sizeof(s->d1->alert_fragment); | ||
795 | dest = s->d1->alert_fragment; | ||
796 | dest_len = &s->d1->alert_fragment_len; | ||
797 | } | ||
798 | /* else it's a CCS message, or it's wrong */ | ||
799 | else if (rr->type != SSL3_RT_CHANGE_CIPHER_SPEC) | ||
800 | { | ||
801 | /* Not certain if this is the right error handling */ | ||
802 | al=SSL_AD_UNEXPECTED_MESSAGE; | ||
803 | SSLerr(SSL_F_DTLS1_READ_BYTES,SSL_R_UNEXPECTED_RECORD); | ||
804 | goto f_err; | ||
805 | } | ||
806 | |||
807 | |||
808 | if (dest_maxlen > 0) | ||
809 | { | ||
810 | /* XDTLS: In a pathalogical case, the Client Hello | ||
811 | * may be fragmented--don't always expect dest_maxlen bytes */ | ||
812 | if ( rr->length < dest_maxlen) | ||
813 | { | ||
814 | s->rstate=SSL_ST_READ_HEADER; | ||
815 | rr->length = 0; | ||
816 | goto start; | ||
817 | } | ||
818 | |||
819 | /* now move 'n' bytes: */ | ||
820 | for ( k = 0; k < dest_maxlen; k++) | ||
821 | { | ||
822 | dest[k] = rr->data[rr->off++]; | ||
823 | rr->length--; | ||
824 | } | ||
825 | *dest_len = dest_maxlen; | ||
826 | } | ||
827 | } | ||
828 | |||
829 | /* s->d1->handshake_fragment_len == 12 iff rr->type == SSL3_RT_HANDSHAKE; | ||
830 | * s->d1->alert_fragment_len == 7 iff rr->type == SSL3_RT_ALERT. | ||
831 | * (Possibly rr is 'empty' now, i.e. rr->length may be 0.) */ | ||
832 | |||
833 | /* If we are a client, check for an incoming 'Hello Request': */ | ||
834 | if ((!s->server) && | ||
835 | (s->d1->handshake_fragment_len >= DTLS1_HM_HEADER_LENGTH) && | ||
836 | (s->d1->handshake_fragment[0] == SSL3_MT_HELLO_REQUEST) && | ||
837 | (s->session != NULL) && (s->session->cipher != NULL)) | ||
838 | { | ||
839 | s->d1->handshake_fragment_len = 0; | ||
840 | |||
841 | if ((s->d1->handshake_fragment[1] != 0) || | ||
842 | (s->d1->handshake_fragment[2] != 0) || | ||
843 | (s->d1->handshake_fragment[3] != 0)) | ||
844 | { | ||
845 | al=SSL_AD_DECODE_ERROR; | ||
846 | SSLerr(SSL_F_DTLS1_READ_BYTES,SSL_R_BAD_HELLO_REQUEST); | ||
847 | goto err; | ||
848 | } | ||
849 | |||
850 | /* no need to check sequence number on HELLO REQUEST messages */ | ||
851 | |||
852 | if (s->msg_callback) | ||
853 | s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE, | ||
854 | s->d1->handshake_fragment, 4, s, s->msg_callback_arg); | ||
855 | |||
856 | if (SSL_is_init_finished(s) && | ||
857 | !(s->s3->flags & SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS) && | ||
858 | !s->s3->renegotiate) | ||
859 | { | ||
860 | ssl3_renegotiate(s); | ||
861 | if (ssl3_renegotiate_check(s)) | ||
862 | { | ||
863 | i=s->handshake_func(s); | ||
864 | if (i < 0) return(i); | ||
865 | if (i == 0) | ||
866 | { | ||
867 | SSLerr(SSL_F_DTLS1_READ_BYTES,SSL_R_SSL_HANDSHAKE_FAILURE); | ||
868 | return(-1); | ||
869 | } | ||
870 | |||
871 | if (!(s->mode & SSL_MODE_AUTO_RETRY)) | ||
872 | { | ||
873 | if (s->s3->rbuf.left == 0) /* no read-ahead left? */ | ||
874 | { | ||
875 | BIO *bio; | ||
876 | /* In the case where we try to read application data, | ||
877 | * but we trigger an SSL handshake, we return -1 with | ||
878 | * the retry option set. Otherwise renegotiation may | ||
879 | * cause nasty problems in the blocking world */ | ||
880 | s->rwstate=SSL_READING; | ||
881 | bio=SSL_get_rbio(s); | ||
882 | BIO_clear_retry_flags(bio); | ||
883 | BIO_set_retry_read(bio); | ||
884 | return(-1); | ||
885 | } | ||
886 | } | ||
887 | } | ||
888 | } | ||
889 | /* we either finished a handshake or ignored the request, | ||
890 | * now try again to obtain the (application) data we were asked for */ | ||
891 | goto start; | ||
892 | } | ||
893 | |||
894 | if (s->d1->alert_fragment_len >= DTLS1_AL_HEADER_LENGTH) | ||
895 | { | ||
896 | int alert_level = s->d1->alert_fragment[0]; | ||
897 | int alert_descr = s->d1->alert_fragment[1]; | ||
898 | |||
899 | s->d1->alert_fragment_len = 0; | ||
900 | |||
901 | if (s->msg_callback) | ||
902 | s->msg_callback(0, s->version, SSL3_RT_ALERT, | ||
903 | s->d1->alert_fragment, 2, s, s->msg_callback_arg); | ||
904 | |||
905 | if (s->info_callback != NULL) | ||
906 | cb=s->info_callback; | ||
907 | else if (s->ctx->info_callback != NULL) | ||
908 | cb=s->ctx->info_callback; | ||
909 | |||
910 | if (cb != NULL) | ||
911 | { | ||
912 | j = (alert_level << 8) | alert_descr; | ||
913 | cb(s, SSL_CB_READ_ALERT, j); | ||
914 | } | ||
915 | |||
916 | if (alert_level == 1) /* warning */ | ||
917 | { | ||
918 | s->s3->warn_alert = alert_descr; | ||
919 | if (alert_descr == SSL_AD_CLOSE_NOTIFY) | ||
920 | { | ||
921 | s->shutdown |= SSL_RECEIVED_SHUTDOWN; | ||
922 | return(0); | ||
923 | } | ||
924 | #if 0 | ||
925 | /* XXX: this is a possible improvement in the future */ | ||
926 | /* now check if it's a missing record */ | ||
927 | if (alert_descr == DTLS1_AD_MISSING_HANDSHAKE_MESSAGE) | ||
928 | { | ||
929 | unsigned short seq; | ||
930 | unsigned int frag_off; | ||
931 | unsigned char *p = &(s->d1->alert_fragment[2]); | ||
932 | |||
933 | n2s(p, seq); | ||
934 | n2l3(p, frag_off); | ||
935 | |||
936 | dtls1_retransmit_message(s, seq, frag_off, &found); | ||
937 | if ( ! found && SSL_in_init(s)) | ||
938 | { | ||
939 | /* fprintf( stderr,"in init = %d\n", SSL_in_init(s)); */ | ||
940 | /* requested a message not yet sent, | ||
941 | send an alert ourselves */ | ||
942 | ssl3_send_alert(s,SSL3_AL_WARNING, | ||
943 | DTLS1_AD_MISSING_HANDSHAKE_MESSAGE); | ||
944 | } | ||
945 | } | ||
946 | #endif | ||
947 | } | ||
948 | else if (alert_level == 2) /* fatal */ | ||
949 | { | ||
950 | char tmp[16]; | ||
951 | |||
952 | s->rwstate=SSL_NOTHING; | ||
953 | s->s3->fatal_alert = alert_descr; | ||
954 | SSLerr(SSL_F_DTLS1_READ_BYTES, SSL_AD_REASON_OFFSET + alert_descr); | ||
955 | BIO_snprintf(tmp,sizeof tmp,"%d",alert_descr); | ||
956 | ERR_add_error_data(2,"SSL alert number ",tmp); | ||
957 | s->shutdown|=SSL_RECEIVED_SHUTDOWN; | ||
958 | SSL_CTX_remove_session(s->ctx,s->session); | ||
959 | return(0); | ||
960 | } | ||
961 | else | ||
962 | { | ||
963 | al=SSL_AD_ILLEGAL_PARAMETER; | ||
964 | SSLerr(SSL_F_DTLS1_READ_BYTES,SSL_R_UNKNOWN_ALERT_TYPE); | ||
965 | goto f_err; | ||
966 | } | ||
967 | |||
968 | goto start; | ||
969 | } | ||
970 | |||
971 | if (s->shutdown & SSL_SENT_SHUTDOWN) /* but we have not received a shutdown */ | ||
972 | { | ||
973 | s->rwstate=SSL_NOTHING; | ||
974 | rr->length=0; | ||
975 | return(0); | ||
976 | } | ||
977 | |||
978 | if (rr->type == SSL3_RT_CHANGE_CIPHER_SPEC) | ||
979 | { | ||
980 | struct ccs_header_st ccs_hdr; | ||
981 | |||
982 | dtls1_get_ccs_header(rr->data, &ccs_hdr); | ||
983 | |||
984 | /* 'Change Cipher Spec' is just a single byte, so we know | ||
985 | * exactly what the record payload has to look like */ | ||
986 | /* XDTLS: check that epoch is consistent */ | ||
987 | if ( (s->client_version == DTLS1_BAD_VER && rr->length != 3) || | ||
988 | (s->client_version != DTLS1_BAD_VER && rr->length != DTLS1_CCS_HEADER_LENGTH) || | ||
989 | (rr->off != 0) || (rr->data[0] != SSL3_MT_CCS)) | ||
990 | { | ||
991 | i=SSL_AD_ILLEGAL_PARAMETER; | ||
992 | SSLerr(SSL_F_DTLS1_READ_BYTES,SSL_R_BAD_CHANGE_CIPHER_SPEC); | ||
993 | goto err; | ||
994 | } | ||
995 | |||
996 | rr->length=0; | ||
997 | |||
998 | if (s->msg_callback) | ||
999 | s->msg_callback(0, s->version, SSL3_RT_CHANGE_CIPHER_SPEC, | ||
1000 | rr->data, 1, s, s->msg_callback_arg); | ||
1001 | |||
1002 | s->s3->change_cipher_spec=1; | ||
1003 | if (!ssl3_do_change_cipher_spec(s)) | ||
1004 | goto err; | ||
1005 | |||
1006 | /* do this whenever CCS is processed */ | ||
1007 | dtls1_reset_seq_numbers(s, SSL3_CC_READ); | ||
1008 | |||
1009 | if (s->client_version == DTLS1_BAD_VER) | ||
1010 | s->d1->handshake_read_seq++; | ||
1011 | |||
1012 | goto start; | ||
1013 | } | ||
1014 | |||
1015 | /* Unexpected handshake message (Client Hello, or protocol violation) */ | ||
1016 | if ((s->d1->handshake_fragment_len >= DTLS1_HM_HEADER_LENGTH) && | ||
1017 | !s->in_handshake) | ||
1018 | { | ||
1019 | struct hm_header_st msg_hdr; | ||
1020 | |||
1021 | /* this may just be a stale retransmit */ | ||
1022 | dtls1_get_message_header(rr->data, &msg_hdr); | ||
1023 | if( rr->epoch != s->d1->r_epoch) | ||
1024 | { | ||
1025 | rr->length = 0; | ||
1026 | goto start; | ||
1027 | } | ||
1028 | |||
1029 | if (((s->state&SSL_ST_MASK) == SSL_ST_OK) && | ||
1030 | !(s->s3->flags & SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS)) | ||
1031 | { | ||
1032 | #if 0 /* worked only because C operator preferences are not as expected (and | ||
1033 | * because this is not really needed for clients except for detecting | ||
1034 | * protocol violations): */ | ||
1035 | s->state=SSL_ST_BEFORE|(s->server) | ||
1036 | ?SSL_ST_ACCEPT | ||
1037 | :SSL_ST_CONNECT; | ||
1038 | #else | ||
1039 | s->state = s->server ? SSL_ST_ACCEPT : SSL_ST_CONNECT; | ||
1040 | #endif | ||
1041 | s->new_session=1; | ||
1042 | } | ||
1043 | i=s->handshake_func(s); | ||
1044 | if (i < 0) return(i); | ||
1045 | if (i == 0) | ||
1046 | { | ||
1047 | SSLerr(SSL_F_DTLS1_READ_BYTES,SSL_R_SSL_HANDSHAKE_FAILURE); | ||
1048 | return(-1); | ||
1049 | } | ||
1050 | |||
1051 | if (!(s->mode & SSL_MODE_AUTO_RETRY)) | ||
1052 | { | ||
1053 | if (s->s3->rbuf.left == 0) /* no read-ahead left? */ | ||
1054 | { | ||
1055 | BIO *bio; | ||
1056 | /* In the case where we try to read application data, | ||
1057 | * but we trigger an SSL handshake, we return -1 with | ||
1058 | * the retry option set. Otherwise renegotiation may | ||
1059 | * cause nasty problems in the blocking world */ | ||
1060 | s->rwstate=SSL_READING; | ||
1061 | bio=SSL_get_rbio(s); | ||
1062 | BIO_clear_retry_flags(bio); | ||
1063 | BIO_set_retry_read(bio); | ||
1064 | return(-1); | ||
1065 | } | ||
1066 | } | ||
1067 | goto start; | ||
1068 | } | ||
1069 | |||
1070 | switch (rr->type) | ||
1071 | { | ||
1072 | default: | ||
1073 | #ifndef OPENSSL_NO_TLS | ||
1074 | /* TLS just ignores unknown message types */ | ||
1075 | if (s->version == TLS1_VERSION) | ||
1076 | { | ||
1077 | rr->length = 0; | ||
1078 | goto start; | ||
1079 | } | ||
1080 | #endif | ||
1081 | al=SSL_AD_UNEXPECTED_MESSAGE; | ||
1082 | SSLerr(SSL_F_DTLS1_READ_BYTES,SSL_R_UNEXPECTED_RECORD); | ||
1083 | goto f_err; | ||
1084 | case SSL3_RT_CHANGE_CIPHER_SPEC: | ||
1085 | case SSL3_RT_ALERT: | ||
1086 | case SSL3_RT_HANDSHAKE: | ||
1087 | /* we already handled all of these, with the possible exception | ||
1088 | * of SSL3_RT_HANDSHAKE when s->in_handshake is set, but that | ||
1089 | * should not happen when type != rr->type */ | ||
1090 | al=SSL_AD_UNEXPECTED_MESSAGE; | ||
1091 | SSLerr(SSL_F_DTLS1_READ_BYTES,ERR_R_INTERNAL_ERROR); | ||
1092 | goto f_err; | ||
1093 | case SSL3_RT_APPLICATION_DATA: | ||
1094 | /* At this point, we were expecting handshake data, | ||
1095 | * but have application data. If the library was | ||
1096 | * running inside ssl3_read() (i.e. in_read_app_data | ||
1097 | * is set) and it makes sense to read application data | ||
1098 | * at this point (session renegotiation not yet started), | ||
1099 | * we will indulge it. | ||
1100 | */ | ||
1101 | if (s->s3->in_read_app_data && | ||
1102 | (s->s3->total_renegotiations != 0) && | ||
1103 | (( | ||
1104 | (s->state & SSL_ST_CONNECT) && | ||
1105 | (s->state >= SSL3_ST_CW_CLNT_HELLO_A) && | ||
1106 | (s->state <= SSL3_ST_CR_SRVR_HELLO_A) | ||
1107 | ) || ( | ||
1108 | (s->state & SSL_ST_ACCEPT) && | ||
1109 | (s->state <= SSL3_ST_SW_HELLO_REQ_A) && | ||
1110 | (s->state >= SSL3_ST_SR_CLNT_HELLO_A) | ||
1111 | ) | ||
1112 | )) | ||
1113 | { | ||
1114 | s->s3->in_read_app_data=2; | ||
1115 | return(-1); | ||
1116 | } | ||
1117 | else | ||
1118 | { | ||
1119 | al=SSL_AD_UNEXPECTED_MESSAGE; | ||
1120 | SSLerr(SSL_F_DTLS1_READ_BYTES,SSL_R_UNEXPECTED_RECORD); | ||
1121 | goto f_err; | ||
1122 | } | ||
1123 | } | ||
1124 | /* not reached */ | ||
1125 | |||
1126 | f_err: | ||
1127 | ssl3_send_alert(s,SSL3_AL_FATAL,al); | ||
1128 | err: | ||
1129 | return(-1); | ||
1130 | } | ||
1131 | |||
1132 | int | ||
1133 | dtls1_write_app_data_bytes(SSL *s, int type, const void *buf_, int len) | ||
1134 | { | ||
1135 | unsigned int n,tot; | ||
1136 | int i; | ||
1137 | |||
1138 | if (SSL_in_init(s) && !s->in_handshake) | ||
1139 | { | ||
1140 | i=s->handshake_func(s); | ||
1141 | if (i < 0) return(i); | ||
1142 | if (i == 0) | ||
1143 | { | ||
1144 | SSLerr(SSL_F_DTLS1_WRITE_APP_DATA_BYTES,SSL_R_SSL_HANDSHAKE_FAILURE); | ||
1145 | return -1; | ||
1146 | } | ||
1147 | } | ||
1148 | |||
1149 | tot = s->s3->wnum; | ||
1150 | n = len - tot; | ||
1151 | |||
1152 | while( n) | ||
1153 | { | ||
1154 | /* dtls1_write_bytes sends one record at a time, sized according to | ||
1155 | * the currently known MTU */ | ||
1156 | i = dtls1_write_bytes(s, type, buf_, len); | ||
1157 | if (i <= 0) return i; | ||
1158 | |||
1159 | if ((i == (int)n) || | ||
1160 | (type == SSL3_RT_APPLICATION_DATA && | ||
1161 | (s->mode & SSL_MODE_ENABLE_PARTIAL_WRITE))) | ||
1162 | { | ||
1163 | /* next chunk of data should get another prepended empty fragment | ||
1164 | * in ciphersuites with known-IV weakness: */ | ||
1165 | s->s3->empty_fragment_done = 0; | ||
1166 | return tot+i; | ||
1167 | } | ||
1168 | |||
1169 | tot += i; | ||
1170 | n-=i; | ||
1171 | } | ||
1172 | |||
1173 | return tot; | ||
1174 | } | ||
1175 | |||
1176 | |||
1177 | /* this only happens when a client hello is received and a handshake | ||
1178 | * is started. */ | ||
1179 | static int | ||
1180 | have_handshake_fragment(SSL *s, int type, unsigned char *buf, | ||
1181 | int len, int peek) | ||
1182 | { | ||
1183 | |||
1184 | if ((type == SSL3_RT_HANDSHAKE) && (s->d1->handshake_fragment_len > 0)) | ||
1185 | /* (partially) satisfy request from storage */ | ||
1186 | { | ||
1187 | unsigned char *src = s->d1->handshake_fragment; | ||
1188 | unsigned char *dst = buf; | ||
1189 | unsigned int k,n; | ||
1190 | |||
1191 | /* peek == 0 */ | ||
1192 | n = 0; | ||
1193 | while ((len > 0) && (s->d1->handshake_fragment_len > 0)) | ||
1194 | { | ||
1195 | *dst++ = *src++; | ||
1196 | len--; s->d1->handshake_fragment_len--; | ||
1197 | n++; | ||
1198 | } | ||
1199 | /* move any remaining fragment bytes: */ | ||
1200 | for (k = 0; k < s->d1->handshake_fragment_len; k++) | ||
1201 | s->d1->handshake_fragment[k] = *src++; | ||
1202 | return n; | ||
1203 | } | ||
1204 | |||
1205 | return 0; | ||
1206 | } | ||
1207 | |||
1208 | |||
1209 | |||
1210 | |||
1211 | /* Call this to write data in records of type 'type' | ||
1212 | * It will return <= 0 if not all data has been sent or non-blocking IO. | ||
1213 | */ | ||
1214 | int dtls1_write_bytes(SSL *s, int type, const void *buf_, int len) | ||
1215 | { | ||
1216 | const unsigned char *buf=buf_; | ||
1217 | unsigned int tot,n,nw; | ||
1218 | int i; | ||
1219 | unsigned int mtu; | ||
1220 | |||
1221 | s->rwstate=SSL_NOTHING; | ||
1222 | tot=s->s3->wnum; | ||
1223 | |||
1224 | n=(len-tot); | ||
1225 | |||
1226 | /* handshake layer figures out MTU for itself, but data records | ||
1227 | * are also sent through this interface, so need to figure out MTU */ | ||
1228 | #if 0 | ||
1229 | mtu = BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_GET_MTU, 0, NULL); | ||
1230 | mtu += DTLS1_HM_HEADER_LENGTH; /* HM already inserted */ | ||
1231 | #endif | ||
1232 | mtu = s->d1->mtu; | ||
1233 | |||
1234 | if (mtu > SSL3_RT_MAX_PLAIN_LENGTH) | ||
1235 | mtu = SSL3_RT_MAX_PLAIN_LENGTH; | ||
1236 | |||
1237 | if (n > mtu) | ||
1238 | nw=mtu; | ||
1239 | else | ||
1240 | nw=n; | ||
1241 | |||
1242 | i=do_dtls1_write(s, type, &(buf[tot]), nw, 0); | ||
1243 | if (i <= 0) | ||
1244 | { | ||
1245 | s->s3->wnum=tot; | ||
1246 | return i; | ||
1247 | } | ||
1248 | |||
1249 | if ( (int)s->s3->wnum + i == len) | ||
1250 | s->s3->wnum = 0; | ||
1251 | else | ||
1252 | s->s3->wnum += i; | ||
1253 | |||
1254 | return tot + i; | ||
1255 | } | ||
1256 | |||
1257 | int do_dtls1_write(SSL *s, int type, const unsigned char *buf, unsigned int len, int create_empty_fragment) | ||
1258 | { | ||
1259 | unsigned char *p,*pseq; | ||
1260 | int i,mac_size,clear=0; | ||
1261 | int prefix_len = 0; | ||
1262 | SSL3_RECORD *wr; | ||
1263 | SSL3_BUFFER *wb; | ||
1264 | SSL_SESSION *sess; | ||
1265 | int bs; | ||
1266 | |||
1267 | /* first check if there is a SSL3_BUFFER still being written | ||
1268 | * out. This will happen with non blocking IO */ | ||
1269 | if (s->s3->wbuf.left != 0) | ||
1270 | { | ||
1271 | OPENSSL_assert(0); /* XDTLS: want to see if we ever get here */ | ||
1272 | return(ssl3_write_pending(s,type,buf,len)); | ||
1273 | } | ||
1274 | |||
1275 | /* If we have an alert to send, lets send it */ | ||
1276 | if (s->s3->alert_dispatch) | ||
1277 | { | ||
1278 | i=s->method->ssl_dispatch_alert(s); | ||
1279 | if (i <= 0) | ||
1280 | return(i); | ||
1281 | /* if it went, fall through and send more stuff */ | ||
1282 | } | ||
1283 | |||
1284 | if (len == 0 && !create_empty_fragment) | ||
1285 | return 0; | ||
1286 | |||
1287 | wr= &(s->s3->wrec); | ||
1288 | wb= &(s->s3->wbuf); | ||
1289 | sess=s->session; | ||
1290 | |||
1291 | if ( (sess == NULL) || | ||
1292 | (s->enc_write_ctx == NULL) || | ||
1293 | (s->write_hash == NULL)) | ||
1294 | clear=1; | ||
1295 | |||
1296 | if (clear) | ||
1297 | mac_size=0; | ||
1298 | else | ||
1299 | mac_size=EVP_MD_size(s->write_hash); | ||
1300 | |||
1301 | /* DTLS implements explicit IV, so no need for empty fragments */ | ||
1302 | #if 0 | ||
1303 | /* 'create_empty_fragment' is true only when this function calls itself */ | ||
1304 | if (!clear && !create_empty_fragment && !s->s3->empty_fragment_done | ||
1305 | && SSL_version(s) != DTLS1_VERSION) | ||
1306 | { | ||
1307 | /* countermeasure against known-IV weakness in CBC ciphersuites | ||
1308 | * (see http://www.openssl.org/~bodo/tls-cbc.txt) | ||
1309 | */ | ||
1310 | |||
1311 | if (s->s3->need_empty_fragments && type == SSL3_RT_APPLICATION_DATA) | ||
1312 | { | ||
1313 | /* recursive function call with 'create_empty_fragment' set; | ||
1314 | * this prepares and buffers the data for an empty fragment | ||
1315 | * (these 'prefix_len' bytes are sent out later | ||
1316 | * together with the actual payload) */ | ||
1317 | prefix_len = s->method->do_ssl_write(s, type, buf, 0, 1); | ||
1318 | if (prefix_len <= 0) | ||
1319 | goto err; | ||
1320 | |||
1321 | if (s->s3->wbuf.len < (size_t)prefix_len + SSL3_RT_MAX_PACKET_SIZE) | ||
1322 | { | ||
1323 | /* insufficient space */ | ||
1324 | SSLerr(SSL_F_DO_DTLS1_WRITE, ERR_R_INTERNAL_ERROR); | ||
1325 | goto err; | ||
1326 | } | ||
1327 | } | ||
1328 | |||
1329 | s->s3->empty_fragment_done = 1; | ||
1330 | } | ||
1331 | #endif | ||
1332 | |||
1333 | p = wb->buf + prefix_len; | ||
1334 | |||
1335 | /* write the header */ | ||
1336 | |||
1337 | *(p++)=type&0xff; | ||
1338 | wr->type=type; | ||
1339 | |||
1340 | if (s->client_version == DTLS1_BAD_VER) | ||
1341 | *(p++) = DTLS1_BAD_VER>>8, | ||
1342 | *(p++) = DTLS1_BAD_VER&0xff; | ||
1343 | else | ||
1344 | *(p++)=(s->version>>8), | ||
1345 | *(p++)=s->version&0xff; | ||
1346 | |||
1347 | /* field where we are to write out packet epoch, seq num and len */ | ||
1348 | pseq=p; | ||
1349 | p+=10; | ||
1350 | |||
1351 | /* lets setup the record stuff. */ | ||
1352 | |||
1353 | /* Make space for the explicit IV in case of CBC. | ||
1354 | * (this is a bit of a boundary violation, but what the heck). | ||
1355 | */ | ||
1356 | if ( s->enc_write_ctx && | ||
1357 | (EVP_CIPHER_mode( s->enc_write_ctx->cipher ) & EVP_CIPH_CBC_MODE)) | ||
1358 | bs = EVP_CIPHER_block_size(s->enc_write_ctx->cipher); | ||
1359 | else | ||
1360 | bs = 0; | ||
1361 | |||
1362 | wr->data=p + bs; /* make room for IV in case of CBC */ | ||
1363 | wr->length=(int)len; | ||
1364 | wr->input=(unsigned char *)buf; | ||
1365 | |||
1366 | /* we now 'read' from wr->input, wr->length bytes into | ||
1367 | * wr->data */ | ||
1368 | |||
1369 | /* first we compress */ | ||
1370 | if (s->compress != NULL) | ||
1371 | { | ||
1372 | if (!ssl3_do_compress(s)) | ||
1373 | { | ||
1374 | SSLerr(SSL_F_DO_DTLS1_WRITE,SSL_R_COMPRESSION_FAILURE); | ||
1375 | goto err; | ||
1376 | } | ||
1377 | } | ||
1378 | else | ||
1379 | { | ||
1380 | memcpy(wr->data,wr->input,wr->length); | ||
1381 | wr->input=wr->data; | ||
1382 | } | ||
1383 | |||
1384 | /* we should still have the output to wr->data and the input | ||
1385 | * from wr->input. Length should be wr->length. | ||
1386 | * wr->data still points in the wb->buf */ | ||
1387 | |||
1388 | if (mac_size != 0) | ||
1389 | { | ||
1390 | s->method->ssl3_enc->mac(s,&(p[wr->length + bs]),1); | ||
1391 | wr->length+=mac_size; | ||
1392 | } | ||
1393 | |||
1394 | /* this is true regardless of mac size */ | ||
1395 | wr->input=p; | ||
1396 | wr->data=p; | ||
1397 | |||
1398 | |||
1399 | /* ssl3_enc can only have an error on read */ | ||
1400 | if (bs) /* bs != 0 in case of CBC */ | ||
1401 | { | ||
1402 | RAND_pseudo_bytes(p,bs); | ||
1403 | /* master IV and last CBC residue stand for | ||
1404 | * the rest of randomness */ | ||
1405 | wr->length += bs; | ||
1406 | } | ||
1407 | |||
1408 | s->method->ssl3_enc->enc(s,1); | ||
1409 | |||
1410 | /* record length after mac and block padding */ | ||
1411 | /* if (type == SSL3_RT_APPLICATION_DATA || | ||
1412 | (type == SSL3_RT_ALERT && ! SSL_in_init(s))) */ | ||
1413 | |||
1414 | /* there's only one epoch between handshake and app data */ | ||
1415 | |||
1416 | s2n(s->d1->w_epoch, pseq); | ||
1417 | |||
1418 | /* XDTLS: ?? */ | ||
1419 | /* else | ||
1420 | s2n(s->d1->handshake_epoch, pseq); */ | ||
1421 | |||
1422 | memcpy(pseq, &(s->s3->write_sequence[2]), 6); | ||
1423 | pseq+=6; | ||
1424 | s2n(wr->length,pseq); | ||
1425 | |||
1426 | /* we should now have | ||
1427 | * wr->data pointing to the encrypted data, which is | ||
1428 | * wr->length long */ | ||
1429 | wr->type=type; /* not needed but helps for debugging */ | ||
1430 | wr->length+=DTLS1_RT_HEADER_LENGTH; | ||
1431 | |||
1432 | #if 0 /* this is now done at the message layer */ | ||
1433 | /* buffer the record, making it easy to handle retransmits */ | ||
1434 | if ( type == SSL3_RT_HANDSHAKE || type == SSL3_RT_CHANGE_CIPHER_SPEC) | ||
1435 | dtls1_buffer_record(s, wr->data, wr->length, | ||
1436 | *((PQ_64BIT *)&(s->s3->write_sequence[0]))); | ||
1437 | #endif | ||
1438 | |||
1439 | ssl3_record_sequence_update(&(s->s3->write_sequence[0])); | ||
1440 | |||
1441 | if (create_empty_fragment) | ||
1442 | { | ||
1443 | /* we are in a recursive call; | ||
1444 | * just return the length, don't write out anything here | ||
1445 | */ | ||
1446 | return wr->length; | ||
1447 | } | ||
1448 | |||
1449 | /* now let's set up wb */ | ||
1450 | wb->left = prefix_len + wr->length; | ||
1451 | wb->offset = 0; | ||
1452 | |||
1453 | /* memorize arguments so that ssl3_write_pending can detect bad write retries later */ | ||
1454 | s->s3->wpend_tot=len; | ||
1455 | s->s3->wpend_buf=buf; | ||
1456 | s->s3->wpend_type=type; | ||
1457 | s->s3->wpend_ret=len; | ||
1458 | |||
1459 | /* we now just need to write the buffer */ | ||
1460 | return ssl3_write_pending(s,type,buf,len); | ||
1461 | err: | ||
1462 | return -1; | ||
1463 | } | ||
1464 | |||
1465 | |||
1466 | |||
1467 | static int dtls1_record_replay_check(SSL *s, DTLS1_BITMAP *bitmap, | ||
1468 | PQ_64BIT *seq_num) | ||
1469 | { | ||
1470 | #if PQ_64BIT_IS_INTEGER | ||
1471 | PQ_64BIT mask = 0x0000000000000001L; | ||
1472 | #endif | ||
1473 | PQ_64BIT rcd_num, tmp; | ||
1474 | |||
1475 | pq_64bit_init(&rcd_num); | ||
1476 | pq_64bit_init(&tmp); | ||
1477 | |||
1478 | /* this is the sequence number for the record just read */ | ||
1479 | pq_64bit_bin2num(&rcd_num, s->s3->read_sequence, 8); | ||
1480 | |||
1481 | |||
1482 | if (pq_64bit_gt(&rcd_num, &(bitmap->max_seq_num)) || | ||
1483 | pq_64bit_eq(&rcd_num, &(bitmap->max_seq_num))) | ||
1484 | { | ||
1485 | pq_64bit_assign(seq_num, &rcd_num); | ||
1486 | pq_64bit_free(&rcd_num); | ||
1487 | pq_64bit_free(&tmp); | ||
1488 | return 1; /* this record is new */ | ||
1489 | } | ||
1490 | |||
1491 | pq_64bit_sub(&tmp, &(bitmap->max_seq_num), &rcd_num); | ||
1492 | |||
1493 | if ( pq_64bit_get_word(&tmp) > bitmap->length) | ||
1494 | { | ||
1495 | pq_64bit_free(&rcd_num); | ||
1496 | pq_64bit_free(&tmp); | ||
1497 | return 0; /* stale, outside the window */ | ||
1498 | } | ||
1499 | |||
1500 | #if PQ_64BIT_IS_BIGNUM | ||
1501 | { | ||
1502 | int offset; | ||
1503 | pq_64bit_sub(&tmp, &(bitmap->max_seq_num), &rcd_num); | ||
1504 | pq_64bit_sub_word(&tmp, 1); | ||
1505 | offset = pq_64bit_get_word(&tmp); | ||
1506 | if ( pq_64bit_is_bit_set(&(bitmap->map), offset)) | ||
1507 | { | ||
1508 | pq_64bit_free(&rcd_num); | ||
1509 | pq_64bit_free(&tmp); | ||
1510 | return 0; | ||
1511 | } | ||
1512 | } | ||
1513 | #else | ||
1514 | mask <<= (bitmap->max_seq_num - rcd_num - 1); | ||
1515 | if (bitmap->map & mask) | ||
1516 | return 0; /* record previously received */ | ||
1517 | #endif | ||
1518 | |||
1519 | pq_64bit_assign(seq_num, &rcd_num); | ||
1520 | pq_64bit_free(&rcd_num); | ||
1521 | pq_64bit_free(&tmp); | ||
1522 | return 1; | ||
1523 | } | ||
1524 | |||
1525 | |||
1526 | static void dtls1_record_bitmap_update(SSL *s, DTLS1_BITMAP *bitmap) | ||
1527 | { | ||
1528 | unsigned int shift; | ||
1529 | PQ_64BIT rcd_num; | ||
1530 | PQ_64BIT tmp; | ||
1531 | PQ_64BIT_CTX *ctx; | ||
1532 | |||
1533 | pq_64bit_init(&rcd_num); | ||
1534 | pq_64bit_init(&tmp); | ||
1535 | |||
1536 | pq_64bit_bin2num(&rcd_num, s->s3->read_sequence, 8); | ||
1537 | |||
1538 | /* unfortunate code complexity due to 64-bit manipulation support | ||
1539 | * on 32-bit machines */ | ||
1540 | if ( pq_64bit_gt(&rcd_num, &(bitmap->max_seq_num)) || | ||
1541 | pq_64bit_eq(&rcd_num, &(bitmap->max_seq_num))) | ||
1542 | { | ||
1543 | pq_64bit_sub(&tmp, &rcd_num, &(bitmap->max_seq_num)); | ||
1544 | pq_64bit_add_word(&tmp, 1); | ||
1545 | |||
1546 | shift = (unsigned int)pq_64bit_get_word(&tmp); | ||
1547 | |||
1548 | pq_64bit_lshift(&(tmp), &(bitmap->map), shift); | ||
1549 | pq_64bit_assign(&(bitmap->map), &tmp); | ||
1550 | |||
1551 | pq_64bit_set_bit(&(bitmap->map), 0); | ||
1552 | pq_64bit_add_word(&rcd_num, 1); | ||
1553 | pq_64bit_assign(&(bitmap->max_seq_num), &rcd_num); | ||
1554 | |||
1555 | pq_64bit_assign_word(&tmp, 1); | ||
1556 | pq_64bit_lshift(&tmp, &tmp, bitmap->length); | ||
1557 | ctx = pq_64bit_ctx_new(&ctx); | ||
1558 | pq_64bit_mod(&(bitmap->map), &(bitmap->map), &tmp, ctx); | ||
1559 | pq_64bit_ctx_free(ctx); | ||
1560 | } | ||
1561 | else | ||
1562 | { | ||
1563 | pq_64bit_sub(&tmp, &(bitmap->max_seq_num), &rcd_num); | ||
1564 | pq_64bit_sub_word(&tmp, 1); | ||
1565 | shift = (unsigned int)pq_64bit_get_word(&tmp); | ||
1566 | |||
1567 | pq_64bit_set_bit(&(bitmap->map), shift); | ||
1568 | } | ||
1569 | |||
1570 | pq_64bit_free(&rcd_num); | ||
1571 | pq_64bit_free(&tmp); | ||
1572 | } | ||
1573 | |||
1574 | |||
1575 | int dtls1_dispatch_alert(SSL *s) | ||
1576 | { | ||
1577 | int i,j; | ||
1578 | void (*cb)(const SSL *ssl,int type,int val)=NULL; | ||
1579 | unsigned char buf[2 + 2 + 3]; /* alert level + alert desc + message seq +frag_off */ | ||
1580 | unsigned char *ptr = &buf[0]; | ||
1581 | |||
1582 | s->s3->alert_dispatch=0; | ||
1583 | |||
1584 | memset(buf, 0x00, sizeof(buf)); | ||
1585 | *ptr++ = s->s3->send_alert[0]; | ||
1586 | *ptr++ = s->s3->send_alert[1]; | ||
1587 | |||
1588 | if (s->s3->send_alert[1] == DTLS1_AD_MISSING_HANDSHAKE_MESSAGE) | ||
1589 | { | ||
1590 | s2n(s->d1->handshake_read_seq, ptr); | ||
1591 | #if 0 | ||
1592 | if ( s->d1->r_msg_hdr.frag_off == 0) /* waiting for a new msg */ | ||
1593 | |||
1594 | else | ||
1595 | s2n(s->d1->r_msg_hdr.seq, ptr); /* partial msg read */ | ||
1596 | #endif | ||
1597 | |||
1598 | #if 0 | ||
1599 | fprintf(stderr, "s->d1->handshake_read_seq = %d, s->d1->r_msg_hdr.seq = %d\n",s->d1->handshake_read_seq,s->d1->r_msg_hdr.seq); | ||
1600 | #endif | ||
1601 | l2n3(s->d1->r_msg_hdr.frag_off, ptr); | ||
1602 | } | ||
1603 | |||
1604 | i = do_dtls1_write(s, SSL3_RT_ALERT, &buf[0], sizeof(buf), 0); | ||
1605 | if (i <= 0) | ||
1606 | { | ||
1607 | s->s3->alert_dispatch=1; | ||
1608 | /* fprintf( stderr, "not done with alert\n" ); */ | ||
1609 | } | ||
1610 | else | ||
1611 | { | ||
1612 | if ( s->s3->send_alert[0] == SSL3_AL_FATAL || | ||
1613 | s->s3->send_alert[1] == DTLS1_AD_MISSING_HANDSHAKE_MESSAGE) | ||
1614 | (void)BIO_flush(s->wbio); | ||
1615 | |||
1616 | if (s->msg_callback) | ||
1617 | s->msg_callback(1, s->version, SSL3_RT_ALERT, s->s3->send_alert, | ||
1618 | 2, s, s->msg_callback_arg); | ||
1619 | |||
1620 | if (s->info_callback != NULL) | ||
1621 | cb=s->info_callback; | ||
1622 | else if (s->ctx->info_callback != NULL) | ||
1623 | cb=s->ctx->info_callback; | ||
1624 | |||
1625 | if (cb != NULL) | ||
1626 | { | ||
1627 | j=(s->s3->send_alert[0]<<8)|s->s3->send_alert[1]; | ||
1628 | cb(s,SSL_CB_WRITE_ALERT,j); | ||
1629 | } | ||
1630 | } | ||
1631 | return(i); | ||
1632 | } | ||
1633 | |||
1634 | |||
1635 | static DTLS1_BITMAP * | ||
1636 | dtls1_get_bitmap(SSL *s, SSL3_RECORD *rr, unsigned int *is_next_epoch) | ||
1637 | { | ||
1638 | |||
1639 | *is_next_epoch = 0; | ||
1640 | |||
1641 | /* In current epoch, accept HM, CCS, DATA, & ALERT */ | ||
1642 | if (rr->epoch == s->d1->r_epoch) | ||
1643 | return &s->d1->bitmap; | ||
1644 | |||
1645 | /* Only HM and ALERT messages can be from the next epoch */ | ||
1646 | else if (rr->epoch == (unsigned long)(s->d1->r_epoch + 1) && | ||
1647 | (rr->type == SSL3_RT_HANDSHAKE || | ||
1648 | rr->type == SSL3_RT_ALERT)) | ||
1649 | { | ||
1650 | *is_next_epoch = 1; | ||
1651 | return &s->d1->next_bitmap; | ||
1652 | } | ||
1653 | |||
1654 | return NULL; | ||
1655 | } | ||
1656 | |||
1657 | #if 0 | ||
1658 | static int | ||
1659 | dtls1_record_needs_buffering(SSL *s, SSL3_RECORD *rr, unsigned short *priority, | ||
1660 | unsigned long *offset) | ||
1661 | { | ||
1662 | |||
1663 | /* alerts are passed up immediately */ | ||
1664 | if ( rr->type == SSL3_RT_APPLICATION_DATA || | ||
1665 | rr->type == SSL3_RT_ALERT) | ||
1666 | return 0; | ||
1667 | |||
1668 | /* Only need to buffer if a handshake is underway. | ||
1669 | * (this implies that Hello Request and Client Hello are passed up | ||
1670 | * immediately) */ | ||
1671 | if ( SSL_in_init(s)) | ||
1672 | { | ||
1673 | unsigned char *data = rr->data; | ||
1674 | /* need to extract the HM/CCS sequence number here */ | ||
1675 | if ( rr->type == SSL3_RT_HANDSHAKE || | ||
1676 | rr->type == SSL3_RT_CHANGE_CIPHER_SPEC) | ||
1677 | { | ||
1678 | unsigned short seq_num; | ||
1679 | struct hm_header_st msg_hdr; | ||
1680 | struct ccs_header_st ccs_hdr; | ||
1681 | |||
1682 | if ( rr->type == SSL3_RT_HANDSHAKE) | ||
1683 | { | ||
1684 | dtls1_get_message_header(data, &msg_hdr); | ||
1685 | seq_num = msg_hdr.seq; | ||
1686 | *offset = msg_hdr.frag_off; | ||
1687 | } | ||
1688 | else | ||
1689 | { | ||
1690 | dtls1_get_ccs_header(data, &ccs_hdr); | ||
1691 | seq_num = ccs_hdr.seq; | ||
1692 | *offset = 0; | ||
1693 | } | ||
1694 | |||
1695 | /* this is either a record we're waiting for, or a | ||
1696 | * retransmit of something we happened to previously | ||
1697 | * receive (higher layers will drop the repeat silently */ | ||
1698 | if ( seq_num < s->d1->handshake_read_seq) | ||
1699 | return 0; | ||
1700 | if (rr->type == SSL3_RT_HANDSHAKE && | ||
1701 | seq_num == s->d1->handshake_read_seq && | ||
1702 | msg_hdr.frag_off < s->d1->r_msg_hdr.frag_off) | ||
1703 | return 0; | ||
1704 | else if ( seq_num == s->d1->handshake_read_seq && | ||
1705 | (rr->type == SSL3_RT_CHANGE_CIPHER_SPEC || | ||
1706 | msg_hdr.frag_off == s->d1->r_msg_hdr.frag_off)) | ||
1707 | return 0; | ||
1708 | else | ||
1709 | { | ||
1710 | *priority = seq_num; | ||
1711 | return 1; | ||
1712 | } | ||
1713 | } | ||
1714 | else /* unknown record type */ | ||
1715 | return 0; | ||
1716 | } | ||
1717 | |||
1718 | return 0; | ||
1719 | } | ||
1720 | #endif | ||
1721 | |||
1722 | void | ||
1723 | dtls1_reset_seq_numbers(SSL *s, int rw) | ||
1724 | { | ||
1725 | unsigned char *seq; | ||
1726 | unsigned int seq_bytes = sizeof(s->s3->read_sequence); | ||
1727 | |||
1728 | if ( rw & SSL3_CC_READ) | ||
1729 | { | ||
1730 | seq = s->s3->read_sequence; | ||
1731 | s->d1->r_epoch++; | ||
1732 | |||
1733 | pq_64bit_assign(&(s->d1->bitmap.map), &(s->d1->next_bitmap.map)); | ||
1734 | s->d1->bitmap.length = s->d1->next_bitmap.length; | ||
1735 | pq_64bit_assign(&(s->d1->bitmap.max_seq_num), | ||
1736 | &(s->d1->next_bitmap.max_seq_num)); | ||
1737 | |||
1738 | pq_64bit_free(&(s->d1->next_bitmap.map)); | ||
1739 | pq_64bit_free(&(s->d1->next_bitmap.max_seq_num)); | ||
1740 | memset(&(s->d1->next_bitmap), 0x00, sizeof(DTLS1_BITMAP)); | ||
1741 | pq_64bit_init(&(s->d1->next_bitmap.map)); | ||
1742 | pq_64bit_init(&(s->d1->next_bitmap.max_seq_num)); | ||
1743 | } | ||
1744 | else | ||
1745 | { | ||
1746 | seq = s->s3->write_sequence; | ||
1747 | s->d1->w_epoch++; | ||
1748 | } | ||
1749 | |||
1750 | memset(seq, 0x00, seq_bytes); | ||
1751 | } | ||
1752 | |||
1753 | #if PQ_64BIT_IS_INTEGER | ||
1754 | static PQ_64BIT | ||
1755 | bytes_to_long_long(unsigned char *bytes, PQ_64BIT *num) | ||
1756 | { | ||
1757 | PQ_64BIT _num; | ||
1758 | |||
1759 | _num = (((PQ_64BIT)bytes[0]) << 56) | | ||
1760 | (((PQ_64BIT)bytes[1]) << 48) | | ||
1761 | (((PQ_64BIT)bytes[2]) << 40) | | ||
1762 | (((PQ_64BIT)bytes[3]) << 32) | | ||
1763 | (((PQ_64BIT)bytes[4]) << 24) | | ||
1764 | (((PQ_64BIT)bytes[5]) << 16) | | ||
1765 | (((PQ_64BIT)bytes[6]) << 8) | | ||
1766 | (((PQ_64BIT)bytes[7]) ); | ||
1767 | |||
1768 | *num = _num ; | ||
1769 | return _num; | ||
1770 | } | ||
1771 | #endif | ||
1772 | |||
1773 | |||
1774 | static void | ||
1775 | dtls1_clear_timeouts(SSL *s) | ||
1776 | { | ||
1777 | memset(&(s->d1->timeout), 0x00, sizeof(struct dtls1_timeout_st)); | ||
1778 | } | ||
diff --git a/src/lib/libssl/d1_srvr.c b/src/lib/libssl/d1_srvr.c new file mode 100644 index 0000000000..927b01f3c4 --- /dev/null +++ b/src/lib/libssl/d1_srvr.c | |||
@@ -0,0 +1,1147 @@ | |||
1 | /* ssl/d1_srvr.c */ | ||
2 | /* | ||
3 | * DTLS implementation written by Nagendra Modadugu | ||
4 | * (nagendra@cs.stanford.edu) for the OpenSSL project 2005. | ||
5 | */ | ||
6 | /* ==================================================================== | ||
7 | * Copyright (c) 1999-2005 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 | * openssl-core@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 | * This product includes cryptographic software written by Eric Young | ||
55 | * (eay@cryptsoft.com). This product includes software written by Tim | ||
56 | * Hudson (tjh@cryptsoft.com). | ||
57 | * | ||
58 | */ | ||
59 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) | ||
60 | * All rights reserved. | ||
61 | * | ||
62 | * This package is an SSL implementation written | ||
63 | * by Eric Young (eay@cryptsoft.com). | ||
64 | * The implementation was written so as to conform with Netscapes SSL. | ||
65 | * | ||
66 | * This library is free for commercial and non-commercial use as long as | ||
67 | * the following conditions are aheared to. The following conditions | ||
68 | * apply to all code found in this distribution, be it the RC4, RSA, | ||
69 | * lhash, DES, etc., code; not just the SSL code. The SSL documentation | ||
70 | * included with this distribution is covered by the same copyright terms | ||
71 | * except that the holder is Tim Hudson (tjh@cryptsoft.com). | ||
72 | * | ||
73 | * Copyright remains Eric Young's, and as such any Copyright notices in | ||
74 | * the code are not to be removed. | ||
75 | * If this package is used in a product, Eric Young should be given attribution | ||
76 | * as the author of the parts of the library used. | ||
77 | * This can be in the form of a textual message at program startup or | ||
78 | * in documentation (online or textual) provided with the package. | ||
79 | * | ||
80 | * Redistribution and use in source and binary forms, with or without | ||
81 | * modification, are permitted provided that the following conditions | ||
82 | * are met: | ||
83 | * 1. Redistributions of source code must retain the copyright | ||
84 | * notice, this list of conditions and the following disclaimer. | ||
85 | * 2. Redistributions in binary form must reproduce the above copyright | ||
86 | * notice, this list of conditions and the following disclaimer in the | ||
87 | * documentation and/or other materials provided with the distribution. | ||
88 | * 3. All advertising materials mentioning features or use of this software | ||
89 | * must display the following acknowledgement: | ||
90 | * "This product includes cryptographic software written by | ||
91 | * Eric Young (eay@cryptsoft.com)" | ||
92 | * The word 'cryptographic' can be left out if the rouines from the library | ||
93 | * being used are not cryptographic related :-). | ||
94 | * 4. If you include any Windows specific code (or a derivative thereof) from | ||
95 | * the apps directory (application code) you must include an acknowledgement: | ||
96 | * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" | ||
97 | * | ||
98 | * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND | ||
99 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
100 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
101 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | ||
102 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
103 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
104 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
105 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
106 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
107 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
108 | * SUCH DAMAGE. | ||
109 | * | ||
110 | * The licence and distribution terms for any publically available version or | ||
111 | * derivative of this code cannot be changed. i.e. this code cannot simply be | ||
112 | * copied and put under another distribution licence | ||
113 | * [including the GNU Public Licence.] | ||
114 | */ | ||
115 | |||
116 | #include <stdio.h> | ||
117 | #include "ssl_locl.h" | ||
118 | #include <openssl/buffer.h> | ||
119 | #include <openssl/rand.h> | ||
120 | #include <openssl/objects.h> | ||
121 | #include <openssl/evp.h> | ||
122 | #include <openssl/x509.h> | ||
123 | #include <openssl/md5.h> | ||
124 | #ifndef OPENSSL_NO_DH | ||
125 | #include <openssl/dh.h> | ||
126 | #endif | ||
127 | |||
128 | static SSL_METHOD *dtls1_get_server_method(int ver); | ||
129 | static int dtls1_send_hello_verify_request(SSL *s); | ||
130 | |||
131 | static SSL_METHOD *dtls1_get_server_method(int ver) | ||
132 | { | ||
133 | if (ver == DTLS1_VERSION) | ||
134 | return(DTLSv1_server_method()); | ||
135 | else | ||
136 | return(NULL); | ||
137 | } | ||
138 | |||
139 | IMPLEMENT_dtls1_meth_func(DTLSv1_server_method, | ||
140 | dtls1_accept, | ||
141 | ssl_undefined_function, | ||
142 | dtls1_get_server_method) | ||
143 | |||
144 | int dtls1_accept(SSL *s) | ||
145 | { | ||
146 | BUF_MEM *buf; | ||
147 | unsigned long l,Time=(unsigned long)time(NULL); | ||
148 | void (*cb)(const SSL *ssl,int type,int val)=NULL; | ||
149 | long num1; | ||
150 | int ret= -1; | ||
151 | int new_state,state,skip=0; | ||
152 | |||
153 | RAND_add(&Time,sizeof(Time),0); | ||
154 | ERR_clear_error(); | ||
155 | clear_sys_error(); | ||
156 | |||
157 | if (s->info_callback != NULL) | ||
158 | cb=s->info_callback; | ||
159 | else if (s->ctx->info_callback != NULL) | ||
160 | cb=s->ctx->info_callback; | ||
161 | |||
162 | /* init things to blank */ | ||
163 | s->in_handshake++; | ||
164 | if (!SSL_in_init(s) || SSL_in_before(s)) SSL_clear(s); | ||
165 | |||
166 | if (s->cert == NULL) | ||
167 | { | ||
168 | SSLerr(SSL_F_DTLS1_ACCEPT,SSL_R_NO_CERTIFICATE_SET); | ||
169 | return(-1); | ||
170 | } | ||
171 | |||
172 | for (;;) | ||
173 | { | ||
174 | state=s->state; | ||
175 | |||
176 | switch (s->state) | ||
177 | { | ||
178 | case SSL_ST_RENEGOTIATE: | ||
179 | s->new_session=1; | ||
180 | /* s->state=SSL_ST_ACCEPT; */ | ||
181 | |||
182 | case SSL_ST_BEFORE: | ||
183 | case SSL_ST_ACCEPT: | ||
184 | case SSL_ST_BEFORE|SSL_ST_ACCEPT: | ||
185 | case SSL_ST_OK|SSL_ST_ACCEPT: | ||
186 | |||
187 | s->server=1; | ||
188 | if (cb != NULL) cb(s,SSL_CB_HANDSHAKE_START,1); | ||
189 | |||
190 | if ((s->version & 0xff00) != (DTLS1_VERSION & 0xff00)) | ||
191 | { | ||
192 | SSLerr(SSL_F_DTLS1_ACCEPT, ERR_R_INTERNAL_ERROR); | ||
193 | return -1; | ||
194 | } | ||
195 | s->type=SSL_ST_ACCEPT; | ||
196 | |||
197 | if (s->init_buf == NULL) | ||
198 | { | ||
199 | if ((buf=BUF_MEM_new()) == NULL) | ||
200 | { | ||
201 | ret= -1; | ||
202 | goto end; | ||
203 | } | ||
204 | if (!BUF_MEM_grow(buf,SSL3_RT_MAX_PLAIN_LENGTH)) | ||
205 | { | ||
206 | ret= -1; | ||
207 | goto end; | ||
208 | } | ||
209 | s->init_buf=buf; | ||
210 | } | ||
211 | |||
212 | if (!ssl3_setup_buffers(s)) | ||
213 | { | ||
214 | ret= -1; | ||
215 | goto end; | ||
216 | } | ||
217 | |||
218 | s->init_num=0; | ||
219 | |||
220 | if (s->state != SSL_ST_RENEGOTIATE) | ||
221 | { | ||
222 | /* Ok, we now need to push on a buffering BIO so that | ||
223 | * the output is sent in a way that TCP likes :-) | ||
224 | */ | ||
225 | if (!ssl_init_wbio_buffer(s,1)) { ret= -1; goto end; } | ||
226 | |||
227 | ssl3_init_finished_mac(s); | ||
228 | s->state=SSL3_ST_SR_CLNT_HELLO_A; | ||
229 | s->ctx->stats.sess_accept++; | ||
230 | } | ||
231 | else | ||
232 | { | ||
233 | /* s->state == SSL_ST_RENEGOTIATE, | ||
234 | * we will just send a HelloRequest */ | ||
235 | s->ctx->stats.sess_accept_renegotiate++; | ||
236 | s->state=SSL3_ST_SW_HELLO_REQ_A; | ||
237 | } | ||
238 | |||
239 | if ( (SSL_get_options(s) & SSL_OP_COOKIE_EXCHANGE)) | ||
240 | s->d1->send_cookie = 1; | ||
241 | else | ||
242 | s->d1->send_cookie = 0; | ||
243 | |||
244 | break; | ||
245 | |||
246 | case SSL3_ST_SW_HELLO_REQ_A: | ||
247 | case SSL3_ST_SW_HELLO_REQ_B: | ||
248 | |||
249 | s->shutdown=0; | ||
250 | ret=dtls1_send_hello_request(s); | ||
251 | if (ret <= 0) goto end; | ||
252 | s->s3->tmp.next_state=SSL3_ST_SW_HELLO_REQ_C; | ||
253 | s->state=SSL3_ST_SW_FLUSH; | ||
254 | s->init_num=0; | ||
255 | |||
256 | ssl3_init_finished_mac(s); | ||
257 | break; | ||
258 | |||
259 | case SSL3_ST_SW_HELLO_REQ_C: | ||
260 | s->state=SSL_ST_OK; | ||
261 | break; | ||
262 | |||
263 | case SSL3_ST_SR_CLNT_HELLO_A: | ||
264 | case SSL3_ST_SR_CLNT_HELLO_B: | ||
265 | case SSL3_ST_SR_CLNT_HELLO_C: | ||
266 | |||
267 | s->shutdown=0; | ||
268 | ret=ssl3_get_client_hello(s); | ||
269 | if (ret <= 0) goto end; | ||
270 | s->new_session = 2; | ||
271 | |||
272 | if ( s->d1->send_cookie) | ||
273 | s->state = DTLS1_ST_SW_HELLO_VERIFY_REQUEST_A; | ||
274 | else | ||
275 | s->state = SSL3_ST_SW_SRVR_HELLO_A; | ||
276 | |||
277 | s->init_num=0; | ||
278 | break; | ||
279 | |||
280 | case DTLS1_ST_SW_HELLO_VERIFY_REQUEST_A: | ||
281 | case DTLS1_ST_SW_HELLO_VERIFY_REQUEST_B: | ||
282 | |||
283 | ret = dtls1_send_hello_verify_request(s); | ||
284 | if ( ret <= 0) goto end; | ||
285 | s->d1->send_cookie = 0; | ||
286 | s->state=SSL3_ST_SW_FLUSH; | ||
287 | s->s3->tmp.next_state=SSL3_ST_SR_CLNT_HELLO_A; | ||
288 | |||
289 | /* HelloVerifyRequests resets Finished MAC */ | ||
290 | if (s->client_version != DTLS1_BAD_VER) | ||
291 | ssl3_init_finished_mac(s); | ||
292 | break; | ||
293 | |||
294 | case SSL3_ST_SW_SRVR_HELLO_A: | ||
295 | case SSL3_ST_SW_SRVR_HELLO_B: | ||
296 | ret=dtls1_send_server_hello(s); | ||
297 | if (ret <= 0) goto end; | ||
298 | |||
299 | if (s->hit) | ||
300 | s->state=SSL3_ST_SW_CHANGE_A; | ||
301 | else | ||
302 | s->state=SSL3_ST_SW_CERT_A; | ||
303 | s->init_num=0; | ||
304 | break; | ||
305 | |||
306 | case SSL3_ST_SW_CERT_A: | ||
307 | case SSL3_ST_SW_CERT_B: | ||
308 | /* Check if it is anon DH */ | ||
309 | if (!(s->s3->tmp.new_cipher->algorithms & SSL_aNULL)) | ||
310 | { | ||
311 | ret=dtls1_send_server_certificate(s); | ||
312 | if (ret <= 0) goto end; | ||
313 | } | ||
314 | else | ||
315 | skip=1; | ||
316 | s->state=SSL3_ST_SW_KEY_EXCH_A; | ||
317 | s->init_num=0; | ||
318 | break; | ||
319 | |||
320 | case SSL3_ST_SW_KEY_EXCH_A: | ||
321 | case SSL3_ST_SW_KEY_EXCH_B: | ||
322 | l=s->s3->tmp.new_cipher->algorithms; | ||
323 | |||
324 | /* clear this, it may get reset by | ||
325 | * send_server_key_exchange */ | ||
326 | if ((s->options & SSL_OP_EPHEMERAL_RSA) | ||
327 | #ifndef OPENSSL_NO_KRB5 | ||
328 | && !(l & SSL_KRB5) | ||
329 | #endif /* OPENSSL_NO_KRB5 */ | ||
330 | ) | ||
331 | /* option SSL_OP_EPHEMERAL_RSA sends temporary RSA key | ||
332 | * even when forbidden by protocol specs | ||
333 | * (handshake may fail as clients are not required to | ||
334 | * be able to handle this) */ | ||
335 | s->s3->tmp.use_rsa_tmp=1; | ||
336 | else | ||
337 | s->s3->tmp.use_rsa_tmp=0; | ||
338 | |||
339 | /* only send if a DH key exchange, fortezza or | ||
340 | * RSA but we have a sign only certificate */ | ||
341 | if (s->s3->tmp.use_rsa_tmp | ||
342 | || (l & (SSL_DH|SSL_kFZA)) | ||
343 | || ((l & SSL_kRSA) | ||
344 | && (s->cert->pkeys[SSL_PKEY_RSA_ENC].privatekey == NULL | ||
345 | || (SSL_C_IS_EXPORT(s->s3->tmp.new_cipher) | ||
346 | && EVP_PKEY_size(s->cert->pkeys[SSL_PKEY_RSA_ENC].privatekey)*8 > SSL_C_EXPORT_PKEYLENGTH(s->s3->tmp.new_cipher) | ||
347 | ) | ||
348 | ) | ||
349 | ) | ||
350 | ) | ||
351 | { | ||
352 | ret=dtls1_send_server_key_exchange(s); | ||
353 | if (ret <= 0) goto end; | ||
354 | } | ||
355 | else | ||
356 | skip=1; | ||
357 | |||
358 | s->state=SSL3_ST_SW_CERT_REQ_A; | ||
359 | s->init_num=0; | ||
360 | break; | ||
361 | |||
362 | case SSL3_ST_SW_CERT_REQ_A: | ||
363 | case SSL3_ST_SW_CERT_REQ_B: | ||
364 | if (/* don't request cert unless asked for it: */ | ||
365 | !(s->verify_mode & SSL_VERIFY_PEER) || | ||
366 | /* if SSL_VERIFY_CLIENT_ONCE is set, | ||
367 | * don't request cert during re-negotiation: */ | ||
368 | ((s->session->peer != NULL) && | ||
369 | (s->verify_mode & SSL_VERIFY_CLIENT_ONCE)) || | ||
370 | /* never request cert in anonymous ciphersuites | ||
371 | * (see section "Certificate request" in SSL 3 drafts | ||
372 | * and in RFC 2246): */ | ||
373 | ((s->s3->tmp.new_cipher->algorithms & SSL_aNULL) && | ||
374 | /* ... except when the application insists on verification | ||
375 | * (against the specs, but s3_clnt.c accepts this for SSL 3) */ | ||
376 | !(s->verify_mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT)) || | ||
377 | /* never request cert in Kerberos ciphersuites */ | ||
378 | (s->s3->tmp.new_cipher->algorithms & SSL_aKRB5)) | ||
379 | { | ||
380 | /* no cert request */ | ||
381 | skip=1; | ||
382 | s->s3->tmp.cert_request=0; | ||
383 | s->state=SSL3_ST_SW_SRVR_DONE_A; | ||
384 | } | ||
385 | else | ||
386 | { | ||
387 | s->s3->tmp.cert_request=1; | ||
388 | ret=dtls1_send_certificate_request(s); | ||
389 | if (ret <= 0) goto end; | ||
390 | #ifndef NETSCAPE_HANG_BUG | ||
391 | s->state=SSL3_ST_SW_SRVR_DONE_A; | ||
392 | #else | ||
393 | s->state=SSL3_ST_SW_FLUSH; | ||
394 | s->s3->tmp.next_state=SSL3_ST_SR_CERT_A; | ||
395 | #endif | ||
396 | s->init_num=0; | ||
397 | } | ||
398 | break; | ||
399 | |||
400 | case SSL3_ST_SW_SRVR_DONE_A: | ||
401 | case SSL3_ST_SW_SRVR_DONE_B: | ||
402 | ret=dtls1_send_server_done(s); | ||
403 | if (ret <= 0) goto end; | ||
404 | s->s3->tmp.next_state=SSL3_ST_SR_CERT_A; | ||
405 | s->state=SSL3_ST_SW_FLUSH; | ||
406 | s->init_num=0; | ||
407 | break; | ||
408 | |||
409 | case SSL3_ST_SW_FLUSH: | ||
410 | /* number of bytes to be flushed */ | ||
411 | num1=BIO_ctrl(s->wbio,BIO_CTRL_INFO,0,NULL); | ||
412 | if (num1 > 0) | ||
413 | { | ||
414 | s->rwstate=SSL_WRITING; | ||
415 | num1=BIO_flush(s->wbio); | ||
416 | if (num1 <= 0) { ret= -1; goto end; } | ||
417 | s->rwstate=SSL_NOTHING; | ||
418 | } | ||
419 | |||
420 | s->state=s->s3->tmp.next_state; | ||
421 | break; | ||
422 | |||
423 | case SSL3_ST_SR_CERT_A: | ||
424 | case SSL3_ST_SR_CERT_B: | ||
425 | /* Check for second client hello (MS SGC) */ | ||
426 | ret = ssl3_check_client_hello(s); | ||
427 | if (ret <= 0) | ||
428 | goto end; | ||
429 | if (ret == 2) | ||
430 | s->state = SSL3_ST_SR_CLNT_HELLO_C; | ||
431 | else { | ||
432 | /* could be sent for a DH cert, even if we | ||
433 | * have not asked for it :-) */ | ||
434 | ret=ssl3_get_client_certificate(s); | ||
435 | if (ret <= 0) goto end; | ||
436 | s->init_num=0; | ||
437 | s->state=SSL3_ST_SR_KEY_EXCH_A; | ||
438 | } | ||
439 | break; | ||
440 | |||
441 | case SSL3_ST_SR_KEY_EXCH_A: | ||
442 | case SSL3_ST_SR_KEY_EXCH_B: | ||
443 | ret=ssl3_get_client_key_exchange(s); | ||
444 | if (ret <= 0) goto end; | ||
445 | s->state=SSL3_ST_SR_CERT_VRFY_A; | ||
446 | s->init_num=0; | ||
447 | |||
448 | /* We need to get hashes here so if there is | ||
449 | * a client cert, it can be verified */ | ||
450 | s->method->ssl3_enc->cert_verify_mac(s, | ||
451 | &(s->s3->finish_dgst1), | ||
452 | &(s->s3->tmp.cert_verify_md[0])); | ||
453 | s->method->ssl3_enc->cert_verify_mac(s, | ||
454 | &(s->s3->finish_dgst2), | ||
455 | &(s->s3->tmp.cert_verify_md[MD5_DIGEST_LENGTH])); | ||
456 | |||
457 | break; | ||
458 | |||
459 | case SSL3_ST_SR_CERT_VRFY_A: | ||
460 | case SSL3_ST_SR_CERT_VRFY_B: | ||
461 | |||
462 | /* we should decide if we expected this one */ | ||
463 | ret=ssl3_get_cert_verify(s); | ||
464 | if (ret <= 0) goto end; | ||
465 | |||
466 | s->state=SSL3_ST_SR_FINISHED_A; | ||
467 | s->init_num=0; | ||
468 | break; | ||
469 | |||
470 | case SSL3_ST_SR_FINISHED_A: | ||
471 | case SSL3_ST_SR_FINISHED_B: | ||
472 | ret=ssl3_get_finished(s,SSL3_ST_SR_FINISHED_A, | ||
473 | SSL3_ST_SR_FINISHED_B); | ||
474 | if (ret <= 0) goto end; | ||
475 | if (s->hit) | ||
476 | s->state=SSL_ST_OK; | ||
477 | else | ||
478 | s->state=SSL3_ST_SW_CHANGE_A; | ||
479 | s->init_num=0; | ||
480 | break; | ||
481 | |||
482 | case SSL3_ST_SW_CHANGE_A: | ||
483 | case SSL3_ST_SW_CHANGE_B: | ||
484 | |||
485 | s->session->cipher=s->s3->tmp.new_cipher; | ||
486 | if (!s->method->ssl3_enc->setup_key_block(s)) | ||
487 | { ret= -1; goto end; } | ||
488 | |||
489 | ret=dtls1_send_change_cipher_spec(s, | ||
490 | SSL3_ST_SW_CHANGE_A,SSL3_ST_SW_CHANGE_B); | ||
491 | |||
492 | if (ret <= 0) goto end; | ||
493 | s->state=SSL3_ST_SW_FINISHED_A; | ||
494 | s->init_num=0; | ||
495 | |||
496 | if (!s->method->ssl3_enc->change_cipher_state(s, | ||
497 | SSL3_CHANGE_CIPHER_SERVER_WRITE)) | ||
498 | { | ||
499 | ret= -1; | ||
500 | goto end; | ||
501 | } | ||
502 | |||
503 | dtls1_reset_seq_numbers(s, SSL3_CC_WRITE); | ||
504 | break; | ||
505 | |||
506 | case SSL3_ST_SW_FINISHED_A: | ||
507 | case SSL3_ST_SW_FINISHED_B: | ||
508 | ret=dtls1_send_finished(s, | ||
509 | SSL3_ST_SW_FINISHED_A,SSL3_ST_SW_FINISHED_B, | ||
510 | s->method->ssl3_enc->server_finished_label, | ||
511 | s->method->ssl3_enc->server_finished_label_len); | ||
512 | if (ret <= 0) goto end; | ||
513 | s->state=SSL3_ST_SW_FLUSH; | ||
514 | if (s->hit) | ||
515 | s->s3->tmp.next_state=SSL3_ST_SR_FINISHED_A; | ||
516 | else | ||
517 | s->s3->tmp.next_state=SSL_ST_OK; | ||
518 | s->init_num=0; | ||
519 | break; | ||
520 | |||
521 | case SSL_ST_OK: | ||
522 | /* clean a few things up */ | ||
523 | ssl3_cleanup_key_block(s); | ||
524 | |||
525 | #if 0 | ||
526 | BUF_MEM_free(s->init_buf); | ||
527 | s->init_buf=NULL; | ||
528 | #endif | ||
529 | |||
530 | /* remove buffering on output */ | ||
531 | ssl_free_wbio_buffer(s); | ||
532 | |||
533 | s->init_num=0; | ||
534 | |||
535 | if (s->new_session == 2) /* skipped if we just sent a HelloRequest */ | ||
536 | { | ||
537 | /* actually not necessarily a 'new' session unless | ||
538 | * SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION is set */ | ||
539 | |||
540 | s->new_session=0; | ||
541 | |||
542 | ssl_update_cache(s,SSL_SESS_CACHE_SERVER); | ||
543 | |||
544 | s->ctx->stats.sess_accept_good++; | ||
545 | /* s->server=1; */ | ||
546 | s->handshake_func=dtls1_accept; | ||
547 | |||
548 | if (cb != NULL) cb(s,SSL_CB_HANDSHAKE_DONE,1); | ||
549 | } | ||
550 | |||
551 | ret = 1; | ||
552 | |||
553 | /* done handshaking, next message is client hello */ | ||
554 | s->d1->handshake_read_seq = 0; | ||
555 | /* next message is server hello */ | ||
556 | s->d1->handshake_write_seq = 0; | ||
557 | goto end; | ||
558 | /* break; */ | ||
559 | |||
560 | default: | ||
561 | SSLerr(SSL_F_DTLS1_ACCEPT,SSL_R_UNKNOWN_STATE); | ||
562 | ret= -1; | ||
563 | goto end; | ||
564 | /* break; */ | ||
565 | } | ||
566 | |||
567 | if (!s->s3->tmp.reuse_message && !skip) | ||
568 | { | ||
569 | if (s->debug) | ||
570 | { | ||
571 | if ((ret=BIO_flush(s->wbio)) <= 0) | ||
572 | goto end; | ||
573 | } | ||
574 | |||
575 | |||
576 | if ((cb != NULL) && (s->state != state)) | ||
577 | { | ||
578 | new_state=s->state; | ||
579 | s->state=state; | ||
580 | cb(s,SSL_CB_ACCEPT_LOOP,1); | ||
581 | s->state=new_state; | ||
582 | } | ||
583 | } | ||
584 | skip=0; | ||
585 | } | ||
586 | end: | ||
587 | /* BIO_flush(s->wbio); */ | ||
588 | |||
589 | s->in_handshake--; | ||
590 | if (cb != NULL) | ||
591 | cb(s,SSL_CB_ACCEPT_EXIT,ret); | ||
592 | return(ret); | ||
593 | } | ||
594 | |||
595 | int dtls1_send_hello_request(SSL *s) | ||
596 | { | ||
597 | unsigned char *p; | ||
598 | |||
599 | if (s->state == SSL3_ST_SW_HELLO_REQ_A) | ||
600 | { | ||
601 | p=(unsigned char *)s->init_buf->data; | ||
602 | p = dtls1_set_message_header(s, p, SSL3_MT_HELLO_REQUEST, 0, 0, 0); | ||
603 | |||
604 | s->state=SSL3_ST_SW_HELLO_REQ_B; | ||
605 | /* number of bytes to write */ | ||
606 | s->init_num=DTLS1_HM_HEADER_LENGTH; | ||
607 | s->init_off=0; | ||
608 | |||
609 | /* no need to buffer this message, since there are no retransmit | ||
610 | * requests for it */ | ||
611 | } | ||
612 | |||
613 | /* SSL3_ST_SW_HELLO_REQ_B */ | ||
614 | return(dtls1_do_write(s,SSL3_RT_HANDSHAKE)); | ||
615 | } | ||
616 | |||
617 | int dtls1_send_hello_verify_request(SSL *s) | ||
618 | { | ||
619 | unsigned int msg_len; | ||
620 | unsigned char *msg, *buf, *p; | ||
621 | |||
622 | if (s->state == DTLS1_ST_SW_HELLO_VERIFY_REQUEST_A) | ||
623 | { | ||
624 | buf = (unsigned char *)s->init_buf->data; | ||
625 | |||
626 | msg = p = &(buf[DTLS1_HM_HEADER_LENGTH]); | ||
627 | if (s->client_version == DTLS1_BAD_VER) | ||
628 | *(p++) = DTLS1_BAD_VER>>8, | ||
629 | *(p++) = DTLS1_BAD_VER&0xff; | ||
630 | else | ||
631 | *(p++) = s->version >> 8, | ||
632 | *(p++) = s->version & 0xFF; | ||
633 | |||
634 | if (s->ctx->app_gen_cookie_cb != NULL && | ||
635 | s->ctx->app_gen_cookie_cb(s, s->d1->cookie, | ||
636 | &(s->d1->cookie_len)) == 0) | ||
637 | { | ||
638 | SSLerr(SSL_F_DTLS1_SEND_HELLO_VERIFY_REQUEST,ERR_R_INTERNAL_ERROR); | ||
639 | return 0; | ||
640 | } | ||
641 | /* else the cookie is assumed to have | ||
642 | * been initialized by the application */ | ||
643 | |||
644 | *(p++) = (unsigned char) s->d1->cookie_len; | ||
645 | memcpy(p, s->d1->cookie, s->d1->cookie_len); | ||
646 | p += s->d1->cookie_len; | ||
647 | msg_len = p - msg; | ||
648 | |||
649 | dtls1_set_message_header(s, buf, | ||
650 | DTLS1_MT_HELLO_VERIFY_REQUEST, msg_len, 0, msg_len); | ||
651 | |||
652 | s->state=DTLS1_ST_SW_HELLO_VERIFY_REQUEST_B; | ||
653 | /* number of bytes to write */ | ||
654 | s->init_num=p-buf; | ||
655 | s->init_off=0; | ||
656 | |||
657 | /* buffer the message to handle re-xmits */ | ||
658 | dtls1_buffer_message(s, 0); | ||
659 | } | ||
660 | |||
661 | /* s->state = DTLS1_ST_SW_HELLO_VERIFY_REQUEST_B */ | ||
662 | return(dtls1_do_write(s,SSL3_RT_HANDSHAKE)); | ||
663 | } | ||
664 | |||
665 | int dtls1_send_server_hello(SSL *s) | ||
666 | { | ||
667 | unsigned char *buf; | ||
668 | unsigned char *p,*d; | ||
669 | int i; | ||
670 | unsigned int sl; | ||
671 | unsigned long l,Time; | ||
672 | |||
673 | if (s->state == SSL3_ST_SW_SRVR_HELLO_A) | ||
674 | { | ||
675 | buf=(unsigned char *)s->init_buf->data; | ||
676 | p=s->s3->server_random; | ||
677 | Time=(unsigned long)time(NULL); /* Time */ | ||
678 | l2n(Time,p); | ||
679 | RAND_pseudo_bytes(p,SSL3_RANDOM_SIZE-sizeof(Time)); | ||
680 | /* Do the message type and length last */ | ||
681 | d=p= &(buf[DTLS1_HM_HEADER_LENGTH]); | ||
682 | |||
683 | if (s->client_version == DTLS1_BAD_VER) | ||
684 | *(p++)=DTLS1_BAD_VER>>8, | ||
685 | *(p++)=DTLS1_BAD_VER&0xff; | ||
686 | else | ||
687 | *(p++)=s->version>>8, | ||
688 | *(p++)=s->version&0xff; | ||
689 | |||
690 | /* Random stuff */ | ||
691 | memcpy(p,s->s3->server_random,SSL3_RANDOM_SIZE); | ||
692 | p+=SSL3_RANDOM_SIZE; | ||
693 | |||
694 | /* now in theory we have 3 options to sending back the | ||
695 | * session id. If it is a re-use, we send back the | ||
696 | * old session-id, if it is a new session, we send | ||
697 | * back the new session-id or we send back a 0 length | ||
698 | * session-id if we want it to be single use. | ||
699 | * Currently I will not implement the '0' length session-id | ||
700 | * 12-Jan-98 - I'll now support the '0' length stuff. | ||
701 | */ | ||
702 | if (!(s->ctx->session_cache_mode & SSL_SESS_CACHE_SERVER)) | ||
703 | s->session->session_id_length=0; | ||
704 | |||
705 | sl=s->session->session_id_length; | ||
706 | if (sl > sizeof s->session->session_id) | ||
707 | { | ||
708 | SSLerr(SSL_F_DTLS1_SEND_SERVER_HELLO, ERR_R_INTERNAL_ERROR); | ||
709 | return -1; | ||
710 | } | ||
711 | *(p++)=sl; | ||
712 | memcpy(p,s->session->session_id,sl); | ||
713 | p+=sl; | ||
714 | |||
715 | /* put the cipher */ | ||
716 | i=ssl3_put_cipher_by_char(s->s3->tmp.new_cipher,p); | ||
717 | p+=i; | ||
718 | |||
719 | /* put the compression method */ | ||
720 | #ifdef OPENSSL_NO_COMP | ||
721 | *(p++)=0; | ||
722 | #else | ||
723 | if (s->s3->tmp.new_compression == NULL) | ||
724 | *(p++)=0; | ||
725 | else | ||
726 | *(p++)=s->s3->tmp.new_compression->id; | ||
727 | #endif | ||
728 | |||
729 | /* do the header */ | ||
730 | l=(p-d); | ||
731 | d=buf; | ||
732 | |||
733 | d = dtls1_set_message_header(s, d, SSL3_MT_SERVER_HELLO, l, 0, l); | ||
734 | |||
735 | s->state=SSL3_ST_CW_CLNT_HELLO_B; | ||
736 | /* number of bytes to write */ | ||
737 | s->init_num=p-buf; | ||
738 | s->init_off=0; | ||
739 | |||
740 | /* buffer the message to handle re-xmits */ | ||
741 | dtls1_buffer_message(s, 0); | ||
742 | } | ||
743 | |||
744 | /* SSL3_ST_CW_CLNT_HELLO_B */ | ||
745 | return(dtls1_do_write(s,SSL3_RT_HANDSHAKE)); | ||
746 | } | ||
747 | |||
748 | int dtls1_send_server_done(SSL *s) | ||
749 | { | ||
750 | unsigned char *p; | ||
751 | |||
752 | if (s->state == SSL3_ST_SW_SRVR_DONE_A) | ||
753 | { | ||
754 | p=(unsigned char *)s->init_buf->data; | ||
755 | |||
756 | /* do the header */ | ||
757 | p = dtls1_set_message_header(s, p, SSL3_MT_SERVER_DONE, 0, 0, 0); | ||
758 | |||
759 | s->state=SSL3_ST_SW_SRVR_DONE_B; | ||
760 | /* number of bytes to write */ | ||
761 | s->init_num=DTLS1_HM_HEADER_LENGTH; | ||
762 | s->init_off=0; | ||
763 | |||
764 | /* buffer the message to handle re-xmits */ | ||
765 | dtls1_buffer_message(s, 0); | ||
766 | } | ||
767 | |||
768 | /* SSL3_ST_CW_CLNT_HELLO_B */ | ||
769 | return(dtls1_do_write(s,SSL3_RT_HANDSHAKE)); | ||
770 | } | ||
771 | |||
772 | int dtls1_send_server_key_exchange(SSL *s) | ||
773 | { | ||
774 | #ifndef OPENSSL_NO_RSA | ||
775 | unsigned char *q; | ||
776 | int j,num; | ||
777 | RSA *rsa; | ||
778 | unsigned char md_buf[MD5_DIGEST_LENGTH+SHA_DIGEST_LENGTH]; | ||
779 | unsigned int u; | ||
780 | #endif | ||
781 | #ifndef OPENSSL_NO_DH | ||
782 | DH *dh=NULL,*dhp; | ||
783 | #endif | ||
784 | EVP_PKEY *pkey; | ||
785 | unsigned char *p,*d; | ||
786 | int al,i; | ||
787 | unsigned long type; | ||
788 | int n; | ||
789 | CERT *cert; | ||
790 | BIGNUM *r[4]; | ||
791 | int nr[4],kn; | ||
792 | BUF_MEM *buf; | ||
793 | EVP_MD_CTX md_ctx; | ||
794 | |||
795 | EVP_MD_CTX_init(&md_ctx); | ||
796 | if (s->state == SSL3_ST_SW_KEY_EXCH_A) | ||
797 | { | ||
798 | type=s->s3->tmp.new_cipher->algorithms & SSL_MKEY_MASK; | ||
799 | cert=s->cert; | ||
800 | |||
801 | buf=s->init_buf; | ||
802 | |||
803 | r[0]=r[1]=r[2]=r[3]=NULL; | ||
804 | n=0; | ||
805 | #ifndef OPENSSL_NO_RSA | ||
806 | if (type & SSL_kRSA) | ||
807 | { | ||
808 | rsa=cert->rsa_tmp; | ||
809 | if ((rsa == NULL) && (s->cert->rsa_tmp_cb != NULL)) | ||
810 | { | ||
811 | rsa=s->cert->rsa_tmp_cb(s, | ||
812 | SSL_C_IS_EXPORT(s->s3->tmp.new_cipher), | ||
813 | SSL_C_EXPORT_PKEYLENGTH(s->s3->tmp.new_cipher)); | ||
814 | if(rsa == NULL) | ||
815 | { | ||
816 | al=SSL_AD_HANDSHAKE_FAILURE; | ||
817 | SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE,SSL_R_ERROR_GENERATING_TMP_RSA_KEY); | ||
818 | goto f_err; | ||
819 | } | ||
820 | RSA_up_ref(rsa); | ||
821 | cert->rsa_tmp=rsa; | ||
822 | } | ||
823 | if (rsa == NULL) | ||
824 | { | ||
825 | al=SSL_AD_HANDSHAKE_FAILURE; | ||
826 | SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE,SSL_R_MISSING_TMP_RSA_KEY); | ||
827 | goto f_err; | ||
828 | } | ||
829 | r[0]=rsa->n; | ||
830 | r[1]=rsa->e; | ||
831 | s->s3->tmp.use_rsa_tmp=1; | ||
832 | } | ||
833 | else | ||
834 | #endif | ||
835 | #ifndef OPENSSL_NO_DH | ||
836 | if (type & SSL_kEDH) | ||
837 | { | ||
838 | dhp=cert->dh_tmp; | ||
839 | if ((dhp == NULL) && (s->cert->dh_tmp_cb != NULL)) | ||
840 | dhp=s->cert->dh_tmp_cb(s, | ||
841 | SSL_C_IS_EXPORT(s->s3->tmp.new_cipher), | ||
842 | SSL_C_EXPORT_PKEYLENGTH(s->s3->tmp.new_cipher)); | ||
843 | if (dhp == NULL) | ||
844 | { | ||
845 | al=SSL_AD_HANDSHAKE_FAILURE; | ||
846 | SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE,SSL_R_MISSING_TMP_DH_KEY); | ||
847 | goto f_err; | ||
848 | } | ||
849 | |||
850 | if (s->s3->tmp.dh != NULL) | ||
851 | { | ||
852 | DH_free(dh); | ||
853 | SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR); | ||
854 | goto err; | ||
855 | } | ||
856 | |||
857 | if ((dh=DHparams_dup(dhp)) == NULL) | ||
858 | { | ||
859 | SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE,ERR_R_DH_LIB); | ||
860 | goto err; | ||
861 | } | ||
862 | |||
863 | s->s3->tmp.dh=dh; | ||
864 | if ((dhp->pub_key == NULL || | ||
865 | dhp->priv_key == NULL || | ||
866 | (s->options & SSL_OP_SINGLE_DH_USE))) | ||
867 | { | ||
868 | if(!DH_generate_key(dh)) | ||
869 | { | ||
870 | SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE, | ||
871 | ERR_R_DH_LIB); | ||
872 | goto err; | ||
873 | } | ||
874 | } | ||
875 | else | ||
876 | { | ||
877 | dh->pub_key=BN_dup(dhp->pub_key); | ||
878 | dh->priv_key=BN_dup(dhp->priv_key); | ||
879 | if ((dh->pub_key == NULL) || | ||
880 | (dh->priv_key == NULL)) | ||
881 | { | ||
882 | SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE,ERR_R_DH_LIB); | ||
883 | goto err; | ||
884 | } | ||
885 | } | ||
886 | r[0]=dh->p; | ||
887 | r[1]=dh->g; | ||
888 | r[2]=dh->pub_key; | ||
889 | } | ||
890 | else | ||
891 | #endif | ||
892 | { | ||
893 | al=SSL_AD_HANDSHAKE_FAILURE; | ||
894 | SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE,SSL_R_UNKNOWN_KEY_EXCHANGE_TYPE); | ||
895 | goto f_err; | ||
896 | } | ||
897 | for (i=0; r[i] != NULL; i++) | ||
898 | { | ||
899 | nr[i]=BN_num_bytes(r[i]); | ||
900 | n+=2+nr[i]; | ||
901 | } | ||
902 | |||
903 | if (!(s->s3->tmp.new_cipher->algorithms & SSL_aNULL)) | ||
904 | { | ||
905 | if ((pkey=ssl_get_sign_pkey(s,s->s3->tmp.new_cipher)) | ||
906 | == NULL) | ||
907 | { | ||
908 | al=SSL_AD_DECODE_ERROR; | ||
909 | goto f_err; | ||
910 | } | ||
911 | kn=EVP_PKEY_size(pkey); | ||
912 | } | ||
913 | else | ||
914 | { | ||
915 | pkey=NULL; | ||
916 | kn=0; | ||
917 | } | ||
918 | |||
919 | if (!BUF_MEM_grow_clean(buf,n+DTLS1_HM_HEADER_LENGTH+kn)) | ||
920 | { | ||
921 | SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE,ERR_LIB_BUF); | ||
922 | goto err; | ||
923 | } | ||
924 | d=(unsigned char *)s->init_buf->data; | ||
925 | p= &(d[DTLS1_HM_HEADER_LENGTH]); | ||
926 | |||
927 | for (i=0; r[i] != NULL; i++) | ||
928 | { | ||
929 | s2n(nr[i],p); | ||
930 | BN_bn2bin(r[i],p); | ||
931 | p+=nr[i]; | ||
932 | } | ||
933 | |||
934 | /* not anonymous */ | ||
935 | if (pkey != NULL) | ||
936 | { | ||
937 | /* n is the length of the params, they start at | ||
938 | * &(d[DTLS1_HM_HEADER_LENGTH]) and p points to the space | ||
939 | * at the end. */ | ||
940 | #ifndef OPENSSL_NO_RSA | ||
941 | if (pkey->type == EVP_PKEY_RSA) | ||
942 | { | ||
943 | q=md_buf; | ||
944 | j=0; | ||
945 | for (num=2; num > 0; num--) | ||
946 | { | ||
947 | EVP_DigestInit_ex(&md_ctx,(num == 2) | ||
948 | ?s->ctx->md5:s->ctx->sha1, NULL); | ||
949 | EVP_DigestUpdate(&md_ctx,&(s->s3->client_random[0]),SSL3_RANDOM_SIZE); | ||
950 | EVP_DigestUpdate(&md_ctx,&(s->s3->server_random[0]),SSL3_RANDOM_SIZE); | ||
951 | EVP_DigestUpdate(&md_ctx,&(d[DTLS1_HM_HEADER_LENGTH]),n); | ||
952 | EVP_DigestFinal_ex(&md_ctx,q, | ||
953 | (unsigned int *)&i); | ||
954 | q+=i; | ||
955 | j+=i; | ||
956 | } | ||
957 | if (RSA_sign(NID_md5_sha1, md_buf, j, | ||
958 | &(p[2]), &u, pkey->pkey.rsa) <= 0) | ||
959 | { | ||
960 | SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE,ERR_LIB_RSA); | ||
961 | goto err; | ||
962 | } | ||
963 | s2n(u,p); | ||
964 | n+=u+2; | ||
965 | } | ||
966 | else | ||
967 | #endif | ||
968 | #if !defined(OPENSSL_NO_DSA) | ||
969 | if (pkey->type == EVP_PKEY_DSA) | ||
970 | { | ||
971 | /* lets do DSS */ | ||
972 | EVP_SignInit_ex(&md_ctx,EVP_dss1(), NULL); | ||
973 | EVP_SignUpdate(&md_ctx,&(s->s3->client_random[0]),SSL3_RANDOM_SIZE); | ||
974 | EVP_SignUpdate(&md_ctx,&(s->s3->server_random[0]),SSL3_RANDOM_SIZE); | ||
975 | EVP_SignUpdate(&md_ctx,&(d[DTLS1_HM_HEADER_LENGTH]),n); | ||
976 | if (!EVP_SignFinal(&md_ctx,&(p[2]), | ||
977 | (unsigned int *)&i,pkey)) | ||
978 | { | ||
979 | SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE,ERR_LIB_DSA); | ||
980 | goto err; | ||
981 | } | ||
982 | s2n(i,p); | ||
983 | n+=i+2; | ||
984 | } | ||
985 | else | ||
986 | #endif | ||
987 | { | ||
988 | /* Is this error check actually needed? */ | ||
989 | al=SSL_AD_HANDSHAKE_FAILURE; | ||
990 | SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE,SSL_R_UNKNOWN_PKEY_TYPE); | ||
991 | goto f_err; | ||
992 | } | ||
993 | } | ||
994 | |||
995 | d = dtls1_set_message_header(s, d, | ||
996 | SSL3_MT_SERVER_KEY_EXCHANGE, n, 0, n); | ||
997 | |||
998 | /* we should now have things packed up, so lets send | ||
999 | * it off */ | ||
1000 | s->init_num=n+DTLS1_HM_HEADER_LENGTH; | ||
1001 | s->init_off=0; | ||
1002 | |||
1003 | /* buffer the message to handle re-xmits */ | ||
1004 | dtls1_buffer_message(s, 0); | ||
1005 | } | ||
1006 | |||
1007 | s->state = SSL3_ST_SW_KEY_EXCH_B; | ||
1008 | EVP_MD_CTX_cleanup(&md_ctx); | ||
1009 | return(dtls1_do_write(s,SSL3_RT_HANDSHAKE)); | ||
1010 | f_err: | ||
1011 | ssl3_send_alert(s,SSL3_AL_FATAL,al); | ||
1012 | err: | ||
1013 | EVP_MD_CTX_cleanup(&md_ctx); | ||
1014 | return(-1); | ||
1015 | } | ||
1016 | |||
1017 | int dtls1_send_certificate_request(SSL *s) | ||
1018 | { | ||
1019 | unsigned char *p,*d; | ||
1020 | int i,j,nl,off,n; | ||
1021 | STACK_OF(X509_NAME) *sk=NULL; | ||
1022 | X509_NAME *name; | ||
1023 | BUF_MEM *buf; | ||
1024 | unsigned int msg_len; | ||
1025 | |||
1026 | if (s->state == SSL3_ST_SW_CERT_REQ_A) | ||
1027 | { | ||
1028 | buf=s->init_buf; | ||
1029 | |||
1030 | d=p=(unsigned char *)&(buf->data[DTLS1_HM_HEADER_LENGTH]); | ||
1031 | |||
1032 | /* get the list of acceptable cert types */ | ||
1033 | p++; | ||
1034 | n=ssl3_get_req_cert_type(s,p); | ||
1035 | d[0]=n; | ||
1036 | p+=n; | ||
1037 | n++; | ||
1038 | |||
1039 | off=n; | ||
1040 | p+=2; | ||
1041 | n+=2; | ||
1042 | |||
1043 | sk=SSL_get_client_CA_list(s); | ||
1044 | nl=0; | ||
1045 | if (sk != NULL) | ||
1046 | { | ||
1047 | for (i=0; i<sk_X509_NAME_num(sk); i++) | ||
1048 | { | ||
1049 | name=sk_X509_NAME_value(sk,i); | ||
1050 | j=i2d_X509_NAME(name,NULL); | ||
1051 | if (!BUF_MEM_grow_clean(buf,DTLS1_HM_HEADER_LENGTH+n+j+2)) | ||
1052 | { | ||
1053 | SSLerr(SSL_F_DTLS1_SEND_CERTIFICATE_REQUEST,ERR_R_BUF_LIB); | ||
1054 | goto err; | ||
1055 | } | ||
1056 | p=(unsigned char *)&(buf->data[DTLS1_HM_HEADER_LENGTH+n]); | ||
1057 | if (!(s->options & SSL_OP_NETSCAPE_CA_DN_BUG)) | ||
1058 | { | ||
1059 | s2n(j,p); | ||
1060 | i2d_X509_NAME(name,&p); | ||
1061 | n+=2+j; | ||
1062 | nl+=2+j; | ||
1063 | } | ||
1064 | else | ||
1065 | { | ||
1066 | d=p; | ||
1067 | i2d_X509_NAME(name,&p); | ||
1068 | j-=2; s2n(j,d); j+=2; | ||
1069 | n+=j; | ||
1070 | nl+=j; | ||
1071 | } | ||
1072 | } | ||
1073 | } | ||
1074 | /* else no CA names */ | ||
1075 | p=(unsigned char *)&(buf->data[DTLS1_HM_HEADER_LENGTH+off]); | ||
1076 | s2n(nl,p); | ||
1077 | |||
1078 | d=(unsigned char *)buf->data; | ||
1079 | *(d++)=SSL3_MT_CERTIFICATE_REQUEST; | ||
1080 | l2n3(n,d); | ||
1081 | s2n(s->d1->handshake_write_seq,d); | ||
1082 | s->d1->handshake_write_seq++; | ||
1083 | |||
1084 | /* we should now have things packed up, so lets send | ||
1085 | * it off */ | ||
1086 | |||
1087 | s->init_num=n+DTLS1_HM_HEADER_LENGTH; | ||
1088 | s->init_off=0; | ||
1089 | #ifdef NETSCAPE_HANG_BUG | ||
1090 | /* XXX: what to do about this? */ | ||
1091 | p=(unsigned char *)s->init_buf->data + s->init_num; | ||
1092 | |||
1093 | /* do the header */ | ||
1094 | *(p++)=SSL3_MT_SERVER_DONE; | ||
1095 | *(p++)=0; | ||
1096 | *(p++)=0; | ||
1097 | *(p++)=0; | ||
1098 | s->init_num += 4; | ||
1099 | #endif | ||
1100 | |||
1101 | /* XDTLS: set message header ? */ | ||
1102 | msg_len = s->init_num - DTLS1_HM_HEADER_LENGTH; | ||
1103 | dtls1_set_message_header(s, (void *)s->init_buf->data, | ||
1104 | SSL3_MT_CERTIFICATE_REQUEST, msg_len, 0, msg_len); | ||
1105 | |||
1106 | /* buffer the message to handle re-xmits */ | ||
1107 | dtls1_buffer_message(s, 0); | ||
1108 | |||
1109 | s->state = SSL3_ST_SW_CERT_REQ_B; | ||
1110 | } | ||
1111 | |||
1112 | /* SSL3_ST_SW_CERT_REQ_B */ | ||
1113 | return(dtls1_do_write(s,SSL3_RT_HANDSHAKE)); | ||
1114 | err: | ||
1115 | return(-1); | ||
1116 | } | ||
1117 | |||
1118 | int dtls1_send_server_certificate(SSL *s) | ||
1119 | { | ||
1120 | unsigned long l; | ||
1121 | X509 *x; | ||
1122 | |||
1123 | if (s->state == SSL3_ST_SW_CERT_A) | ||
1124 | { | ||
1125 | x=ssl_get_server_send_cert(s); | ||
1126 | if (x == NULL && | ||
1127 | /* VRS: allow null cert if auth == KRB5 */ | ||
1128 | (s->s3->tmp.new_cipher->algorithms | ||
1129 | & (SSL_MKEY_MASK|SSL_AUTH_MASK)) | ||
1130 | != (SSL_aKRB5|SSL_kKRB5)) | ||
1131 | { | ||
1132 | SSLerr(SSL_F_DTLS1_SEND_SERVER_CERTIFICATE,ERR_R_INTERNAL_ERROR); | ||
1133 | return(0); | ||
1134 | } | ||
1135 | |||
1136 | l=dtls1_output_cert_chain(s,x); | ||
1137 | s->state=SSL3_ST_SW_CERT_B; | ||
1138 | s->init_num=(int)l; | ||
1139 | s->init_off=0; | ||
1140 | |||
1141 | /* buffer the message to handle re-xmits */ | ||
1142 | dtls1_buffer_message(s, 0); | ||
1143 | } | ||
1144 | |||
1145 | /* SSL3_ST_SW_CERT_B */ | ||
1146 | return(dtls1_do_write(s,SSL3_RT_HANDSHAKE)); | ||
1147 | } | ||
diff --git a/src/lib/libssl/dtls1.h b/src/lib/libssl/dtls1.h new file mode 100644 index 0000000000..a663cf85f2 --- /dev/null +++ b/src/lib/libssl/dtls1.h | |||
@@ -0,0 +1,211 @@ | |||
1 | /* ssl/dtls1.h */ | ||
2 | /* | ||
3 | * DTLS implementation written by Nagendra Modadugu | ||
4 | * (nagendra@cs.stanford.edu) for the OpenSSL project 2005. | ||
5 | */ | ||
6 | /* ==================================================================== | ||
7 | * Copyright (c) 1999-2005 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 | * openssl-core@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 | * This product includes cryptographic software written by Eric Young | ||
55 | * (eay@cryptsoft.com). This product includes software written by Tim | ||
56 | * Hudson (tjh@cryptsoft.com). | ||
57 | * | ||
58 | */ | ||
59 | |||
60 | #ifndef HEADER_DTLS1_H | ||
61 | #define HEADER_DTLS1_H | ||
62 | |||
63 | #include <openssl/buffer.h> | ||
64 | #include <openssl/pqueue.h> | ||
65 | |||
66 | #ifdef __cplusplus | ||
67 | extern "C" { | ||
68 | #endif | ||
69 | |||
70 | #define DTLS1_VERSION 0xFEFF | ||
71 | #define DTLS1_BAD_VER 0x0100 | ||
72 | |||
73 | #define DTLS1_AD_MISSING_HANDSHAKE_MESSAGE 110 | ||
74 | |||
75 | /* lengths of messages */ | ||
76 | #define DTLS1_COOKIE_LENGTH 32 | ||
77 | |||
78 | #define DTLS1_RT_HEADER_LENGTH 13 | ||
79 | |||
80 | #define DTLS1_HM_HEADER_LENGTH 12 | ||
81 | |||
82 | #define DTLS1_HM_BAD_FRAGMENT -2 | ||
83 | #define DTLS1_HM_FRAGMENT_RETRY -3 | ||
84 | |||
85 | #define DTLS1_CCS_HEADER_LENGTH 1 | ||
86 | |||
87 | #define DTLS1_AL_HEADER_LENGTH 7 | ||
88 | |||
89 | |||
90 | typedef struct dtls1_bitmap_st | ||
91 | { | ||
92 | PQ_64BIT map; | ||
93 | unsigned long length; /* sizeof the bitmap in bits */ | ||
94 | PQ_64BIT max_seq_num; /* max record number seen so far */ | ||
95 | } DTLS1_BITMAP; | ||
96 | |||
97 | struct hm_header_st | ||
98 | { | ||
99 | unsigned char type; | ||
100 | unsigned long msg_len; | ||
101 | unsigned short seq; | ||
102 | unsigned long frag_off; | ||
103 | unsigned long frag_len; | ||
104 | unsigned int is_ccs; | ||
105 | }; | ||
106 | |||
107 | struct ccs_header_st | ||
108 | { | ||
109 | unsigned char type; | ||
110 | unsigned short seq; | ||
111 | }; | ||
112 | |||
113 | struct dtls1_timeout_st | ||
114 | { | ||
115 | /* Number of read timeouts so far */ | ||
116 | unsigned int read_timeouts; | ||
117 | |||
118 | /* Number of write timeouts so far */ | ||
119 | unsigned int write_timeouts; | ||
120 | |||
121 | /* Number of alerts received so far */ | ||
122 | unsigned int num_alerts; | ||
123 | }; | ||
124 | |||
125 | typedef struct record_pqueue_st | ||
126 | { | ||
127 | unsigned short epoch; | ||
128 | pqueue q; | ||
129 | } record_pqueue; | ||
130 | |||
131 | typedef struct hm_fragment_st | ||
132 | { | ||
133 | struct hm_header_st msg_header; | ||
134 | unsigned char *fragment; | ||
135 | } hm_fragment; | ||
136 | |||
137 | typedef struct dtls1_state_st | ||
138 | { | ||
139 | unsigned int send_cookie; | ||
140 | unsigned char cookie[DTLS1_COOKIE_LENGTH]; | ||
141 | unsigned char rcvd_cookie[DTLS1_COOKIE_LENGTH]; | ||
142 | unsigned int cookie_len; | ||
143 | |||
144 | /* | ||
145 | * The current data and handshake epoch. This is initially | ||
146 | * undefined, and starts at zero once the initial handshake is | ||
147 | * completed | ||
148 | */ | ||
149 | unsigned short r_epoch; | ||
150 | unsigned short w_epoch; | ||
151 | |||
152 | /* records being received in the current epoch */ | ||
153 | DTLS1_BITMAP bitmap; | ||
154 | |||
155 | /* renegotiation starts a new set of sequence numbers */ | ||
156 | DTLS1_BITMAP next_bitmap; | ||
157 | |||
158 | /* handshake message numbers */ | ||
159 | unsigned short handshake_write_seq; | ||
160 | unsigned short next_handshake_write_seq; | ||
161 | |||
162 | unsigned short handshake_read_seq; | ||
163 | |||
164 | /* Received handshake records (processed and unprocessed) */ | ||
165 | record_pqueue unprocessed_rcds; | ||
166 | record_pqueue processed_rcds; | ||
167 | |||
168 | /* Buffered handshake messages */ | ||
169 | pqueue buffered_messages; | ||
170 | |||
171 | /* Buffered (sent) handshake records */ | ||
172 | pqueue sent_messages; | ||
173 | |||
174 | unsigned int mtu; /* max wire packet size */ | ||
175 | |||
176 | struct hm_header_st w_msg_hdr; | ||
177 | struct hm_header_st r_msg_hdr; | ||
178 | |||
179 | struct dtls1_timeout_st timeout; | ||
180 | |||
181 | /* storage for Alert/Handshake protocol data received but not | ||
182 | * yet processed by ssl3_read_bytes: */ | ||
183 | unsigned char alert_fragment[DTLS1_AL_HEADER_LENGTH]; | ||
184 | unsigned int alert_fragment_len; | ||
185 | unsigned char handshake_fragment[DTLS1_HM_HEADER_LENGTH]; | ||
186 | unsigned int handshake_fragment_len; | ||
187 | |||
188 | unsigned int retransmitting; | ||
189 | |||
190 | } DTLS1_STATE; | ||
191 | |||
192 | typedef struct dtls1_record_data_st | ||
193 | { | ||
194 | unsigned char *packet; | ||
195 | unsigned int packet_length; | ||
196 | SSL3_BUFFER rbuf; | ||
197 | SSL3_RECORD rrec; | ||
198 | } DTLS1_RECORD_DATA; | ||
199 | |||
200 | |||
201 | /* Timeout multipliers (timeout slice is defined in apps/timeouts.h */ | ||
202 | #define DTLS1_TMO_READ_COUNT 2 | ||
203 | #define DTLS1_TMO_WRITE_COUNT 2 | ||
204 | |||
205 | #define DTLS1_TMO_ALERT_COUNT 12 | ||
206 | |||
207 | #ifdef __cplusplus | ||
208 | } | ||
209 | #endif | ||
210 | #endif | ||
211 | |||
diff --git a/src/lib/libssl/test/CAss.cnf b/src/lib/libssl/test/CAss.cnf index 21da59a73a..20f8f05e3d 100644 --- a/src/lib/libssl/test/CAss.cnf +++ b/src/lib/libssl/test/CAss.cnf | |||
@@ -24,10 +24,53 @@ organizationName_value = Dodgy Brothers | |||
24 | commonName = Common Name (eg, YOUR name) | 24 | commonName = Common Name (eg, YOUR name) |
25 | commonName_value = Dodgy CA | 25 | commonName_value = Dodgy CA |
26 | 26 | ||
27 | #################################################################### | ||
28 | [ ca ] | ||
29 | default_ca = CA_default # The default ca section | ||
30 | |||
31 | #################################################################### | ||
32 | [ CA_default ] | ||
33 | |||
34 | dir = ./demoCA # Where everything is kept | ||
35 | certs = $dir/certs # Where the issued certs are kept | ||
36 | crl_dir = $dir/crl # Where the issued crl are kept | ||
37 | database = $dir/index.txt # database index file. | ||
38 | #unique_subject = no # Set to 'no' to allow creation of | ||
39 | # several ctificates with same subject. | ||
40 | new_certs_dir = $dir/newcerts # default place for new certs. | ||
41 | |||
42 | certificate = $dir/cacert.pem # The CA certificate | ||
43 | serial = $dir/serial # The current serial number | ||
44 | crl = $dir/crl.pem # The current CRL | ||
45 | private_key = $dir/private/cakey.pem# The private key | ||
46 | RANDFILE = $dir/private/.rand # private random number file | ||
47 | |||
48 | x509_extensions = v3_ca # The extentions to add to the cert | ||
49 | |||
50 | name_opt = ca_default # Subject Name options | ||
51 | cert_opt = ca_default # Certificate field options | ||
52 | |||
53 | default_days = 365 # how long to certify for | ||
54 | default_crl_days= 30 # how long before next CRL | ||
55 | default_md = md5 # which md to use. | ||
56 | preserve = no # keep passed DN ordering | ||
57 | |||
58 | policy = policy_anything | ||
59 | |||
60 | [ policy_anything ] | ||
61 | countryName = optional | ||
62 | stateOrProvinceName = optional | ||
63 | localityName = optional | ||
64 | organizationName = optional | ||
65 | organizationalUnitName = optional | ||
66 | commonName = supplied | ||
67 | emailAddress = optional | ||
68 | |||
69 | |||
70 | |||
27 | [ v3_ca ] | 71 | [ v3_ca ] |
28 | subjectKeyIdentifier=hash | 72 | subjectKeyIdentifier=hash |
29 | authorityKeyIdentifier=keyid:always,issuer:always | 73 | authorityKeyIdentifier=keyid:always,issuer:always |
30 | basicConstraints = CA:true,pathlen:1 | 74 | basicConstraints = CA:true,pathlen:1 |
31 | keyUsage = cRLSign, keyCertSign | 75 | keyUsage = cRLSign, keyCertSign |
32 | issuerAltName=issuer:copy | 76 | issuerAltName=issuer:copy |
33 | |||
diff --git a/src/lib/libssl/test/cms-examples.pl b/src/lib/libssl/test/cms-examples.pl new file mode 100644 index 0000000000..2e95b48ba4 --- /dev/null +++ b/src/lib/libssl/test/cms-examples.pl | |||
@@ -0,0 +1,409 @@ | |||
1 | # test/cms-examples.pl | ||
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 | # Perl script to run tests against S/MIME examples in RFC4134 | ||
54 | # Assumes RFC is in current directory and called "rfc4134.txt" | ||
55 | |||
56 | use MIME::Base64; | ||
57 | |||
58 | my $badttest = 0; | ||
59 | my $verbose = 1; | ||
60 | |||
61 | my $cmscmd; | ||
62 | my $exdir = "./"; | ||
63 | my $exfile = "./rfc4134.txt"; | ||
64 | |||
65 | if (-f "../apps/openssl") | ||
66 | { | ||
67 | $cmscmd = "../util/shlib_wrap.sh ../apps/openssl cms"; | ||
68 | } | ||
69 | elsif (-f "..\\out32dll\\openssl.exe") | ||
70 | { | ||
71 | $cmscmd = "..\\out32dll\\openssl.exe cms"; | ||
72 | } | ||
73 | elsif (-f "..\\out32\\openssl.exe") | ||
74 | { | ||
75 | $cmscmd = "..\\out32\\openssl.exe cms"; | ||
76 | } | ||
77 | |||
78 | my @test_list = ( | ||
79 | [ "3.1.bin" => "dataout" ], | ||
80 | [ "3.2.bin" => "encode, dataout" ], | ||
81 | [ "4.1.bin" => "encode, verifyder, cont, dss" ], | ||
82 | [ "4.2.bin" => "encode, verifyder, cont, rsa" ], | ||
83 | [ "4.3.bin" => "encode, verifyder, cont_extern, dss" ], | ||
84 | [ "4.4.bin" => "encode, verifyder, cont, dss" ], | ||
85 | [ "4.5.bin" => "verifyder, cont, rsa" ], | ||
86 | [ "4.6.bin" => "encode, verifyder, cont, dss" ], | ||
87 | [ "4.7.bin" => "encode, verifyder, cont, dss" ], | ||
88 | [ "4.8.eml" => "verifymime, dss" ], | ||
89 | [ "4.9.eml" => "verifymime, dss" ], | ||
90 | [ "4.10.bin" => "encode, verifyder, cont, dss" ], | ||
91 | [ "4.11.bin" => "encode, certsout" ], | ||
92 | [ "5.1.bin" => "encode, envelopeder, cont" ], | ||
93 | [ "5.2.bin" => "encode, envelopeder, cont" ], | ||
94 | [ "5.3.eml" => "envelopemime, cont" ], | ||
95 | [ "6.0.bin" => "encode, digest, cont" ], | ||
96 | [ "7.1.bin" => "encode, encrypted, cont" ], | ||
97 | [ "7.2.bin" => "encode, encrypted, cont" ] | ||
98 | ); | ||
99 | |||
100 | # Extract examples from RFC4134 text. | ||
101 | # Base64 decode all examples, certificates and | ||
102 | # private keys are converted to PEM format. | ||
103 | |||
104 | my ( $filename, $data ); | ||
105 | |||
106 | my @cleanup = ( "cms.out", "cms.err", "tmp.der", "tmp.txt" ); | ||
107 | |||
108 | $data = ""; | ||
109 | |||
110 | open( IN, $exfile ) || die "Can't Open RFC examples file $exfile"; | ||
111 | |||
112 | while (<IN>) { | ||
113 | next unless (/^\|/); | ||
114 | s/^\|//; | ||
115 | next if (/^\*/); | ||
116 | if (/^>(.*)$/) { | ||
117 | $filename = $1; | ||
118 | next; | ||
119 | } | ||
120 | if (/^</) { | ||
121 | $filename = "$exdir/$filename"; | ||
122 | if ( $filename =~ /\.bin$/ || $filename =~ /\.eml$/ ) { | ||
123 | $data = decode_base64($data); | ||
124 | open OUT, ">$filename"; | ||
125 | binmode OUT; | ||
126 | print OUT $data; | ||
127 | close OUT; | ||
128 | push @cleanup, $filename; | ||
129 | } | ||
130 | elsif ( $filename =~ /\.cer$/ ) { | ||
131 | write_pem( $filename, "CERTIFICATE", $data ); | ||
132 | } | ||
133 | elsif ( $filename =~ /\.pri$/ ) { | ||
134 | write_pem( $filename, "PRIVATE KEY", $data ); | ||
135 | } | ||
136 | $data = ""; | ||
137 | $filename = ""; | ||
138 | } | ||
139 | else { | ||
140 | $data .= $_; | ||
141 | } | ||
142 | |||
143 | } | ||
144 | |||
145 | my $secretkey = | ||
146 | "73:7c:79:1f:25:ea:d0:e0:46:29:25:43:52:f7:dc:62:91:e5:cb:26:91:7a:da:32"; | ||
147 | |||
148 | foreach (@test_list) { | ||
149 | my ( $file, $tlist ) = @$_; | ||
150 | print "Example file $file:\n"; | ||
151 | if ( $tlist =~ /encode/ ) { | ||
152 | run_reencode_test( $exdir, $file ); | ||
153 | } | ||
154 | if ( $tlist =~ /certsout/ ) { | ||
155 | run_certsout_test( $exdir, $file ); | ||
156 | } | ||
157 | if ( $tlist =~ /dataout/ ) { | ||
158 | run_dataout_test( $exdir, $file ); | ||
159 | } | ||
160 | if ( $tlist =~ /verify/ ) { | ||
161 | run_verify_test( $exdir, $tlist, $file ); | ||
162 | } | ||
163 | if ( $tlist =~ /digest/ ) { | ||
164 | run_digest_test( $exdir, $tlist, $file ); | ||
165 | } | ||
166 | if ( $tlist =~ /encrypted/ ) { | ||
167 | run_encrypted_test( $exdir, $tlist, $file, $secretkey ); | ||
168 | } | ||
169 | if ( $tlist =~ /envelope/ ) { | ||
170 | run_envelope_test( $exdir, $tlist, $file ); | ||
171 | } | ||
172 | |||
173 | } | ||
174 | |||
175 | foreach (@cleanup) { | ||
176 | unlink $_; | ||
177 | } | ||
178 | |||
179 | if ($badtest) { | ||
180 | print "\n$badtest TESTS FAILED!!\n"; | ||
181 | } | ||
182 | else { | ||
183 | print "\n***All tests successful***\n"; | ||
184 | } | ||
185 | |||
186 | sub write_pem { | ||
187 | my ( $filename, $str, $data ) = @_; | ||
188 | |||
189 | $filename =~ s/\.[^.]*$/.pem/; | ||
190 | |||
191 | push @cleanup, $filename; | ||
192 | |||
193 | open OUT, ">$filename"; | ||
194 | |||
195 | print OUT "-----BEGIN $str-----\n"; | ||
196 | print OUT $data; | ||
197 | print OUT "-----END $str-----\n"; | ||
198 | |||
199 | close OUT; | ||
200 | } | ||
201 | |||
202 | sub run_reencode_test { | ||
203 | my ( $cmsdir, $tfile ) = @_; | ||
204 | unlink "tmp.der"; | ||
205 | |||
206 | system( "$cmscmd -cmsout -inform DER -outform DER" | ||
207 | . " -in $cmsdir/$tfile -out tmp.der" ); | ||
208 | |||
209 | if ($?) { | ||
210 | print "\tReencode command FAILED!!\n"; | ||
211 | $badtest++; | ||
212 | } | ||
213 | elsif ( !cmp_files( "$cmsdir/$tfile", "tmp.der" ) ) { | ||
214 | print "\tReencode FAILED!!\n"; | ||
215 | $badtest++; | ||
216 | } | ||
217 | else { | ||
218 | print "\tReencode passed\n" if $verbose; | ||
219 | } | ||
220 | } | ||
221 | |||
222 | sub run_certsout_test { | ||
223 | my ( $cmsdir, $tfile ) = @_; | ||
224 | unlink "tmp.der"; | ||
225 | unlink "tmp.pem"; | ||
226 | |||
227 | system( "$cmscmd -cmsout -inform DER -certsout tmp.pem" | ||
228 | . " -in $cmsdir/$tfile -out tmp.der" ); | ||
229 | |||
230 | if ($?) { | ||
231 | print "\tCertificate output command FAILED!!\n"; | ||
232 | $badtest++; | ||
233 | } | ||
234 | else { | ||
235 | print "\tCertificate output passed\n" if $verbose; | ||
236 | } | ||
237 | } | ||
238 | |||
239 | sub run_dataout_test { | ||
240 | my ( $cmsdir, $tfile ) = @_; | ||
241 | unlink "tmp.txt"; | ||
242 | |||
243 | system( | ||
244 | "$cmscmd -data_out -inform DER" . " -in $cmsdir/$tfile -out tmp.txt" ); | ||
245 | |||
246 | if ($?) { | ||
247 | print "\tDataout command FAILED!!\n"; | ||
248 | $badtest++; | ||
249 | } | ||
250 | elsif ( !cmp_files( "$cmsdir/ExContent.bin", "tmp.txt" ) ) { | ||
251 | print "\tDataout compare FAILED!!\n"; | ||
252 | $badtest++; | ||
253 | } | ||
254 | else { | ||
255 | print "\tDataout passed\n" if $verbose; | ||
256 | } | ||
257 | } | ||
258 | |||
259 | sub run_verify_test { | ||
260 | my ( $cmsdir, $tlist, $tfile ) = @_; | ||
261 | unlink "tmp.txt"; | ||
262 | |||
263 | $form = "DER" if $tlist =~ /verifyder/; | ||
264 | $form = "SMIME" if $tlist =~ /verifymime/; | ||
265 | $cafile = "$cmsdir/CarlDSSSelf.pem" if $tlist =~ /dss/; | ||
266 | $cafile = "$cmsdir/CarlRSASelf.pem" if $tlist =~ /rsa/; | ||
267 | |||
268 | $cmd = | ||
269 | "$cmscmd -verify -inform $form" | ||
270 | . " -CAfile $cafile" | ||
271 | . " -in $cmsdir/$tfile -out tmp.txt"; | ||
272 | |||
273 | $cmd .= " -content $cmsdir/ExContent.bin" if $tlist =~ /cont_extern/; | ||
274 | |||
275 | system("$cmd 2>cms.err 1>cms.out"); | ||
276 | |||
277 | if ($?) { | ||
278 | print "\tVerify command FAILED!!\n"; | ||
279 | $badtest++; | ||
280 | } | ||
281 | elsif ( $tlist =~ /cont/ | ||
282 | && !cmp_files( "$cmsdir/ExContent.bin", "tmp.txt" ) ) | ||
283 | { | ||
284 | print "\tVerify content compare FAILED!!\n"; | ||
285 | $badtest++; | ||
286 | } | ||
287 | else { | ||
288 | print "\tVerify passed\n" if $verbose; | ||
289 | } | ||
290 | } | ||
291 | |||
292 | sub run_envelope_test { | ||
293 | my ( $cmsdir, $tlist, $tfile ) = @_; | ||
294 | unlink "tmp.txt"; | ||
295 | |||
296 | $form = "DER" if $tlist =~ /envelopeder/; | ||
297 | $form = "SMIME" if $tlist =~ /envelopemime/; | ||
298 | |||
299 | $cmd = | ||
300 | "$cmscmd -decrypt -inform $form" | ||
301 | . " -recip $cmsdir/BobRSASignByCarl.pem" | ||
302 | . " -inkey $cmsdir/BobPrivRSAEncrypt.pem" | ||
303 | . " -in $cmsdir/$tfile -out tmp.txt"; | ||
304 | |||
305 | system("$cmd 2>cms.err 1>cms.out"); | ||
306 | |||
307 | if ($?) { | ||
308 | print "\tDecrypt command FAILED!!\n"; | ||
309 | $badtest++; | ||
310 | } | ||
311 | elsif ( $tlist =~ /cont/ | ||
312 | && !cmp_files( "$cmsdir/ExContent.bin", "tmp.txt" ) ) | ||
313 | { | ||
314 | print "\tDecrypt content compare FAILED!!\n"; | ||
315 | $badtest++; | ||
316 | } | ||
317 | else { | ||
318 | print "\tDecrypt passed\n" if $verbose; | ||
319 | } | ||
320 | } | ||
321 | |||
322 | sub run_digest_test { | ||
323 | my ( $cmsdir, $tlist, $tfile ) = @_; | ||
324 | unlink "tmp.txt"; | ||
325 | |||
326 | my $cmd = | ||
327 | "$cmscmd -digest_verify -inform DER" . " -in $cmsdir/$tfile -out tmp.txt"; | ||
328 | |||
329 | system("$cmd 2>cms.err 1>cms.out"); | ||
330 | |||
331 | if ($?) { | ||
332 | print "\tDigest verify command FAILED!!\n"; | ||
333 | $badtest++; | ||
334 | } | ||
335 | elsif ( $tlist =~ /cont/ | ||
336 | && !cmp_files( "$cmsdir/ExContent.bin", "tmp.txt" ) ) | ||
337 | { | ||
338 | print "\tDigest verify content compare FAILED!!\n"; | ||
339 | $badtest++; | ||
340 | } | ||
341 | else { | ||
342 | print "\tDigest verify passed\n" if $verbose; | ||
343 | } | ||
344 | } | ||
345 | |||
346 | sub run_encrypted_test { | ||
347 | my ( $cmsdir, $tlist, $tfile, $key ) = @_; | ||
348 | unlink "tmp.txt"; | ||
349 | |||
350 | system( "$cmscmd -EncryptedData_decrypt -inform DER" | ||
351 | . " -secretkey $key" | ||
352 | . " -in $cmsdir/$tfile -out tmp.txt" ); | ||
353 | |||
354 | if ($?) { | ||
355 | print "\tEncrypted Data command FAILED!!\n"; | ||
356 | $badtest++; | ||
357 | } | ||
358 | elsif ( $tlist =~ /cont/ | ||
359 | && !cmp_files( "$cmsdir/ExContent.bin", "tmp.txt" ) ) | ||
360 | { | ||
361 | print "\tEncrypted Data content compare FAILED!!\n"; | ||
362 | $badtest++; | ||
363 | } | ||
364 | else { | ||
365 | print "\tEncryptedData verify passed\n" if $verbose; | ||
366 | } | ||
367 | } | ||
368 | |||
369 | sub cmp_files { | ||
370 | my ( $f1, $f2 ) = @_; | ||
371 | my ( $fp1, $fp2 ); | ||
372 | |||
373 | my ( $rd1, $rd2 ); | ||
374 | |||
375 | if ( !open( $fp1, "<$f1" ) ) { | ||
376 | print STDERR "Can't Open file $f1\n"; | ||
377 | return 0; | ||
378 | } | ||
379 | |||
380 | if ( !open( $fp2, "<$f2" ) ) { | ||
381 | print STDERR "Can't Open file $f2\n"; | ||
382 | return 0; | ||
383 | } | ||
384 | |||
385 | binmode $fp1; | ||
386 | binmode $fp2; | ||
387 | |||
388 | my $ret = 0; | ||
389 | |||
390 | for ( ; ; ) { | ||
391 | $n1 = sysread $fp1, $rd1, 4096; | ||
392 | $n2 = sysread $fp2, $rd2, 4096; | ||
393 | last if ( $n1 != $n2 ); | ||
394 | last if ( $rd1 ne $rd2 ); | ||
395 | |||
396 | if ( $n1 == 0 ) { | ||
397 | $ret = 1; | ||
398 | last; | ||
399 | } | ||
400 | |||
401 | } | ||
402 | |||
403 | close $fp1; | ||
404 | close $fp2; | ||
405 | |||
406 | return $ret; | ||
407 | |||
408 | } | ||
409 | |||
diff --git a/src/lib/libssl/test/cms-test.pl b/src/lib/libssl/test/cms-test.pl new file mode 100644 index 0000000000..a84e089ddc --- /dev/null +++ b/src/lib/libssl/test/cms-test.pl | |||
@@ -0,0 +1,453 @@ | |||
1 | # test/cms-test.pl | ||
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 | # CMS, PKCS7 consistency test script. Run extensive tests on | ||
54 | # OpenSSL PKCS#7 and CMS implementations. | ||
55 | |||
56 | my $ossl_path; | ||
57 | |||
58 | if ( -f "../apps/openssl" ) { | ||
59 | $ossl_path = "../util/shlib_wrap.sh ../apps/openssl"; | ||
60 | } | ||
61 | elsif ( -f "..\\out32dll\\openssl.exe" ) { | ||
62 | $ossl_path = "..\\out32dll\\openssl.exe"; | ||
63 | } | ||
64 | elsif ( -f "..\\out32\\openssl.exe" ) { | ||
65 | $ossl_path = "..\\out32\\openssl.exe"; | ||
66 | } | ||
67 | else { | ||
68 | die "Can't find OpenSSL executable"; | ||
69 | } | ||
70 | |||
71 | my $pk7cmd = "$ossl_path smime "; | ||
72 | my $cmscmd = "$ossl_path cms "; | ||
73 | my $smdir = "smime-certs"; | ||
74 | my $halt_err = 1; | ||
75 | |||
76 | my $badcmd = 0; | ||
77 | my $ossl8 = `$ossl_path version -v` =~ /0\.9\.8/; | ||
78 | |||
79 | my @smime_pkcs7_tests = ( | ||
80 | |||
81 | [ | ||
82 | "signed content DER format, RSA key", | ||
83 | "-sign -in smcont.txt -outform DER -nodetach" | ||
84 | . " -certfile $smdir/smroot.pem" | ||
85 | . " -signer $smdir/smrsa1.pem -out test.cms", | ||
86 | "-verify -in test.cms -inform DER " | ||
87 | . " -CAfile $smdir/smroot.pem -out smtst.txt" | ||
88 | ], | ||
89 | |||
90 | [ | ||
91 | "signed detached content DER format, RSA key", | ||
92 | "-sign -in smcont.txt -outform DER" | ||
93 | . " -signer $smdir/smrsa1.pem -out test.cms", | ||
94 | "-verify -in test.cms -inform DER " | ||
95 | . " -CAfile $smdir/smroot.pem -out smtst.txt -content smcont.txt" | ||
96 | ], | ||
97 | |||
98 | [ | ||
99 | "signed content test streaming BER format, RSA", | ||
100 | "-sign -in smcont.txt -outform DER -nodetach" | ||
101 | . " -stream -signer $smdir/smrsa1.pem -out test.cms", | ||
102 | "-verify -in test.cms -inform DER " | ||
103 | . " -CAfile $smdir/smroot.pem -out smtst.txt" | ||
104 | ], | ||
105 | |||
106 | [ | ||
107 | "signed content DER format, DSA key", | ||
108 | "-sign -in smcont.txt -outform DER -nodetach" | ||
109 | . " -signer $smdir/smdsa1.pem -out test.cms", | ||
110 | "-verify -in test.cms -inform DER " | ||
111 | . " -CAfile $smdir/smroot.pem -out smtst.txt" | ||
112 | ], | ||
113 | |||
114 | [ | ||
115 | "signed detached content DER format, DSA key", | ||
116 | "-sign -in smcont.txt -outform DER" | ||
117 | . " -signer $smdir/smdsa1.pem -out test.cms", | ||
118 | "-verify -in test.cms -inform DER " | ||
119 | . " -CAfile $smdir/smroot.pem -out smtst.txt -content smcont.txt" | ||
120 | ], | ||
121 | |||
122 | [ | ||
123 | "signed detached content DER format, add RSA signer", | ||
124 | "-resign -inform DER -in test.cms -outform DER" | ||
125 | . " -signer $smdir/smrsa1.pem -out test2.cms", | ||
126 | "-verify -in test2.cms -inform DER " | ||
127 | . " -CAfile $smdir/smroot.pem -out smtst.txt -content smcont.txt" | ||
128 | ], | ||
129 | |||
130 | [ | ||
131 | "signed content test streaming BER format, DSA key", | ||
132 | "-sign -in smcont.txt -outform DER -nodetach" | ||
133 | . " -stream -signer $smdir/smdsa1.pem -out test.cms", | ||
134 | "-verify -in test.cms -inform DER " | ||
135 | . " -CAfile $smdir/smroot.pem -out smtst.txt" | ||
136 | ], | ||
137 | |||
138 | [ | ||
139 | "signed content test streaming BER format, 2 DSA and 2 RSA keys", | ||
140 | "-sign -in smcont.txt -outform DER -nodetach" | ||
141 | . " -signer $smdir/smrsa1.pem -signer $smdir/smrsa2.pem" | ||
142 | . " -signer $smdir/smdsa1.pem -signer $smdir/smdsa2.pem" | ||
143 | . " -stream -out test.cms", | ||
144 | "-verify -in test.cms -inform DER " | ||
145 | . " -CAfile $smdir/smroot.pem -out smtst.txt" | ||
146 | ], | ||
147 | |||
148 | [ | ||
149 | "signed content test streaming BER format, 2 DSA and 2 RSA keys, no attributes", | ||
150 | "-sign -in smcont.txt -outform DER -noattr -nodetach" | ||
151 | . " -signer $smdir/smrsa1.pem -signer $smdir/smrsa2.pem" | ||
152 | . " -signer $smdir/smdsa1.pem -signer $smdir/smdsa2.pem" | ||
153 | . " -stream -out test.cms", | ||
154 | "-verify -in test.cms -inform DER " | ||
155 | . " -CAfile $smdir/smroot.pem -out smtst.txt" | ||
156 | ], | ||
157 | |||
158 | [ | ||
159 | "signed content test streaming S/MIME format, 2 DSA and 2 RSA keys", | ||
160 | "-sign -in smcont.txt -nodetach" | ||
161 | . " -signer $smdir/smrsa1.pem -signer $smdir/smrsa2.pem" | ||
162 | . " -signer $smdir/smdsa1.pem -signer $smdir/smdsa2.pem" | ||
163 | . " -stream -out test.cms", | ||
164 | "-verify -in test.cms " . " -CAfile $smdir/smroot.pem -out smtst.txt" | ||
165 | ], | ||
166 | |||
167 | [ | ||
168 | "signed content test streaming multipart S/MIME format, 2 DSA and 2 RSA keys", | ||
169 | "-sign -in smcont.txt" | ||
170 | . " -signer $smdir/smrsa1.pem -signer $smdir/smrsa2.pem" | ||
171 | . " -signer $smdir/smdsa1.pem -signer $smdir/smdsa2.pem" | ||
172 | . " -stream -out test.cms", | ||
173 | "-verify -in test.cms " . " -CAfile $smdir/smroot.pem -out smtst.txt" | ||
174 | ], | ||
175 | |||
176 | [ | ||
177 | "enveloped content test streaming S/MIME format, 3 recipients", | ||
178 | "-encrypt -in smcont.txt" | ||
179 | . " -stream -out test.cms" | ||
180 | . " $smdir/smrsa1.pem $smdir/smrsa2.pem $smdir/smrsa3.pem ", | ||
181 | "-decrypt -recip $smdir/smrsa1.pem -in test.cms -out smtst.txt" | ||
182 | ], | ||
183 | |||
184 | [ | ||
185 | "enveloped content test streaming S/MIME format, 3 recipients, 3rd used", | ||
186 | "-encrypt -in smcont.txt" | ||
187 | . " -stream -out test.cms" | ||
188 | . " $smdir/smrsa1.pem $smdir/smrsa2.pem $smdir/smrsa3.pem ", | ||
189 | "-decrypt -recip $smdir/smrsa3.pem -in test.cms -out smtst.txt" | ||
190 | ], | ||
191 | |||
192 | [ | ||
193 | "enveloped content test streaming S/MIME format, 3 recipients, key only used", | ||
194 | "-encrypt -in smcont.txt" | ||
195 | . " -stream -out test.cms" | ||
196 | . " $smdir/smrsa1.pem $smdir/smrsa2.pem $smdir/smrsa3.pem ", | ||
197 | "-decrypt -inkey $smdir/smrsa3.pem -in test.cms -out smtst.txt" | ||
198 | ], | ||
199 | |||
200 | [ | ||
201 | "enveloped content test streaming S/MIME format, AES-256 cipher, 3 recipients", | ||
202 | "-encrypt -in smcont.txt" | ||
203 | . " -aes256 -stream -out test.cms" | ||
204 | . " $smdir/smrsa1.pem $smdir/smrsa2.pem $smdir/smrsa3.pem ", | ||
205 | "-decrypt -recip $smdir/smrsa1.pem -in test.cms -out smtst.txt" | ||
206 | ], | ||
207 | |||
208 | ); | ||
209 | |||
210 | my @smime_cms_tests = ( | ||
211 | |||
212 | [ | ||
213 | "signed content test streaming BER format, 2 DSA and 2 RSA keys, keyid", | ||
214 | "-sign -in smcont.txt -outform DER -nodetach -keyid" | ||
215 | . " -signer $smdir/smrsa1.pem -signer $smdir/smrsa2.pem" | ||
216 | . " -signer $smdir/smdsa1.pem -signer $smdir/smdsa2.pem" | ||
217 | . " -stream -out test.cms", | ||
218 | "-verify -in test.cms -inform DER " | ||
219 | . " -CAfile $smdir/smroot.pem -out smtst.txt" | ||
220 | ], | ||
221 | |||
222 | [ | ||
223 | "signed content test streaming PEM format, 2 DSA and 2 RSA keys", | ||
224 | "-sign -in smcont.txt -outform PEM -nodetach" | ||
225 | . " -signer $smdir/smrsa1.pem -signer $smdir/smrsa2.pem" | ||
226 | . " -signer $smdir/smdsa1.pem -signer $smdir/smdsa2.pem" | ||
227 | . " -stream -out test.cms", | ||
228 | "-verify -in test.cms -inform PEM " | ||
229 | . " -CAfile $smdir/smroot.pem -out smtst.txt" | ||
230 | ], | ||
231 | |||
232 | [ | ||
233 | "signed content MIME format, RSA key, signed receipt request", | ||
234 | "-sign -in smcont.txt -signer $smdir/smrsa1.pem -nodetach" | ||
235 | . " -receipt_request_to test@openssl.org -receipt_request_all" | ||
236 | . " -out test.cms", | ||
237 | "-verify -in test.cms " | ||
238 | . " -CAfile $smdir/smroot.pem -out smtst.txt" | ||
239 | ], | ||
240 | |||
241 | [ | ||
242 | "signed receipt MIME format, RSA key", | ||
243 | "-sign_receipt -in test.cms" | ||
244 | . " -signer $smdir/smrsa2.pem" | ||
245 | . " -out test2.cms", | ||
246 | "-verify_receipt test2.cms -in test.cms" | ||
247 | . " -CAfile $smdir/smroot.pem" | ||
248 | ], | ||
249 | |||
250 | [ | ||
251 | "enveloped content test streaming S/MIME format, 3 recipients, keyid", | ||
252 | "-encrypt -in smcont.txt" | ||
253 | . " -stream -out test.cms -keyid" | ||
254 | . " $smdir/smrsa1.pem $smdir/smrsa2.pem $smdir/smrsa3.pem ", | ||
255 | "-decrypt -recip $smdir/smrsa1.pem -in test.cms -out smtst.txt" | ||
256 | ], | ||
257 | |||
258 | [ | ||
259 | "enveloped content test streaming PEM format, KEK", | ||
260 | "-encrypt -in smcont.txt -outform PEM -aes128" | ||
261 | . " -stream -out test.cms " | ||
262 | . " -secretkey 000102030405060708090A0B0C0D0E0F " | ||
263 | . " -secretkeyid C0FEE0", | ||
264 | "-decrypt -in test.cms -out smtst.txt -inform PEM" | ||
265 | . " -secretkey 000102030405060708090A0B0C0D0E0F " | ||
266 | . " -secretkeyid C0FEE0" | ||
267 | ], | ||
268 | |||
269 | [ | ||
270 | "enveloped content test streaming PEM format, KEK, key only", | ||
271 | "-encrypt -in smcont.txt -outform PEM -aes128" | ||
272 | . " -stream -out test.cms " | ||
273 | . " -secretkey 000102030405060708090A0B0C0D0E0F " | ||
274 | . " -secretkeyid C0FEE0", | ||
275 | "-decrypt -in test.cms -out smtst.txt -inform PEM" | ||
276 | . " -secretkey 000102030405060708090A0B0C0D0E0F " | ||
277 | ], | ||
278 | |||
279 | [ | ||
280 | "data content test streaming PEM format", | ||
281 | "-data_create -in smcont.txt -outform PEM -nodetach" | ||
282 | . " -stream -out test.cms", | ||
283 | "-data_out -in test.cms -inform PEM -out smtst.txt" | ||
284 | ], | ||
285 | |||
286 | [ | ||
287 | "encrypted content test streaming PEM format, 128 bit RC2 key", | ||
288 | "-EncryptedData_encrypt -in smcont.txt -outform PEM" | ||
289 | . " -rc2 -secretkey 000102030405060708090A0B0C0D0E0F" | ||
290 | . " -stream -out test.cms", | ||
291 | "-EncryptedData_decrypt -in test.cms -inform PEM " | ||
292 | . " -secretkey 000102030405060708090A0B0C0D0E0F -out smtst.txt" | ||
293 | ], | ||
294 | |||
295 | [ | ||
296 | "encrypted content test streaming PEM format, 40 bit RC2 key", | ||
297 | "-EncryptedData_encrypt -in smcont.txt -outform PEM" | ||
298 | . " -rc2 -secretkey 0001020304" | ||
299 | . " -stream -out test.cms", | ||
300 | "-EncryptedData_decrypt -in test.cms -inform PEM " | ||
301 | . " -secretkey 0001020304 -out smtst.txt" | ||
302 | ], | ||
303 | |||
304 | [ | ||
305 | "encrypted content test streaming PEM format, triple DES key", | ||
306 | "-EncryptedData_encrypt -in smcont.txt -outform PEM" | ||
307 | . " -des3 -secretkey 000102030405060708090A0B0C0D0E0F1011121314151617" | ||
308 | . " -stream -out test.cms", | ||
309 | "-EncryptedData_decrypt -in test.cms -inform PEM " | ||
310 | . " -secretkey 000102030405060708090A0B0C0D0E0F1011121314151617" | ||
311 | . " -out smtst.txt" | ||
312 | ], | ||
313 | |||
314 | [ | ||
315 | "encrypted content test streaming PEM format, 128 bit AES key", | ||
316 | "-EncryptedData_encrypt -in smcont.txt -outform PEM" | ||
317 | . " -aes128 -secretkey 000102030405060708090A0B0C0D0E0F" | ||
318 | . " -stream -out test.cms", | ||
319 | "-EncryptedData_decrypt -in test.cms -inform PEM " | ||
320 | . " -secretkey 000102030405060708090A0B0C0D0E0F -out smtst.txt" | ||
321 | ], | ||
322 | |||
323 | ); | ||
324 | |||
325 | my @smime_cms_comp_tests = ( | ||
326 | |||
327 | [ | ||
328 | "compressed content test streaming PEM format", | ||
329 | "-compress -in smcont.txt -outform PEM -nodetach" | ||
330 | . " -stream -out test.cms", | ||
331 | "-uncompress -in test.cms -inform PEM -out smtst.txt" | ||
332 | ] | ||
333 | |||
334 | ); | ||
335 | |||
336 | print "PKCS#7 <=> PKCS#7 consistency tests\n"; | ||
337 | |||
338 | run_smime_tests( \$badcmd, \@smime_pkcs7_tests, $pk7cmd, $pk7cmd ); | ||
339 | |||
340 | print "CMS => PKCS#7 compatibility tests\n"; | ||
341 | |||
342 | run_smime_tests( \$badcmd, \@smime_pkcs7_tests, $cmscmd, $pk7cmd ); | ||
343 | |||
344 | print "CMS <= PKCS#7 compatibility tests\n"; | ||
345 | |||
346 | run_smime_tests( \$badcmd, \@smime_pkcs7_tests, $pk7cmd, $cmscmd ); | ||
347 | |||
348 | print "CMS <=> CMS consistency tests\n"; | ||
349 | |||
350 | run_smime_tests( \$badcmd, \@smime_pkcs7_tests, $cmscmd, $cmscmd ); | ||
351 | run_smime_tests( \$badcmd, \@smime_cms_tests, $cmscmd, $cmscmd ); | ||
352 | |||
353 | if ( `$ossl_path version -f` =~ /ZLIB/ ) { | ||
354 | run_smime_tests( \$badcmd, \@smime_cms_comp_tests, $cmscmd, $cmscmd ); | ||
355 | } | ||
356 | else { | ||
357 | print "Zlib not supported: compression tests skipped\n"; | ||
358 | } | ||
359 | |||
360 | print "Running modified tests for OpenSSL 0.9.8 cms backport\n" if($ossl8); | ||
361 | |||
362 | if ($badcmd) { | ||
363 | print "$badcmd TESTS FAILED!!\n"; | ||
364 | } | ||
365 | else { | ||
366 | print "ALL TESTS SUCCESSFUL.\n"; | ||
367 | } | ||
368 | |||
369 | unlink "test.cms"; | ||
370 | unlink "test2.cms"; | ||
371 | unlink "smtst.txt"; | ||
372 | unlink "cms.out"; | ||
373 | unlink "cms.err"; | ||
374 | |||
375 | sub run_smime_tests { | ||
376 | my ( $rv, $aref, $scmd, $vcmd ) = @_; | ||
377 | |||
378 | foreach $smtst (@$aref) { | ||
379 | my ( $tnam, $rscmd, $rvcmd ) = @$smtst; | ||
380 | if ($ossl8) | ||
381 | { | ||
382 | # Skip smime resign: 0.9.8 smime doesn't support -resign | ||
383 | next if ($scmd =~ /smime/ && $rscmd =~ /-resign/); | ||
384 | # Disable streaming: option not supported in 0.9.8 | ||
385 | $tnam =~ s/streaming//; | ||
386 | $rscmd =~ s/-stream//; | ||
387 | $rvcmd =~ s/-stream//; | ||
388 | } | ||
389 | system("$scmd$rscmd 2>cms.err 1>cms.out"); | ||
390 | if ($?) { | ||
391 | print "$tnam: generation error\n"; | ||
392 | $$rv++; | ||
393 | exit 1 if $halt_err; | ||
394 | next; | ||
395 | } | ||
396 | system("$vcmd$rvcmd 2>cms.err 1>cms.out"); | ||
397 | if ($?) { | ||
398 | print "$tnam: verify error\n"; | ||
399 | $$rv++; | ||
400 | exit 1 if $halt_err; | ||
401 | next; | ||
402 | } | ||
403 | if (!cmp_files("smtst.txt", "smcont.txt")) { | ||
404 | print "$tnam: content verify error\n"; | ||
405 | $$rv++; | ||
406 | exit 1 if $halt_err; | ||
407 | next; | ||
408 | } | ||
409 | print "$tnam: OK\n"; | ||
410 | } | ||
411 | } | ||
412 | |||
413 | sub cmp_files { | ||
414 | my ( $f1, $f2 ) = @_; | ||
415 | my ( $fp1, $fp2 ); | ||
416 | |||
417 | my ( $rd1, $rd2 ); | ||
418 | |||
419 | if ( !open( $fp1, "<$f1" ) ) { | ||
420 | print STDERR "Can't Open file $f1\n"; | ||
421 | return 0; | ||
422 | } | ||
423 | |||
424 | if ( !open( $fp2, "<$f2" ) ) { | ||
425 | print STDERR "Can't Open file $f2\n"; | ||
426 | return 0; | ||
427 | } | ||
428 | |||
429 | binmode $fp1; | ||
430 | binmode $fp2; | ||
431 | |||
432 | my $ret = 0; | ||
433 | |||
434 | for ( ; ; ) { | ||
435 | $n1 = sysread $fp1, $rd1, 4096; | ||
436 | $n2 = sysread $fp2, $rd2, 4096; | ||
437 | last if ( $n1 != $n2 ); | ||
438 | last if ( $rd1 ne $rd2 ); | ||
439 | |||
440 | if ( $n1 == 0 ) { | ||
441 | $ret = 1; | ||
442 | last; | ||
443 | } | ||
444 | |||
445 | } | ||
446 | |||
447 | close $fp1; | ||
448 | close $fp2; | ||
449 | |||
450 | return $ret; | ||
451 | |||
452 | } | ||
453 | |||
diff --git a/src/lib/libssl/test/smcont.txt b/src/lib/libssl/test/smcont.txt new file mode 100644 index 0000000000..e837c0b75b --- /dev/null +++ b/src/lib/libssl/test/smcont.txt | |||
@@ -0,0 +1 @@ | |||
Some test content for OpenSSL CMS \ No newline at end of file | |||
diff --git a/src/lib/libssl/test/smime-certs/smdsa1.pem b/src/lib/libssl/test/smime-certs/smdsa1.pem new file mode 100644 index 0000000000..d5677dbfbe --- /dev/null +++ b/src/lib/libssl/test/smime-certs/smdsa1.pem | |||
@@ -0,0 +1,34 @@ | |||
1 | -----BEGIN DSA PRIVATE KEY----- | ||
2 | MIIBuwIBAAKBgQDFJfsIPOIawMO5biw+AoYUhNVxReBOLQosU3Qv4B8krac0BNr3 | ||
3 | OjSGLh1wZxHqhlAE0QmasTaKojuk20nNWeFnczSz6vDl0IVJEhS8VYor5kt9gLqt | ||
4 | GcoAgsf4gRDIutJyQDaNn3IVY89uXUVIoexvQeLQDBCgQPC5O8rJdqBwtwIVAK2J | ||
5 | jt+dqk07eQUE59koYUEKyNorAoGBAI4IEpusf8G14kCHmRtnHXM2tG5EWJDmW6Qt | ||
6 | wjqvWp1GKUx5WFy1tVWR9nl5rL0Di+kNdENo+SkKj7h3uDulGOI6T0mQYbV2h1IK | ||
7 | +FMOGnOqvZ8eNTE2n4PGTo5puZ63LBm+QYrQsrNiUY4vakLFQ2rEK/SLwdsDFK4Z | ||
8 | SJCBQw5zAoGATQlPPF+OeU8nu3rsdXGDiZdJzOkuCce3KQfTABA9C+Dk4CVcvBdd | ||
9 | YRLGpnykumkNTO1sTO+4/Gphsuje1ujK9td4UEhdYqylCe5QjEMrszDlJtelDQF9 | ||
10 | C0yhdjKGTP0kxofLhsGckcuQvcKEKffT2pDDKJIy4vWQO0UyJl1vjLcCFG2uiGGx | ||
11 | 9fMUZq1v0ePD4Wo0Xkxo | ||
12 | -----END DSA PRIVATE KEY----- | ||
13 | -----BEGIN CERTIFICATE----- | ||
14 | MIIDpDCCAw2gAwIBAgIJAMtotfHYdEsWMA0GCSqGSIb3DQEBBQUAMEQxCzAJBgNV | ||
15 | BAYTAlVLMRYwFAYDVQQKEw1PcGVuU1NMIEdyb3VwMR0wGwYDVQQDExRUZXN0IFMv | ||
16 | TUlNRSBSU0EgUm9vdDAeFw0wODAyMjIxMzUzMDlaFw0xNjA1MTAxMzUzMDlaMEUx | ||
17 | CzAJBgNVBAYTAlVLMRYwFAYDVQQKDA1PcGVuU1NMIEdyb3VwMR4wHAYDVQQDDBVU | ||
18 | ZXN0IFMvTUlNRSBFRSBEU0EgIzEwggG3MIIBLAYHKoZIzjgEATCCAR8CgYEAxSX7 | ||
19 | CDziGsDDuW4sPgKGFITVcUXgTi0KLFN0L+AfJK2nNATa9zo0hi4dcGcR6oZQBNEJ | ||
20 | mrE2iqI7pNtJzVnhZ3M0s+rw5dCFSRIUvFWKK+ZLfYC6rRnKAILH+IEQyLrSckA2 | ||
21 | jZ9yFWPPbl1FSKHsb0Hi0AwQoEDwuTvKyXagcLcCFQCtiY7fnapNO3kFBOfZKGFB | ||
22 | CsjaKwKBgQCOCBKbrH/BteJAh5kbZx1zNrRuRFiQ5lukLcI6r1qdRilMeVhctbVV | ||
23 | kfZ5eay9A4vpDXRDaPkpCo+4d7g7pRjiOk9JkGG1dodSCvhTDhpzqr2fHjUxNp+D | ||
24 | xk6OabmetywZvkGK0LKzYlGOL2pCxUNqxCv0i8HbAxSuGUiQgUMOcwOBhAACgYBN | ||
25 | CU88X455Tye7eux1cYOJl0nM6S4Jx7cpB9MAED0L4OTgJVy8F11hEsamfKS6aQ1M | ||
26 | 7WxM77j8amGy6N7W6Mr213hQSF1irKUJ7lCMQyuzMOUm16UNAX0LTKF2MoZM/STG | ||
27 | h8uGwZyRy5C9woQp99PakMMokjLi9ZA7RTImXW+Mt6OBgzCBgDAdBgNVHQ4EFgQU | ||
28 | 4Qfbhpi5yqXaXuCLXj427mR25MkwHwYDVR0jBBgwFoAUE89Lp7uJLrM4Vxd2xput | ||
29 | aFvl7RcwDAYDVR0TAQH/BAIwADAOBgNVHQ8BAf8EBAMCBsAwIAYDVR0RBBkwF4EV | ||
30 | c21pbWVkc2ExQG9wZW5zc2wub3JnMA0GCSqGSIb3DQEBBQUAA4GBAFrdUzKK1pWO | ||
31 | kd02S423KUBc4GWWyiGlVoEO7WxVhHLJ8sm67X7OtJOwe0UGt+Nc5qLtyJYSirw8 | ||
32 | phjiTdNpQCTJ8+Kc56tWkJ6H7NAI4vTJtPL5BM/EmeYrVSU9JI9xhqpyKw9IBD+n | ||
33 | hRJ79W9FaiJRvaAOX+TkyTukJrxAWRyv | ||
34 | -----END CERTIFICATE----- | ||
diff --git a/src/lib/libssl/test/smime-certs/smdsa2.pem b/src/lib/libssl/test/smime-certs/smdsa2.pem new file mode 100644 index 0000000000..ef86c115d7 --- /dev/null +++ b/src/lib/libssl/test/smime-certs/smdsa2.pem | |||
@@ -0,0 +1,34 @@ | |||
1 | -----BEGIN DSA PRIVATE KEY----- | ||
2 | MIIBvAIBAAKBgQDFJfsIPOIawMO5biw+AoYUhNVxReBOLQosU3Qv4B8krac0BNr3 | ||
3 | OjSGLh1wZxHqhlAE0QmasTaKojuk20nNWeFnczSz6vDl0IVJEhS8VYor5kt9gLqt | ||
4 | GcoAgsf4gRDIutJyQDaNn3IVY89uXUVIoexvQeLQDBCgQPC5O8rJdqBwtwIVAK2J | ||
5 | jt+dqk07eQUE59koYUEKyNorAoGBAI4IEpusf8G14kCHmRtnHXM2tG5EWJDmW6Qt | ||
6 | wjqvWp1GKUx5WFy1tVWR9nl5rL0Di+kNdENo+SkKj7h3uDulGOI6T0mQYbV2h1IK | ||
7 | +FMOGnOqvZ8eNTE2n4PGTo5puZ63LBm+QYrQsrNiUY4vakLFQ2rEK/SLwdsDFK4Z | ||
8 | SJCBQw5zAoGBAIPmO8BtJ+Yac58trrPwq9b/6VW3jQTWzTLWSH84/QQdqQa+Pz3v | ||
9 | It/+hHM0daNF5uls8ICsPL1aLXmRx0pHvIyb0aAzYae4T4Jv/COPDMTdKbA1uitJ | ||
10 | VbkGZrm+LIrs7I9lOkb4T0vI6kL/XdOCXY1469zsqCgJ/O2ibn6mq0nWAhR716o2 | ||
11 | Nf8SimTZYB0/CKje6M5ufA== | ||
12 | -----END DSA PRIVATE KEY----- | ||
13 | -----BEGIN CERTIFICATE----- | ||
14 | MIIDpTCCAw6gAwIBAgIJAMtotfHYdEsXMA0GCSqGSIb3DQEBBQUAMEQxCzAJBgNV | ||
15 | BAYTAlVLMRYwFAYDVQQKEw1PcGVuU1NMIEdyb3VwMR0wGwYDVQQDExRUZXN0IFMv | ||
16 | TUlNRSBSU0EgUm9vdDAeFw0wODAyMjIxMzUzMDlaFw0xNjA1MTAxMzUzMDlaMEUx | ||
17 | CzAJBgNVBAYTAlVLMRYwFAYDVQQKDA1PcGVuU1NMIEdyb3VwMR4wHAYDVQQDDBVU | ||
18 | ZXN0IFMvTUlNRSBFRSBEU0EgIzIwggG4MIIBLAYHKoZIzjgEATCCAR8CgYEAxSX7 | ||
19 | CDziGsDDuW4sPgKGFITVcUXgTi0KLFN0L+AfJK2nNATa9zo0hi4dcGcR6oZQBNEJ | ||
20 | mrE2iqI7pNtJzVnhZ3M0s+rw5dCFSRIUvFWKK+ZLfYC6rRnKAILH+IEQyLrSckA2 | ||
21 | jZ9yFWPPbl1FSKHsb0Hi0AwQoEDwuTvKyXagcLcCFQCtiY7fnapNO3kFBOfZKGFB | ||
22 | CsjaKwKBgQCOCBKbrH/BteJAh5kbZx1zNrRuRFiQ5lukLcI6r1qdRilMeVhctbVV | ||
23 | kfZ5eay9A4vpDXRDaPkpCo+4d7g7pRjiOk9JkGG1dodSCvhTDhpzqr2fHjUxNp+D | ||
24 | xk6OabmetywZvkGK0LKzYlGOL2pCxUNqxCv0i8HbAxSuGUiQgUMOcwOBhQACgYEA | ||
25 | g+Y7wG0n5hpzny2us/Cr1v/pVbeNBNbNMtZIfzj9BB2pBr4/Pe8i3/6EczR1o0Xm | ||
26 | 6WzwgKw8vVoteZHHSke8jJvRoDNhp7hPgm/8I48MxN0psDW6K0lVuQZmub4siuzs | ||
27 | j2U6RvhPS8jqQv9d04JdjXjr3OyoKAn87aJufqarSdajgYMwgYAwHQYDVR0OBBYE | ||
28 | FHsAGNfVltSYUq4hC+YVYwsYtA+dMB8GA1UdIwQYMBaAFBPPS6e7iS6zOFcXdsab | ||
29 | rWhb5e0XMAwGA1UdEwEB/wQCMAAwDgYDVR0PAQH/BAQDAgbAMCAGA1UdEQQZMBeB | ||
30 | FXNtaW1lZHNhMkBvcGVuc3NsLm9yZzANBgkqhkiG9w0BAQUFAAOBgQCx9BtCbaYF | ||
31 | FXjLClkuKXbESaDZA1biPgY25i00FsUzARuhCpqD2v+0tu5c33ZzIhL6xlvBRU5l | ||
32 | 6Atw/xpZhae+hdBEtxPJoGekLLrHOau7Md3XwDjV4lFgcEJkWZoaSOOIK+4D5jF0 | ||
33 | jZWtHjnwEzuLYlo7ScHSsbcQfjH0M1TP5A== | ||
34 | -----END CERTIFICATE----- | ||
diff --git a/src/lib/libssl/test/smime-certs/smdsa3.pem b/src/lib/libssl/test/smime-certs/smdsa3.pem new file mode 100644 index 0000000000..eeb848dabc --- /dev/null +++ b/src/lib/libssl/test/smime-certs/smdsa3.pem | |||
@@ -0,0 +1,34 @@ | |||
1 | -----BEGIN DSA PRIVATE KEY----- | ||
2 | MIIBvAIBAAKBgQDFJfsIPOIawMO5biw+AoYUhNVxReBOLQosU3Qv4B8krac0BNr3 | ||
3 | OjSGLh1wZxHqhlAE0QmasTaKojuk20nNWeFnczSz6vDl0IVJEhS8VYor5kt9gLqt | ||
4 | GcoAgsf4gRDIutJyQDaNn3IVY89uXUVIoexvQeLQDBCgQPC5O8rJdqBwtwIVAK2J | ||
5 | jt+dqk07eQUE59koYUEKyNorAoGBAI4IEpusf8G14kCHmRtnHXM2tG5EWJDmW6Qt | ||
6 | wjqvWp1GKUx5WFy1tVWR9nl5rL0Di+kNdENo+SkKj7h3uDulGOI6T0mQYbV2h1IK | ||
7 | +FMOGnOqvZ8eNTE2n4PGTo5puZ63LBm+QYrQsrNiUY4vakLFQ2rEK/SLwdsDFK4Z | ||
8 | SJCBQw5zAoGAYzOpPmh8Je1IDauEXhgaLz14wqYUHHcrj2VWVJ6fRm8GhdQFJSI7 | ||
9 | GUk08pgKZSKic2lNqxuzW7/vFxKQ/nvzfytY16b+2i+BR4Q6yvMzCebE1hHVg0Ju | ||
10 | TwfUMwoFEOhYP6ZwHSUiQl9IBMH9TNJCMwYMxfY+VOrURFsjGTRUgpwCFQCIGt5g | ||
11 | Y+XZd0Sv69CatDIRYWvaIA== | ||
12 | -----END DSA PRIVATE KEY----- | ||
13 | -----BEGIN CERTIFICATE----- | ||
14 | MIIDpDCCAw2gAwIBAgIJAMtotfHYdEsYMA0GCSqGSIb3DQEBBQUAMEQxCzAJBgNV | ||
15 | BAYTAlVLMRYwFAYDVQQKEw1PcGVuU1NMIEdyb3VwMR0wGwYDVQQDExRUZXN0IFMv | ||
16 | TUlNRSBSU0EgUm9vdDAeFw0wODAyMjIxMzUzMDlaFw0xNjA1MTAxMzUzMDlaMEUx | ||
17 | CzAJBgNVBAYTAlVLMRYwFAYDVQQKDA1PcGVuU1NMIEdyb3VwMR4wHAYDVQQDDBVU | ||
18 | ZXN0IFMvTUlNRSBFRSBEU0EgIzMwggG3MIIBLAYHKoZIzjgEATCCAR8CgYEAxSX7 | ||
19 | CDziGsDDuW4sPgKGFITVcUXgTi0KLFN0L+AfJK2nNATa9zo0hi4dcGcR6oZQBNEJ | ||
20 | mrE2iqI7pNtJzVnhZ3M0s+rw5dCFSRIUvFWKK+ZLfYC6rRnKAILH+IEQyLrSckA2 | ||
21 | jZ9yFWPPbl1FSKHsb0Hi0AwQoEDwuTvKyXagcLcCFQCtiY7fnapNO3kFBOfZKGFB | ||
22 | CsjaKwKBgQCOCBKbrH/BteJAh5kbZx1zNrRuRFiQ5lukLcI6r1qdRilMeVhctbVV | ||
23 | kfZ5eay9A4vpDXRDaPkpCo+4d7g7pRjiOk9JkGG1dodSCvhTDhpzqr2fHjUxNp+D | ||
24 | xk6OabmetywZvkGK0LKzYlGOL2pCxUNqxCv0i8HbAxSuGUiQgUMOcwOBhAACgYBj | ||
25 | M6k+aHwl7UgNq4ReGBovPXjCphQcdyuPZVZUnp9GbwaF1AUlIjsZSTTymAplIqJz | ||
26 | aU2rG7Nbv+8XEpD+e/N/K1jXpv7aL4FHhDrK8zMJ5sTWEdWDQm5PB9QzCgUQ6Fg/ | ||
27 | pnAdJSJCX0gEwf1M0kIzBgzF9j5U6tREWyMZNFSCnKOBgzCBgDAdBgNVHQ4EFgQU | ||
28 | VhpVXqQ/EzUMdxLvP7o9EhJ8h70wHwYDVR0jBBgwFoAUE89Lp7uJLrM4Vxd2xput | ||
29 | aFvl7RcwDAYDVR0TAQH/BAIwADAOBgNVHQ8BAf8EBAMCBsAwIAYDVR0RBBkwF4EV | ||
30 | c21pbWVkc2EzQG9wZW5zc2wub3JnMA0GCSqGSIb3DQEBBQUAA4GBACM9e75EQa8m | ||
31 | k/AZkH/tROqf3yeqijULl9x8FjFatqoY+29OM6oMGM425IqSkKd2ipz7OxO0SShu | ||
32 | rE0O3edS7DvYBwvhWPviRaYBMyZ4iFJVup+fOzoYK/j/bASxS3BHQBwb2r4rhe25 | ||
33 | OlTyyFEk7DJyW18YFOG97S1P52oQ5f5x | ||
34 | -----END CERTIFICATE----- | ||
diff --git a/src/lib/libssl/test/smime-certs/smdsap.pem b/src/lib/libssl/test/smime-certs/smdsap.pem new file mode 100644 index 0000000000..249706c8c7 --- /dev/null +++ b/src/lib/libssl/test/smime-certs/smdsap.pem | |||
@@ -0,0 +1,9 @@ | |||
1 | -----BEGIN DSA PARAMETERS----- | ||
2 | MIIBHwKBgQDFJfsIPOIawMO5biw+AoYUhNVxReBOLQosU3Qv4B8krac0BNr3OjSG | ||
3 | Lh1wZxHqhlAE0QmasTaKojuk20nNWeFnczSz6vDl0IVJEhS8VYor5kt9gLqtGcoA | ||
4 | gsf4gRDIutJyQDaNn3IVY89uXUVIoexvQeLQDBCgQPC5O8rJdqBwtwIVAK2Jjt+d | ||
5 | qk07eQUE59koYUEKyNorAoGBAI4IEpusf8G14kCHmRtnHXM2tG5EWJDmW6Qtwjqv | ||
6 | Wp1GKUx5WFy1tVWR9nl5rL0Di+kNdENo+SkKj7h3uDulGOI6T0mQYbV2h1IK+FMO | ||
7 | GnOqvZ8eNTE2n4PGTo5puZ63LBm+QYrQsrNiUY4vakLFQ2rEK/SLwdsDFK4ZSJCB | ||
8 | Qw5z | ||
9 | -----END DSA PARAMETERS----- | ||
diff --git a/src/lib/libssl/test/smime-certs/smroot.pem b/src/lib/libssl/test/smime-certs/smroot.pem new file mode 100644 index 0000000000..a59eb2684c --- /dev/null +++ b/src/lib/libssl/test/smime-certs/smroot.pem | |||
@@ -0,0 +1,30 @@ | |||
1 | -----BEGIN RSA PRIVATE KEY----- | ||
2 | MIICXAIBAAKBgQDBV1Z/Q5gPF7lojc8pKUdyz5+Jf2B3vs4he6egekugWnoJduki | ||
3 | 9Lnae/JchB/soIX0co3nLc11NuFFlnAWJNMDJr08l5AHAJLYNHevF5l/f9oDQwvZ | ||
4 | speKh1xpIAJNqCTzVeQ/ZLx6/GccIXV/xDuKIiovqJTPgR5WPkYKaw++lQIDAQAB | ||
5 | AoGALXnUj5SflJU4+B2652ydMKUjWl0KnL/VjkyejgGV/j6py8Ybaixz9q8Gv7oY | ||
6 | JDlRqMC1HfZJCFQDQrHy5VJ+CywA/H9WrqKo/Ch9U4tJAZtkig1Cmay/BAYixVu0 | ||
7 | xBeim10aKF6hxHH4Chg9We+OCuzWBWJhqveNjuDedL/i7JUCQQDlejovcwBUCbhJ | ||
8 | U12qKOwlaboolWbl7yF3XdckTJZg7+1UqQHZH5jYZlLZyZxiaC92SNV0SyTLJZnS | ||
9 | Jh5CO+VDAkEA16/pPcuVtMMz/R6SSPpRSIAa1stLs0mFSs3NpR4pdm0n42mu05pO | ||
10 | 1tJEt3a1g7zkreQBf53+Dwb+lA841EkjRwJBAIFmt0DifKDnCkBu/jZh9SfzwsH3 | ||
11 | 3Zpzik+hXxxdA7+ODCrdUul449vDd5zQD5t+XKU61QNLDGhxv5e9XvrCg7kCQH/a | ||
12 | 3ldsVF0oDaxxL+QkxoREtCQ5tLEd1u7F2q6Tl56FDE0pe6Ih6bQ8RtG+g9EI60IN | ||
13 | U7oTrOO5kLWx5E0q4ccCQAZVgoenn9MhRU1agKOCuM6LT2DxReTu4XztJzynej+8 | ||
14 | 0J93n3ebanB1MlRpn1XJwhQ7gAC8ImaQKLJK5jdJzFc= | ||
15 | -----END RSA PRIVATE KEY----- | ||
16 | -----BEGIN CERTIFICATE----- | ||
17 | MIICaTCCAdKgAwIBAgIJAP6VN47boiXRMA0GCSqGSIb3DQEBBQUAMEQxCzAJBgNV | ||
18 | BAYTAlVLMRYwFAYDVQQKEw1PcGVuU1NMIEdyb3VwMR0wGwYDVQQDExRUZXN0IFMv | ||
19 | TUlNRSBSU0EgUm9vdDAeFw0wODAyMjIxMzUzMDdaFw0xNjA1MTExMzUzMDdaMEQx | ||
20 | CzAJBgNVBAYTAlVLMRYwFAYDVQQKEw1PcGVuU1NMIEdyb3VwMR0wGwYDVQQDExRU | ||
21 | ZXN0IFMvTUlNRSBSU0EgUm9vdDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA | ||
22 | wVdWf0OYDxe5aI3PKSlHcs+fiX9gd77OIXunoHpLoFp6CXbpIvS52nvyXIQf7KCF | ||
23 | 9HKN5y3NdTbhRZZwFiTTAya9PJeQBwCS2DR3rxeZf3/aA0ML2bKXiodcaSACTagk | ||
24 | 81XkP2S8evxnHCF1f8Q7iiIqL6iUz4EeVj5GCmsPvpUCAwEAAaNjMGEwHQYDVR0O | ||
25 | BBYEFBPPS6e7iS6zOFcXdsabrWhb5e0XMB8GA1UdIwQYMBaAFBPPS6e7iS6zOFcX | ||
26 | dsabrWhb5e0XMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMA0GCSqG | ||
27 | SIb3DQEBBQUAA4GBAIECprq5viDvnDbkyOaiSr9ubMUmWqvycfAJMdPZRKcOZczS | ||
28 | l+L9R9lF3JSqbt3knOe9u6bGDBOTY2285PdCCuHRVMk2Af1f6El1fqAlRUwNqipp | ||
29 | r68sWFuRqrcRNtk6QQvXfkOhrqQBuDa7te/OVQLa2lGN9Dr2mQsD8ijctatG | ||
30 | -----END CERTIFICATE----- | ||
diff --git a/src/lib/libssl/test/smime-certs/smrsa1.pem b/src/lib/libssl/test/smime-certs/smrsa1.pem new file mode 100644 index 0000000000..2cf3148e33 --- /dev/null +++ b/src/lib/libssl/test/smime-certs/smrsa1.pem | |||
@@ -0,0 +1,31 @@ | |||
1 | -----BEGIN RSA PRIVATE KEY----- | ||
2 | MIICXgIBAAKBgQC6A978j4pmPgUtUQqF+bjh6vdhwGOGZSD7xXgFTMjm88twfv+E | ||
3 | ixkq2KXSDjD0ZXoQbdOaSbvGRQrIJpG2NGiKAFdYNrP025kCCdh5wF/aEI7KLEm7 | ||
4 | JlHwXpQsuj4wkMgmkFjL3Ty4Z55aNH+2pPQIa0k+ENJXm2gDuhqgBmduAwIDAQAB | ||
5 | AoGBAJMuYu51aO2THyeHGwt81uOytcCbqGP7eoib62ZOJhxPRGYjpmuqX+R9/V5i | ||
6 | KiwGavm63JYUx0WO9YP+uIZxm1BUATzkgkS74u5LP6ajhkZh6/Bck1oIYYkbVOXl | ||
7 | JVrdENuH6U7nupznsyYgONByo+ykFPVUGmutgiaC7NMVo/MxAkEA6KLejWXdCIEn | ||
8 | xr7hGph9NlvY9xuRIMexRV/WrddcFfCdjI1PciIupgrIkR65M9yr7atm1iU6/aRf | ||
9 | KOr8rLZsSQJBAMyyXN71NsDNx4BP6rtJ/LJMP0BylznWkA7zWfGCbAYn9VhZVlSY | ||
10 | Eu9Gyr7quD1ix7G3kInKVYOEEOpockBLz+sCQQCedyMmKjcQLfpMVYW8uhbAynvW | ||
11 | h36qV5yXZxszO7nMcCTBsxhk5IfmLv5EbCs3+p9avCDGyoGOeUMg+kC33WORAkAg | ||
12 | oUIarH4o5+SoeJTTfCzTA0KF9H5U0vYt2+73h7HOnWoHxl3zqDZEfEVvf50U8/0f | ||
13 | QELDJETTbScBJtsnkq43AkEA38etvoZ2i4FJvvo7R/9gWBHVEcrGzcsCBYrNnIR1 | ||
14 | SZLRwHEGaiOK1wxMsWzqp7PJwL9z/M8A8DyOFBx3GPOniA== | ||
15 | -----END RSA PRIVATE KEY----- | ||
16 | -----BEGIN CERTIFICATE----- | ||
17 | MIICizCCAfSgAwIBAgIJAMtotfHYdEsTMA0GCSqGSIb3DQEBBQUAMEQxCzAJBgNV | ||
18 | BAYTAlVLMRYwFAYDVQQKEw1PcGVuU1NMIEdyb3VwMR0wGwYDVQQDExRUZXN0IFMv | ||
19 | TUlNRSBSU0EgUm9vdDAeFw0wODAyMjIxMzUzMDhaFw0xNjA1MTAxMzUzMDhaMEUx | ||
20 | CzAJBgNVBAYTAlVLMRYwFAYDVQQKDA1PcGVuU1NMIEdyb3VwMR4wHAYDVQQDDBVU | ||
21 | ZXN0IFMvTUlNRSBFRSBSU0EgIzEwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGB | ||
22 | ALoD3vyPimY+BS1RCoX5uOHq92HAY4ZlIPvFeAVMyObzy3B+/4SLGSrYpdIOMPRl | ||
23 | ehBt05pJu8ZFCsgmkbY0aIoAV1g2s/TbmQIJ2HnAX9oQjsosSbsmUfBelCy6PjCQ | ||
24 | yCaQWMvdPLhnnlo0f7ak9AhrST4Q0lebaAO6GqAGZ24DAgMBAAGjgYMwgYAwHQYD | ||
25 | VR0OBBYEFE2vMvKz5jrC7Lbdg68XwZ95iL/QMB8GA1UdIwQYMBaAFBPPS6e7iS6z | ||
26 | OFcXdsabrWhb5e0XMAwGA1UdEwEB/wQCMAAwDgYDVR0PAQH/BAQDAgXgMCAGA1Ud | ||
27 | EQQZMBeBFXNtaW1lcnNhMUBvcGVuc3NsLm9yZzANBgkqhkiG9w0BAQUFAAOBgQAi | ||
28 | O3GOkUl646oLnOimc36i9wxZ1tejsqs8vMjJ0Pym6Uq9FE2JoGzJ6OhB1GOsEVmj | ||
29 | 9cQ5UNQcRYL3cqOFtl6f4Dpu/lhzfbaqgmLjv29G1mS0uuTZrixhlyCXjwcbOkNC | ||
30 | I/+wvHHENYIK5+T/79M9LaZ2Qk4F9MNE1VMljdz9Qw== | ||
31 | -----END CERTIFICATE----- | ||
diff --git a/src/lib/libssl/test/smime-certs/smrsa2.pem b/src/lib/libssl/test/smime-certs/smrsa2.pem new file mode 100644 index 0000000000..d41f69c82f --- /dev/null +++ b/src/lib/libssl/test/smime-certs/smrsa2.pem | |||
@@ -0,0 +1,31 @@ | |||
1 | -----BEGIN RSA PRIVATE KEY----- | ||
2 | MIICWwIBAAKBgQCwBfryW4Vu5U9wNIDKspJO/N9YF4CcTlrCUyzVlKgb+8urHlSe | ||
3 | 59i5verR9IOCCXkemjOzZ/3nALTGqYZlnEvHp0Rjk+KdKXnKBIB+SRPpeu3LcXMT | ||
4 | WPgsThPa0UQxedNKG0g6aG+kLhsDlFBCoxd09jJtSpb9jmroJOq0ZYEHLwIDAQAB | ||
5 | AoGAKa/w4677Je1W5+r3SYoLDnvi5TkDs4D3C6ipKJgBTEdQz+DqB4w/DpZE4551 | ||
6 | +rkFn1LDxcxuHGRVa+tAMhZW97fwq9YUbjVZEyOz79qrX+BMyl/NbHkf1lIKDo3q | ||
7 | dWalzQvop7nbzeLC+VmmviwZfLQUbA61AQl3jm4dswT4XykCQQDloDadEv/28NTx | ||
8 | bvvywvyGuvJkCkEIycm4JrIInvwsd76h/chZ3oymrqzc7hkEtK6kThqlS5y+WXl6 | ||
9 | QzPruTKTAkEAxD2ro/VUoN+scIVaLmn0RBmZ67+9Pdn6pNSfjlK3s0T0EM6/iUWS | ||
10 | M06l6L9wFS3/ceu1tIifsh9BeqOGTa+udQJARIFnybTBaIqw/NZ/lA1YCVn8tpvY | ||
11 | iyaoZ6gjtS65TQrsdKeh/i3HCHNUXxUpoZ3F/H7QtD+6o49ODou+EbVOwQJAVmex | ||
12 | A2gp8wuJKaINqxIL81AybZLnCCzKJ3lXJ5tUNyLNM/lUbGStktm2Q1zHRQwTxV07 | ||
13 | jFn7trn8YrtNjzcjYQJAUKIJRt38A8Jw3HoPT+D0WS2IgxjVL0eYGsZX1lyeammG | ||
14 | 6rfnQ3u5uP7mEK2EH2o8mDUpAE0gclWBU9UkKxJsGA== | ||
15 | -----END RSA PRIVATE KEY----- | ||
16 | -----BEGIN CERTIFICATE----- | ||
17 | MIICizCCAfSgAwIBAgIJAMtotfHYdEsUMA0GCSqGSIb3DQEBBQUAMEQxCzAJBgNV | ||
18 | BAYTAlVLMRYwFAYDVQQKEw1PcGVuU1NMIEdyb3VwMR0wGwYDVQQDExRUZXN0IFMv | ||
19 | TUlNRSBSU0EgUm9vdDAeFw0wODAyMjIxMzUzMDhaFw0xNjA1MTAxMzUzMDhaMEUx | ||
20 | CzAJBgNVBAYTAlVLMRYwFAYDVQQKDA1PcGVuU1NMIEdyb3VwMR4wHAYDVQQDDBVU | ||
21 | ZXN0IFMvTUlNRSBFRSBSU0EgIzIwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGB | ||
22 | ALAF+vJbhW7lT3A0gMqykk7831gXgJxOWsJTLNWUqBv7y6seVJ7n2Lm96tH0g4IJ | ||
23 | eR6aM7Nn/ecAtMaphmWcS8enRGOT4p0pecoEgH5JE+l67ctxcxNY+CxOE9rRRDF5 | ||
24 | 00obSDpob6QuGwOUUEKjF3T2Mm1Klv2Oaugk6rRlgQcvAgMBAAGjgYMwgYAwHQYD | ||
25 | VR0OBBYEFIL/u+mEvaw7RuKLRuElfVkxSQjYMB8GA1UdIwQYMBaAFBPPS6e7iS6z | ||
26 | OFcXdsabrWhb5e0XMAwGA1UdEwEB/wQCMAAwDgYDVR0PAQH/BAQDAgXgMCAGA1Ud | ||
27 | EQQZMBeBFXNtaW1lcnNhMkBvcGVuc3NsLm9yZzANBgkqhkiG9w0BAQUFAAOBgQC2 | ||
28 | rXR5bm/9RtOMQPleNpd3y6uUX3oy+0CafK5Yl3PMnItjjnKJ0l1/DbLbDj2twehe | ||
29 | ewaB8CROcBCA3AMLSmGvPKgUCFMGtWam3328M4fBHzon5ka7qDXzM+imkAly/Yx2 | ||
30 | YNdR/aNOug+5sXygHmTSKqiCpQjOIClzXoPVVeEVHw== | ||
31 | -----END CERTIFICATE----- | ||
diff --git a/src/lib/libssl/test/smime-certs/smrsa3.pem b/src/lib/libssl/test/smime-certs/smrsa3.pem new file mode 100644 index 0000000000..c8cbe55151 --- /dev/null +++ b/src/lib/libssl/test/smime-certs/smrsa3.pem | |||
@@ -0,0 +1,31 @@ | |||
1 | -----BEGIN RSA PRIVATE KEY----- | ||
2 | MIICXAIBAAKBgQC6syTZtZNe1hRScFc4PUVyVLsr7+C1HDIZnOHmwFoLayX6RHwy | ||
3 | ep/TkdwiPHnemVLuwvpSjLMLZkXy/J764kSHJrNeVl3UvmCVCOm40hAtK1+F39pM | ||
4 | h8phkbPPD7i+hwq4/Vs79o46nzwbVKmzgoZBJhZ+codujUSYM3LjJ4aq+wIDAQAB | ||
5 | AoGAE1Zixrnr3bLGwBMqtYSDIOhtyos59whImCaLr17U9MHQWS+mvYO98if1aQZi | ||
6 | iQ/QazJ+wvYXxWJ+dEB+JvYwqrGeuAU6He/rAb4OShG4FPVU2D19gzRnaButWMeT | ||
7 | /1lgXV08hegGBL7RQNaN7b0viFYMcKnSghleMP0/q+Y/oaECQQDkXEwDYJW13X9p | ||
8 | ijS20ykWdY5lLknjkHRhhOYux0rlhOqsyMZjoUmwI2m0qj9yrIysKhrk4MZaM/uC | ||
9 | hy0xp3hdAkEA0Uv/UY0Kwsgc+W6YxeypECtg1qCE6FBib8n4iFy/6VcWqhvE5xrs | ||
10 | OdhKv9/p6aLjLneGd1sU+F8eS9LGyKIbNwJBAJPgbNzXA7uUZriqZb5qeTXxBDfj | ||
11 | RLfXSHYKAKEULxz3+JvRHB9SR4yHMiFrCdExiZrHXUkPgYLSHLGG5a4824UCQD6T | ||
12 | 9XvhquUARkGCAuWy0/3Eqoihp/t6BWSdQ9Upviu7YUhtUxsyXo0REZB7F4pGrJx5 | ||
13 | GlhXgFaewgUzuUHFzlMCQCzJMMWslWpoLntnR6sMhBMhBFHSw+Y5CbxBmFrdtSkd | ||
14 | VdtNO1VuDCTxjjW7W3Khj7LX4KZ1ye/5jfAgnnnXisc= | ||
15 | -----END RSA PRIVATE KEY----- | ||
16 | -----BEGIN CERTIFICATE----- | ||
17 | MIICizCCAfSgAwIBAgIJAMtotfHYdEsVMA0GCSqGSIb3DQEBBQUAMEQxCzAJBgNV | ||
18 | BAYTAlVLMRYwFAYDVQQKEw1PcGVuU1NMIEdyb3VwMR0wGwYDVQQDExRUZXN0IFMv | ||
19 | TUlNRSBSU0EgUm9vdDAeFw0wODAyMjIxMzUzMDlaFw0xNjA1MTAxMzUzMDlaMEUx | ||
20 | CzAJBgNVBAYTAlVLMRYwFAYDVQQKDA1PcGVuU1NMIEdyb3VwMR4wHAYDVQQDDBVU | ||
21 | ZXN0IFMvTUlNRSBFRSBSU0EgIzMwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGB | ||
22 | ALqzJNm1k17WFFJwVzg9RXJUuyvv4LUcMhmc4ebAWgtrJfpEfDJ6n9OR3CI8ed6Z | ||
23 | Uu7C+lKMswtmRfL8nvriRIcms15WXdS+YJUI6bjSEC0rX4Xf2kyHymGRs88PuL6H | ||
24 | Crj9Wzv2jjqfPBtUqbOChkEmFn5yh26NRJgzcuMnhqr7AgMBAAGjgYMwgYAwHQYD | ||
25 | VR0OBBYEFDsSFjNtYZzd0tTHafNS7tneQQj6MB8GA1UdIwQYMBaAFBPPS6e7iS6z | ||
26 | OFcXdsabrWhb5e0XMAwGA1UdEwEB/wQCMAAwDgYDVR0PAQH/BAQDAgXgMCAGA1Ud | ||
27 | EQQZMBeBFXNtaW1lcnNhM0BvcGVuc3NsLm9yZzANBgkqhkiG9w0BAQUFAAOBgQBE | ||
28 | tUDB+1Dqigu4p1xtdq7JRK6S+gfA7RWmhz0j2scb2zhpS12h37JLHsidGeKAzZYq | ||
29 | jUjOrH/j3xcV5AnuJoqImJaN23nzzxtR4qGGX2mrq6EtObzdEGgCUaizsGM+0slJ | ||
30 | PYxcy8KeY/63B1BpYhj2RjGkL6HrvuAaxVORa3acoA== | ||
31 | -----END CERTIFICATE----- | ||