summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/lib/libcrypto/aes/aes_ige.c323
-rw-r--r--src/lib/libcrypto/aes/aes_wrap.c259
-rw-r--r--src/lib/libcrypto/aes/asm/aes-ia64.S1123
-rwxr-xr-xsrc/lib/libcrypto/aes/asm/aes-x86_64.pl1578
-rw-r--r--src/lib/libcrypto/asn1/asn1_gen.c848
-rw-r--r--src/lib/libcrypto/asn1/asn_mime.c874
-rw-r--r--src/lib/libcrypto/bio/bss_dgram.c488
-rw-r--r--src/lib/libcrypto/bn/asm/x86_64-gcc.c4
-rwxr-xr-xsrc/lib/libcrypto/bn/asm/x86_64-mont.pl214
-rw-r--r--src/lib/libcrypto/bn/bn_const.c402
-rw-r--r--src/lib/libcrypto/bn/bn_depr.c112
-rw-r--r--src/lib/libcrypto/bn/bn_gf2m.c1091
-rw-r--r--src/lib/libcrypto/bn/bn_nist.c692
-rw-r--r--src/lib/libcrypto/camellia/camellia.c1624
-rw-r--r--src/lib/libcrypto/camellia/camellia.h129
-rw-r--r--src/lib/libcrypto/camellia/cmll_cbc.c273
-rw-r--r--src/lib/libcrypto/camellia/cmll_cfb.c235
-rw-r--r--src/lib/libcrypto/camellia/cmll_ctr.c143
-rw-r--r--src/lib/libcrypto/camellia/cmll_ecb.c74
-rw-r--r--src/lib/libcrypto/camellia/cmll_locl.h165
-rw-r--r--src/lib/libcrypto/camellia/cmll_misc.c116
-rw-r--r--src/lib/libcrypto/camellia/cmll_ofb.c141
-rw-r--r--src/lib/libcrypto/cms/cms.h473
-rw-r--r--src/lib/libcrypto/cms/cms_asn1.c346
-rw-r--r--src/lib/libcrypto/cms/cms_att.c195
-rw-r--r--src/lib/libcrypto/cms/cms_cd.c134
-rw-r--r--src/lib/libcrypto/cms/cms_dd.c148
-rw-r--r--src/lib/libcrypto/cms/cms_enc.c262
-rw-r--r--src/lib/libcrypto/cms/cms_env.c825
-rw-r--r--src/lib/libcrypto/cms/cms_err.c236
-rw-r--r--src/lib/libcrypto/cms/cms_ess.c420
-rw-r--r--src/lib/libcrypto/cms/cms_io.c140
-rw-r--r--src/lib/libcrypto/cms/cms_lcl.h460
-rw-r--r--src/lib/libcrypto/cms/cms_lib.c623
-rw-r--r--src/lib/libcrypto/cms/cms_sd.c1014
-rw-r--r--src/lib/libcrypto/cms/cms_smime.c806
-rw-r--r--src/lib/libcrypto/des/asm/des_enc.m41980
-rw-r--r--src/lib/libcrypto/dh/dh_depr.c83
-rw-r--r--src/lib/libcrypto/doc/ERR_set_mark.pod38
-rw-r--r--src/lib/libcrypto/doc/PKCS12_create.pod18
-rw-r--r--src/lib/libcrypto/doc/PKCS7_sign.pod24
-rw-r--r--src/lib/libcrypto/doc/SMIME_write_PKCS7.pod14
-rw-r--r--src/lib/libcrypto/doc/X509_NAME_print_ex.pod4
-rw-r--r--src/lib/libcrypto/doc/d2i_X509.pod6
-rw-r--r--src/lib/libcrypto/doc/d2i_X509_CRL.pod2
-rw-r--r--src/lib/libcrypto/doc/d2i_X509_REQ.pod2
-rw-r--r--src/lib/libcrypto/doc/engine.pod212
-rw-r--r--src/lib/libcrypto/doc/x509.pod64
-rw-r--r--src/lib/libcrypto/dsa/dsa_depr.c106
-rw-r--r--src/lib/libcrypto/ec/ec2_mult.c380
-rw-r--r--src/lib/libcrypto/ec/ec2_smpl.c971
-rw-r--r--src/lib/libcrypto/ec/ec_asn1.c1429
-rw-r--r--src/lib/libcrypto/ec/ec_check.c123
-rw-r--r--src/lib/libcrypto/ec/ec_curve.c1270
-rw-r--r--src/lib/libcrypto/ec/ec_key.c465
-rw-r--r--src/lib/libcrypto/ec/ec_print.c195
-rw-r--r--src/lib/libcrypto/ecdh/ecdh.h123
-rw-r--r--src/lib/libcrypto/ecdh/ech_err.c98
-rw-r--r--src/lib/libcrypto/ecdh/ech_key.c83
-rw-r--r--src/lib/libcrypto/ecdh/ech_lib.c247
-rw-r--r--src/lib/libcrypto/ecdh/ech_locl.h94
-rw-r--r--src/lib/libcrypto/ecdsa/ecdsa.h271
-rw-r--r--src/lib/libcrypto/ecdsa/ecs_asn1.c67
-rw-r--r--src/lib/libcrypto/ecdsa/ecs_err.c104
-rw-r--r--src/lib/libcrypto/ecdsa/ecs_lib.c261
-rw-r--r--src/lib/libcrypto/ecdsa/ecs_locl.h107
-rw-r--r--src/lib/libcrypto/ecdsa/ecs_ossl.c478
-rw-r--r--src/lib/libcrypto/ecdsa/ecs_sign.c104
-rw-r--r--src/lib/libcrypto/ecdsa/ecs_vrf.c96
-rw-r--r--src/lib/libcrypto/engine/eng_padlock.c1219
-rw-r--r--src/lib/libcrypto/engine/tb_ecdh.c133
-rw-r--r--src/lib/libcrypto/engine/tb_ecdsa.c118
-rw-r--r--src/lib/libcrypto/engine/tb_store.c123
-rw-r--r--src/lib/libcrypto/evp/e_camellia.c131
-rw-r--r--src/lib/libcrypto/evp/e_old.c17
-rw-r--r--src/lib/libcrypto/evp/m_ecdsa.c148
-rw-r--r--src/lib/libcrypto/ia64cpuid.S121
-rwxr-xr-xsrc/lib/libcrypto/md5/asm/md5-x86_64.pl245
-rw-r--r--src/lib/libcrypto/mem_clr.c12
-rw-r--r--src/lib/libcrypto/o_str.c13
-rwxr-xr-xsrc/lib/libcrypto/perlasm/x86_64-xlate.pl554
-rwxr-xr-xsrc/lib/libcrypto/rc4/asm/rc4-x86_64.pl286
-rw-r--r--src/lib/libcrypto/rsa/rsa_depr.c101
-rw-r--r--src/lib/libcrypto/rsa/rsa_pss.c10
-rw-r--r--src/lib/libcrypto/rsa/rsa_x931.c2
-rw-r--r--src/lib/libcrypto/sha/asm/sha1-ia64.pl346
-rwxr-xr-xsrc/lib/libcrypto/sha/asm/sha1-x86_64.pl242
-rwxr-xr-xsrc/lib/libcrypto/sha/asm/sha512-ia64.pl672
-rwxr-xr-xsrc/lib/libcrypto/sha/asm/sha512-x86_64.pl344
-rw-r--r--src/lib/libcrypto/sha/sha256.c282
-rw-r--r--src/lib/libcrypto/sha/sha512.c537
-rw-r--r--src/lib/libcrypto/sparccpuid.S239
-rw-r--r--src/lib/libcrypto/x509/x509_vpm.c420
-rw-r--r--src/lib/libcrypto/x509v3/pcy_cache.c287
-rw-r--r--src/lib/libcrypto/x509v3/pcy_data.c123
-rw-r--r--src/lib/libcrypto/x509v3/pcy_int.h223
-rw-r--r--src/lib/libcrypto/x509v3/pcy_lib.c167
-rw-r--r--src/lib/libcrypto/x509v3/pcy_map.c186
-rw-r--r--src/lib/libcrypto/x509v3/pcy_node.c158
-rw-r--r--src/lib/libcrypto/x509v3/pcy_tree.c692
-rw-r--r--src/lib/libcrypto/x509v3/v3_ncons.c220
-rw-r--r--src/lib/libcrypto/x509v3/v3_pci.c31
-rw-r--r--src/lib/libcrypto/x509v3/v3_pcons.c136
-rw-r--r--src/lib/libcrypto/x509v3/v3_pmaps.c153
-rw-r--r--src/lib/libcrypto/x86_64cpuid.pl159
-rw-r--r--src/lib/libcrypto/x86cpuid.pl225
-rw-r--r--src/lib/libssl/d1_both.c1193
-rw-r--r--src/lib/libssl/d1_clnt.c1156
-rw-r--r--src/lib/libssl/d1_enc.c281
-rw-r--r--src/lib/libssl/d1_lib.c210
-rw-r--r--src/lib/libssl/d1_meth.c77
-rw-r--r--src/lib/libssl/d1_pkt.c1778
-rw-r--r--src/lib/libssl/d1_srvr.c1147
-rw-r--r--src/lib/libssl/dtls1.h211
-rw-r--r--src/lib/libssl/test/CAss.cnf45
-rw-r--r--src/lib/libssl/test/cms-examples.pl409
-rw-r--r--src/lib/libssl/test/cms-test.pl453
-rw-r--r--src/lib/libssl/test/smcont.txt1
-rw-r--r--src/lib/libssl/test/smime-certs/smdsa1.pem34
-rw-r--r--src/lib/libssl/test/smime-certs/smdsa2.pem34
-rw-r--r--src/lib/libssl/test/smime-certs/smdsa3.pem34
-rw-r--r--src/lib/libssl/test/smime-certs/smdsap.pem9
-rw-r--r--src/lib/libssl/test/smime-certs/smroot.pem30
-rw-r--r--src/lib/libssl/test/smime-certs/smrsa1.pem31
-rw-r--r--src/lib/libssl/test/smime-certs/smrsa2.pem31
-rw-r--r--src/lib/libssl/test/smime-certs/smrsa3.pem31
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))
58typedef 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
79void 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
213void 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
58static const unsigned char default_iv[] = {
59 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6,
60};
61
62int 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
99int 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
143int 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
185int main(int argc, char **argv)
186{
187
188static 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
195static 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
202static 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
208static 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
214static 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
220static 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
227static 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
234static 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
33rk0=r8; rk1=r9;
34
35pfssave=r2;
36lcsave=r10;
37prsave=r3;
38maskff=r11;
39twenty4=r14;
40sixteen=r15;
41
42te00=r16; te11=r17; te22=r18; te33=r19;
43te01=r20; te12=r21; te23=r22; te30=r23;
44te02=r24; te13=r25; te20=r26; te31=r27;
45te03=r28; te10=r29; te21=r30; te32=r31;
46
47// these are rotating...
48t0=r32; s0=r33;
49t1=r34; s1=r35;
50t2=r36; s2=r37;
51t3=r38; s3=r39;
52
53te0=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
279AES_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
418print "// *AES_decrypt are autogenerated by the following script:\n#if 0\n";
419open(PROG,'<'.$0); while(<PROG>) { print; } close(PROG);
420print "#endif\n";
421while(<>) {
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
656AES_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
796AES_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
962AES_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;
30open 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
50sub hi() { my $r=shift; $r =~ s/%[er]([a-d])x/%\1h/; $r; }
51sub 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; }
54sub _data_word()
55{ my $i;
56 while(defined($i=shift)) { $code.=sprintf".long\t0x%08x,0x%08x\n",$i,$i; }
57}
58sub 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
66sub 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
74sub 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
134sub 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
229sub 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
265sub 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
353AES_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
392sub 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
452sub 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
542sub 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
574sub 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
667AES_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
717sub 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
751AES_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
947sub 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
975AES_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
1037my $_rsp="0(%rsp)"; # saved %rsp
1038my $_len="8(%rsp)"; # copy of 3rd parameter, length
1039my $_key="16(%rsp)"; # copy of 4th parameter, key
1040my $_ivp="24(%rsp)"; # copy of 5th parameter, ivp
1041my $keyp="32(%rsp)"; # one to pass as $key
1042my $ivec="40(%rsp)"; # ivec[16]
1043my $aes_key="56(%rsp)"; # copy of aes_key
1044my $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
1050AES_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
1399AES_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
1474AES_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
1576print $code;
1577
1578close 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
89struct tag_name_st
90 {
91 const char *strnam;
92 int len;
93 int tag;
94 };
95
96typedef 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
105typedef 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
116static int bitstr_cb(const char *elem, int len, void *bitstr);
117static int asn1_cb(const char *elem, int len, void *bitstr);
118static int append_exp(tag_exp_arg *arg, int exp_tag, int exp_class, int exp_constructed, int exp_pad, int imp_ok);
119static int parse_tagging(const char *vstart, int vlen, int *ptag, int *pclass);
120static ASN1_TYPE *asn1_multi(int utype, const char *section, X509V3_CTX *cnf);
121static ASN1_TYPE *asn1_str2type(const char *str, int format, int utype);
122static int asn1_str2tag(const char *tagstr, int len);
123
124ASN1_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
135ASN1_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
269static 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
378static 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
440static 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
509static 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
549static 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
624static 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
827static 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
72typedef struct {
73char *param_name; /* Param name e.g. "micalg" */
74char *param_value; /* Param value e.g. "sha1" */
75} MIME_PARAM;
76
77DECLARE_STACK_OF(MIME_PARAM)
78IMPLEMENT_STACK_OF(MIME_PARAM)
79
80typedef struct {
81char *name; /* Name of line e.g. "content-type" */
82char *value; /* Value of line e.g. "text/plain" */
83STACK_OF(MIME_PARAM) *params; /* Zero or more parameters */
84} MIME_HEADER;
85
86DECLARE_STACK_OF(MIME_HEADER)
87IMPLEMENT_STACK_OF(MIME_HEADER)
88
89static char * strip_ends(char *name);
90static char * strip_start(char *name);
91static char * strip_end(char *name);
92static MIME_HEADER *mime_hdr_new(char *name, char *value);
93static int mime_hdr_addparam(MIME_HEADER *mhdr, char *name, char *value);
94static STACK_OF(MIME_HEADER) *mime_parse_hdr(BIO *bio);
95static int mime_hdr_cmp(const MIME_HEADER * const *a,
96 const MIME_HEADER * const *b);
97static int mime_param_cmp(const MIME_PARAM * const *a,
98 const MIME_PARAM * const *b);
99static void mime_param_free(MIME_PARAM *param);
100static int mime_bound_check(char *line, int linelen, char *bound, int blen);
101static int multi_split(BIO *bio, char *bound, STACK_OF(BIO) **ret);
102static int strip_eol(char *linebuf, int *plen);
103static MIME_HEADER *mime_hdr_find(STACK_OF(MIME_HEADER) *hdrs, char *name);
104static MIME_PARAM *mime_param_find(MIME_HEADER *hdr, char *name);
105static 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
112static 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
133static 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
153static 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
207int 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
306static 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
362ASN1_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 */
466int 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 */
504int 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
536static 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
588static 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
683return headers;
684
685}
686
687static 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 */
693static 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? */
710static 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
728static 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
761static 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
790static 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
796static 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
804static 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
814static 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, &param);
820 if(idx < 0) return NULL;
821 return sk_MIME_PARAM_value(hdr->params, idx);
822}
823
824static 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
832static 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 */
844static 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
858static 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
77static int dgram_write(BIO *h, const char *buf, int num);
78static int dgram_read(BIO *h, char *buf, int size);
79static int dgram_puts(BIO *h, const char *str);
80static long dgram_ctrl(BIO *h, int cmd, long arg1, void *arg2);
81static int dgram_new(BIO *h);
82static int dgram_free(BIO *data);
83static int dgram_clear(BIO *bio);
84
85int BIO_dgram_should_retry(int s);
86
87static 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
101typedef 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
109BIO_METHOD *BIO_s_datagram(void)
110 {
111 return(&methods_dgramp);
112 }
113
114BIO *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
124static 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
140static 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
154static 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
169static 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
204static 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
237static 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
397static 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
406int 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
424int 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
23die "can't locate x86_64-xlate.pl";
24
25open 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
49bn_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
213print $code;
214close 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
14BIGNUM *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
37BIGNUM *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
63BIGNUM *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
93BIGNUM *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
129BIGNUM *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
175BIGNUM *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
232BIGNUM *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
310BIGNUM *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
65static void *dummy=&dummy;
66
67#ifndef OPENSSL_NO_DEPRECATED
68BIGNUM *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;
89err:
90 if (!found && (ret == NULL) && (rnd != NULL)) BN_free(rnd);
91 return(found ? rnd : NULL);
92 }
93
94int 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
102int 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
100static 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
143static 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
166static 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
193static 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)
225static 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 */
270static 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 */
286int 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. */
323int 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 */
417int 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);
433err:
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 */
442int 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
483err:
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 */
495int 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);
512err:
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. */
519int 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;
540err:
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 */
551int 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);
568err:
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 */
579int 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
630err:
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 */
641int 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
654err:
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 */
664int 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
682err:
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 */
693int 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
754err:
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 */
767int 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
782err:
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 */
792int 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;
823err:
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 */
835int 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);
852err:
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 */
861int 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
882err:
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 */
894int 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);
910err:
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 */
918int 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
1002err:
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 */
1013int 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);
1030err:
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 */
1041int 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 */
1075int 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
69static const BN_ULONG _nist_p_192[] =
70 {0xFFFFFFFFFFFFFFFFULL,0xFFFFFFFFFFFFFFFEULL,
71 0xFFFFFFFFFFFFFFFFULL};
72static const BN_ULONG _nist_p_224[] =
73 {0x0000000000000001ULL,0xFFFFFFFF00000000ULL,
74 0xFFFFFFFFFFFFFFFFULL,0x00000000FFFFFFFFULL};
75static const BN_ULONG _nist_p_256[] =
76 {0xFFFFFFFFFFFFFFFFULL,0x00000000FFFFFFFFULL,
77 0x0000000000000000ULL,0xFFFFFFFF00000001ULL};
78static const BN_ULONG _nist_p_384[] =
79 {0x00000000FFFFFFFFULL,0xFFFFFFFF00000000ULL,
80 0xFFFFFFFFFFFFFFFEULL,0xFFFFFFFFFFFFFFFFULL,
81 0xFFFFFFFFFFFFFFFFULL,0xFFFFFFFFFFFFFFFFULL};
82static 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
89static const BN_ULONG _nist_p_192[] = {0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFE,
90 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF};
91static const BN_ULONG _nist_p_224[] = {0x00000001,0x00000000,0x00000000,
92 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF};
93static const BN_ULONG _nist_p_256[] = {0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
94 0x00000000,0x00000000,0x00000000,0x00000001,0xFFFFFFFF};
95static const BN_ULONG _nist_p_384[] = {0xFFFFFFFF,0x00000000,0x00000000,
96 0xFFFFFFFF,0xFFFFFFFE,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
97 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF};
98static 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
104const 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
111const 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
118const 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
125const 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
132const 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
141static 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
151static 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
190int 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
262int 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
354int 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
495int 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
640int 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;
687err:
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) \
109do \
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) \
119do \
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) \
135do \
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) \
160do \
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) \
178do \
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
201static 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
269static 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
337static 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
405static 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
479void 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
782void 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
1194void 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 */
1214void 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
1304void 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 */
1397void 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
1511void 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
68extern "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 */
78typedef unsigned int KEY_TABLE_TYPE[CAMELLIA_TABLE_WORD_LEN];
79
80struct 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
88typedef struct camellia_key_st CAMELLIA_KEY;
89
90int Camellia_set_key(const unsigned char *userKey, const int bits,
91 CAMELLIA_KEY *key);
92
93void Camellia_encrypt(const unsigned char *in, unsigned char *out,
94 const CAMELLIA_KEY *key);
95void Camellia_decrypt(const unsigned char *in, unsigned char *out,
96 const CAMELLIA_KEY *key);
97
98void Camellia_ecb_encrypt(const unsigned char *in, unsigned char *out,
99 const CAMELLIA_KEY *key, const int enc);
100void 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);
103void 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);
106void 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);
109void 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);
112void 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);
115void 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);
118void 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
64void 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
126void 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 */
171void 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 */
204void 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
223void 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 */
65static 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 */
115void 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
62void 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
76typedef unsigned char u8;
77typedef unsigned int u32;
78
79#ifdef __cplusplus
80extern "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
151void camellia_setup128(const u8 *key, u32 *subkey);
152void camellia_setup192(const u8 *key, u32 *subkey);
153void camellia_setup256(const u8 *key, u32 *subkey);
154
155void camellia_encrypt128(const u32 *subkey, u32 *io);
156void camellia_decrypt128(const u32 *subkey, u32 *io);
157void camellia_encrypt256(const u32 *subkey, u32 *io);
158void 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
56const char CAMELLIA_version[]="CAMELLIA" OPENSSL_VERSION_PTEXT;
57
58int 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
91void 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
104void 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 */
121void 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
65extern "C" {
66#endif
67
68
69typedef struct CMS_ContentInfo_st CMS_ContentInfo;
70typedef struct CMS_SignerInfo_st CMS_SignerInfo;
71typedef struct CMS_CertificateChoices CMS_CertificateChoices;
72typedef struct CMS_RevocationInfoChoice_st CMS_RevocationInfoChoice;
73typedef struct CMS_RecipientInfo_st CMS_RecipientInfo;
74typedef struct CMS_ReceiptRequest_st CMS_ReceiptRequest;
75typedef struct CMS_Receipt_st CMS_Receipt;
76
77DECLARE_STACK_OF(CMS_SignerInfo)
78DECLARE_STACK_OF(GENERAL_NAMES)
79DECLARE_ASN1_FUNCTIONS_const(CMS_ContentInfo)
80DECLARE_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
114const ASN1_OBJECT *CMS_get0_type(CMS_ContentInfo *cms);
115
116BIO *CMS_dataInit(CMS_ContentInfo *cms, BIO *icont);
117int CMS_dataFinal(CMS_ContentInfo *cms, BIO *bio);
118
119ASN1_OCTET_STRING **CMS_get0_content(CMS_ContentInfo *cms);
120int CMS_is_detached(CMS_ContentInfo *cms);
121int CMS_set_detached(CMS_ContentInfo *cms, int detached);
122
123#ifdef HEADER_PEM_H
124DECLARE_PEM_rw_const(CMS, CMS_ContentInfo)
125#endif
126
127CMS_ContentInfo *d2i_CMS_bio(BIO *bp, CMS_ContentInfo **cms);
128int i2d_CMS_bio(BIO *bp, CMS_ContentInfo *cms);
129
130CMS_ContentInfo *SMIME_read_CMS(BIO *bio, BIO **bcont);
131int SMIME_write_CMS(BIO *bio, CMS_ContentInfo *cms, BIO *data, int flags);
132
133int CMS_final(CMS_ContentInfo *cms, BIO *data, BIO *dcont, unsigned int flags);
134
135CMS_ContentInfo *CMS_sign(X509 *signcert, EVP_PKEY *pkey, STACK_OF(X509) *certs,
136 BIO *data, unsigned int flags);
137
138CMS_ContentInfo *CMS_sign_receipt(CMS_SignerInfo *si,
139 X509 *signcert, EVP_PKEY *pkey,
140 STACK_OF(X509) *certs,
141 unsigned int flags);
142
143int CMS_data(CMS_ContentInfo *cms, BIO *out, unsigned int flags);
144CMS_ContentInfo *CMS_data_create(BIO *in, unsigned int flags);
145
146int CMS_digest_verify(CMS_ContentInfo *cms, BIO *dcont, BIO *out,
147 unsigned int flags);
148CMS_ContentInfo *CMS_digest_create(BIO *in, const EVP_MD *md,
149 unsigned int flags);
150
151int CMS_EncryptedData_decrypt(CMS_ContentInfo *cms,
152 const unsigned char *key, size_t keylen,
153 BIO *dcont, BIO *out, unsigned int flags);
154
155CMS_ContentInfo *CMS_EncryptedData_encrypt(BIO *in, const EVP_CIPHER *cipher,
156 const unsigned char *key, size_t keylen,
157 unsigned int flags);
158
159int CMS_EncryptedData_set1_key(CMS_ContentInfo *cms, const EVP_CIPHER *ciph,
160 const unsigned char *key, size_t keylen);
161
162int CMS_verify(CMS_ContentInfo *cms, STACK_OF(X509) *certs,
163 X509_STORE *store, BIO *dcont, BIO *out, unsigned int flags);
164
165int CMS_verify_receipt(CMS_ContentInfo *rcms, CMS_ContentInfo *ocms,
166 STACK_OF(X509) *certs,
167 X509_STORE *store, unsigned int flags);
168
169STACK_OF(X509) *CMS_get0_signers(CMS_ContentInfo *cms);
170
171CMS_ContentInfo *CMS_encrypt(STACK_OF(X509) *certs, BIO *in,
172 const EVP_CIPHER *cipher, unsigned int flags);
173
174int CMS_decrypt(CMS_ContentInfo *cms, EVP_PKEY *pkey, X509 *cert,
175 BIO *dcont, BIO *out,
176 unsigned int flags);
177
178int CMS_decrypt_set1_pkey(CMS_ContentInfo *cms, EVP_PKEY *pk, X509 *cert);
179int CMS_decrypt_set1_key(CMS_ContentInfo *cms,
180 unsigned char *key, size_t keylen,
181 unsigned char *id, size_t idlen);
182
183STACK_OF(CMS_RecipientInfo) *CMS_get0_RecipientInfos(CMS_ContentInfo *cms);
184int CMS_RecipientInfo_type(CMS_RecipientInfo *ri);
185CMS_ContentInfo *CMS_EnvelopedData_create(const EVP_CIPHER *cipher);
186CMS_RecipientInfo *CMS_add1_recipient_cert(CMS_ContentInfo *cms,
187 X509 *recip, unsigned int flags);
188int CMS_RecipientInfo_set0_pkey(CMS_RecipientInfo *ri, EVP_PKEY *pkey);
189int CMS_RecipientInfo_ktri_cert_cmp(CMS_RecipientInfo *ri, X509 *cert);
190int CMS_RecipientInfo_ktri_get0_algs(CMS_RecipientInfo *ri,
191 EVP_PKEY **pk, X509 **recip,
192 X509_ALGOR **palg);
193int CMS_RecipientInfo_ktri_get0_signer_id(CMS_RecipientInfo *ri,
194 ASN1_OCTET_STRING **keyid,
195 X509_NAME **issuer, ASN1_INTEGER **sno);
196
197CMS_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
204int 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
211int CMS_RecipientInfo_set0_key(CMS_RecipientInfo *ri,
212 unsigned char *key, size_t keylen);
213
214int CMS_RecipientInfo_kekri_id_cmp(CMS_RecipientInfo *ri,
215 const unsigned char *id, size_t idlen);
216
217int CMS_RecipientInfo_decrypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri);
218
219int CMS_uncompress(CMS_ContentInfo *cms, BIO *dcont, BIO *out,
220 unsigned int flags);
221CMS_ContentInfo *CMS_compress(BIO *in, int comp_nid, unsigned int flags);
222
223int CMS_set1_eContentType(CMS_ContentInfo *cms, const ASN1_OBJECT *oid);
224const ASN1_OBJECT *CMS_get0_eContentType(CMS_ContentInfo *cms);
225
226CMS_CertificateChoices *CMS_add0_CertificateChoices(CMS_ContentInfo *cms);
227int CMS_add0_cert(CMS_ContentInfo *cms, X509 *cert);
228int CMS_add1_cert(CMS_ContentInfo *cms, X509 *cert);
229STACK_OF(X509) *CMS_get1_certs(CMS_ContentInfo *cms);
230
231CMS_RevocationInfoChoice *CMS_add0_RevocationInfoChoice(CMS_ContentInfo *cms);
232int CMS_add0_crl(CMS_ContentInfo *cms, X509_CRL *crl);
233STACK_OF(X509_CRL) *CMS_get1_crls(CMS_ContentInfo *cms);
234
235int CMS_SignedData_init(CMS_ContentInfo *cms);
236CMS_SignerInfo *CMS_add1_signer(CMS_ContentInfo *cms,
237 X509 *signer, EVP_PKEY *pk, const EVP_MD *md,
238 unsigned int flags);
239STACK_OF(CMS_SignerInfo) *CMS_get0_SignerInfos(CMS_ContentInfo *cms);
240
241void CMS_SignerInfo_set1_signer_cert(CMS_SignerInfo *si, X509 *signer);
242int CMS_SignerInfo_get0_signer_id(CMS_SignerInfo *si,
243 ASN1_OCTET_STRING **keyid,
244 X509_NAME **issuer, ASN1_INTEGER **sno);
245int CMS_SignerInfo_cert_cmp(CMS_SignerInfo *si, X509 *cert);
246int CMS_set1_signers_certs(CMS_ContentInfo *cms, STACK_OF(X509) *certs,
247 unsigned int flags);
248void CMS_SignerInfo_get0_algs(CMS_SignerInfo *si, EVP_PKEY **pk, X509 **signer,
249 X509_ALGOR **pdig, X509_ALGOR **psig);
250int CMS_SignerInfo_sign(CMS_SignerInfo *si);
251int CMS_SignerInfo_verify(CMS_SignerInfo *si);
252int CMS_SignerInfo_verify_content(CMS_SignerInfo *si, BIO *chain);
253
254int CMS_add_smimecap(CMS_SignerInfo *si, STACK_OF(X509_ALGOR) *algs);
255int CMS_add_simple_smimecap(STACK_OF(X509_ALGOR) **algs,
256 int algnid, int keysize);
257int CMS_add_standard_smimecap(STACK_OF(X509_ALGOR) **smcap);
258
259int CMS_signed_get_attr_count(const CMS_SignerInfo *si);
260int CMS_signed_get_attr_by_NID(const CMS_SignerInfo *si, int nid,
261 int lastpos);
262int CMS_signed_get_attr_by_OBJ(const CMS_SignerInfo *si, ASN1_OBJECT *obj,
263 int lastpos);
264X509_ATTRIBUTE *CMS_signed_get_attr(const CMS_SignerInfo *si, int loc);
265X509_ATTRIBUTE *CMS_signed_delete_attr(CMS_SignerInfo *si, int loc);
266int CMS_signed_add1_attr(CMS_SignerInfo *si, X509_ATTRIBUTE *attr);
267int CMS_signed_add1_attr_by_OBJ(CMS_SignerInfo *si,
268 const ASN1_OBJECT *obj, int type,
269 const void *bytes, int len);
270int CMS_signed_add1_attr_by_NID(CMS_SignerInfo *si,
271 int nid, int type,
272 const void *bytes, int len);
273int CMS_signed_add1_attr_by_txt(CMS_SignerInfo *si,
274 const char *attrname, int type,
275 const void *bytes, int len);
276void *CMS_signed_get0_data_by_OBJ(CMS_SignerInfo *si, ASN1_OBJECT *oid,
277 int lastpos, int type);
278
279int CMS_unsigned_get_attr_count(const CMS_SignerInfo *si);
280int CMS_unsigned_get_attr_by_NID(const CMS_SignerInfo *si, int nid,
281 int lastpos);
282int CMS_unsigned_get_attr_by_OBJ(const CMS_SignerInfo *si, ASN1_OBJECT *obj,
283 int lastpos);
284X509_ATTRIBUTE *CMS_unsigned_get_attr(const CMS_SignerInfo *si, int loc);
285X509_ATTRIBUTE *CMS_unsigned_delete_attr(CMS_SignerInfo *si, int loc);
286int CMS_unsigned_add1_attr(CMS_SignerInfo *si, X509_ATTRIBUTE *attr);
287int CMS_unsigned_add1_attr_by_OBJ(CMS_SignerInfo *si,
288 const ASN1_OBJECT *obj, int type,
289 const void *bytes, int len);
290int CMS_unsigned_add1_attr_by_NID(CMS_SignerInfo *si,
291 int nid, int type,
292 const void *bytes, int len);
293int CMS_unsigned_add1_attr_by_txt(CMS_SignerInfo *si,
294 const char *attrname, int type,
295 const void *bytes, int len);
296void *CMS_unsigned_get0_data_by_OBJ(CMS_SignerInfo *si, ASN1_OBJECT *oid,
297 int lastpos, int type);
298
299#ifdef HEADER_X509V3_H
300
301int CMS_get1_ReceiptRequest(CMS_SignerInfo *si, CMS_ReceiptRequest **prr);
302CMS_ReceiptRequest *CMS_ReceiptRequest_create0(unsigned char *id, int idlen,
303 int allorfirst,
304 STACK_OF(GENERAL_NAMES) *receiptList,
305 STACK_OF(GENERAL_NAMES) *receiptsTo);
306int CMS_add1_ReceiptRequest(CMS_SignerInfo *si, CMS_ReceiptRequest *rr);
307void 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 */
319void 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
61ASN1_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
66ASN1_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
71ASN1_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
79ASN1_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
84ASN1_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 */
90static 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
103ASN1_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
113ASN1_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
118ASN1_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
123ASN1_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
132ASN1_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
137ASN1_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
143ASN1_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
150ASN1_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
155ASN1_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
161ASN1_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
166ASN1_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
171ASN1_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
176ASN1_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
182ASN1_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
190ASN1_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
196ASN1_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
203ASN1_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
210ASN1_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 */
216static 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
242ASN1_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
250ASN1_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
258ASN1_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
265ASN1_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
271ASN1_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
283ASN1_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
291ASN1_ADB_TEMPLATE(cms_default) = ASN1_EXP(CMS_ContentInfo, d.other, ASN1_ANY, 0);
292
293ASN1_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
303ASN1_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
314ASN1_ITEM_TEMPLATE(CMS_Attributes_Sign) =
315 ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SET_ORDER, 0, CMS_ATTRIBUTES, X509_ATTRIBUTE)
316ASN1_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
322ASN1_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)
325ASN1_ITEM_TEMPLATE_END(CMS_Attributes_Verify)
326
327
328
329ASN1_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
334ASN1_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
340ASN1_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
63int CMS_signed_get_attr_count(const CMS_SignerInfo *si)
64{
65 return X509at_get_attr_count(si->signedAttrs);
66}
67
68int 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
74int 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
80X509_ATTRIBUTE *CMS_signed_get_attr(const CMS_SignerInfo *si, int loc)
81{
82 return X509at_get_attr(si->signedAttrs, loc);
83}
84
85X509_ATTRIBUTE *CMS_signed_delete_attr(CMS_SignerInfo *si, int loc)
86{
87 return X509at_delete_attr(si->signedAttrs, loc);
88}
89
90int 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
96int 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
105int 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
114int 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
123void *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
129int CMS_unsigned_get_attr_count(const CMS_SignerInfo *si)
130{
131 return X509at_get_attr_count(si->unsignedAttrs);
132}
133
134int 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
140int 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
146X509_ATTRIBUTE *CMS_unsigned_get_attr(const CMS_SignerInfo *si, int loc)
147{
148 return X509at_get_attr(si->unsignedAttrs, loc);
149}
150
151X509_ATTRIBUTE *CMS_unsigned_delete_attr(CMS_SignerInfo *si, int loc)
152{
153 return X509at_delete_attr(si->unsignedAttrs, loc);
154}
155
156int 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
162int 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
171int 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
180int 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
189void *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
64DECLARE_ASN1_ITEM(CMS_CompressedData)
65
66#ifdef ZLIB
67
68/* CMS CompressedData Utilities */
69
70CMS_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
113BIO *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
62DECLARE_ASN1_ITEM(CMS_DigestedData)
63
64/* CMS DigestedData Utilities */
65
66CMS_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
97BIO *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
104int 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
65DECLARE_ASN1_ITEM(CMS_EncryptedData)
66
67/* Return BIO based on EncryptedContentInfo and key */
68
69BIO *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
207int 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
225int 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
256BIO *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
66DECLARE_ASN1_ITEM(CMS_EnvelopedData)
67DECLARE_ASN1_ITEM(CMS_RecipientInfo)
68DECLARE_ASN1_ITEM(CMS_KeyTransRecipientInfo)
69DECLARE_ASN1_ITEM(CMS_KEKRecipientInfo)
70DECLARE_ASN1_ITEM(CMS_OtherKeyAttribute)
71
72DECLARE_STACK_OF(CMS_RecipientInfo)
73
74static 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
85static 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
106STACK_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
115int CMS_RecipientInfo_type(CMS_RecipientInfo *ri)
116 {
117 return ri->type;
118 }
119
120CMS_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
147CMS_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
234int 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
257int 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
274int 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
285int 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
299static 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
348static 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
397int 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
417static 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
435CMS_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
547int 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
584int 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
603static 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
663static 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
742int 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
759BIO *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
71static 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
142static 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
226void 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
63DECLARE_ASN1_ITEM(CMS_ReceiptRequest)
64DECLARE_ASN1_ITEM(CMS_Receipt)
65
66IMPLEMENT_ASN1_FUNCTIONS_const(CMS_ReceiptRequest)
67
68/* ESS services: for now just Signed Receipt related */
69
70int 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
92CMS_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
140int 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
166void 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
194static 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
209int 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
229int 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
377ASN1_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
61CMS_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
66int i2d_CMS_bio(BIO *bp, CMS_ContentInfo *cms)
67 {
68 return ASN1_item_i2d_bio(ASN1_ITEM_rptr(CMS_ContentInfo), bp, cms);
69 }
70
71IMPLEMENT_PEM_rw_const(CMS, CMS_ContentInfo, PEM_STRING_CMS, CMS_ContentInfo)
72
73/* Callback for int_smime_write_ASN1 */
74
75static 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
120int 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
136CMS_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
58extern "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
69typedef struct CMS_IssuerAndSerialNumber_st CMS_IssuerAndSerialNumber;
70typedef struct CMS_EncapsulatedContentInfo_st CMS_EncapsulatedContentInfo;
71typedef struct CMS_SignerIdentifier_st CMS_SignerIdentifier;
72typedef struct CMS_SignedData_st CMS_SignedData;
73typedef struct CMS_OtherRevocationInfoFormat_st CMS_OtherRevocationInfoFormat;
74typedef struct CMS_OriginatorInfo_st CMS_OriginatorInfo;
75typedef struct CMS_EncryptedContentInfo_st CMS_EncryptedContentInfo;
76typedef struct CMS_EnvelopedData_st CMS_EnvelopedData;
77typedef struct CMS_DigestedData_st CMS_DigestedData;
78typedef struct CMS_EncryptedData_st CMS_EncryptedData;
79typedef struct CMS_AuthenticatedData_st CMS_AuthenticatedData;
80typedef struct CMS_CompressedData_st CMS_CompressedData;
81typedef struct CMS_OtherCertificateFormat_st CMS_OtherCertificateFormat;
82typedef struct CMS_KeyTransRecipientInfo_st CMS_KeyTransRecipientInfo;
83typedef struct CMS_OriginatorPublicKey_st CMS_OriginatorPublicKey;
84typedef struct CMS_OriginatorIdentifierOrKey_st CMS_OriginatorIdentifierOrKey;
85typedef struct CMS_KeyAgreeRecipientInfo_st CMS_KeyAgreeRecipientInfo;
86typedef struct CMS_OtherKeyAttribute_st CMS_OtherKeyAttribute;
87typedef struct CMS_RecipientKeyIdentifier_st CMS_RecipientKeyIdentifier;
88typedef struct CMS_KeyAgreeRecipientIdentifier_st CMS_KeyAgreeRecipientIdentifier;
89typedef struct CMS_RecipientEncryptedKey_st CMS_RecipientEncryptedKey;
90typedef struct CMS_KEKIdentifier_st CMS_KEKIdentifier;
91typedef struct CMS_KEKRecipientInfo_st CMS_KEKRecipientInfo;
92typedef struct CMS_PasswordRecipientInfo_st CMS_PasswordRecipientInfo;
93typedef struct CMS_OtherRecipientInfo_st CMS_OtherRecipientInfo;
94typedef struct CMS_ReceiptsFrom_st CMS_ReceiptsFrom;
95
96struct 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
113struct 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
123struct 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
131struct 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
145struct CMS_SignerIdentifier_st
146 {
147 int type;
148 union {
149 CMS_IssuerAndSerialNumber *issuerAndSerialNumber;
150 ASN1_OCTET_STRING *subjectKeyIdentifier;
151 } d;
152 };
153
154struct 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
163struct CMS_OriginatorInfo_st
164 {
165 STACK_OF(CMS_CertificateChoices) *certificates;
166 STACK_OF(CMS_RevocationInfoChoice) *crls;
167 };
168
169struct 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
180struct 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
192typedef CMS_SignerIdentifier CMS_RecipientIdentifier;
193
194struct 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
205struct 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
214struct 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
224struct CMS_OriginatorPublicKey_st
225 {
226 X509_ALGOR *algorithm;
227 ASN1_BIT_STRING *publicKey;
228 };
229
230struct CMS_RecipientEncryptedKey_st
231 {
232 CMS_KeyAgreeRecipientIdentifier *rid;
233 ASN1_OCTET_STRING *encryptedKey;
234 };
235
236struct CMS_KeyAgreeRecipientIdentifier_st
237 {
238 int type;
239 union {
240 CMS_IssuerAndSerialNumber *issuerAndSerialNumber;
241 CMS_RecipientKeyIdentifier *rKeyId;
242 } d;
243 };
244
245struct CMS_RecipientKeyIdentifier_st
246 {
247 ASN1_OCTET_STRING *subjectKeyIdentifier;
248 ASN1_GENERALIZEDTIME *date;
249 CMS_OtherKeyAttribute *other;
250 };
251
252struct 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
263struct CMS_KEKIdentifier_st
264 {
265 ASN1_OCTET_STRING *keyIdentifier;
266 ASN1_GENERALIZEDTIME *date;
267 CMS_OtherKeyAttribute *other;
268 };
269
270struct CMS_PasswordRecipientInfo_st
271 {
272 long version;
273 X509_ALGOR *keyDerivationAlgorithm;
274 X509_ALGOR *keyEncryptionAlgorithm;
275 ASN1_OCTET_STRING *encryptedKey;
276 };
277
278struct CMS_OtherRecipientInfo_st
279 {
280 ASN1_OBJECT *oriType;
281 ASN1_TYPE *oriValue;
282 };
283
284struct CMS_DigestedData_st
285 {
286 long version;
287 X509_ALGOR *digestAlgorithm;
288 CMS_EncapsulatedContentInfo *encapContentInfo;
289 ASN1_OCTET_STRING *digest;
290 };
291
292struct CMS_EncryptedData_st
293 {
294 long version;
295 CMS_EncryptedContentInfo *encryptedContentInfo;
296 STACK_OF(X509_ATTRIBUTE) *unprotectedAttrs;
297 };
298
299struct 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
312struct CMS_CompressedData_st
313 {
314 long version;
315 X509_ALGOR *compressionAlgorithm;
316 STACK_OF(CMS_RecipientInfo) *recipientInfos;
317 CMS_EncapsulatedContentInfo *encapContentInfo;
318 };
319
320struct 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
332struct CMS_OtherRevocationInfoFormat_st
333 {
334 ASN1_OBJECT *otherRevInfoFormat;
335 ASN1_TYPE *otherRevInfo;
336 };
337
338struct 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
356struct 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
366struct CMS_IssuerAndSerialNumber_st
367 {
368 X509_NAME *issuer;
369 ASN1_INTEGER *serialNumber;
370 };
371
372struct CMS_OtherKeyAttribute_st
373 {
374 ASN1_OBJECT *keyAttrId;
375 ASN1_TYPE *keyAttr;
376 };
377
378/* ESS structures */
379
380#ifdef HEADER_X509V3_H
381
382struct CMS_ReceiptRequest_st
383 {
384 ASN1_OCTET_STRING *signedContentIdentifier;
385 CMS_ReceiptsFrom *receiptsFrom;
386 STACK_OF(GENERAL_NAMES) *receiptsTo;
387 };
388
389
390struct 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
401struct CMS_Receipt_st
402 {
403 long version;
404 ASN1_OBJECT *contentType;
405 ASN1_OCTET_STRING *signedContentIdentifier;
406 ASN1_OCTET_STRING *originatorSignatureValue;
407 };
408
409DECLARE_ASN1_ITEM(CMS_SignerInfo)
410DECLARE_ASN1_ITEM(CMS_IssuerAndSerialNumber)
411DECLARE_ASN1_ITEM(CMS_Attributes_Sign)
412DECLARE_ASN1_ITEM(CMS_Attributes_Verify)
413DECLARE_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
421BIO *cms_content_bio(CMS_ContentInfo *cms);
422
423CMS_ContentInfo *cms_Data_create(void);
424
425CMS_ContentInfo *cms_DigestedData_create(const EVP_MD *md);
426BIO *cms_DigestedData_init_bio(CMS_ContentInfo *cms);
427int cms_DigestedData_do_final(CMS_ContentInfo *cms, BIO *chain, int verify);
428
429BIO *cms_SignedData_init_bio(CMS_ContentInfo *cms);
430int cms_SignedData_final(CMS_ContentInfo *cms, BIO *chain);
431int cms_set1_SignerIdentifier(CMS_SignerIdentifier *sid, X509 *cert, int type);
432int cms_SignerIdentifier_get0_signer_id(CMS_SignerIdentifier *sid,
433 ASN1_OCTET_STRING **keyid,
434 X509_NAME **issuer, ASN1_INTEGER **sno);
435int cms_SignerIdentifier_cert_cmp(CMS_SignerIdentifier *sid, X509 *cert);
436
437CMS_ContentInfo *cms_CompressedData_create(int comp_nid);
438BIO *cms_CompressedData_init_bio(CMS_ContentInfo *cms);
439
440void cms_DigestAlgorithm_set(X509_ALGOR *alg, const EVP_MD *md);
441BIO *cms_DigestAlgorithm_init_bio(X509_ALGOR *digestAlgorithm);
442int cms_DigestAlgorithm_find_ctx(EVP_MD_CTX *mctx, BIO *chain,
443 X509_ALGOR *mdalg);
444
445BIO *cms_EncryptedContent_init_bio(CMS_EncryptedContentInfo *ec);
446BIO *cms_EncryptedData_init_bio(CMS_ContentInfo *cms);
447int cms_EncryptedContent_init(CMS_EncryptedContentInfo *ec,
448 const EVP_CIPHER *cipher,
449 const unsigned char *key, size_t keylen);
450
451int cms_Receipt_verify(CMS_ContentInfo *cms, CMS_ContentInfo *req_cms);
452int cms_msgSigDigest_add1(CMS_SignerInfo *dest, CMS_SignerInfo *src);
453ASN1_OCTET_STRING *cms_encode_Receipt(CMS_SignerInfo *si);
454
455BIO *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
63IMPLEMENT_ASN1_FUNCTIONS_const(CMS_ContentInfo)
64
65DECLARE_ASN1_ITEM(CMS_CertificateChoices)
66DECLARE_ASN1_ITEM(CMS_RevocationInfoChoice)
67DECLARE_STACK_OF(CMS_CertificateChoices)
68DECLARE_STACK_OF(CMS_RevocationInfoChoice)
69
70const ASN1_OBJECT *CMS_get0_type(CMS_ContentInfo *cms)
71 {
72 return cms->contentType;
73 }
74
75CMS_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
88BIO *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
104BIO *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
157int 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
208ASN1_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
247static 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
278const 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
287int 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
303int 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
314int 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
345void 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
370BIO *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
399int 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
427static 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
446CMS_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
468int 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
499int 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
508static 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
527CMS_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
549int 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
560STACK_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
593STACK_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
64DECLARE_ASN1_ITEM(CMS_SignedData)
65
66static 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
76static 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
99int 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
109static 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
171static 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
209int 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
255int 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
276int 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
300CMS_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
472static 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
502STACK_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
511STACK_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
539void 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
553int 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
560int CMS_SignerInfo_cert_cmp(CMS_SignerInfo *si, X509 *cert)
561 {
562 return cms_SignerIdentifier_cert_cmp(si->sid, cert);
563 }
564
565int 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
616void 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
634static 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
648static 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
715int 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
731int 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
799int 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
842BIO *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
872int 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
942int 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
955int 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
988static 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
995static 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
1002int 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
62static 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
117static 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
128static 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
145int 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
162CMS_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
177int 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
201CMS_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
224int 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
250CMS_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
280static 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
317int 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
449int 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
460CMS_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
504CMS_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
576CMS_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
615int 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
651int 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
690int 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
714int 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
746int 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
769CMS_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
793int 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
800CMS_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
113changequote({,})
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
146define(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
297define(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
555define(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
646define(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
780define(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
843define(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
911define(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
978define(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
1045define(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
1106define(testvalue,{1})
1107
1108define(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
1178DES_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
1236DES_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
1351DES_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
1393DES_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
1534DES_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
1756DES_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
64static void *dummy=&dummy;
65
66#ifndef OPENSSL_NO_DEPRECATED
67DH *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
5ERR_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
17ERR_set_mark() sets a mark on the current topmost error record if there
18is one.
19
20ERR_pop_to_mark() will pop the top of the error stack until a mark is found.
21The mark is then removed. If there is no mark, the whole stack is removed.
22
23=head1 RETURN VALUES
24
25ERR_set_mark() returns 0 if the error stack is empty, otherwise 1.
26
27ERR_pop_to_mark() returns 0 if there was no mark in the error stack, which
28implies that the stack became empty, otherwise 1.
29
30=head1 SEE ALSO
31
32L<err(3)|err(3)>
33
34=head1 HISTORY
35
36ERR_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
46had restrictions on the permissible sizes of keys which could be used for 46had restrictions on the permissible sizes of keys which could be used for
47encryption. 47encryption.
48 48
49=head1 NEW FUNCTIONALITY IN OPENSSL 0.9.8
50
51Some additional functionality was added to PKCS12_create() in OpenSSL
520.9.8. These extensions are detailed below.
53
54If a certificate contains an B<alias> or B<keyid> then this will be
55used for the corresponding B<friendlyName> or B<localKeyID> in the
56PKCS12 structure.
57
58Either B<pkey>, B<cert> or both can be B<NULL> to indicate that no key or
59certficate is required. In previous versions both had to be present or
60a fatal error is returned.
61
62B<nid_key> or B<nid_cert> can be set to -1 indicating that no encryption
63should be used.
64
65B<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
51L<d2i_PKCS12(3)|d2i_PKCS12(3)> 69L<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
51algorithms: triple DES, 128 bit RC2, 64 bit RC2, DES and 40 bit RC2. If any 51algorithms: triple DES, 128 bit RC2, 64 bit RC2, DES and 40 bit RC2. If any
52of these algorithms is disabled then it will not be included. 52of these algorithms is disabled then it will not be included.
53 53
54If the flags B<PKCS7_PARTSIGN> is set then the returned B<PKCS7> structure
55is just initialized ready to perform the signing operation. The signing
56is however B<not> performed and the data to be signed is not read from
57the B<data> parameter. Signing is deferred until after the data has been
58written. In this way data can be signed in a single pass. Currently the
59flag B<PKCS7_DETACHED> B<must> also be set.
60
61=head1 NOTES
62
63Currently the flag B<PKCS7_PARTSIGN> is only supported for detached
64data. If this flag is set the returned B<PKCS7> structure is B<not>
65complete and outputting its contents via a function that does not
66properly finalize the B<PKCS7> structure will give unpredictable
67results.
68
69At present only the SMIME_write_PKCS7() function properly finalizes the
70structure.
71
54=head1 BUGS 72=head1 BUGS
55 73
56PKCS7_sign() is somewhat limited. It does not support multiple signers, some 74PKCS7_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
64having to hold it all in memory, this would however require fairly major 82having to hold it all in memory, this would however require fairly major
65revisions of the OpenSSL ASN1 code. 83revisions of the OpenSSL ASN1 code.
66 84
67Clear text signing does not store the content in memory but the way PKCS7_sign()
68operates means that two passes of the data must typically be made: one to compute
69the signatures and a second to output the data along with the signature. There
70should 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
83PKCS7_sign() was added to OpenSSL 0.9.5 97PKCS7_sign() was added to OpenSSL 0.9.5
84 98
99The 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>
30are added to the content, this only makes sense if B<PKCS7_DETACHED> 30are added to the content, this only makes sense if B<PKCS7_DETACHED>
31is also set. 31is also set.
32 32
33If cleartext signing is being used then the data must be read twice: 33If the B<PKCS7_PARTSIGN> flag is set the signed data is finalized
34once to compute the signature in PKCS7_sign() and once to output the 34and output along with the content. This flag should only be set
35S/MIME message. 35if B<PKCS7_DETACHED> is also set and the previous call to PKCS7_sign()
36also set these flags.
37
38If cleartext signing is being used and B<PKCS7_PARTSIGN> not set then
39the data must be read twice: once to compute the signature in PKCS7_sign()
40and once to output the S/MIME message.
36 41
37=head1 BUGS 42=head1 BUGS
38 43
39SMIME_write_PKCS7() always base64 encodes PKCS#7 structures, there 44SMIME_write_PKCS7() always base64 encodes PKCS#7 structures, there
40should be an option to disable this. 45should be an option to disable this.
41 46
42There should really be a way to produce cleartext signing using only
43a single pass of the data.
44
45=head1 RETURN VALUES 47=head1 RETURN VALUES
46 48
47SMIME_write_PKCS7() returns 1 for success or 0 for failure. 49SMIME_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
89B<XN_FLAG_ONELINE> is a more readable one line format it is the same as: 89B<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
92B<XN_FLAG_MULTILINE> is a multiline format is is the same as: 92B<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
95B<XN_FLAG_COMPAT> uses a format identical to X509_NAME_print(): in fact it calls X509_NAME_print() internally. 95B<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
23The X509 encode and decode routines encode and parse an 23The X509 encode and decode routines encode and parse an
24B<X509> structure, which represents an X509 certificate. 24B<X509> structure, which represents an X509 certificate.
25 25
26d2i_X509() attempts to decode B<len> bytes at B<*out>. If 26d2i_X509() attempts to decode B<len> bytes at B<*in>. If
27successful a pointer to the B<X509> structure is returned. If an error 27successful a pointer to the B<X509> structure is returned. If an error
28occurred then B<NULL> is returned. If B<px> is not B<NULL> then the 28occurred then B<NULL> is returned. If B<px> is not B<NULL> then the
29returned structure is written to B<*px>. If B<*px> is not B<NULL> 29returned structure is written to B<*px>. If B<*px> is not B<NULL>
30then it is assumed that B<*px> contains a valid B<X509> 30then it is assumed that B<*px> contains a valid B<X509>
31structure and an attempt is made to reuse it. If the call is 31structure and an attempt is made to reuse it. If the call is
32successful B<*out> is incremented to the byte following the 32successful B<*in> is incremented to the byte following the
33parsed data. 33parsed data.
34 34
35i2d_X509() encodes the structure pointed to by B<x> into DER format. 35i2d_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>
148implementation includes the following abstractions; 171implementation 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
158Due to the modular nature of the ENGINE API, pointers to ENGINEs need to be 182Due to the modular nature of the ENGINE API, pointers to ENGINEs need to be
159treated as handles - ie. not only as pointers, but also as references to 183treated as handles - ie. not only as pointers, but also as references to
160the underlying ENGINE object. Ie. you should obtain a new reference when 184the underlying ENGINE object. Ie. one should obtain a new reference when
161making copies of an ENGINE pointer if the copies will be used (and 185making copies of an ENGINE pointer if the copies will be used (and
162released) independantly. 186released) independently.
163 187
164ENGINE objects have two levels of reference-counting to match the way in 188ENGINE objects have two levels of reference-counting to match the way in
165which the objects are used. At the most basic level, each ENGINE pointer is 189which the objects are used. At the most basic level, each ENGINE pointer is
166inherently a B<structural> reference - you need a structural reference 190inherently a B<structural> reference - a structural reference is required
167simply to refer to the pointer value at all, as this kind of reference is 191to use the pointer value at all, as this kind of reference is a guarantee
168your guarantee that the structure can not be deallocated until you release 192that the structure can not be deallocated until the reference is released.
169your reference. 193
170 194However, a structural reference provides no guarantee that the ENGINE is
171However, a structural reference provides no guarantee that the ENGINE has 195initiliased and able to use any of its cryptographic
172been initiliased to be usable to perform any of its cryptographic 196implementations. Indeed it's quite possible that most ENGINEs will not
173implementations - and indeed it's quite possible that most ENGINEs will not 197initialise at all in typical environments, as ENGINEs are typically used to
174initialised at all on standard setups, as ENGINEs are typically used to
175support specialised hardware. To use an ENGINE's functionality, you need a 198support specialised hardware. To use an ENGINE's functionality, you need a
176B<functional> reference. This kind of reference can be considered a 199B<functional> reference. This kind of reference can be considered a
177specialised form of structural reference, because each functional reference 200specialised form of structural reference, because each functional reference
178implicitly contains a structural reference as well - however to avoid 201implicitly contains a structural reference as well - however to avoid
179difficult-to-find programming bugs, it is recommended to treat the two 202difficult-to-find programming bugs, it is recommended to treat the two
180kinds of reference independantly. If you have a functional reference to an 203kinds of reference independently. If you have a functional reference to an
181ENGINE, you have a guarantee that the ENGINE has been initialised ready to 204ENGINE, you have a guarantee that the ENGINE has been initialised ready to
182perform cryptographic operations and will not be uninitialised or cleaned 205perform cryptographic operations and will remain uninitialised
183up until after you have released your reference. 206until after you have released your reference.
184
185We will discuss the two kinds of reference separately, including how to
186tell which one you are dealing with at any given point in time (after all
187they are both simply (ENGINE *) pointers, the difference is in the way they
188are used).
189 207
190I<Structural references> 208I<Structural references>
191 209
192This basic type of reference is typically used for creating new ENGINEs 210This basic type of reference is used for instantiating new ENGINEs,
193dynamically, iterating across OpenSSL's internal linked-list of loaded 211iterating across OpenSSL's internal linked-list of loaded
194ENGINEs, reading information about an ENGINE, etc. Essentially a structural 212ENGINEs, reading information about an ENGINE, etc. Essentially a structural
195reference is sufficient if you only need to query or manipulate the data of 213reference is sufficient if you only need to query or manipulate the data of
196an ENGINE implementation rather than use its functionality. 214an ENGINE implementation rather than use its functionality.
197 215
198The ENGINE_new() function returns a structural reference to a new (empty) 216The ENGINE_new() function returns a structural reference to a new (empty)
199ENGINE object. Other than that, structural references come from return 217ENGINE object. There are other ENGINE API functions that return structural
200values to various ENGINE API functions such as; ENGINE_by_id(), 218references such as; ENGINE_by_id(), ENGINE_get_first(), ENGINE_get_last(),
201ENGINE_get_first(), ENGINE_get_last(), ENGINE_get_next(), 219ENGINE_get_next(), ENGINE_get_prev(). All structural references should be
202ENGINE_get_prev(). All structural references should be released by a 220released by a corresponding to call to the ENGINE_free() function - the
203corresponding to call to the ENGINE_free() function - the ENGINE object 221ENGINE object itself will only actually be cleaned up and deallocated when
204itself will only actually be cleaned up and deallocated when the last 222the last structural reference is released.
205structural reference is released.
206 223
207It should also be noted that many ENGINE API function calls that accept a 224It should also be noted that many ENGINE API function calls that accept a
208structural reference will internally obtain another reference - typically 225structural reference will internally obtain another reference - typically
@@ -237,15 +254,9 @@ call the ENGINE_init() function. This returns zero if the ENGINE was not
237already operational and couldn't be successfully initialised (eg. lack of 254already operational and couldn't be successfully initialised (eg. lack of
238system drivers, no special hardware attached, etc), otherwise it will 255system drivers, no special hardware attached, etc), otherwise it will
239return non-zero to indicate that the ENGINE is now operational and will 256return non-zero to indicate that the ENGINE is now operational and will
240have allocated a new B<functional> reference to the ENGINE. In this case, 257have allocated a new B<functional> reference to the ENGINE. All functional
241the supplied ENGINE pointer is, from the point of the view of the caller, 258references are released by calling ENGINE_finish() (which removes the
242both a structural reference and a functional reference - so if the caller 259implicit structural reference as well).
243intends to use it as a functional reference it should free the structural
244reference with ENGINE_free() first. If the caller wishes to use it only as
245a structural reference (eg. if the ENGINE_init() call was simply to test if
246the ENGINE seems available/online), then it should free the functional
247reference; all functional references are released by the ENGINE_finish()
248function.
249 260
250The second way to get a functional reference is by asking OpenSSL for a 261The second way to get a functional reference is by asking OpenSSL for a
251default implementation for a given task, eg. by ENGINE_get_default_RSA(), 262default 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.
259For each supported abstraction, the ENGINE code maintains an internal table 270For each supported abstraction, the ENGINE code maintains an internal table
260of state to control which implementations are available for a given 271of state to control which implementations are available for a given
261abstraction and which should be used by default. These implementations are 272abstraction and which should be used by default. These implementations are
262registered in the tables separated-out by an 'nid' index, because 273registered in the tables and indexed by an 'nid' value, because
263abstractions like EVP_CIPHER and EVP_DIGEST support many distinct 274abstractions like EVP_CIPHER and EVP_DIGEST support many distinct
264algorithms and modes - ENGINEs will support different numbers and 275algorithms and modes, and ENGINEs can support arbitrarily many of them.
265combinations of these. In the case of other abstractions like RSA, DSA, 276In the case of other abstractions like RSA, DSA, etc, there is only one
266etc, there is only one "algorithm" so all implementations implicitly 277"algorithm" so all implementations implicitly register using the same 'nid'
267register using the same 'nid' index. ENGINEs can be B<registered> into 278index.
268these tables to make themselves available for use automatically by the 279
269various abstractions, eg. RSA. For illustrative purposes, we continue with 280When a default ENGINE is requested for a given abstraction/algorithm/mode, (eg.
270the RSA example, though all comments apply similarly to the other 281when calling RSA_new_method(NULL)), a "get_default" call will be made to the
271abstractions (they each get their own table and linkage to the 282ENGINE subsystem to process the corresponding state table and return a
272corresponding section of openssl code). 283functional reference to an initialised ENGINE whose implementation should be
273 284used. If no ENGINE should (or can) be used, it will return NULL and the caller
274When a new RSA key is being created, ie. in RSA_new_method(), a 285will 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 286conventional software implementation. In the latter case, OpenSSL will from
276state table and return a functional reference to an initialised ENGINE 287then on behave the way it used to before the ENGINE API existed.
277whose RSA_METHOD should be used. If no ENGINE should (or can) be used, it
278will return NULL and the RSA key will operate with a NULL ENGINE handle by
279using the conventional RSA implementation in OpenSSL (and will from then on
280behave the way it used to before the ENGINE API existed - for details see
281L<RSA_new_method(3)|RSA_new_method(3)>).
282 288
283Each state table has a flag to note whether it has processed this 289Each 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.
296ENGINE_set_default_RSA() does the same job as ENGINE_register_RSA() except 302ENGINE_set_default_RSA() does the same job as ENGINE_register_RSA() except
297that it also sets the state table's cached response for the "get_default" 303that it also sets the state table's cached response for the "get_default"
298query. 304query. In the case of abstractions like EVP_CIPHER, where implementations are
299 305indexed by 'nid', these flags and cached-responses are distinct for each 'nid'
300In the case of abstractions like EVP_CIPHER, where implementations are 306value.
301indexed by 'nid', these flags and cached-responses are distinct for each
302'nid' value.
303
304It is worth illustrating the difference between "registration" of ENGINEs
305into these per-algorithm state tables and using the alternative
306"set_default" functions. The latter handles both "registration" and also
307setting the cached "default" ENGINE in each relevant state table - so
308registered ENGINEs will only have a chance to be initialised for use as a
309default if a default ENGINE wasn't already set for the same state table.
310Eg. if ENGINE X supports cipher nids {A,B} and RSA, ENGINE Y supports
311ciphers {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
321The 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
361If no ENGINE API functions are called at all in an application, then there 340If no ENGINE API functions are called at all in an application, then there
362are no inherent memory leaks to worry about from the ENGINE functionality, 341are no inherent memory leaks to worry about from the ENGINE functionality,
363however if any ENGINEs are "load"ed, even if they are never registered or 342however if any ENGINEs are loaded, even if they are never registered or
364used, it is necessary to use the ENGINE_cleanup() function to 343used, it is necessary to use the ENGINE_cleanup() function to
365correspondingly cleanup before program exit, if the caller wishes to avoid 344correspondingly cleanup before program exit, if the caller wishes to avoid
366memory leaks. This mechanism uses an internal callback registration table 345memory leaks. This mechanism uses an internal callback registration table
@@ -375,7 +354,7 @@ linker.
375The fact that ENGINEs are made visible to OpenSSL (and thus are linked into 354The fact that ENGINEs are made visible to OpenSSL (and thus are linked into
376the program and loaded into memory at run-time) does not mean they are 355the 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
378is something for the application to have control over. Some applications 357is something for the application to control. Some applications
379will want to allow the user to specify exactly which ENGINE they want used 358will want to allow the user to specify exactly which ENGINE they want used
380if any is to be used at all. Others may prefer to load all support and have 359if any is to be used at all. Others may prefer to load all support and have
381OpenSSL automatically use at run-time any ENGINE that is able to 360OpenSSL 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;
433That's all that's required. Eg. the next time OpenSSL tries to set up an 412That's all that's required. Eg. the next time OpenSSL tries to set up an
434RSA key, any bundled ENGINEs that implement RSA_METHOD will be passed to 413RSA key, any bundled ENGINEs that implement RSA_METHOD will be passed to
435ENGINE_init() and if any of those succeed, that ENGINE will be set as the 414ENGINE_init() and if any of those succeed, that ENGINE will be set as the
436default for use with RSA from then on. 415default 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
441ENGINE implementation to define an arbitrary set of configuration 420ENGINE 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
443OpenSSL. This mechanism is entirely based on the use of name-value pairs 422OpenSSL. This mechanism is entirely based on the use of name-value pairs
444and and assumes ASCII input (no unicode or UTF for now!), so it is ideal if 423and assumes ASCII input (no unicode or UTF for now!), so it is ideal if
445applications want to provide a transparent way for users to provide 424applications want to provide a transparent way for users to provide
446arbitrary configuration "directives" directly to such ENGINEs. It is also 425arbitrary configuration "directives" directly to such ENGINEs. It is also
447possible for the application to dynamically interrogate the loaded ENGINE 426possible for the application to dynamically interrogate the loaded ENGINE
@@ -450,8 +429,8 @@ available "control commands", providing a more flexible configuration
450scheme. However, if the user is expected to know which ENGINE device he/she 429scheme. However, if the user is expected to know which ENGINE device he/she
451is using (in the case of specialised hardware, this goes without saying) 430is using (in the case of specialised hardware, this goes without saying)
452then applications may not need to concern themselves with discovering the 431then applications may not need to concern themselves with discovering the
453supported control commands and simply prefer to allow settings to passed 432supported control commands and simply prefer to pass settings into ENGINEs
454into ENGINEs exactly as they are provided by the user. 433exactly as they are provided by the user.
455 434
456Before illustrating how control commands work, it is worth mentioning what 435Before illustrating how control commands work, it is worth mentioning what
457they are typically used for. Broadly speaking there are two uses for 436they 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
459implementation (which may know nothing at all specific to the host system) 438implementation (which may know nothing at all specific to the host system)
460so that it can be initialised for use. This could include the path to any 439so that it can be initialised for use. This could include the path to any
461driver or config files it needs to load, required network addresses, 440driver or config files it needs to load, required network addresses,
462smart-card identifiers, passwords to initialise password-protected devices, 441smart-card identifiers, passwords to initialise protected devices,
463logging information, etc etc. This class of commands typically needs to be 442logging information, etc etc. This class of commands typically needs to be
464passed to an ENGINE B<before> attempting to initialise it, ie. before 443passed to an ENGINE B<before> attempting to initialise it, ie. before
465calling ENGINE_init(). The other class of commands consist of settings or 444calling ENGINE_init(). The other class of commands consist of settings or
466operations that tweak certain behaviour or cause certain operations to take 445operations that tweak certain behaviour or cause certain operations to take
467place, and these commands may work either before or after ENGINE_init(), or 446place, and these commands may work either before or after ENGINE_init(), or
468in same cases both. ENGINE implementations should provide indications of 447in some cases both. ENGINE implementations should provide indications of
469this in the descriptions attached to builtin control commands and/or in 448this in the descriptions attached to builtin control commands and/or in
470external product documentation. 449external product documentation.
471 450
@@ -529,14 +508,14 @@ FALSE.
529I<Discovering supported control commands> 508I<Discovering supported control commands>
530 509
531It is possible to discover at run-time the names, numerical-ids, descriptions 510It is possible to discover at run-time the names, numerical-ids, descriptions
532and input parameters of the control commands supported from a structural 511and input parameters of the control commands supported by an ENGINE using a
533reference to any ENGINE. It is first important to note that some control 512structural reference. Note that some control commands are defined by OpenSSL
534commands are defined by OpenSSL itself and it will intercept and handle these 513itself and it will intercept and handle these control commands on behalf of the
535control commands on behalf of the ENGINE, ie. the ENGINE's ctrl() handler is not 514ENGINE, ie. the ENGINE's ctrl() handler is not used for the control command.
536used for the control command. openssl/engine.h defines a symbol, 515openssl/engine.h defines an index, ENGINE_CMD_BASE, that all control commands
537ENGINE_CMD_BASE, that all control commands implemented by ENGINEs from. Any 516implemented by ENGINEs should be numbered from. Any command value lower than
538command value lower than this symbol is considered a "generic" command is 517this symbol is considered a "generic" command is handled directly by the
539handled directly by the OpenSSL core routines. 518OpenSSL core routines.
540 519
541It is using these "core" control commands that one can discover the the control 520It is using these "core" control commands that one can discover the the control
542commands implemented by a given ENGINE, specifically the commands; 521commands 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
554Whilst these commands are automatically processed by the OpenSSL framework code, 533Whilst these commands are automatically processed by the OpenSSL framework code,
555they use various properties exposed by each ENGINE by which to process these 534they use various properties exposed by each ENGINE to process these
556queries. An ENGINE has 3 properties it exposes that can affect this behaviour; 535queries. An ENGINE has 3 properties it exposes that can affect how this behaves;
557it can supply a ctrl() handler, it can specify ENGINE_FLAGS_MANUAL_CMD_CTRL in 536it can supply a ctrl() handler, it can specify ENGINE_FLAGS_MANUAL_CMD_CTRL in
558the ENGINE's flags, and it can expose an array of control command descriptions. 537the ENGINE's flags, and it can expose an array of control command descriptions.
559If an ENGINE specifies the ENGINE_FLAGS_MANUAL_CMD_CTRL flag, then it will 538If an ENGINE specifies the ENGINE_FLAGS_MANUAL_CMD_CTRL flag, then it will
@@ -608,14 +587,13 @@ extension).
608The ENGINE API and internal architecture is currently being reviewed. Slated for 587The ENGINE API and internal architecture is currently being reviewed. Slated for
609possible release in 0.9.8 is support for transparent loading of "dynamic" 588possible release in 0.9.8 is support for transparent loading of "dynamic"
610ENGINEs (built as self-contained shared-libraries). This would allow ENGINE 589ENGINEs (built as self-contained shared-libraries). This would allow ENGINE
611implementations to be provided independantly of OpenSSL libraries and/or 590implementations to be provided independently of OpenSSL libraries and/or
612OpenSSL-based applications, and would also remove any requirement for 591OpenSSL-based applications, and would also remove any requirement for
613applications to explicitly use the "dynamic" ENGINE to bind to shared-library 592applications to explicitly use the "dynamic" ENGINE to bind to shared-library
614implementations. 593implementations.
615 594
616=head1 SEE ALSO 595=head1 SEE ALSO
617 596
618L<rsa(3)|rsa(3)>, L<dsa(3)|dsa(3)>, L<dh(3)|dh(3)>, L<rand(3)|rand(3)>, 597L<rsa(3)|rsa(3)>, L<dsa(3)|dsa(3)>, L<dh(3)|dh(3)>, L<rand(3)|rand(3)>
619L<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
5x509 - X.509 certificate handling
6
7=head1 SYNOPSIS
8
9 #include <openssl/x509.h>
10
11=head1 DESCRIPTION
12
13A X.509 certificate is a structured grouping of information about
14an individual, a device, or anything one can imagine. A X.509 CRL
15(certificate revocation list) is a tool to help determine if a
16certificate is still valid. The exact definition of those can be
17found in the X.509 document from ITU-T, or in RFC3280 from PKIX.
18In OpenSSL, the type X509 is used to express such a certificate, and
19the type X509_CRL is used to express a CRL.
20
21A related structure is a certificate request, defined in PKCS#10 from
22RSA Security, Inc, also reflected in RFC2896. In OpenSSL, the type
23X509_REQ is used to express such a certificate request.
24
25To handle some complex parts of a certificate, there are the types
26X509_NAME (to express a certificate name), X509_ATTRIBUTE (to express
27a certificate attributes), X509_EXTENSION (to express a certificate
28extension) and a few more.
29
30Finally, there's the supertype X509_INFO, which can contain a CRL, a
31certificate and a corresponding private key.
32
33B<X509_>I<...>, B<d2i_X509_>I<...> and B<i2d_X509_>I<...> handle X.509
34certificates, with some exceptions, shown below.
35
36B<X509_CRL_>I<...>, B<d2i_X509_CRL_>I<...> and B<i2d_X509_CRL_>I<...>
37handle X.509 CRLs.
38
39B<X509_REQ_>I<...>, B<d2i_X509_REQ_>I<...> and B<i2d_X509_REQ_>I<...>
40handle PKCS#10 certificate requests.
41
42B<X509_NAME_>I<...> handle certificate names.
43
44B<X509_ATTRIBUTE_>I<...> handle certificate attributes.
45
46B<X509_EXTENSION_>I<...> handle certificate extensions.
47
48=head1 SEE ALSO
49
50L<X509_NAME_ENTRY_get_object(3)|X509_NAME_ENTRY_get_object(3)>,
51L<X509_NAME_add_entry_by_txt(3)|X509_NAME_add_entry_by_txt(3)>,
52L<X509_NAME_add_entry_by_NID(3)|X509_NAME_add_entry_by_NID(3)>,
53L<X509_NAME_print_ex(3)|X509_NAME_print_ex(3)>,
54L<X509_NAME_new(3)|X509_NAME_new(3)>,
55L<d2i_X509(3)|d2i_X509(3)>,
56L<d2i_X509_ALGOR(3)|d2i_X509_ALGOR(3)>,
57L<d2i_X509_CRL(3)|d2i_X509_CRL(3)>,
58L<d2i_X509_NAME(3)|d2i_X509_NAME(3)>,
59L<d2i_X509_REQ(3)|d2i_X509_REQ(3)>,
60L<d2i_X509_SIG(3)|d2i_X509_SIG(3)>,
61L<crypto(3)|crypto(3)>,
62L<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
72static 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
86DSA *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 */
82static 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 */
113static 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 */
150static 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 */
215static 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 */
314int 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
372int ec_GF2m_precompute_mult(EC_GROUP *group, BN_CTX *ctx)
373 {
374 return ec_wNAF_precompute_mult(group, ctx);
375 }
376
377int 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
75const 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 */
127int 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 */
139void 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 */
150void 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 */
166int 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. */
186int 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 */
219int 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. */
246int 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 */
255int 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
283err:
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. */
293int 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. */
303void 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. */
312void 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. */
322int 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 */
336int 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 */
347int 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 */
374int 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 */
420size_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 */
562int 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 */
677int 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 */
779int 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
785int 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. */
797int 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 */
807int 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 */
862int 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. */
904int 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. */
940int 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. */
954int 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. */
961int 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. */
968int 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
66int 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
87int 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
105int 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 */
131typedef struct x9_62_pentanomial_st {
132 long k1;
133 long k2;
134 long k3;
135 } X9_62_PENTANOMIAL;
136
137typedef 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
153typedef 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
166typedef 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
172typedef 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
181struct 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 */
191typedef 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 */
199ASN1_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
205DECLARE_ASN1_ALLOC_FUNCTIONS(X9_62_PENTANOMIAL)
206IMPLEMENT_ASN1_ALLOC_FUNCTIONS(X9_62_PENTANOMIAL)
207
208ASN1_ADB_TEMPLATE(char_two_def) = ASN1_SIMPLE(X9_62_CHARACTERISTIC_TWO, p.other, ASN1_ANY);
209
210ASN1_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
216ASN1_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
222DECLARE_ASN1_ALLOC_FUNCTIONS(X9_62_CHARACTERISTIC_TWO)
223IMPLEMENT_ASN1_ALLOC_FUNCTIONS(X9_62_CHARACTERISTIC_TWO)
224
225ASN1_ADB_TEMPLATE(fieldID_def) = ASN1_SIMPLE(X9_62_FIELDID, p.other, ASN1_ANY);
226
227ASN1_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
232ASN1_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
237ASN1_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
243ASN1_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
252DECLARE_ASN1_ALLOC_FUNCTIONS(ECPARAMETERS)
253IMPLEMENT_ASN1_ALLOC_FUNCTIONS(ECPARAMETERS)
254
255ASN1_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
261DECLARE_ASN1_FUNCTIONS_const(ECPKPARAMETERS)
262DECLARE_ASN1_ENCODE_FUNCTIONS_const(ECPKPARAMETERS, ECPKPARAMETERS)
263IMPLEMENT_ASN1_FUNCTIONS_const(ECPKPARAMETERS)
264
265ASN1_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
272DECLARE_ASN1_FUNCTIONS_const(EC_PRIVATEKEY)
273DECLARE_ASN1_ENCODE_FUNCTIONS_const(EC_PRIVATEKEY, EC_PRIVATEKEY)
274IMPLEMENT_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 */
279static int ec_asn1_group2fieldid(const EC_GROUP *, X9_62_FIELDID *);
280/* ec_asn1_group2curve() sets the values in a X9_62_CURVE object */
281static int ec_asn1_group2curve(const EC_GROUP *, X9_62_CURVE *);
282/* ec_asn1_parameters2group() creates a EC_GROUP object from a
283 * ECPARAMETERS object */
284static EC_GROUP *ec_asn1_parameters2group(const ECPARAMETERS *);
285/* ec_asn1_group2parameters() creates a ECPARAMETERS object from a
286 * EC_GROUP object */
287static ECPARAMETERS *ec_asn1_group2parameters(const EC_GROUP *,ECPARAMETERS *);
288/* ec_asn1_pkparameters2group() creates a EC_GROUP object from a
289 * ECPKPARAMETERS object */
290static EC_GROUP *ec_asn1_pkparameters2group(const ECPKPARAMETERS *);
291/* ec_asn1_group2pkparameters() creates a ECPKPARAMETERS object from a
292 * EC_GROUP object */
293static ECPKPARAMETERS *ec_asn1_group2pkparameters(const EC_GROUP *,
294 ECPKPARAMETERS *);
295
296
297/* the function definitions */
298
299static 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
425err : if (tmp)
426 BN_free(tmp);
427 return(ok);
428}
429
430static 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
552err: 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
563static 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
671err : 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
684ECPKPARAMETERS *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
740static 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
986err: 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
1004EC_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
1053EC_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
1081int 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
1102EC_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;
1196err:
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
1210int 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;
1312err:
1313 if (buffer)
1314 OPENSSL_free(buffer);
1315 if (priv_key)
1316 EC_PRIVATEKEY_free(priv_key);
1317 return(ok?ret:0);
1318 }
1319
1320int 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
1330EC_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
1362EC_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
1391int 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
59int 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
115err:
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
76typedef 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 */
93static 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};
96static 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
108static 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};
111static 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
123static 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};
126static 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
144static 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};
147static 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) */
165static 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};
168static 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
180static 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};
183static 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
195static 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};
198static 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
210static 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};
213static 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
225static 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};
228static 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
240static 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};
243static 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) */
255static 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};
258static 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
270static 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};
273static 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
285static 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};
288static 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
300static 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};
303static 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
315static 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
327static 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};
330static 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
342static 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};
345static 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
357static 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
369static 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
381static 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 */
394static 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
406static 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
418static 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 */
431static 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};
434static 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
446static 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};
449static 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
461static 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};
464static 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
476static 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};
479static 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
491static 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
503static 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};
506static 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
526static 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};
529static 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
548static 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};
551static 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
563static 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};
566static 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
578static 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
590static 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};
593static 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
605static 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
617static 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
633static 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};
636static 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
654static 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
670static 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};
673static 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
691static 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
711static 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};
714static 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
738static 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};
741static 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
753static 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};
756static 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
768static 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};
771static 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
783static 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
795static 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};
798static 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
810static 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};
813static 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
825static 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};
828static 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
840static 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
852static 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};
855static 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
867static 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};
870static 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
882static 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};
885static 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
897static 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
911static 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
929static 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};
932static 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
950static 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
968static 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
986static 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 */
1004static 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 */
1022static 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
1035typedef struct _ec_list_element_st {
1036 int nid;
1037 const EC_CURVE_DATA *data;
1038 } ec_list_element;
1039
1040static 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
1121static size_t curve_list_length = sizeof(curve_list)/sizeof(ec_list_element);
1122
1123static 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;
1203err:
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
1228EC_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
1254size_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
69EC_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
91EC_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
105void 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
138EC_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
204EC_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
217int 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
233int 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
283err:
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
295int 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;
366err:
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
376const EC_GROUP *EC_KEY_get0_group(const EC_KEY *key)
377 {
378 return key->group;
379 }
380
381int 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
389const BIGNUM *EC_KEY_get0_private_key(const EC_KEY *key)
390 {
391 return key->priv_key;
392 }
393
394int 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
402const EC_POINT *EC_KEY_get0_public_key(const EC_KEY *key)
403 {
404 return key->pub_key;
405 }
406
407int 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
415unsigned int EC_KEY_get_enc_flags(const EC_KEY *key)
416 {
417 return key->enc_flag;
418 }
419
420void EC_KEY_set_enc_flags(EC_KEY *key, unsigned int flags)
421 {
422 key->enc_flag = flags;
423 }
424
425point_conversion_form_t EC_KEY_get_conv_form(const EC_KEY *key)
426 {
427 return key->conv_form;
428 }
429
430void 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
437void *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
443void 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
454void 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
460int 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
59BIGNUM *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
89EC_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
132static const char *HEX_DIGITS = "0123456789ABCDEF";
133
134/* the return value must be freed (using OPENSSL_free()) */
135char *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
179EC_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
85extern "C" {
86#endif
87
88const ECDH_METHOD *ECDH_OpenSSL(void);
89
90void ECDH_set_default_method(const ECDH_METHOD *);
91const ECDH_METHOD *ECDH_get_default_method(void);
92int ECDH_set_method(EC_KEY *, const ECDH_METHOD *);
93
94int 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
97int 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);
99int ECDH_set_ex_data(EC_KEY *d, int idx, void *arg);
100void *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 */
107void 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
71static 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
78static 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
88void 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
75int 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
77const char ECDH_version[]="ECDH" OPENSSL_VERSION_PTEXT;
78
79static const ECDH_METHOD *default_ECDH_method = NULL;
80
81static void *ecdh_data_new(void);
82static void *ecdh_data_dup(void *);
83static void ecdh_data_free(void *);
84
85void ECDH_set_default_method(const ECDH_METHOD *meth)
86 {
87 default_ECDH_method = meth;
88 }
89
90const 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
97int 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
127static 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
171static void *ecdh_data_new(void)
172 {
173 return (void *)ECDH_DATA_new_method(NULL);
174 }
175
176static 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
187void 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
203ECDH_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
224int 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
231int 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
240void *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
62extern "C" {
63#endif
64
65struct 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
78typedef 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
88ECDH_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
75extern "C" {
76#endif
77
78typedef 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 */
88ECDSA_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 */
94void 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 */
103int 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 */
113ECDSA_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 */
123ECDSA_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 */
136ECDSA_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 */
148int ECDSA_do_verify(const unsigned char *dgst, int dgst_len,
149 const ECDSA_SIG *sig, EC_KEY* eckey);
150
151const 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 */
157void 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 */
163const 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 */
171int 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 */
178int 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 */
188int 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 */
202int 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 */
220int 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 */
235int 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 */
239int 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);
241int ECDSA_set_ex_data(EC_KEY *d, int idx, void *arg);
242void *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 */
249void 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
60ASN1_SEQUENCE(ECDSA_SIG) = {
61 ASN1_SIMPLE(ECDSA_SIG, r, CBIGNUM),
62 ASN1_SIMPLE(ECDSA_SIG, s, CBIGNUM)
63} ASN1_SEQUENCE_END(ECDSA_SIG)
64
65DECLARE_ASN1_FUNCTIONS_const(ECDSA_SIG)
66DECLARE_ASN1_ENCODE_FUNCTIONS_const(ECDSA_SIG, ECDSA_SIG)
67IMPLEMENT_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
71static 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
80static 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
94void 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
64const char ECDSA_version[]="ECDSA" OPENSSL_VERSION_PTEXT;
65
66static const ECDSA_METHOD *default_ECDSA_method = NULL;
67
68static void *ecdsa_data_new(void);
69static void *ecdsa_data_dup(void *);
70static void ecdsa_data_free(void *);
71
72void ECDSA_set_default_method(const ECDSA_METHOD *meth)
73{
74 default_ECDSA_method = meth;
75}
76
77const 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
84int 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
107static 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
151static void *ecdsa_data_new(void)
152{
153 return (void *)ECDSA_DATA_new_method(NULL);
154}
155
156static 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
167static 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
182ECDSA_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
203int 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
238int 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
245int 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
254void *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
65extern "C" {
66#endif
67
68struct 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
85typedef 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 */
101ECDSA_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
64static ECDSA_SIG *ecdsa_do_sign(const unsigned char *dgst, int dlen,
65 const BIGNUM *, const BIGNUM *, EC_KEY *eckey);
66static int ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp,
67 BIGNUM **rp);
68static int ecdsa_do_verify(const unsigned char *dgst, int dgst_len,
69 const ECDSA_SIG *sig, EC_KEY *eckey);
70
71static 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
84const ECDSA_METHOD *ECDSA_OpenSSL(void)
85{
86 return &openssl_ecdsa_meth;
87}
88
89static 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;
194err:
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
212static 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;
327err:
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
346static 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);
472err:
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
61ECDSA_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
66ECDSA_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
75int 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
81int 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
97int 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 */
69int 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 */
83int 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);
93err:
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
107static ENGINE *ENGINE_padlock (void);
108# endif
109#endif
110
111void 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 */
137static int padlock_available(void);
138static int padlock_init(ENGINE *e);
139
140/* RNG Stuff */
141static RAND_METHOD padlock_rand;
142
143/* Cipher Stuff */
144#ifndef OPENSSL_NO_AES
145static int padlock_ciphers(ENGINE *e, const EVP_CIPHER **cipher, const int **nids, int nid);
146#endif
147
148/* Engine names */
149static const char *padlock_id = "padlock";
150static char padlock_name[100];
151
152/* Available features */
153static int padlock_use_ace = 0; /* Advanced Cryptography Engine */
154static int padlock_use_rng = 0; /* Random Number Generator */
155#ifndef OPENSSL_NO_AES
156static int padlock_aes_align_required = 1;
157#endif
158
159/* ===== Engine "management" functions ===== */
160
161/* Prepare the ENGINE structure for registration */
162static int
163padlock_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 */
195static ENGINE *
196ENGINE_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 */
213static int
214padlock_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
223static int
224padlock_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
237IMPLEMENT_DYNAMIC_CHECK_FN ();
238IMPLEMENT_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 */
257struct 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 */
281static 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 */
304static int
305padlock_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. */
331static int
332padlock_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() */
376static inline void
377padlock_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. */
392static inline void
393padlock_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 */
408static inline void
409padlock_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) \
432static 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 */
448PADLOCK_XCRYPT_ASM(padlock_xcrypt_ecb, ".byte 0xf3,0x0f,0xa7,0xc8") /* rep xcryptecb */
449PADLOCK_XCRYPT_ASM(padlock_xcrypt_cbc, ".byte 0xf3,0x0f,0xa7,0xd0") /* rep xcryptcbc */
450PADLOCK_XCRYPT_ASM(padlock_xcrypt_cfb, ".byte 0xf3,0x0f,0xa7,0xe0") /* rep xcryptcfb */
451PADLOCK_XCRYPT_ASM(padlock_xcrypt_ofb, ".byte 0xf3,0x0f,0xa7,0xe8") /* rep xcryptofb */
452#endif
453
454/* The RNG call itself */
455static inline unsigned int
456padlock_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 */
479static inline unsigned char *
480padlock_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) \
510static 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
521PADLOCK_XCRYPT_ASM(padlock_xcrypt_ecb,0xc8)
522PADLOCK_XCRYPT_ASM(padlock_xcrypt_cbc,0xd0)
523PADLOCK_XCRYPT_ASM(padlock_xcrypt_cfb,0xe0)
524PADLOCK_XCRYPT_ASM(padlock_xcrypt_ofb,0xe8)
525
526static int __fastcall
527padlock_xstore(void *outp,unsigned int code)
528{ _asm mov edi,ecx
529 _asm _emit 0x0f _asm _emit 0xa7 _asm _emit 0xc0
530}
531
532static void __fastcall
533padlock_reload_key(void)
534{ _asm pushfd _asm popfd }
535
536static void __fastcall
537padlock_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
551static int
552padlock_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
600static void __fastcall
601padlock_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. */
650static 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};
666static int padlock_cipher_nids_num = (sizeof(padlock_cipher_nids)/
667 sizeof(padlock_cipher_nids[0]));
668
669/* Function prototypes ... */
670static int padlock_aes_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
671 const unsigned char *iv, int enc);
672static 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) \
688static 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
704DECLARE_AES_EVP(128,ecb,ECB);
705DECLARE_AES_EVP(128,cbc,CBC);
706DECLARE_AES_EVP(128,cfb,CFB);
707DECLARE_AES_EVP(128,ofb,OFB);
708
709DECLARE_AES_EVP(192,ecb,ECB);
710DECLARE_AES_EVP(192,cbc,CBC);
711DECLARE_AES_EVP(192,cfb,CFB);
712DECLARE_AES_EVP(192,ofb,OFB);
713
714DECLARE_AES_EVP(256,ecb,ECB);
715DECLARE_AES_EVP(256,cbc,CBC);
716DECLARE_AES_EVP(256,cfb,CFB);
717DECLARE_AES_EVP(256,ofb,OFB);
718
719static int
720padlock_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 */
779static int
780padlock_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 */
849static int
850padlock_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. */
900static int
901padlock_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 */
1169static int
1170padlock_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 */
1200static int
1201padlock_rand_status(void)
1202{
1203 return 1;
1204}
1205
1206/* Prepare structure for registration */
1207static 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
77static ENGINE_TABLE *ecdh_table = NULL;
78static const int dummy_nid = 1;
79
80void ENGINE_unregister_ECDH(ENGINE *e)
81 {
82 engine_table_unregister(&ecdh_table, e);
83 }
84
85static void engine_unregister_all_ECDH(void)
86 {
87 engine_table_cleanup(&ecdh_table);
88 }
89
90int 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
98void 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
106int 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). */
117ENGINE *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 */
123const 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 */
129int 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
62static ENGINE_TABLE *ecdsa_table = NULL;
63static const int dummy_nid = 1;
64
65void ENGINE_unregister_ECDSA(ENGINE *e)
66 {
67 engine_table_unregister(&ecdsa_table, e);
68 }
69
70static void engine_unregister_all_ECDSA(void)
71 {
72 engine_table_cleanup(&ecdsa_table);
73 }
74
75int 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
83void 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
91int 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). */
102ENGINE *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 */
108const 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 */
114int 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
62static ENGINE_TABLE *store_table = NULL;
63static const int dummy_nid = 1;
64
65void ENGINE_unregister_STORE(ENGINE *e)
66 {
67 engine_table_unregister(&store_table, e);
68 }
69
70static void engine_unregister_all_STORE(void)
71 {
72 engine_table_cleanup(&store_table);
73 }
74
75int 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
83void 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
93int 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). */
106ENGINE *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 */
113const 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 */
119int 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
65static int camellia_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
66 const unsigned char *iv, int enc);
67
68/* Camellia subkey Structure */
69typedef 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
77IMPLEMENT_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)
83IMPLEMENT_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)
89IMPLEMENT_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
98IMPLEMENT_CAMELLIA_CFBR(128,1)
99IMPLEMENT_CAMELLIA_CFBR(192,1)
100IMPLEMENT_CAMELLIA_CFBR(256,1)
101
102IMPLEMENT_CAMELLIA_CFBR(128,8)
103IMPLEMENT_CAMELLIA_CFBR(192,8)
104IMPLEMENT_CAMELLIA_CFBR(256,8)
105
106
107
108/* The subkey for Camellia is generated. */
109static 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
128static 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
60static 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
73const EVP_CIPHER *EVP_bf_cfb(void);
69const EVP_CIPHER *EVP_bf_cfb(void) { return EVP_bf_cfb64(); } 74const 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
79const EVP_CIPHER *EVP_des_cfb(void);
74const EVP_CIPHER *EVP_des_cfb(void) { return EVP_des_cfb64(); } 80const EVP_CIPHER *EVP_des_cfb(void) { return EVP_des_cfb64(); }
75#undef EVP_des_ede3_cfb 81#undef EVP_des_ede3_cfb
82const EVP_CIPHER *EVP_des_ede3_cfb(void);
76const EVP_CIPHER *EVP_des_ede3_cfb(void) { return EVP_des_ede3_cfb64(); } 83const EVP_CIPHER *EVP_des_ede3_cfb(void) { return EVP_des_ede3_cfb64(); }
77#undef EVP_des_ede_cfb 84#undef EVP_des_ede_cfb
85const EVP_CIPHER *EVP_des_ede_cfb(void);
78const EVP_CIPHER *EVP_des_ede_cfb(void) { return EVP_des_ede_cfb64(); } 86const 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
91const EVP_CIPHER *EVP_idea_cfb(void);
83const EVP_CIPHER *EVP_idea_cfb(void) { return EVP_idea_cfb64(); } 92const 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
97const EVP_CIPHER *EVP_rc2_cfb(void);
88const EVP_CIPHER *EVP_rc2_cfb(void) { return EVP_rc2_cfb64(); } 98const 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
103const EVP_CIPHER *EVP_cast5_cfb(void);
93const EVP_CIPHER *EVP_cast5_cfb(void) { return EVP_cast5_cfb64(); } 104const 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
109const EVP_CIPHER *EVP_rc5_32_12_16_cfb(void);
98const EVP_CIPHER *EVP_rc5_32_12_16_cfb(void) { return EVP_rc5_32_12_16_cfb64(); } 110const 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
115const EVP_CIPHER *EVP_aes_128_cfb(void);
103const EVP_CIPHER *EVP_aes_128_cfb(void) { return EVP_aes_128_cfb128(); } 116const EVP_CIPHER *EVP_aes_128_cfb(void) { return EVP_aes_128_cfb128(); }
104#undef EVP_aes_192_cfb 117#undef EVP_aes_192_cfb
118const EVP_CIPHER *EVP_aes_192_cfb(void);
105const EVP_CIPHER *EVP_aes_192_cfb(void) { return EVP_aes_192_cfb128(); } 119const EVP_CIPHER *EVP_aes_192_cfb(void) { return EVP_aes_192_cfb128(); }
106#undef EVP_aes_256_cfb 120#undef EVP_aes_256_cfb
121const EVP_CIPHER *EVP_aes_256_cfb(void);
107const EVP_CIPHER *EVP_aes_256_cfb(void) { return EVP_aes_256_cfb128(); } 122const 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
119static int init(EVP_MD_CTX *ctx)
120 { return SHA1_Init(ctx->md_data); }
121
122static int update(EVP_MD_CTX *ctx,const void *data,size_t count)
123 { return SHA1_Update(ctx->md_data,data,count); }
124
125static int final(EVP_MD_CTX *ctx,unsigned char *md)
126 { return SHA1_Final(md,ctx->md_data); }
127
128static 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
144const 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#
6OPENSSL_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
14OPENSSL_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
43OPENSSL_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
10use strict;
11
12my $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)
19sub 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 */
34EOF
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)
42sub 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 */
57EOF
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)
65sub 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 */
79EOF
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)
87sub 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 */
104EOF
105}
106
107my $output = shift;
108open 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
116md5_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
148EOF
149round1_step(-1,'%eax','%ebx','%ecx','%edx', '1','0xd76aa478', '7');
150round1_step( 0,'%edx','%eax','%ebx','%ecx', '2','0xe8c7b756','12');
151round1_step( 0,'%ecx','%edx','%eax','%ebx', '3','0x242070db','17');
152round1_step( 0,'%ebx','%ecx','%edx','%eax', '4','0xc1bdceee','22');
153round1_step( 0,'%eax','%ebx','%ecx','%edx', '5','0xf57c0faf', '7');
154round1_step( 0,'%edx','%eax','%ebx','%ecx', '6','0x4787c62a','12');
155round1_step( 0,'%ecx','%edx','%eax','%ebx', '7','0xa8304613','17');
156round1_step( 0,'%ebx','%ecx','%edx','%eax', '8','0xfd469501','22');
157round1_step( 0,'%eax','%ebx','%ecx','%edx', '9','0x698098d8', '7');
158round1_step( 0,'%edx','%eax','%ebx','%ecx','10','0x8b44f7af','12');
159round1_step( 0,'%ecx','%edx','%eax','%ebx','11','0xffff5bb1','17');
160round1_step( 0,'%ebx','%ecx','%edx','%eax','12','0x895cd7be','22');
161round1_step( 0,'%eax','%ebx','%ecx','%edx','13','0x6b901122', '7');
162round1_step( 0,'%edx','%eax','%ebx','%ecx','14','0xfd987193','12');
163round1_step( 0,'%ecx','%edx','%eax','%ebx','15','0xa679438e','17');
164round1_step( 1,'%ebx','%ecx','%edx','%eax', '0','0x49b40821','22');
165
166round2_step(-1,'%eax','%ebx','%ecx','%edx', '6','0xf61e2562', '5');
167round2_step( 0,'%edx','%eax','%ebx','%ecx','11','0xc040b340', '9');
168round2_step( 0,'%ecx','%edx','%eax','%ebx', '0','0x265e5a51','14');
169round2_step( 0,'%ebx','%ecx','%edx','%eax', '5','0xe9b6c7aa','20');
170round2_step( 0,'%eax','%ebx','%ecx','%edx','10','0xd62f105d', '5');
171round2_step( 0,'%edx','%eax','%ebx','%ecx','15', '0x2441453', '9');
172round2_step( 0,'%ecx','%edx','%eax','%ebx', '4','0xd8a1e681','14');
173round2_step( 0,'%ebx','%ecx','%edx','%eax', '9','0xe7d3fbc8','20');
174round2_step( 0,'%eax','%ebx','%ecx','%edx','14','0x21e1cde6', '5');
175round2_step( 0,'%edx','%eax','%ebx','%ecx', '3','0xc33707d6', '9');
176round2_step( 0,'%ecx','%edx','%eax','%ebx', '8','0xf4d50d87','14');
177round2_step( 0,'%ebx','%ecx','%edx','%eax','13','0x455a14ed','20');
178round2_step( 0,'%eax','%ebx','%ecx','%edx', '2','0xa9e3e905', '5');
179round2_step( 0,'%edx','%eax','%ebx','%ecx', '7','0xfcefa3f8', '9');
180round2_step( 0,'%ecx','%edx','%eax','%ebx','12','0x676f02d9','14');
181round2_step( 1,'%ebx','%ecx','%edx','%eax', '0','0x8d2a4c8a','20');
182
183round3_step(-1,'%eax','%ebx','%ecx','%edx', '8','0xfffa3942', '4');
184round3_step( 0,'%edx','%eax','%ebx','%ecx','11','0x8771f681','11');
185round3_step( 0,'%ecx','%edx','%eax','%ebx','14','0x6d9d6122','16');
186round3_step( 0,'%ebx','%ecx','%edx','%eax', '1','0xfde5380c','23');
187round3_step( 0,'%eax','%ebx','%ecx','%edx', '4','0xa4beea44', '4');
188round3_step( 0,'%edx','%eax','%ebx','%ecx', '7','0x4bdecfa9','11');
189round3_step( 0,'%ecx','%edx','%eax','%ebx','10','0xf6bb4b60','16');
190round3_step( 0,'%ebx','%ecx','%edx','%eax','13','0xbebfbc70','23');
191round3_step( 0,'%eax','%ebx','%ecx','%edx', '0','0x289b7ec6', '4');
192round3_step( 0,'%edx','%eax','%ebx','%ecx', '3','0xeaa127fa','11');
193round3_step( 0,'%ecx','%edx','%eax','%ebx', '6','0xd4ef3085','16');
194round3_step( 0,'%ebx','%ecx','%edx','%eax', '9', '0x4881d05','23');
195round3_step( 0,'%eax','%ebx','%ecx','%edx','12','0xd9d4d039', '4');
196round3_step( 0,'%edx','%eax','%ebx','%ecx','15','0xe6db99e5','11');
197round3_step( 0,'%ecx','%edx','%eax','%ebx', '2','0x1fa27cf8','16');
198round3_step( 1,'%ebx','%ecx','%edx','%eax', '0','0xc4ac5665','23');
199
200round4_step(-1,'%eax','%ebx','%ecx','%edx', '7','0xf4292244', '6');
201round4_step( 0,'%edx','%eax','%ebx','%ecx','14','0x432aff97','10');
202round4_step( 0,'%ecx','%edx','%eax','%ebx', '5','0xab9423a7','15');
203round4_step( 0,'%ebx','%ecx','%edx','%eax','12','0xfc93a039','21');
204round4_step( 0,'%eax','%ebx','%ecx','%edx', '3','0x655b59c3', '6');
205round4_step( 0,'%edx','%eax','%ebx','%ecx','10','0x8f0ccc92','10');
206round4_step( 0,'%ecx','%edx','%eax','%ebx', '1','0xffeff47d','15');
207round4_step( 0,'%ebx','%ecx','%edx','%eax', '8','0x85845dd1','21');
208round4_step( 0,'%eax','%ebx','%ecx','%edx','15','0x6fa87e4f', '6');
209round4_step( 0,'%edx','%eax','%ebx','%ecx', '6','0xfe2ce6e0','10');
210round4_step( 0,'%ecx','%edx','%eax','%ebx','13','0xa3014314','15');
211round4_step( 0,'%ebx','%ecx','%edx','%eax', '4','0x4e0811a1','21');
212round4_step( 0,'%eax','%ebx','%ecx','%edx','11','0xf7537e82', '6');
213round4_step( 0,'%edx','%eax','%ebx','%ecx', '2','0xbd3af235','10');
214round4_step( 0,'%ecx','%edx','%eax','%ebx', '9','0x2ad7d2bb','15');
215round4_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
241EOF
242
243print $code;
244
245close 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;
64void OPENSSL_cleanse(void *ptr, size_t len) 64void 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
63int OPENSSL_strncasecmp(const char *str1, const char *str2, size_t n) 67int 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
101int 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
59my $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
68my $masmref=8 + 50727*2**-32; # 8.00.50727 shipped with VS2005
69my $masm=$masmref if ($output =~ /\.asm/);
70if ($masm && `ml64 2>&1` =~ m/Version ([0-9]+)\.([0-9]+)(\.([0-9]+))?/)
71{ $masm=$1 + $2*2**-16 + $4*2**-32; }
72
73my $current_segment;
74my $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
432while($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
487print "\n$current_segment\tENDS\nEND\n" if ($masm);
488
489close 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
27open 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
66die "can't locate x86_64-xlate.pl";
67
68open 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
45RC4: or $len,$len 86RC4: 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___
106for ($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___
121push(@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
263RC4_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
338RC4_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
150print $code; 362print $code;
363
364close 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
67static void *dummy=&dummy;
68
69#else
70
71RSA *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 }
96err:
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
67const static unsigned char zeroes[] = {0,0,0,0,0,0,0,0}; 67static 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
69int RSA_verify_PKCS1_PSS(RSA *rsa, const unsigned char *mHash, 73int 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,
105int RSA_padding_check_X931(unsigned char *to, int tlen, 105int 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
56sub BODY_00_15 { 52sub BODY_00_15 {
57local *code=shift; 53local *code=shift;
58local ($i,$a,$b,$c,$d,$e,$f,$unaligned)=@_; 54local ($i,$a,$b,$c,$d,$e,$f)=@_;
59 55
60if ($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 }
73elsif ($i<15) {
74 $code.=<<___;
75{ .mmi; ld4 $X[($i+1)&0xf]=[inp],4 // prefetch
76___
77 }
78else {
79 $code.=<<___;
80{ .mmi; nop.m 0
81___ 62___
82 }
83if ($i<15) { 63if ($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 }
102else { 88else {
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;
245ctx=r32; // in0 231ctx=r32; // in0
246inp=r33; // in1 232inp=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
252sha1_block_asm_host_order: 238sha1_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 };;
263tmp4=in2;
264tmp5=loc13;
265tmp6=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
400sha1_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#
302stringz "SHA1 block transform for IA64, CRYPTOGAMS by <appro\@openssl.org>"
547___ 303___
548 304
549print $code; 305print $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
37die "can't locate x86_64-xlate.pl";
38
39open 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
62sub PROLOGUE {
63my $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
88sub EPILOGUE {
89my $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
100sub BODY_00_19 {
101my ($i,$a,$b,$c,$d,$e,$f,$host)=@_;
102my $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
143sub BODY_20_39 {
144my ($i,$a,$b,$c,$d,$e,$f)=@_;
145my $j=$i+1;
146my $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
179sub BODY_40_59 {
180my ($i,$a,$b,$c,$d,$e,$f)=@_;
181my $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";
208for($i=0;$i<20;$i++) { &BODY_00_19($i,@V); unshift(@V,pop(@V)); }
209for(;$i<40;$i++) { &BODY_20_39($i,@V); unshift(@V,pop(@V)); }
210for(;$i<60;$i++) { &BODY_40_59($i,@V); unshift(@V,pop(@V)); }
211for(;$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;
241print $code;
242close 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
67if ($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
97open STDOUT,">$output" || die "can't open $output: $!";
98
99if ($^O eq "hpux") {
100 $ADDP="addp4";
101 for (@ARGV) { $ADDP="add" if (/[\+DD|\-mlp]64/); }
102} else { $ADDP="add"; }
103for (@ARGV) { $big_endian=1 if (/\-DB_ENDIAN/);
104 $big_endian=0 if (/\-DL_ENDIAN/); }
105if (!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
114pfssave=r2;
115lcsave=r3;
116prsave=r14;
117K=r15;
118A=r16; B=r17; C=r18; D=r19;
119E=r20; F=r21; G=r22; H=r23;
120T1=r24; T2=r25;
121s0=r26; s1=r27; t0=r28; t1=r29;
122Ktbl=r30;
123ctx=r31; // 1st arg
124input=r48; // 2nd arg
125num=r49; // 3rd arg
126sgm0=r50; sgm1=r51; // small constants
127A_=r54; B_=r55; C_=r56; D_=r57;
128E_=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;
595if ($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
603print $code;
604
605print<<___ if ($BITS==32);
606.align 64
607.type K256#,\@object
608K256: 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
625stringz "SHA256 block transform for IA64, CRYPTOGAMS by <appro\@openssl.org>"
626___
627print<<___ if ($BITS==64);
628.align 64
629.type K512#,\@object
630K512: 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
671stringz "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
48die "can't locate x86_64-xlate.pl";
49
50open STDOUT,"| $^X $xlate $output";
51
52if ($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
90sub 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
141sub 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
272if ($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;
343print $code;
344close 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
17const char SHA256_version[]="SHA-256" OPENSSL_VERSION_PTEXT;
18
19int 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
30int 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
41unsigned 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
54unsigned 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
67int SHA224_Update(SHA256_CTX *c, const void *data, size_t len)
68{ return SHA256_Update (c,data,len); }
69int 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
111static
112#endif
113void sha256_block_data_order (SHA256_CTX *ctx, const void *in, size_t num);
114
115#include "md32_common.h"
116
117#ifndef SHA256_ASM
118static 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
151static 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
203static 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
53const 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
62int 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
77int 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
93static
94#endif
95void sha512_block_data_order (SHA512_CTX *ctx, const void *in, size_t num);
96
97int 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
175int SHA384_Final (unsigned char *md,SHA512_CTX *c)
176{ return SHA512_Final (md,c); }
177
178int 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
229int SHA384_Update (SHA512_CTX *c, const void *data, size_t len)
230{ return SHA512_Update (c,data,len); }
231
232void SHA512_Transform (SHA512_CTX *c, const unsigned char *data)
233{ sha512_block_data_order (c,data,1); }
234
235unsigned 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
248unsigned 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
262static 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
401static 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
462static 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*.
25OPENSSL_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
137walk_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
1491: 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
1632: ret
164 restore
165.size OPENSSL_wipe_cpu,.-OPENSSL_wipe_cpu
166
167.global OPENSSL_atomic_add
168.type OPENSSL_atomic_add,#function
169OPENSSL_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
2061: 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
70static 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
87X509_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
96void 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
146int 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
198int 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
205int 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
215int 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
223int X509_VERIFY_PARAM_clear_flags(X509_VERIFY_PARAM *param, unsigned long flags)
224 {
225 param->flags &= ~flags;
226 return 1;
227 }
228
229unsigned long X509_VERIFY_PARAM_get_flags(X509_VERIFY_PARAM *param)
230 {
231 return param->flags;
232 }
233
234int X509_VERIFY_PARAM_set_purpose(X509_VERIFY_PARAM *param, int purpose)
235 {
236 return X509_PURPOSE_set(&param->purpose, purpose);
237 }
238
239int X509_VERIFY_PARAM_set_trust(X509_VERIFY_PARAM *param, int trust)
240 {
241 return X509_TRUST_set(&param->trust, trust);
242 }
243
244void X509_VERIFY_PARAM_set_depth(X509_VERIFY_PARAM *param, int depth)
245 {
246 param->depth = depth;
247 }
248
249void 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
255int 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
268int 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
304int 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
315static 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
357static STACK_OF(X509_VERIFY_PARAM) *param_table = NULL;
358
359static 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
365static 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
371int 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
396const 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
414void 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
65static int policy_data_cmp(const X509_POLICY_DATA * const *a,
66 const X509_POLICY_DATA * const *b);
67static 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
73static 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
129static 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
236void 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
247const 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
261X509_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
273static 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
279static 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
67void 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
85X509_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
59DECLARE_STACK_OF(X509_POLICY_DATA)
60DECLARE_STACK_OF(X509_POLICY_REF)
61DECLARE_STACK_OF(X509_POLICY_NODE)
62
63typedef struct X509_POLICY_DATA_st X509_POLICY_DATA;
64typedef 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
74struct 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
117struct 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
125struct 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
148struct 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
158struct 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
171struct 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
196X509_POLICY_DATA *policy_data_new(POLICYINFO *policy, ASN1_OBJECT *id,
197 int crit);
198void policy_data_free(X509_POLICY_DATA *data);
199
200X509_POLICY_DATA *policy_cache_find_data(const X509_POLICY_CACHE *cache,
201 const ASN1_OBJECT *id);
202int policy_cache_set_mapping(X509 *x, POLICY_MAPPINGS *maps);
203
204
205STACK_OF(X509_POLICY_NODE) *policy_node_cmp_new(void);
206
207void policy_cache_init(void);
208
209void policy_cache_free(X509_POLICY_CACHE *cache);
210
211X509_POLICY_NODE *level_find_node(const X509_POLICY_LEVEL *level,
212 const ASN1_OBJECT *id);
213
214X509_POLICY_NODE *tree_find_sk(STACK_OF(X509_POLICY_NODE) *sk,
215 const ASN1_OBJECT *id);
216
217X509_POLICY_NODE *level_add_node(X509_POLICY_LEVEL *level,
218 X509_POLICY_DATA *data,
219 X509_POLICY_NODE *parent,
220 X509_POLICY_TREE *tree);
221void policy_node_free(X509_POLICY_NODE *node);
222
223const 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
70int X509_policy_tree_level_count(const X509_POLICY_TREE *tree)
71 {
72 if (!tree)
73 return 0;
74 return tree->nlevel;
75 }
76
77X509_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
85STACK_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
93STACK_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
106int 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
120X509_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
135const 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
143int 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
151STACK_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
159const 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
65static 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
71static 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
78static 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
94int 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
65static 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
71STACK_OF(X509_POLICY_NODE) *policy_node_cmp_new(void)
72 {
73 return sk_X509_POLICY_NODE_new(node_cmp);
74 }
75
76X509_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
94X509_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
100X509_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
153void 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
74static 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
244static 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
282static 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
336static 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
384static 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
412static 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
458static 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
522static 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
546static 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
553void 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
592int 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
66static void *v2i_NAME_CONSTRAINTS(X509V3_EXT_METHOD *method,
67 X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval);
68static int i2r_NAME_CONSTRAINTS(X509V3_EXT_METHOD *method,
69 void *a, BIO *bp, int ind);
70static int do_i2r_name_constraints(X509V3_EXT_METHOD *method,
71 STACK_OF(GENERAL_SUBTREE) *trees,
72 BIO *bp, int ind, char *name);
73static int print_nc_ipadd(BIO *bp, ASN1_OCTET_STRING *ip);
74
75const 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
85ASN1_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
91ASN1_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
99IMPLEMENT_ASN1_ALLOC_FUNCTIONS(GENERAL_SUBTREE)
100IMPLEMENT_ASN1_ALLOC_FUNCTIONS(NAME_CONSTRAINTS)
101
102static 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
158static 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
169static 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
191static 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,
44static PROXY_CERT_INFO_EXTENSION *r2i_pci(X509V3_EXT_METHOD *method, 44static PROXY_CERT_INFO_EXTENSION *r2i_pci(X509V3_EXT_METHOD *method,
45 X509V3_CTX *ctx, char *str); 45 X509V3_CTX *ctx, char *str);
46 46
47X509V3_EXT_METHOD v3_pci = 47const 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; }
310end: 299end:
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
67static STACK_OF(CONF_VALUE) *i2v_POLICY_CONSTRAINTS(X509V3_EXT_METHOD *method,
68 void *bcons, STACK_OF(CONF_VALUE) *extlist);
69static void *v2i_POLICY_CONSTRAINTS(X509V3_EXT_METHOD *method,
70 X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *values);
71
72const X509V3_EXT_METHOD v3_policy_constraints = {
73NID_policy_constraints, 0,
74ASN1_ITEM_ref(POLICY_CONSTRAINTS),
750,0,0,0,
760,0,
77i2v_POLICY_CONSTRAINTS,
78v2i_POLICY_CONSTRAINTS,
79NULL,NULL,
80NULL
81};
82
83ASN1_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
88IMPLEMENT_ASN1_ALLOC_FUNCTIONS(POLICY_CONSTRAINTS)
89
90
91static 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
102static 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
66static void *v2i_POLICY_MAPPINGS(X509V3_EXT_METHOD *method,
67 X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval);
68static STACK_OF(CONF_VALUE) *i2v_POLICY_MAPPINGS(X509V3_EXT_METHOD *method,
69 void *pmps, STACK_OF(CONF_VALUE) *extlist);
70
71const 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
82ASN1_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
87ASN1_ITEM_TEMPLATE(POLICY_MAPPINGS) =
88 ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, POLICY_MAPPINGS,
89 POLICY_MAPPING)
90ASN1_ITEM_TEMPLATE_END(POLICY_MAPPINGS)
91
92IMPLEMENT_ASN1_ALLOC_FUNCTIONS(POLICY_MAPPING)
93
94
95static 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
112static 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/);
5open STDOUT,">$output" || die "can't open $output: $!";
6
7print<<___ if(defined($masm));
8_TEXT SEGMENT
9PUBLIC OPENSSL_rdtsc
10
11PUBLIC OPENSSL_atomic_add
12ALIGN 16
13OPENSSL_atomic_add PROC
14 mov eax,DWORD PTR[rcx]
15\$Lspin: lea r8,DWORD PTR[rdx+rax]
16lock cmpxchg DWORD PTR[rcx],r8d
17 jne \$Lspin
18 mov eax,r8d
19 cdqe
20 ret
21OPENSSL_atomic_add ENDP
22
23PUBLIC OPENSSL_wipe_cpu
24ALIGN 16
25OPENSSL_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
40OPENSSL_wipe_cpu ENDP
41_TEXT ENDS
42
43CRT\$XIU SEGMENT
44EXTRN OPENSSL_cpuid_setup:PROC
45DQ OPENSSL_cpuid_setup
46CRT\$XIU ENDS
47
48___
49print<<___ if(!defined($masm));
50.text
51
52.globl OPENSSL_atomic_add
53.type OPENSSL_atomic_add,\@function
54.align 16
55OPENSSL_atomic_add:
56 movl (%rdi),%eax
57.Lspin: leaq (%rsi,%rax),%r8
58lock; 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
68OPENSSL_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
102open STDOUT,"| $^X perlasm/x86_64-xlate.pl $output";
103print<<___;
104.text
105
106.globl OPENSSL_rdtsc
107.type OPENSSL_rdtsc,\@abi-omnipotent
108.align 16
109OPENSSL_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
119OPENSSL_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___
159close 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
3push(@INC,"perlasm");
4require "x86asm.pl";
5
6&asm_init($ARGV[0],"x86cpuid");
7
8for (@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 */
128static unsigned int g_probable_mtu[] = {1500 - 28, 512 - 28, 256 - 28};
129
130static unsigned int dtls1_min_mtu(void);
131static unsigned int dtls1_guess_mtu(unsigned int curr_mtu);
132static void dtls1_fix_message_header(SSL *s, unsigned long frag_off,
133 unsigned long frag_len);
134static unsigned char *dtls1_write_message_header(SSL *s,
135 unsigned char *p);
136static 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);
139static int dtls1_retransmit_buffered_messages(SSL *s);
140static long dtls1_get_message_fragment(SSL *s, int st1, int stn,
141 long max, int *ok);
142
143static hm_fragment *
144dtls1_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
169static void
170dtls1_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) */
177int 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 */
351long 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
445f_err:
446 ssl3_send_alert(s,SSL3_AL_FATAL,al);
447 *ok = 0;
448 return -1;
449 }
450
451
452static 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
501static int
502dtls1_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
552static int
553dtls1_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
604err:
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
612static long
613dtls1_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
714f_err:
715 ssl3_send_alert(s,SSL3_AL_FATAL,al);
716 s->init_num = 0;
717
718 *ok=0;
719 return(-1);
720 }
721
722int 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 */
771int 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
804unsigned 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
884int 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
946static int
947dtls1_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
971int
972dtls1_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
1027int
1028dtls1_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 */
1082void
1083dtls1_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
1096unsigned char *
1097dtls1_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 */
1114static void
1115dtls1_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
1128static void
1129dtls1_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
1138static unsigned char *
1139dtls1_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
1153static unsigned int
1154dtls1_min_mtu(void)
1155 {
1156 return (g_probable_mtu[(sizeof(g_probable_mtu) /
1157 sizeof(g_probable_mtu[0])) - 1]);
1158 }
1159
1160static unsigned int
1161dtls1_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
1175void
1176dtls1_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
1187void
1188dtls1_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
128static SSL_METHOD *dtls1_get_client_method(int ver);
129static int dtls1_get_hello_verify(SSL *s);
130
131static 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
139IMPLEMENT_dtls1_meth_func(DTLSv1_client_method,
140 ssl_undefined_function,
141 dtls1_connect,
142 dtls1_get_client_method)
143
144int 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 }
524end:
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
533int 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));
641err:
642 return(-1);
643 }
644
645static 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
691f_err:
692 ssl3_send_alert(s, SSL3_AL_FATAL, al);
693 return -1;
694 }
695
696int 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));
992err:
993 return(-1);
994 }
995
996int 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));
1070err:
1071 return(-1);
1072 }
1073
1074int 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
125int 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
64const char dtls1_version_str[]="DTLSv1" OPENSSL_VERSION_PTEXT;
65
66SSL3_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
80long 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
87IMPLEMENT_dtls1_meth_func(dtlsv1_base_method,
88 ssl_undefined_function,
89 ssl_undefined_function,
90 ssl_bad_method)
91
92int 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
138void 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
186void 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 */
199SSL_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
64static SSL_METHOD *dtls1_get_method(int ver);
65static SSL_METHOD *dtls1_get_method(int ver)
66 {
67 if (ver == DTLS1_VERSION)
68 return(DTLSv1_method());
69 else
70 return(NULL);
71 }
72
73IMPLEMENT_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
125static int have_handshake_fragment(SSL *s, int type, unsigned char *buf,
126 int len, int peek);
127static int dtls1_record_replay_check(SSL *s, DTLS1_BITMAP *bitmap,
128 PQ_64BIT *seq_num);
129static void dtls1_record_bitmap_update(SSL *s, DTLS1_BITMAP *bitmap);
130static DTLS1_BITMAP *dtls1_get_bitmap(SSL *s, SSL3_RECORD *rr,
131 unsigned int *is_next_epoch);
132#if 0
133static int dtls1_record_needs_buffering(SSL *s, SSL3_RECORD *rr,
134 unsigned short *priority, unsigned long *offset);
135#endif
136static int dtls1_buffer_record(SSL *s, record_pqueue *q,
137 PQ_64BIT priority);
138static int dtls1_process_record(SSL *s);
139#if PQ_64BIT_IS_INTEGER
140static PQ_64BIT bytes_to_long_long(unsigned char *bytes, PQ_64BIT *num);
141#endif
142static void dtls1_clear_timeouts(SSL *s);
143
144/* copy buffered record into SSL structure */
145static int
146dtls1_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
164static int
165dtls1_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
213static int
214dtls1_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
244static int
245dtls1_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
281static int
282dtls1_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
324static int
325dtls1_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
377printf("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'); }
379printf("\n");
380#endif
381
382 /* r->length is now the compressed data plus mac */
383if ( (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
459decryption_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);
467f_err:
468 ssl3_send_alert(s,SSL3_AL_FATAL,al);
469err:
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 */
483int 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 */
507again:
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
625f_err:
626 ssl3_send_alert(s,SSL3_AL_FATAL,al);
627err:
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 */
658int 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
696start:
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
1126f_err:
1127 ssl3_send_alert(s,SSL3_AL_FATAL,al);
1128err:
1129 return(-1);
1130 }
1131
1132int
1133dtls1_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. */
1179static int
1180have_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 */
1214int 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
1257int 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);
1461err:
1462 return -1;
1463 }
1464
1465
1466
1467static 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
1526static 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
1575int 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
1635static DTLS1_BITMAP *
1636dtls1_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
1658static int
1659dtls1_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
1722void
1723dtls1_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
1754static PQ_64BIT
1755bytes_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
1774static void
1775dtls1_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
128static SSL_METHOD *dtls1_get_server_method(int ver);
129static int dtls1_send_hello_verify_request(SSL *s);
130
131static 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
139IMPLEMENT_dtls1_meth_func(DTLSv1_server_method,
140 dtls1_accept,
141 ssl_undefined_function,
142 dtls1_get_server_method)
143
144int 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 }
586end:
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
595int 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
617int 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
665int 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
748int 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
772int 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));
1010f_err:
1011 ssl3_send_alert(s,SSL3_AL_FATAL,al);
1012err:
1013 EVP_MD_CTX_cleanup(&md_ctx);
1014 return(-1);
1015 }
1016
1017int 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));
1114err:
1115 return(-1);
1116 }
1117
1118int 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
67extern "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
90typedef 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
97struct 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
107struct ccs_header_st
108 {
109 unsigned char type;
110 unsigned short seq;
111 };
112
113struct 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
125typedef struct record_pqueue_st
126 {
127 unsigned short epoch;
128 pqueue q;
129 } record_pqueue;
130
131typedef struct hm_fragment_st
132 {
133 struct hm_header_st msg_header;
134 unsigned char *fragment;
135 } hm_fragment;
136
137typedef 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
192typedef 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
24commonName = Common Name (eg, YOUR name) 24commonName = Common Name (eg, YOUR name)
25commonName_value = Dodgy CA 25commonName_value = Dodgy CA
26 26
27####################################################################
28[ ca ]
29default_ca = CA_default # The default ca section
30
31####################################################################
32[ CA_default ]
33
34dir = ./demoCA # Where everything is kept
35certs = $dir/certs # Where the issued certs are kept
36crl_dir = $dir/crl # Where the issued crl are kept
37database = $dir/index.txt # database index file.
38#unique_subject = no # Set to 'no' to allow creation of
39 # several ctificates with same subject.
40new_certs_dir = $dir/newcerts # default place for new certs.
41
42certificate = $dir/cacert.pem # The CA certificate
43serial = $dir/serial # The current serial number
44crl = $dir/crl.pem # The current CRL
45private_key = $dir/private/cakey.pem# The private key
46RANDFILE = $dir/private/.rand # private random number file
47
48x509_extensions = v3_ca # The extentions to add to the cert
49
50name_opt = ca_default # Subject Name options
51cert_opt = ca_default # Certificate field options
52
53default_days = 365 # how long to certify for
54default_crl_days= 30 # how long before next CRL
55default_md = md5 # which md to use.
56preserve = no # keep passed DN ordering
57
58policy = policy_anything
59
60[ policy_anything ]
61countryName = optional
62stateOrProvinceName = optional
63localityName = optional
64organizationName = optional
65organizationalUnitName = optional
66commonName = supplied
67emailAddress = optional
68
69
70
27[ v3_ca ] 71[ v3_ca ]
28subjectKeyIdentifier=hash 72subjectKeyIdentifier=hash
29authorityKeyIdentifier=keyid:always,issuer:always 73authorityKeyIdentifier=keyid:always,issuer:always
30basicConstraints = CA:true,pathlen:1 74basicConstraints = CA:true,pathlen:1
31keyUsage = cRLSign, keyCertSign 75keyUsage = cRLSign, keyCertSign
32issuerAltName=issuer:copy 76issuerAltName=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
56use MIME::Base64;
57
58my $badttest = 0;
59my $verbose = 1;
60
61my $cmscmd;
62my $exdir = "./";
63my $exfile = "./rfc4134.txt";
64
65if (-f "../apps/openssl")
66 {
67 $cmscmd = "../util/shlib_wrap.sh ../apps/openssl cms";
68 }
69elsif (-f "..\\out32dll\\openssl.exe")
70 {
71 $cmscmd = "..\\out32dll\\openssl.exe cms";
72 }
73elsif (-f "..\\out32\\openssl.exe")
74 {
75 $cmscmd = "..\\out32\\openssl.exe cms";
76 }
77
78my @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
104my ( $filename, $data );
105
106my @cleanup = ( "cms.out", "cms.err", "tmp.der", "tmp.txt" );
107
108$data = "";
109
110open( IN, $exfile ) || die "Can't Open RFC examples file $exfile";
111
112while (<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
145my $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
148foreach (@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
175foreach (@cleanup) {
176 unlink $_;
177}
178
179if ($badtest) {
180 print "\n$badtest TESTS FAILED!!\n";
181}
182else {
183 print "\n***All tests successful***\n";
184}
185
186sub 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
202sub 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
222sub 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
239sub 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
259sub 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
292sub 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
322sub 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
346sub 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
369sub 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
56my $ossl_path;
57
58if ( -f "../apps/openssl" ) {
59 $ossl_path = "../util/shlib_wrap.sh ../apps/openssl";
60}
61elsif ( -f "..\\out32dll\\openssl.exe" ) {
62 $ossl_path = "..\\out32dll\\openssl.exe";
63}
64elsif ( -f "..\\out32\\openssl.exe" ) {
65 $ossl_path = "..\\out32\\openssl.exe";
66}
67else {
68 die "Can't find OpenSSL executable";
69}
70
71my $pk7cmd = "$ossl_path smime ";
72my $cmscmd = "$ossl_path cms ";
73my $smdir = "smime-certs";
74my $halt_err = 1;
75
76my $badcmd = 0;
77my $ossl8 = `$ossl_path version -v` =~ /0\.9\.8/;
78
79my @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
210my @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
325my @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
336print "PKCS#7 <=> PKCS#7 consistency tests\n";
337
338run_smime_tests( \$badcmd, \@smime_pkcs7_tests, $pk7cmd, $pk7cmd );
339
340print "CMS => PKCS#7 compatibility tests\n";
341
342run_smime_tests( \$badcmd, \@smime_pkcs7_tests, $cmscmd, $pk7cmd );
343
344print "CMS <= PKCS#7 compatibility tests\n";
345
346run_smime_tests( \$badcmd, \@smime_pkcs7_tests, $pk7cmd, $cmscmd );
347
348print "CMS <=> CMS consistency tests\n";
349
350run_smime_tests( \$badcmd, \@smime_pkcs7_tests, $cmscmd, $cmscmd );
351run_smime_tests( \$badcmd, \@smime_cms_tests, $cmscmd, $cmscmd );
352
353if ( `$ossl_path version -f` =~ /ZLIB/ ) {
354 run_smime_tests( \$badcmd, \@smime_cms_comp_tests, $cmscmd, $cmscmd );
355}
356else {
357 print "Zlib not supported: compression tests skipped\n";
358}
359
360print "Running modified tests for OpenSSL 0.9.8 cms backport\n" if($ossl8);
361
362if ($badcmd) {
363 print "$badcmd TESTS FAILED!!\n";
364}
365else {
366 print "ALL TESTS SUCCESSFUL.\n";
367}
368
369unlink "test.cms";
370unlink "test2.cms";
371unlink "smtst.txt";
372unlink "cms.out";
373unlink "cms.err";
374
375sub 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
413sub 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-----
2MIIBuwIBAAKBgQDFJfsIPOIawMO5biw+AoYUhNVxReBOLQosU3Qv4B8krac0BNr3
3OjSGLh1wZxHqhlAE0QmasTaKojuk20nNWeFnczSz6vDl0IVJEhS8VYor5kt9gLqt
4GcoAgsf4gRDIutJyQDaNn3IVY89uXUVIoexvQeLQDBCgQPC5O8rJdqBwtwIVAK2J
5jt+dqk07eQUE59koYUEKyNorAoGBAI4IEpusf8G14kCHmRtnHXM2tG5EWJDmW6Qt
6wjqvWp1GKUx5WFy1tVWR9nl5rL0Di+kNdENo+SkKj7h3uDulGOI6T0mQYbV2h1IK
7+FMOGnOqvZ8eNTE2n4PGTo5puZ63LBm+QYrQsrNiUY4vakLFQ2rEK/SLwdsDFK4Z
8SJCBQw5zAoGATQlPPF+OeU8nu3rsdXGDiZdJzOkuCce3KQfTABA9C+Dk4CVcvBdd
9YRLGpnykumkNTO1sTO+4/Gphsuje1ujK9td4UEhdYqylCe5QjEMrszDlJtelDQF9
10C0yhdjKGTP0kxofLhsGckcuQvcKEKffT2pDDKJIy4vWQO0UyJl1vjLcCFG2uiGGx
119fMUZq1v0ePD4Wo0Xkxo
12-----END DSA PRIVATE KEY-----
13-----BEGIN CERTIFICATE-----
14MIIDpDCCAw2gAwIBAgIJAMtotfHYdEsWMA0GCSqGSIb3DQEBBQUAMEQxCzAJBgNV
15BAYTAlVLMRYwFAYDVQQKEw1PcGVuU1NMIEdyb3VwMR0wGwYDVQQDExRUZXN0IFMv
16TUlNRSBSU0EgUm9vdDAeFw0wODAyMjIxMzUzMDlaFw0xNjA1MTAxMzUzMDlaMEUx
17CzAJBgNVBAYTAlVLMRYwFAYDVQQKDA1PcGVuU1NMIEdyb3VwMR4wHAYDVQQDDBVU
18ZXN0IFMvTUlNRSBFRSBEU0EgIzEwggG3MIIBLAYHKoZIzjgEATCCAR8CgYEAxSX7
19CDziGsDDuW4sPgKGFITVcUXgTi0KLFN0L+AfJK2nNATa9zo0hi4dcGcR6oZQBNEJ
20mrE2iqI7pNtJzVnhZ3M0s+rw5dCFSRIUvFWKK+ZLfYC6rRnKAILH+IEQyLrSckA2
21jZ9yFWPPbl1FSKHsb0Hi0AwQoEDwuTvKyXagcLcCFQCtiY7fnapNO3kFBOfZKGFB
22CsjaKwKBgQCOCBKbrH/BteJAh5kbZx1zNrRuRFiQ5lukLcI6r1qdRilMeVhctbVV
23kfZ5eay9A4vpDXRDaPkpCo+4d7g7pRjiOk9JkGG1dodSCvhTDhpzqr2fHjUxNp+D
24xk6OabmetywZvkGK0LKzYlGOL2pCxUNqxCv0i8HbAxSuGUiQgUMOcwOBhAACgYBN
25CU88X455Tye7eux1cYOJl0nM6S4Jx7cpB9MAED0L4OTgJVy8F11hEsamfKS6aQ1M
267WxM77j8amGy6N7W6Mr213hQSF1irKUJ7lCMQyuzMOUm16UNAX0LTKF2MoZM/STG
27h8uGwZyRy5C9woQp99PakMMokjLi9ZA7RTImXW+Mt6OBgzCBgDAdBgNVHQ4EFgQU
284Qfbhpi5yqXaXuCLXj427mR25MkwHwYDVR0jBBgwFoAUE89Lp7uJLrM4Vxd2xput
29aFvl7RcwDAYDVR0TAQH/BAIwADAOBgNVHQ8BAf8EBAMCBsAwIAYDVR0RBBkwF4EV
30c21pbWVkc2ExQG9wZW5zc2wub3JnMA0GCSqGSIb3DQEBBQUAA4GBAFrdUzKK1pWO
31kd02S423KUBc4GWWyiGlVoEO7WxVhHLJ8sm67X7OtJOwe0UGt+Nc5qLtyJYSirw8
32phjiTdNpQCTJ8+Kc56tWkJ6H7NAI4vTJtPL5BM/EmeYrVSU9JI9xhqpyKw9IBD+n
33hRJ79W9FaiJRvaAOX+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-----
2MIIBvAIBAAKBgQDFJfsIPOIawMO5biw+AoYUhNVxReBOLQosU3Qv4B8krac0BNr3
3OjSGLh1wZxHqhlAE0QmasTaKojuk20nNWeFnczSz6vDl0IVJEhS8VYor5kt9gLqt
4GcoAgsf4gRDIutJyQDaNn3IVY89uXUVIoexvQeLQDBCgQPC5O8rJdqBwtwIVAK2J
5jt+dqk07eQUE59koYUEKyNorAoGBAI4IEpusf8G14kCHmRtnHXM2tG5EWJDmW6Qt
6wjqvWp1GKUx5WFy1tVWR9nl5rL0Di+kNdENo+SkKj7h3uDulGOI6T0mQYbV2h1IK
7+FMOGnOqvZ8eNTE2n4PGTo5puZ63LBm+QYrQsrNiUY4vakLFQ2rEK/SLwdsDFK4Z
8SJCBQw5zAoGBAIPmO8BtJ+Yac58trrPwq9b/6VW3jQTWzTLWSH84/QQdqQa+Pz3v
9It/+hHM0daNF5uls8ICsPL1aLXmRx0pHvIyb0aAzYae4T4Jv/COPDMTdKbA1uitJ
10VbkGZrm+LIrs7I9lOkb4T0vI6kL/XdOCXY1469zsqCgJ/O2ibn6mq0nWAhR716o2
11Nf8SimTZYB0/CKje6M5ufA==
12-----END DSA PRIVATE KEY-----
13-----BEGIN CERTIFICATE-----
14MIIDpTCCAw6gAwIBAgIJAMtotfHYdEsXMA0GCSqGSIb3DQEBBQUAMEQxCzAJBgNV
15BAYTAlVLMRYwFAYDVQQKEw1PcGVuU1NMIEdyb3VwMR0wGwYDVQQDExRUZXN0IFMv
16TUlNRSBSU0EgUm9vdDAeFw0wODAyMjIxMzUzMDlaFw0xNjA1MTAxMzUzMDlaMEUx
17CzAJBgNVBAYTAlVLMRYwFAYDVQQKDA1PcGVuU1NMIEdyb3VwMR4wHAYDVQQDDBVU
18ZXN0IFMvTUlNRSBFRSBEU0EgIzIwggG4MIIBLAYHKoZIzjgEATCCAR8CgYEAxSX7
19CDziGsDDuW4sPgKGFITVcUXgTi0KLFN0L+AfJK2nNATa9zo0hi4dcGcR6oZQBNEJ
20mrE2iqI7pNtJzVnhZ3M0s+rw5dCFSRIUvFWKK+ZLfYC6rRnKAILH+IEQyLrSckA2
21jZ9yFWPPbl1FSKHsb0Hi0AwQoEDwuTvKyXagcLcCFQCtiY7fnapNO3kFBOfZKGFB
22CsjaKwKBgQCOCBKbrH/BteJAh5kbZx1zNrRuRFiQ5lukLcI6r1qdRilMeVhctbVV
23kfZ5eay9A4vpDXRDaPkpCo+4d7g7pRjiOk9JkGG1dodSCvhTDhpzqr2fHjUxNp+D
24xk6OabmetywZvkGK0LKzYlGOL2pCxUNqxCv0i8HbAxSuGUiQgUMOcwOBhQACgYEA
25g+Y7wG0n5hpzny2us/Cr1v/pVbeNBNbNMtZIfzj9BB2pBr4/Pe8i3/6EczR1o0Xm
266WzwgKw8vVoteZHHSke8jJvRoDNhp7hPgm/8I48MxN0psDW6K0lVuQZmub4siuzs
27j2U6RvhPS8jqQv9d04JdjXjr3OyoKAn87aJufqarSdajgYMwgYAwHQYDVR0OBBYE
28FHsAGNfVltSYUq4hC+YVYwsYtA+dMB8GA1UdIwQYMBaAFBPPS6e7iS6zOFcXdsab
29rWhb5e0XMAwGA1UdEwEB/wQCMAAwDgYDVR0PAQH/BAQDAgbAMCAGA1UdEQQZMBeB
30FXNtaW1lZHNhMkBvcGVuc3NsLm9yZzANBgkqhkiG9w0BAQUFAAOBgQCx9BtCbaYF
31FXjLClkuKXbESaDZA1biPgY25i00FsUzARuhCpqD2v+0tu5c33ZzIhL6xlvBRU5l
326Atw/xpZhae+hdBEtxPJoGekLLrHOau7Md3XwDjV4lFgcEJkWZoaSOOIK+4D5jF0
33jZWtHjnwEzuLYlo7ScHSsbcQfjH0M1TP5A==
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-----
2MIIBvAIBAAKBgQDFJfsIPOIawMO5biw+AoYUhNVxReBOLQosU3Qv4B8krac0BNr3
3OjSGLh1wZxHqhlAE0QmasTaKojuk20nNWeFnczSz6vDl0IVJEhS8VYor5kt9gLqt
4GcoAgsf4gRDIutJyQDaNn3IVY89uXUVIoexvQeLQDBCgQPC5O8rJdqBwtwIVAK2J
5jt+dqk07eQUE59koYUEKyNorAoGBAI4IEpusf8G14kCHmRtnHXM2tG5EWJDmW6Qt
6wjqvWp1GKUx5WFy1tVWR9nl5rL0Di+kNdENo+SkKj7h3uDulGOI6T0mQYbV2h1IK
7+FMOGnOqvZ8eNTE2n4PGTo5puZ63LBm+QYrQsrNiUY4vakLFQ2rEK/SLwdsDFK4Z
8SJCBQw5zAoGAYzOpPmh8Je1IDauEXhgaLz14wqYUHHcrj2VWVJ6fRm8GhdQFJSI7
9GUk08pgKZSKic2lNqxuzW7/vFxKQ/nvzfytY16b+2i+BR4Q6yvMzCebE1hHVg0Ju
10TwfUMwoFEOhYP6ZwHSUiQl9IBMH9TNJCMwYMxfY+VOrURFsjGTRUgpwCFQCIGt5g
11Y+XZd0Sv69CatDIRYWvaIA==
12-----END DSA PRIVATE KEY-----
13-----BEGIN CERTIFICATE-----
14MIIDpDCCAw2gAwIBAgIJAMtotfHYdEsYMA0GCSqGSIb3DQEBBQUAMEQxCzAJBgNV
15BAYTAlVLMRYwFAYDVQQKEw1PcGVuU1NMIEdyb3VwMR0wGwYDVQQDExRUZXN0IFMv
16TUlNRSBSU0EgUm9vdDAeFw0wODAyMjIxMzUzMDlaFw0xNjA1MTAxMzUzMDlaMEUx
17CzAJBgNVBAYTAlVLMRYwFAYDVQQKDA1PcGVuU1NMIEdyb3VwMR4wHAYDVQQDDBVU
18ZXN0IFMvTUlNRSBFRSBEU0EgIzMwggG3MIIBLAYHKoZIzjgEATCCAR8CgYEAxSX7
19CDziGsDDuW4sPgKGFITVcUXgTi0KLFN0L+AfJK2nNATa9zo0hi4dcGcR6oZQBNEJ
20mrE2iqI7pNtJzVnhZ3M0s+rw5dCFSRIUvFWKK+ZLfYC6rRnKAILH+IEQyLrSckA2
21jZ9yFWPPbl1FSKHsb0Hi0AwQoEDwuTvKyXagcLcCFQCtiY7fnapNO3kFBOfZKGFB
22CsjaKwKBgQCOCBKbrH/BteJAh5kbZx1zNrRuRFiQ5lukLcI6r1qdRilMeVhctbVV
23kfZ5eay9A4vpDXRDaPkpCo+4d7g7pRjiOk9JkGG1dodSCvhTDhpzqr2fHjUxNp+D
24xk6OabmetywZvkGK0LKzYlGOL2pCxUNqxCv0i8HbAxSuGUiQgUMOcwOBhAACgYBj
25M6k+aHwl7UgNq4ReGBovPXjCphQcdyuPZVZUnp9GbwaF1AUlIjsZSTTymAplIqJz
26aU2rG7Nbv+8XEpD+e/N/K1jXpv7aL4FHhDrK8zMJ5sTWEdWDQm5PB9QzCgUQ6Fg/
27pnAdJSJCX0gEwf1M0kIzBgzF9j5U6tREWyMZNFSCnKOBgzCBgDAdBgNVHQ4EFgQU
28VhpVXqQ/EzUMdxLvP7o9EhJ8h70wHwYDVR0jBBgwFoAUE89Lp7uJLrM4Vxd2xput
29aFvl7RcwDAYDVR0TAQH/BAIwADAOBgNVHQ8BAf8EBAMCBsAwIAYDVR0RBBkwF4EV
30c21pbWVkc2EzQG9wZW5zc2wub3JnMA0GCSqGSIb3DQEBBQUAA4GBACM9e75EQa8m
31k/AZkH/tROqf3yeqijULl9x8FjFatqoY+29OM6oMGM425IqSkKd2ipz7OxO0SShu
32rE0O3edS7DvYBwvhWPviRaYBMyZ4iFJVup+fOzoYK/j/bASxS3BHQBwb2r4rhe25
33OlTyyFEk7DJyW18YFOG97S1P52oQ5f5x
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-----
2MIIBHwKBgQDFJfsIPOIawMO5biw+AoYUhNVxReBOLQosU3Qv4B8krac0BNr3OjSG
3Lh1wZxHqhlAE0QmasTaKojuk20nNWeFnczSz6vDl0IVJEhS8VYor5kt9gLqtGcoA
4gsf4gRDIutJyQDaNn3IVY89uXUVIoexvQeLQDBCgQPC5O8rJdqBwtwIVAK2Jjt+d
5qk07eQUE59koYUEKyNorAoGBAI4IEpusf8G14kCHmRtnHXM2tG5EWJDmW6Qtwjqv
6Wp1GKUx5WFy1tVWR9nl5rL0Di+kNdENo+SkKj7h3uDulGOI6T0mQYbV2h1IK+FMO
7GnOqvZ8eNTE2n4PGTo5puZ63LBm+QYrQsrNiUY4vakLFQ2rEK/SLwdsDFK4ZSJCB
8Qw5z
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-----
2MIICXAIBAAKBgQDBV1Z/Q5gPF7lojc8pKUdyz5+Jf2B3vs4he6egekugWnoJduki
39Lnae/JchB/soIX0co3nLc11NuFFlnAWJNMDJr08l5AHAJLYNHevF5l/f9oDQwvZ
4speKh1xpIAJNqCTzVeQ/ZLx6/GccIXV/xDuKIiovqJTPgR5WPkYKaw++lQIDAQAB
5AoGALXnUj5SflJU4+B2652ydMKUjWl0KnL/VjkyejgGV/j6py8Ybaixz9q8Gv7oY
6JDlRqMC1HfZJCFQDQrHy5VJ+CywA/H9WrqKo/Ch9U4tJAZtkig1Cmay/BAYixVu0
7xBeim10aKF6hxHH4Chg9We+OCuzWBWJhqveNjuDedL/i7JUCQQDlejovcwBUCbhJ
8U12qKOwlaboolWbl7yF3XdckTJZg7+1UqQHZH5jYZlLZyZxiaC92SNV0SyTLJZnS
9Jh5CO+VDAkEA16/pPcuVtMMz/R6SSPpRSIAa1stLs0mFSs3NpR4pdm0n42mu05pO
101tJEt3a1g7zkreQBf53+Dwb+lA841EkjRwJBAIFmt0DifKDnCkBu/jZh9SfzwsH3
113Zpzik+hXxxdA7+ODCrdUul449vDd5zQD5t+XKU61QNLDGhxv5e9XvrCg7kCQH/a
123ldsVF0oDaxxL+QkxoREtCQ5tLEd1u7F2q6Tl56FDE0pe6Ih6bQ8RtG+g9EI60IN
13U7oTrOO5kLWx5E0q4ccCQAZVgoenn9MhRU1agKOCuM6LT2DxReTu4XztJzynej+8
140J93n3ebanB1MlRpn1XJwhQ7gAC8ImaQKLJK5jdJzFc=
15-----END RSA PRIVATE KEY-----
16-----BEGIN CERTIFICATE-----
17MIICaTCCAdKgAwIBAgIJAP6VN47boiXRMA0GCSqGSIb3DQEBBQUAMEQxCzAJBgNV
18BAYTAlVLMRYwFAYDVQQKEw1PcGVuU1NMIEdyb3VwMR0wGwYDVQQDExRUZXN0IFMv
19TUlNRSBSU0EgUm9vdDAeFw0wODAyMjIxMzUzMDdaFw0xNjA1MTExMzUzMDdaMEQx
20CzAJBgNVBAYTAlVLMRYwFAYDVQQKEw1PcGVuU1NMIEdyb3VwMR0wGwYDVQQDExRU
21ZXN0IFMvTUlNRSBSU0EgUm9vdDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA
22wVdWf0OYDxe5aI3PKSlHcs+fiX9gd77OIXunoHpLoFp6CXbpIvS52nvyXIQf7KCF
239HKN5y3NdTbhRZZwFiTTAya9PJeQBwCS2DR3rxeZf3/aA0ML2bKXiodcaSACTagk
2481XkP2S8evxnHCF1f8Q7iiIqL6iUz4EeVj5GCmsPvpUCAwEAAaNjMGEwHQYDVR0O
25BBYEFBPPS6e7iS6zOFcXdsabrWhb5e0XMB8GA1UdIwQYMBaAFBPPS6e7iS6zOFcX
26dsabrWhb5e0XMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMA0GCSqG
27SIb3DQEBBQUAA4GBAIECprq5viDvnDbkyOaiSr9ubMUmWqvycfAJMdPZRKcOZczS
28l+L9R9lF3JSqbt3knOe9u6bGDBOTY2285PdCCuHRVMk2Af1f6El1fqAlRUwNqipp
29r68sWFuRqrcRNtk6QQvXfkOhrqQBuDa7te/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-----
2MIICXgIBAAKBgQC6A978j4pmPgUtUQqF+bjh6vdhwGOGZSD7xXgFTMjm88twfv+E
3ixkq2KXSDjD0ZXoQbdOaSbvGRQrIJpG2NGiKAFdYNrP025kCCdh5wF/aEI7KLEm7
4JlHwXpQsuj4wkMgmkFjL3Ty4Z55aNH+2pPQIa0k+ENJXm2gDuhqgBmduAwIDAQAB
5AoGBAJMuYu51aO2THyeHGwt81uOytcCbqGP7eoib62ZOJhxPRGYjpmuqX+R9/V5i
6KiwGavm63JYUx0WO9YP+uIZxm1BUATzkgkS74u5LP6ajhkZh6/Bck1oIYYkbVOXl
7JVrdENuH6U7nupznsyYgONByo+ykFPVUGmutgiaC7NMVo/MxAkEA6KLejWXdCIEn
8xr7hGph9NlvY9xuRIMexRV/WrddcFfCdjI1PciIupgrIkR65M9yr7atm1iU6/aRf
9KOr8rLZsSQJBAMyyXN71NsDNx4BP6rtJ/LJMP0BylznWkA7zWfGCbAYn9VhZVlSY
10Eu9Gyr7quD1ix7G3kInKVYOEEOpockBLz+sCQQCedyMmKjcQLfpMVYW8uhbAynvW
11h36qV5yXZxszO7nMcCTBsxhk5IfmLv5EbCs3+p9avCDGyoGOeUMg+kC33WORAkAg
12oUIarH4o5+SoeJTTfCzTA0KF9H5U0vYt2+73h7HOnWoHxl3zqDZEfEVvf50U8/0f
13QELDJETTbScBJtsnkq43AkEA38etvoZ2i4FJvvo7R/9gWBHVEcrGzcsCBYrNnIR1
14SZLRwHEGaiOK1wxMsWzqp7PJwL9z/M8A8DyOFBx3GPOniA==
15-----END RSA PRIVATE KEY-----
16-----BEGIN CERTIFICATE-----
17MIICizCCAfSgAwIBAgIJAMtotfHYdEsTMA0GCSqGSIb3DQEBBQUAMEQxCzAJBgNV
18BAYTAlVLMRYwFAYDVQQKEw1PcGVuU1NMIEdyb3VwMR0wGwYDVQQDExRUZXN0IFMv
19TUlNRSBSU0EgUm9vdDAeFw0wODAyMjIxMzUzMDhaFw0xNjA1MTAxMzUzMDhaMEUx
20CzAJBgNVBAYTAlVLMRYwFAYDVQQKDA1PcGVuU1NMIEdyb3VwMR4wHAYDVQQDDBVU
21ZXN0IFMvTUlNRSBFRSBSU0EgIzEwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGB
22ALoD3vyPimY+BS1RCoX5uOHq92HAY4ZlIPvFeAVMyObzy3B+/4SLGSrYpdIOMPRl
23ehBt05pJu8ZFCsgmkbY0aIoAV1g2s/TbmQIJ2HnAX9oQjsosSbsmUfBelCy6PjCQ
24yCaQWMvdPLhnnlo0f7ak9AhrST4Q0lebaAO6GqAGZ24DAgMBAAGjgYMwgYAwHQYD
25VR0OBBYEFE2vMvKz5jrC7Lbdg68XwZ95iL/QMB8GA1UdIwQYMBaAFBPPS6e7iS6z
26OFcXdsabrWhb5e0XMAwGA1UdEwEB/wQCMAAwDgYDVR0PAQH/BAQDAgXgMCAGA1Ud
27EQQZMBeBFXNtaW1lcnNhMUBvcGVuc3NsLm9yZzANBgkqhkiG9w0BAQUFAAOBgQAi
28O3GOkUl646oLnOimc36i9wxZ1tejsqs8vMjJ0Pym6Uq9FE2JoGzJ6OhB1GOsEVmj
299cQ5UNQcRYL3cqOFtl6f4Dpu/lhzfbaqgmLjv29G1mS0uuTZrixhlyCXjwcbOkNC
30I/+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-----
2MIICWwIBAAKBgQCwBfryW4Vu5U9wNIDKspJO/N9YF4CcTlrCUyzVlKgb+8urHlSe
359i5verR9IOCCXkemjOzZ/3nALTGqYZlnEvHp0Rjk+KdKXnKBIB+SRPpeu3LcXMT
4WPgsThPa0UQxedNKG0g6aG+kLhsDlFBCoxd09jJtSpb9jmroJOq0ZYEHLwIDAQAB
5AoGAKa/w4677Je1W5+r3SYoLDnvi5TkDs4D3C6ipKJgBTEdQz+DqB4w/DpZE4551
6+rkFn1LDxcxuHGRVa+tAMhZW97fwq9YUbjVZEyOz79qrX+BMyl/NbHkf1lIKDo3q
7dWalzQvop7nbzeLC+VmmviwZfLQUbA61AQl3jm4dswT4XykCQQDloDadEv/28NTx
8bvvywvyGuvJkCkEIycm4JrIInvwsd76h/chZ3oymrqzc7hkEtK6kThqlS5y+WXl6
9QzPruTKTAkEAxD2ro/VUoN+scIVaLmn0RBmZ67+9Pdn6pNSfjlK3s0T0EM6/iUWS
10M06l6L9wFS3/ceu1tIifsh9BeqOGTa+udQJARIFnybTBaIqw/NZ/lA1YCVn8tpvY
11iyaoZ6gjtS65TQrsdKeh/i3HCHNUXxUpoZ3F/H7QtD+6o49ODou+EbVOwQJAVmex
12A2gp8wuJKaINqxIL81AybZLnCCzKJ3lXJ5tUNyLNM/lUbGStktm2Q1zHRQwTxV07
13jFn7trn8YrtNjzcjYQJAUKIJRt38A8Jw3HoPT+D0WS2IgxjVL0eYGsZX1lyeammG
146rfnQ3u5uP7mEK2EH2o8mDUpAE0gclWBU9UkKxJsGA==
15-----END RSA PRIVATE KEY-----
16-----BEGIN CERTIFICATE-----
17MIICizCCAfSgAwIBAgIJAMtotfHYdEsUMA0GCSqGSIb3DQEBBQUAMEQxCzAJBgNV
18BAYTAlVLMRYwFAYDVQQKEw1PcGVuU1NMIEdyb3VwMR0wGwYDVQQDExRUZXN0IFMv
19TUlNRSBSU0EgUm9vdDAeFw0wODAyMjIxMzUzMDhaFw0xNjA1MTAxMzUzMDhaMEUx
20CzAJBgNVBAYTAlVLMRYwFAYDVQQKDA1PcGVuU1NMIEdyb3VwMR4wHAYDVQQDDBVU
21ZXN0IFMvTUlNRSBFRSBSU0EgIzIwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGB
22ALAF+vJbhW7lT3A0gMqykk7831gXgJxOWsJTLNWUqBv7y6seVJ7n2Lm96tH0g4IJ
23eR6aM7Nn/ecAtMaphmWcS8enRGOT4p0pecoEgH5JE+l67ctxcxNY+CxOE9rRRDF5
2400obSDpob6QuGwOUUEKjF3T2Mm1Klv2Oaugk6rRlgQcvAgMBAAGjgYMwgYAwHQYD
25VR0OBBYEFIL/u+mEvaw7RuKLRuElfVkxSQjYMB8GA1UdIwQYMBaAFBPPS6e7iS6z
26OFcXdsabrWhb5e0XMAwGA1UdEwEB/wQCMAAwDgYDVR0PAQH/BAQDAgXgMCAGA1Ud
27EQQZMBeBFXNtaW1lcnNhMkBvcGVuc3NsLm9yZzANBgkqhkiG9w0BAQUFAAOBgQC2
28rXR5bm/9RtOMQPleNpd3y6uUX3oy+0CafK5Yl3PMnItjjnKJ0l1/DbLbDj2twehe
29ewaB8CROcBCA3AMLSmGvPKgUCFMGtWam3328M4fBHzon5ka7qDXzM+imkAly/Yx2
30YNdR/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-----
2MIICXAIBAAKBgQC6syTZtZNe1hRScFc4PUVyVLsr7+C1HDIZnOHmwFoLayX6RHwy
3ep/TkdwiPHnemVLuwvpSjLMLZkXy/J764kSHJrNeVl3UvmCVCOm40hAtK1+F39pM
4h8phkbPPD7i+hwq4/Vs79o46nzwbVKmzgoZBJhZ+codujUSYM3LjJ4aq+wIDAQAB
5AoGAE1Zixrnr3bLGwBMqtYSDIOhtyos59whImCaLr17U9MHQWS+mvYO98if1aQZi
6iQ/QazJ+wvYXxWJ+dEB+JvYwqrGeuAU6He/rAb4OShG4FPVU2D19gzRnaButWMeT
7/1lgXV08hegGBL7RQNaN7b0viFYMcKnSghleMP0/q+Y/oaECQQDkXEwDYJW13X9p
8ijS20ykWdY5lLknjkHRhhOYux0rlhOqsyMZjoUmwI2m0qj9yrIysKhrk4MZaM/uC
9hy0xp3hdAkEA0Uv/UY0Kwsgc+W6YxeypECtg1qCE6FBib8n4iFy/6VcWqhvE5xrs
10OdhKv9/p6aLjLneGd1sU+F8eS9LGyKIbNwJBAJPgbNzXA7uUZriqZb5qeTXxBDfj
11RLfXSHYKAKEULxz3+JvRHB9SR4yHMiFrCdExiZrHXUkPgYLSHLGG5a4824UCQD6T
129XvhquUARkGCAuWy0/3Eqoihp/t6BWSdQ9Upviu7YUhtUxsyXo0REZB7F4pGrJx5
13GlhXgFaewgUzuUHFzlMCQCzJMMWslWpoLntnR6sMhBMhBFHSw+Y5CbxBmFrdtSkd
14VdtNO1VuDCTxjjW7W3Khj7LX4KZ1ye/5jfAgnnnXisc=
15-----END RSA PRIVATE KEY-----
16-----BEGIN CERTIFICATE-----
17MIICizCCAfSgAwIBAgIJAMtotfHYdEsVMA0GCSqGSIb3DQEBBQUAMEQxCzAJBgNV
18BAYTAlVLMRYwFAYDVQQKEw1PcGVuU1NMIEdyb3VwMR0wGwYDVQQDExRUZXN0IFMv
19TUlNRSBSU0EgUm9vdDAeFw0wODAyMjIxMzUzMDlaFw0xNjA1MTAxMzUzMDlaMEUx
20CzAJBgNVBAYTAlVLMRYwFAYDVQQKDA1PcGVuU1NMIEdyb3VwMR4wHAYDVQQDDBVU
21ZXN0IFMvTUlNRSBFRSBSU0EgIzMwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGB
22ALqzJNm1k17WFFJwVzg9RXJUuyvv4LUcMhmc4ebAWgtrJfpEfDJ6n9OR3CI8ed6Z
23Uu7C+lKMswtmRfL8nvriRIcms15WXdS+YJUI6bjSEC0rX4Xf2kyHymGRs88PuL6H
24Crj9Wzv2jjqfPBtUqbOChkEmFn5yh26NRJgzcuMnhqr7AgMBAAGjgYMwgYAwHQYD
25VR0OBBYEFDsSFjNtYZzd0tTHafNS7tneQQj6MB8GA1UdIwQYMBaAFBPPS6e7iS6z
26OFcXdsabrWhb5e0XMAwGA1UdEwEB/wQCMAAwDgYDVR0PAQH/BAQDAgXgMCAGA1Ud
27EQQZMBeBFXNtaW1lcnNhM0BvcGVuc3NsLm9yZzANBgkqhkiG9w0BAQUFAAOBgQBE
28tUDB+1Dqigu4p1xtdq7JRK6S+gfA7RWmhz0j2scb2zhpS12h37JLHsidGeKAzZYq
29jUjOrH/j3xcV5AnuJoqImJaN23nzzxtR4qGGX2mrq6EtObzdEGgCUaizsGM+0slJ
30PYxcy8KeY/63B1BpYhj2RjGkL6HrvuAaxVORa3acoA==
31-----END CERTIFICATE-----