diff options
author | cvs2svn <admin@example.com> | 2002-05-15 02:29:24 +0000 |
---|---|---|
committer | cvs2svn <admin@example.com> | 2002-05-15 02:29:24 +0000 |
commit | 027351f729b9e837200dae6e1520cda6577ab930 (patch) | |
tree | e25a717057aa4529e433fc3b1fac8d4df8db3a5c | |
parent | aeeae06a79815dc190061534d47236cec09f9e32 (diff) | |
download | openbsd-027351f729b9e837200dae6e1520cda6577ab930.tar.gz openbsd-027351f729b9e837200dae6e1520cda6577ab930.tar.bz2 openbsd-027351f729b9e837200dae6e1520cda6577ab930.zip |
This commit was manufactured by cvs2git to create branch 'unlabeled-1.1.1'.
Diffstat (limited to '')
299 files changed, 64443 insertions, 0 deletions
diff --git a/src/lib/libcrypto/aes/README b/src/lib/libcrypto/aes/README new file mode 100644 index 0000000000..0f9620a80e --- /dev/null +++ b/src/lib/libcrypto/aes/README | |||
@@ -0,0 +1,3 @@ | |||
1 | This is an OpenSSL-compatible version of AES (also called Rijndael). | ||
2 | aes_core.c is basically the same as rijndael-alg-fst.c but with an | ||
3 | API that looks like the rest of the OpenSSL symmetric cipher suite. | ||
diff --git a/src/lib/libcrypto/aes/aes.h b/src/lib/libcrypto/aes/aes.h new file mode 100644 index 0000000000..e8da921ec5 --- /dev/null +++ b/src/lib/libcrypto/aes/aes.h | |||
@@ -0,0 +1,109 @@ | |||
1 | /* crypto/aes/aes.h -*- mode:C; c-file-style: "eay" -*- */ | ||
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 | */ | ||
51 | |||
52 | #ifndef HEADER_AES_H | ||
53 | #define HEADER_AES_H | ||
54 | |||
55 | #ifdef OPENSSL_NO_AES | ||
56 | #error AES is disabled. | ||
57 | #endif | ||
58 | |||
59 | static const int AES_DECRYPT = 0; | ||
60 | static const int AES_ENCRYPT = 1; | ||
61 | /* Because array size can't be a const in C, the following two are macros. | ||
62 | Both sizes are in bytes. */ | ||
63 | #define AES_MAXNR 14 | ||
64 | #define AES_BLOCK_SIZE 16 | ||
65 | |||
66 | #ifdef __cplusplus | ||
67 | extern "C" { | ||
68 | #endif | ||
69 | |||
70 | /* This should be a hidden type, but EVP requires that the size be known */ | ||
71 | struct aes_key_st { | ||
72 | unsigned long rd_key[4 *(AES_MAXNR + 1)]; | ||
73 | int rounds; | ||
74 | }; | ||
75 | typedef struct aes_key_st AES_KEY; | ||
76 | |||
77 | const char *AES_options(void); | ||
78 | |||
79 | int AES_set_encrypt_key(const unsigned char *userKey, const int bits, | ||
80 | AES_KEY *key); | ||
81 | int AES_set_decrypt_key(const unsigned char *userKey, const int bits, | ||
82 | AES_KEY *key); | ||
83 | |||
84 | void AES_encrypt(const unsigned char *in, unsigned char *out, | ||
85 | const AES_KEY *key); | ||
86 | void AES_decrypt(const unsigned char *in, unsigned char *out, | ||
87 | const AES_KEY *key); | ||
88 | |||
89 | void AES_ecb_encrypt(const unsigned char *in, unsigned char *out, | ||
90 | const AES_KEY *key, const int enc); | ||
91 | void AES_cbc_encrypt(const unsigned char *in, unsigned char *out, | ||
92 | const unsigned long length, const AES_KEY *key, | ||
93 | unsigned char *ivec, const int enc); | ||
94 | void AES_cfb128_encrypt(const unsigned char *in, unsigned char *out, | ||
95 | const unsigned long length, const AES_KEY *key, | ||
96 | unsigned char *ivec, int *num, const int enc); | ||
97 | void AES_ofb128_encrypt(const unsigned char *in, unsigned char *out, | ||
98 | const unsigned long length, const AES_KEY *key, | ||
99 | unsigned char *ivec, int *num); | ||
100 | void AES_ctr128_encrypt(const unsigned char *in, unsigned char *out, | ||
101 | const unsigned long length, const AES_KEY *key, | ||
102 | unsigned char *counter, unsigned int *num); | ||
103 | |||
104 | |||
105 | #ifdef __cplusplus | ||
106 | } | ||
107 | #endif | ||
108 | |||
109 | #endif /* !HEADER_AES_H */ | ||
diff --git a/src/lib/libcrypto/aes/aes_cbc.c b/src/lib/libcrypto/aes/aes_cbc.c new file mode 100644 index 0000000000..3dfd7aba2a --- /dev/null +++ b/src/lib/libcrypto/aes/aes_cbc.c | |||
@@ -0,0 +1,89 @@ | |||
1 | /* crypto/aes/aes_cbc.c -*- mode:C; c-file-style: "eay" -*- */ | ||
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 | */ | ||
51 | |||
52 | #include <assert.h> | ||
53 | #include <openssl/aes.h> | ||
54 | #include "aes_locl.h" | ||
55 | |||
56 | void AES_cbc_encrypt(const unsigned char *in, unsigned char *out, | ||
57 | const unsigned long length, const AES_KEY *key, | ||
58 | unsigned char *ivec, const int enc) { | ||
59 | |||
60 | int n; | ||
61 | unsigned long len = length; | ||
62 | unsigned char tmp[16]; | ||
63 | |||
64 | assert(in && out && key && ivec); | ||
65 | assert(length % AES_BLOCK_SIZE == 0); | ||
66 | assert((AES_ENCRYPT == enc)||(AES_DECRYPT == enc)); | ||
67 | |||
68 | if (AES_ENCRYPT == enc) | ||
69 | while (len > 0) { | ||
70 | for(n=0; n < 16; ++n) | ||
71 | tmp[n] = in[n] ^ ivec[n]; | ||
72 | AES_encrypt(tmp, out, key); | ||
73 | memcpy(ivec, out, 16); | ||
74 | len -= 16; | ||
75 | in += 16; | ||
76 | out += 16; | ||
77 | } | ||
78 | else | ||
79 | while (len > 0) { | ||
80 | memcpy(tmp, in, 16); | ||
81 | AES_decrypt(in, out, key); | ||
82 | for(n=0; n < 16; ++n) | ||
83 | out[n] ^= ivec[n]; | ||
84 | memcpy(ivec, tmp, 16); | ||
85 | len -= 16; | ||
86 | in += 16; | ||
87 | out += 16; | ||
88 | } | ||
89 | } | ||
diff --git a/src/lib/libcrypto/aes/aes_cfb.c b/src/lib/libcrypto/aes/aes_cfb.c new file mode 100644 index 0000000000..9b2917298a --- /dev/null +++ b/src/lib/libcrypto/aes/aes_cfb.c | |||
@@ -0,0 +1,151 @@ | |||
1 | /* crypto/aes/aes_cfb.c -*- mode:C; c-file-style: "eay" -*- */ | ||
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 | */ | ||
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 | #include <assert.h> | ||
109 | #include <openssl/aes.h> | ||
110 | #include "aes_locl.h" | ||
111 | |||
112 | /* The input and output encrypted as though 128bit cfb mode is being | ||
113 | * used. The extra state information to record how much of the | ||
114 | * 128bit block we have used is contained in *num; | ||
115 | */ | ||
116 | |||
117 | void AES_cfb128_encrypt(const unsigned char *in, unsigned char *out, | ||
118 | const unsigned long length, const AES_KEY *key, | ||
119 | unsigned char *ivec, int *num, const int enc) { | ||
120 | |||
121 | unsigned int n; | ||
122 | unsigned long l = length; | ||
123 | unsigned char c; | ||
124 | |||
125 | assert(in && out && key && ivec && num); | ||
126 | |||
127 | n = *num; | ||
128 | |||
129 | if (enc) { | ||
130 | while (l--) { | ||
131 | if (n == 0) { | ||
132 | AES_encrypt(ivec, ivec, key); | ||
133 | } | ||
134 | ivec[n] = *(out++) = *(in++) ^ ivec[n]; | ||
135 | n = (n+1) % AES_BLOCK_SIZE; | ||
136 | } | ||
137 | } else { | ||
138 | while (l--) { | ||
139 | if (n == 0) { | ||
140 | AES_decrypt(ivec, ivec, key); | ||
141 | } | ||
142 | c = *(in); | ||
143 | *(out++) = *(in++) ^ ivec[n]; | ||
144 | ivec[n] = c; | ||
145 | n = (n+1) % AES_BLOCK_SIZE; | ||
146 | } | ||
147 | } | ||
148 | |||
149 | *num=n; | ||
150 | } | ||
151 | |||
diff --git a/src/lib/libcrypto/aes/aes_core.c b/src/lib/libcrypto/aes/aes_core.c new file mode 100644 index 0000000000..937988dd8c --- /dev/null +++ b/src/lib/libcrypto/aes/aes_core.c | |||
@@ -0,0 +1,1251 @@ | |||
1 | /* crypto/aes/aes_core.c -*- mode:C; c-file-style: "eay" -*- */ | ||
2 | /** | ||
3 | * rijndael-alg-fst.c | ||
4 | * | ||
5 | * @version 3.0 (December 2000) | ||
6 | * | ||
7 | * Optimised ANSI C code for the Rijndael cipher (now AES) | ||
8 | * | ||
9 | * @author Vincent Rijmen <vincent.rijmen@esat.kuleuven.ac.be> | ||
10 | * @author Antoon Bosselaers <antoon.bosselaers@esat.kuleuven.ac.be> | ||
11 | * @author Paulo Barreto <paulo.barreto@terra.com.br> | ||
12 | * | ||
13 | * This code is hereby placed in the public domain. | ||
14 | * | ||
15 | * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS | ||
16 | * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
17 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
18 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE | ||
19 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
20 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
21 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR | ||
22 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, | ||
23 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE | ||
24 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, | ||
25 | * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
26 | */ | ||
27 | |||
28 | /* Note: rewritten a little bit to provide error control and an OpenSSL- | ||
29 | compatible API */ | ||
30 | |||
31 | #include <assert.h> | ||
32 | #include <stdlib.h> | ||
33 | #include <openssl/aes.h> | ||
34 | #include "aes_locl.h" | ||
35 | |||
36 | /* | ||
37 | Te0[x] = S [x].[02, 01, 01, 03]; | ||
38 | Te1[x] = S [x].[03, 02, 01, 01]; | ||
39 | Te2[x] = S [x].[01, 03, 02, 01]; | ||
40 | Te3[x] = S [x].[01, 01, 03, 02]; | ||
41 | Te4[x] = S [x].[01, 01, 01, 01]; | ||
42 | |||
43 | Td0[x] = Si[x].[0e, 09, 0d, 0b]; | ||
44 | Td1[x] = Si[x].[0b, 0e, 09, 0d]; | ||
45 | Td2[x] = Si[x].[0d, 0b, 0e, 09]; | ||
46 | Td3[x] = Si[x].[09, 0d, 0b, 0e]; | ||
47 | Td4[x] = Si[x].[01, 01, 01, 01]; | ||
48 | */ | ||
49 | |||
50 | static const u32 Te0[256] = { | ||
51 | 0xc66363a5U, 0xf87c7c84U, 0xee777799U, 0xf67b7b8dU, | ||
52 | 0xfff2f20dU, 0xd66b6bbdU, 0xde6f6fb1U, 0x91c5c554U, | ||
53 | 0x60303050U, 0x02010103U, 0xce6767a9U, 0x562b2b7dU, | ||
54 | 0xe7fefe19U, 0xb5d7d762U, 0x4dababe6U, 0xec76769aU, | ||
55 | 0x8fcaca45U, 0x1f82829dU, 0x89c9c940U, 0xfa7d7d87U, | ||
56 | 0xeffafa15U, 0xb25959ebU, 0x8e4747c9U, 0xfbf0f00bU, | ||
57 | 0x41adadecU, 0xb3d4d467U, 0x5fa2a2fdU, 0x45afafeaU, | ||
58 | 0x239c9cbfU, 0x53a4a4f7U, 0xe4727296U, 0x9bc0c05bU, | ||
59 | 0x75b7b7c2U, 0xe1fdfd1cU, 0x3d9393aeU, 0x4c26266aU, | ||
60 | 0x6c36365aU, 0x7e3f3f41U, 0xf5f7f702U, 0x83cccc4fU, | ||
61 | 0x6834345cU, 0x51a5a5f4U, 0xd1e5e534U, 0xf9f1f108U, | ||
62 | 0xe2717193U, 0xabd8d873U, 0x62313153U, 0x2a15153fU, | ||
63 | 0x0804040cU, 0x95c7c752U, 0x46232365U, 0x9dc3c35eU, | ||
64 | 0x30181828U, 0x379696a1U, 0x0a05050fU, 0x2f9a9ab5U, | ||
65 | 0x0e070709U, 0x24121236U, 0x1b80809bU, 0xdfe2e23dU, | ||
66 | 0xcdebeb26U, 0x4e272769U, 0x7fb2b2cdU, 0xea75759fU, | ||
67 | 0x1209091bU, 0x1d83839eU, 0x582c2c74U, 0x341a1a2eU, | ||
68 | 0x361b1b2dU, 0xdc6e6eb2U, 0xb45a5aeeU, 0x5ba0a0fbU, | ||
69 | 0xa45252f6U, 0x763b3b4dU, 0xb7d6d661U, 0x7db3b3ceU, | ||
70 | 0x5229297bU, 0xdde3e33eU, 0x5e2f2f71U, 0x13848497U, | ||
71 | 0xa65353f5U, 0xb9d1d168U, 0x00000000U, 0xc1eded2cU, | ||
72 | 0x40202060U, 0xe3fcfc1fU, 0x79b1b1c8U, 0xb65b5bedU, | ||
73 | 0xd46a6abeU, 0x8dcbcb46U, 0x67bebed9U, 0x7239394bU, | ||
74 | 0x944a4adeU, 0x984c4cd4U, 0xb05858e8U, 0x85cfcf4aU, | ||
75 | 0xbbd0d06bU, 0xc5efef2aU, 0x4faaaae5U, 0xedfbfb16U, | ||
76 | 0x864343c5U, 0x9a4d4dd7U, 0x66333355U, 0x11858594U, | ||
77 | 0x8a4545cfU, 0xe9f9f910U, 0x04020206U, 0xfe7f7f81U, | ||
78 | 0xa05050f0U, 0x783c3c44U, 0x259f9fbaU, 0x4ba8a8e3U, | ||
79 | 0xa25151f3U, 0x5da3a3feU, 0x804040c0U, 0x058f8f8aU, | ||
80 | 0x3f9292adU, 0x219d9dbcU, 0x70383848U, 0xf1f5f504U, | ||
81 | 0x63bcbcdfU, 0x77b6b6c1U, 0xafdada75U, 0x42212163U, | ||
82 | 0x20101030U, 0xe5ffff1aU, 0xfdf3f30eU, 0xbfd2d26dU, | ||
83 | 0x81cdcd4cU, 0x180c0c14U, 0x26131335U, 0xc3ecec2fU, | ||
84 | 0xbe5f5fe1U, 0x359797a2U, 0x884444ccU, 0x2e171739U, | ||
85 | 0x93c4c457U, 0x55a7a7f2U, 0xfc7e7e82U, 0x7a3d3d47U, | ||
86 | 0xc86464acU, 0xba5d5de7U, 0x3219192bU, 0xe6737395U, | ||
87 | 0xc06060a0U, 0x19818198U, 0x9e4f4fd1U, 0xa3dcdc7fU, | ||
88 | 0x44222266U, 0x542a2a7eU, 0x3b9090abU, 0x0b888883U, | ||
89 | 0x8c4646caU, 0xc7eeee29U, 0x6bb8b8d3U, 0x2814143cU, | ||
90 | 0xa7dede79U, 0xbc5e5ee2U, 0x160b0b1dU, 0xaddbdb76U, | ||
91 | 0xdbe0e03bU, 0x64323256U, 0x743a3a4eU, 0x140a0a1eU, | ||
92 | 0x924949dbU, 0x0c06060aU, 0x4824246cU, 0xb85c5ce4U, | ||
93 | 0x9fc2c25dU, 0xbdd3d36eU, 0x43acacefU, 0xc46262a6U, | ||
94 | 0x399191a8U, 0x319595a4U, 0xd3e4e437U, 0xf279798bU, | ||
95 | 0xd5e7e732U, 0x8bc8c843U, 0x6e373759U, 0xda6d6db7U, | ||
96 | 0x018d8d8cU, 0xb1d5d564U, 0x9c4e4ed2U, 0x49a9a9e0U, | ||
97 | 0xd86c6cb4U, 0xac5656faU, 0xf3f4f407U, 0xcfeaea25U, | ||
98 | 0xca6565afU, 0xf47a7a8eU, 0x47aeaee9U, 0x10080818U, | ||
99 | 0x6fbabad5U, 0xf0787888U, 0x4a25256fU, 0x5c2e2e72U, | ||
100 | 0x381c1c24U, 0x57a6a6f1U, 0x73b4b4c7U, 0x97c6c651U, | ||
101 | 0xcbe8e823U, 0xa1dddd7cU, 0xe874749cU, 0x3e1f1f21U, | ||
102 | 0x964b4bddU, 0x61bdbddcU, 0x0d8b8b86U, 0x0f8a8a85U, | ||
103 | 0xe0707090U, 0x7c3e3e42U, 0x71b5b5c4U, 0xcc6666aaU, | ||
104 | 0x904848d8U, 0x06030305U, 0xf7f6f601U, 0x1c0e0e12U, | ||
105 | 0xc26161a3U, 0x6a35355fU, 0xae5757f9U, 0x69b9b9d0U, | ||
106 | 0x17868691U, 0x99c1c158U, 0x3a1d1d27U, 0x279e9eb9U, | ||
107 | 0xd9e1e138U, 0xebf8f813U, 0x2b9898b3U, 0x22111133U, | ||
108 | 0xd26969bbU, 0xa9d9d970U, 0x078e8e89U, 0x339494a7U, | ||
109 | 0x2d9b9bb6U, 0x3c1e1e22U, 0x15878792U, 0xc9e9e920U, | ||
110 | 0x87cece49U, 0xaa5555ffU, 0x50282878U, 0xa5dfdf7aU, | ||
111 | 0x038c8c8fU, 0x59a1a1f8U, 0x09898980U, 0x1a0d0d17U, | ||
112 | 0x65bfbfdaU, 0xd7e6e631U, 0x844242c6U, 0xd06868b8U, | ||
113 | 0x824141c3U, 0x299999b0U, 0x5a2d2d77U, 0x1e0f0f11U, | ||
114 | 0x7bb0b0cbU, 0xa85454fcU, 0x6dbbbbd6U, 0x2c16163aU, | ||
115 | }; | ||
116 | static const u32 Te1[256] = { | ||
117 | 0xa5c66363U, 0x84f87c7cU, 0x99ee7777U, 0x8df67b7bU, | ||
118 | 0x0dfff2f2U, 0xbdd66b6bU, 0xb1de6f6fU, 0x5491c5c5U, | ||
119 | 0x50603030U, 0x03020101U, 0xa9ce6767U, 0x7d562b2bU, | ||
120 | 0x19e7fefeU, 0x62b5d7d7U, 0xe64dababU, 0x9aec7676U, | ||
121 | 0x458fcacaU, 0x9d1f8282U, 0x4089c9c9U, 0x87fa7d7dU, | ||
122 | 0x15effafaU, 0xebb25959U, 0xc98e4747U, 0x0bfbf0f0U, | ||
123 | 0xec41adadU, 0x67b3d4d4U, 0xfd5fa2a2U, 0xea45afafU, | ||
124 | 0xbf239c9cU, 0xf753a4a4U, 0x96e47272U, 0x5b9bc0c0U, | ||
125 | 0xc275b7b7U, 0x1ce1fdfdU, 0xae3d9393U, 0x6a4c2626U, | ||
126 | 0x5a6c3636U, 0x417e3f3fU, 0x02f5f7f7U, 0x4f83ccccU, | ||
127 | 0x5c683434U, 0xf451a5a5U, 0x34d1e5e5U, 0x08f9f1f1U, | ||
128 | 0x93e27171U, 0x73abd8d8U, 0x53623131U, 0x3f2a1515U, | ||
129 | 0x0c080404U, 0x5295c7c7U, 0x65462323U, 0x5e9dc3c3U, | ||
130 | 0x28301818U, 0xa1379696U, 0x0f0a0505U, 0xb52f9a9aU, | ||
131 | 0x090e0707U, 0x36241212U, 0x9b1b8080U, 0x3ddfe2e2U, | ||
132 | 0x26cdebebU, 0x694e2727U, 0xcd7fb2b2U, 0x9fea7575U, | ||
133 | 0x1b120909U, 0x9e1d8383U, 0x74582c2cU, 0x2e341a1aU, | ||
134 | 0x2d361b1bU, 0xb2dc6e6eU, 0xeeb45a5aU, 0xfb5ba0a0U, | ||
135 | 0xf6a45252U, 0x4d763b3bU, 0x61b7d6d6U, 0xce7db3b3U, | ||
136 | 0x7b522929U, 0x3edde3e3U, 0x715e2f2fU, 0x97138484U, | ||
137 | 0xf5a65353U, 0x68b9d1d1U, 0x00000000U, 0x2cc1ededU, | ||
138 | 0x60402020U, 0x1fe3fcfcU, 0xc879b1b1U, 0xedb65b5bU, | ||
139 | 0xbed46a6aU, 0x468dcbcbU, 0xd967bebeU, 0x4b723939U, | ||
140 | 0xde944a4aU, 0xd4984c4cU, 0xe8b05858U, 0x4a85cfcfU, | ||
141 | 0x6bbbd0d0U, 0x2ac5efefU, 0xe54faaaaU, 0x16edfbfbU, | ||
142 | 0xc5864343U, 0xd79a4d4dU, 0x55663333U, 0x94118585U, | ||
143 | 0xcf8a4545U, 0x10e9f9f9U, 0x06040202U, 0x81fe7f7fU, | ||
144 | 0xf0a05050U, 0x44783c3cU, 0xba259f9fU, 0xe34ba8a8U, | ||
145 | 0xf3a25151U, 0xfe5da3a3U, 0xc0804040U, 0x8a058f8fU, | ||
146 | 0xad3f9292U, 0xbc219d9dU, 0x48703838U, 0x04f1f5f5U, | ||
147 | 0xdf63bcbcU, 0xc177b6b6U, 0x75afdadaU, 0x63422121U, | ||
148 | 0x30201010U, 0x1ae5ffffU, 0x0efdf3f3U, 0x6dbfd2d2U, | ||
149 | 0x4c81cdcdU, 0x14180c0cU, 0x35261313U, 0x2fc3ececU, | ||
150 | 0xe1be5f5fU, 0xa2359797U, 0xcc884444U, 0x392e1717U, | ||
151 | 0x5793c4c4U, 0xf255a7a7U, 0x82fc7e7eU, 0x477a3d3dU, | ||
152 | 0xacc86464U, 0xe7ba5d5dU, 0x2b321919U, 0x95e67373U, | ||
153 | 0xa0c06060U, 0x98198181U, 0xd19e4f4fU, 0x7fa3dcdcU, | ||
154 | 0x66442222U, 0x7e542a2aU, 0xab3b9090U, 0x830b8888U, | ||
155 | 0xca8c4646U, 0x29c7eeeeU, 0xd36bb8b8U, 0x3c281414U, | ||
156 | 0x79a7dedeU, 0xe2bc5e5eU, 0x1d160b0bU, 0x76addbdbU, | ||
157 | 0x3bdbe0e0U, 0x56643232U, 0x4e743a3aU, 0x1e140a0aU, | ||
158 | 0xdb924949U, 0x0a0c0606U, 0x6c482424U, 0xe4b85c5cU, | ||
159 | 0x5d9fc2c2U, 0x6ebdd3d3U, 0xef43acacU, 0xa6c46262U, | ||
160 | 0xa8399191U, 0xa4319595U, 0x37d3e4e4U, 0x8bf27979U, | ||
161 | 0x32d5e7e7U, 0x438bc8c8U, 0x596e3737U, 0xb7da6d6dU, | ||
162 | 0x8c018d8dU, 0x64b1d5d5U, 0xd29c4e4eU, 0xe049a9a9U, | ||
163 | 0xb4d86c6cU, 0xfaac5656U, 0x07f3f4f4U, 0x25cfeaeaU, | ||
164 | 0xafca6565U, 0x8ef47a7aU, 0xe947aeaeU, 0x18100808U, | ||
165 | 0xd56fbabaU, 0x88f07878U, 0x6f4a2525U, 0x725c2e2eU, | ||
166 | 0x24381c1cU, 0xf157a6a6U, 0xc773b4b4U, 0x5197c6c6U, | ||
167 | 0x23cbe8e8U, 0x7ca1ddddU, 0x9ce87474U, 0x213e1f1fU, | ||
168 | 0xdd964b4bU, 0xdc61bdbdU, 0x860d8b8bU, 0x850f8a8aU, | ||
169 | 0x90e07070U, 0x427c3e3eU, 0xc471b5b5U, 0xaacc6666U, | ||
170 | 0xd8904848U, 0x05060303U, 0x01f7f6f6U, 0x121c0e0eU, | ||
171 | 0xa3c26161U, 0x5f6a3535U, 0xf9ae5757U, 0xd069b9b9U, | ||
172 | 0x91178686U, 0x5899c1c1U, 0x273a1d1dU, 0xb9279e9eU, | ||
173 | 0x38d9e1e1U, 0x13ebf8f8U, 0xb32b9898U, 0x33221111U, | ||
174 | 0xbbd26969U, 0x70a9d9d9U, 0x89078e8eU, 0xa7339494U, | ||
175 | 0xb62d9b9bU, 0x223c1e1eU, 0x92158787U, 0x20c9e9e9U, | ||
176 | 0x4987ceceU, 0xffaa5555U, 0x78502828U, 0x7aa5dfdfU, | ||
177 | 0x8f038c8cU, 0xf859a1a1U, 0x80098989U, 0x171a0d0dU, | ||
178 | 0xda65bfbfU, 0x31d7e6e6U, 0xc6844242U, 0xb8d06868U, | ||
179 | 0xc3824141U, 0xb0299999U, 0x775a2d2dU, 0x111e0f0fU, | ||
180 | 0xcb7bb0b0U, 0xfca85454U, 0xd66dbbbbU, 0x3a2c1616U, | ||
181 | }; | ||
182 | static const u32 Te2[256] = { | ||
183 | 0x63a5c663U, 0x7c84f87cU, 0x7799ee77U, 0x7b8df67bU, | ||
184 | 0xf20dfff2U, 0x6bbdd66bU, 0x6fb1de6fU, 0xc55491c5U, | ||
185 | 0x30506030U, 0x01030201U, 0x67a9ce67U, 0x2b7d562bU, | ||
186 | 0xfe19e7feU, 0xd762b5d7U, 0xabe64dabU, 0x769aec76U, | ||
187 | 0xca458fcaU, 0x829d1f82U, 0xc94089c9U, 0x7d87fa7dU, | ||
188 | 0xfa15effaU, 0x59ebb259U, 0x47c98e47U, 0xf00bfbf0U, | ||
189 | 0xadec41adU, 0xd467b3d4U, 0xa2fd5fa2U, 0xafea45afU, | ||
190 | 0x9cbf239cU, 0xa4f753a4U, 0x7296e472U, 0xc05b9bc0U, | ||
191 | 0xb7c275b7U, 0xfd1ce1fdU, 0x93ae3d93U, 0x266a4c26U, | ||
192 | 0x365a6c36U, 0x3f417e3fU, 0xf702f5f7U, 0xcc4f83ccU, | ||
193 | 0x345c6834U, 0xa5f451a5U, 0xe534d1e5U, 0xf108f9f1U, | ||
194 | 0x7193e271U, 0xd873abd8U, 0x31536231U, 0x153f2a15U, | ||
195 | 0x040c0804U, 0xc75295c7U, 0x23654623U, 0xc35e9dc3U, | ||
196 | 0x18283018U, 0x96a13796U, 0x050f0a05U, 0x9ab52f9aU, | ||
197 | 0x07090e07U, 0x12362412U, 0x809b1b80U, 0xe23ddfe2U, | ||
198 | 0xeb26cdebU, 0x27694e27U, 0xb2cd7fb2U, 0x759fea75U, | ||
199 | 0x091b1209U, 0x839e1d83U, 0x2c74582cU, 0x1a2e341aU, | ||
200 | 0x1b2d361bU, 0x6eb2dc6eU, 0x5aeeb45aU, 0xa0fb5ba0U, | ||
201 | 0x52f6a452U, 0x3b4d763bU, 0xd661b7d6U, 0xb3ce7db3U, | ||
202 | 0x297b5229U, 0xe33edde3U, 0x2f715e2fU, 0x84971384U, | ||
203 | 0x53f5a653U, 0xd168b9d1U, 0x00000000U, 0xed2cc1edU, | ||
204 | 0x20604020U, 0xfc1fe3fcU, 0xb1c879b1U, 0x5bedb65bU, | ||
205 | 0x6abed46aU, 0xcb468dcbU, 0xbed967beU, 0x394b7239U, | ||
206 | 0x4ade944aU, 0x4cd4984cU, 0x58e8b058U, 0xcf4a85cfU, | ||
207 | 0xd06bbbd0U, 0xef2ac5efU, 0xaae54faaU, 0xfb16edfbU, | ||
208 | 0x43c58643U, 0x4dd79a4dU, 0x33556633U, 0x85941185U, | ||
209 | 0x45cf8a45U, 0xf910e9f9U, 0x02060402U, 0x7f81fe7fU, | ||
210 | 0x50f0a050U, 0x3c44783cU, 0x9fba259fU, 0xa8e34ba8U, | ||
211 | 0x51f3a251U, 0xa3fe5da3U, 0x40c08040U, 0x8f8a058fU, | ||
212 | 0x92ad3f92U, 0x9dbc219dU, 0x38487038U, 0xf504f1f5U, | ||
213 | 0xbcdf63bcU, 0xb6c177b6U, 0xda75afdaU, 0x21634221U, | ||
214 | 0x10302010U, 0xff1ae5ffU, 0xf30efdf3U, 0xd26dbfd2U, | ||
215 | 0xcd4c81cdU, 0x0c14180cU, 0x13352613U, 0xec2fc3ecU, | ||
216 | 0x5fe1be5fU, 0x97a23597U, 0x44cc8844U, 0x17392e17U, | ||
217 | 0xc45793c4U, 0xa7f255a7U, 0x7e82fc7eU, 0x3d477a3dU, | ||
218 | 0x64acc864U, 0x5de7ba5dU, 0x192b3219U, 0x7395e673U, | ||
219 | 0x60a0c060U, 0x81981981U, 0x4fd19e4fU, 0xdc7fa3dcU, | ||
220 | 0x22664422U, 0x2a7e542aU, 0x90ab3b90U, 0x88830b88U, | ||
221 | 0x46ca8c46U, 0xee29c7eeU, 0xb8d36bb8U, 0x143c2814U, | ||
222 | 0xde79a7deU, 0x5ee2bc5eU, 0x0b1d160bU, 0xdb76addbU, | ||
223 | 0xe03bdbe0U, 0x32566432U, 0x3a4e743aU, 0x0a1e140aU, | ||
224 | 0x49db9249U, 0x060a0c06U, 0x246c4824U, 0x5ce4b85cU, | ||
225 | 0xc25d9fc2U, 0xd36ebdd3U, 0xacef43acU, 0x62a6c462U, | ||
226 | 0x91a83991U, 0x95a43195U, 0xe437d3e4U, 0x798bf279U, | ||
227 | 0xe732d5e7U, 0xc8438bc8U, 0x37596e37U, 0x6db7da6dU, | ||
228 | 0x8d8c018dU, 0xd564b1d5U, 0x4ed29c4eU, 0xa9e049a9U, | ||
229 | 0x6cb4d86cU, 0x56faac56U, 0xf407f3f4U, 0xea25cfeaU, | ||
230 | 0x65afca65U, 0x7a8ef47aU, 0xaee947aeU, 0x08181008U, | ||
231 | 0xbad56fbaU, 0x7888f078U, 0x256f4a25U, 0x2e725c2eU, | ||
232 | 0x1c24381cU, 0xa6f157a6U, 0xb4c773b4U, 0xc65197c6U, | ||
233 | 0xe823cbe8U, 0xdd7ca1ddU, 0x749ce874U, 0x1f213e1fU, | ||
234 | 0x4bdd964bU, 0xbddc61bdU, 0x8b860d8bU, 0x8a850f8aU, | ||
235 | 0x7090e070U, 0x3e427c3eU, 0xb5c471b5U, 0x66aacc66U, | ||
236 | 0x48d89048U, 0x03050603U, 0xf601f7f6U, 0x0e121c0eU, | ||
237 | 0x61a3c261U, 0x355f6a35U, 0x57f9ae57U, 0xb9d069b9U, | ||
238 | 0x86911786U, 0xc15899c1U, 0x1d273a1dU, 0x9eb9279eU, | ||
239 | 0xe138d9e1U, 0xf813ebf8U, 0x98b32b98U, 0x11332211U, | ||
240 | 0x69bbd269U, 0xd970a9d9U, 0x8e89078eU, 0x94a73394U, | ||
241 | 0x9bb62d9bU, 0x1e223c1eU, 0x87921587U, 0xe920c9e9U, | ||
242 | 0xce4987ceU, 0x55ffaa55U, 0x28785028U, 0xdf7aa5dfU, | ||
243 | 0x8c8f038cU, 0xa1f859a1U, 0x89800989U, 0x0d171a0dU, | ||
244 | 0xbfda65bfU, 0xe631d7e6U, 0x42c68442U, 0x68b8d068U, | ||
245 | 0x41c38241U, 0x99b02999U, 0x2d775a2dU, 0x0f111e0fU, | ||
246 | 0xb0cb7bb0U, 0x54fca854U, 0xbbd66dbbU, 0x163a2c16U, | ||
247 | }; | ||
248 | static const u32 Te3[256] = { | ||
249 | |||
250 | 0x6363a5c6U, 0x7c7c84f8U, 0x777799eeU, 0x7b7b8df6U, | ||
251 | 0xf2f20dffU, 0x6b6bbdd6U, 0x6f6fb1deU, 0xc5c55491U, | ||
252 | 0x30305060U, 0x01010302U, 0x6767a9ceU, 0x2b2b7d56U, | ||
253 | 0xfefe19e7U, 0xd7d762b5U, 0xababe64dU, 0x76769aecU, | ||
254 | 0xcaca458fU, 0x82829d1fU, 0xc9c94089U, 0x7d7d87faU, | ||
255 | 0xfafa15efU, 0x5959ebb2U, 0x4747c98eU, 0xf0f00bfbU, | ||
256 | 0xadadec41U, 0xd4d467b3U, 0xa2a2fd5fU, 0xafafea45U, | ||
257 | 0x9c9cbf23U, 0xa4a4f753U, 0x727296e4U, 0xc0c05b9bU, | ||
258 | 0xb7b7c275U, 0xfdfd1ce1U, 0x9393ae3dU, 0x26266a4cU, | ||
259 | 0x36365a6cU, 0x3f3f417eU, 0xf7f702f5U, 0xcccc4f83U, | ||
260 | 0x34345c68U, 0xa5a5f451U, 0xe5e534d1U, 0xf1f108f9U, | ||
261 | 0x717193e2U, 0xd8d873abU, 0x31315362U, 0x15153f2aU, | ||
262 | 0x04040c08U, 0xc7c75295U, 0x23236546U, 0xc3c35e9dU, | ||
263 | 0x18182830U, 0x9696a137U, 0x05050f0aU, 0x9a9ab52fU, | ||
264 | 0x0707090eU, 0x12123624U, 0x80809b1bU, 0xe2e23ddfU, | ||
265 | 0xebeb26cdU, 0x2727694eU, 0xb2b2cd7fU, 0x75759feaU, | ||
266 | 0x09091b12U, 0x83839e1dU, 0x2c2c7458U, 0x1a1a2e34U, | ||
267 | 0x1b1b2d36U, 0x6e6eb2dcU, 0x5a5aeeb4U, 0xa0a0fb5bU, | ||
268 | 0x5252f6a4U, 0x3b3b4d76U, 0xd6d661b7U, 0xb3b3ce7dU, | ||
269 | 0x29297b52U, 0xe3e33eddU, 0x2f2f715eU, 0x84849713U, | ||
270 | 0x5353f5a6U, 0xd1d168b9U, 0x00000000U, 0xeded2cc1U, | ||
271 | 0x20206040U, 0xfcfc1fe3U, 0xb1b1c879U, 0x5b5bedb6U, | ||
272 | 0x6a6abed4U, 0xcbcb468dU, 0xbebed967U, 0x39394b72U, | ||
273 | 0x4a4ade94U, 0x4c4cd498U, 0x5858e8b0U, 0xcfcf4a85U, | ||
274 | 0xd0d06bbbU, 0xefef2ac5U, 0xaaaae54fU, 0xfbfb16edU, | ||
275 | 0x4343c586U, 0x4d4dd79aU, 0x33335566U, 0x85859411U, | ||
276 | 0x4545cf8aU, 0xf9f910e9U, 0x02020604U, 0x7f7f81feU, | ||
277 | 0x5050f0a0U, 0x3c3c4478U, 0x9f9fba25U, 0xa8a8e34bU, | ||
278 | 0x5151f3a2U, 0xa3a3fe5dU, 0x4040c080U, 0x8f8f8a05U, | ||
279 | 0x9292ad3fU, 0x9d9dbc21U, 0x38384870U, 0xf5f504f1U, | ||
280 | 0xbcbcdf63U, 0xb6b6c177U, 0xdada75afU, 0x21216342U, | ||
281 | 0x10103020U, 0xffff1ae5U, 0xf3f30efdU, 0xd2d26dbfU, | ||
282 | 0xcdcd4c81U, 0x0c0c1418U, 0x13133526U, 0xecec2fc3U, | ||
283 | 0x5f5fe1beU, 0x9797a235U, 0x4444cc88U, 0x1717392eU, | ||
284 | 0xc4c45793U, 0xa7a7f255U, 0x7e7e82fcU, 0x3d3d477aU, | ||
285 | 0x6464acc8U, 0x5d5de7baU, 0x19192b32U, 0x737395e6U, | ||
286 | 0x6060a0c0U, 0x81819819U, 0x4f4fd19eU, 0xdcdc7fa3U, | ||
287 | 0x22226644U, 0x2a2a7e54U, 0x9090ab3bU, 0x8888830bU, | ||
288 | 0x4646ca8cU, 0xeeee29c7U, 0xb8b8d36bU, 0x14143c28U, | ||
289 | 0xdede79a7U, 0x5e5ee2bcU, 0x0b0b1d16U, 0xdbdb76adU, | ||
290 | 0xe0e03bdbU, 0x32325664U, 0x3a3a4e74U, 0x0a0a1e14U, | ||
291 | 0x4949db92U, 0x06060a0cU, 0x24246c48U, 0x5c5ce4b8U, | ||
292 | 0xc2c25d9fU, 0xd3d36ebdU, 0xacacef43U, 0x6262a6c4U, | ||
293 | 0x9191a839U, 0x9595a431U, 0xe4e437d3U, 0x79798bf2U, | ||
294 | 0xe7e732d5U, 0xc8c8438bU, 0x3737596eU, 0x6d6db7daU, | ||
295 | 0x8d8d8c01U, 0xd5d564b1U, 0x4e4ed29cU, 0xa9a9e049U, | ||
296 | 0x6c6cb4d8U, 0x5656faacU, 0xf4f407f3U, 0xeaea25cfU, | ||
297 | 0x6565afcaU, 0x7a7a8ef4U, 0xaeaee947U, 0x08081810U, | ||
298 | 0xbabad56fU, 0x787888f0U, 0x25256f4aU, 0x2e2e725cU, | ||
299 | 0x1c1c2438U, 0xa6a6f157U, 0xb4b4c773U, 0xc6c65197U, | ||
300 | 0xe8e823cbU, 0xdddd7ca1U, 0x74749ce8U, 0x1f1f213eU, | ||
301 | 0x4b4bdd96U, 0xbdbddc61U, 0x8b8b860dU, 0x8a8a850fU, | ||
302 | 0x707090e0U, 0x3e3e427cU, 0xb5b5c471U, 0x6666aaccU, | ||
303 | 0x4848d890U, 0x03030506U, 0xf6f601f7U, 0x0e0e121cU, | ||
304 | 0x6161a3c2U, 0x35355f6aU, 0x5757f9aeU, 0xb9b9d069U, | ||
305 | 0x86869117U, 0xc1c15899U, 0x1d1d273aU, 0x9e9eb927U, | ||
306 | 0xe1e138d9U, 0xf8f813ebU, 0x9898b32bU, 0x11113322U, | ||
307 | 0x6969bbd2U, 0xd9d970a9U, 0x8e8e8907U, 0x9494a733U, | ||
308 | 0x9b9bb62dU, 0x1e1e223cU, 0x87879215U, 0xe9e920c9U, | ||
309 | 0xcece4987U, 0x5555ffaaU, 0x28287850U, 0xdfdf7aa5U, | ||
310 | 0x8c8c8f03U, 0xa1a1f859U, 0x89898009U, 0x0d0d171aU, | ||
311 | 0xbfbfda65U, 0xe6e631d7U, 0x4242c684U, 0x6868b8d0U, | ||
312 | 0x4141c382U, 0x9999b029U, 0x2d2d775aU, 0x0f0f111eU, | ||
313 | 0xb0b0cb7bU, 0x5454fca8U, 0xbbbbd66dU, 0x16163a2cU, | ||
314 | }; | ||
315 | static const u32 Te4[256] = { | ||
316 | 0x63636363U, 0x7c7c7c7cU, 0x77777777U, 0x7b7b7b7bU, | ||
317 | 0xf2f2f2f2U, 0x6b6b6b6bU, 0x6f6f6f6fU, 0xc5c5c5c5U, | ||
318 | 0x30303030U, 0x01010101U, 0x67676767U, 0x2b2b2b2bU, | ||
319 | 0xfefefefeU, 0xd7d7d7d7U, 0xababababU, 0x76767676U, | ||
320 | 0xcacacacaU, 0x82828282U, 0xc9c9c9c9U, 0x7d7d7d7dU, | ||
321 | 0xfafafafaU, 0x59595959U, 0x47474747U, 0xf0f0f0f0U, | ||
322 | 0xadadadadU, 0xd4d4d4d4U, 0xa2a2a2a2U, 0xafafafafU, | ||
323 | 0x9c9c9c9cU, 0xa4a4a4a4U, 0x72727272U, 0xc0c0c0c0U, | ||
324 | 0xb7b7b7b7U, 0xfdfdfdfdU, 0x93939393U, 0x26262626U, | ||
325 | 0x36363636U, 0x3f3f3f3fU, 0xf7f7f7f7U, 0xccccccccU, | ||
326 | 0x34343434U, 0xa5a5a5a5U, 0xe5e5e5e5U, 0xf1f1f1f1U, | ||
327 | 0x71717171U, 0xd8d8d8d8U, 0x31313131U, 0x15151515U, | ||
328 | 0x04040404U, 0xc7c7c7c7U, 0x23232323U, 0xc3c3c3c3U, | ||
329 | 0x18181818U, 0x96969696U, 0x05050505U, 0x9a9a9a9aU, | ||
330 | 0x07070707U, 0x12121212U, 0x80808080U, 0xe2e2e2e2U, | ||
331 | 0xebebebebU, 0x27272727U, 0xb2b2b2b2U, 0x75757575U, | ||
332 | 0x09090909U, 0x83838383U, 0x2c2c2c2cU, 0x1a1a1a1aU, | ||
333 | 0x1b1b1b1bU, 0x6e6e6e6eU, 0x5a5a5a5aU, 0xa0a0a0a0U, | ||
334 | 0x52525252U, 0x3b3b3b3bU, 0xd6d6d6d6U, 0xb3b3b3b3U, | ||
335 | 0x29292929U, 0xe3e3e3e3U, 0x2f2f2f2fU, 0x84848484U, | ||
336 | 0x53535353U, 0xd1d1d1d1U, 0x00000000U, 0xededededU, | ||
337 | 0x20202020U, 0xfcfcfcfcU, 0xb1b1b1b1U, 0x5b5b5b5bU, | ||
338 | 0x6a6a6a6aU, 0xcbcbcbcbU, 0xbebebebeU, 0x39393939U, | ||
339 | 0x4a4a4a4aU, 0x4c4c4c4cU, 0x58585858U, 0xcfcfcfcfU, | ||
340 | 0xd0d0d0d0U, 0xefefefefU, 0xaaaaaaaaU, 0xfbfbfbfbU, | ||
341 | 0x43434343U, 0x4d4d4d4dU, 0x33333333U, 0x85858585U, | ||
342 | 0x45454545U, 0xf9f9f9f9U, 0x02020202U, 0x7f7f7f7fU, | ||
343 | 0x50505050U, 0x3c3c3c3cU, 0x9f9f9f9fU, 0xa8a8a8a8U, | ||
344 | 0x51515151U, 0xa3a3a3a3U, 0x40404040U, 0x8f8f8f8fU, | ||
345 | 0x92929292U, 0x9d9d9d9dU, 0x38383838U, 0xf5f5f5f5U, | ||
346 | 0xbcbcbcbcU, 0xb6b6b6b6U, 0xdadadadaU, 0x21212121U, | ||
347 | 0x10101010U, 0xffffffffU, 0xf3f3f3f3U, 0xd2d2d2d2U, | ||
348 | 0xcdcdcdcdU, 0x0c0c0c0cU, 0x13131313U, 0xececececU, | ||
349 | 0x5f5f5f5fU, 0x97979797U, 0x44444444U, 0x17171717U, | ||
350 | 0xc4c4c4c4U, 0xa7a7a7a7U, 0x7e7e7e7eU, 0x3d3d3d3dU, | ||
351 | 0x64646464U, 0x5d5d5d5dU, 0x19191919U, 0x73737373U, | ||
352 | 0x60606060U, 0x81818181U, 0x4f4f4f4fU, 0xdcdcdcdcU, | ||
353 | 0x22222222U, 0x2a2a2a2aU, 0x90909090U, 0x88888888U, | ||
354 | 0x46464646U, 0xeeeeeeeeU, 0xb8b8b8b8U, 0x14141414U, | ||
355 | 0xdedededeU, 0x5e5e5e5eU, 0x0b0b0b0bU, 0xdbdbdbdbU, | ||
356 | 0xe0e0e0e0U, 0x32323232U, 0x3a3a3a3aU, 0x0a0a0a0aU, | ||
357 | 0x49494949U, 0x06060606U, 0x24242424U, 0x5c5c5c5cU, | ||
358 | 0xc2c2c2c2U, 0xd3d3d3d3U, 0xacacacacU, 0x62626262U, | ||
359 | 0x91919191U, 0x95959595U, 0xe4e4e4e4U, 0x79797979U, | ||
360 | 0xe7e7e7e7U, 0xc8c8c8c8U, 0x37373737U, 0x6d6d6d6dU, | ||
361 | 0x8d8d8d8dU, 0xd5d5d5d5U, 0x4e4e4e4eU, 0xa9a9a9a9U, | ||
362 | 0x6c6c6c6cU, 0x56565656U, 0xf4f4f4f4U, 0xeaeaeaeaU, | ||
363 | 0x65656565U, 0x7a7a7a7aU, 0xaeaeaeaeU, 0x08080808U, | ||
364 | 0xbabababaU, 0x78787878U, 0x25252525U, 0x2e2e2e2eU, | ||
365 | 0x1c1c1c1cU, 0xa6a6a6a6U, 0xb4b4b4b4U, 0xc6c6c6c6U, | ||
366 | 0xe8e8e8e8U, 0xddddddddU, 0x74747474U, 0x1f1f1f1fU, | ||
367 | 0x4b4b4b4bU, 0xbdbdbdbdU, 0x8b8b8b8bU, 0x8a8a8a8aU, | ||
368 | 0x70707070U, 0x3e3e3e3eU, 0xb5b5b5b5U, 0x66666666U, | ||
369 | 0x48484848U, 0x03030303U, 0xf6f6f6f6U, 0x0e0e0e0eU, | ||
370 | 0x61616161U, 0x35353535U, 0x57575757U, 0xb9b9b9b9U, | ||
371 | 0x86868686U, 0xc1c1c1c1U, 0x1d1d1d1dU, 0x9e9e9e9eU, | ||
372 | 0xe1e1e1e1U, 0xf8f8f8f8U, 0x98989898U, 0x11111111U, | ||
373 | 0x69696969U, 0xd9d9d9d9U, 0x8e8e8e8eU, 0x94949494U, | ||
374 | 0x9b9b9b9bU, 0x1e1e1e1eU, 0x87878787U, 0xe9e9e9e9U, | ||
375 | 0xcecececeU, 0x55555555U, 0x28282828U, 0xdfdfdfdfU, | ||
376 | 0x8c8c8c8cU, 0xa1a1a1a1U, 0x89898989U, 0x0d0d0d0dU, | ||
377 | 0xbfbfbfbfU, 0xe6e6e6e6U, 0x42424242U, 0x68686868U, | ||
378 | 0x41414141U, 0x99999999U, 0x2d2d2d2dU, 0x0f0f0f0fU, | ||
379 | 0xb0b0b0b0U, 0x54545454U, 0xbbbbbbbbU, 0x16161616U, | ||
380 | }; | ||
381 | static const u32 Td0[256] = { | ||
382 | 0x51f4a750U, 0x7e416553U, 0x1a17a4c3U, 0x3a275e96U, | ||
383 | 0x3bab6bcbU, 0x1f9d45f1U, 0xacfa58abU, 0x4be30393U, | ||
384 | 0x2030fa55U, 0xad766df6U, 0x88cc7691U, 0xf5024c25U, | ||
385 | 0x4fe5d7fcU, 0xc52acbd7U, 0x26354480U, 0xb562a38fU, | ||
386 | 0xdeb15a49U, 0x25ba1b67U, 0x45ea0e98U, 0x5dfec0e1U, | ||
387 | 0xc32f7502U, 0x814cf012U, 0x8d4697a3U, 0x6bd3f9c6U, | ||
388 | 0x038f5fe7U, 0x15929c95U, 0xbf6d7aebU, 0x955259daU, | ||
389 | 0xd4be832dU, 0x587421d3U, 0x49e06929U, 0x8ec9c844U, | ||
390 | 0x75c2896aU, 0xf48e7978U, 0x99583e6bU, 0x27b971ddU, | ||
391 | 0xbee14fb6U, 0xf088ad17U, 0xc920ac66U, 0x7dce3ab4U, | ||
392 | 0x63df4a18U, 0xe51a3182U, 0x97513360U, 0x62537f45U, | ||
393 | 0xb16477e0U, 0xbb6bae84U, 0xfe81a01cU, 0xf9082b94U, | ||
394 | 0x70486858U, 0x8f45fd19U, 0x94de6c87U, 0x527bf8b7U, | ||
395 | 0xab73d323U, 0x724b02e2U, 0xe31f8f57U, 0x6655ab2aU, | ||
396 | 0xb2eb2807U, 0x2fb5c203U, 0x86c57b9aU, 0xd33708a5U, | ||
397 | 0x302887f2U, 0x23bfa5b2U, 0x02036abaU, 0xed16825cU, | ||
398 | 0x8acf1c2bU, 0xa779b492U, 0xf307f2f0U, 0x4e69e2a1U, | ||
399 | 0x65daf4cdU, 0x0605bed5U, 0xd134621fU, 0xc4a6fe8aU, | ||
400 | 0x342e539dU, 0xa2f355a0U, 0x058ae132U, 0xa4f6eb75U, | ||
401 | 0x0b83ec39U, 0x4060efaaU, 0x5e719f06U, 0xbd6e1051U, | ||
402 | 0x3e218af9U, 0x96dd063dU, 0xdd3e05aeU, 0x4de6bd46U, | ||
403 | 0x91548db5U, 0x71c45d05U, 0x0406d46fU, 0x605015ffU, | ||
404 | 0x1998fb24U, 0xd6bde997U, 0x894043ccU, 0x67d99e77U, | ||
405 | 0xb0e842bdU, 0x07898b88U, 0xe7195b38U, 0x79c8eedbU, | ||
406 | 0xa17c0a47U, 0x7c420fe9U, 0xf8841ec9U, 0x00000000U, | ||
407 | 0x09808683U, 0x322bed48U, 0x1e1170acU, 0x6c5a724eU, | ||
408 | 0xfd0efffbU, 0x0f853856U, 0x3daed51eU, 0x362d3927U, | ||
409 | 0x0a0fd964U, 0x685ca621U, 0x9b5b54d1U, 0x24362e3aU, | ||
410 | 0x0c0a67b1U, 0x9357e70fU, 0xb4ee96d2U, 0x1b9b919eU, | ||
411 | 0x80c0c54fU, 0x61dc20a2U, 0x5a774b69U, 0x1c121a16U, | ||
412 | 0xe293ba0aU, 0xc0a02ae5U, 0x3c22e043U, 0x121b171dU, | ||
413 | 0x0e090d0bU, 0xf28bc7adU, 0x2db6a8b9U, 0x141ea9c8U, | ||
414 | 0x57f11985U, 0xaf75074cU, 0xee99ddbbU, 0xa37f60fdU, | ||
415 | 0xf701269fU, 0x5c72f5bcU, 0x44663bc5U, 0x5bfb7e34U, | ||
416 | 0x8b432976U, 0xcb23c6dcU, 0xb6edfc68U, 0xb8e4f163U, | ||
417 | 0xd731dccaU, 0x42638510U, 0x13972240U, 0x84c61120U, | ||
418 | 0x854a247dU, 0xd2bb3df8U, 0xaef93211U, 0xc729a16dU, | ||
419 | 0x1d9e2f4bU, 0xdcb230f3U, 0x0d8652ecU, 0x77c1e3d0U, | ||
420 | 0x2bb3166cU, 0xa970b999U, 0x119448faU, 0x47e96422U, | ||
421 | 0xa8fc8cc4U, 0xa0f03f1aU, 0x567d2cd8U, 0x223390efU, | ||
422 | 0x87494ec7U, 0xd938d1c1U, 0x8ccaa2feU, 0x98d40b36U, | ||
423 | 0xa6f581cfU, 0xa57ade28U, 0xdab78e26U, 0x3fadbfa4U, | ||
424 | 0x2c3a9de4U, 0x5078920dU, 0x6a5fcc9bU, 0x547e4662U, | ||
425 | 0xf68d13c2U, 0x90d8b8e8U, 0x2e39f75eU, 0x82c3aff5U, | ||
426 | 0x9f5d80beU, 0x69d0937cU, 0x6fd52da9U, 0xcf2512b3U, | ||
427 | 0xc8ac993bU, 0x10187da7U, 0xe89c636eU, 0xdb3bbb7bU, | ||
428 | 0xcd267809U, 0x6e5918f4U, 0xec9ab701U, 0x834f9aa8U, | ||
429 | 0xe6956e65U, 0xaaffe67eU, 0x21bccf08U, 0xef15e8e6U, | ||
430 | 0xbae79bd9U, 0x4a6f36ceU, 0xea9f09d4U, 0x29b07cd6U, | ||
431 | 0x31a4b2afU, 0x2a3f2331U, 0xc6a59430U, 0x35a266c0U, | ||
432 | 0x744ebc37U, 0xfc82caa6U, 0xe090d0b0U, 0x33a7d815U, | ||
433 | 0xf104984aU, 0x41ecdaf7U, 0x7fcd500eU, 0x1791f62fU, | ||
434 | 0x764dd68dU, 0x43efb04dU, 0xccaa4d54U, 0xe49604dfU, | ||
435 | 0x9ed1b5e3U, 0x4c6a881bU, 0xc12c1fb8U, 0x4665517fU, | ||
436 | 0x9d5eea04U, 0x018c355dU, 0xfa877473U, 0xfb0b412eU, | ||
437 | 0xb3671d5aU, 0x92dbd252U, 0xe9105633U, 0x6dd64713U, | ||
438 | 0x9ad7618cU, 0x37a10c7aU, 0x59f8148eU, 0xeb133c89U, | ||
439 | 0xcea927eeU, 0xb761c935U, 0xe11ce5edU, 0x7a47b13cU, | ||
440 | 0x9cd2df59U, 0x55f2733fU, 0x1814ce79U, 0x73c737bfU, | ||
441 | 0x53f7cdeaU, 0x5ffdaa5bU, 0xdf3d6f14U, 0x7844db86U, | ||
442 | 0xcaaff381U, 0xb968c43eU, 0x3824342cU, 0xc2a3405fU, | ||
443 | 0x161dc372U, 0xbce2250cU, 0x283c498bU, 0xff0d9541U, | ||
444 | 0x39a80171U, 0x080cb3deU, 0xd8b4e49cU, 0x6456c190U, | ||
445 | 0x7bcb8461U, 0xd532b670U, 0x486c5c74U, 0xd0b85742U, | ||
446 | }; | ||
447 | static const u32 Td1[256] = { | ||
448 | 0x5051f4a7U, 0x537e4165U, 0xc31a17a4U, 0x963a275eU, | ||
449 | 0xcb3bab6bU, 0xf11f9d45U, 0xabacfa58U, 0x934be303U, | ||
450 | 0x552030faU, 0xf6ad766dU, 0x9188cc76U, 0x25f5024cU, | ||
451 | 0xfc4fe5d7U, 0xd7c52acbU, 0x80263544U, 0x8fb562a3U, | ||
452 | 0x49deb15aU, 0x6725ba1bU, 0x9845ea0eU, 0xe15dfec0U, | ||
453 | 0x02c32f75U, 0x12814cf0U, 0xa38d4697U, 0xc66bd3f9U, | ||
454 | 0xe7038f5fU, 0x9515929cU, 0xebbf6d7aU, 0xda955259U, | ||
455 | 0x2dd4be83U, 0xd3587421U, 0x2949e069U, 0x448ec9c8U, | ||
456 | 0x6a75c289U, 0x78f48e79U, 0x6b99583eU, 0xdd27b971U, | ||
457 | 0xb6bee14fU, 0x17f088adU, 0x66c920acU, 0xb47dce3aU, | ||
458 | 0x1863df4aU, 0x82e51a31U, 0x60975133U, 0x4562537fU, | ||
459 | 0xe0b16477U, 0x84bb6baeU, 0x1cfe81a0U, 0x94f9082bU, | ||
460 | 0x58704868U, 0x198f45fdU, 0x8794de6cU, 0xb7527bf8U, | ||
461 | 0x23ab73d3U, 0xe2724b02U, 0x57e31f8fU, 0x2a6655abU, | ||
462 | 0x07b2eb28U, 0x032fb5c2U, 0x9a86c57bU, 0xa5d33708U, | ||
463 | 0xf2302887U, 0xb223bfa5U, 0xba02036aU, 0x5ced1682U, | ||
464 | 0x2b8acf1cU, 0x92a779b4U, 0xf0f307f2U, 0xa14e69e2U, | ||
465 | 0xcd65daf4U, 0xd50605beU, 0x1fd13462U, 0x8ac4a6feU, | ||
466 | 0x9d342e53U, 0xa0a2f355U, 0x32058ae1U, 0x75a4f6ebU, | ||
467 | 0x390b83ecU, 0xaa4060efU, 0x065e719fU, 0x51bd6e10U, | ||
468 | 0xf93e218aU, 0x3d96dd06U, 0xaedd3e05U, 0x464de6bdU, | ||
469 | 0xb591548dU, 0x0571c45dU, 0x6f0406d4U, 0xff605015U, | ||
470 | 0x241998fbU, 0x97d6bde9U, 0xcc894043U, 0x7767d99eU, | ||
471 | 0xbdb0e842U, 0x8807898bU, 0x38e7195bU, 0xdb79c8eeU, | ||
472 | 0x47a17c0aU, 0xe97c420fU, 0xc9f8841eU, 0x00000000U, | ||
473 | 0x83098086U, 0x48322bedU, 0xac1e1170U, 0x4e6c5a72U, | ||
474 | 0xfbfd0effU, 0x560f8538U, 0x1e3daed5U, 0x27362d39U, | ||
475 | 0x640a0fd9U, 0x21685ca6U, 0xd19b5b54U, 0x3a24362eU, | ||
476 | 0xb10c0a67U, 0x0f9357e7U, 0xd2b4ee96U, 0x9e1b9b91U, | ||
477 | 0x4f80c0c5U, 0xa261dc20U, 0x695a774bU, 0x161c121aU, | ||
478 | 0x0ae293baU, 0xe5c0a02aU, 0x433c22e0U, 0x1d121b17U, | ||
479 | 0x0b0e090dU, 0xadf28bc7U, 0xb92db6a8U, 0xc8141ea9U, | ||
480 | 0x8557f119U, 0x4caf7507U, 0xbbee99ddU, 0xfda37f60U, | ||
481 | 0x9ff70126U, 0xbc5c72f5U, 0xc544663bU, 0x345bfb7eU, | ||
482 | 0x768b4329U, 0xdccb23c6U, 0x68b6edfcU, 0x63b8e4f1U, | ||
483 | 0xcad731dcU, 0x10426385U, 0x40139722U, 0x2084c611U, | ||
484 | 0x7d854a24U, 0xf8d2bb3dU, 0x11aef932U, 0x6dc729a1U, | ||
485 | 0x4b1d9e2fU, 0xf3dcb230U, 0xec0d8652U, 0xd077c1e3U, | ||
486 | 0x6c2bb316U, 0x99a970b9U, 0xfa119448U, 0x2247e964U, | ||
487 | 0xc4a8fc8cU, 0x1aa0f03fU, 0xd8567d2cU, 0xef223390U, | ||
488 | 0xc787494eU, 0xc1d938d1U, 0xfe8ccaa2U, 0x3698d40bU, | ||
489 | 0xcfa6f581U, 0x28a57adeU, 0x26dab78eU, 0xa43fadbfU, | ||
490 | 0xe42c3a9dU, 0x0d507892U, 0x9b6a5fccU, 0x62547e46U, | ||
491 | 0xc2f68d13U, 0xe890d8b8U, 0x5e2e39f7U, 0xf582c3afU, | ||
492 | 0xbe9f5d80U, 0x7c69d093U, 0xa96fd52dU, 0xb3cf2512U, | ||
493 | 0x3bc8ac99U, 0xa710187dU, 0x6ee89c63U, 0x7bdb3bbbU, | ||
494 | 0x09cd2678U, 0xf46e5918U, 0x01ec9ab7U, 0xa8834f9aU, | ||
495 | 0x65e6956eU, 0x7eaaffe6U, 0x0821bccfU, 0xe6ef15e8U, | ||
496 | 0xd9bae79bU, 0xce4a6f36U, 0xd4ea9f09U, 0xd629b07cU, | ||
497 | 0xaf31a4b2U, 0x312a3f23U, 0x30c6a594U, 0xc035a266U, | ||
498 | 0x37744ebcU, 0xa6fc82caU, 0xb0e090d0U, 0x1533a7d8U, | ||
499 | 0x4af10498U, 0xf741ecdaU, 0x0e7fcd50U, 0x2f1791f6U, | ||
500 | 0x8d764dd6U, 0x4d43efb0U, 0x54ccaa4dU, 0xdfe49604U, | ||
501 | 0xe39ed1b5U, 0x1b4c6a88U, 0xb8c12c1fU, 0x7f466551U, | ||
502 | 0x049d5eeaU, 0x5d018c35U, 0x73fa8774U, 0x2efb0b41U, | ||
503 | 0x5ab3671dU, 0x5292dbd2U, 0x33e91056U, 0x136dd647U, | ||
504 | 0x8c9ad761U, 0x7a37a10cU, 0x8e59f814U, 0x89eb133cU, | ||
505 | 0xeecea927U, 0x35b761c9U, 0xede11ce5U, 0x3c7a47b1U, | ||
506 | 0x599cd2dfU, 0x3f55f273U, 0x791814ceU, 0xbf73c737U, | ||
507 | 0xea53f7cdU, 0x5b5ffdaaU, 0x14df3d6fU, 0x867844dbU, | ||
508 | 0x81caaff3U, 0x3eb968c4U, 0x2c382434U, 0x5fc2a340U, | ||
509 | 0x72161dc3U, 0x0cbce225U, 0x8b283c49U, 0x41ff0d95U, | ||
510 | 0x7139a801U, 0xde080cb3U, 0x9cd8b4e4U, 0x906456c1U, | ||
511 | 0x617bcb84U, 0x70d532b6U, 0x74486c5cU, 0x42d0b857U, | ||
512 | }; | ||
513 | static const u32 Td2[256] = { | ||
514 | 0xa75051f4U, 0x65537e41U, 0xa4c31a17U, 0x5e963a27U, | ||
515 | 0x6bcb3babU, 0x45f11f9dU, 0x58abacfaU, 0x03934be3U, | ||
516 | 0xfa552030U, 0x6df6ad76U, 0x769188ccU, 0x4c25f502U, | ||
517 | 0xd7fc4fe5U, 0xcbd7c52aU, 0x44802635U, 0xa38fb562U, | ||
518 | 0x5a49deb1U, 0x1b6725baU, 0x0e9845eaU, 0xc0e15dfeU, | ||
519 | 0x7502c32fU, 0xf012814cU, 0x97a38d46U, 0xf9c66bd3U, | ||
520 | 0x5fe7038fU, 0x9c951592U, 0x7aebbf6dU, 0x59da9552U, | ||
521 | 0x832dd4beU, 0x21d35874U, 0x692949e0U, 0xc8448ec9U, | ||
522 | 0x896a75c2U, 0x7978f48eU, 0x3e6b9958U, 0x71dd27b9U, | ||
523 | 0x4fb6bee1U, 0xad17f088U, 0xac66c920U, 0x3ab47dceU, | ||
524 | 0x4a1863dfU, 0x3182e51aU, 0x33609751U, 0x7f456253U, | ||
525 | 0x77e0b164U, 0xae84bb6bU, 0xa01cfe81U, 0x2b94f908U, | ||
526 | 0x68587048U, 0xfd198f45U, 0x6c8794deU, 0xf8b7527bU, | ||
527 | 0xd323ab73U, 0x02e2724bU, 0x8f57e31fU, 0xab2a6655U, | ||
528 | 0x2807b2ebU, 0xc2032fb5U, 0x7b9a86c5U, 0x08a5d337U, | ||
529 | 0x87f23028U, 0xa5b223bfU, 0x6aba0203U, 0x825ced16U, | ||
530 | 0x1c2b8acfU, 0xb492a779U, 0xf2f0f307U, 0xe2a14e69U, | ||
531 | 0xf4cd65daU, 0xbed50605U, 0x621fd134U, 0xfe8ac4a6U, | ||
532 | 0x539d342eU, 0x55a0a2f3U, 0xe132058aU, 0xeb75a4f6U, | ||
533 | 0xec390b83U, 0xefaa4060U, 0x9f065e71U, 0x1051bd6eU, | ||
534 | |||
535 | 0x8af93e21U, 0x063d96ddU, 0x05aedd3eU, 0xbd464de6U, | ||
536 | 0x8db59154U, 0x5d0571c4U, 0xd46f0406U, 0x15ff6050U, | ||
537 | 0xfb241998U, 0xe997d6bdU, 0x43cc8940U, 0x9e7767d9U, | ||
538 | 0x42bdb0e8U, 0x8b880789U, 0x5b38e719U, 0xeedb79c8U, | ||
539 | 0x0a47a17cU, 0x0fe97c42U, 0x1ec9f884U, 0x00000000U, | ||
540 | 0x86830980U, 0xed48322bU, 0x70ac1e11U, 0x724e6c5aU, | ||
541 | 0xfffbfd0eU, 0x38560f85U, 0xd51e3daeU, 0x3927362dU, | ||
542 | 0xd9640a0fU, 0xa621685cU, 0x54d19b5bU, 0x2e3a2436U, | ||
543 | 0x67b10c0aU, 0xe70f9357U, 0x96d2b4eeU, 0x919e1b9bU, | ||
544 | 0xc54f80c0U, 0x20a261dcU, 0x4b695a77U, 0x1a161c12U, | ||
545 | 0xba0ae293U, 0x2ae5c0a0U, 0xe0433c22U, 0x171d121bU, | ||
546 | 0x0d0b0e09U, 0xc7adf28bU, 0xa8b92db6U, 0xa9c8141eU, | ||
547 | 0x198557f1U, 0x074caf75U, 0xddbbee99U, 0x60fda37fU, | ||
548 | 0x269ff701U, 0xf5bc5c72U, 0x3bc54466U, 0x7e345bfbU, | ||
549 | 0x29768b43U, 0xc6dccb23U, 0xfc68b6edU, 0xf163b8e4U, | ||
550 | 0xdccad731U, 0x85104263U, 0x22401397U, 0x112084c6U, | ||
551 | 0x247d854aU, 0x3df8d2bbU, 0x3211aef9U, 0xa16dc729U, | ||
552 | 0x2f4b1d9eU, 0x30f3dcb2U, 0x52ec0d86U, 0xe3d077c1U, | ||
553 | 0x166c2bb3U, 0xb999a970U, 0x48fa1194U, 0x642247e9U, | ||
554 | 0x8cc4a8fcU, 0x3f1aa0f0U, 0x2cd8567dU, 0x90ef2233U, | ||
555 | 0x4ec78749U, 0xd1c1d938U, 0xa2fe8ccaU, 0x0b3698d4U, | ||
556 | 0x81cfa6f5U, 0xde28a57aU, 0x8e26dab7U, 0xbfa43fadU, | ||
557 | 0x9de42c3aU, 0x920d5078U, 0xcc9b6a5fU, 0x4662547eU, | ||
558 | 0x13c2f68dU, 0xb8e890d8U, 0xf75e2e39U, 0xaff582c3U, | ||
559 | 0x80be9f5dU, 0x937c69d0U, 0x2da96fd5U, 0x12b3cf25U, | ||
560 | 0x993bc8acU, 0x7da71018U, 0x636ee89cU, 0xbb7bdb3bU, | ||
561 | 0x7809cd26U, 0x18f46e59U, 0xb701ec9aU, 0x9aa8834fU, | ||
562 | 0x6e65e695U, 0xe67eaaffU, 0xcf0821bcU, 0xe8e6ef15U, | ||
563 | 0x9bd9bae7U, 0x36ce4a6fU, 0x09d4ea9fU, 0x7cd629b0U, | ||
564 | 0xb2af31a4U, 0x23312a3fU, 0x9430c6a5U, 0x66c035a2U, | ||
565 | 0xbc37744eU, 0xcaa6fc82U, 0xd0b0e090U, 0xd81533a7U, | ||
566 | 0x984af104U, 0xdaf741ecU, 0x500e7fcdU, 0xf62f1791U, | ||
567 | 0xd68d764dU, 0xb04d43efU, 0x4d54ccaaU, 0x04dfe496U, | ||
568 | 0xb5e39ed1U, 0x881b4c6aU, 0x1fb8c12cU, 0x517f4665U, | ||
569 | 0xea049d5eU, 0x355d018cU, 0x7473fa87U, 0x412efb0bU, | ||
570 | 0x1d5ab367U, 0xd25292dbU, 0x5633e910U, 0x47136dd6U, | ||
571 | 0x618c9ad7U, 0x0c7a37a1U, 0x148e59f8U, 0x3c89eb13U, | ||
572 | 0x27eecea9U, 0xc935b761U, 0xe5ede11cU, 0xb13c7a47U, | ||
573 | 0xdf599cd2U, 0x733f55f2U, 0xce791814U, 0x37bf73c7U, | ||
574 | 0xcdea53f7U, 0xaa5b5ffdU, 0x6f14df3dU, 0xdb867844U, | ||
575 | 0xf381caafU, 0xc43eb968U, 0x342c3824U, 0x405fc2a3U, | ||
576 | 0xc372161dU, 0x250cbce2U, 0x498b283cU, 0x9541ff0dU, | ||
577 | 0x017139a8U, 0xb3de080cU, 0xe49cd8b4U, 0xc1906456U, | ||
578 | 0x84617bcbU, 0xb670d532U, 0x5c74486cU, 0x5742d0b8U, | ||
579 | }; | ||
580 | static const u32 Td3[256] = { | ||
581 | 0xf4a75051U, 0x4165537eU, 0x17a4c31aU, 0x275e963aU, | ||
582 | 0xab6bcb3bU, 0x9d45f11fU, 0xfa58abacU, 0xe303934bU, | ||
583 | 0x30fa5520U, 0x766df6adU, 0xcc769188U, 0x024c25f5U, | ||
584 | 0xe5d7fc4fU, 0x2acbd7c5U, 0x35448026U, 0x62a38fb5U, | ||
585 | 0xb15a49deU, 0xba1b6725U, 0xea0e9845U, 0xfec0e15dU, | ||
586 | 0x2f7502c3U, 0x4cf01281U, 0x4697a38dU, 0xd3f9c66bU, | ||
587 | 0x8f5fe703U, 0x929c9515U, 0x6d7aebbfU, 0x5259da95U, | ||
588 | 0xbe832dd4U, 0x7421d358U, 0xe0692949U, 0xc9c8448eU, | ||
589 | 0xc2896a75U, 0x8e7978f4U, 0x583e6b99U, 0xb971dd27U, | ||
590 | 0xe14fb6beU, 0x88ad17f0U, 0x20ac66c9U, 0xce3ab47dU, | ||
591 | 0xdf4a1863U, 0x1a3182e5U, 0x51336097U, 0x537f4562U, | ||
592 | 0x6477e0b1U, 0x6bae84bbU, 0x81a01cfeU, 0x082b94f9U, | ||
593 | 0x48685870U, 0x45fd198fU, 0xde6c8794U, 0x7bf8b752U, | ||
594 | 0x73d323abU, 0x4b02e272U, 0x1f8f57e3U, 0x55ab2a66U, | ||
595 | 0xeb2807b2U, 0xb5c2032fU, 0xc57b9a86U, 0x3708a5d3U, | ||
596 | 0x2887f230U, 0xbfa5b223U, 0x036aba02U, 0x16825cedU, | ||
597 | 0xcf1c2b8aU, 0x79b492a7U, 0x07f2f0f3U, 0x69e2a14eU, | ||
598 | 0xdaf4cd65U, 0x05bed506U, 0x34621fd1U, 0xa6fe8ac4U, | ||
599 | 0x2e539d34U, 0xf355a0a2U, 0x8ae13205U, 0xf6eb75a4U, | ||
600 | 0x83ec390bU, 0x60efaa40U, 0x719f065eU, 0x6e1051bdU, | ||
601 | 0x218af93eU, 0xdd063d96U, 0x3e05aeddU, 0xe6bd464dU, | ||
602 | 0x548db591U, 0xc45d0571U, 0x06d46f04U, 0x5015ff60U, | ||
603 | 0x98fb2419U, 0xbde997d6U, 0x4043cc89U, 0xd99e7767U, | ||
604 | 0xe842bdb0U, 0x898b8807U, 0x195b38e7U, 0xc8eedb79U, | ||
605 | 0x7c0a47a1U, 0x420fe97cU, 0x841ec9f8U, 0x00000000U, | ||
606 | 0x80868309U, 0x2bed4832U, 0x1170ac1eU, 0x5a724e6cU, | ||
607 | 0x0efffbfdU, 0x8538560fU, 0xaed51e3dU, 0x2d392736U, | ||
608 | 0x0fd9640aU, 0x5ca62168U, 0x5b54d19bU, 0x362e3a24U, | ||
609 | 0x0a67b10cU, 0x57e70f93U, 0xee96d2b4U, 0x9b919e1bU, | ||
610 | 0xc0c54f80U, 0xdc20a261U, 0x774b695aU, 0x121a161cU, | ||
611 | 0x93ba0ae2U, 0xa02ae5c0U, 0x22e0433cU, 0x1b171d12U, | ||
612 | 0x090d0b0eU, 0x8bc7adf2U, 0xb6a8b92dU, 0x1ea9c814U, | ||
613 | 0xf1198557U, 0x75074cafU, 0x99ddbbeeU, 0x7f60fda3U, | ||
614 | 0x01269ff7U, 0x72f5bc5cU, 0x663bc544U, 0xfb7e345bU, | ||
615 | 0x4329768bU, 0x23c6dccbU, 0xedfc68b6U, 0xe4f163b8U, | ||
616 | 0x31dccad7U, 0x63851042U, 0x97224013U, 0xc6112084U, | ||
617 | 0x4a247d85U, 0xbb3df8d2U, 0xf93211aeU, 0x29a16dc7U, | ||
618 | 0x9e2f4b1dU, 0xb230f3dcU, 0x8652ec0dU, 0xc1e3d077U, | ||
619 | 0xb3166c2bU, 0x70b999a9U, 0x9448fa11U, 0xe9642247U, | ||
620 | 0xfc8cc4a8U, 0xf03f1aa0U, 0x7d2cd856U, 0x3390ef22U, | ||
621 | 0x494ec787U, 0x38d1c1d9U, 0xcaa2fe8cU, 0xd40b3698U, | ||
622 | 0xf581cfa6U, 0x7ade28a5U, 0xb78e26daU, 0xadbfa43fU, | ||
623 | 0x3a9de42cU, 0x78920d50U, 0x5fcc9b6aU, 0x7e466254U, | ||
624 | 0x8d13c2f6U, 0xd8b8e890U, 0x39f75e2eU, 0xc3aff582U, | ||
625 | 0x5d80be9fU, 0xd0937c69U, 0xd52da96fU, 0x2512b3cfU, | ||
626 | 0xac993bc8U, 0x187da710U, 0x9c636ee8U, 0x3bbb7bdbU, | ||
627 | 0x267809cdU, 0x5918f46eU, 0x9ab701ecU, 0x4f9aa883U, | ||
628 | 0x956e65e6U, 0xffe67eaaU, 0xbccf0821U, 0x15e8e6efU, | ||
629 | 0xe79bd9baU, 0x6f36ce4aU, 0x9f09d4eaU, 0xb07cd629U, | ||
630 | 0xa4b2af31U, 0x3f23312aU, 0xa59430c6U, 0xa266c035U, | ||
631 | 0x4ebc3774U, 0x82caa6fcU, 0x90d0b0e0U, 0xa7d81533U, | ||
632 | 0x04984af1U, 0xecdaf741U, 0xcd500e7fU, 0x91f62f17U, | ||
633 | 0x4dd68d76U, 0xefb04d43U, 0xaa4d54ccU, 0x9604dfe4U, | ||
634 | 0xd1b5e39eU, 0x6a881b4cU, 0x2c1fb8c1U, 0x65517f46U, | ||
635 | 0x5eea049dU, 0x8c355d01U, 0x877473faU, 0x0b412efbU, | ||
636 | 0x671d5ab3U, 0xdbd25292U, 0x105633e9U, 0xd647136dU, | ||
637 | 0xd7618c9aU, 0xa10c7a37U, 0xf8148e59U, 0x133c89ebU, | ||
638 | 0xa927eeceU, 0x61c935b7U, 0x1ce5ede1U, 0x47b13c7aU, | ||
639 | 0xd2df599cU, 0xf2733f55U, 0x14ce7918U, 0xc737bf73U, | ||
640 | 0xf7cdea53U, 0xfdaa5b5fU, 0x3d6f14dfU, 0x44db8678U, | ||
641 | 0xaff381caU, 0x68c43eb9U, 0x24342c38U, 0xa3405fc2U, | ||
642 | 0x1dc37216U, 0xe2250cbcU, 0x3c498b28U, 0x0d9541ffU, | ||
643 | 0xa8017139U, 0x0cb3de08U, 0xb4e49cd8U, 0x56c19064U, | ||
644 | 0xcb84617bU, 0x32b670d5U, 0x6c5c7448U, 0xb85742d0U, | ||
645 | }; | ||
646 | static const u32 Td4[256] = { | ||
647 | 0x52525252U, 0x09090909U, 0x6a6a6a6aU, 0xd5d5d5d5U, | ||
648 | 0x30303030U, 0x36363636U, 0xa5a5a5a5U, 0x38383838U, | ||
649 | 0xbfbfbfbfU, 0x40404040U, 0xa3a3a3a3U, 0x9e9e9e9eU, | ||
650 | 0x81818181U, 0xf3f3f3f3U, 0xd7d7d7d7U, 0xfbfbfbfbU, | ||
651 | 0x7c7c7c7cU, 0xe3e3e3e3U, 0x39393939U, 0x82828282U, | ||
652 | 0x9b9b9b9bU, 0x2f2f2f2fU, 0xffffffffU, 0x87878787U, | ||
653 | 0x34343434U, 0x8e8e8e8eU, 0x43434343U, 0x44444444U, | ||
654 | 0xc4c4c4c4U, 0xdedededeU, 0xe9e9e9e9U, 0xcbcbcbcbU, | ||
655 | 0x54545454U, 0x7b7b7b7bU, 0x94949494U, 0x32323232U, | ||
656 | 0xa6a6a6a6U, 0xc2c2c2c2U, 0x23232323U, 0x3d3d3d3dU, | ||
657 | 0xeeeeeeeeU, 0x4c4c4c4cU, 0x95959595U, 0x0b0b0b0bU, | ||
658 | 0x42424242U, 0xfafafafaU, 0xc3c3c3c3U, 0x4e4e4e4eU, | ||
659 | 0x08080808U, 0x2e2e2e2eU, 0xa1a1a1a1U, 0x66666666U, | ||
660 | 0x28282828U, 0xd9d9d9d9U, 0x24242424U, 0xb2b2b2b2U, | ||
661 | 0x76767676U, 0x5b5b5b5bU, 0xa2a2a2a2U, 0x49494949U, | ||
662 | 0x6d6d6d6dU, 0x8b8b8b8bU, 0xd1d1d1d1U, 0x25252525U, | ||
663 | 0x72727272U, 0xf8f8f8f8U, 0xf6f6f6f6U, 0x64646464U, | ||
664 | 0x86868686U, 0x68686868U, 0x98989898U, 0x16161616U, | ||
665 | 0xd4d4d4d4U, 0xa4a4a4a4U, 0x5c5c5c5cU, 0xccccccccU, | ||
666 | 0x5d5d5d5dU, 0x65656565U, 0xb6b6b6b6U, 0x92929292U, | ||
667 | 0x6c6c6c6cU, 0x70707070U, 0x48484848U, 0x50505050U, | ||
668 | 0xfdfdfdfdU, 0xededededU, 0xb9b9b9b9U, 0xdadadadaU, | ||
669 | 0x5e5e5e5eU, 0x15151515U, 0x46464646U, 0x57575757U, | ||
670 | 0xa7a7a7a7U, 0x8d8d8d8dU, 0x9d9d9d9dU, 0x84848484U, | ||
671 | 0x90909090U, 0xd8d8d8d8U, 0xababababU, 0x00000000U, | ||
672 | 0x8c8c8c8cU, 0xbcbcbcbcU, 0xd3d3d3d3U, 0x0a0a0a0aU, | ||
673 | 0xf7f7f7f7U, 0xe4e4e4e4U, 0x58585858U, 0x05050505U, | ||
674 | 0xb8b8b8b8U, 0xb3b3b3b3U, 0x45454545U, 0x06060606U, | ||
675 | 0xd0d0d0d0U, 0x2c2c2c2cU, 0x1e1e1e1eU, 0x8f8f8f8fU, | ||
676 | 0xcacacacaU, 0x3f3f3f3fU, 0x0f0f0f0fU, 0x02020202U, | ||
677 | 0xc1c1c1c1U, 0xafafafafU, 0xbdbdbdbdU, 0x03030303U, | ||
678 | 0x01010101U, 0x13131313U, 0x8a8a8a8aU, 0x6b6b6b6bU, | ||
679 | 0x3a3a3a3aU, 0x91919191U, 0x11111111U, 0x41414141U, | ||
680 | 0x4f4f4f4fU, 0x67676767U, 0xdcdcdcdcU, 0xeaeaeaeaU, | ||
681 | 0x97979797U, 0xf2f2f2f2U, 0xcfcfcfcfU, 0xcecececeU, | ||
682 | 0xf0f0f0f0U, 0xb4b4b4b4U, 0xe6e6e6e6U, 0x73737373U, | ||
683 | 0x96969696U, 0xacacacacU, 0x74747474U, 0x22222222U, | ||
684 | 0xe7e7e7e7U, 0xadadadadU, 0x35353535U, 0x85858585U, | ||
685 | 0xe2e2e2e2U, 0xf9f9f9f9U, 0x37373737U, 0xe8e8e8e8U, | ||
686 | 0x1c1c1c1cU, 0x75757575U, 0xdfdfdfdfU, 0x6e6e6e6eU, | ||
687 | 0x47474747U, 0xf1f1f1f1U, 0x1a1a1a1aU, 0x71717171U, | ||
688 | 0x1d1d1d1dU, 0x29292929U, 0xc5c5c5c5U, 0x89898989U, | ||
689 | 0x6f6f6f6fU, 0xb7b7b7b7U, 0x62626262U, 0x0e0e0e0eU, | ||
690 | 0xaaaaaaaaU, 0x18181818U, 0xbebebebeU, 0x1b1b1b1bU, | ||
691 | 0xfcfcfcfcU, 0x56565656U, 0x3e3e3e3eU, 0x4b4b4b4bU, | ||
692 | 0xc6c6c6c6U, 0xd2d2d2d2U, 0x79797979U, 0x20202020U, | ||
693 | 0x9a9a9a9aU, 0xdbdbdbdbU, 0xc0c0c0c0U, 0xfefefefeU, | ||
694 | 0x78787878U, 0xcdcdcdcdU, 0x5a5a5a5aU, 0xf4f4f4f4U, | ||
695 | 0x1f1f1f1fU, 0xddddddddU, 0xa8a8a8a8U, 0x33333333U, | ||
696 | 0x88888888U, 0x07070707U, 0xc7c7c7c7U, 0x31313131U, | ||
697 | 0xb1b1b1b1U, 0x12121212U, 0x10101010U, 0x59595959U, | ||
698 | 0x27272727U, 0x80808080U, 0xececececU, 0x5f5f5f5fU, | ||
699 | 0x60606060U, 0x51515151U, 0x7f7f7f7fU, 0xa9a9a9a9U, | ||
700 | 0x19191919U, 0xb5b5b5b5U, 0x4a4a4a4aU, 0x0d0d0d0dU, | ||
701 | 0x2d2d2d2dU, 0xe5e5e5e5U, 0x7a7a7a7aU, 0x9f9f9f9fU, | ||
702 | 0x93939393U, 0xc9c9c9c9U, 0x9c9c9c9cU, 0xefefefefU, | ||
703 | 0xa0a0a0a0U, 0xe0e0e0e0U, 0x3b3b3b3bU, 0x4d4d4d4dU, | ||
704 | 0xaeaeaeaeU, 0x2a2a2a2aU, 0xf5f5f5f5U, 0xb0b0b0b0U, | ||
705 | 0xc8c8c8c8U, 0xebebebebU, 0xbbbbbbbbU, 0x3c3c3c3cU, | ||
706 | 0x83838383U, 0x53535353U, 0x99999999U, 0x61616161U, | ||
707 | 0x17171717U, 0x2b2b2b2bU, 0x04040404U, 0x7e7e7e7eU, | ||
708 | 0xbabababaU, 0x77777777U, 0xd6d6d6d6U, 0x26262626U, | ||
709 | 0xe1e1e1e1U, 0x69696969U, 0x14141414U, 0x63636363U, | ||
710 | 0x55555555U, 0x21212121U, 0x0c0c0c0cU, 0x7d7d7d7dU, | ||
711 | }; | ||
712 | static const u32 rcon[] = { | ||
713 | 0x01000000, 0x02000000, 0x04000000, 0x08000000, | ||
714 | 0x10000000, 0x20000000, 0x40000000, 0x80000000, | ||
715 | 0x1B000000, 0x36000000, /* for 128-bit blocks, Rijndael never uses more than 10 rcon values */ | ||
716 | }; | ||
717 | |||
718 | /** | ||
719 | * Expand the cipher key into the encryption key schedule. | ||
720 | */ | ||
721 | int AES_set_encrypt_key(const unsigned char *userKey, const int bits, | ||
722 | AES_KEY *key) { | ||
723 | |||
724 | u32 *rk; | ||
725 | int i = 0; | ||
726 | u32 temp; | ||
727 | |||
728 | if (!userKey || !key) | ||
729 | return -1; | ||
730 | if (bits != 128 && bits != 192 && bits != 256) | ||
731 | return -2; | ||
732 | |||
733 | rk = key->rd_key; | ||
734 | |||
735 | if (bits==128) | ||
736 | key->rounds = 10; | ||
737 | else if (bits==192) | ||
738 | key->rounds = 12; | ||
739 | else | ||
740 | key->rounds = 14; | ||
741 | |||
742 | rk[0] = GETU32(userKey ); | ||
743 | rk[1] = GETU32(userKey + 4); | ||
744 | rk[2] = GETU32(userKey + 8); | ||
745 | rk[3] = GETU32(userKey + 12); | ||
746 | if (bits == 128) { | ||
747 | for (;;) { | ||
748 | temp = rk[3]; | ||
749 | rk[4] = rk[0] ^ | ||
750 | (Te4[(temp >> 16) & 0xff] & 0xff000000) ^ | ||
751 | (Te4[(temp >> 8) & 0xff] & 0x00ff0000) ^ | ||
752 | (Te4[(temp ) & 0xff] & 0x0000ff00) ^ | ||
753 | (Te4[(temp >> 24) ] & 0x000000ff) ^ | ||
754 | rcon[i]; | ||
755 | rk[5] = rk[1] ^ rk[4]; | ||
756 | rk[6] = rk[2] ^ rk[5]; | ||
757 | rk[7] = rk[3] ^ rk[6]; | ||
758 | if (++i == 10) { | ||
759 | return 0; | ||
760 | } | ||
761 | rk += 4; | ||
762 | } | ||
763 | } | ||
764 | rk[4] = GETU32(userKey + 16); | ||
765 | rk[5] = GETU32(userKey + 20); | ||
766 | if (bits == 192) { | ||
767 | for (;;) { | ||
768 | temp = rk[ 5]; | ||
769 | rk[ 6] = rk[ 0] ^ | ||
770 | (Te4[(temp >> 16) & 0xff] & 0xff000000) ^ | ||
771 | (Te4[(temp >> 8) & 0xff] & 0x00ff0000) ^ | ||
772 | (Te4[(temp ) & 0xff] & 0x0000ff00) ^ | ||
773 | (Te4[(temp >> 24) ] & 0x000000ff) ^ | ||
774 | rcon[i]; | ||
775 | rk[ 7] = rk[ 1] ^ rk[ 6]; | ||
776 | rk[ 8] = rk[ 2] ^ rk[ 7]; | ||
777 | rk[ 9] = rk[ 3] ^ rk[ 8]; | ||
778 | if (++i == 8) { | ||
779 | return 0; | ||
780 | } | ||
781 | rk[10] = rk[ 4] ^ rk[ 9]; | ||
782 | rk[11] = rk[ 5] ^ rk[10]; | ||
783 | rk += 6; | ||
784 | } | ||
785 | } | ||
786 | rk[6] = GETU32(userKey + 24); | ||
787 | rk[7] = GETU32(userKey + 28); | ||
788 | if (bits == 256) { | ||
789 | for (;;) { | ||
790 | temp = rk[ 7]; | ||
791 | rk[ 8] = rk[ 0] ^ | ||
792 | (Te4[(temp >> 16) & 0xff] & 0xff000000) ^ | ||
793 | (Te4[(temp >> 8) & 0xff] & 0x00ff0000) ^ | ||
794 | (Te4[(temp ) & 0xff] & 0x0000ff00) ^ | ||
795 | (Te4[(temp >> 24) ] & 0x000000ff) ^ | ||
796 | rcon[i]; | ||
797 | rk[ 9] = rk[ 1] ^ rk[ 8]; | ||
798 | rk[10] = rk[ 2] ^ rk[ 9]; | ||
799 | rk[11] = rk[ 3] ^ rk[10]; | ||
800 | if (++i == 7) { | ||
801 | return 0; | ||
802 | } | ||
803 | temp = rk[11]; | ||
804 | rk[12] = rk[ 4] ^ | ||
805 | (Te4[(temp >> 24) ] & 0xff000000) ^ | ||
806 | (Te4[(temp >> 16) & 0xff] & 0x00ff0000) ^ | ||
807 | (Te4[(temp >> 8) & 0xff] & 0x0000ff00) ^ | ||
808 | (Te4[(temp ) & 0xff] & 0x000000ff); | ||
809 | rk[13] = rk[ 5] ^ rk[12]; | ||
810 | rk[14] = rk[ 6] ^ rk[13]; | ||
811 | rk[15] = rk[ 7] ^ rk[14]; | ||
812 | |||
813 | rk += 8; | ||
814 | } | ||
815 | } | ||
816 | return 0; | ||
817 | } | ||
818 | |||
819 | /** | ||
820 | * Expand the cipher key into the decryption key schedule. | ||
821 | */ | ||
822 | int AES_set_decrypt_key(const unsigned char *userKey, const int bits, | ||
823 | AES_KEY *key) { | ||
824 | |||
825 | u32 *rk; | ||
826 | int i, j, status; | ||
827 | u32 temp; | ||
828 | |||
829 | /* first, start with an encryption schedule */ | ||
830 | status = AES_set_encrypt_key(userKey, bits, key); | ||
831 | if (status < 0) | ||
832 | return status; | ||
833 | |||
834 | rk = key->rd_key; | ||
835 | |||
836 | /* invert the order of the round keys: */ | ||
837 | for (i = 0, j = 4*(key->rounds); i < j; i += 4, j -= 4) { | ||
838 | temp = rk[i ]; rk[i ] = rk[j ]; rk[j ] = temp; | ||
839 | temp = rk[i + 1]; rk[i + 1] = rk[j + 1]; rk[j + 1] = temp; | ||
840 | temp = rk[i + 2]; rk[i + 2] = rk[j + 2]; rk[j + 2] = temp; | ||
841 | temp = rk[i + 3]; rk[i + 3] = rk[j + 3]; rk[j + 3] = temp; | ||
842 | } | ||
843 | /* apply the inverse MixColumn transform to all round keys but the first and the last: */ | ||
844 | for (i = 1; i < (key->rounds); i++) { | ||
845 | rk += 4; | ||
846 | rk[0] = | ||
847 | Td0[Te4[(rk[0] >> 24) ] & 0xff] ^ | ||
848 | Td1[Te4[(rk[0] >> 16) & 0xff] & 0xff] ^ | ||
849 | Td2[Te4[(rk[0] >> 8) & 0xff] & 0xff] ^ | ||
850 | Td3[Te4[(rk[0] ) & 0xff] & 0xff]; | ||
851 | rk[1] = | ||
852 | Td0[Te4[(rk[1] >> 24) ] & 0xff] ^ | ||
853 | Td1[Te4[(rk[1] >> 16) & 0xff] & 0xff] ^ | ||
854 | Td2[Te4[(rk[1] >> 8) & 0xff] & 0xff] ^ | ||
855 | Td3[Te4[(rk[1] ) & 0xff] & 0xff]; | ||
856 | rk[2] = | ||
857 | Td0[Te4[(rk[2] >> 24) ] & 0xff] ^ | ||
858 | Td1[Te4[(rk[2] >> 16) & 0xff] & 0xff] ^ | ||
859 | Td2[Te4[(rk[2] >> 8) & 0xff] & 0xff] ^ | ||
860 | Td3[Te4[(rk[2] ) & 0xff] & 0xff]; | ||
861 | rk[3] = | ||
862 | Td0[Te4[(rk[3] >> 24) ] & 0xff] ^ | ||
863 | Td1[Te4[(rk[3] >> 16) & 0xff] & 0xff] ^ | ||
864 | Td2[Te4[(rk[3] >> 8) & 0xff] & 0xff] ^ | ||
865 | Td3[Te4[(rk[3] ) & 0xff] & 0xff]; | ||
866 | } | ||
867 | return 0; | ||
868 | } | ||
869 | |||
870 | /* | ||
871 | * Encrypt a single block | ||
872 | * in and out can overlap | ||
873 | */ | ||
874 | void AES_encrypt(const unsigned char *in, unsigned char *out, | ||
875 | const AES_KEY *key) { | ||
876 | |||
877 | const u32 *rk; | ||
878 | u32 s0, s1, s2, s3, t0, t1, t2, t3; | ||
879 | #ifndef FULL_UNROLL | ||
880 | int r; | ||
881 | #endif /* ?FULL_UNROLL */ | ||
882 | |||
883 | assert(in && out && key); | ||
884 | rk = key->rd_key; | ||
885 | |||
886 | /* | ||
887 | * map byte array block to cipher state | ||
888 | * and add initial round key: | ||
889 | */ | ||
890 | s0 = GETU32(in ) ^ rk[0]; | ||
891 | s1 = GETU32(in + 4) ^ rk[1]; | ||
892 | s2 = GETU32(in + 8) ^ rk[2]; | ||
893 | s3 = GETU32(in + 12) ^ rk[3]; | ||
894 | #ifdef FULL_UNROLL | ||
895 | /* round 1: */ | ||
896 | t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[ 4]; | ||
897 | t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[ 5]; | ||
898 | t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[ 6]; | ||
899 | t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[ 7]; | ||
900 | /* round 2: */ | ||
901 | s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[ 8]; | ||
902 | s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[ 9]; | ||
903 | s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[10]; | ||
904 | s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[11]; | ||
905 | /* round 3: */ | ||
906 | t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[12]; | ||
907 | t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[13]; | ||
908 | t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[14]; | ||
909 | t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[15]; | ||
910 | /* round 4: */ | ||
911 | s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[16]; | ||
912 | s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[17]; | ||
913 | s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[18]; | ||
914 | s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[19]; | ||
915 | /* round 5: */ | ||
916 | t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[20]; | ||
917 | t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[21]; | ||
918 | t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[22]; | ||
919 | t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[23]; | ||
920 | /* round 6: */ | ||
921 | s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[24]; | ||
922 | s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[25]; | ||
923 | s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[26]; | ||
924 | s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[27]; | ||
925 | /* round 7: */ | ||
926 | t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[28]; | ||
927 | t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[29]; | ||
928 | t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[30]; | ||
929 | t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[31]; | ||
930 | /* round 8: */ | ||
931 | s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[32]; | ||
932 | s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[33]; | ||
933 | s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[34]; | ||
934 | s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[35]; | ||
935 | /* round 9: */ | ||
936 | t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[36]; | ||
937 | t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[37]; | ||
938 | t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[38]; | ||
939 | t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[39]; | ||
940 | if (key->rounds > 10) { | ||
941 | /* round 10: */ | ||
942 | s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[40]; | ||
943 | s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[41]; | ||
944 | s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[42]; | ||
945 | s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[43]; | ||
946 | /* round 11: */ | ||
947 | t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[44]; | ||
948 | t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[45]; | ||
949 | t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[46]; | ||
950 | t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[47]; | ||
951 | if (key->rounds > 12) { | ||
952 | /* round 12: */ | ||
953 | s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[48]; | ||
954 | s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[49]; | ||
955 | s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[50]; | ||
956 | s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[51]; | ||
957 | /* round 13: */ | ||
958 | t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[52]; | ||
959 | t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[53]; | ||
960 | t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[54]; | ||
961 | t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[55]; | ||
962 | } | ||
963 | } | ||
964 | rk += key->rounds << 2; | ||
965 | #else /* !FULL_UNROLL */ | ||
966 | /* | ||
967 | * Nr - 1 full rounds: | ||
968 | */ | ||
969 | r = key->rounds >> 1; | ||
970 | for (;;) { | ||
971 | t0 = | ||
972 | Te0[(s0 >> 24) ] ^ | ||
973 | Te1[(s1 >> 16) & 0xff] ^ | ||
974 | Te2[(s2 >> 8) & 0xff] ^ | ||
975 | Te3[(s3 ) & 0xff] ^ | ||
976 | rk[4]; | ||
977 | t1 = | ||
978 | Te0[(s1 >> 24) ] ^ | ||
979 | Te1[(s2 >> 16) & 0xff] ^ | ||
980 | Te2[(s3 >> 8) & 0xff] ^ | ||
981 | Te3[(s0 ) & 0xff] ^ | ||
982 | rk[5]; | ||
983 | t2 = | ||
984 | Te0[(s2 >> 24) ] ^ | ||
985 | Te1[(s3 >> 16) & 0xff] ^ | ||
986 | Te2[(s0 >> 8) & 0xff] ^ | ||
987 | Te3[(s1 ) & 0xff] ^ | ||
988 | rk[6]; | ||
989 | t3 = | ||
990 | Te0[(s3 >> 24) ] ^ | ||
991 | Te1[(s0 >> 16) & 0xff] ^ | ||
992 | Te2[(s1 >> 8) & 0xff] ^ | ||
993 | Te3[(s2 ) & 0xff] ^ | ||
994 | rk[7]; | ||
995 | |||
996 | rk += 8; | ||
997 | if (--r == 0) { | ||
998 | break; | ||
999 | } | ||
1000 | |||
1001 | s0 = | ||
1002 | Te0[(t0 >> 24) ] ^ | ||
1003 | Te1[(t1 >> 16) & 0xff] ^ | ||
1004 | Te2[(t2 >> 8) & 0xff] ^ | ||
1005 | Te3[(t3 ) & 0xff] ^ | ||
1006 | rk[0]; | ||
1007 | s1 = | ||
1008 | Te0[(t1 >> 24) ] ^ | ||
1009 | Te1[(t2 >> 16) & 0xff] ^ | ||
1010 | Te2[(t3 >> 8) & 0xff] ^ | ||
1011 | Te3[(t0 ) & 0xff] ^ | ||
1012 | rk[1]; | ||
1013 | s2 = | ||
1014 | Te0[(t2 >> 24) ] ^ | ||
1015 | Te1[(t3 >> 16) & 0xff] ^ | ||
1016 | Te2[(t0 >> 8) & 0xff] ^ | ||
1017 | Te3[(t1 ) & 0xff] ^ | ||
1018 | rk[2]; | ||
1019 | s3 = | ||
1020 | Te0[(t3 >> 24) ] ^ | ||
1021 | Te1[(t0 >> 16) & 0xff] ^ | ||
1022 | Te2[(t1 >> 8) & 0xff] ^ | ||
1023 | Te3[(t2 ) & 0xff] ^ | ||
1024 | rk[3]; | ||
1025 | } | ||
1026 | #endif /* ?FULL_UNROLL */ | ||
1027 | /* | ||
1028 | * apply last round and | ||
1029 | * map cipher state to byte array block: | ||
1030 | */ | ||
1031 | s0 = | ||
1032 | (Te4[(t0 >> 24) ] & 0xff000000) ^ | ||
1033 | (Te4[(t1 >> 16) & 0xff] & 0x00ff0000) ^ | ||
1034 | (Te4[(t2 >> 8) & 0xff] & 0x0000ff00) ^ | ||
1035 | (Te4[(t3 ) & 0xff] & 0x000000ff) ^ | ||
1036 | rk[0]; | ||
1037 | PUTU32(out , s0); | ||
1038 | s1 = | ||
1039 | (Te4[(t1 >> 24) ] & 0xff000000) ^ | ||
1040 | (Te4[(t2 >> 16) & 0xff] & 0x00ff0000) ^ | ||
1041 | (Te4[(t3 >> 8) & 0xff] & 0x0000ff00) ^ | ||
1042 | (Te4[(t0 ) & 0xff] & 0x000000ff) ^ | ||
1043 | rk[1]; | ||
1044 | PUTU32(out + 4, s1); | ||
1045 | s2 = | ||
1046 | (Te4[(t2 >> 24) ] & 0xff000000) ^ | ||
1047 | (Te4[(t3 >> 16) & 0xff] & 0x00ff0000) ^ | ||
1048 | (Te4[(t0 >> 8) & 0xff] & 0x0000ff00) ^ | ||
1049 | (Te4[(t1 ) & 0xff] & 0x000000ff) ^ | ||
1050 | rk[2]; | ||
1051 | PUTU32(out + 8, s2); | ||
1052 | s3 = | ||
1053 | (Te4[(t3 >> 24) ] & 0xff000000) ^ | ||
1054 | (Te4[(t0 >> 16) & 0xff] & 0x00ff0000) ^ | ||
1055 | (Te4[(t1 >> 8) & 0xff] & 0x0000ff00) ^ | ||
1056 | (Te4[(t2 ) & 0xff] & 0x000000ff) ^ | ||
1057 | rk[3]; | ||
1058 | PUTU32(out + 12, s3); | ||
1059 | } | ||
1060 | |||
1061 | /* | ||
1062 | * Decrypt a single block | ||
1063 | * in and out can overlap | ||
1064 | */ | ||
1065 | void AES_decrypt(const unsigned char *in, unsigned char *out, | ||
1066 | const AES_KEY *key) { | ||
1067 | |||
1068 | const u32 *rk; | ||
1069 | u32 s0, s1, s2, s3, t0, t1, t2, t3; | ||
1070 | #ifndef FULL_UNROLL | ||
1071 | int r; | ||
1072 | #endif /* ?FULL_UNROLL */ | ||
1073 | |||
1074 | assert(in && out && key); | ||
1075 | rk = key->rd_key; | ||
1076 | |||
1077 | /* | ||
1078 | * map byte array block to cipher state | ||
1079 | * and add initial round key: | ||
1080 | */ | ||
1081 | s0 = GETU32(in ) ^ rk[0]; | ||
1082 | s1 = GETU32(in + 4) ^ rk[1]; | ||
1083 | s2 = GETU32(in + 8) ^ rk[2]; | ||
1084 | s3 = GETU32(in + 12) ^ rk[3]; | ||
1085 | #ifdef FULL_UNROLL | ||
1086 | /* round 1: */ | ||
1087 | t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[ 4]; | ||
1088 | t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[ 5]; | ||
1089 | t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[ 6]; | ||
1090 | t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[ 7]; | ||
1091 | /* round 2: */ | ||
1092 | s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[ 8]; | ||
1093 | s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[ 9]; | ||
1094 | s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[10]; | ||
1095 | s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[11]; | ||
1096 | /* round 3: */ | ||
1097 | t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[12]; | ||
1098 | t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[13]; | ||
1099 | t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[14]; | ||
1100 | t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[15]; | ||
1101 | /* round 4: */ | ||
1102 | s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[16]; | ||
1103 | s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[17]; | ||
1104 | s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[18]; | ||
1105 | s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[19]; | ||
1106 | /* round 5: */ | ||
1107 | t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[20]; | ||
1108 | t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[21]; | ||
1109 | t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[22]; | ||
1110 | t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[23]; | ||
1111 | /* round 6: */ | ||
1112 | s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[24]; | ||
1113 | s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[25]; | ||
1114 | s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[26]; | ||
1115 | s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[27]; | ||
1116 | /* round 7: */ | ||
1117 | t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[28]; | ||
1118 | t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[29]; | ||
1119 | t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[30]; | ||
1120 | t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[31]; | ||
1121 | /* round 8: */ | ||
1122 | s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[32]; | ||
1123 | s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[33]; | ||
1124 | s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[34]; | ||
1125 | s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[35]; | ||
1126 | /* round 9: */ | ||
1127 | t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[36]; | ||
1128 | t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[37]; | ||
1129 | t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[38]; | ||
1130 | t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[39]; | ||
1131 | if (key->rounds > 10) { | ||
1132 | /* round 10: */ | ||
1133 | s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[40]; | ||
1134 | s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[41]; | ||
1135 | s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[42]; | ||
1136 | s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[43]; | ||
1137 | /* round 11: */ | ||
1138 | t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[44]; | ||
1139 | t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[45]; | ||
1140 | t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[46]; | ||
1141 | t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[47]; | ||
1142 | if (key->rounds > 12) { | ||
1143 | /* round 12: */ | ||
1144 | s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[48]; | ||
1145 | s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[49]; | ||
1146 | s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[50]; | ||
1147 | s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[51]; | ||
1148 | /* round 13: */ | ||
1149 | t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[52]; | ||
1150 | t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[53]; | ||
1151 | t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[54]; | ||
1152 | t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[55]; | ||
1153 | } | ||
1154 | } | ||
1155 | rk += key->rounds << 2; | ||
1156 | #else /* !FULL_UNROLL */ | ||
1157 | /* | ||
1158 | * Nr - 1 full rounds: | ||
1159 | */ | ||
1160 | r = key->rounds >> 1; | ||
1161 | for (;;) { | ||
1162 | t0 = | ||
1163 | Td0[(s0 >> 24) ] ^ | ||
1164 | Td1[(s3 >> 16) & 0xff] ^ | ||
1165 | Td2[(s2 >> 8) & 0xff] ^ | ||
1166 | Td3[(s1 ) & 0xff] ^ | ||
1167 | rk[4]; | ||
1168 | t1 = | ||
1169 | Td0[(s1 >> 24) ] ^ | ||
1170 | Td1[(s0 >> 16) & 0xff] ^ | ||
1171 | Td2[(s3 >> 8) & 0xff] ^ | ||
1172 | Td3[(s2 ) & 0xff] ^ | ||
1173 | rk[5]; | ||
1174 | t2 = | ||
1175 | Td0[(s2 >> 24) ] ^ | ||
1176 | Td1[(s1 >> 16) & 0xff] ^ | ||
1177 | Td2[(s0 >> 8) & 0xff] ^ | ||
1178 | Td3[(s3 ) & 0xff] ^ | ||
1179 | rk[6]; | ||
1180 | t3 = | ||
1181 | Td0[(s3 >> 24) ] ^ | ||
1182 | Td1[(s2 >> 16) & 0xff] ^ | ||
1183 | Td2[(s1 >> 8) & 0xff] ^ | ||
1184 | Td3[(s0 ) & 0xff] ^ | ||
1185 | rk[7]; | ||
1186 | |||
1187 | rk += 8; | ||
1188 | if (--r == 0) { | ||
1189 | break; | ||
1190 | } | ||
1191 | |||
1192 | s0 = | ||
1193 | Td0[(t0 >> 24) ] ^ | ||
1194 | Td1[(t3 >> 16) & 0xff] ^ | ||
1195 | Td2[(t2 >> 8) & 0xff] ^ | ||
1196 | Td3[(t1 ) & 0xff] ^ | ||
1197 | rk[0]; | ||
1198 | s1 = | ||
1199 | Td0[(t1 >> 24) ] ^ | ||
1200 | Td1[(t0 >> 16) & 0xff] ^ | ||
1201 | Td2[(t3 >> 8) & 0xff] ^ | ||
1202 | Td3[(t2 ) & 0xff] ^ | ||
1203 | rk[1]; | ||
1204 | s2 = | ||
1205 | Td0[(t2 >> 24) ] ^ | ||
1206 | Td1[(t1 >> 16) & 0xff] ^ | ||
1207 | Td2[(t0 >> 8) & 0xff] ^ | ||
1208 | Td3[(t3 ) & 0xff] ^ | ||
1209 | rk[2]; | ||
1210 | s3 = | ||
1211 | Td0[(t3 >> 24) ] ^ | ||
1212 | Td1[(t2 >> 16) & 0xff] ^ | ||
1213 | Td2[(t1 >> 8) & 0xff] ^ | ||
1214 | Td3[(t0 ) & 0xff] ^ | ||
1215 | rk[3]; | ||
1216 | } | ||
1217 | #endif /* ?FULL_UNROLL */ | ||
1218 | /* | ||
1219 | * apply last round and | ||
1220 | * map cipher state to byte array block: | ||
1221 | */ | ||
1222 | s0 = | ||
1223 | (Td4[(t0 >> 24) ] & 0xff000000) ^ | ||
1224 | (Td4[(t3 >> 16) & 0xff] & 0x00ff0000) ^ | ||
1225 | (Td4[(t2 >> 8) & 0xff] & 0x0000ff00) ^ | ||
1226 | (Td4[(t1 ) & 0xff] & 0x000000ff) ^ | ||
1227 | rk[0]; | ||
1228 | PUTU32(out , s0); | ||
1229 | s1 = | ||
1230 | (Td4[(t1 >> 24) ] & 0xff000000) ^ | ||
1231 | (Td4[(t0 >> 16) & 0xff] & 0x00ff0000) ^ | ||
1232 | (Td4[(t3 >> 8) & 0xff] & 0x0000ff00) ^ | ||
1233 | (Td4[(t2 ) & 0xff] & 0x000000ff) ^ | ||
1234 | rk[1]; | ||
1235 | PUTU32(out + 4, s1); | ||
1236 | s2 = | ||
1237 | (Td4[(t2 >> 24) ] & 0xff000000) ^ | ||
1238 | (Td4[(t1 >> 16) & 0xff] & 0x00ff0000) ^ | ||
1239 | (Td4[(t0 >> 8) & 0xff] & 0x0000ff00) ^ | ||
1240 | (Td4[(t3 ) & 0xff] & 0x000000ff) ^ | ||
1241 | rk[2]; | ||
1242 | PUTU32(out + 8, s2); | ||
1243 | s3 = | ||
1244 | (Td4[(t3 >> 24) ] & 0xff000000) ^ | ||
1245 | (Td4[(t2 >> 16) & 0xff] & 0x00ff0000) ^ | ||
1246 | (Td4[(t1 >> 8) & 0xff] & 0x0000ff00) ^ | ||
1247 | (Td4[(t0 ) & 0xff] & 0x000000ff) ^ | ||
1248 | rk[3]; | ||
1249 | PUTU32(out + 12, s3); | ||
1250 | } | ||
1251 | |||
diff --git a/src/lib/libcrypto/aes/aes_ctr.c b/src/lib/libcrypto/aes/aes_ctr.c new file mode 100644 index 0000000000..8e800481de --- /dev/null +++ b/src/lib/libcrypto/aes/aes_ctr.c | |||
@@ -0,0 +1,117 @@ | |||
1 | /* crypto/aes/aes_ctr.c -*- mode:C; c-file-style: "eay" -*- */ | ||
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 | */ | ||
51 | |||
52 | #include <assert.h> | ||
53 | #include <openssl/aes.h> | ||
54 | #include "aes_locl.h" | ||
55 | |||
56 | /* NOTE: CTR mode is big-endian. The rest of the AES code | ||
57 | * is endian-neutral. */ | ||
58 | |||
59 | /* increment counter (128-bit int) by 2^64 */ | ||
60 | static void AES_ctr128_inc(unsigned char *counter) { | ||
61 | unsigned long c; | ||
62 | |||
63 | /* Grab 3rd dword of counter and increment */ | ||
64 | #ifdef L_ENDIAN | ||
65 | c = GETU32(counter + 8); | ||
66 | c++; | ||
67 | PUTU32(counter + 8, c); | ||
68 | #else | ||
69 | c = GETU32(counter + 4); | ||
70 | c++; | ||
71 | PUTU32(counter + 4, c); | ||
72 | #endif | ||
73 | |||
74 | /* if no overflow, we're done */ | ||
75 | if (c) | ||
76 | return; | ||
77 | |||
78 | /* Grab top dword of counter and increment */ | ||
79 | #ifdef L_ENDIAN | ||
80 | c = GETU32(counter + 12); | ||
81 | c++; | ||
82 | PUTU32(counter + 12, c); | ||
83 | #else | ||
84 | c = GETU32(counter + 0); | ||
85 | c++; | ||
86 | PUTU32(counter + 0, c); | ||
87 | #endif | ||
88 | |||
89 | } | ||
90 | |||
91 | /* The input encrypted as though 128bit counter mode is being | ||
92 | * used. The extra state information to record how much of the | ||
93 | * 128bit block we have used is contained in *num; | ||
94 | */ | ||
95 | void AES_ctr128_encrypt(const unsigned char *in, unsigned char *out, | ||
96 | const unsigned long length, const AES_KEY *key, | ||
97 | unsigned char *counter, unsigned int *num) { | ||
98 | |||
99 | unsigned int n; | ||
100 | unsigned long l=length; | ||
101 | unsigned char tmp[AES_BLOCK_SIZE]; | ||
102 | |||
103 | assert(in && out && key && counter && num); | ||
104 | |||
105 | n = *num; | ||
106 | |||
107 | while (l--) { | ||
108 | if (n == 0) { | ||
109 | AES_ctr128_inc(counter); | ||
110 | AES_encrypt(counter, tmp, key); | ||
111 | } | ||
112 | *(out++) = *(in++) ^ tmp[n]; | ||
113 | n = (n+1) % AES_BLOCK_SIZE; | ||
114 | } | ||
115 | |||
116 | *num=n; | ||
117 | } | ||
diff --git a/src/lib/libcrypto/aes/aes_ecb.c b/src/lib/libcrypto/aes/aes_ecb.c new file mode 100644 index 0000000000..1cb2e07d3d --- /dev/null +++ b/src/lib/libcrypto/aes/aes_ecb.c | |||
@@ -0,0 +1,67 @@ | |||
1 | /* crypto/aes/aes_ecb.c -*- mode:C; c-file-style: "eay" -*- */ | ||
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 | */ | ||
51 | |||
52 | #include <assert.h> | ||
53 | #include <openssl/aes.h> | ||
54 | #include "aes_locl.h" | ||
55 | |||
56 | void AES_ecb_encrypt(const unsigned char *in, unsigned char *out, | ||
57 | const AES_KEY *key, const int enc) { | ||
58 | |||
59 | assert(in && out && key); | ||
60 | assert((AES_ENCRYPT == enc)||(AES_DECRYPT == enc)); | ||
61 | |||
62 | if (AES_ENCRYPT == enc) | ||
63 | AES_encrypt(in, out, key); | ||
64 | else | ||
65 | AES_decrypt(in, out, key); | ||
66 | } | ||
67 | |||
diff --git a/src/lib/libcrypto/aes/aes_locl.h b/src/lib/libcrypto/aes/aes_locl.h new file mode 100644 index 0000000000..541d1d6e84 --- /dev/null +++ b/src/lib/libcrypto/aes/aes_locl.h | |||
@@ -0,0 +1,88 @@ | |||
1 | /* crypto/aes/aes.h -*- mode:C; c-file-style: "eay" -*- */ | ||
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 | */ | ||
51 | |||
52 | #ifndef HEADER_AES_LOCL_H | ||
53 | #define HEADER_AES_LOCL_H | ||
54 | |||
55 | #include <openssl/e_os2.h> | ||
56 | |||
57 | #ifdef OPENSSL_NO_AES | ||
58 | #error AES is disabled. | ||
59 | #endif | ||
60 | |||
61 | #include <stdio.h> | ||
62 | #include <stdlib.h> | ||
63 | |||
64 | #if defined(__STDC__) || defined(OPENSSL_SYS_VMS) || defined(M_XENIX) || defined(OPENSSL_SYS_MSDOS) | ||
65 | #include <string.h> | ||
66 | #endif | ||
67 | |||
68 | #ifdef _MSC_VER | ||
69 | # define SWAP(x) (_lrotl(x, 8) & 0x00ff00ff | _lrotr(x, 8) & 0xff00ff00) | ||
70 | # define GETU32(p) SWAP(*((u32 *)(p))) | ||
71 | # define PUTU32(ct, st) { *((u32 *)(ct)) = SWAP((st)); } | ||
72 | #else | ||
73 | # define GETU32(pt) (((u32)(pt)[0] << 24) ^ ((u32)(pt)[1] << 16) ^ ((u32)(pt)[2] << 8) ^ ((u32)(pt)[3])) | ||
74 | # define PUTU32(ct, st) { (ct)[0] = (u8)((st) >> 24); (ct)[1] = (u8)((st) >> 16); (ct)[2] = (u8)((st) >> 8); (ct)[3] = (u8)(st); } | ||
75 | #endif | ||
76 | |||
77 | typedef unsigned long u32; | ||
78 | typedef unsigned short u16; | ||
79 | typedef unsigned char u8; | ||
80 | |||
81 | #define MAXKC (256/32) | ||
82 | #define MAXKB (256/8) | ||
83 | #define MAXNR 14 | ||
84 | |||
85 | /* This controls loop-unrolling in aes_core.c */ | ||
86 | #undef FULL_UNROLL | ||
87 | |||
88 | #endif /* !HEADER_AES_LOCL_H */ | ||
diff --git a/src/lib/libcrypto/aes/aes_misc.c b/src/lib/libcrypto/aes/aes_misc.c new file mode 100644 index 0000000000..090def25d5 --- /dev/null +++ b/src/lib/libcrypto/aes/aes_misc.c | |||
@@ -0,0 +1,64 @@ | |||
1 | /* crypto/aes/aes_misc.c -*- mode:C; c-file-style: "eay" -*- */ | ||
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 | */ | ||
51 | |||
52 | #include <openssl/opensslv.h> | ||
53 | #include <openssl/aes.h> | ||
54 | #include "aes_locl.h" | ||
55 | |||
56 | const char *AES_version="AES" OPENSSL_VERSION_PTEXT; | ||
57 | |||
58 | const char *AES_options(void) { | ||
59 | #ifdef FULL_UNROLL | ||
60 | return "aes(full)"; | ||
61 | #else | ||
62 | return "aes(partial)"; | ||
63 | #endif | ||
64 | } | ||
diff --git a/src/lib/libcrypto/aes/aes_ofb.c b/src/lib/libcrypto/aes/aes_ofb.c new file mode 100644 index 0000000000..e33bdaea28 --- /dev/null +++ b/src/lib/libcrypto/aes/aes_ofb.c | |||
@@ -0,0 +1,136 @@ | |||
1 | /* crypto/aes/aes_ofb.c -*- mode:C; c-file-style: "eay" -*- */ | ||
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 | */ | ||
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 | #include <assert.h> | ||
109 | #include <openssl/aes.h> | ||
110 | #include "aes_locl.h" | ||
111 | |||
112 | /* The input and output encrypted as though 128bit ofb mode is being | ||
113 | * used. The extra state information to record how much of the | ||
114 | * 128bit block we have used is contained in *num; | ||
115 | */ | ||
116 | void AES_ofb128_encrypt(const unsigned char *in, unsigned char *out, | ||
117 | const unsigned long length, const AES_KEY *key, | ||
118 | unsigned char *ivec, int *num) { | ||
119 | |||
120 | unsigned int n; | ||
121 | unsigned long l=length; | ||
122 | |||
123 | assert(in && out && key && ivec && num); | ||
124 | |||
125 | n = *num; | ||
126 | |||
127 | while (l--) { | ||
128 | if (n == 0) { | ||
129 | AES_encrypt(ivec, ivec, key); | ||
130 | } | ||
131 | *(out++) = *(in++) ^ ivec[n]; | ||
132 | n = (n+1) % AES_BLOCK_SIZE; | ||
133 | } | ||
134 | |||
135 | *num=n; | ||
136 | } | ||
diff --git a/src/lib/libcrypto/asn1/a_enum.c b/src/lib/libcrypto/asn1/a_enum.c new file mode 100644 index 0000000000..9239ecc439 --- /dev/null +++ b/src/lib/libcrypto/asn1/a_enum.c | |||
@@ -0,0 +1,326 @@ | |||
1 | /* crypto/asn1/a_enum.c */ | ||
2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) | ||
3 | * All rights reserved. | ||
4 | * | ||
5 | * This package is an SSL implementation written | ||
6 | * by Eric Young (eay@cryptsoft.com). | ||
7 | * The implementation was written so as to conform with Netscapes SSL. | ||
8 | * | ||
9 | * This library is free for commercial and non-commercial use as long as | ||
10 | * the following conditions are aheared to. The following conditions | ||
11 | * apply to all code found in this distribution, be it the RC4, RSA, | ||
12 | * lhash, DES, etc., code; not just the SSL code. The SSL documentation | ||
13 | * included with this distribution is covered by the same copyright terms | ||
14 | * except that the holder is Tim Hudson (tjh@cryptsoft.com). | ||
15 | * | ||
16 | * Copyright remains Eric Young's, and as such any Copyright notices in | ||
17 | * the code are not to be removed. | ||
18 | * If this package is used in a product, Eric Young should be given attribution | ||
19 | * as the author of the parts of the library used. | ||
20 | * This can be in the form of a textual message at program startup or | ||
21 | * in documentation (online or textual) provided with the package. | ||
22 | * | ||
23 | * Redistribution and use in source and binary forms, with or without | ||
24 | * modification, are permitted provided that the following conditions | ||
25 | * are met: | ||
26 | * 1. Redistributions of source code must retain the copyright | ||
27 | * notice, this list of conditions and the following disclaimer. | ||
28 | * 2. Redistributions in binary form must reproduce the above copyright | ||
29 | * notice, this list of conditions and the following disclaimer in the | ||
30 | * documentation and/or other materials provided with the distribution. | ||
31 | * 3. All advertising materials mentioning features or use of this software | ||
32 | * must display the following acknowledgement: | ||
33 | * "This product includes cryptographic software written by | ||
34 | * Eric Young (eay@cryptsoft.com)" | ||
35 | * The word 'cryptographic' can be left out if the rouines from the library | ||
36 | * being used are not cryptographic related :-). | ||
37 | * 4. If you include any Windows specific code (or a derivative thereof) from | ||
38 | * the apps directory (application code) you must include an acknowledgement: | ||
39 | * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" | ||
40 | * | ||
41 | * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND | ||
42 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
43 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
44 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | ||
45 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
46 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
47 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
48 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
49 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
50 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
51 | * SUCH DAMAGE. | ||
52 | * | ||
53 | * The licence and distribution terms for any publically available version or | ||
54 | * derivative of this code cannot be changed. i.e. this code cannot simply be | ||
55 | * copied and put under another distribution licence | ||
56 | * [including the GNU Public Licence.] | ||
57 | */ | ||
58 | |||
59 | #include <stdio.h> | ||
60 | #include "cryptlib.h" | ||
61 | #include <openssl/asn1.h> | ||
62 | |||
63 | /* | ||
64 | * Code for ENUMERATED type: identical to INTEGER apart from a different tag. | ||
65 | * for comments on encoding see a_int.c | ||
66 | */ | ||
67 | |||
68 | int i2d_ASN1_ENUMERATED(ASN1_ENUMERATED *a, unsigned char **pp) | ||
69 | { | ||
70 | int pad=0,ret,r,i,t; | ||
71 | unsigned char *p,*n,pb=0; | ||
72 | |||
73 | if ((a == NULL) || (a->data == NULL)) return(0); | ||
74 | t=a->type; | ||
75 | if (a->length == 0) | ||
76 | ret=1; | ||
77 | else | ||
78 | { | ||
79 | ret=a->length; | ||
80 | i=a->data[0]; | ||
81 | if ((t == V_ASN1_ENUMERATED) && (i > 127)) { | ||
82 | pad=1; | ||
83 | pb=0; | ||
84 | } else if(t == V_ASN1_NEG_ENUMERATED) { | ||
85 | if(i>128) { | ||
86 | pad=1; | ||
87 | pb=0xFF; | ||
88 | } else if(i == 128) { | ||
89 | for(i = 1; i < a->length; i++) if(a->data[i]) { | ||
90 | pad=1; | ||
91 | pb=0xFF; | ||
92 | break; | ||
93 | } | ||
94 | } | ||
95 | } | ||
96 | ret+=pad; | ||
97 | } | ||
98 | r=ASN1_object_size(0,ret,V_ASN1_ENUMERATED); | ||
99 | if (pp == NULL) return(r); | ||
100 | p= *pp; | ||
101 | |||
102 | ASN1_put_object(&p,0,ret,V_ASN1_ENUMERATED,V_ASN1_UNIVERSAL); | ||
103 | if (pad) *(p++)=pb; | ||
104 | if (a->length == 0) | ||
105 | *(p++)=0; | ||
106 | else if (t == V_ASN1_ENUMERATED) | ||
107 | { | ||
108 | memcpy(p,a->data,(unsigned int)a->length); | ||
109 | p+=a->length; | ||
110 | } | ||
111 | else { | ||
112 | /* Begin at the end of the encoding */ | ||
113 | n=a->data + a->length - 1; | ||
114 | p += a->length - 1; | ||
115 | i = a->length; | ||
116 | /* Copy zeros to destination as long as source is zero */ | ||
117 | while(!*n) { | ||
118 | *(p--) = 0; | ||
119 | n--; | ||
120 | i--; | ||
121 | } | ||
122 | /* Complement and increment next octet */ | ||
123 | *(p--) = ((*(n--)) ^ 0xff) + 1; | ||
124 | i--; | ||
125 | /* Complement any octets left */ | ||
126 | for(;i > 0; i--) *(p--) = *(n--) ^ 0xff; | ||
127 | p += a->length; | ||
128 | } | ||
129 | |||
130 | *pp=p; | ||
131 | return(r); | ||
132 | } | ||
133 | |||
134 | ASN1_ENUMERATED *d2i_ASN1_ENUMERATED(ASN1_ENUMERATED **a, unsigned char **pp, | ||
135 | long length) | ||
136 | { | ||
137 | ASN1_ENUMERATED *ret=NULL; | ||
138 | unsigned char *p,*to,*s; | ||
139 | long len; | ||
140 | int inf,tag,xclass; | ||
141 | int i; | ||
142 | |||
143 | if ((a == NULL) || ((*a) == NULL)) | ||
144 | { | ||
145 | if ((ret=ASN1_ENUMERATED_new()) == NULL) return(NULL); | ||
146 | ret->type=V_ASN1_ENUMERATED; | ||
147 | } | ||
148 | else | ||
149 | ret=(*a); | ||
150 | |||
151 | p= *pp; | ||
152 | inf=ASN1_get_object(&p,&len,&tag,&xclass,length); | ||
153 | if (inf & 0x80) | ||
154 | { | ||
155 | i=ASN1_R_BAD_OBJECT_HEADER; | ||
156 | goto err; | ||
157 | } | ||
158 | |||
159 | if (tag != V_ASN1_ENUMERATED) | ||
160 | { | ||
161 | i=ASN1_R_EXPECTING_AN_ENUMERATED; | ||
162 | goto err; | ||
163 | } | ||
164 | |||
165 | /* We must Malloc stuff, even for 0 bytes otherwise it | ||
166 | * signifies a missing NULL parameter. */ | ||
167 | s=(unsigned char *)Malloc((int)len+1); | ||
168 | if (s == NULL) | ||
169 | { | ||
170 | i=ERR_R_MALLOC_FAILURE; | ||
171 | goto err; | ||
172 | } | ||
173 | to=s; | ||
174 | if (*p & 0x80) /* a negative number */ | ||
175 | { | ||
176 | ret->type=V_ASN1_NEG_ENUMERATED; | ||
177 | if ((*p == 0xff) && (len != 1)) { | ||
178 | p++; | ||
179 | len--; | ||
180 | } | ||
181 | i = len; | ||
182 | p += i - 1; | ||
183 | to += i - 1; | ||
184 | while((!*p) && i) { | ||
185 | *(to--) = 0; | ||
186 | i--; | ||
187 | p--; | ||
188 | } | ||
189 | if(!i) { | ||
190 | *s = 1; | ||
191 | s[len] = 0; | ||
192 | p += len; | ||
193 | len++; | ||
194 | } else { | ||
195 | *(to--) = (*(p--) ^ 0xff) + 1; | ||
196 | i--; | ||
197 | for(;i > 0; i--) *(to--) = *(p--) ^ 0xff; | ||
198 | p += len; | ||
199 | } | ||
200 | } else { | ||
201 | ret->type=V_ASN1_ENUMERATED; | ||
202 | if ((*p == 0) && (len != 1)) | ||
203 | { | ||
204 | p++; | ||
205 | len--; | ||
206 | } | ||
207 | memcpy(s,p,(int)len); | ||
208 | p+=len; | ||
209 | } | ||
210 | |||
211 | if (ret->data != NULL) Free((char *)ret->data); | ||
212 | ret->data=s; | ||
213 | ret->length=(int)len; | ||
214 | if (a != NULL) (*a)=ret; | ||
215 | *pp=p; | ||
216 | return(ret); | ||
217 | err: | ||
218 | ASN1err(ASN1_F_D2I_ASN1_ENUMERATED,i); | ||
219 | if ((ret != NULL) && ((a == NULL) || (*a != ret))) | ||
220 | ASN1_ENUMERATED_free(ret); | ||
221 | return(NULL); | ||
222 | } | ||
223 | |||
224 | int ASN1_ENUMERATED_set(ASN1_ENUMERATED *a, long v) | ||
225 | { | ||
226 | int i,j,k; | ||
227 | unsigned char buf[sizeof(long)+1]; | ||
228 | long d; | ||
229 | |||
230 | a->type=V_ASN1_ENUMERATED; | ||
231 | if (a->length < (sizeof(long)+1)) | ||
232 | { | ||
233 | if (a->data != NULL) | ||
234 | Free((char *)a->data); | ||
235 | if ((a->data=(unsigned char *)Malloc(sizeof(long)+1)) != NULL) | ||
236 | memset((char *)a->data,0,sizeof(long)+1); | ||
237 | } | ||
238 | if (a->data == NULL) | ||
239 | { | ||
240 | ASN1err(ASN1_F_ASN1_ENUMERATED_SET,ERR_R_MALLOC_FAILURE); | ||
241 | return(0); | ||
242 | } | ||
243 | d=v; | ||
244 | if (d < 0) | ||
245 | { | ||
246 | d= -d; | ||
247 | a->type=V_ASN1_NEG_ENUMERATED; | ||
248 | } | ||
249 | |||
250 | for (i=0; i<sizeof(long); i++) | ||
251 | { | ||
252 | if (d == 0) break; | ||
253 | buf[i]=(int)d&0xff; | ||
254 | d>>=8; | ||
255 | } | ||
256 | j=0; | ||
257 | for (k=i-1; k >=0; k--) | ||
258 | a->data[j++]=buf[k]; | ||
259 | a->length=j; | ||
260 | return(1); | ||
261 | } | ||
262 | |||
263 | long ASN1_ENUMERATED_get(ASN1_ENUMERATED *a) | ||
264 | { | ||
265 | int neg=0,i; | ||
266 | long r=0; | ||
267 | |||
268 | if (a == NULL) return(0L); | ||
269 | i=a->type; | ||
270 | if (i == V_ASN1_NEG_ENUMERATED) | ||
271 | neg=1; | ||
272 | else if (i != V_ASN1_ENUMERATED) | ||
273 | return(0); | ||
274 | |||
275 | if (a->length > sizeof(long)) | ||
276 | { | ||
277 | /* hmm... a bit ugly */ | ||
278 | return(0xffffffffL); | ||
279 | } | ||
280 | if (a->data == NULL) | ||
281 | return(0); | ||
282 | |||
283 | for (i=0; i<a->length; i++) | ||
284 | { | ||
285 | r<<=8; | ||
286 | r|=(unsigned char)a->data[i]; | ||
287 | } | ||
288 | if (neg) r= -r; | ||
289 | return(r); | ||
290 | } | ||
291 | |||
292 | ASN1_ENUMERATED *BN_to_ASN1_ENUMERATED(BIGNUM *bn, ASN1_ENUMERATED *ai) | ||
293 | { | ||
294 | ASN1_ENUMERATED *ret; | ||
295 | int len,j; | ||
296 | |||
297 | if (ai == NULL) | ||
298 | ret=ASN1_ENUMERATED_new(); | ||
299 | else | ||
300 | ret=ai; | ||
301 | if (ret == NULL) | ||
302 | { | ||
303 | ASN1err(ASN1_F_BN_TO_ASN1_ENUMERATED,ERR_R_NESTED_ASN1_ERROR); | ||
304 | goto err; | ||
305 | } | ||
306 | if(bn->neg) ret->type = V_ASN1_NEG_ENUMERATED; | ||
307 | else ret->type=V_ASN1_ENUMERATED; | ||
308 | j=BN_num_bits(bn); | ||
309 | len=((j == 0)?0:((j/8)+1)); | ||
310 | ret->data=(unsigned char *)Malloc(len+4); | ||
311 | ret->length=BN_bn2bin(bn,ret->data); | ||
312 | return(ret); | ||
313 | err: | ||
314 | if (ret != ai) ASN1_ENUMERATED_free(ret); | ||
315 | return(NULL); | ||
316 | } | ||
317 | |||
318 | BIGNUM *ASN1_ENUMERATED_to_BN(ASN1_ENUMERATED *ai, BIGNUM *bn) | ||
319 | { | ||
320 | BIGNUM *ret; | ||
321 | |||
322 | if ((ret=BN_bin2bn(ai->data,ai->length,bn)) == NULL) | ||
323 | ASN1err(ASN1_F_ASN1_ENUMERATED_TO_BN,ASN1_R_BN_LIB); | ||
324 | if(ai->type == V_ASN1_NEG_ENUMERATED) bn->neg = 1; | ||
325 | return(ret); | ||
326 | } | ||
diff --git a/src/lib/libcrypto/asn1/a_mbstr.c b/src/lib/libcrypto/asn1/a_mbstr.c new file mode 100644 index 0000000000..7a710d5459 --- /dev/null +++ b/src/lib/libcrypto/asn1/a_mbstr.c | |||
@@ -0,0 +1,390 @@ | |||
1 | /* a_mbstr.c */ | ||
2 | /* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL | ||
3 | * project 1999. | ||
4 | */ | ||
5 | /* ==================================================================== | ||
6 | * Copyright (c) 1999 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 | #include <ctype.h> | ||
61 | #include "cryptlib.h" | ||
62 | #include <openssl/asn1.h> | ||
63 | |||
64 | static int traverse_string(const unsigned char *p, int len, int inform, | ||
65 | int (*rfunc)(unsigned long value, void *in), void *arg); | ||
66 | static int in_utf8(unsigned long value, void *arg); | ||
67 | static int out_utf8(unsigned long value, void *arg); | ||
68 | static int type_str(unsigned long value, void *arg); | ||
69 | static int cpy_asc(unsigned long value, void *arg); | ||
70 | static int cpy_bmp(unsigned long value, void *arg); | ||
71 | static int cpy_univ(unsigned long value, void *arg); | ||
72 | static int cpy_utf8(unsigned long value, void *arg); | ||
73 | static int is_printable(unsigned long value); | ||
74 | |||
75 | /* These functions take a string in UTF8, ASCII or multibyte form and | ||
76 | * a mask of permissible ASN1 string types. It then works out the minimal | ||
77 | * type (using the order Printable < IA5 < T61 < BMP < Universal < UTF8) | ||
78 | * and creates a string of the correct type with the supplied data. | ||
79 | * Yes this is horrible: it has to be :-( | ||
80 | * The 'ncopy' form checks minimum and maximum size limits too. | ||
81 | */ | ||
82 | |||
83 | int ASN1_mbstring_copy(ASN1_STRING **out, const unsigned char *in, int len, | ||
84 | int inform, unsigned long mask) | ||
85 | { | ||
86 | return ASN1_mbstring_ncopy(out, in, len, inform, mask, 0, 0); | ||
87 | } | ||
88 | |||
89 | int ASN1_mbstring_ncopy(ASN1_STRING **out, const unsigned char *in, int len, | ||
90 | int inform, unsigned long mask, | ||
91 | long minsize, long maxsize) | ||
92 | { | ||
93 | int str_type; | ||
94 | int ret; | ||
95 | int outform, outlen; | ||
96 | ASN1_STRING *dest; | ||
97 | unsigned char *p; | ||
98 | int nchar; | ||
99 | char strbuf[32]; | ||
100 | int (*cpyfunc)(unsigned long,void *) = NULL; | ||
101 | if(len == -1) len = strlen((const char *)in); | ||
102 | if(!mask) mask = DIRSTRING_TYPE; | ||
103 | |||
104 | /* First do a string check and work out the number of characters */ | ||
105 | switch(inform) { | ||
106 | |||
107 | case MBSTRING_BMP: | ||
108 | if(len & 1) { | ||
109 | ASN1err(ASN1_F_ASN1_MBSTRING_COPY, | ||
110 | ASN1_R_INVALID_BMPSTRING_LENGTH); | ||
111 | return -1; | ||
112 | } | ||
113 | nchar = len >> 1; | ||
114 | break; | ||
115 | |||
116 | case MBSTRING_UNIV: | ||
117 | if(len & 3) { | ||
118 | ASN1err(ASN1_F_ASN1_MBSTRING_COPY, | ||
119 | ASN1_R_INVALID_UNIVERSALSTRING_LENGTH); | ||
120 | return -1; | ||
121 | } | ||
122 | nchar = len >> 2; | ||
123 | break; | ||
124 | |||
125 | case MBSTRING_UTF8: | ||
126 | nchar = 0; | ||
127 | /* This counts the characters and does utf8 syntax checking */ | ||
128 | ret = traverse_string(in, len, MBSTRING_UTF8, in_utf8, &nchar); | ||
129 | if(ret < 0) { | ||
130 | ASN1err(ASN1_F_ASN1_MBSTRING_COPY, | ||
131 | ASN1_R_INVALID_UTF8STRING); | ||
132 | return -1; | ||
133 | } | ||
134 | break; | ||
135 | |||
136 | case MBSTRING_ASC: | ||
137 | nchar = len; | ||
138 | break; | ||
139 | |||
140 | default: | ||
141 | ASN1err(ASN1_F_ASN1_MBSTRING_COPY, ASN1_R_UNKNOWN_FORMAT); | ||
142 | return -1; | ||
143 | } | ||
144 | |||
145 | if((minsize > 0) && (nchar < minsize)) { | ||
146 | ASN1err(ASN1_F_ASN1_MBSTRING_COPY, ASN1_R_STRING_TOO_SHORT); | ||
147 | sprintf(strbuf, "%ld", minsize); | ||
148 | ERR_add_error_data(2, "minsize=", strbuf); | ||
149 | return -1; | ||
150 | } | ||
151 | |||
152 | if((maxsize > 0) && (nchar > maxsize)) { | ||
153 | ASN1err(ASN1_F_ASN1_MBSTRING_COPY, ASN1_R_STRING_TOO_LONG); | ||
154 | sprintf(strbuf, "%ld", maxsize); | ||
155 | ERR_add_error_data(2, "maxsize=", strbuf); | ||
156 | return -1; | ||
157 | } | ||
158 | |||
159 | /* Now work out minimal type (if any) */ | ||
160 | if(traverse_string(in, len, inform, type_str, &mask) < 0) { | ||
161 | ASN1err(ASN1_F_ASN1_MBSTRING_COPY, ASN1_R_ILLEGAL_CHARACTERS); | ||
162 | return -1; | ||
163 | } | ||
164 | |||
165 | |||
166 | /* Now work out output format and string type */ | ||
167 | outform = MBSTRING_ASC; | ||
168 | if(mask & B_ASN1_PRINTABLESTRING) str_type = V_ASN1_PRINTABLESTRING; | ||
169 | else if(mask & B_ASN1_IA5STRING) str_type = V_ASN1_IA5STRING; | ||
170 | else if(mask & B_ASN1_T61STRING) str_type = V_ASN1_T61STRING; | ||
171 | else if(mask & B_ASN1_BMPSTRING) { | ||
172 | str_type = V_ASN1_BMPSTRING; | ||
173 | outform = MBSTRING_BMP; | ||
174 | } else if(mask & B_ASN1_UNIVERSALSTRING) { | ||
175 | str_type = V_ASN1_UNIVERSALSTRING; | ||
176 | outform = MBSTRING_UNIV; | ||
177 | } else { | ||
178 | str_type = V_ASN1_UTF8STRING; | ||
179 | outform = MBSTRING_UTF8; | ||
180 | } | ||
181 | if(!out) return str_type; | ||
182 | if(*out) { | ||
183 | dest = *out; | ||
184 | if(dest->data) { | ||
185 | dest->length = 0; | ||
186 | Free(dest->data); | ||
187 | dest->data = NULL; | ||
188 | } | ||
189 | dest->type = str_type; | ||
190 | } else { | ||
191 | dest = ASN1_STRING_type_new(str_type); | ||
192 | if(!dest) { | ||
193 | ASN1err(ASN1_F_ASN1_MBSTRING_COPY, | ||
194 | ERR_R_MALLOC_FAILURE); | ||
195 | return -1; | ||
196 | } | ||
197 | *out = dest; | ||
198 | } | ||
199 | /* If both the same type just copy across */ | ||
200 | if(inform == outform) { | ||
201 | if(!ASN1_STRING_set(dest, in, len)) { | ||
202 | ASN1err(ASN1_F_ASN1_MBSTRING_COPY,ERR_R_MALLOC_FAILURE); | ||
203 | return -1; | ||
204 | } | ||
205 | return str_type; | ||
206 | } | ||
207 | |||
208 | /* Work out how much space the destination will need */ | ||
209 | switch(outform) { | ||
210 | case MBSTRING_ASC: | ||
211 | outlen = nchar; | ||
212 | cpyfunc = cpy_asc; | ||
213 | break; | ||
214 | |||
215 | case MBSTRING_BMP: | ||
216 | outlen = nchar << 1; | ||
217 | cpyfunc = cpy_bmp; | ||
218 | break; | ||
219 | |||
220 | case MBSTRING_UNIV: | ||
221 | outlen = nchar << 2; | ||
222 | cpyfunc = cpy_univ; | ||
223 | break; | ||
224 | |||
225 | case MBSTRING_UTF8: | ||
226 | outlen = 0; | ||
227 | traverse_string(in, len, inform, out_utf8, &outlen); | ||
228 | cpyfunc = cpy_utf8; | ||
229 | break; | ||
230 | } | ||
231 | if(!(p = Malloc(outlen + 1))) { | ||
232 | ASN1_STRING_free(dest); | ||
233 | ASN1err(ASN1_F_ASN1_MBSTRING_COPY,ERR_R_MALLOC_FAILURE); | ||
234 | return -1; | ||
235 | } | ||
236 | dest->length = outlen; | ||
237 | dest->data = p; | ||
238 | p[outlen] = 0; | ||
239 | traverse_string(in, len, inform, cpyfunc, &p); | ||
240 | return str_type; | ||
241 | } | ||
242 | |||
243 | /* This function traverses a string and passes the value of each character | ||
244 | * to an optional function along with a void * argument. | ||
245 | */ | ||
246 | |||
247 | static int traverse_string(const unsigned char *p, int len, int inform, | ||
248 | int (*rfunc)(unsigned long value, void *in), void *arg) | ||
249 | { | ||
250 | unsigned long value; | ||
251 | int ret; | ||
252 | while(len) { | ||
253 | if(inform == MBSTRING_ASC) { | ||
254 | value = *p++; | ||
255 | len--; | ||
256 | } else if(inform == MBSTRING_BMP) { | ||
257 | value = *p++ << 8; | ||
258 | value |= *p++; | ||
259 | len -= 2; | ||
260 | } else if(inform == MBSTRING_UNIV) { | ||
261 | value = *p++ << 24; | ||
262 | value |= *p++ << 16; | ||
263 | value |= *p++ << 8; | ||
264 | value |= *p++; | ||
265 | len -= 4; | ||
266 | } else { | ||
267 | ret = UTF8_getc(p, len, &value); | ||
268 | if(ret < 0) return -1; | ||
269 | len -= ret; | ||
270 | p += ret; | ||
271 | } | ||
272 | if(rfunc) { | ||
273 | ret = rfunc(value, arg); | ||
274 | if(ret <= 0) return ret; | ||
275 | } | ||
276 | } | ||
277 | return 1; | ||
278 | } | ||
279 | |||
280 | /* Various utility functions for traverse_string */ | ||
281 | |||
282 | /* Just count number of characters */ | ||
283 | |||
284 | static int in_utf8(unsigned long value, void *arg) | ||
285 | { | ||
286 | int *nchar; | ||
287 | nchar = arg; | ||
288 | (*nchar)++; | ||
289 | return 1; | ||
290 | } | ||
291 | |||
292 | /* Determine size of output as a UTF8 String */ | ||
293 | |||
294 | static int out_utf8(unsigned long value, void *arg) | ||
295 | { | ||
296 | long *outlen; | ||
297 | outlen = arg; | ||
298 | *outlen += UTF8_putc(NULL, -1, value); | ||
299 | return 1; | ||
300 | } | ||
301 | |||
302 | /* Determine the "type" of a string: check each character against a | ||
303 | * supplied "mask". | ||
304 | */ | ||
305 | |||
306 | static int type_str(unsigned long value, void *arg) | ||
307 | { | ||
308 | unsigned long types; | ||
309 | types = *((unsigned long *)arg); | ||
310 | if((types & B_ASN1_PRINTABLESTRING) && !is_printable(value)) | ||
311 | types &= ~B_ASN1_PRINTABLESTRING; | ||
312 | if((types & B_ASN1_IA5STRING) && (value > 127)) | ||
313 | types &= ~B_ASN1_IA5STRING; | ||
314 | if((types & B_ASN1_T61STRING) && (value > 0xff)) | ||
315 | types &= ~B_ASN1_T61STRING; | ||
316 | if((types & B_ASN1_BMPSTRING) && (value > 0xffff)) | ||
317 | types &= ~B_ASN1_BMPSTRING; | ||
318 | if(!types) return -1; | ||
319 | *((unsigned long *)arg) = types; | ||
320 | return 1; | ||
321 | } | ||
322 | |||
323 | /* Copy one byte per character ASCII like strings */ | ||
324 | |||
325 | static int cpy_asc(unsigned long value, void *arg) | ||
326 | { | ||
327 | unsigned char **p, *q; | ||
328 | p = arg; | ||
329 | q = *p; | ||
330 | *q = (unsigned char) value; | ||
331 | (*p)++; | ||
332 | return 1; | ||
333 | } | ||
334 | |||
335 | /* Copy two byte per character BMPStrings */ | ||
336 | |||
337 | static int cpy_bmp(unsigned long value, void *arg) | ||
338 | { | ||
339 | unsigned char **p, *q; | ||
340 | p = arg; | ||
341 | q = *p; | ||
342 | *q++ = (unsigned char) ((value >> 8) & 0xff); | ||
343 | *q = (unsigned char) (value & 0xff); | ||
344 | *p += 2; | ||
345 | return 1; | ||
346 | } | ||
347 | |||
348 | /* Copy four byte per character UniversalStrings */ | ||
349 | |||
350 | static int cpy_univ(unsigned long value, void *arg) | ||
351 | { | ||
352 | unsigned char **p, *q; | ||
353 | p = arg; | ||
354 | q = *p; | ||
355 | *q++ = (unsigned char) ((value >> 24) & 0xff); | ||
356 | *q++ = (unsigned char) ((value >> 16) & 0xff); | ||
357 | *q++ = (unsigned char) ((value >> 8) & 0xff); | ||
358 | *q = (unsigned char) (value & 0xff); | ||
359 | *p += 4; | ||
360 | return 1; | ||
361 | } | ||
362 | |||
363 | /* Copy to a UTF8String */ | ||
364 | |||
365 | static int cpy_utf8(unsigned long value, void *arg) | ||
366 | { | ||
367 | unsigned char **p; | ||
368 | int ret; | ||
369 | p = arg; | ||
370 | /* We already know there is enough room so pass 0xff as the length */ | ||
371 | ret = UTF8_putc(*p, 0xff, value); | ||
372 | *p += ret; | ||
373 | return 1; | ||
374 | } | ||
375 | |||
376 | /* Return 1 if the character is permitted in a PrintableString */ | ||
377 | static int is_printable(unsigned long value) | ||
378 | { | ||
379 | int ch; | ||
380 | if(value > 0x7f) return 0; | ||
381 | ch = (int) value; | ||
382 | /* Note: we can't use 'isalnum' because certain accented | ||
383 | * characters may count as alphanumeric in some environments. | ||
384 | */ | ||
385 | if((ch >= 'a') && (ch <= 'z')) return 1; | ||
386 | if((ch >= 'A') && (ch <= 'Z')) return 1; | ||
387 | if((ch >= '0') && (ch <= '9')) return 1; | ||
388 | if ((ch == ' ') || strchr("'()+,-./:=?", ch)) return 1; | ||
389 | return 0; | ||
390 | } | ||
diff --git a/src/lib/libcrypto/asn1/a_strex.c b/src/lib/libcrypto/asn1/a_strex.c new file mode 100644 index 0000000000..569b811998 --- /dev/null +++ b/src/lib/libcrypto/asn1/a_strex.c | |||
@@ -0,0 +1,533 @@ | |||
1 | /* a_strex.c */ | ||
2 | /* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL | ||
3 | * project 2000. | ||
4 | */ | ||
5 | /* ==================================================================== | ||
6 | * Copyright (c) 2000 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 | #include <string.h> | ||
61 | #include <openssl/crypto.h> | ||
62 | #include <openssl/x509.h> | ||
63 | #include <openssl/asn1.h> | ||
64 | |||
65 | #include "charmap.h" | ||
66 | |||
67 | /* ASN1_STRING_print_ex() and X509_NAME_print_ex(). | ||
68 | * Enhanced string and name printing routines handling | ||
69 | * multibyte characters, RFC2253 and a host of other | ||
70 | * options. | ||
71 | */ | ||
72 | |||
73 | |||
74 | #define CHARTYPE_BS_ESC (ASN1_STRFLGS_ESC_2253 | CHARTYPE_FIRST_ESC_2253 | CHARTYPE_LAST_ESC_2253) | ||
75 | |||
76 | |||
77 | /* Three IO functions for sending data to memory, a BIO and | ||
78 | * and a FILE pointer. | ||
79 | */ | ||
80 | |||
81 | int send_mem_chars(void *arg, const void *buf, int len) | ||
82 | { | ||
83 | unsigned char **out = arg; | ||
84 | if(!out) return 1; | ||
85 | memcpy(*out, buf, len); | ||
86 | *out += len; | ||
87 | return 1; | ||
88 | } | ||
89 | |||
90 | int send_bio_chars(void *arg, const void *buf, int len) | ||
91 | { | ||
92 | if(!arg) return 1; | ||
93 | if(BIO_write(arg, buf, len) != len) return 0; | ||
94 | return 1; | ||
95 | } | ||
96 | |||
97 | int send_fp_chars(void *arg, const void *buf, int len) | ||
98 | { | ||
99 | if(!arg) return 1; | ||
100 | if(fwrite(buf, 1, len, arg) != (unsigned int)len) return 0; | ||
101 | return 1; | ||
102 | } | ||
103 | |||
104 | typedef int char_io(void *arg, const void *buf, int len); | ||
105 | |||
106 | /* This function handles display of | ||
107 | * strings, one character at a time. | ||
108 | * It is passed an unsigned long for each | ||
109 | * character because it could come from 2 or even | ||
110 | * 4 byte forms. | ||
111 | */ | ||
112 | |||
113 | static int do_esc_char(unsigned long c, unsigned char flags, char *do_quotes, char_io *io_ch, void *arg) | ||
114 | { | ||
115 | unsigned char chflgs, chtmp; | ||
116 | char tmphex[11]; | ||
117 | if(c > 0xffff) { | ||
118 | BIO_snprintf(tmphex, 11, "\\W%08lX", c); | ||
119 | if(!io_ch(arg, tmphex, 10)) return -1; | ||
120 | return 10; | ||
121 | } | ||
122 | if(c > 0xff) { | ||
123 | BIO_snprintf(tmphex, 11, "\\U%04lX", c); | ||
124 | if(!io_ch(arg, tmphex, 6)) return -1; | ||
125 | return 6; | ||
126 | } | ||
127 | chtmp = (unsigned char)c; | ||
128 | if(chtmp > 0x7f) chflgs = flags & ASN1_STRFLGS_ESC_MSB; | ||
129 | else chflgs = char_type[chtmp] & flags; | ||
130 | if(chflgs & CHARTYPE_BS_ESC) { | ||
131 | /* If we don't escape with quotes, signal we need quotes */ | ||
132 | if(chflgs & ASN1_STRFLGS_ESC_QUOTE) { | ||
133 | if(do_quotes) *do_quotes = 1; | ||
134 | if(!io_ch(arg, &chtmp, 1)) return -1; | ||
135 | return 1; | ||
136 | } | ||
137 | if(!io_ch(arg, "\\", 1)) return -1; | ||
138 | if(!io_ch(arg, &chtmp, 1)) return -1; | ||
139 | return 2; | ||
140 | } | ||
141 | if(chflgs & (ASN1_STRFLGS_ESC_CTRL|ASN1_STRFLGS_ESC_MSB)) { | ||
142 | BIO_snprintf(tmphex, 11, "\\%02X", chtmp); | ||
143 | if(!io_ch(arg, tmphex, 3)) return -1; | ||
144 | return 3; | ||
145 | } | ||
146 | if(!io_ch(arg, &chtmp, 1)) return -1; | ||
147 | return 1; | ||
148 | } | ||
149 | |||
150 | #define BUF_TYPE_WIDTH_MASK 0x7 | ||
151 | #define BUF_TYPE_CONVUTF8 0x8 | ||
152 | |||
153 | /* This function sends each character in a buffer to | ||
154 | * do_esc_char(). It interprets the content formats | ||
155 | * and converts to or from UTF8 as appropriate. | ||
156 | */ | ||
157 | |||
158 | static int do_buf(unsigned char *buf, int buflen, | ||
159 | int type, unsigned char flags, char *quotes, char_io *io_ch, void *arg) | ||
160 | { | ||
161 | int i, outlen, len; | ||
162 | unsigned char orflags, *p, *q; | ||
163 | unsigned long c; | ||
164 | p = buf; | ||
165 | q = buf + buflen; | ||
166 | outlen = 0; | ||
167 | while(p != q) { | ||
168 | if(p == buf) orflags = CHARTYPE_FIRST_ESC_2253; | ||
169 | else orflags = 0; | ||
170 | switch(type & BUF_TYPE_WIDTH_MASK) { | ||
171 | case 4: | ||
172 | c = ((unsigned long)*p++) << 24; | ||
173 | c |= ((unsigned long)*p++) << 16; | ||
174 | c |= ((unsigned long)*p++) << 8; | ||
175 | c |= *p++; | ||
176 | break; | ||
177 | |||
178 | case 2: | ||
179 | c = ((unsigned long)*p++) << 8; | ||
180 | c |= *p++; | ||
181 | break; | ||
182 | |||
183 | case 1: | ||
184 | c = *p++; | ||
185 | break; | ||
186 | |||
187 | case 0: | ||
188 | i = UTF8_getc(p, buflen, &c); | ||
189 | if(i < 0) return -1; /* Invalid UTF8String */ | ||
190 | p += i; | ||
191 | break; | ||
192 | } | ||
193 | if (p == q) orflags = CHARTYPE_LAST_ESC_2253; | ||
194 | if(type & BUF_TYPE_CONVUTF8) { | ||
195 | unsigned char utfbuf[6]; | ||
196 | int utflen; | ||
197 | utflen = UTF8_putc(utfbuf, 6, c); | ||
198 | for(i = 0; i < utflen; i++) { | ||
199 | /* We don't need to worry about setting orflags correctly | ||
200 | * because if utflen==1 its value will be correct anyway | ||
201 | * otherwise each character will be > 0x7f and so the | ||
202 | * character will never be escaped on first and last. | ||
203 | */ | ||
204 | len = do_esc_char(utfbuf[i], (unsigned char)(flags | orflags), quotes, io_ch, arg); | ||
205 | if(len < 0) return -1; | ||
206 | outlen += len; | ||
207 | } | ||
208 | } else { | ||
209 | len = do_esc_char(c, (unsigned char)(flags | orflags), quotes, io_ch, arg); | ||
210 | if(len < 0) return -1; | ||
211 | outlen += len; | ||
212 | } | ||
213 | } | ||
214 | return outlen; | ||
215 | } | ||
216 | |||
217 | /* This function hex dumps a buffer of characters */ | ||
218 | |||
219 | static int do_hex_dump(char_io *io_ch, void *arg, unsigned char *buf, int buflen) | ||
220 | { | ||
221 | const static char hexdig[] = "0123456789ABCDEF"; | ||
222 | unsigned char *p, *q; | ||
223 | char hextmp[2]; | ||
224 | if(arg) { | ||
225 | p = buf; | ||
226 | q = buf + buflen; | ||
227 | while(p != q) { | ||
228 | hextmp[0] = hexdig[*p >> 4]; | ||
229 | hextmp[1] = hexdig[*p & 0xf]; | ||
230 | if(!io_ch(arg, hextmp, 2)) return -1; | ||
231 | p++; | ||
232 | } | ||
233 | } | ||
234 | return buflen << 1; | ||
235 | } | ||
236 | |||
237 | /* "dump" a string. This is done when the type is unknown, | ||
238 | * or the flags request it. We can either dump the content | ||
239 | * octets or the entire DER encoding. This uses the RFC2253 | ||
240 | * #01234 format. | ||
241 | */ | ||
242 | |||
243 | int do_dump(unsigned long lflags, char_io *io_ch, void *arg, ASN1_STRING *str) | ||
244 | { | ||
245 | /* Placing the ASN1_STRING in a temp ASN1_TYPE allows | ||
246 | * the DER encoding to readily obtained | ||
247 | */ | ||
248 | ASN1_TYPE t; | ||
249 | unsigned char *der_buf, *p; | ||
250 | int outlen, der_len; | ||
251 | |||
252 | if(!io_ch(arg, "#", 1)) return -1; | ||
253 | /* If we don't dump DER encoding just dump content octets */ | ||
254 | if(!(lflags & ASN1_STRFLGS_DUMP_DER)) { | ||
255 | outlen = do_hex_dump(io_ch, arg, str->data, str->length); | ||
256 | if(outlen < 0) return -1; | ||
257 | return outlen + 1; | ||
258 | } | ||
259 | t.type = str->type; | ||
260 | t.value.ptr = (char *)str; | ||
261 | der_len = i2d_ASN1_TYPE(&t, NULL); | ||
262 | der_buf = OPENSSL_malloc(der_len); | ||
263 | if(!der_buf) return -1; | ||
264 | p = der_buf; | ||
265 | i2d_ASN1_TYPE(&t, &p); | ||
266 | outlen = do_hex_dump(io_ch, arg, der_buf, der_len); | ||
267 | OPENSSL_free(der_buf); | ||
268 | if(outlen < 0) return -1; | ||
269 | return outlen + 1; | ||
270 | } | ||
271 | |||
272 | /* Lookup table to convert tags to character widths, | ||
273 | * 0 = UTF8 encoded, -1 is used for non string types | ||
274 | * otherwise it is the number of bytes per character | ||
275 | */ | ||
276 | |||
277 | const static char tag2nbyte[] = { | ||
278 | -1, -1, -1, -1, -1, /* 0-4 */ | ||
279 | -1, -1, -1, -1, -1, /* 5-9 */ | ||
280 | -1, -1, 0, -1, /* 10-13 */ | ||
281 | -1, -1, -1, -1, /* 15-17 */ | ||
282 | -1, 1, 1, /* 18-20 */ | ||
283 | -1, 1, -1,-1, /* 21-24 */ | ||
284 | -1, 1, -1, /* 25-27 */ | ||
285 | 4, -1, 2 /* 28-30 */ | ||
286 | }; | ||
287 | |||
288 | #define ESC_FLAGS (ASN1_STRFLGS_ESC_2253 | \ | ||
289 | ASN1_STRFLGS_ESC_QUOTE | \ | ||
290 | ASN1_STRFLGS_ESC_CTRL | \ | ||
291 | ASN1_STRFLGS_ESC_MSB) | ||
292 | |||
293 | /* This is the main function, print out an | ||
294 | * ASN1_STRING taking note of various escape | ||
295 | * and display options. Returns number of | ||
296 | * characters written or -1 if an error | ||
297 | * occurred. | ||
298 | */ | ||
299 | |||
300 | static int do_print_ex(char_io *io_ch, void *arg, unsigned long lflags, ASN1_STRING *str) | ||
301 | { | ||
302 | int outlen, len; | ||
303 | int type; | ||
304 | char quotes; | ||
305 | unsigned char flags; | ||
306 | quotes = 0; | ||
307 | /* Keep a copy of escape flags */ | ||
308 | flags = (unsigned char)(lflags & ESC_FLAGS); | ||
309 | |||
310 | type = str->type; | ||
311 | |||
312 | outlen = 0; | ||
313 | |||
314 | |||
315 | if(lflags & ASN1_STRFLGS_SHOW_TYPE) { | ||
316 | const char *tagname; | ||
317 | tagname = ASN1_tag2str(type); | ||
318 | outlen += strlen(tagname); | ||
319 | if(!io_ch(arg, tagname, outlen) || !io_ch(arg, ":", 1)) return -1; | ||
320 | outlen++; | ||
321 | } | ||
322 | |||
323 | /* Decide what to do with type, either dump content or display it */ | ||
324 | |||
325 | /* Dump everything */ | ||
326 | if(lflags & ASN1_STRFLGS_DUMP_ALL) type = -1; | ||
327 | /* Ignore the string type */ | ||
328 | else if(lflags & ASN1_STRFLGS_IGNORE_TYPE) type = 1; | ||
329 | else { | ||
330 | /* Else determine width based on type */ | ||
331 | if((type > 0) && (type < 31)) type = tag2nbyte[type]; | ||
332 | else type = -1; | ||
333 | if((type == -1) && !(lflags & ASN1_STRFLGS_DUMP_UNKNOWN)) type = 1; | ||
334 | } | ||
335 | |||
336 | if(type == -1) { | ||
337 | len = do_dump(lflags, io_ch, arg, str); | ||
338 | if(len < 0) return -1; | ||
339 | outlen += len; | ||
340 | return outlen; | ||
341 | } | ||
342 | |||
343 | if(lflags & ASN1_STRFLGS_UTF8_CONVERT) { | ||
344 | /* Note: if string is UTF8 and we want | ||
345 | * to convert to UTF8 then we just interpret | ||
346 | * it as 1 byte per character to avoid converting | ||
347 | * twice. | ||
348 | */ | ||
349 | if(!type) type = 1; | ||
350 | else type |= BUF_TYPE_CONVUTF8; | ||
351 | } | ||
352 | |||
353 | len = do_buf(str->data, str->length, type, flags, "es, io_ch, NULL); | ||
354 | if(outlen < 0) return -1; | ||
355 | outlen += len; | ||
356 | if(quotes) outlen += 2; | ||
357 | if(!arg) return outlen; | ||
358 | if(quotes && !io_ch(arg, "\"", 1)) return -1; | ||
359 | do_buf(str->data, str->length, type, flags, NULL, io_ch, arg); | ||
360 | if(quotes && !io_ch(arg, "\"", 1)) return -1; | ||
361 | return outlen; | ||
362 | } | ||
363 | |||
364 | /* Used for line indenting: print 'indent' spaces */ | ||
365 | |||
366 | static int do_indent(char_io *io_ch, void *arg, int indent) | ||
367 | { | ||
368 | int i; | ||
369 | for(i = 0; i < indent; i++) | ||
370 | if(!io_ch(arg, " ", 1)) return 0; | ||
371 | return 1; | ||
372 | } | ||
373 | |||
374 | |||
375 | static int do_name_ex(char_io *io_ch, void *arg, X509_NAME *n, | ||
376 | int indent, unsigned long flags) | ||
377 | { | ||
378 | int i, prev = -1, orflags, cnt; | ||
379 | int fn_opt, fn_nid; | ||
380 | ASN1_OBJECT *fn; | ||
381 | ASN1_STRING *val; | ||
382 | X509_NAME_ENTRY *ent; | ||
383 | char objtmp[80]; | ||
384 | const char *objbuf; | ||
385 | int outlen, len; | ||
386 | char *sep_dn, *sep_mv, *sep_eq; | ||
387 | int sep_dn_len, sep_mv_len, sep_eq_len; | ||
388 | if(indent < 0) indent = 0; | ||
389 | outlen = indent; | ||
390 | if(!do_indent(io_ch, arg, indent)) return -1; | ||
391 | switch (flags & XN_FLAG_SEP_MASK) | ||
392 | { | ||
393 | case XN_FLAG_SEP_MULTILINE: | ||
394 | sep_dn = "\n"; | ||
395 | sep_dn_len = 1; | ||
396 | sep_mv = " + "; | ||
397 | sep_mv_len = 3; | ||
398 | break; | ||
399 | |||
400 | case XN_FLAG_SEP_COMMA_PLUS: | ||
401 | sep_dn = ","; | ||
402 | sep_dn_len = 1; | ||
403 | sep_mv = "+"; | ||
404 | sep_mv_len = 1; | ||
405 | indent = 0; | ||
406 | break; | ||
407 | |||
408 | case XN_FLAG_SEP_CPLUS_SPC: | ||
409 | sep_dn = ", "; | ||
410 | sep_dn_len = 2; | ||
411 | sep_mv = " + "; | ||
412 | sep_mv_len = 3; | ||
413 | indent = 0; | ||
414 | break; | ||
415 | |||
416 | case XN_FLAG_SEP_SPLUS_SPC: | ||
417 | sep_dn = "; "; | ||
418 | sep_dn_len = 2; | ||
419 | sep_mv = " + "; | ||
420 | sep_mv_len = 3; | ||
421 | indent = 0; | ||
422 | break; | ||
423 | |||
424 | default: | ||
425 | return -1; | ||
426 | } | ||
427 | |||
428 | if(flags & XN_FLAG_SPC_EQ) { | ||
429 | sep_eq = " = "; | ||
430 | sep_eq_len = 3; | ||
431 | } else { | ||
432 | sep_eq = "="; | ||
433 | sep_eq_len = 1; | ||
434 | } | ||
435 | |||
436 | fn_opt = flags & XN_FLAG_FN_MASK; | ||
437 | |||
438 | cnt = X509_NAME_entry_count(n); | ||
439 | for(i = 0; i < cnt; i++) { | ||
440 | if(flags & XN_FLAG_DN_REV) | ||
441 | ent = X509_NAME_get_entry(n, cnt - i - 1); | ||
442 | else ent = X509_NAME_get_entry(n, i); | ||
443 | if(prev != -1) { | ||
444 | if(prev == ent->set) { | ||
445 | if(!io_ch(arg, sep_mv, sep_mv_len)) return -1; | ||
446 | outlen += sep_mv_len; | ||
447 | } else { | ||
448 | if(!io_ch(arg, sep_dn, sep_dn_len)) return -1; | ||
449 | outlen += sep_dn_len; | ||
450 | if(!do_indent(io_ch, arg, indent)) return -1; | ||
451 | outlen += indent; | ||
452 | } | ||
453 | } | ||
454 | prev = ent->set; | ||
455 | fn = X509_NAME_ENTRY_get_object(ent); | ||
456 | val = X509_NAME_ENTRY_get_data(ent); | ||
457 | fn_nid = OBJ_obj2nid(fn); | ||
458 | if(fn_opt != XN_FLAG_FN_NONE) { | ||
459 | int objlen; | ||
460 | if((fn_opt == XN_FLAG_FN_OID) || (fn_nid==NID_undef) ) { | ||
461 | OBJ_obj2txt(objtmp, 80, fn, 1); | ||
462 | objbuf = objtmp; | ||
463 | } else { | ||
464 | if(fn_opt == XN_FLAG_FN_SN) | ||
465 | objbuf = OBJ_nid2sn(fn_nid); | ||
466 | else if(fn_opt == XN_FLAG_FN_LN) | ||
467 | objbuf = OBJ_nid2ln(fn_nid); | ||
468 | else objbuf = ""; | ||
469 | } | ||
470 | objlen = strlen(objbuf); | ||
471 | if(!io_ch(arg, objbuf, objlen)) return -1; | ||
472 | if(!io_ch(arg, sep_eq, sep_eq_len)) return -1; | ||
473 | outlen += objlen + sep_eq_len; | ||
474 | } | ||
475 | /* If the field name is unknown then fix up the DER dump | ||
476 | * flag. We might want to limit this further so it will | ||
477 | * DER dump on anything other than a few 'standard' fields. | ||
478 | */ | ||
479 | if((fn_nid == NID_undef) && (flags & XN_FLAG_DUMP_UNKNOWN_FIELDS)) | ||
480 | orflags = ASN1_STRFLGS_DUMP_ALL; | ||
481 | else orflags = 0; | ||
482 | |||
483 | len = do_print_ex(io_ch, arg, flags | orflags, val); | ||
484 | if(len < 0) return -1; | ||
485 | outlen += len; | ||
486 | } | ||
487 | return outlen; | ||
488 | } | ||
489 | |||
490 | /* Wrappers round the main functions */ | ||
491 | |||
492 | int X509_NAME_print_ex(BIO *out, X509_NAME *nm, int indent, unsigned long flags) | ||
493 | { | ||
494 | return do_name_ex(send_bio_chars, out, nm, indent, flags); | ||
495 | } | ||
496 | |||
497 | |||
498 | int X509_NAME_print_ex_fp(FILE *fp, X509_NAME *nm, int indent, unsigned long flags) | ||
499 | { | ||
500 | return do_name_ex(send_fp_chars, fp, nm, indent, flags); | ||
501 | } | ||
502 | |||
503 | int ASN1_STRING_print_ex(BIO *out, ASN1_STRING *str, unsigned long flags) | ||
504 | { | ||
505 | return do_print_ex(send_bio_chars, out, flags, str); | ||
506 | } | ||
507 | |||
508 | |||
509 | int ASN1_STRING_print_ex_fp(FILE *fp, ASN1_STRING *str, unsigned long flags) | ||
510 | { | ||
511 | return do_print_ex(send_fp_chars, fp, flags, str); | ||
512 | } | ||
513 | |||
514 | /* Utility function: convert any string type to UTF8, returns number of bytes | ||
515 | * in output string or a negative error code | ||
516 | */ | ||
517 | |||
518 | int ASN1_STRING_to_UTF8(unsigned char **out, ASN1_STRING *in) | ||
519 | { | ||
520 | ASN1_STRING stmp, *str = &stmp; | ||
521 | int mbflag, type, ret; | ||
522 | if(!*out || !in) return -1; | ||
523 | type = in->type; | ||
524 | if((type < 0) || (type > 30)) return -1; | ||
525 | mbflag = tag2nbyte[type]; | ||
526 | if(mbflag == -1) return -1; | ||
527 | mbflag |= MBSTRING_FLAG; | ||
528 | stmp.data = NULL; | ||
529 | ret = ASN1_mbstring_copy(&str, in->data, in->length, mbflag, B_ASN1_UTF8STRING); | ||
530 | if(ret < 0) return ret; | ||
531 | if(out) *out = stmp.data; | ||
532 | return stmp.length; | ||
533 | } | ||
diff --git a/src/lib/libcrypto/asn1/a_strnid.c b/src/lib/libcrypto/asn1/a_strnid.c new file mode 100644 index 0000000000..ab8417ffab --- /dev/null +++ b/src/lib/libcrypto/asn1/a_strnid.c | |||
@@ -0,0 +1,247 @@ | |||
1 | /* a_strnid.c */ | ||
2 | /* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL | ||
3 | * project 1999. | ||
4 | */ | ||
5 | /* ==================================================================== | ||
6 | * Copyright (c) 1999 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 | #include <ctype.h> | ||
61 | #include "cryptlib.h" | ||
62 | #include <openssl/asn1.h> | ||
63 | #include <openssl/objects.h> | ||
64 | |||
65 | |||
66 | static STACK_OF(ASN1_STRING_TABLE) *stable = NULL; | ||
67 | static void st_free(ASN1_STRING_TABLE *tbl); | ||
68 | static int sk_table_cmp(ASN1_STRING_TABLE **a, ASN1_STRING_TABLE **b); | ||
69 | static int table_cmp(ASN1_STRING_TABLE *a, ASN1_STRING_TABLE *b); | ||
70 | |||
71 | |||
72 | /* This is the global mask for the mbstring functions: this is use to | ||
73 | * mask out certain types (such as BMPString and UTF8String) because | ||
74 | * certain software (e.g. Netscape) has problems with them. | ||
75 | */ | ||
76 | |||
77 | static unsigned long global_mask = 0xFFFFFFFFL; | ||
78 | |||
79 | void ASN1_STRING_set_default_mask(unsigned long mask) | ||
80 | { | ||
81 | global_mask = mask; | ||
82 | } | ||
83 | |||
84 | unsigned long ASN1_STRING_get_default_mask(void) | ||
85 | { | ||
86 | return global_mask; | ||
87 | } | ||
88 | |||
89 | /* This function sets the default to various "flavours" of configuration. | ||
90 | * based on an ASCII string. Currently this is: | ||
91 | * MASK:XXXX : a numerical mask value. | ||
92 | * nobmp : Don't use BMPStrings (just Printable, T61). | ||
93 | * pkix : PKIX recommendation in RFC2459. | ||
94 | * utf8only : only use UTF8Strings (RFC2459 recommendation for 2004). | ||
95 | * default: the default value, Printable, T61, BMP. | ||
96 | */ | ||
97 | |||
98 | int ASN1_STRING_set_default_mask_asc(char *p) | ||
99 | { | ||
100 | unsigned long mask; | ||
101 | char *end; | ||
102 | if(!strncmp(p, "MASK:", 5)) { | ||
103 | if(!p[5]) return 0; | ||
104 | mask = strtoul(p + 5, &end, 0); | ||
105 | if(*end) return 0; | ||
106 | } else if(!strcmp(p, "nombstr")) | ||
107 | mask = ~(B_ASN1_BMPSTRING|B_ASN1_UTF8STRING); | ||
108 | else if(!strcmp(p, "pkix")) | ||
109 | mask = ~B_ASN1_T61STRING; | ||
110 | else if(!strcmp(p, "utf8only")) mask = B_ASN1_UTF8STRING; | ||
111 | else if(!strcmp(p, "default")) | ||
112 | mask = 0xFFFFFFFFL; | ||
113 | else return 0; | ||
114 | ASN1_STRING_set_default_mask(mask); | ||
115 | return 1; | ||
116 | } | ||
117 | |||
118 | /* The following function generates an ASN1_STRING based on limits in a table. | ||
119 | * Frequently the types and length of an ASN1_STRING are restricted by a | ||
120 | * corresponding OID. For example certificates and certificate requests. | ||
121 | */ | ||
122 | |||
123 | ASN1_STRING *ASN1_STRING_set_by_NID(ASN1_STRING **out, const unsigned char *in, | ||
124 | int inlen, int inform, int nid) | ||
125 | { | ||
126 | ASN1_STRING_TABLE *tbl; | ||
127 | ASN1_STRING *str = NULL; | ||
128 | unsigned long mask; | ||
129 | int ret; | ||
130 | if(!out) out = &str; | ||
131 | tbl = ASN1_STRING_TABLE_get(nid); | ||
132 | if(tbl) { | ||
133 | mask = tbl->mask; | ||
134 | if(!(tbl->flags & STABLE_NO_MASK)) mask &= global_mask; | ||
135 | ret = ASN1_mbstring_ncopy(out, in, inlen, inform, tbl->mask, | ||
136 | tbl->minsize, tbl->maxsize); | ||
137 | } else ret = ASN1_mbstring_copy(out, in, inlen, inform, DIRSTRING_TYPE & global_mask); | ||
138 | if(ret <= 0) return NULL; | ||
139 | return *out; | ||
140 | } | ||
141 | |||
142 | /* Now the tables and helper functions for the string table: | ||
143 | */ | ||
144 | |||
145 | /* size limits: this stuff is taken straight from RFC2459 */ | ||
146 | |||
147 | #define ub_name 32768 | ||
148 | #define ub_common_name 64 | ||
149 | #define ub_locality_name 128 | ||
150 | #define ub_state_name 128 | ||
151 | #define ub_organization_name 64 | ||
152 | #define ub_organization_unit_name 64 | ||
153 | #define ub_title 64 | ||
154 | #define ub_email_address 128 | ||
155 | |||
156 | /* This table must be kept in NID order */ | ||
157 | |||
158 | static ASN1_STRING_TABLE tbl_standard[] = { | ||
159 | {NID_commonName, 1, ub_common_name, DIRSTRING_TYPE, 0}, | ||
160 | {NID_countryName, 2, 2, B_ASN1_PRINTABLESTRING, STABLE_NO_MASK}, | ||
161 | {NID_localityName, 1, ub_locality_name, DIRSTRING_TYPE, 0}, | ||
162 | {NID_stateOrProvinceName, 1, ub_state_name, DIRSTRING_TYPE, 0}, | ||
163 | {NID_organizationName, 1, ub_organization_name, DIRSTRING_TYPE, 0}, | ||
164 | {NID_organizationalUnitName, 1, ub_organization_unit_name, DIRSTRING_TYPE, 0}, | ||
165 | {NID_pkcs9_emailAddress, 1, ub_email_address, B_ASN1_IA5STRING, STABLE_NO_MASK}, | ||
166 | {NID_pkcs9_unstructuredName, 1, -1, PKCS9STRING_TYPE, 0}, | ||
167 | {NID_pkcs9_challengePassword, 1, -1, PKCS9STRING_TYPE, 0}, | ||
168 | {NID_pkcs9_unstructuredAddress, 1, -1, DIRSTRING_TYPE, 0}, | ||
169 | {NID_givenName, 1, ub_name, DIRSTRING_TYPE, 0}, | ||
170 | {NID_surname, 1, ub_name, DIRSTRING_TYPE, 0}, | ||
171 | {NID_initials, 1, ub_name, DIRSTRING_TYPE, 0}, | ||
172 | {NID_name, 1, ub_name, DIRSTRING_TYPE, 0}, | ||
173 | {NID_dnQualifier, -1, -1, B_ASN1_PRINTABLESTRING, STABLE_NO_MASK} | ||
174 | }; | ||
175 | |||
176 | static int sk_table_cmp(ASN1_STRING_TABLE **a, ASN1_STRING_TABLE **b) | ||
177 | { | ||
178 | return (*a)->nid - (*b)->nid; | ||
179 | } | ||
180 | |||
181 | static int table_cmp(ASN1_STRING_TABLE *a, ASN1_STRING_TABLE *b) | ||
182 | { | ||
183 | return a->nid - b->nid; | ||
184 | } | ||
185 | |||
186 | ASN1_STRING_TABLE *ASN1_STRING_TABLE_get(int nid) | ||
187 | { | ||
188 | int idx; | ||
189 | ASN1_STRING_TABLE *ttmp; | ||
190 | ASN1_STRING_TABLE fnd; | ||
191 | fnd.nid = nid; | ||
192 | ttmp = (ASN1_STRING_TABLE *) OBJ_bsearch((char *)&fnd, | ||
193 | (char *)tbl_standard, | ||
194 | sizeof(tbl_standard)/sizeof(ASN1_STRING_TABLE), | ||
195 | sizeof(ASN1_STRING_TABLE), (int(*)())table_cmp); | ||
196 | if(ttmp) return ttmp; | ||
197 | if(!stable) return NULL; | ||
198 | idx = sk_ASN1_STRING_TABLE_find(stable, &fnd); | ||
199 | if(idx < 0) return NULL; | ||
200 | return sk_ASN1_STRING_TABLE_value(stable, idx); | ||
201 | } | ||
202 | |||
203 | int ASN1_STRING_TABLE_add(int nid, | ||
204 | long minsize, long maxsize, unsigned long mask, | ||
205 | unsigned long flags) | ||
206 | { | ||
207 | ASN1_STRING_TABLE *tmp; | ||
208 | char new_nid = 0; | ||
209 | flags &= ~STABLE_FLAGS_MALLOC; | ||
210 | if(!stable) stable = sk_ASN1_STRING_TABLE_new(sk_table_cmp); | ||
211 | if(!stable) { | ||
212 | ASN1err(ASN1_F_ASN1_STRING_TABLE_ADD, ERR_R_MALLOC_FAILURE); | ||
213 | return 0; | ||
214 | } | ||
215 | if(!(tmp = ASN1_STRING_TABLE_get(nid))) { | ||
216 | tmp = Malloc(sizeof(ASN1_STRING_TABLE)); | ||
217 | if(!tmp) { | ||
218 | ASN1err(ASN1_F_ASN1_STRING_TABLE_ADD, | ||
219 | ERR_R_MALLOC_FAILURE); | ||
220 | return 0; | ||
221 | } | ||
222 | tmp->flags = flags | STABLE_FLAGS_MALLOC; | ||
223 | tmp->nid = nid; | ||
224 | new_nid = 1; | ||
225 | } else tmp->flags = (tmp->flags & STABLE_FLAGS_MALLOC) | flags; | ||
226 | if(minsize != -1) tmp->minsize = minsize; | ||
227 | if(maxsize != -1) tmp->maxsize = maxsize; | ||
228 | tmp->mask = mask; | ||
229 | if(new_nid) sk_ASN1_STRING_TABLE_push(stable, tmp); | ||
230 | return 1; | ||
231 | } | ||
232 | |||
233 | void ASN1_STRING_TABLE_cleanup(void) | ||
234 | { | ||
235 | STACK_OF(ASN1_STRING_TABLE) *tmp; | ||
236 | tmp = stable; | ||
237 | if(!tmp) return; | ||
238 | stable = NULL; | ||
239 | sk_ASN1_STRING_TABLE_pop_free(tmp, st_free); | ||
240 | } | ||
241 | |||
242 | static void st_free(ASN1_STRING_TABLE *tbl) | ||
243 | { | ||
244 | if(tbl->flags & STABLE_FLAGS_MALLOC) Free(tbl); | ||
245 | } | ||
246 | |||
247 | IMPLEMENT_STACK_OF(ASN1_STRING_TABLE) | ||
diff --git a/src/lib/libcrypto/asn1/a_time.c b/src/lib/libcrypto/asn1/a_time.c new file mode 100644 index 0000000000..c1690a5694 --- /dev/null +++ b/src/lib/libcrypto/asn1/a_time.c | |||
@@ -0,0 +1,123 @@ | |||
1 | /* crypto/asn1/a_time.c */ | ||
2 | /* ==================================================================== | ||
3 | * Copyright (c) 1999 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 | |||
57 | /* This is an implementation of the ASN1 Time structure which is: | ||
58 | * Time ::= CHOICE { | ||
59 | * utcTime UTCTime, | ||
60 | * generalTime GeneralizedTime } | ||
61 | * written by Steve Henson. | ||
62 | */ | ||
63 | |||
64 | #include <stdio.h> | ||
65 | #include <time.h> | ||
66 | #include "cryptlib.h" | ||
67 | #include <openssl/asn1.h> | ||
68 | |||
69 | int i2d_ASN1_TIME(ASN1_TIME *a, unsigned char **pp) | ||
70 | { | ||
71 | #ifdef CHARSET_EBCDIC | ||
72 | /* KLUDGE! We convert to ascii before writing DER */ | ||
73 | char tmp[24]; | ||
74 | ASN1_STRING tmpstr; | ||
75 | |||
76 | if(a->type == V_ASN1_UTCTIME || a->type == V_ASN1_GENERALIZEDTIME) { | ||
77 | int len; | ||
78 | |||
79 | tmpstr = *(ASN1_STRING *)a; | ||
80 | len = tmpstr.length; | ||
81 | ebcdic2ascii(tmp, tmpstr.data, (len >= sizeof tmp) ? sizeof tmp : len); | ||
82 | tmpstr.data = tmp; | ||
83 | a = (ASN1_GENERALIZEDTIME *) &tmpstr; | ||
84 | } | ||
85 | #endif | ||
86 | if(a->type == V_ASN1_UTCTIME || a->type == V_ASN1_GENERALIZEDTIME) | ||
87 | return(i2d_ASN1_bytes((ASN1_STRING *)a,pp, | ||
88 | a->type ,V_ASN1_UNIVERSAL)); | ||
89 | ASN1err(ASN1_F_I2D_ASN1_TIME,ASN1_R_EXPECTING_A_TIME); | ||
90 | return -1; | ||
91 | } | ||
92 | |||
93 | |||
94 | ASN1_TIME *d2i_ASN1_TIME(ASN1_TIME **a, unsigned char **pp, long length) | ||
95 | { | ||
96 | unsigned char tag; | ||
97 | tag = **pp & ~V_ASN1_CONSTRUCTED; | ||
98 | if(tag == (V_ASN1_UTCTIME|V_ASN1_UNIVERSAL)) | ||
99 | return d2i_ASN1_UTCTIME(a, pp, length); | ||
100 | if(tag == (V_ASN1_GENERALIZEDTIME|V_ASN1_UNIVERSAL)) | ||
101 | return d2i_ASN1_GENERALIZEDTIME(a, pp, length); | ||
102 | ASN1err(ASN1_F_D2I_ASN1_TIME,ASN1_R_EXPECTING_A_TIME); | ||
103 | return(NULL); | ||
104 | } | ||
105 | |||
106 | |||
107 | ASN1_TIME *ASN1_TIME_set(ASN1_TIME *s, time_t t) | ||
108 | { | ||
109 | struct tm *ts; | ||
110 | #if defined(THREADS) && !defined(WIN32) | ||
111 | struct tm data; | ||
112 | #endif | ||
113 | |||
114 | #if defined(THREADS) && !defined(WIN32) | ||
115 | gmtime_r(&t,&data); | ||
116 | ts=&data; /* should return &data, but doesn't on some systems, so we don't even look at the return value */ | ||
117 | #else | ||
118 | ts=gmtime(&t); | ||
119 | #endif | ||
120 | if((ts->tm_year >= 50) && (ts->tm_year < 150)) | ||
121 | return ASN1_UTCTIME_set(s, t); | ||
122 | return ASN1_GENERALIZEDTIME_set(s,t); | ||
123 | } | ||
diff --git a/src/lib/libcrypto/asn1/a_utf8.c b/src/lib/libcrypto/asn1/a_utf8.c new file mode 100644 index 0000000000..4a8a92e9e4 --- /dev/null +++ b/src/lib/libcrypto/asn1/a_utf8.c | |||
@@ -0,0 +1,83 @@ | |||
1 | /* crypto/asn1/a_utf8.c */ | ||
2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) | ||
3 | * All rights reserved. | ||
4 | * | ||
5 | * This package is an SSL implementation written | ||
6 | * by Eric Young (eay@cryptsoft.com). | ||
7 | * The implementation was written so as to conform with Netscapes SSL. | ||
8 | * | ||
9 | * This library is free for commercial and non-commercial use as long as | ||
10 | * the following conditions are aheared to. The following conditions | ||
11 | * apply to all code found in this distribution, be it the RC4, RSA, | ||
12 | * lhash, DES, etc., code; not just the SSL code. The SSL documentation | ||
13 | * included with this distribution is covered by the same copyright terms | ||
14 | * except that the holder is Tim Hudson (tjh@cryptsoft.com). | ||
15 | * | ||
16 | * Copyright remains Eric Young's, and as such any Copyright notices in | ||
17 | * the code are not to be removed. | ||
18 | * If this package is used in a product, Eric Young should be given attribution | ||
19 | * as the author of the parts of the library used. | ||
20 | * This can be in the form of a textual message at program startup or | ||
21 | * in documentation (online or textual) provided with the package. | ||
22 | * | ||
23 | * Redistribution and use in source and binary forms, with or without | ||
24 | * modification, are permitted provided that the following conditions | ||
25 | * are met: | ||
26 | * 1. Redistributions of source code must retain the copyright | ||
27 | * notice, this list of conditions and the following disclaimer. | ||
28 | * 2. Redistributions in binary form must reproduce the above copyright | ||
29 | * notice, this list of conditions and the following disclaimer in the | ||
30 | * documentation and/or other materials provided with the distribution. | ||
31 | * 3. All advertising materials mentioning features or use of this software | ||
32 | * must display the following acknowledgement: | ||
33 | * "This product includes cryptographic software written by | ||
34 | * Eric Young (eay@cryptsoft.com)" | ||
35 | * The word 'cryptographic' can be left out if the rouines from the library | ||
36 | * being used are not cryptographic related :-). | ||
37 | * 4. If you include any Windows specific code (or a derivative thereof) from | ||
38 | * the apps directory (application code) you must include an acknowledgement: | ||
39 | * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" | ||
40 | * | ||
41 | * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND | ||
42 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
43 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
44 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | ||
45 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
46 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
47 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
48 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
49 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
50 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
51 | * SUCH DAMAGE. | ||
52 | * | ||
53 | * The licence and distribution terms for any publically available version or | ||
54 | * derivative of this code cannot be changed. i.e. this code cannot simply be | ||
55 | * copied and put under another distribution licence | ||
56 | * [including the GNU Public Licence.] | ||
57 | */ | ||
58 | |||
59 | #include <stdio.h> | ||
60 | #include "cryptlib.h" | ||
61 | #include <openssl/asn1.h> | ||
62 | |||
63 | int i2d_ASN1_UTF8STRING(ASN1_UTF8STRING *a, unsigned char **pp) | ||
64 | { | ||
65 | return(i2d_ASN1_bytes((ASN1_STRING *)a,pp, | ||
66 | V_ASN1_UTF8STRING,V_ASN1_UNIVERSAL)); | ||
67 | } | ||
68 | |||
69 | ASN1_UTF8STRING *d2i_ASN1_UTF8STRING(ASN1_UTF8STRING **a, unsigned char **pp, | ||
70 | long length) | ||
71 | { | ||
72 | ASN1_UTF8STRING *ret=NULL; | ||
73 | |||
74 | ret=(ASN1_UTF8STRING *)d2i_ASN1_bytes((ASN1_STRING **)a, | ||
75 | pp,length,V_ASN1_UTF8STRING,V_ASN1_UNIVERSAL); | ||
76 | if (ret == NULL) | ||
77 | { | ||
78 | ASN1err(ASN1_F_D2I_ASN1_UTF8STRING,ERR_R_NESTED_ASN1_ERROR); | ||
79 | return(NULL); | ||
80 | } | ||
81 | return(ret); | ||
82 | } | ||
83 | |||
diff --git a/src/lib/libcrypto/asn1/asn1t.h b/src/lib/libcrypto/asn1/asn1t.h new file mode 100644 index 0000000000..ed372f8554 --- /dev/null +++ b/src/lib/libcrypto/asn1/asn1t.h | |||
@@ -0,0 +1,846 @@ | |||
1 | /* asn1t.h */ | ||
2 | /* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL | ||
3 | * project 2000. | ||
4 | */ | ||
5 | /* ==================================================================== | ||
6 | * Copyright (c) 2000 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 | #ifndef HEADER_ASN1T_H | ||
59 | #define HEADER_ASN1T_H | ||
60 | |||
61 | #include <stddef.h> | ||
62 | #include <openssl/e_os2.h> | ||
63 | #include <openssl/asn1.h> | ||
64 | |||
65 | #ifdef OPENSSL_BUILD_SHLIBCRYPTO | ||
66 | # undef OPENSSL_EXTERN | ||
67 | # define OPENSSL_EXTERN OPENSSL_EXPORT | ||
68 | #endif | ||
69 | |||
70 | /* ASN1 template defines, structures and functions */ | ||
71 | |||
72 | #ifdef __cplusplus | ||
73 | extern "C" { | ||
74 | #endif | ||
75 | |||
76 | |||
77 | #ifndef OPENSSL_EXPORT_VAR_AS_FUNCTION | ||
78 | |||
79 | /* Macro to obtain ASN1_ADB pointer from a type (only used internally) */ | ||
80 | #define ASN1_ADB_ptr(iptr) ((const ASN1_ADB *)(iptr)) | ||
81 | |||
82 | |||
83 | /* Macros for start and end of ASN1_ITEM definition */ | ||
84 | |||
85 | #define ASN1_ITEM_start(itname) \ | ||
86 | OPENSSL_GLOBAL const ASN1_ITEM itname##_it = { | ||
87 | |||
88 | #define ASN1_ITEM_end(itname) \ | ||
89 | }; | ||
90 | |||
91 | #else | ||
92 | |||
93 | /* Macro to obtain ASN1_ADB pointer from a type (only used internally) */ | ||
94 | #define ASN1_ADB_ptr(iptr) ((const ASN1_ADB *)(iptr())) | ||
95 | |||
96 | |||
97 | /* Macros for start and end of ASN1_ITEM definition */ | ||
98 | |||
99 | #define ASN1_ITEM_start(itname) \ | ||
100 | const ASN1_ITEM * itname##_it(void) \ | ||
101 | { \ | ||
102 | static const ASN1_ITEM local_it = { \ | ||
103 | |||
104 | #define ASN1_ITEM_end(itname) \ | ||
105 | }; \ | ||
106 | return &local_it; \ | ||
107 | } | ||
108 | |||
109 | #endif | ||
110 | |||
111 | |||
112 | /* Macros to aid ASN1 template writing */ | ||
113 | |||
114 | #define ASN1_ITEM_TEMPLATE(tname) \ | ||
115 | const static ASN1_TEMPLATE tname##_item_tt | ||
116 | |||
117 | #define ASN1_ITEM_TEMPLATE_END(tname) \ | ||
118 | ;\ | ||
119 | ASN1_ITEM_start(tname) \ | ||
120 | ASN1_ITYPE_PRIMITIVE,\ | ||
121 | -1,\ | ||
122 | &tname##_item_tt,\ | ||
123 | 0,\ | ||
124 | NULL,\ | ||
125 | 0,\ | ||
126 | #tname \ | ||
127 | ASN1_ITEM_end(tname) | ||
128 | |||
129 | |||
130 | /* This is a ASN1 type which just embeds a template */ | ||
131 | |||
132 | /* This pair helps declare a SEQUENCE. We can do: | ||
133 | * | ||
134 | * ASN1_SEQUENCE(stname) = { | ||
135 | * ... SEQUENCE components ... | ||
136 | * } ASN1_SEQUENCE_END(stname) | ||
137 | * | ||
138 | * This will produce an ASN1_ITEM called stname_it | ||
139 | * for a structure called stname. | ||
140 | * | ||
141 | * If you want the same structure but a different | ||
142 | * name then use: | ||
143 | * | ||
144 | * ASN1_SEQUENCE(itname) = { | ||
145 | * ... SEQUENCE components ... | ||
146 | * } ASN1_SEQUENCE_END_name(stname, itname) | ||
147 | * | ||
148 | * This will create an item called itname_it using | ||
149 | * a structure called stname. | ||
150 | */ | ||
151 | |||
152 | #define ASN1_SEQUENCE(tname) \ | ||
153 | const static ASN1_TEMPLATE tname##_seq_tt[] | ||
154 | |||
155 | #define ASN1_SEQUENCE_END(stname) ASN1_SEQUENCE_END_name(stname, stname) | ||
156 | |||
157 | #define ASN1_SEQUENCE_END_name(stname, tname) \ | ||
158 | ;\ | ||
159 | ASN1_ITEM_start(tname) \ | ||
160 | ASN1_ITYPE_SEQUENCE,\ | ||
161 | V_ASN1_SEQUENCE,\ | ||
162 | tname##_seq_tt,\ | ||
163 | sizeof(tname##_seq_tt) / sizeof(ASN1_TEMPLATE),\ | ||
164 | NULL,\ | ||
165 | sizeof(stname),\ | ||
166 | #stname \ | ||
167 | ASN1_ITEM_end(tname) | ||
168 | |||
169 | #define ASN1_SEQUENCE_cb(tname, cb) \ | ||
170 | const static ASN1_AUX tname##_aux = {NULL, 0, 0, 0, cb, 0}; \ | ||
171 | ASN1_SEQUENCE(tname) | ||
172 | |||
173 | #define ASN1_BROKEN_SEQUENCE(tname) \ | ||
174 | const static ASN1_AUX tname##_aux = {NULL, ASN1_AFLG_BROKEN, 0, 0, 0, 0}; \ | ||
175 | ASN1_SEQUENCE(tname) | ||
176 | |||
177 | #define ASN1_SEQUENCE_ref(tname, cb, lck) \ | ||
178 | const static ASN1_AUX tname##_aux = {NULL, ASN1_AFLG_REFCOUNT, offsetof(tname, references), lck, cb, 0}; \ | ||
179 | ASN1_SEQUENCE(tname) | ||
180 | |||
181 | #define ASN1_SEQUENCE_enc(tname, enc, cb) \ | ||
182 | const static ASN1_AUX tname##_aux = {NULL, ASN1_AFLG_ENCODING, 0, 0, cb, offsetof(tname, enc)}; \ | ||
183 | ASN1_SEQUENCE(tname) | ||
184 | |||
185 | #define ASN1_BROKEN_SEQUENCE_END(stname) ASN1_SEQUENCE_END_ref(stname, stname) | ||
186 | |||
187 | #define ASN1_SEQUENCE_END_enc(stname, tname) ASN1_SEQUENCE_END_ref(stname, tname) | ||
188 | |||
189 | #define ASN1_SEQUENCE_END_cb(stname, tname) ASN1_SEQUENCE_END_ref(stname, tname) | ||
190 | |||
191 | #define ASN1_SEQUENCE_END_ref(stname, tname) \ | ||
192 | ;\ | ||
193 | ASN1_ITEM_start(tname) \ | ||
194 | ASN1_ITYPE_SEQUENCE,\ | ||
195 | V_ASN1_SEQUENCE,\ | ||
196 | tname##_seq_tt,\ | ||
197 | sizeof(tname##_seq_tt) / sizeof(ASN1_TEMPLATE),\ | ||
198 | &tname##_aux,\ | ||
199 | sizeof(stname),\ | ||
200 | #stname \ | ||
201 | ASN1_ITEM_end(tname) | ||
202 | |||
203 | |||
204 | /* This pair helps declare a CHOICE type. We can do: | ||
205 | * | ||
206 | * ASN1_CHOICE(chname) = { | ||
207 | * ... CHOICE options ... | ||
208 | * ASN1_CHOICE_END(chname) | ||
209 | * | ||
210 | * This will produce an ASN1_ITEM called chname_it | ||
211 | * for a structure called chname. The structure | ||
212 | * definition must look like this: | ||
213 | * typedef struct { | ||
214 | * int type; | ||
215 | * union { | ||
216 | * ASN1_SOMETHING *opt1; | ||
217 | * ASN1_SOMEOTHER *opt2; | ||
218 | * } value; | ||
219 | * } chname; | ||
220 | * | ||
221 | * the name of the selector must be 'type'. | ||
222 | * to use an alternative selector name use the | ||
223 | * ASN1_CHOICE_END_selector() version. | ||
224 | */ | ||
225 | |||
226 | #define ASN1_CHOICE(tname) \ | ||
227 | const static ASN1_TEMPLATE tname##_ch_tt[] | ||
228 | |||
229 | #define ASN1_CHOICE_cb(tname, cb) \ | ||
230 | const static ASN1_AUX tname##_aux = {NULL, 0, 0, 0, cb, 0}; \ | ||
231 | ASN1_CHOICE(tname) | ||
232 | |||
233 | #define ASN1_CHOICE_END(stname) ASN1_CHOICE_END_name(stname, stname) | ||
234 | |||
235 | #define ASN1_CHOICE_END_name(stname, tname) ASN1_CHOICE_END_selector(stname, tname, type) | ||
236 | |||
237 | #define ASN1_CHOICE_END_selector(stname, tname, selname) \ | ||
238 | ;\ | ||
239 | ASN1_ITEM_start(tname) \ | ||
240 | ASN1_ITYPE_CHOICE,\ | ||
241 | offsetof(stname,selname) ,\ | ||
242 | tname##_ch_tt,\ | ||
243 | sizeof(tname##_ch_tt) / sizeof(ASN1_TEMPLATE),\ | ||
244 | NULL,\ | ||
245 | sizeof(stname),\ | ||
246 | #stname \ | ||
247 | ASN1_ITEM_end(tname) | ||
248 | |||
249 | #define ASN1_CHOICE_END_cb(stname, tname, selname) \ | ||
250 | ;\ | ||
251 | ASN1_ITEM_start(tname) \ | ||
252 | ASN1_ITYPE_CHOICE,\ | ||
253 | offsetof(stname,selname) ,\ | ||
254 | tname##_ch_tt,\ | ||
255 | sizeof(tname##_ch_tt) / sizeof(ASN1_TEMPLATE),\ | ||
256 | &tname##_aux,\ | ||
257 | sizeof(stname),\ | ||
258 | #stname \ | ||
259 | ASN1_ITEM_end(tname) | ||
260 | |||
261 | /* This helps with the template wrapper form of ASN1_ITEM */ | ||
262 | |||
263 | #define ASN1_EX_TEMPLATE_TYPE(flags, tag, name, type) { \ | ||
264 | (flags), (tag), 0,\ | ||
265 | #name, ASN1_ITEM_ref(type) } | ||
266 | |||
267 | /* These help with SEQUENCE or CHOICE components */ | ||
268 | |||
269 | /* used to declare other types */ | ||
270 | |||
271 | #define ASN1_EX_TYPE(flags, tag, stname, field, type) { \ | ||
272 | (flags), (tag), offsetof(stname, field),\ | ||
273 | #field, ASN1_ITEM_ref(type) } | ||
274 | |||
275 | /* used when the structure is combined with the parent */ | ||
276 | |||
277 | #define ASN1_EX_COMBINE(flags, tag, type) { \ | ||
278 | (flags)|ASN1_TFLG_COMBINE, (tag), 0, NULL, ASN1_ITEM_ref(type) } | ||
279 | |||
280 | /* implicit and explicit helper macros */ | ||
281 | |||
282 | #define ASN1_IMP_EX(stname, field, type, tag, ex) \ | ||
283 | ASN1_EX_TYPE(ASN1_TFLG_IMPLICIT | ex, tag, stname, field, type) | ||
284 | |||
285 | #define ASN1_EXP_EX(stname, field, type, tag, ex) \ | ||
286 | ASN1_EX_TYPE(ASN1_TFLG_EXPLICIT | ex, tag, stname, field, type) | ||
287 | |||
288 | /* Any defined by macros: the field used is in the table itself */ | ||
289 | |||
290 | #ifndef OPENSSL_EXPORT_VAR_AS_FUNCTION | ||
291 | #define ASN1_ADB_OBJECT(tblname) { ASN1_TFLG_ADB_OID, -1, 0, #tblname, (const ASN1_ITEM *)&(tblname##_adb) } | ||
292 | #define ASN1_ADB_INTEGER(tblname) { ASN1_TFLG_ADB_INT, -1, 0, #tblname, (const ASN1_ITEM *)&(tblname##_adb) } | ||
293 | #else | ||
294 | #define ASN1_ADB_OBJECT(tblname) { ASN1_TFLG_ADB_OID, -1, 0, #tblname, tblname##_adb } | ||
295 | #define ASN1_ADB_INTEGER(tblname) { ASN1_TFLG_ADB_INT, -1, 0, #tblname, tblname##_adb } | ||
296 | #endif | ||
297 | /* Plain simple type */ | ||
298 | #define ASN1_SIMPLE(stname, field, type) ASN1_EX_TYPE(0,0, stname, field, type) | ||
299 | |||
300 | /* OPTIONAL simple type */ | ||
301 | #define ASN1_OPT(stname, field, type) ASN1_EX_TYPE(ASN1_TFLG_OPTIONAL, 0, stname, field, type) | ||
302 | |||
303 | /* IMPLICIT tagged simple type */ | ||
304 | #define ASN1_IMP(stname, field, type, tag) ASN1_IMP_EX(stname, field, type, tag, 0) | ||
305 | |||
306 | /* IMPLICIT tagged OPTIONAL simple type */ | ||
307 | #define ASN1_IMP_OPT(stname, field, type, tag) ASN1_IMP_EX(stname, field, type, tag, ASN1_TFLG_OPTIONAL) | ||
308 | |||
309 | /* Same as above but EXPLICIT */ | ||
310 | |||
311 | #define ASN1_EXP(stname, field, type, tag) ASN1_EXP_EX(stname, field, type, tag, 0) | ||
312 | #define ASN1_EXP_OPT(stname, field, type, tag) ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_OPTIONAL) | ||
313 | |||
314 | /* SEQUENCE OF type */ | ||
315 | #define ASN1_SEQUENCE_OF(stname, field, type) \ | ||
316 | ASN1_EX_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, stname, field, type) | ||
317 | |||
318 | /* OPTIONAL SEQUENCE OF */ | ||
319 | #define ASN1_SEQUENCE_OF_OPT(stname, field, type) \ | ||
320 | ASN1_EX_TYPE(ASN1_TFLG_SEQUENCE_OF|ASN1_TFLG_OPTIONAL, 0, stname, field, type) | ||
321 | |||
322 | /* Same as above but for SET OF */ | ||
323 | |||
324 | #define ASN1_SET_OF(stname, field, type) \ | ||
325 | ASN1_EX_TYPE(ASN1_TFLG_SET_OF, 0, stname, field, type) | ||
326 | |||
327 | #define ASN1_SET_OF_OPT(stname, field, type) \ | ||
328 | ASN1_EX_TYPE(ASN1_TFLG_SET_OF|ASN1_TFLG_OPTIONAL, 0, stname, field, type) | ||
329 | |||
330 | /* Finally compound types of SEQUENCE, SET, IMPLICIT, EXPLICIT and OPTIONAL */ | ||
331 | |||
332 | #define ASN1_IMP_SET_OF(stname, field, type, tag) \ | ||
333 | ASN1_IMP_EX(stname, field, type, tag, ASN1_TFLG_SET_OF) | ||
334 | |||
335 | #define ASN1_EXP_SET_OF(stname, field, type, tag) \ | ||
336 | ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_SET_OF) | ||
337 | |||
338 | #define ASN1_IMP_SET_OF_OPT(stname, field, type, tag) \ | ||
339 | ASN1_IMP_EX(stname, field, type, tag, ASN1_TFLG_SET_OF|ASN1_TFLG_OPTIONAL) | ||
340 | |||
341 | #define ASN1_EXP_SET_OF_OPT(stname, field, type, tag) \ | ||
342 | ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_SET_OF|ASN1_TFLG_OPTIONAL) | ||
343 | |||
344 | #define ASN1_IMP_SEQUENCE_OF(stname, field, type, tag) \ | ||
345 | ASN1_IMP_EX(stname, field, type, tag, ASN1_TFLG_SEQUENCE_OF) | ||
346 | |||
347 | #define ASN1_IMP_SEQUENCE_OF_OPT(stname, field, type, tag) \ | ||
348 | ASN1_IMP_EX(stname, field, type, tag, ASN1_TFLG_SEQUENCE_OF|ASN1_TFLG_OPTIONAL) | ||
349 | |||
350 | #define ASN1_EXP_SEQUENCE_OF(stname, field, type, tag) \ | ||
351 | ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_SEQUENCE_OF) | ||
352 | |||
353 | #define ASN1_EXP_SEQUENCE_OF_OPT(stname, field, type, tag) \ | ||
354 | ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_SEQUENCE_OF|ASN1_TFLG_OPTIONAL) | ||
355 | |||
356 | /* Macros for the ASN1_ADB structure */ | ||
357 | |||
358 | #define ASN1_ADB(name) \ | ||
359 | const static ASN1_ADB_TABLE name##_adbtbl[] | ||
360 | |||
361 | #ifndef OPENSSL_EXPORT_VAR_AS_FUNCTION | ||
362 | |||
363 | #define ASN1_ADB_END(name, flags, field, app_table, def, none) \ | ||
364 | ;\ | ||
365 | const static ASN1_ADB name##_adb = {\ | ||
366 | flags,\ | ||
367 | offsetof(name, field),\ | ||
368 | app_table,\ | ||
369 | name##_adbtbl,\ | ||
370 | sizeof(name##_adbtbl) / sizeof(ASN1_ADB_TABLE),\ | ||
371 | def,\ | ||
372 | none\ | ||
373 | } | ||
374 | |||
375 | #else | ||
376 | |||
377 | #define ASN1_ADB_END(name, flags, field, app_table, def, none) \ | ||
378 | ;\ | ||
379 | const static ASN1_ITEM *name##_adb(void) \ | ||
380 | { \ | ||
381 | const static ASN1_ADB internal_adb = \ | ||
382 | {\ | ||
383 | flags,\ | ||
384 | offsetof(name, field),\ | ||
385 | app_table,\ | ||
386 | name##_adbtbl,\ | ||
387 | sizeof(name##_adbtbl) / sizeof(ASN1_ADB_TABLE),\ | ||
388 | def,\ | ||
389 | none\ | ||
390 | }; \ | ||
391 | return (const ASN1_ITEM *) &internal_adb; \ | ||
392 | } \ | ||
393 | void dummy_function(void) | ||
394 | |||
395 | #endif | ||
396 | |||
397 | #define ADB_ENTRY(val, template) {val, template} | ||
398 | |||
399 | #define ASN1_ADB_TEMPLATE(name) \ | ||
400 | const static ASN1_TEMPLATE name##_tt | ||
401 | |||
402 | /* This is the ASN1 template structure that defines | ||
403 | * a wrapper round the actual type. It determines the | ||
404 | * actual position of the field in the value structure, | ||
405 | * various flags such as OPTIONAL and the field name. | ||
406 | */ | ||
407 | |||
408 | struct ASN1_TEMPLATE_st { | ||
409 | unsigned long flags; /* Various flags */ | ||
410 | long tag; /* tag, not used if no tagging */ | ||
411 | unsigned long offset; /* Offset of this field in structure */ | ||
412 | #ifndef NO_ASN1_FIELD_NAMES | ||
413 | char *field_name; /* Field name */ | ||
414 | #endif | ||
415 | ASN1_ITEM_EXP *item; /* Relevant ASN1_ITEM or ASN1_ADB */ | ||
416 | }; | ||
417 | |||
418 | /* Macro to extract ASN1_ITEM and ASN1_ADB pointer from ASN1_TEMPLATE */ | ||
419 | |||
420 | #define ASN1_TEMPLATE_item(t) (t->item_ptr) | ||
421 | #define ASN1_TEMPLATE_adb(t) (t->item_ptr) | ||
422 | |||
423 | typedef struct ASN1_ADB_TABLE_st ASN1_ADB_TABLE; | ||
424 | typedef struct ASN1_ADB_st ASN1_ADB; | ||
425 | |||
426 | struct ASN1_ADB_st { | ||
427 | unsigned long flags; /* Various flags */ | ||
428 | unsigned long offset; /* Offset of selector field */ | ||
429 | STACK_OF(ASN1_ADB_TABLE) **app_items; /* Application defined items */ | ||
430 | const ASN1_ADB_TABLE *tbl; /* Table of possible types */ | ||
431 | long tblcount; /* Number of entries in tbl */ | ||
432 | const ASN1_TEMPLATE *default_tt; /* Type to use if no match */ | ||
433 | const ASN1_TEMPLATE *null_tt; /* Type to use if selector is NULL */ | ||
434 | }; | ||
435 | |||
436 | struct ASN1_ADB_TABLE_st { | ||
437 | long value; /* NID for an object or value for an int */ | ||
438 | const ASN1_TEMPLATE tt; /* item for this value */ | ||
439 | }; | ||
440 | |||
441 | /* template flags */ | ||
442 | |||
443 | /* Field is optional */ | ||
444 | #define ASN1_TFLG_OPTIONAL (0x1) | ||
445 | |||
446 | /* Field is a SET OF */ | ||
447 | #define ASN1_TFLG_SET_OF (0x1 << 1) | ||
448 | |||
449 | /* Field is a SEQUENCE OF */ | ||
450 | #define ASN1_TFLG_SEQUENCE_OF (0x2 << 1) | ||
451 | |||
452 | /* Special case: this refers to a SET OF that | ||
453 | * will be sorted into DER order when encoded *and* | ||
454 | * the corresponding STACK will be modified to match | ||
455 | * the new order. | ||
456 | */ | ||
457 | #define ASN1_TFLG_SET_ORDER (0x3 << 1) | ||
458 | |||
459 | /* Mask for SET OF or SEQUENCE OF */ | ||
460 | #define ASN1_TFLG_SK_MASK (0x3 << 1) | ||
461 | |||
462 | /* These flags mean the tag should be taken from the | ||
463 | * tag field. If EXPLICIT then the underlying type | ||
464 | * is used for the inner tag. | ||
465 | */ | ||
466 | |||
467 | /* IMPLICIT tagging */ | ||
468 | #define ASN1_TFLG_IMPTAG (0x1 << 3) | ||
469 | |||
470 | |||
471 | /* EXPLICIT tagging, inner tag from underlying type */ | ||
472 | #define ASN1_TFLG_EXPTAG (0x2 << 3) | ||
473 | |||
474 | #define ASN1_TFLG_TAG_MASK (0x3 << 3) | ||
475 | |||
476 | /* context specific IMPLICIT */ | ||
477 | #define ASN1_TFLG_IMPLICIT ASN1_TFLG_IMPTAG|ASN1_TFLG_CONTEXT | ||
478 | |||
479 | /* context specific EXPLICIT */ | ||
480 | #define ASN1_TFLG_EXPLICIT ASN1_TFLG_EXPTAG|ASN1_TFLG_CONTEXT | ||
481 | |||
482 | /* If tagging is in force these determine the | ||
483 | * type of tag to use. Otherwise the tag is | ||
484 | * determined by the underlying type. These | ||
485 | * values reflect the actual octet format. | ||
486 | */ | ||
487 | |||
488 | /* Universal tag */ | ||
489 | #define ASN1_TFLG_UNIVERSAL (0x0<<6) | ||
490 | /* Application tag */ | ||
491 | #define ASN1_TFLG_APPLICATION (0x1<<6) | ||
492 | /* Context specific tag */ | ||
493 | #define ASN1_TFLG_CONTEXT (0x2<<6) | ||
494 | /* Private tag */ | ||
495 | #define ASN1_TFLG_PRIVATE (0x3<<6) | ||
496 | |||
497 | #define ASN1_TFLG_TAG_CLASS (0x3<<6) | ||
498 | |||
499 | /* These are for ANY DEFINED BY type. In this case | ||
500 | * the 'item' field points to an ASN1_ADB structure | ||
501 | * which contains a table of values to decode the | ||
502 | * relevant type | ||
503 | */ | ||
504 | |||
505 | #define ASN1_TFLG_ADB_MASK (0x3<<8) | ||
506 | |||
507 | #define ASN1_TFLG_ADB_OID (0x1<<8) | ||
508 | |||
509 | #define ASN1_TFLG_ADB_INT (0x1<<9) | ||
510 | |||
511 | /* This flag means a parent structure is passed | ||
512 | * instead of the field: this is useful is a | ||
513 | * SEQUENCE is being combined with a CHOICE for | ||
514 | * example. Since this means the structure and | ||
515 | * item name will differ we need to use the | ||
516 | * ASN1_CHOICE_END_name() macro for example. | ||
517 | */ | ||
518 | |||
519 | #define ASN1_TFLG_COMBINE (0x1<<10) | ||
520 | |||
521 | /* This is the actual ASN1 item itself */ | ||
522 | |||
523 | struct ASN1_ITEM_st { | ||
524 | char itype; /* The item type, primitive, SEQUENCE, CHOICE or extern */ | ||
525 | long utype; /* underlying type */ | ||
526 | const ASN1_TEMPLATE *templates; /* If SEQUENCE or CHOICE this contains the contents */ | ||
527 | long tcount; /* Number of templates if SEQUENCE or CHOICE */ | ||
528 | const void *funcs; /* functions that handle this type */ | ||
529 | long size; /* Structure size (usually)*/ | ||
530 | #ifndef NO_ASN1_FIELD_NAMES | ||
531 | const char *sname; /* Structure name */ | ||
532 | #endif | ||
533 | }; | ||
534 | |||
535 | /* These are values for the itype field and | ||
536 | * determine how the type is interpreted. | ||
537 | * | ||
538 | * For PRIMITIVE types the underlying type | ||
539 | * determines the behaviour if items is NULL. | ||
540 | * | ||
541 | * Otherwise templates must contain a single | ||
542 | * template and the type is treated in the | ||
543 | * same way as the type specified in the template. | ||
544 | * | ||
545 | * For SEQUENCE types the templates field points | ||
546 | * to the members, the size field is the | ||
547 | * structure size. | ||
548 | * | ||
549 | * For CHOICE types the templates field points | ||
550 | * to each possible member (typically a union) | ||
551 | * and the 'size' field is the offset of the | ||
552 | * selector. | ||
553 | * | ||
554 | * The 'funcs' field is used for application | ||
555 | * specific functions. | ||
556 | * | ||
557 | * For COMPAT types the funcs field gives a | ||
558 | * set of functions that handle this type, this | ||
559 | * supports the old d2i, i2d convention. | ||
560 | * | ||
561 | * The EXTERN type uses a new style d2i/i2d. | ||
562 | * The new style should be used where possible | ||
563 | * because it avoids things like the d2i IMPLICIT | ||
564 | * hack. | ||
565 | * | ||
566 | * MSTRING is a multiple string type, it is used | ||
567 | * for a CHOICE of character strings where the | ||
568 | * actual strings all occupy an ASN1_STRING | ||
569 | * structure. In this case the 'utype' field | ||
570 | * has a special meaning, it is used as a mask | ||
571 | * of acceptable types using the B_ASN1 constants. | ||
572 | * | ||
573 | */ | ||
574 | |||
575 | #define ASN1_ITYPE_PRIMITIVE 0x0 | ||
576 | |||
577 | #define ASN1_ITYPE_SEQUENCE 0x1 | ||
578 | |||
579 | #define ASN1_ITYPE_CHOICE 0x2 | ||
580 | |||
581 | #define ASN1_ITYPE_COMPAT 0x3 | ||
582 | |||
583 | #define ASN1_ITYPE_EXTERN 0x4 | ||
584 | |||
585 | #define ASN1_ITYPE_MSTRING 0x5 | ||
586 | |||
587 | /* Cache for ASN1 tag and length, so we | ||
588 | * don't keep re-reading it for things | ||
589 | * like CHOICE | ||
590 | */ | ||
591 | |||
592 | struct ASN1_TLC_st{ | ||
593 | char valid; /* Values below are valid */ | ||
594 | int ret; /* return value */ | ||
595 | long plen; /* length */ | ||
596 | int ptag; /* class value */ | ||
597 | int pclass; /* class value */ | ||
598 | int hdrlen; /* header length */ | ||
599 | }; | ||
600 | |||
601 | /* Typedefs for ASN1 function pointers */ | ||
602 | |||
603 | typedef ASN1_VALUE * ASN1_new_func(void); | ||
604 | typedef void ASN1_free_func(ASN1_VALUE *a); | ||
605 | typedef ASN1_VALUE * ASN1_d2i_func(ASN1_VALUE **a, unsigned char ** in, long length); | ||
606 | typedef int ASN1_i2d_func(ASN1_VALUE * a, unsigned char **in); | ||
607 | |||
608 | typedef int ASN1_ex_d2i(ASN1_VALUE **pval, unsigned char **in, long len, const ASN1_ITEM *it, | ||
609 | int tag, int aclass, char opt, ASN1_TLC *ctx); | ||
610 | |||
611 | typedef int ASN1_ex_i2d(ASN1_VALUE **pval, unsigned char **out, const ASN1_ITEM *it, int tag, int aclass); | ||
612 | typedef int ASN1_ex_new_func(ASN1_VALUE **pval, const ASN1_ITEM *it); | ||
613 | typedef void ASN1_ex_free_func(ASN1_VALUE **pval, const ASN1_ITEM *it); | ||
614 | |||
615 | typedef int ASN1_primitive_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype, const ASN1_ITEM *it); | ||
616 | typedef int ASN1_primitive_c2i(ASN1_VALUE **pval, unsigned char *cont, int len, int utype, char *free_cont, const ASN1_ITEM *it); | ||
617 | |||
618 | typedef struct ASN1_COMPAT_FUNCS_st { | ||
619 | ASN1_new_func *asn1_new; | ||
620 | ASN1_free_func *asn1_free; | ||
621 | ASN1_d2i_func *asn1_d2i; | ||
622 | ASN1_i2d_func *asn1_i2d; | ||
623 | } ASN1_COMPAT_FUNCS; | ||
624 | |||
625 | typedef struct ASN1_EXTERN_FUNCS_st { | ||
626 | void *app_data; | ||
627 | ASN1_ex_new_func *asn1_ex_new; | ||
628 | ASN1_ex_free_func *asn1_ex_free; | ||
629 | ASN1_ex_free_func *asn1_ex_clear; | ||
630 | ASN1_ex_d2i *asn1_ex_d2i; | ||
631 | ASN1_ex_i2d *asn1_ex_i2d; | ||
632 | } ASN1_EXTERN_FUNCS; | ||
633 | |||
634 | typedef struct ASN1_PRIMITIVE_FUNCS_st { | ||
635 | void *app_data; | ||
636 | unsigned long flags; | ||
637 | ASN1_ex_new_func *prim_new; | ||
638 | ASN1_ex_free_func *prim_free; | ||
639 | ASN1_ex_free_func *prim_clear; | ||
640 | ASN1_primitive_c2i *prim_c2i; | ||
641 | ASN1_primitive_i2c *prim_i2c; | ||
642 | } ASN1_PRIMITIVE_FUNCS; | ||
643 | |||
644 | /* This is the ASN1_AUX structure: it handles various | ||
645 | * miscellaneous requirements. For example the use of | ||
646 | * reference counts and an informational callback. | ||
647 | * | ||
648 | * The "informational callback" is called at various | ||
649 | * points during the ASN1 encoding and decoding. It can | ||
650 | * be used to provide minor customisation of the structures | ||
651 | * used. This is most useful where the supplied routines | ||
652 | * *almost* do the right thing but need some extra help | ||
653 | * at a few points. If the callback returns zero then | ||
654 | * it is assumed a fatal error has occurred and the | ||
655 | * main operation should be abandoned. | ||
656 | * | ||
657 | * If major changes in the default behaviour are required | ||
658 | * then an external type is more appropriate. | ||
659 | */ | ||
660 | |||
661 | typedef int ASN1_aux_cb(int operation, ASN1_VALUE **in, const ASN1_ITEM *it); | ||
662 | |||
663 | typedef struct ASN1_AUX_st { | ||
664 | void *app_data; | ||
665 | int flags; | ||
666 | int ref_offset; /* Offset of reference value */ | ||
667 | int ref_lock; /* Lock type to use */ | ||
668 | ASN1_aux_cb *asn1_cb; | ||
669 | int enc_offset; /* Offset of ASN1_ENCODING structure */ | ||
670 | } ASN1_AUX; | ||
671 | |||
672 | /* Flags in ASN1_AUX */ | ||
673 | |||
674 | /* Use a reference count */ | ||
675 | #define ASN1_AFLG_REFCOUNT 1 | ||
676 | /* Save the encoding of structure (useful for signatures) */ | ||
677 | #define ASN1_AFLG_ENCODING 2 | ||
678 | /* The Sequence length is invalid */ | ||
679 | #define ASN1_AFLG_BROKEN 4 | ||
680 | |||
681 | /* operation values for asn1_cb */ | ||
682 | |||
683 | #define ASN1_OP_NEW_PRE 0 | ||
684 | #define ASN1_OP_NEW_POST 1 | ||
685 | #define ASN1_OP_FREE_PRE 2 | ||
686 | #define ASN1_OP_FREE_POST 3 | ||
687 | #define ASN1_OP_D2I_PRE 4 | ||
688 | #define ASN1_OP_D2I_POST 5 | ||
689 | #define ASN1_OP_I2D_PRE 6 | ||
690 | #define ASN1_OP_I2D_POST 7 | ||
691 | |||
692 | /* Macro to implement a primitive type */ | ||
693 | #define IMPLEMENT_ASN1_TYPE(stname) IMPLEMENT_ASN1_TYPE_ex(stname, stname, 0) | ||
694 | #define IMPLEMENT_ASN1_TYPE_ex(itname, vname, ex) \ | ||
695 | ASN1_ITEM_start(itname) \ | ||
696 | ASN1_ITYPE_PRIMITIVE, V_##vname, NULL, 0, NULL, ex, #itname \ | ||
697 | ASN1_ITEM_end(itname) | ||
698 | |||
699 | /* Macro to implement a multi string type */ | ||
700 | #define IMPLEMENT_ASN1_MSTRING(itname, mask) \ | ||
701 | ASN1_ITEM_start(itname) \ | ||
702 | ASN1_ITYPE_MSTRING, mask, NULL, 0, NULL, sizeof(ASN1_STRING), #itname \ | ||
703 | ASN1_ITEM_end(itname) | ||
704 | |||
705 | /* Macro to implement an ASN1_ITEM in terms of old style funcs */ | ||
706 | |||
707 | #define IMPLEMENT_COMPAT_ASN1(sname) IMPLEMENT_COMPAT_ASN1_type(sname, V_ASN1_SEQUENCE) | ||
708 | |||
709 | #define IMPLEMENT_COMPAT_ASN1_type(sname, tag) \ | ||
710 | static const ASN1_COMPAT_FUNCS sname##_ff = { \ | ||
711 | (ASN1_new_func *)sname##_new, \ | ||
712 | (ASN1_free_func *)sname##_free, \ | ||
713 | (ASN1_d2i_func *)d2i_##sname, \ | ||
714 | (ASN1_i2d_func *)i2d_##sname, \ | ||
715 | }; \ | ||
716 | ASN1_ITEM_start(sname) \ | ||
717 | ASN1_ITYPE_COMPAT, \ | ||
718 | tag, \ | ||
719 | NULL, \ | ||
720 | 0, \ | ||
721 | &sname##_ff, \ | ||
722 | 0, \ | ||
723 | #sname \ | ||
724 | ASN1_ITEM_end(sname) | ||
725 | |||
726 | #define IMPLEMENT_EXTERN_ASN1(sname, tag, fptrs) \ | ||
727 | ASN1_ITEM_start(sname) \ | ||
728 | ASN1_ITYPE_EXTERN, \ | ||
729 | tag, \ | ||
730 | NULL, \ | ||
731 | 0, \ | ||
732 | &fptrs, \ | ||
733 | 0, \ | ||
734 | #sname \ | ||
735 | ASN1_ITEM_end(sname) | ||
736 | |||
737 | /* Macro to implement standard functions in terms of ASN1_ITEM structures */ | ||
738 | |||
739 | #define IMPLEMENT_ASN1_FUNCTIONS(stname) IMPLEMENT_ASN1_FUNCTIONS_fname(stname, stname, stname) | ||
740 | |||
741 | #define IMPLEMENT_ASN1_FUNCTIONS_name(stname, itname) IMPLEMENT_ASN1_FUNCTIONS_fname(stname, itname, itname) | ||
742 | |||
743 | #define IMPLEMENT_ASN1_FUNCTIONS_ENCODE_name(stname, itname) \ | ||
744 | IMPLEMENT_ASN1_FUNCTIONS_ENCODE_fname(stname, itname, itname) | ||
745 | |||
746 | #define IMPLEMENT_ASN1_ALLOC_FUNCTIONS_fname(stname, itname, fname) \ | ||
747 | stname *fname##_new(void) \ | ||
748 | { \ | ||
749 | return (stname *)ASN1_item_new(ASN1_ITEM_rptr(itname)); \ | ||
750 | } \ | ||
751 | void fname##_free(stname *a) \ | ||
752 | { \ | ||
753 | ASN1_item_free((ASN1_VALUE *)a, ASN1_ITEM_rptr(itname)); \ | ||
754 | } | ||
755 | |||
756 | #define IMPLEMENT_ASN1_FUNCTIONS_fname(stname, itname, fname) \ | ||
757 | IMPLEMENT_ASN1_ENCODE_FUNCTIONS_fname(stname, itname, fname) \ | ||
758 | IMPLEMENT_ASN1_ALLOC_FUNCTIONS_fname(stname, itname, fname) | ||
759 | |||
760 | #define IMPLEMENT_ASN1_ENCODE_FUNCTIONS_fname(stname, itname, fname) \ | ||
761 | stname *d2i_##fname(stname **a, unsigned char **in, long len) \ | ||
762 | { \ | ||
763 | return (stname *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, ASN1_ITEM_rptr(itname));\ | ||
764 | } \ | ||
765 | int i2d_##fname(stname *a, unsigned char **out) \ | ||
766 | { \ | ||
767 | return ASN1_item_i2d((ASN1_VALUE *)a, out, ASN1_ITEM_rptr(itname));\ | ||
768 | } | ||
769 | |||
770 | /* This includes evil casts to remove const: they will go away when full | ||
771 | * ASN1 constification is done. | ||
772 | */ | ||
773 | #define IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(stname, itname, fname) \ | ||
774 | stname *d2i_##fname(stname **a, const unsigned char **in, long len) \ | ||
775 | { \ | ||
776 | return (stname *)ASN1_item_d2i((ASN1_VALUE **)a, (unsigned char **)in, len, ASN1_ITEM_rptr(itname));\ | ||
777 | } \ | ||
778 | int i2d_##fname(const stname *a, unsigned char **out) \ | ||
779 | { \ | ||
780 | return ASN1_item_i2d((ASN1_VALUE *)a, out, ASN1_ITEM_rptr(itname));\ | ||
781 | } | ||
782 | |||
783 | #define IMPLEMENT_ASN1_DUP_FUNCTION(stname) \ | ||
784 | stname * stname##_dup(stname *x) \ | ||
785 | { \ | ||
786 | return ASN1_item_dup(ASN1_ITEM_rptr(stname), x); \ | ||
787 | } | ||
788 | |||
789 | #define IMPLEMENT_ASN1_FUNCTIONS_const(name) \ | ||
790 | IMPLEMENT_ASN1_FUNCTIONS_const_fname(name, name, name) | ||
791 | |||
792 | #define IMPLEMENT_ASN1_FUNCTIONS_const_fname(stname, itname, fname) \ | ||
793 | IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(stname, itname, fname) \ | ||
794 | IMPLEMENT_ASN1_ALLOC_FUNCTIONS_fname(stname, itname, fname) | ||
795 | |||
796 | /* external definitions for primitive types */ | ||
797 | |||
798 | DECLARE_ASN1_ITEM(ASN1_BOOLEAN) | ||
799 | DECLARE_ASN1_ITEM(ASN1_TBOOLEAN) | ||
800 | DECLARE_ASN1_ITEM(ASN1_FBOOLEAN) | ||
801 | DECLARE_ASN1_ITEM(ASN1_ANY) | ||
802 | DECLARE_ASN1_ITEM(ASN1_SEQUENCE) | ||
803 | DECLARE_ASN1_ITEM(CBIGNUM) | ||
804 | DECLARE_ASN1_ITEM(BIGNUM) | ||
805 | DECLARE_ASN1_ITEM(LONG) | ||
806 | DECLARE_ASN1_ITEM(ZLONG) | ||
807 | |||
808 | DECLARE_STACK_OF(ASN1_VALUE) | ||
809 | |||
810 | /* Functions used internally by the ASN1 code */ | ||
811 | |||
812 | int ASN1_item_ex_new(ASN1_VALUE **pval, const ASN1_ITEM *it); | ||
813 | void ASN1_item_ex_free(ASN1_VALUE **pval, const ASN1_ITEM *it); | ||
814 | int ASN1_template_new(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt); | ||
815 | int ASN1_primitive_new(ASN1_VALUE **pval, const ASN1_ITEM *it); | ||
816 | |||
817 | void ASN1_template_free(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt); | ||
818 | int ASN1_template_d2i(ASN1_VALUE **pval, unsigned char **in, long len, const ASN1_TEMPLATE *tt); | ||
819 | int ASN1_item_ex_d2i(ASN1_VALUE **pval, unsigned char **in, long len, const ASN1_ITEM *it, | ||
820 | int tag, int aclass, char opt, ASN1_TLC *ctx); | ||
821 | |||
822 | int ASN1_item_ex_i2d(ASN1_VALUE **pval, unsigned char **out, const ASN1_ITEM *it, int tag, int aclass); | ||
823 | int ASN1_template_i2d(ASN1_VALUE **pval, unsigned char **out, const ASN1_TEMPLATE *tt); | ||
824 | void ASN1_primitive_free(ASN1_VALUE **pval, const ASN1_ITEM *it); | ||
825 | |||
826 | int asn1_ex_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype, const ASN1_ITEM *it); | ||
827 | int asn1_ex_c2i(ASN1_VALUE **pval, unsigned char *cont, int len, int utype, char *free_cont, const ASN1_ITEM *it); | ||
828 | |||
829 | int asn1_get_choice_selector(ASN1_VALUE **pval, const ASN1_ITEM *it); | ||
830 | int asn1_set_choice_selector(ASN1_VALUE **pval, int value, const ASN1_ITEM *it); | ||
831 | |||
832 | ASN1_VALUE ** asn1_get_field_ptr(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt); | ||
833 | |||
834 | const ASN1_TEMPLATE *asn1_do_adb(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt, int nullerr); | ||
835 | |||
836 | int asn1_do_lock(ASN1_VALUE **pval, int op, const ASN1_ITEM *it); | ||
837 | |||
838 | void asn1_enc_init(ASN1_VALUE **pval, const ASN1_ITEM *it); | ||
839 | void asn1_enc_free(ASN1_VALUE **pval, const ASN1_ITEM *it); | ||
840 | int asn1_enc_restore(int *len, unsigned char **out, ASN1_VALUE **pval, const ASN1_ITEM *it); | ||
841 | int asn1_enc_save(ASN1_VALUE **pval, unsigned char *in, int inlen, const ASN1_ITEM *it); | ||
842 | |||
843 | #ifdef __cplusplus | ||
844 | } | ||
845 | #endif | ||
846 | #endif | ||
diff --git a/src/lib/libcrypto/asn1/asn_moid.c b/src/lib/libcrypto/asn1/asn_moid.c new file mode 100644 index 0000000000..be20db4bad --- /dev/null +++ b/src/lib/libcrypto/asn1/asn_moid.c | |||
@@ -0,0 +1,95 @@ | |||
1 | /* asn_moid.c */ | ||
2 | /* Written by Stephen Henson (shenson@bigfoot.com) for the OpenSSL | ||
3 | * project 2001. | ||
4 | */ | ||
5 | /* ==================================================================== | ||
6 | * Copyright (c) 2001 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 | #include <openssl/crypto.h> | ||
61 | #include "cryptlib.h" | ||
62 | #include <openssl/conf.h> | ||
63 | #include <openssl/dso.h> | ||
64 | #include <openssl/x509.h> | ||
65 | |||
66 | /* Simple ASN1 OID module: add all objects in a given section */ | ||
67 | |||
68 | static int oid_module_init(CONF_IMODULE *md, const CONF *cnf) | ||
69 | { | ||
70 | int i; | ||
71 | const char *oid_section; | ||
72 | STACK_OF(CONF_VALUE) *sktmp; | ||
73 | CONF_VALUE *oval; | ||
74 | oid_section = CONF_imodule_get_value(md); | ||
75 | if(!(sktmp = NCONF_get_section(cnf, oid_section))) | ||
76 | { | ||
77 | ASN1err(ASN1_F_OID_MODULE_INIT, ASN1_R_ERROR_LOADING_SECTION); | ||
78 | return 0; | ||
79 | } | ||
80 | for(i = 0; i < sk_CONF_VALUE_num(sktmp); i++) | ||
81 | { | ||
82 | oval = sk_CONF_VALUE_value(sktmp, i); | ||
83 | if(OBJ_create(oval->value, oval->name, oval->name) == NID_undef) | ||
84 | { | ||
85 | ASN1err(ASN1_F_OID_MODULE_INIT, ASN1_R_ADDING_OBJECT); | ||
86 | return 0; | ||
87 | } | ||
88 | } | ||
89 | return 1; | ||
90 | } | ||
91 | |||
92 | void ASN1_add_oid_module(void) | ||
93 | { | ||
94 | CONF_module_add("oid_section", oid_module_init, 0); | ||
95 | } | ||
diff --git a/src/lib/libcrypto/asn1/asn_pack.c b/src/lib/libcrypto/asn1/asn_pack.c new file mode 100644 index 0000000000..662a2626a1 --- /dev/null +++ b/src/lib/libcrypto/asn1/asn_pack.c | |||
@@ -0,0 +1,145 @@ | |||
1 | /* asn_pack.c */ | ||
2 | /* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL | ||
3 | * project 1999. | ||
4 | */ | ||
5 | /* ==================================================================== | ||
6 | * Copyright (c) 1999 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 | #include "cryptlib.h" | ||
61 | #include <openssl/asn1.h> | ||
62 | |||
63 | /* ASN1 packing and unpacking functions */ | ||
64 | |||
65 | /* Turn an ASN1 encoded SEQUENCE OF into a STACK of structures */ | ||
66 | |||
67 | STACK *ASN1_seq_unpack(unsigned char *buf, int len, char *(*d2i)(), | ||
68 | void (*free_func)()) | ||
69 | { | ||
70 | STACK *sk; | ||
71 | unsigned char *pbuf; | ||
72 | pbuf = buf; | ||
73 | if (!(sk = d2i_ASN1_SET(NULL, &pbuf, len, d2i, free_func, | ||
74 | V_ASN1_SEQUENCE, V_ASN1_UNIVERSAL))) | ||
75 | ASN1err(ASN1_F_ASN1_SEQ_UNPACK,ASN1_R_DECODE_ERROR); | ||
76 | return sk; | ||
77 | } | ||
78 | |||
79 | /* Turn a STACK structures into an ASN1 encoded SEQUENCE OF structure in a | ||
80 | * Malloc'ed buffer | ||
81 | */ | ||
82 | |||
83 | unsigned char *ASN1_seq_pack(STACK *safes, int (*i2d)(), unsigned char **buf, | ||
84 | int *len) | ||
85 | { | ||
86 | int safelen; | ||
87 | unsigned char *safe, *p; | ||
88 | if (!(safelen = i2d_ASN1_SET(safes, NULL, i2d, V_ASN1_SEQUENCE, | ||
89 | V_ASN1_UNIVERSAL, IS_SEQUENCE))) { | ||
90 | ASN1err(ASN1_F_ASN1_SEQ_PACK,ASN1_R_ENCODE_ERROR); | ||
91 | return NULL; | ||
92 | } | ||
93 | if (!(safe = Malloc (safelen))) { | ||
94 | ASN1err(ASN1_F_ASN1_SEQ_PACK,ERR_R_MALLOC_FAILURE); | ||
95 | return NULL; | ||
96 | } | ||
97 | p = safe; | ||
98 | i2d_ASN1_SET(safes, &p, i2d, V_ASN1_SEQUENCE, V_ASN1_UNIVERSAL, | ||
99 | IS_SEQUENCE); | ||
100 | if (len) *len = safelen; | ||
101 | if (buf) *buf = safe; | ||
102 | return safe; | ||
103 | } | ||
104 | |||
105 | /* Extract an ASN1 object from an ASN1_STRING */ | ||
106 | |||
107 | void *ASN1_unpack_string (ASN1_STRING *oct, char *(*d2i)()) | ||
108 | { | ||
109 | unsigned char *p; | ||
110 | char *ret; | ||
111 | |||
112 | p = oct->data; | ||
113 | if(!(ret = d2i(NULL, &p, oct->length))) | ||
114 | ASN1err(ASN1_F_ASN1_UNPACK_STRING,ASN1_R_DECODE_ERROR); | ||
115 | return ret; | ||
116 | } | ||
117 | |||
118 | /* Pack an ASN1 object into an ASN1_STRING */ | ||
119 | |||
120 | ASN1_STRING *ASN1_pack_string (void *obj, int (*i2d)(), ASN1_STRING **oct) | ||
121 | { | ||
122 | unsigned char *p; | ||
123 | ASN1_STRING *octmp; | ||
124 | |||
125 | if (!oct || !*oct) { | ||
126 | if (!(octmp = ASN1_STRING_new ())) { | ||
127 | ASN1err(ASN1_F_ASN1_PACK_STRING,ERR_R_MALLOC_FAILURE); | ||
128 | return NULL; | ||
129 | } | ||
130 | if (oct) *oct = octmp; | ||
131 | } else octmp = *oct; | ||
132 | |||
133 | if (!(octmp->length = i2d(obj, NULL))) { | ||
134 | ASN1err(ASN1_F_ASN1_PACK_STRING,ASN1_R_ENCODE_ERROR); | ||
135 | return NULL; | ||
136 | } | ||
137 | if (!(p = Malloc (octmp->length))) { | ||
138 | ASN1err(ASN1_F_ASN1_PACK_STRING,ERR_R_MALLOC_FAILURE); | ||
139 | return NULL; | ||
140 | } | ||
141 | octmp->data = p; | ||
142 | i2d (obj, &p); | ||
143 | return octmp; | ||
144 | } | ||
145 | |||
diff --git a/src/lib/libcrypto/asn1/charmap.h b/src/lib/libcrypto/asn1/charmap.h new file mode 100644 index 0000000000..bd020a9562 --- /dev/null +++ b/src/lib/libcrypto/asn1/charmap.h | |||
@@ -0,0 +1,15 @@ | |||
1 | /* Auto generated with chartype.pl script. | ||
2 | * Mask of various character properties | ||
3 | */ | ||
4 | |||
5 | static unsigned char char_type[] = { | ||
6 | 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, | ||
7 | 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, | ||
8 | 120, 0, 1,40, 0, 0, 0,16,16,16, 0,25,25,16,16,16, | ||
9 | 16,16,16,16,16,16,16,16,16,16,16, 9, 9,16, 9,16, | ||
10 | 0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, | ||
11 | 16,16,16,16,16,16,16,16,16,16,16, 0, 1, 0, 0, 0, | ||
12 | 0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, | ||
13 | 16,16,16,16,16,16,16,16,16,16,16, 0, 0, 0, 0, 2 | ||
14 | }; | ||
15 | |||
diff --git a/src/lib/libcrypto/asn1/charmap.pl b/src/lib/libcrypto/asn1/charmap.pl new file mode 100644 index 0000000000..2875c59867 --- /dev/null +++ b/src/lib/libcrypto/asn1/charmap.pl | |||
@@ -0,0 +1,80 @@ | |||
1 | #!/usr/local/bin/perl -w | ||
2 | |||
3 | use strict; | ||
4 | |||
5 | my ($i, @arr); | ||
6 | |||
7 | # Set up an array with the type of ASCII characters | ||
8 | # Each set bit represents a character property. | ||
9 | |||
10 | # RFC2253 character properties | ||
11 | my $RFC2253_ESC = 1; # Character escaped with \ | ||
12 | my $ESC_CTRL = 2; # Escaped control character | ||
13 | # These are used with RFC1779 quoting using " | ||
14 | my $NOESC_QUOTE = 8; # Not escaped if quoted | ||
15 | my $PSTRING_CHAR = 0x10; # Valid PrintableString character | ||
16 | my $RFC2253_FIRST_ESC = 0x20; # Escaped with \ if first character | ||
17 | my $RFC2253_LAST_ESC = 0x40; # Escaped with \ if last character | ||
18 | |||
19 | for($i = 0; $i < 128; $i++) { | ||
20 | # Set the RFC2253 escape characters (control) | ||
21 | $arr[$i] = 0; | ||
22 | if(($i < 32) || ($i > 126)) { | ||
23 | $arr[$i] |= $ESC_CTRL; | ||
24 | } | ||
25 | |||
26 | # Some PrintableString characters | ||
27 | if( ( ( $i >= ord("a")) && ( $i <= ord("z")) ) | ||
28 | || ( ( $i >= ord("A")) && ( $i <= ord("Z")) ) | ||
29 | || ( ( $i >= ord("0")) && ( $i <= ord("9")) ) ) { | ||
30 | $arr[$i] |= $PSTRING_CHAR; | ||
31 | } | ||
32 | } | ||
33 | |||
34 | # Now setup the rest | ||
35 | |||
36 | # Remaining RFC2253 escaped characters | ||
37 | |||
38 | $arr[ord(" ")] |= $NOESC_QUOTE | $RFC2253_FIRST_ESC | $RFC2253_LAST_ESC; | ||
39 | $arr[ord("#")] |= $NOESC_QUOTE | $RFC2253_FIRST_ESC; | ||
40 | |||
41 | $arr[ord(",")] |= $NOESC_QUOTE | $RFC2253_ESC; | ||
42 | $arr[ord("+")] |= $NOESC_QUOTE | $RFC2253_ESC; | ||
43 | $arr[ord("\"")] |= $RFC2253_ESC; | ||
44 | $arr[ord("\\")] |= $RFC2253_ESC; | ||
45 | $arr[ord("<")] |= $NOESC_QUOTE | $RFC2253_ESC; | ||
46 | $arr[ord(">")] |= $NOESC_QUOTE | $RFC2253_ESC; | ||
47 | $arr[ord(";")] |= $NOESC_QUOTE | $RFC2253_ESC; | ||
48 | |||
49 | # Remaining PrintableString characters | ||
50 | |||
51 | $arr[ord(" ")] |= $PSTRING_CHAR; | ||
52 | $arr[ord("'")] |= $PSTRING_CHAR; | ||
53 | $arr[ord("(")] |= $PSTRING_CHAR; | ||
54 | $arr[ord(")")] |= $PSTRING_CHAR; | ||
55 | $arr[ord("+")] |= $PSTRING_CHAR; | ||
56 | $arr[ord(",")] |= $PSTRING_CHAR; | ||
57 | $arr[ord("-")] |= $PSTRING_CHAR; | ||
58 | $arr[ord(".")] |= $PSTRING_CHAR; | ||
59 | $arr[ord("/")] |= $PSTRING_CHAR; | ||
60 | $arr[ord(":")] |= $PSTRING_CHAR; | ||
61 | $arr[ord("=")] |= $PSTRING_CHAR; | ||
62 | $arr[ord("?")] |= $PSTRING_CHAR; | ||
63 | |||
64 | # Now generate the C code | ||
65 | |||
66 | print <<EOF; | ||
67 | /* Auto generated with chartype.pl script. | ||
68 | * Mask of various character properties | ||
69 | */ | ||
70 | |||
71 | static unsigned char char_type[] = { | ||
72 | EOF | ||
73 | |||
74 | for($i = 0; $i < 128; $i++) { | ||
75 | print("\n") if($i && (($i % 16) == 0)); | ||
76 | printf("%2d", $arr[$i]); | ||
77 | print(",") if ($i != 127); | ||
78 | } | ||
79 | print("\n};\n\n"); | ||
80 | |||
diff --git a/src/lib/libcrypto/asn1/f_enum.c b/src/lib/libcrypto/asn1/f_enum.c new file mode 100644 index 0000000000..3bcceecdb8 --- /dev/null +++ b/src/lib/libcrypto/asn1/f_enum.c | |||
@@ -0,0 +1,207 @@ | |||
1 | /* crypto/asn1/f_enum.c */ | ||
2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) | ||
3 | * All rights reserved. | ||
4 | * | ||
5 | * This package is an SSL implementation written | ||
6 | * by Eric Young (eay@cryptsoft.com). | ||
7 | * The implementation was written so as to conform with Netscapes SSL. | ||
8 | * | ||
9 | * This library is free for commercial and non-commercial use as long as | ||
10 | * the following conditions are aheared to. The following conditions | ||
11 | * apply to all code found in this distribution, be it the RC4, RSA, | ||
12 | * lhash, DES, etc., code; not just the SSL code. The SSL documentation | ||
13 | * included with this distribution is covered by the same copyright terms | ||
14 | * except that the holder is Tim Hudson (tjh@cryptsoft.com). | ||
15 | * | ||
16 | * Copyright remains Eric Young's, and as such any Copyright notices in | ||
17 | * the code are not to be removed. | ||
18 | * If this package is used in a product, Eric Young should be given attribution | ||
19 | * as the author of the parts of the library used. | ||
20 | * This can be in the form of a textual message at program startup or | ||
21 | * in documentation (online or textual) provided with the package. | ||
22 | * | ||
23 | * Redistribution and use in source and binary forms, with or without | ||
24 | * modification, are permitted provided that the following conditions | ||
25 | * are met: | ||
26 | * 1. Redistributions of source code must retain the copyright | ||
27 | * notice, this list of conditions and the following disclaimer. | ||
28 | * 2. Redistributions in binary form must reproduce the above copyright | ||
29 | * notice, this list of conditions and the following disclaimer in the | ||
30 | * documentation and/or other materials provided with the distribution. | ||
31 | * 3. All advertising materials mentioning features or use of this software | ||
32 | * must display the following acknowledgement: | ||
33 | * "This product includes cryptographic software written by | ||
34 | * Eric Young (eay@cryptsoft.com)" | ||
35 | * The word 'cryptographic' can be left out if the rouines from the library | ||
36 | * being used are not cryptographic related :-). | ||
37 | * 4. If you include any Windows specific code (or a derivative thereof) from | ||
38 | * the apps directory (application code) you must include an acknowledgement: | ||
39 | * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" | ||
40 | * | ||
41 | * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND | ||
42 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
43 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
44 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | ||
45 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
46 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
47 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
48 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
49 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
50 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
51 | * SUCH DAMAGE. | ||
52 | * | ||
53 | * The licence and distribution terms for any publically available version or | ||
54 | * derivative of this code cannot be changed. i.e. this code cannot simply be | ||
55 | * copied and put under another distribution licence | ||
56 | * [including the GNU Public Licence.] | ||
57 | */ | ||
58 | |||
59 | #include <stdio.h> | ||
60 | #include "cryptlib.h" | ||
61 | #include <openssl/buffer.h> | ||
62 | #include <openssl/asn1.h> | ||
63 | |||
64 | /* Based on a_int.c: equivalent ENUMERATED functions */ | ||
65 | |||
66 | int i2a_ASN1_ENUMERATED(BIO *bp, ASN1_ENUMERATED *a) | ||
67 | { | ||
68 | int i,n=0; | ||
69 | static const char *h="0123456789ABCDEF"; | ||
70 | char buf[2]; | ||
71 | |||
72 | if (a == NULL) return(0); | ||
73 | |||
74 | if (a->length == 0) | ||
75 | { | ||
76 | if (BIO_write(bp,"00",2) != 2) goto err; | ||
77 | n=2; | ||
78 | } | ||
79 | else | ||
80 | { | ||
81 | for (i=0; i<a->length; i++) | ||
82 | { | ||
83 | if ((i != 0) && (i%35 == 0)) | ||
84 | { | ||
85 | if (BIO_write(bp,"\\\n",2) != 2) goto err; | ||
86 | n+=2; | ||
87 | } | ||
88 | buf[0]=h[((unsigned char)a->data[i]>>4)&0x0f]; | ||
89 | buf[1]=h[((unsigned char)a->data[i] )&0x0f]; | ||
90 | if (BIO_write(bp,buf,2) != 2) goto err; | ||
91 | n+=2; | ||
92 | } | ||
93 | } | ||
94 | return(n); | ||
95 | err: | ||
96 | return(-1); | ||
97 | } | ||
98 | |||
99 | int a2i_ASN1_ENUMERATED(BIO *bp, ASN1_ENUMERATED *bs, char *buf, int size) | ||
100 | { | ||
101 | int ret=0; | ||
102 | int i,j,k,m,n,again,bufsize; | ||
103 | unsigned char *s=NULL,*sp; | ||
104 | unsigned char *bufp; | ||
105 | int num=0,slen=0,first=1; | ||
106 | |||
107 | bs->type=V_ASN1_ENUMERATED; | ||
108 | |||
109 | bufsize=BIO_gets(bp,buf,size); | ||
110 | for (;;) | ||
111 | { | ||
112 | if (bufsize < 1) goto err_sl; | ||
113 | i=bufsize; | ||
114 | if (buf[i-1] == '\n') buf[--i]='\0'; | ||
115 | if (i == 0) goto err_sl; | ||
116 | if (buf[i-1] == '\r') buf[--i]='\0'; | ||
117 | if (i == 0) goto err_sl; | ||
118 | again=(buf[i-1] == '\\'); | ||
119 | |||
120 | for (j=0; j<i; j++) | ||
121 | { | ||
122 | if (!( ((buf[j] >= '0') && (buf[j] <= '9')) || | ||
123 | ((buf[j] >= 'a') && (buf[j] <= 'f')) || | ||
124 | ((buf[j] >= 'A') && (buf[j] <= 'F')))) | ||
125 | { | ||
126 | i=j; | ||
127 | break; | ||
128 | } | ||
129 | } | ||
130 | buf[i]='\0'; | ||
131 | /* We have now cleared all the crap off the end of the | ||
132 | * line */ | ||
133 | if (i < 2) goto err_sl; | ||
134 | |||
135 | bufp=(unsigned char *)buf; | ||
136 | if (first) | ||
137 | { | ||
138 | first=0; | ||
139 | if ((bufp[0] == '0') && (buf[1] == '0')) | ||
140 | { | ||
141 | bufp+=2; | ||
142 | i-=2; | ||
143 | } | ||
144 | } | ||
145 | k=0; | ||
146 | i-=again; | ||
147 | if (i%2 != 0) | ||
148 | { | ||
149 | ASN1err(ASN1_F_A2I_ASN1_ENUMERATED,ASN1_R_ODD_NUMBER_OF_CHARS); | ||
150 | goto err; | ||
151 | } | ||
152 | i/=2; | ||
153 | if (num+i > slen) | ||
154 | { | ||
155 | if (s == NULL) | ||
156 | sp=(unsigned char *)Malloc( | ||
157 | (unsigned int)num+i*2); | ||
158 | else | ||
159 | sp=(unsigned char *)Realloc(s, | ||
160 | (unsigned int)num+i*2); | ||
161 | if (sp == NULL) | ||
162 | { | ||
163 | ASN1err(ASN1_F_A2I_ASN1_ENUMERATED,ERR_R_MALLOC_FAILURE); | ||
164 | if (s != NULL) Free((char *)s); | ||
165 | goto err; | ||
166 | } | ||
167 | s=sp; | ||
168 | slen=num+i*2; | ||
169 | } | ||
170 | for (j=0; j<i; j++,k+=2) | ||
171 | { | ||
172 | for (n=0; n<2; n++) | ||
173 | { | ||
174 | m=bufp[k+n]; | ||
175 | if ((m >= '0') && (m <= '9')) | ||
176 | m-='0'; | ||
177 | else if ((m >= 'a') && (m <= 'f')) | ||
178 | m=m-'a'+10; | ||
179 | else if ((m >= 'A') && (m <= 'F')) | ||
180 | m=m-'A'+10; | ||
181 | else | ||
182 | { | ||
183 | ASN1err(ASN1_F_A2I_ASN1_ENUMERATED,ASN1_R_NON_HEX_CHARACTERS); | ||
184 | goto err; | ||
185 | } | ||
186 | s[num+j]<<=4; | ||
187 | s[num+j]|=m; | ||
188 | } | ||
189 | } | ||
190 | num+=i; | ||
191 | if (again) | ||
192 | bufsize=BIO_gets(bp,buf,size); | ||
193 | else | ||
194 | break; | ||
195 | } | ||
196 | bs->length=num; | ||
197 | bs->data=s; | ||
198 | ret=1; | ||
199 | err: | ||
200 | if (0) | ||
201 | { | ||
202 | err_sl: | ||
203 | ASN1err(ASN1_F_A2I_ASN1_ENUMERATED,ASN1_R_SHORT_LINE); | ||
204 | } | ||
205 | return(ret); | ||
206 | } | ||
207 | |||
diff --git a/src/lib/libcrypto/asn1/nsseq.c b/src/lib/libcrypto/asn1/nsseq.c new file mode 100644 index 0000000000..417d024b81 --- /dev/null +++ b/src/lib/libcrypto/asn1/nsseq.c | |||
@@ -0,0 +1,118 @@ | |||
1 | /* nsseq.c */ | ||
2 | /* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL | ||
3 | * project 1999. | ||
4 | */ | ||
5 | /* ==================================================================== | ||
6 | * Copyright (c) 1999 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 | #include <stdlib.h> | ||
61 | #include <openssl/asn1_mac.h> | ||
62 | #include <openssl/err.h> | ||
63 | #include <openssl/x509.h> | ||
64 | #include <openssl/objects.h> | ||
65 | |||
66 | /* Netscape certificate sequence structure */ | ||
67 | |||
68 | int i2d_NETSCAPE_CERT_SEQUENCE(NETSCAPE_CERT_SEQUENCE *a, unsigned char **pp) | ||
69 | { | ||
70 | int v = 0; | ||
71 | M_ASN1_I2D_vars(a); | ||
72 | M_ASN1_I2D_len (a->type, i2d_ASN1_OBJECT); | ||
73 | M_ASN1_I2D_len_EXP_SEQUENCE_opt_type(X509,a->certs,i2d_X509,0, | ||
74 | V_ASN1_SEQUENCE,v); | ||
75 | |||
76 | M_ASN1_I2D_seq_total(); | ||
77 | |||
78 | M_ASN1_I2D_put (a->type, i2d_ASN1_OBJECT); | ||
79 | M_ASN1_I2D_put_EXP_SEQUENCE_opt_type(X509,a->certs,i2d_X509,0, | ||
80 | V_ASN1_SEQUENCE,v); | ||
81 | |||
82 | M_ASN1_I2D_finish(); | ||
83 | } | ||
84 | |||
85 | NETSCAPE_CERT_SEQUENCE *NETSCAPE_CERT_SEQUENCE_new(void) | ||
86 | { | ||
87 | NETSCAPE_CERT_SEQUENCE *ret=NULL; | ||
88 | ASN1_CTX c; | ||
89 | M_ASN1_New_Malloc(ret, NETSCAPE_CERT_SEQUENCE); | ||
90 | /* Note hardcoded object type */ | ||
91 | ret->type = OBJ_nid2obj(NID_netscape_cert_sequence); | ||
92 | ret->certs = NULL; | ||
93 | return (ret); | ||
94 | M_ASN1_New_Error(ASN1_F_NETSCAPE_CERT_SEQUENCE_NEW); | ||
95 | } | ||
96 | |||
97 | NETSCAPE_CERT_SEQUENCE *d2i_NETSCAPE_CERT_SEQUENCE(NETSCAPE_CERT_SEQUENCE **a, | ||
98 | unsigned char **pp, long length) | ||
99 | { | ||
100 | M_ASN1_D2I_vars(a,NETSCAPE_CERT_SEQUENCE *, | ||
101 | NETSCAPE_CERT_SEQUENCE_new); | ||
102 | M_ASN1_D2I_Init(); | ||
103 | M_ASN1_D2I_start_sequence(); | ||
104 | M_ASN1_D2I_get (ret->type, d2i_ASN1_OBJECT); | ||
105 | M_ASN1_D2I_get_EXP_set_opt_type(X509,ret->certs,d2i_X509,X509_free,0, | ||
106 | V_ASN1_SEQUENCE); | ||
107 | M_ASN1_D2I_Finish(a, NETSCAPE_CERT_SEQUENCE_free, | ||
108 | ASN1_F_D2I_NETSCAPE_CERT_SEQUENCE); | ||
109 | } | ||
110 | |||
111 | void NETSCAPE_CERT_SEQUENCE_free (NETSCAPE_CERT_SEQUENCE *a) | ||
112 | { | ||
113 | if (a == NULL) return; | ||
114 | ASN1_OBJECT_free(a->type); | ||
115 | if(a->certs) | ||
116 | sk_X509_pop_free(a->certs, X509_free); | ||
117 | Free (a); | ||
118 | } | ||
diff --git a/src/lib/libcrypto/asn1/p5_pbe.c b/src/lib/libcrypto/asn1/p5_pbe.c new file mode 100644 index 0000000000..b831836e7b --- /dev/null +++ b/src/lib/libcrypto/asn1/p5_pbe.c | |||
@@ -0,0 +1,156 @@ | |||
1 | /* p5_pbe.c */ | ||
2 | /* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL | ||
3 | * project 1999. | ||
4 | */ | ||
5 | /* ==================================================================== | ||
6 | * Copyright (c) 1999 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 | #include "cryptlib.h" | ||
61 | #include <openssl/asn1_mac.h> | ||
62 | #include <openssl/x509.h> | ||
63 | #include <openssl/rand.h> | ||
64 | |||
65 | /* PKCS#5 password based encryption structure */ | ||
66 | |||
67 | int i2d_PBEPARAM(PBEPARAM *a, unsigned char **pp) | ||
68 | { | ||
69 | M_ASN1_I2D_vars(a); | ||
70 | M_ASN1_I2D_len (a->salt, i2d_ASN1_OCTET_STRING); | ||
71 | M_ASN1_I2D_len (a->iter, i2d_ASN1_INTEGER); | ||
72 | |||
73 | M_ASN1_I2D_seq_total (); | ||
74 | |||
75 | M_ASN1_I2D_put (a->salt, i2d_ASN1_OCTET_STRING); | ||
76 | M_ASN1_I2D_put (a->iter, i2d_ASN1_INTEGER); | ||
77 | M_ASN1_I2D_finish(); | ||
78 | } | ||
79 | |||
80 | PBEPARAM *PBEPARAM_new(void) | ||
81 | { | ||
82 | PBEPARAM *ret=NULL; | ||
83 | ASN1_CTX c; | ||
84 | M_ASN1_New_Malloc(ret, PBEPARAM); | ||
85 | M_ASN1_New(ret->iter,ASN1_INTEGER_new); | ||
86 | M_ASN1_New(ret->salt,ASN1_OCTET_STRING_new); | ||
87 | return (ret); | ||
88 | M_ASN1_New_Error(ASN1_F_PBEPARAM_NEW); | ||
89 | } | ||
90 | |||
91 | PBEPARAM *d2i_PBEPARAM(PBEPARAM **a, unsigned char **pp, long length) | ||
92 | { | ||
93 | M_ASN1_D2I_vars(a,PBEPARAM *,PBEPARAM_new); | ||
94 | M_ASN1_D2I_Init(); | ||
95 | M_ASN1_D2I_start_sequence(); | ||
96 | M_ASN1_D2I_get (ret->salt, d2i_ASN1_OCTET_STRING); | ||
97 | M_ASN1_D2I_get (ret->iter, d2i_ASN1_INTEGER); | ||
98 | M_ASN1_D2I_Finish(a, PBEPARAM_free, ASN1_F_D2I_PBEPARAM); | ||
99 | } | ||
100 | |||
101 | void PBEPARAM_free (PBEPARAM *a) | ||
102 | { | ||
103 | if(a==NULL) return; | ||
104 | ASN1_OCTET_STRING_free(a->salt); | ||
105 | ASN1_INTEGER_free (a->iter); | ||
106 | Free ((char *)a); | ||
107 | } | ||
108 | |||
109 | /* Return an algorithm identifier for a PKCS#5 PBE algorithm */ | ||
110 | |||
111 | X509_ALGOR *PKCS5_pbe_set(int alg, int iter, unsigned char *salt, | ||
112 | int saltlen) | ||
113 | { | ||
114 | PBEPARAM *pbe; | ||
115 | ASN1_OBJECT *al; | ||
116 | X509_ALGOR *algor; | ||
117 | ASN1_TYPE *astype; | ||
118 | |||
119 | if (!(pbe = PBEPARAM_new ())) { | ||
120 | ASN1err(ASN1_F_ASN1_PBE_SET,ERR_R_MALLOC_FAILURE); | ||
121 | return NULL; | ||
122 | } | ||
123 | if(iter <= 0) iter = PKCS5_DEFAULT_ITER; | ||
124 | ASN1_INTEGER_set (pbe->iter, iter); | ||
125 | if (!saltlen) saltlen = PKCS5_SALT_LEN; | ||
126 | if (!(pbe->salt->data = Malloc (saltlen))) { | ||
127 | ASN1err(ASN1_F_ASN1_PBE_SET,ERR_R_MALLOC_FAILURE); | ||
128 | return NULL; | ||
129 | } | ||
130 | pbe->salt->length = saltlen; | ||
131 | if (salt) memcpy (pbe->salt->data, salt, saltlen); | ||
132 | else RAND_bytes (pbe->salt->data, saltlen); | ||
133 | |||
134 | if (!(astype = ASN1_TYPE_new())) { | ||
135 | ASN1err(ASN1_F_ASN1_PBE_SET,ERR_R_MALLOC_FAILURE); | ||
136 | return NULL; | ||
137 | } | ||
138 | |||
139 | astype->type = V_ASN1_SEQUENCE; | ||
140 | if(!ASN1_pack_string(pbe, i2d_PBEPARAM, &astype->value.sequence)) { | ||
141 | ASN1err(ASN1_F_ASN1_PBE_SET,ERR_R_MALLOC_FAILURE); | ||
142 | return NULL; | ||
143 | } | ||
144 | PBEPARAM_free (pbe); | ||
145 | |||
146 | al = OBJ_nid2obj(alg); /* never need to free al */ | ||
147 | if (!(algor = X509_ALGOR_new())) { | ||
148 | ASN1err(ASN1_F_ASN1_PBE_SET,ERR_R_MALLOC_FAILURE); | ||
149 | return NULL; | ||
150 | } | ||
151 | ASN1_OBJECT_free(algor->algorithm); | ||
152 | algor->algorithm = al; | ||
153 | algor->parameter = astype; | ||
154 | |||
155 | return (algor); | ||
156 | } | ||
diff --git a/src/lib/libcrypto/asn1/p5_pbev2.c b/src/lib/libcrypto/asn1/p5_pbev2.c new file mode 100644 index 0000000000..09f4bf6112 --- /dev/null +++ b/src/lib/libcrypto/asn1/p5_pbev2.c | |||
@@ -0,0 +1,274 @@ | |||
1 | /* p5_pbev2.c */ | ||
2 | /* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL | ||
3 | * project 1999. | ||
4 | */ | ||
5 | /* ==================================================================== | ||
6 | * Copyright (c) 1999 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 | #include "cryptlib.h" | ||
61 | #include <openssl/asn1_mac.h> | ||
62 | #include <openssl/x509.h> | ||
63 | #include <openssl/rand.h> | ||
64 | |||
65 | /* PKCS#5 v2.0 password based encryption structures */ | ||
66 | |||
67 | int i2d_PBE2PARAM(PBE2PARAM *a, unsigned char **pp) | ||
68 | { | ||
69 | M_ASN1_I2D_vars(a); | ||
70 | M_ASN1_I2D_len (a->keyfunc, i2d_X509_ALGOR); | ||
71 | M_ASN1_I2D_len (a->encryption, i2d_X509_ALGOR); | ||
72 | |||
73 | M_ASN1_I2D_seq_total (); | ||
74 | |||
75 | M_ASN1_I2D_put (a->keyfunc, i2d_X509_ALGOR); | ||
76 | M_ASN1_I2D_put (a->encryption, i2d_X509_ALGOR); | ||
77 | |||
78 | M_ASN1_I2D_finish(); | ||
79 | } | ||
80 | |||
81 | PBE2PARAM *PBE2PARAM_new(void) | ||
82 | { | ||
83 | PBE2PARAM *ret=NULL; | ||
84 | ASN1_CTX c; | ||
85 | M_ASN1_New_Malloc(ret, PBE2PARAM); | ||
86 | M_ASN1_New(ret->keyfunc,X509_ALGOR_new); | ||
87 | M_ASN1_New(ret->encryption,X509_ALGOR_new); | ||
88 | return (ret); | ||
89 | M_ASN1_New_Error(ASN1_F_PBE2PARAM_NEW); | ||
90 | } | ||
91 | |||
92 | PBE2PARAM *d2i_PBE2PARAM(PBE2PARAM **a, unsigned char **pp, long length) | ||
93 | { | ||
94 | M_ASN1_D2I_vars(a,PBE2PARAM *,PBE2PARAM_new); | ||
95 | M_ASN1_D2I_Init(); | ||
96 | M_ASN1_D2I_start_sequence(); | ||
97 | M_ASN1_D2I_get (ret->keyfunc, d2i_X509_ALGOR); | ||
98 | M_ASN1_D2I_get (ret->encryption, d2i_X509_ALGOR); | ||
99 | M_ASN1_D2I_Finish(a, PBE2PARAM_free, ASN1_F_D2I_PBE2PARAM); | ||
100 | } | ||
101 | |||
102 | void PBE2PARAM_free (PBE2PARAM *a) | ||
103 | { | ||
104 | if(a==NULL) return; | ||
105 | X509_ALGOR_free(a->keyfunc); | ||
106 | X509_ALGOR_free(a->encryption); | ||
107 | Free ((char *)a); | ||
108 | } | ||
109 | |||
110 | int i2d_PBKDF2PARAM(PBKDF2PARAM *a, unsigned char **pp) | ||
111 | { | ||
112 | M_ASN1_I2D_vars(a); | ||
113 | M_ASN1_I2D_len (a->salt, i2d_ASN1_TYPE); | ||
114 | M_ASN1_I2D_len (a->iter, i2d_ASN1_INTEGER); | ||
115 | M_ASN1_I2D_len (a->keylength, i2d_ASN1_INTEGER); | ||
116 | M_ASN1_I2D_len (a->prf, i2d_X509_ALGOR); | ||
117 | |||
118 | M_ASN1_I2D_seq_total (); | ||
119 | |||
120 | M_ASN1_I2D_put (a->salt, i2d_ASN1_TYPE); | ||
121 | M_ASN1_I2D_put (a->iter, i2d_ASN1_INTEGER); | ||
122 | M_ASN1_I2D_put (a->keylength, i2d_ASN1_INTEGER); | ||
123 | M_ASN1_I2D_put (a->prf, i2d_X509_ALGOR); | ||
124 | |||
125 | M_ASN1_I2D_finish(); | ||
126 | } | ||
127 | |||
128 | PBKDF2PARAM *PBKDF2PARAM_new(void) | ||
129 | { | ||
130 | PBKDF2PARAM *ret=NULL; | ||
131 | ASN1_CTX c; | ||
132 | M_ASN1_New_Malloc(ret, PBKDF2PARAM); | ||
133 | M_ASN1_New(ret->salt, ASN1_TYPE_new); | ||
134 | M_ASN1_New(ret->iter, ASN1_INTEGER_new); | ||
135 | ret->keylength = NULL; | ||
136 | ret->prf = NULL; | ||
137 | return (ret); | ||
138 | M_ASN1_New_Error(ASN1_F_PBKDF2PARAM_NEW); | ||
139 | } | ||
140 | |||
141 | PBKDF2PARAM *d2i_PBKDF2PARAM(PBKDF2PARAM **a, unsigned char **pp, | ||
142 | long length) | ||
143 | { | ||
144 | M_ASN1_D2I_vars(a,PBKDF2PARAM *,PBKDF2PARAM_new); | ||
145 | M_ASN1_D2I_Init(); | ||
146 | M_ASN1_D2I_start_sequence(); | ||
147 | M_ASN1_D2I_get (ret->salt, d2i_ASN1_TYPE); | ||
148 | M_ASN1_D2I_get (ret->iter, d2i_ASN1_INTEGER); | ||
149 | M_ASN1_D2I_get_opt (ret->keylength, d2i_ASN1_INTEGER, V_ASN1_INTEGER); | ||
150 | M_ASN1_D2I_get_opt (ret->prf, d2i_X509_ALGOR, V_ASN1_SEQUENCE); | ||
151 | M_ASN1_D2I_Finish(a, PBKDF2PARAM_free, ASN1_F_D2I_PBKDF2PARAM); | ||
152 | } | ||
153 | |||
154 | void PBKDF2PARAM_free (PBKDF2PARAM *a) | ||
155 | { | ||
156 | if(a==NULL) return; | ||
157 | ASN1_TYPE_free(a->salt); | ||
158 | ASN1_INTEGER_free(a->iter); | ||
159 | ASN1_INTEGER_free(a->keylength); | ||
160 | X509_ALGOR_free(a->prf); | ||
161 | Free ((char *)a); | ||
162 | } | ||
163 | |||
164 | /* Return an algorithm identifier for a PKCS#5 v2.0 PBE algorithm: | ||
165 | * yes I know this is horrible! | ||
166 | */ | ||
167 | |||
168 | X509_ALGOR *PKCS5_pbe2_set(const EVP_CIPHER *cipher, int iter, | ||
169 | unsigned char *salt, int saltlen) | ||
170 | { | ||
171 | X509_ALGOR *scheme = NULL, *kalg = NULL, *ret = NULL; | ||
172 | int alg_nid; | ||
173 | EVP_CIPHER_CTX ctx; | ||
174 | unsigned char iv[EVP_MAX_IV_LENGTH]; | ||
175 | PBKDF2PARAM *kdf = NULL; | ||
176 | PBE2PARAM *pbe2 = NULL; | ||
177 | ASN1_OCTET_STRING *osalt = NULL; | ||
178 | |||
179 | if(!(pbe2 = PBE2PARAM_new())) goto merr; | ||
180 | |||
181 | /* Setup the AlgorithmIdentifier for the encryption scheme */ | ||
182 | scheme = pbe2->encryption; | ||
183 | |||
184 | alg_nid = EVP_CIPHER_type(cipher); | ||
185 | |||
186 | scheme->algorithm = OBJ_nid2obj(alg_nid); | ||
187 | if(!(scheme->parameter = ASN1_TYPE_new())) goto merr; | ||
188 | |||
189 | /* Create random IV */ | ||
190 | RAND_bytes(iv, EVP_CIPHER_iv_length(cipher)); | ||
191 | |||
192 | /* Dummy cipherinit to just setup the IV */ | ||
193 | EVP_CipherInit(&ctx, cipher, NULL, iv, 0); | ||
194 | if(EVP_CIPHER_param_to_asn1(&ctx, scheme->parameter) < 0) { | ||
195 | ASN1err(ASN1_F_PKCS5_PBE2_SET, | ||
196 | ASN1_R_ERROR_SETTING_CIPHER_PARAMS); | ||
197 | goto err; | ||
198 | } | ||
199 | EVP_CIPHER_CTX_cleanup(&ctx); | ||
200 | |||
201 | if(!(kdf = PBKDF2PARAM_new())) goto merr; | ||
202 | if(!(osalt = ASN1_OCTET_STRING_new())) goto merr; | ||
203 | |||
204 | if (!saltlen) saltlen = PKCS5_SALT_LEN; | ||
205 | if (!(osalt->data = Malloc (saltlen))) goto merr; | ||
206 | osalt->length = saltlen; | ||
207 | if (salt) memcpy (osalt->data, salt, saltlen); | ||
208 | else RAND_bytes (osalt->data, saltlen); | ||
209 | |||
210 | if(iter <= 0) iter = PKCS5_DEFAULT_ITER; | ||
211 | if(!ASN1_INTEGER_set(kdf->iter, iter)) goto merr; | ||
212 | |||
213 | /* Now include salt in kdf structure */ | ||
214 | kdf->salt->value.octet_string = osalt; | ||
215 | kdf->salt->type = V_ASN1_OCTET_STRING; | ||
216 | osalt = NULL; | ||
217 | |||
218 | /* If its RC2 then we'd better setup the key length */ | ||
219 | |||
220 | if(alg_nid == NID_rc2_cbc) { | ||
221 | if(!(kdf->keylength = ASN1_INTEGER_new())) goto merr; | ||
222 | if(!ASN1_INTEGER_set (kdf->keylength, | ||
223 | EVP_CIPHER_key_length(cipher))) goto merr; | ||
224 | } | ||
225 | |||
226 | /* prf can stay NULL because we are using hmacWithSHA1 */ | ||
227 | |||
228 | /* Now setup the PBE2PARAM keyfunc structure */ | ||
229 | |||
230 | pbe2->keyfunc->algorithm = OBJ_nid2obj(NID_id_pbkdf2); | ||
231 | |||
232 | /* Encode PBKDF2PARAM into parameter of pbe2 */ | ||
233 | |||
234 | if(!(pbe2->keyfunc->parameter = ASN1_TYPE_new())) goto merr; | ||
235 | |||
236 | if(!ASN1_pack_string(kdf, i2d_PBKDF2PARAM, | ||
237 | &pbe2->keyfunc->parameter->value.sequence)) goto merr; | ||
238 | pbe2->keyfunc->parameter->type = V_ASN1_SEQUENCE; | ||
239 | |||
240 | PBKDF2PARAM_free(kdf); | ||
241 | kdf = NULL; | ||
242 | |||
243 | /* Now set up top level AlgorithmIdentifier */ | ||
244 | |||
245 | if(!(ret = X509_ALGOR_new())) goto merr; | ||
246 | if(!(ret->parameter = ASN1_TYPE_new())) goto merr; | ||
247 | |||
248 | ret->algorithm = OBJ_nid2obj(NID_pbes2); | ||
249 | |||
250 | /* Encode PBE2PARAM into parameter */ | ||
251 | |||
252 | if(!ASN1_pack_string(pbe2, i2d_PBE2PARAM, | ||
253 | &ret->parameter->value.sequence)) goto merr; | ||
254 | ret->parameter->type = V_ASN1_SEQUENCE; | ||
255 | |||
256 | PBE2PARAM_free(pbe2); | ||
257 | pbe2 = NULL; | ||
258 | |||
259 | return ret; | ||
260 | |||
261 | merr: | ||
262 | ASN1err(ASN1_F_PKCS5_PBE2_SET,ERR_R_MALLOC_FAILURE); | ||
263 | |||
264 | err: | ||
265 | PBE2PARAM_free(pbe2); | ||
266 | /* Note 'scheme' is freed as part of pbe2 */ | ||
267 | ASN1_OCTET_STRING_free(osalt); | ||
268 | PBKDF2PARAM_free(kdf); | ||
269 | X509_ALGOR_free(kalg); | ||
270 | X509_ALGOR_free(ret); | ||
271 | |||
272 | return NULL; | ||
273 | |||
274 | } | ||
diff --git a/src/lib/libcrypto/asn1/p8_pkey.c b/src/lib/libcrypto/asn1/p8_pkey.c new file mode 100644 index 0000000000..aa9a4f6c96 --- /dev/null +++ b/src/lib/libcrypto/asn1/p8_pkey.c | |||
@@ -0,0 +1,129 @@ | |||
1 | /* p8_pkey.c */ | ||
2 | /* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL | ||
3 | * project 1999. | ||
4 | */ | ||
5 | /* ==================================================================== | ||
6 | * Copyright (c) 1999 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 | #include "cryptlib.h" | ||
61 | #include <openssl/asn1_mac.h> | ||
62 | #include <openssl/x509.h> | ||
63 | |||
64 | int i2d_PKCS8_PRIV_KEY_INFO (PKCS8_PRIV_KEY_INFO *a, unsigned char **pp) | ||
65 | { | ||
66 | |||
67 | M_ASN1_I2D_vars(a); | ||
68 | |||
69 | M_ASN1_I2D_len (a->version, i2d_ASN1_INTEGER); | ||
70 | M_ASN1_I2D_len (a->pkeyalg, i2d_X509_ALGOR); | ||
71 | M_ASN1_I2D_len (a->pkey, i2d_ASN1_TYPE); | ||
72 | M_ASN1_I2D_len_IMP_SET_opt_type (X509_ATTRIBUTE, a->attributes, | ||
73 | i2d_X509_ATTRIBUTE, 0); | ||
74 | |||
75 | M_ASN1_I2D_seq_total (); | ||
76 | |||
77 | M_ASN1_I2D_put (a->version, i2d_ASN1_INTEGER); | ||
78 | M_ASN1_I2D_put (a->pkeyalg, i2d_X509_ALGOR); | ||
79 | M_ASN1_I2D_put (a->pkey, i2d_ASN1_TYPE); | ||
80 | M_ASN1_I2D_put_IMP_SET_opt_type (X509_ATTRIBUTE, a->attributes, | ||
81 | i2d_X509_ATTRIBUTE, 0); | ||
82 | |||
83 | M_ASN1_I2D_finish(); | ||
84 | } | ||
85 | |||
86 | PKCS8_PRIV_KEY_INFO *PKCS8_PRIV_KEY_INFO_new(void) | ||
87 | { | ||
88 | PKCS8_PRIV_KEY_INFO *ret=NULL; | ||
89 | ASN1_CTX c; | ||
90 | M_ASN1_New_Malloc(ret, PKCS8_PRIV_KEY_INFO); | ||
91 | M_ASN1_New (ret->version, ASN1_INTEGER_new); | ||
92 | M_ASN1_New (ret->pkeyalg, X509_ALGOR_new); | ||
93 | M_ASN1_New (ret->pkey, ASN1_TYPE_new); | ||
94 | ret->attributes = NULL; | ||
95 | ret->broken = PKCS8_OK; | ||
96 | return (ret); | ||
97 | M_ASN1_New_Error(ASN1_F_PKCS8_PRIV_KEY_INFO_NEW); | ||
98 | } | ||
99 | |||
100 | PKCS8_PRIV_KEY_INFO *d2i_PKCS8_PRIV_KEY_INFO(PKCS8_PRIV_KEY_INFO **a, | ||
101 | unsigned char **pp, long length) | ||
102 | { | ||
103 | M_ASN1_D2I_vars(a,PKCS8_PRIV_KEY_INFO *,PKCS8_PRIV_KEY_INFO_new); | ||
104 | M_ASN1_D2I_Init(); | ||
105 | M_ASN1_D2I_start_sequence(); | ||
106 | M_ASN1_D2I_get (ret->version, d2i_ASN1_INTEGER); | ||
107 | M_ASN1_D2I_get (ret->pkeyalg, d2i_X509_ALGOR); | ||
108 | M_ASN1_D2I_get (ret->pkey, d2i_ASN1_TYPE); | ||
109 | M_ASN1_D2I_get_IMP_set_opt_type(X509_ATTRIBUTE, ret->attributes, | ||
110 | d2i_X509_ATTRIBUTE, | ||
111 | X509_ATTRIBUTE_free, 0); | ||
112 | if (ASN1_TYPE_get(ret->pkey) == V_ASN1_SEQUENCE) | ||
113 | ret->broken = PKCS8_NO_OCTET; | ||
114 | M_ASN1_D2I_Finish(a, PKCS8_PRIV_KEY_INFO_free, ASN1_F_D2I_PKCS8_PRIV_KEY_INFO); | ||
115 | } | ||
116 | |||
117 | void PKCS8_PRIV_KEY_INFO_free (PKCS8_PRIV_KEY_INFO *a) | ||
118 | { | ||
119 | if (a == NULL) return; | ||
120 | ASN1_INTEGER_free (a->version); | ||
121 | X509_ALGOR_free(a->pkeyalg); | ||
122 | /* Clear sensitive data */ | ||
123 | if (a->pkey->value.octet_string) | ||
124 | memset (a->pkey->value.octet_string->data, | ||
125 | 0, a->pkey->value.octet_string->length); | ||
126 | ASN1_TYPE_free (a->pkey); | ||
127 | sk_X509_ATTRIBUTE_pop_free (a->attributes, X509_ATTRIBUTE_free); | ||
128 | Free (a); | ||
129 | } | ||
diff --git a/src/lib/libcrypto/asn1/t_bitst.c b/src/lib/libcrypto/asn1/t_bitst.c new file mode 100644 index 0000000000..8ee789f082 --- /dev/null +++ b/src/lib/libcrypto/asn1/t_bitst.c | |||
@@ -0,0 +1,99 @@ | |||
1 | /* t_bitst.c */ | ||
2 | /* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL | ||
3 | * project 1999. | ||
4 | */ | ||
5 | /* ==================================================================== | ||
6 | * Copyright (c) 1999 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 | #include "cryptlib.h" | ||
61 | #include <openssl/conf.h> | ||
62 | #include <openssl/x509v3.h> | ||
63 | |||
64 | int ASN1_BIT_STRING_name_print(BIO *out, ASN1_BIT_STRING *bs, | ||
65 | BIT_STRING_BITNAME *tbl, int indent) | ||
66 | { | ||
67 | BIT_STRING_BITNAME *bnam; | ||
68 | char first = 1; | ||
69 | BIO_printf(out, "%*s", indent, ""); | ||
70 | for(bnam = tbl; bnam->lname; bnam++) { | ||
71 | if(ASN1_BIT_STRING_get_bit(bs, bnam->bitnum)) { | ||
72 | if(!first) BIO_puts(out, ", "); | ||
73 | BIO_puts(out, bnam->lname); | ||
74 | first = 0; | ||
75 | } | ||
76 | } | ||
77 | BIO_puts(out, "\n"); | ||
78 | return 1; | ||
79 | } | ||
80 | |||
81 | int ASN1_BIT_STRING_set_asc(ASN1_BIT_STRING *bs, char *name, int value, | ||
82 | BIT_STRING_BITNAME *tbl) | ||
83 | { | ||
84 | int bitnum; | ||
85 | bitnum = ASN1_BIT_STRING_num_asc(name, tbl); | ||
86 | if(bitnum < 0) return 0; | ||
87 | if(bs) ASN1_BIT_STRING_set_bit(bs, bitnum, value); | ||
88 | return 1; | ||
89 | } | ||
90 | |||
91 | int ASN1_BIT_STRING_num_asc(char *name, BIT_STRING_BITNAME *tbl) | ||
92 | { | ||
93 | BIT_STRING_BITNAME *bnam; | ||
94 | for(bnam = tbl; bnam->lname; bnam++) { | ||
95 | if(!strcmp(bnam->sname, name) || | ||
96 | !strcmp(bnam->lname, name) ) return bnam->bitnum; | ||
97 | } | ||
98 | return -1; | ||
99 | } | ||
diff --git a/src/lib/libcrypto/asn1/t_crl.c b/src/lib/libcrypto/asn1/t_crl.c new file mode 100644 index 0000000000..c2e447ce6f --- /dev/null +++ b/src/lib/libcrypto/asn1/t_crl.c | |||
@@ -0,0 +1,166 @@ | |||
1 | /* t_crl.c */ | ||
2 | /* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL | ||
3 | * project 1999. | ||
4 | */ | ||
5 | /* ==================================================================== | ||
6 | * Copyright (c) 1999 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 | #include "cryptlib.h" | ||
61 | #include <openssl/buffer.h> | ||
62 | #include <openssl/bn.h> | ||
63 | #include <openssl/objects.h> | ||
64 | #include <openssl/x509.h> | ||
65 | #include <openssl/x509v3.h> | ||
66 | |||
67 | static void ext_print(BIO *out, X509_EXTENSION *ex); | ||
68 | #ifndef NO_FP_API | ||
69 | int X509_CRL_print_fp(FILE *fp, X509_CRL *x) | ||
70 | { | ||
71 | BIO *b; | ||
72 | int ret; | ||
73 | |||
74 | if ((b=BIO_new(BIO_s_file())) == NULL) | ||
75 | { | ||
76 | X509err(X509_F_X509_PRINT_FP,ERR_R_BUF_LIB); | ||
77 | return(0); | ||
78 | } | ||
79 | BIO_set_fp(b,fp,BIO_NOCLOSE); | ||
80 | ret=X509_CRL_print(b, x); | ||
81 | BIO_free(b); | ||
82 | return(ret); | ||
83 | } | ||
84 | #endif | ||
85 | |||
86 | int X509_CRL_print(BIO *out, X509_CRL *x) | ||
87 | { | ||
88 | char buf[256]; | ||
89 | unsigned char *s; | ||
90 | STACK_OF(X509_REVOKED) *rev; | ||
91 | X509_REVOKED *r; | ||
92 | long l; | ||
93 | int i, j, n; | ||
94 | |||
95 | BIO_printf(out, "Certificate Revocation List (CRL):\n"); | ||
96 | l = X509_CRL_get_version(x); | ||
97 | BIO_printf(out, "%8sVersion %lu (0x%lx)\n", "", l+1, l); | ||
98 | i = OBJ_obj2nid(x->sig_alg->algorithm); | ||
99 | BIO_printf(out, "%8sSignature Algorithm: %s\n", "", | ||
100 | (i == NID_undef) ? "NONE" : OBJ_nid2ln(i)); | ||
101 | X509_NAME_oneline(X509_CRL_get_issuer(x),buf,256); | ||
102 | BIO_printf(out,"%8sIssuer: %s\n","",buf); | ||
103 | BIO_printf(out,"%8sLast Update: ",""); | ||
104 | ASN1_TIME_print(out,X509_CRL_get_lastUpdate(x)); | ||
105 | BIO_printf(out,"\n%8sNext Update: ",""); | ||
106 | if (X509_CRL_get_nextUpdate(x)) | ||
107 | ASN1_TIME_print(out,X509_CRL_get_nextUpdate(x)); | ||
108 | else BIO_printf(out,"NONE"); | ||
109 | BIO_printf(out,"\n"); | ||
110 | |||
111 | n=X509_CRL_get_ext_count(x); | ||
112 | if (n > 0) { | ||
113 | BIO_printf(out,"%8sCRL extensions:\n",""); | ||
114 | for (i=0; i<n; i++) ext_print(out, X509_CRL_get_ext(x, i)); | ||
115 | } | ||
116 | |||
117 | |||
118 | rev = X509_CRL_get_REVOKED(x); | ||
119 | |||
120 | if(sk_X509_REVOKED_num(rev)) | ||
121 | BIO_printf(out, "Revoked Certificates:\n"); | ||
122 | else BIO_printf(out, "No Revoked Certificates.\n"); | ||
123 | |||
124 | for(i = 0; i < sk_X509_REVOKED_num(rev); i++) { | ||
125 | r = sk_X509_REVOKED_value(rev, i); | ||
126 | BIO_printf(out," Serial Number: "); | ||
127 | i2a_ASN1_INTEGER(out,r->serialNumber); | ||
128 | BIO_printf(out,"\n Revocation Date: ",""); | ||
129 | ASN1_TIME_print(out,r->revocationDate); | ||
130 | BIO_printf(out,"\n"); | ||
131 | for(j = 0; j < X509_REVOKED_get_ext_count(r); j++) | ||
132 | ext_print(out, X509_REVOKED_get_ext(r, j)); | ||
133 | } | ||
134 | |||
135 | i=OBJ_obj2nid(x->sig_alg->algorithm); | ||
136 | BIO_printf(out," Signature Algorithm: %s", | ||
137 | (i == NID_undef)?"UNKNOWN":OBJ_nid2ln(i)); | ||
138 | |||
139 | s = x->signature->data; | ||
140 | n = x->signature->length; | ||
141 | for (i=0; i<n; i++, s++) | ||
142 | { | ||
143 | if ((i%18) == 0) BIO_write(out,"\n ",9); | ||
144 | BIO_printf(out,"%02x%s",*s, ((i+1) == n)?"":":"); | ||
145 | } | ||
146 | BIO_write(out,"\n",1); | ||
147 | |||
148 | return 1; | ||
149 | |||
150 | } | ||
151 | |||
152 | static void ext_print(BIO *out, X509_EXTENSION *ex) | ||
153 | { | ||
154 | ASN1_OBJECT *obj; | ||
155 | int j; | ||
156 | BIO_printf(out,"%12s",""); | ||
157 | obj=X509_EXTENSION_get_object(ex); | ||
158 | i2a_ASN1_OBJECT(out,obj); | ||
159 | j=X509_EXTENSION_get_critical(ex); | ||
160 | BIO_printf(out, ": %s\n", j ? "critical":"",""); | ||
161 | if(!X509V3_EXT_print(out, ex, 0, 16)) { | ||
162 | BIO_printf(out, "%16s", ""); | ||
163 | ASN1_OCTET_STRING_print(out,ex->value); | ||
164 | } | ||
165 | BIO_write(out,"\n",1); | ||
166 | } | ||
diff --git a/src/lib/libcrypto/asn1/t_spki.c b/src/lib/libcrypto/asn1/t_spki.c new file mode 100644 index 0000000000..d708434fca --- /dev/null +++ b/src/lib/libcrypto/asn1/t_spki.c | |||
@@ -0,0 +1,116 @@ | |||
1 | /* t_spki.c */ | ||
2 | /* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL | ||
3 | * project 1999. | ||
4 | */ | ||
5 | /* ==================================================================== | ||
6 | * Copyright (c) 1999 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 | #include "cryptlib.h" | ||
61 | #include <openssl/x509.h> | ||
62 | #include <openssl/asn1_mac.h> | ||
63 | |||
64 | /* Print out an SPKI */ | ||
65 | |||
66 | int NETSCAPE_SPKI_print(BIO *out, NETSCAPE_SPKI *spki) | ||
67 | { | ||
68 | EVP_PKEY *pkey; | ||
69 | ASN1_IA5STRING *chal; | ||
70 | int i, n; | ||
71 | char *s; | ||
72 | BIO_printf(out, "Netscape SPKI:\n"); | ||
73 | i=OBJ_obj2nid(spki->spkac->pubkey->algor->algorithm); | ||
74 | BIO_printf(out," Public Key Algorithm: %s\n", | ||
75 | (i == NID_undef)?"UNKNOWN":OBJ_nid2ln(i)); | ||
76 | pkey = X509_PUBKEY_get(spki->spkac->pubkey); | ||
77 | if(!pkey) BIO_printf(out, " Unable to load public key\n"); | ||
78 | else { | ||
79 | #ifndef NO_RSA | ||
80 | if (pkey->type == EVP_PKEY_RSA) | ||
81 | { | ||
82 | BIO_printf(out," RSA Public Key: (%d bit)\n", | ||
83 | BN_num_bits(pkey->pkey.rsa->n)); | ||
84 | RSA_print(out,pkey->pkey.rsa,2); | ||
85 | } | ||
86 | else | ||
87 | #endif | ||
88 | #ifndef NO_DSA | ||
89 | if (pkey->type == EVP_PKEY_DSA) | ||
90 | { | ||
91 | BIO_printf(out," DSA Public Key:\n"); | ||
92 | DSA_print(out,pkey->pkey.dsa,2); | ||
93 | } | ||
94 | else | ||
95 | #endif | ||
96 | BIO_printf(out," Unknown Public Key:\n"); | ||
97 | EVP_PKEY_free(pkey); | ||
98 | } | ||
99 | chal = spki->spkac->challenge; | ||
100 | if(chal->length) | ||
101 | BIO_printf(out, " Challenge String: %s\n", chal->data); | ||
102 | i=OBJ_obj2nid(spki->sig_algor->algorithm); | ||
103 | BIO_printf(out," Signature Algorithm: %s", | ||
104 | (i == NID_undef)?"UNKNOWN":OBJ_nid2ln(i)); | ||
105 | |||
106 | n=spki->signature->length; | ||
107 | s=(char *)spki->signature->data; | ||
108 | for (i=0; i<n; i++) | ||
109 | { | ||
110 | if ((i%18) == 0) BIO_write(out,"\n ",7); | ||
111 | BIO_printf(out,"%02x%s",(unsigned char)s[i], | ||
112 | ((i+1) == n)?"":":"); | ||
113 | } | ||
114 | BIO_write(out,"\n",1); | ||
115 | return 1; | ||
116 | } | ||
diff --git a/src/lib/libcrypto/asn1/t_x509a.c b/src/lib/libcrypto/asn1/t_x509a.c new file mode 100644 index 0000000000..a18ebb586c --- /dev/null +++ b/src/lib/libcrypto/asn1/t_x509a.c | |||
@@ -0,0 +1,102 @@ | |||
1 | /* t_x509a.c */ | ||
2 | /* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL | ||
3 | * project 1999. | ||
4 | */ | ||
5 | /* ==================================================================== | ||
6 | * Copyright (c) 1999 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 | #include "cryptlib.h" | ||
61 | #include <openssl/evp.h> | ||
62 | #include <openssl/asn1_mac.h> | ||
63 | #include <openssl/x509.h> | ||
64 | |||
65 | /* X509_CERT_AUX and string set routines | ||
66 | */ | ||
67 | |||
68 | int X509_CERT_AUX_print(BIO *out, X509_CERT_AUX *aux, int indent) | ||
69 | { | ||
70 | char oidstr[80], first; | ||
71 | int i; | ||
72 | if(!aux) return 1; | ||
73 | if(aux->trust) { | ||
74 | first = 1; | ||
75 | BIO_printf(out, "%*sTrusted Uses:\n%*s", | ||
76 | indent, "", indent + 2, ""); | ||
77 | for(i = 0; i < sk_ASN1_OBJECT_num(aux->trust); i++) { | ||
78 | if(!first) BIO_puts(out, ", "); | ||
79 | else first = 0; | ||
80 | OBJ_obj2txt(oidstr, 80, | ||
81 | sk_ASN1_OBJECT_value(aux->trust, i), 0); | ||
82 | BIO_puts(out, oidstr); | ||
83 | } | ||
84 | BIO_puts(out, "\n"); | ||
85 | } else BIO_printf(out, "%*sNo Trusted Uses.\n", indent, ""); | ||
86 | if(aux->reject) { | ||
87 | first = 1; | ||
88 | BIO_printf(out, "%*sRejected Uses:\n%*s", | ||
89 | indent, "", indent + 2, ""); | ||
90 | for(i = 0; i < sk_ASN1_OBJECT_num(aux->reject); i++) { | ||
91 | if(!first) BIO_puts(out, ", "); | ||
92 | else first = 0; | ||
93 | OBJ_obj2txt(oidstr, 80, | ||
94 | sk_ASN1_OBJECT_value(aux->reject, i), 0); | ||
95 | BIO_puts(out, oidstr); | ||
96 | } | ||
97 | BIO_puts(out, "\n"); | ||
98 | } else BIO_printf(out, "%*sNo Rejected Uses.\n", indent, ""); | ||
99 | if(aux->alias) BIO_printf(out, "%*sAlias: %s\n", indent, "", | ||
100 | aux->alias->data); | ||
101 | return 1; | ||
102 | } | ||
diff --git a/src/lib/libcrypto/asn1/tasn_dec.c b/src/lib/libcrypto/asn1/tasn_dec.c new file mode 100644 index 0000000000..0fc1f421e2 --- /dev/null +++ b/src/lib/libcrypto/asn1/tasn_dec.c | |||
@@ -0,0 +1,958 @@ | |||
1 | /* tasn_dec.c */ | ||
2 | /* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL | ||
3 | * project 2000. | ||
4 | */ | ||
5 | /* ==================================================================== | ||
6 | * Copyright (c) 2000 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 <stddef.h> | ||
61 | #include <string.h> | ||
62 | #include <openssl/asn1.h> | ||
63 | #include <openssl/asn1t.h> | ||
64 | #include <openssl/objects.h> | ||
65 | #include <openssl/buffer.h> | ||
66 | #include <openssl/err.h> | ||
67 | |||
68 | static int asn1_check_eoc(unsigned char **in, long len); | ||
69 | static int asn1_collect(BUF_MEM *buf, unsigned char **in, long len, char inf, int tag, int aclass); | ||
70 | static int collect_data(BUF_MEM *buf, unsigned char **p, long plen); | ||
71 | static int asn1_check_tlen(long *olen, int *otag, unsigned char *oclass, char *inf, char *cst, | ||
72 | unsigned char **in, long len, int exptag, int expclass, char opt, ASN1_TLC *ctx); | ||
73 | static int asn1_template_ex_d2i(ASN1_VALUE **pval, unsigned char **in, long len, const ASN1_TEMPLATE *tt, char opt, ASN1_TLC *ctx); | ||
74 | static int asn1_template_noexp_d2i(ASN1_VALUE **val, unsigned char **in, long len, const ASN1_TEMPLATE *tt, char opt, ASN1_TLC *ctx); | ||
75 | static int asn1_d2i_ex_primitive(ASN1_VALUE **pval, unsigned char **in, long len, | ||
76 | const ASN1_ITEM *it, int tag, int aclass, char opt, ASN1_TLC *ctx); | ||
77 | |||
78 | /* Table to convert tags to bit values, used for MSTRING type */ | ||
79 | static unsigned long tag2bit[32]={ | ||
80 | 0, 0, 0, B_ASN1_BIT_STRING, /* tags 0 - 3 */ | ||
81 | B_ASN1_OCTET_STRING, 0, 0, B_ASN1_UNKNOWN,/* tags 4- 7 */ | ||
82 | B_ASN1_UNKNOWN, B_ASN1_UNKNOWN, B_ASN1_UNKNOWN, B_ASN1_UNKNOWN,/* tags 8-11 */ | ||
83 | B_ASN1_UTF8STRING,B_ASN1_UNKNOWN,B_ASN1_UNKNOWN,B_ASN1_UNKNOWN,/* tags 12-15 */ | ||
84 | 0, 0, B_ASN1_NUMERICSTRING,B_ASN1_PRINTABLESTRING, /* tags 16-19 */ | ||
85 | B_ASN1_T61STRING,B_ASN1_VIDEOTEXSTRING,B_ASN1_IA5STRING, /* tags 20-22 */ | ||
86 | B_ASN1_UTCTIME, B_ASN1_GENERALIZEDTIME, /* tags 23-24 */ | ||
87 | B_ASN1_GRAPHICSTRING,B_ASN1_ISO64STRING,B_ASN1_GENERALSTRING, /* tags 25-27 */ | ||
88 | B_ASN1_UNIVERSALSTRING,B_ASN1_UNKNOWN,B_ASN1_BMPSTRING,B_ASN1_UNKNOWN, /* tags 28-31 */ | ||
89 | }; | ||
90 | |||
91 | unsigned long ASN1_tag2bit(int tag) | ||
92 | { | ||
93 | if((tag < 0) || (tag > 30)) return 0; | ||
94 | return tag2bit[tag]; | ||
95 | } | ||
96 | |||
97 | /* Macro to initialize and invalidate the cache */ | ||
98 | |||
99 | #define asn1_tlc_clear(c) if(c) (c)->valid = 0 | ||
100 | |||
101 | /* Decode an ASN1 item, this currently behaves just | ||
102 | * like a standard 'd2i' function. 'in' points to | ||
103 | * a buffer to read the data from, in future we will | ||
104 | * have more advanced versions that can input data | ||
105 | * a piece at a time and this will simply be a special | ||
106 | * case. | ||
107 | */ | ||
108 | |||
109 | ASN1_VALUE *ASN1_item_d2i(ASN1_VALUE **pval, unsigned char **in, long len, const ASN1_ITEM *it) | ||
110 | { | ||
111 | ASN1_TLC c; | ||
112 | ASN1_VALUE *ptmpval = NULL; | ||
113 | if(!pval) pval = &ptmpval; | ||
114 | asn1_tlc_clear(&c); | ||
115 | if(ASN1_item_ex_d2i(pval, in, len, it, -1, 0, 0, &c) > 0) | ||
116 | return *pval; | ||
117 | return NULL; | ||
118 | } | ||
119 | |||
120 | int ASN1_template_d2i(ASN1_VALUE **pval, unsigned char **in, long len, const ASN1_TEMPLATE *tt) | ||
121 | { | ||
122 | ASN1_TLC c; | ||
123 | asn1_tlc_clear(&c); | ||
124 | return asn1_template_ex_d2i(pval, in, len, tt, 0, &c); | ||
125 | } | ||
126 | |||
127 | |||
128 | /* Decode an item, taking care of IMPLICIT tagging, if any. | ||
129 | * If 'opt' set and tag mismatch return -1 to handle OPTIONAL | ||
130 | */ | ||
131 | |||
132 | int ASN1_item_ex_d2i(ASN1_VALUE **pval, unsigned char **in, long len, const ASN1_ITEM *it, | ||
133 | int tag, int aclass, char opt, ASN1_TLC *ctx) | ||
134 | { | ||
135 | const ASN1_TEMPLATE *tt, *errtt = NULL; | ||
136 | const ASN1_COMPAT_FUNCS *cf; | ||
137 | const ASN1_EXTERN_FUNCS *ef; | ||
138 | const ASN1_AUX *aux = it->funcs; | ||
139 | ASN1_aux_cb *asn1_cb; | ||
140 | unsigned char *p, *q, imphack = 0, oclass; | ||
141 | char seq_eoc, seq_nolen, cst, isopt; | ||
142 | long tmplen; | ||
143 | int i; | ||
144 | int otag; | ||
145 | int ret = 0; | ||
146 | ASN1_VALUE *pchval, **pchptr, *ptmpval; | ||
147 | if(!pval) return 0; | ||
148 | if(aux && aux->asn1_cb) asn1_cb = aux->asn1_cb; | ||
149 | else asn1_cb = 0; | ||
150 | |||
151 | switch(it->itype) { | ||
152 | |||
153 | case ASN1_ITYPE_PRIMITIVE: | ||
154 | if(it->templates) { | ||
155 | /* tagging or OPTIONAL is currently illegal on an item template | ||
156 | * because the flags can't get passed down. In practice this isn't | ||
157 | * a problem: we include the relevant flags from the item template | ||
158 | * in the template itself. | ||
159 | */ | ||
160 | if ((tag != -1) || opt) { | ||
161 | ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ASN1_R_ILLEGAL_OPTIONS_ON_ITEM_TEMPLATE); | ||
162 | goto err; | ||
163 | } | ||
164 | return asn1_template_ex_d2i(pval, in, len, it->templates, opt, ctx); | ||
165 | } | ||
166 | return asn1_d2i_ex_primitive(pval, in, len, it, tag, aclass, opt, ctx); | ||
167 | break; | ||
168 | |||
169 | case ASN1_ITYPE_MSTRING: | ||
170 | p = *in; | ||
171 | /* Just read in tag and class */ | ||
172 | ret = asn1_check_tlen(NULL, &otag, &oclass, NULL, NULL, &p, len, -1, 0, 1, ctx); | ||
173 | if(!ret) { | ||
174 | ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ERR_R_NESTED_ASN1_ERROR); | ||
175 | goto err; | ||
176 | } | ||
177 | /* Must be UNIVERSAL class */ | ||
178 | if(oclass != V_ASN1_UNIVERSAL) { | ||
179 | /* If OPTIONAL, assume this is OK */ | ||
180 | if(opt) return -1; | ||
181 | ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ASN1_R_MSTRING_NOT_UNIVERSAL); | ||
182 | goto err; | ||
183 | } | ||
184 | /* Check tag matches bit map */ | ||
185 | if(!(ASN1_tag2bit(otag) & it->utype)) { | ||
186 | /* If OPTIONAL, assume this is OK */ | ||
187 | if(opt) return -1; | ||
188 | ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ASN1_R_MSTRING_WRONG_TAG); | ||
189 | goto err; | ||
190 | } | ||
191 | return asn1_d2i_ex_primitive(pval, in, len, it, otag, 0, 0, ctx); | ||
192 | |||
193 | case ASN1_ITYPE_EXTERN: | ||
194 | /* Use new style d2i */ | ||
195 | ef = it->funcs; | ||
196 | return ef->asn1_ex_d2i(pval, in, len, it, tag, aclass, opt, ctx); | ||
197 | |||
198 | case ASN1_ITYPE_COMPAT: | ||
199 | /* we must resort to old style evil hackery */ | ||
200 | cf = it->funcs; | ||
201 | |||
202 | /* If OPTIONAL see if it is there */ | ||
203 | if(opt) { | ||
204 | int exptag; | ||
205 | p = *in; | ||
206 | if(tag == -1) exptag = it->utype; | ||
207 | else exptag = tag; | ||
208 | /* Don't care about anything other than presence of expected tag */ | ||
209 | ret = asn1_check_tlen(NULL, NULL, NULL, NULL, NULL, &p, len, exptag, aclass, 1, ctx); | ||
210 | if(!ret) { | ||
211 | ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ERR_R_NESTED_ASN1_ERROR); | ||
212 | goto err; | ||
213 | } | ||
214 | if(ret == -1) return -1; | ||
215 | } | ||
216 | /* This is the old style evil hack IMPLICIT handling: | ||
217 | * since the underlying code is expecting a tag and | ||
218 | * class other than the one present we change the | ||
219 | * buffer temporarily then change it back afterwards. | ||
220 | * This doesn't and never did work for tags > 30. | ||
221 | * | ||
222 | * Yes this is *horrible* but it is only needed for | ||
223 | * old style d2i which will hopefully not be around | ||
224 | * for much longer. | ||
225 | * FIXME: should copy the buffer then modify it so | ||
226 | * the input buffer can be const: we should *always* | ||
227 | * copy because the old style d2i might modify the | ||
228 | * buffer. | ||
229 | */ | ||
230 | |||
231 | if(tag != -1) { | ||
232 | p = *in; | ||
233 | imphack = *p; | ||
234 | *p = (unsigned char)((*p & V_ASN1_CONSTRUCTED) | it->utype); | ||
235 | } | ||
236 | |||
237 | ptmpval = cf->asn1_d2i(pval, in, len); | ||
238 | |||
239 | if(tag != -1) *p = imphack; | ||
240 | |||
241 | if(ptmpval) return 1; | ||
242 | ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ERR_R_NESTED_ASN1_ERROR); | ||
243 | goto err; | ||
244 | |||
245 | |||
246 | case ASN1_ITYPE_CHOICE: | ||
247 | if(asn1_cb && !asn1_cb(ASN1_OP_D2I_PRE, pval, it)) | ||
248 | goto auxerr; | ||
249 | |||
250 | /* Allocate structure */ | ||
251 | if(!*pval) { | ||
252 | if(!ASN1_item_ex_new(pval, it)) { | ||
253 | ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ERR_R_NESTED_ASN1_ERROR); | ||
254 | goto err; | ||
255 | } | ||
256 | } | ||
257 | /* CHOICE type, try each possibility in turn */ | ||
258 | pchval = NULL; | ||
259 | p = *in; | ||
260 | for(i = 0, tt=it->templates; i < it->tcount; i++, tt++) { | ||
261 | pchptr = asn1_get_field_ptr(pval, tt); | ||
262 | /* We mark field as OPTIONAL so its absence | ||
263 | * can be recognised. | ||
264 | */ | ||
265 | ret = asn1_template_ex_d2i(pchptr, &p, len, tt, 1, ctx); | ||
266 | /* If field not present, try the next one */ | ||
267 | if(ret == -1) continue; | ||
268 | /* If positive return, read OK, break loop */ | ||
269 | if(ret > 0) break; | ||
270 | /* Otherwise must be an ASN1 parsing error */ | ||
271 | errtt = tt; | ||
272 | ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ERR_R_NESTED_ASN1_ERROR); | ||
273 | goto err; | ||
274 | } | ||
275 | /* Did we fall off the end without reading anything? */ | ||
276 | if(i == it->tcount) { | ||
277 | /* If OPTIONAL, this is OK */ | ||
278 | if(opt) { | ||
279 | /* Free and zero it */ | ||
280 | ASN1_item_ex_free(pval, it); | ||
281 | return -1; | ||
282 | } | ||
283 | ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ASN1_R_NO_MATCHING_CHOICE_TYPE); | ||
284 | goto err; | ||
285 | } | ||
286 | asn1_set_choice_selector(pval, i, it); | ||
287 | *in = p; | ||
288 | if(asn1_cb && !asn1_cb(ASN1_OP_D2I_POST, pval, it)) | ||
289 | goto auxerr; | ||
290 | return 1; | ||
291 | |||
292 | case ASN1_ITYPE_SEQUENCE: | ||
293 | p = *in; | ||
294 | tmplen = len; | ||
295 | |||
296 | /* If no IMPLICIT tagging set to SEQUENCE, UNIVERSAL */ | ||
297 | if(tag == -1) { | ||
298 | tag = V_ASN1_SEQUENCE; | ||
299 | aclass = V_ASN1_UNIVERSAL; | ||
300 | } | ||
301 | /* Get SEQUENCE length and update len, p */ | ||
302 | ret = asn1_check_tlen(&len, NULL, NULL, &seq_eoc, &cst, &p, len, tag, aclass, opt, ctx); | ||
303 | if(!ret) { | ||
304 | ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ERR_R_NESTED_ASN1_ERROR); | ||
305 | goto err; | ||
306 | } else if(ret == -1) return -1; | ||
307 | if(aux && (aux->flags & ASN1_AFLG_BROKEN)) { | ||
308 | len = tmplen - (p - *in); | ||
309 | seq_nolen = 1; | ||
310 | } else seq_nolen = seq_eoc; /* If indefinite we don't do a length check */ | ||
311 | if(!cst) { | ||
312 | ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ASN1_R_SEQUENCE_NOT_CONSTRUCTED); | ||
313 | goto err; | ||
314 | } | ||
315 | |||
316 | if(!*pval) { | ||
317 | if(!ASN1_item_ex_new(pval, it)) { | ||
318 | ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ERR_R_NESTED_ASN1_ERROR); | ||
319 | goto err; | ||
320 | } | ||
321 | } | ||
322 | if(asn1_cb && !asn1_cb(ASN1_OP_D2I_PRE, pval, it)) | ||
323 | goto auxerr; | ||
324 | |||
325 | /* Get each field entry */ | ||
326 | for(i = 0, tt = it->templates; i < it->tcount; i++, tt++) { | ||
327 | const ASN1_TEMPLATE *seqtt; | ||
328 | ASN1_VALUE **pseqval; | ||
329 | seqtt = asn1_do_adb(pval, tt, 1); | ||
330 | if(!seqtt) goto err; | ||
331 | pseqval = asn1_get_field_ptr(pval, seqtt); | ||
332 | /* Have we ran out of data? */ | ||
333 | if(!len) break; | ||
334 | q = p; | ||
335 | if(asn1_check_eoc(&p, len)) { | ||
336 | if(!seq_eoc) { | ||
337 | ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ASN1_R_UNEXPECTED_EOC); | ||
338 | goto err; | ||
339 | } | ||
340 | len -= p - q; | ||
341 | seq_eoc = 0; | ||
342 | q = p; | ||
343 | break; | ||
344 | } | ||
345 | /* This determines the OPTIONAL flag value. The field cannot | ||
346 | * be omitted if it is the last of a SEQUENCE and there is | ||
347 | * still data to be read. This isn't strictly necessary but | ||
348 | * it increases efficiency in some cases. | ||
349 | */ | ||
350 | if(i == (it->tcount - 1)) isopt = 0; | ||
351 | else isopt = (char)(seqtt->flags & ASN1_TFLG_OPTIONAL); | ||
352 | /* attempt to read in field, allowing each to be OPTIONAL */ | ||
353 | ret = asn1_template_ex_d2i(pseqval, &p, len, seqtt, isopt, ctx); | ||
354 | if(!ret) { | ||
355 | errtt = seqtt; | ||
356 | goto err; | ||
357 | } else if(ret == -1) { | ||
358 | /* OPTIONAL component absent. Free and zero the field | ||
359 | */ | ||
360 | ASN1_template_free(pseqval, seqtt); | ||
361 | continue; | ||
362 | } | ||
363 | /* Update length */ | ||
364 | len -= p - q; | ||
365 | } | ||
366 | /* Check for EOC if expecting one */ | ||
367 | if(seq_eoc && !asn1_check_eoc(&p, len)) { | ||
368 | ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ASN1_R_MISSING_EOC); | ||
369 | goto err; | ||
370 | } | ||
371 | /* Check all data read */ | ||
372 | if(!seq_nolen && len) { | ||
373 | ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ASN1_R_SEQUENCE_LENGTH_MISMATCH); | ||
374 | goto err; | ||
375 | } | ||
376 | |||
377 | /* If we get here we've got no more data in the SEQUENCE, | ||
378 | * however we may not have read all fields so check all | ||
379 | * remaining are OPTIONAL and clear any that are. | ||
380 | */ | ||
381 | for(; i < it->tcount; tt++, i++) { | ||
382 | const ASN1_TEMPLATE *seqtt; | ||
383 | seqtt = asn1_do_adb(pval, tt, 1); | ||
384 | if(!seqtt) goto err; | ||
385 | if(seqtt->flags & ASN1_TFLG_OPTIONAL) { | ||
386 | ASN1_VALUE **pseqval; | ||
387 | pseqval = asn1_get_field_ptr(pval, seqtt); | ||
388 | ASN1_template_free(pseqval, seqtt); | ||
389 | } else { | ||
390 | errtt = seqtt; | ||
391 | ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ASN1_R_FIELD_MISSING); | ||
392 | goto err; | ||
393 | } | ||
394 | } | ||
395 | /* Save encoding */ | ||
396 | if(!asn1_enc_save(pval, *in, p - *in, it)) goto auxerr; | ||
397 | *in = p; | ||
398 | if(asn1_cb && !asn1_cb(ASN1_OP_D2I_POST, pval, it)) | ||
399 | goto auxerr; | ||
400 | return 1; | ||
401 | |||
402 | default: | ||
403 | return 0; | ||
404 | } | ||
405 | auxerr: | ||
406 | ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ASN1_R_AUX_ERROR); | ||
407 | err: | ||
408 | ASN1_item_ex_free(pval, it); | ||
409 | if(errtt) ERR_add_error_data(4, "Field=", errtt->field_name, ", Type=", it->sname); | ||
410 | else ERR_add_error_data(2, "Type=", it->sname); | ||
411 | return 0; | ||
412 | } | ||
413 | |||
414 | /* Templates are handled with two separate functions. One handles any EXPLICIT tag and the other handles the | ||
415 | * rest. | ||
416 | */ | ||
417 | |||
418 | static int asn1_template_ex_d2i(ASN1_VALUE **val, unsigned char **in, long inlen, const ASN1_TEMPLATE *tt, char opt, ASN1_TLC *ctx) | ||
419 | { | ||
420 | int flags, aclass; | ||
421 | int ret; | ||
422 | long len; | ||
423 | unsigned char *p, *q; | ||
424 | char exp_eoc; | ||
425 | if(!val) return 0; | ||
426 | flags = tt->flags; | ||
427 | aclass = flags & ASN1_TFLG_TAG_CLASS; | ||
428 | |||
429 | p = *in; | ||
430 | |||
431 | /* Check if EXPLICIT tag expected */ | ||
432 | if(flags & ASN1_TFLG_EXPTAG) { | ||
433 | char cst; | ||
434 | /* Need to work out amount of data available to the inner content and where it | ||
435 | * starts: so read in EXPLICIT header to get the info. | ||
436 | */ | ||
437 | ret = asn1_check_tlen(&len, NULL, NULL, &exp_eoc, &cst, &p, inlen, tt->tag, aclass, opt, ctx); | ||
438 | q = p; | ||
439 | if(!ret) { | ||
440 | ASN1err(ASN1_F_ASN1_TEMPLATE_EX_D2I, ERR_R_NESTED_ASN1_ERROR); | ||
441 | return 0; | ||
442 | } else if(ret == -1) return -1; | ||
443 | if(!cst) { | ||
444 | ASN1err(ASN1_F_ASN1_TEMPLATE_EX_D2I, ASN1_R_EXPLICIT_TAG_NOT_CONSTRUCTED); | ||
445 | return 0; | ||
446 | } | ||
447 | /* We've found the field so it can't be OPTIONAL now */ | ||
448 | ret = asn1_template_noexp_d2i(val, &p, len, tt, 0, ctx); | ||
449 | if(!ret) { | ||
450 | ASN1err(ASN1_F_ASN1_TEMPLATE_EX_D2I, ERR_R_NESTED_ASN1_ERROR); | ||
451 | return 0; | ||
452 | } | ||
453 | /* We read the field in OK so update length */ | ||
454 | len -= p - q; | ||
455 | if(exp_eoc) { | ||
456 | /* If NDEF we must have an EOC here */ | ||
457 | if(!asn1_check_eoc(&p, len)) { | ||
458 | ASN1err(ASN1_F_ASN1_TEMPLATE_D2I, ASN1_R_MISSING_EOC); | ||
459 | goto err; | ||
460 | } | ||
461 | } else { | ||
462 | /* Otherwise we must hit the EXPLICIT tag end or its an error */ | ||
463 | if(len) { | ||
464 | ASN1err(ASN1_F_ASN1_TEMPLATE_D2I, ASN1_R_EXPLICIT_LENGTH_MISMATCH); | ||
465 | goto err; | ||
466 | } | ||
467 | } | ||
468 | } else | ||
469 | return asn1_template_noexp_d2i(val, in, inlen, tt, opt, ctx); | ||
470 | |||
471 | *in = p; | ||
472 | return 1; | ||
473 | |||
474 | err: | ||
475 | ASN1_template_free(val, tt); | ||
476 | *val = NULL; | ||
477 | return 0; | ||
478 | } | ||
479 | |||
480 | static int asn1_template_noexp_d2i(ASN1_VALUE **val, unsigned char **in, long len, const ASN1_TEMPLATE *tt, char opt, ASN1_TLC *ctx) | ||
481 | { | ||
482 | int flags, aclass; | ||
483 | int ret; | ||
484 | unsigned char *p, *q; | ||
485 | if(!val) return 0; | ||
486 | flags = tt->flags; | ||
487 | aclass = flags & ASN1_TFLG_TAG_CLASS; | ||
488 | |||
489 | p = *in; | ||
490 | q = p; | ||
491 | |||
492 | if(flags & ASN1_TFLG_SK_MASK) { | ||
493 | /* SET OF, SEQUENCE OF */ | ||
494 | int sktag, skaclass; | ||
495 | char sk_eoc; | ||
496 | /* First work out expected inner tag value */ | ||
497 | if(flags & ASN1_TFLG_IMPTAG) { | ||
498 | sktag = tt->tag; | ||
499 | skaclass = aclass; | ||
500 | } else { | ||
501 | skaclass = V_ASN1_UNIVERSAL; | ||
502 | if(flags & ASN1_TFLG_SET_OF) sktag = V_ASN1_SET; | ||
503 | else sktag = V_ASN1_SEQUENCE; | ||
504 | } | ||
505 | /* Get the tag */ | ||
506 | ret = asn1_check_tlen(&len, NULL, NULL, &sk_eoc, NULL, &p, len, sktag, skaclass, opt, ctx); | ||
507 | if(!ret) { | ||
508 | ASN1err(ASN1_F_ASN1_TEMPLATE_EX_D2I, ERR_R_NESTED_ASN1_ERROR); | ||
509 | return 0; | ||
510 | } else if(ret == -1) return -1; | ||
511 | if(!*val) *val = (ASN1_VALUE *)sk_new_null(); | ||
512 | else { | ||
513 | /* We've got a valid STACK: free up any items present */ | ||
514 | STACK *sktmp = (STACK *)*val; | ||
515 | ASN1_VALUE *vtmp; | ||
516 | while(sk_num(sktmp) > 0) { | ||
517 | vtmp = (ASN1_VALUE *)sk_pop(sktmp); | ||
518 | ASN1_item_ex_free(&vtmp, ASN1_ITEM_ptr(tt->item)); | ||
519 | } | ||
520 | } | ||
521 | |||
522 | if(!*val) { | ||
523 | ASN1err(ASN1_F_ASN1_TEMPLATE_EX_D2I, ERR_R_MALLOC_FAILURE); | ||
524 | goto err; | ||
525 | } | ||
526 | /* Read as many items as we can */ | ||
527 | while(len > 0) { | ||
528 | ASN1_VALUE *skfield; | ||
529 | q = p; | ||
530 | /* See if EOC found */ | ||
531 | if(asn1_check_eoc(&p, len)) { | ||
532 | if(!sk_eoc) { | ||
533 | ASN1err(ASN1_F_ASN1_TEMPLATE_D2I, ASN1_R_UNEXPECTED_EOC); | ||
534 | goto err; | ||
535 | } | ||
536 | len -= p - q; | ||
537 | sk_eoc = 0; | ||
538 | break; | ||
539 | } | ||
540 | skfield = NULL; | ||
541 | if(!ASN1_item_ex_d2i(&skfield, &p, len, ASN1_ITEM_ptr(tt->item), -1, 0, 0, ctx)) { | ||
542 | ASN1err(ASN1_F_ASN1_TEMPLATE_D2I, ERR_R_NESTED_ASN1_ERROR); | ||
543 | goto err; | ||
544 | } | ||
545 | len -= p - q; | ||
546 | if(!sk_push((STACK *)*val, (char *)skfield)) { | ||
547 | ASN1err(ASN1_F_ASN1_TEMPLATE_D2I, ERR_R_MALLOC_FAILURE); | ||
548 | goto err; | ||
549 | } | ||
550 | } | ||
551 | if(sk_eoc) { | ||
552 | ASN1err(ASN1_F_ASN1_TEMPLATE_D2I, ASN1_R_MISSING_EOC); | ||
553 | goto err; | ||
554 | } | ||
555 | } else if(flags & ASN1_TFLG_IMPTAG) { | ||
556 | /* IMPLICIT tagging */ | ||
557 | ret = ASN1_item_ex_d2i(val, &p, len, ASN1_ITEM_ptr(tt->item), tt->tag, aclass, opt, ctx); | ||
558 | if(!ret) { | ||
559 | ASN1err(ASN1_F_ASN1_TEMPLATE_D2I, ERR_R_NESTED_ASN1_ERROR); | ||
560 | goto err; | ||
561 | } else if(ret == -1) return -1; | ||
562 | } else { | ||
563 | /* Nothing special */ | ||
564 | ret = ASN1_item_ex_d2i(val, &p, len, ASN1_ITEM_ptr(tt->item), -1, 0, opt, ctx); | ||
565 | if(!ret) { | ||
566 | ASN1err(ASN1_F_ASN1_TEMPLATE_D2I, ERR_R_NESTED_ASN1_ERROR); | ||
567 | goto err; | ||
568 | } else if(ret == -1) return -1; | ||
569 | } | ||
570 | |||
571 | *in = p; | ||
572 | return 1; | ||
573 | |||
574 | err: | ||
575 | ASN1_template_free(val, tt); | ||
576 | *val = NULL; | ||
577 | return 0; | ||
578 | } | ||
579 | |||
580 | static int asn1_d2i_ex_primitive(ASN1_VALUE **pval, unsigned char **in, long inlen, | ||
581 | const ASN1_ITEM *it, | ||
582 | int tag, int aclass, char opt, ASN1_TLC *ctx) | ||
583 | { | ||
584 | int ret = 0, utype; | ||
585 | long plen; | ||
586 | char cst, inf, free_cont = 0; | ||
587 | unsigned char *p; | ||
588 | BUF_MEM buf; | ||
589 | unsigned char *cont = NULL; | ||
590 | long len; | ||
591 | if(!pval) { | ||
592 | ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, ASN1_R_ILLEGAL_NULL); | ||
593 | return 0; /* Should never happen */ | ||
594 | } | ||
595 | |||
596 | if(it->itype == ASN1_ITYPE_MSTRING) { | ||
597 | utype = tag; | ||
598 | tag = -1; | ||
599 | } else utype = it->utype; | ||
600 | |||
601 | if(utype == V_ASN1_ANY) { | ||
602 | /* If type is ANY need to figure out type from tag */ | ||
603 | unsigned char oclass; | ||
604 | if(tag >= 0) { | ||
605 | ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, ASN1_R_ILLEGAL_TAGGED_ANY); | ||
606 | return 0; | ||
607 | } | ||
608 | if(opt) { | ||
609 | ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, ASN1_R_ILLEGAL_OPTIONAL_ANY); | ||
610 | return 0; | ||
611 | } | ||
612 | p = *in; | ||
613 | ret = asn1_check_tlen(NULL, &utype, &oclass, NULL, NULL, &p, inlen, -1, 0, 0, ctx); | ||
614 | if(!ret) { | ||
615 | ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, ERR_R_NESTED_ASN1_ERROR); | ||
616 | return 0; | ||
617 | } | ||
618 | if(oclass != V_ASN1_UNIVERSAL) utype = V_ASN1_OTHER; | ||
619 | } | ||
620 | if(tag == -1) { | ||
621 | tag = utype; | ||
622 | aclass = V_ASN1_UNIVERSAL; | ||
623 | } | ||
624 | p = *in; | ||
625 | /* Check header */ | ||
626 | ret = asn1_check_tlen(&plen, NULL, NULL, &inf, &cst, &p, inlen, tag, aclass, opt, ctx); | ||
627 | if(!ret) { | ||
628 | ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, ERR_R_NESTED_ASN1_ERROR); | ||
629 | return 0; | ||
630 | } else if(ret == -1) return -1; | ||
631 | /* SEQUENCE, SET and "OTHER" are left in encoded form */ | ||
632 | if((utype == V_ASN1_SEQUENCE) || (utype == V_ASN1_SET) || (utype == V_ASN1_OTHER)) { | ||
633 | /* Clear context cache for type OTHER because the auto clear when | ||
634 | * we have a exact match wont work | ||
635 | */ | ||
636 | if(utype == V_ASN1_OTHER) { | ||
637 | asn1_tlc_clear(ctx); | ||
638 | /* SEQUENCE and SET must be constructed */ | ||
639 | } else if(!cst) { | ||
640 | ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, ASN1_R_TYPE_NOT_CONSTRUCTED); | ||
641 | return 0; | ||
642 | } | ||
643 | |||
644 | cont = *in; | ||
645 | /* If indefinite length constructed find the real end */ | ||
646 | if(inf) { | ||
647 | if(!asn1_collect(NULL, &p, plen, inf, -1, -1)) goto err; | ||
648 | len = p - cont; | ||
649 | } else { | ||
650 | len = p - cont + plen; | ||
651 | p += plen; | ||
652 | buf.data = NULL; | ||
653 | } | ||
654 | } else if(cst) { | ||
655 | buf.length = 0; | ||
656 | buf.max = 0; | ||
657 | buf.data = NULL; | ||
658 | /* Should really check the internal tags are correct but | ||
659 | * some things may get this wrong. The relevant specs | ||
660 | * say that constructed string types should be OCTET STRINGs | ||
661 | * internally irrespective of the type. So instead just check | ||
662 | * for UNIVERSAL class and ignore the tag. | ||
663 | */ | ||
664 | if(!asn1_collect(&buf, &p, plen, inf, -1, V_ASN1_UNIVERSAL)) goto err; | ||
665 | len = buf.length; | ||
666 | /* Append a final null to string */ | ||
667 | if(!BUF_MEM_grow(&buf, len + 1)) { | ||
668 | ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, ERR_R_MALLOC_FAILURE); | ||
669 | return 0; | ||
670 | } | ||
671 | buf.data[len] = 0; | ||
672 | cont = (unsigned char *)buf.data; | ||
673 | free_cont = 1; | ||
674 | } else { | ||
675 | cont = p; | ||
676 | len = plen; | ||
677 | p += plen; | ||
678 | } | ||
679 | |||
680 | /* We now have content length and type: translate into a structure */ | ||
681 | if(!asn1_ex_c2i(pval, cont, len, utype, &free_cont, it)) goto err; | ||
682 | |||
683 | *in = p; | ||
684 | ret = 1; | ||
685 | err: | ||
686 | if(free_cont && buf.data) OPENSSL_free(buf.data); | ||
687 | return ret; | ||
688 | } | ||
689 | |||
690 | /* Translate ASN1 content octets into a structure */ | ||
691 | |||
692 | int asn1_ex_c2i(ASN1_VALUE **pval, unsigned char *cont, int len, int utype, char *free_cont, const ASN1_ITEM *it) | ||
693 | { | ||
694 | ASN1_STRING *stmp; | ||
695 | ASN1_TYPE *typ = NULL; | ||
696 | int ret = 0; | ||
697 | const ASN1_PRIMITIVE_FUNCS *pf; | ||
698 | ASN1_INTEGER **tint; | ||
699 | pf = it->funcs; | ||
700 | if(pf && pf->prim_c2i) return pf->prim_c2i(pval, cont, len, utype, free_cont, it); | ||
701 | /* If ANY type clear type and set pointer to internal value */ | ||
702 | if(it->utype == V_ASN1_ANY) { | ||
703 | if(!*pval) { | ||
704 | typ = ASN1_TYPE_new(); | ||
705 | *pval = (ASN1_VALUE *)typ; | ||
706 | } else typ = (ASN1_TYPE *)*pval; | ||
707 | if(utype != typ->type) ASN1_TYPE_set(typ, utype, NULL); | ||
708 | pval = (ASN1_VALUE **)&typ->value.ptr; | ||
709 | } | ||
710 | switch(utype) { | ||
711 | case V_ASN1_OBJECT: | ||
712 | if(!c2i_ASN1_OBJECT((ASN1_OBJECT **)pval, &cont, len)) goto err; | ||
713 | break; | ||
714 | |||
715 | case V_ASN1_NULL: | ||
716 | if(len) { | ||
717 | ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, ASN1_R_NULL_IS_WRONG_LENGTH); | ||
718 | goto err; | ||
719 | } | ||
720 | *pval = (ASN1_VALUE *)1; | ||
721 | break; | ||
722 | |||
723 | case V_ASN1_BOOLEAN: | ||
724 | if(len != 1) { | ||
725 | ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, ASN1_R_BOOLEAN_IS_WRONG_LENGTH); | ||
726 | goto err; | ||
727 | } else { | ||
728 | ASN1_BOOLEAN *tbool; | ||
729 | tbool = (ASN1_BOOLEAN *)pval; | ||
730 | *tbool = *cont; | ||
731 | } | ||
732 | break; | ||
733 | |||
734 | case V_ASN1_BIT_STRING: | ||
735 | if(!c2i_ASN1_BIT_STRING((ASN1_BIT_STRING **)pval, &cont, len)) goto err; | ||
736 | break; | ||
737 | |||
738 | case V_ASN1_INTEGER: | ||
739 | case V_ASN1_NEG_INTEGER: | ||
740 | case V_ASN1_ENUMERATED: | ||
741 | case V_ASN1_NEG_ENUMERATED: | ||
742 | tint = (ASN1_INTEGER **)pval; | ||
743 | if(!c2i_ASN1_INTEGER(tint, &cont, len)) goto err; | ||
744 | /* Fixup type to match the expected form */ | ||
745 | (*tint)->type = utype | ((*tint)->type & V_ASN1_NEG); | ||
746 | break; | ||
747 | |||
748 | case V_ASN1_OCTET_STRING: | ||
749 | case V_ASN1_NUMERICSTRING: | ||
750 | case V_ASN1_PRINTABLESTRING: | ||
751 | case V_ASN1_T61STRING: | ||
752 | case V_ASN1_VIDEOTEXSTRING: | ||
753 | case V_ASN1_IA5STRING: | ||
754 | case V_ASN1_UTCTIME: | ||
755 | case V_ASN1_GENERALIZEDTIME: | ||
756 | case V_ASN1_GRAPHICSTRING: | ||
757 | case V_ASN1_VISIBLESTRING: | ||
758 | case V_ASN1_GENERALSTRING: | ||
759 | case V_ASN1_UNIVERSALSTRING: | ||
760 | case V_ASN1_BMPSTRING: | ||
761 | case V_ASN1_UTF8STRING: | ||
762 | case V_ASN1_OTHER: | ||
763 | case V_ASN1_SET: | ||
764 | case V_ASN1_SEQUENCE: | ||
765 | default: | ||
766 | /* All based on ASN1_STRING and handled the same */ | ||
767 | if(!*pval) { | ||
768 | stmp = ASN1_STRING_type_new(utype); | ||
769 | if(!stmp) { | ||
770 | ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, ERR_R_MALLOC_FAILURE); | ||
771 | goto err; | ||
772 | } | ||
773 | *pval = (ASN1_VALUE *)stmp; | ||
774 | } else { | ||
775 | stmp = (ASN1_STRING *)*pval; | ||
776 | stmp->type = utype; | ||
777 | } | ||
778 | /* If we've already allocated a buffer use it */ | ||
779 | if(*free_cont) { | ||
780 | if(stmp->data) OPENSSL_free(stmp->data); | ||
781 | stmp->data = cont; | ||
782 | stmp->length = len; | ||
783 | *free_cont = 0; | ||
784 | } else { | ||
785 | if(!ASN1_STRING_set(stmp, cont, len)) { | ||
786 | ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, ERR_R_MALLOC_FAILURE); | ||
787 | ASN1_STRING_free(stmp); | ||
788 | *pval = NULL; | ||
789 | goto err; | ||
790 | } | ||
791 | } | ||
792 | break; | ||
793 | } | ||
794 | /* If ASN1_ANY and NULL type fix up value */ | ||
795 | if(typ && utype==V_ASN1_NULL) typ->value.ptr = NULL; | ||
796 | |||
797 | ret = 1; | ||
798 | err: | ||
799 | if(!ret) ASN1_TYPE_free(typ); | ||
800 | return ret; | ||
801 | } | ||
802 | |||
803 | /* This function collects the asn1 data from a constructred string | ||
804 | * type into a buffer. The values of 'in' and 'len' should refer | ||
805 | * to the contents of the constructed type and 'inf' should be set | ||
806 | * if it is indefinite length. If 'buf' is NULL then we just want | ||
807 | * to find the end of the current structure: useful for indefinite | ||
808 | * length constructed stuff. | ||
809 | */ | ||
810 | |||
811 | static int asn1_collect(BUF_MEM *buf, unsigned char **in, long len, char inf, int tag, int aclass) | ||
812 | { | ||
813 | unsigned char *p, *q; | ||
814 | long plen; | ||
815 | char cst, ininf; | ||
816 | p = *in; | ||
817 | inf &= 1; | ||
818 | /* If no buffer and not indefinite length constructed just pass over the encoded data */ | ||
819 | if(!buf && !inf) { | ||
820 | *in += len; | ||
821 | return 1; | ||
822 | } | ||
823 | while(len > 0) { | ||
824 | q = p; | ||
825 | /* Check for EOC */ | ||
826 | if(asn1_check_eoc(&p, len)) { | ||
827 | /* EOC is illegal outside indefinite length constructed form */ | ||
828 | if(!inf) { | ||
829 | ASN1err(ASN1_F_ASN1_COLLECT, ASN1_R_UNEXPECTED_EOC); | ||
830 | return 0; | ||
831 | } | ||
832 | inf = 0; | ||
833 | break; | ||
834 | } | ||
835 | if(!asn1_check_tlen(&plen, NULL, NULL, &ininf, &cst, &p, len, tag, aclass, 0, NULL)) { | ||
836 | ASN1err(ASN1_F_ASN1_COLLECT, ERR_R_NESTED_ASN1_ERROR); | ||
837 | return 0; | ||
838 | } | ||
839 | /* If indefinite length constructed update max length */ | ||
840 | if(cst) { | ||
841 | if(!asn1_collect(buf, &p, plen, ininf, tag, aclass)) return 0; | ||
842 | } else { | ||
843 | if(!collect_data(buf, &p, plen)) return 0; | ||
844 | } | ||
845 | len -= p - q; | ||
846 | } | ||
847 | if(inf) { | ||
848 | ASN1err(ASN1_F_ASN1_COLLECT, ASN1_R_MISSING_EOC); | ||
849 | return 0; | ||
850 | } | ||
851 | *in = p; | ||
852 | return 1; | ||
853 | } | ||
854 | |||
855 | static int collect_data(BUF_MEM *buf, unsigned char **p, long plen) | ||
856 | { | ||
857 | int len; | ||
858 | if(buf) { | ||
859 | len = buf->length; | ||
860 | if(!BUF_MEM_grow(buf, len + plen)) { | ||
861 | ASN1err(ASN1_F_COLLECT_DATA, ERR_R_MALLOC_FAILURE); | ||
862 | return 0; | ||
863 | } | ||
864 | memcpy(buf->data + len, *p, plen); | ||
865 | } | ||
866 | *p += plen; | ||
867 | return 1; | ||
868 | } | ||
869 | |||
870 | /* Check for ASN1 EOC and swallow it if found */ | ||
871 | |||
872 | static int asn1_check_eoc(unsigned char **in, long len) | ||
873 | { | ||
874 | unsigned char *p; | ||
875 | if(len < 2) return 0; | ||
876 | p = *in; | ||
877 | if(!p[0] && !p[1]) { | ||
878 | *in += 2; | ||
879 | return 1; | ||
880 | } | ||
881 | return 0; | ||
882 | } | ||
883 | |||
884 | /* Check an ASN1 tag and length: a bit like ASN1_get_object | ||
885 | * but it sets the length for indefinite length constructed | ||
886 | * form, we don't know the exact length but we can set an | ||
887 | * upper bound to the amount of data available minus the | ||
888 | * header length just read. | ||
889 | */ | ||
890 | |||
891 | static int asn1_check_tlen(long *olen, int *otag, unsigned char *oclass, char *inf, char *cst, | ||
892 | unsigned char **in, long len, int exptag, int expclass, char opt, ASN1_TLC *ctx) | ||
893 | { | ||
894 | int i; | ||
895 | int ptag, pclass; | ||
896 | long plen; | ||
897 | unsigned char *p, *q; | ||
898 | p = *in; | ||
899 | q = p; | ||
900 | |||
901 | if(ctx && ctx->valid) { | ||
902 | i = ctx->ret; | ||
903 | plen = ctx->plen; | ||
904 | pclass = ctx->pclass; | ||
905 | ptag = ctx->ptag; | ||
906 | p += ctx->hdrlen; | ||
907 | } else { | ||
908 | i = ASN1_get_object(&p, &plen, &ptag, &pclass, len); | ||
909 | if(ctx) { | ||
910 | ctx->ret = i; | ||
911 | ctx->plen = plen; | ||
912 | ctx->pclass = pclass; | ||
913 | ctx->ptag = ptag; | ||
914 | ctx->hdrlen = p - q; | ||
915 | ctx->valid = 1; | ||
916 | /* If definite length, length + header can't exceed total | ||
917 | * amount of data available. | ||
918 | */ | ||
919 | if(!(i & 1) && ((plen + ctx->hdrlen) > len)) { | ||
920 | ASN1err(ASN1_F_ASN1_CHECK_TLEN, ASN1_R_TOO_LONG); | ||
921 | asn1_tlc_clear(ctx); | ||
922 | return 0; | ||
923 | } | ||
924 | } | ||
925 | } | ||
926 | |||
927 | if(i & 0x80) { | ||
928 | ASN1err(ASN1_F_ASN1_CHECK_TLEN, ASN1_R_BAD_OBJECT_HEADER); | ||
929 | asn1_tlc_clear(ctx); | ||
930 | return 0; | ||
931 | } | ||
932 | if(exptag >= 0) { | ||
933 | if((exptag != ptag) || (expclass != pclass)) { | ||
934 | /* If type is OPTIONAL, not an error, but indicate missing | ||
935 | * type. | ||
936 | */ | ||
937 | if(opt) return -1; | ||
938 | asn1_tlc_clear(ctx); | ||
939 | ASN1err(ASN1_F_ASN1_CHECK_TLEN, ASN1_R_WRONG_TAG); | ||
940 | return 0; | ||
941 | } | ||
942 | /* We have a tag and class match, so assume we are going to do something with it */ | ||
943 | asn1_tlc_clear(ctx); | ||
944 | } | ||
945 | |||
946 | if(i & 1) plen = len - (p - q); | ||
947 | |||
948 | if(inf) *inf = i & 1; | ||
949 | |||
950 | if(cst) *cst = i & V_ASN1_CONSTRUCTED; | ||
951 | |||
952 | if(olen) *olen = plen; | ||
953 | if(oclass) *oclass = pclass; | ||
954 | if(otag) *otag = ptag; | ||
955 | |||
956 | *in = p; | ||
957 | return 1; | ||
958 | } | ||
diff --git a/src/lib/libcrypto/asn1/tasn_enc.c b/src/lib/libcrypto/asn1/tasn_enc.c new file mode 100644 index 0000000000..f6c8ddef0a --- /dev/null +++ b/src/lib/libcrypto/asn1/tasn_enc.c | |||
@@ -0,0 +1,497 @@ | |||
1 | /* tasn_enc.c */ | ||
2 | /* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL | ||
3 | * project 2000. | ||
4 | */ | ||
5 | /* ==================================================================== | ||
6 | * Copyright (c) 2000 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 <stddef.h> | ||
61 | #include <string.h> | ||
62 | #include <openssl/asn1.h> | ||
63 | #include <openssl/asn1t.h> | ||
64 | #include <openssl/objects.h> | ||
65 | |||
66 | static int asn1_i2d_ex_primitive(ASN1_VALUE **pval, unsigned char **out, const ASN1_ITEM *it, int tag, int aclass); | ||
67 | static int asn1_set_seq_out(STACK_OF(ASN1_VALUE) *seq, unsigned char **out, int skcontlen, const ASN1_ITEM *item, int isset); | ||
68 | |||
69 | /* Encode an ASN1 item, this is compatible with the | ||
70 | * standard 'i2d' function. 'out' points to | ||
71 | * a buffer to output the data to, in future we will | ||
72 | * have more advanced versions that can output data | ||
73 | * a piece at a time and this will simply be a special | ||
74 | * case. | ||
75 | * | ||
76 | * The new i2d has one additional feature. If the output | ||
77 | * buffer is NULL (i.e. *out == NULL) then a buffer is | ||
78 | * allocated and populated with the encoding. | ||
79 | */ | ||
80 | |||
81 | |||
82 | int ASN1_item_i2d(ASN1_VALUE *val, unsigned char **out, const ASN1_ITEM *it) | ||
83 | { | ||
84 | if(out && !*out) { | ||
85 | unsigned char *p, *buf; | ||
86 | int len; | ||
87 | len = ASN1_item_ex_i2d(&val, NULL, it, -1, 0); | ||
88 | if(len <= 0) return len; | ||
89 | buf = OPENSSL_malloc(len); | ||
90 | if(!buf) return -1; | ||
91 | p = buf; | ||
92 | ASN1_item_ex_i2d(&val, &p, it, -1, 0); | ||
93 | *out = buf; | ||
94 | return len; | ||
95 | } | ||
96 | |||
97 | return ASN1_item_ex_i2d(&val, out, it, -1, 0); | ||
98 | } | ||
99 | |||
100 | /* Encode an item, taking care of IMPLICIT tagging (if any). | ||
101 | * This function performs the normal item handling: it can be | ||
102 | * used in external types. | ||
103 | */ | ||
104 | |||
105 | int ASN1_item_ex_i2d(ASN1_VALUE **pval, unsigned char **out, const ASN1_ITEM *it, int tag, int aclass) | ||
106 | { | ||
107 | const ASN1_TEMPLATE *tt = NULL; | ||
108 | unsigned char *p = NULL; | ||
109 | int i, seqcontlen, seqlen; | ||
110 | ASN1_STRING *strtmp; | ||
111 | const ASN1_COMPAT_FUNCS *cf; | ||
112 | const ASN1_EXTERN_FUNCS *ef; | ||
113 | const ASN1_AUX *aux = it->funcs; | ||
114 | ASN1_aux_cb *asn1_cb; | ||
115 | if((it->itype != ASN1_ITYPE_PRIMITIVE) && !*pval) return 0; | ||
116 | if(aux && aux->asn1_cb) asn1_cb = aux->asn1_cb; | ||
117 | else asn1_cb = 0; | ||
118 | |||
119 | switch(it->itype) { | ||
120 | |||
121 | case ASN1_ITYPE_PRIMITIVE: | ||
122 | if(it->templates) | ||
123 | return ASN1_template_i2d(pval, out, it->templates); | ||
124 | return asn1_i2d_ex_primitive(pval, out, it, tag, aclass); | ||
125 | break; | ||
126 | |||
127 | case ASN1_ITYPE_MSTRING: | ||
128 | strtmp = (ASN1_STRING *)*pval; | ||
129 | return asn1_i2d_ex_primitive(pval, out, it, -1, 0); | ||
130 | |||
131 | case ASN1_ITYPE_CHOICE: | ||
132 | if(asn1_cb && !asn1_cb(ASN1_OP_I2D_PRE, pval, it)) | ||
133 | return 0; | ||
134 | i = asn1_get_choice_selector(pval, it); | ||
135 | if((i >= 0) && (i < it->tcount)) { | ||
136 | ASN1_VALUE **pchval; | ||
137 | const ASN1_TEMPLATE *chtt; | ||
138 | chtt = it->templates + i; | ||
139 | pchval = asn1_get_field_ptr(pval, chtt); | ||
140 | return ASN1_template_i2d(pchval, out, chtt); | ||
141 | } | ||
142 | /* Fixme: error condition if selector out of range */ | ||
143 | if(asn1_cb && !asn1_cb(ASN1_OP_I2D_POST, pval, it)) | ||
144 | return 0; | ||
145 | break; | ||
146 | |||
147 | case ASN1_ITYPE_EXTERN: | ||
148 | /* If new style i2d it does all the work */ | ||
149 | ef = it->funcs; | ||
150 | return ef->asn1_ex_i2d(pval, out, it, tag, aclass); | ||
151 | |||
152 | case ASN1_ITYPE_COMPAT: | ||
153 | /* old style hackery... */ | ||
154 | cf = it->funcs; | ||
155 | if(out) p = *out; | ||
156 | i = cf->asn1_i2d(*pval, out); | ||
157 | /* Fixup for IMPLICIT tag: note this messes up for tags > 30, | ||
158 | * but so did the old code. Tags > 30 are very rare anyway. | ||
159 | */ | ||
160 | if(out && (tag != -1)) | ||
161 | *p = aclass | tag | (*p & V_ASN1_CONSTRUCTED); | ||
162 | return i; | ||
163 | |||
164 | case ASN1_ITYPE_SEQUENCE: | ||
165 | i = asn1_enc_restore(&seqcontlen, out, pval, it); | ||
166 | /* An error occurred */ | ||
167 | if(i < 0) return 0; | ||
168 | /* We have a valid cached encoding... */ | ||
169 | if(i > 0) return seqcontlen; | ||
170 | /* Otherwise carry on */ | ||
171 | seqcontlen = 0; | ||
172 | /* If no IMPLICIT tagging set to SEQUENCE, UNIVERSAL */ | ||
173 | if(tag == -1) { | ||
174 | tag = V_ASN1_SEQUENCE; | ||
175 | aclass = V_ASN1_UNIVERSAL; | ||
176 | } | ||
177 | if(asn1_cb && !asn1_cb(ASN1_OP_I2D_PRE, pval, it)) | ||
178 | return 0; | ||
179 | /* First work out sequence content length */ | ||
180 | for(i = 0, tt = it->templates; i < it->tcount; tt++, i++) { | ||
181 | const ASN1_TEMPLATE *seqtt; | ||
182 | ASN1_VALUE **pseqval; | ||
183 | seqtt = asn1_do_adb(pval, tt, 1); | ||
184 | if(!seqtt) return 0; | ||
185 | pseqval = asn1_get_field_ptr(pval, seqtt); | ||
186 | /* FIXME: check for errors in enhanced version */ | ||
187 | /* FIXME: special handling of indefinite length encoding */ | ||
188 | seqcontlen += ASN1_template_i2d(pseqval, NULL, seqtt); | ||
189 | } | ||
190 | seqlen = ASN1_object_size(1, seqcontlen, tag); | ||
191 | if(!out) return seqlen; | ||
192 | /* Output SEQUENCE header */ | ||
193 | ASN1_put_object(out, 1, seqcontlen, tag, aclass); | ||
194 | for(i = 0, tt = it->templates; i < it->tcount; tt++, i++) { | ||
195 | const ASN1_TEMPLATE *seqtt; | ||
196 | ASN1_VALUE **pseqval; | ||
197 | seqtt = asn1_do_adb(pval, tt, 1); | ||
198 | if(!seqtt) return 0; | ||
199 | pseqval = asn1_get_field_ptr(pval, seqtt); | ||
200 | /* FIXME: check for errors in enhanced version */ | ||
201 | ASN1_template_i2d(pseqval, out, seqtt); | ||
202 | } | ||
203 | if(asn1_cb && !asn1_cb(ASN1_OP_I2D_POST, pval, it)) | ||
204 | return 0; | ||
205 | return seqlen; | ||
206 | |||
207 | default: | ||
208 | return 0; | ||
209 | } | ||
210 | return 0; | ||
211 | } | ||
212 | |||
213 | int ASN1_template_i2d(ASN1_VALUE **pval, unsigned char **out, const ASN1_TEMPLATE *tt) | ||
214 | { | ||
215 | int i, ret, flags, aclass; | ||
216 | flags = tt->flags; | ||
217 | aclass = flags & ASN1_TFLG_TAG_CLASS; | ||
218 | if(flags & ASN1_TFLG_SK_MASK) { | ||
219 | /* SET OF, SEQUENCE OF */ | ||
220 | STACK_OF(ASN1_VALUE) *sk = (STACK_OF(ASN1_VALUE) *)*pval; | ||
221 | int isset, sktag, skaclass; | ||
222 | int skcontlen, sklen; | ||
223 | ASN1_VALUE *skitem; | ||
224 | if(!*pval) return 0; | ||
225 | if(flags & ASN1_TFLG_SET_OF) { | ||
226 | isset = 1; | ||
227 | /* 2 means we reorder */ | ||
228 | if(flags & ASN1_TFLG_SEQUENCE_OF) isset = 2; | ||
229 | } else isset = 0; | ||
230 | /* First work out inner tag value */ | ||
231 | if(flags & ASN1_TFLG_IMPTAG) { | ||
232 | sktag = tt->tag; | ||
233 | skaclass = aclass; | ||
234 | } else { | ||
235 | skaclass = V_ASN1_UNIVERSAL; | ||
236 | if(isset) sktag = V_ASN1_SET; | ||
237 | else sktag = V_ASN1_SEQUENCE; | ||
238 | } | ||
239 | /* Now work out length of items */ | ||
240 | skcontlen = 0; | ||
241 | for(i = 0; i < sk_ASN1_VALUE_num(sk); i++) { | ||
242 | skitem = sk_ASN1_VALUE_value(sk, i); | ||
243 | skcontlen += ASN1_item_ex_i2d(&skitem, NULL, ASN1_ITEM_ptr(tt->item), -1, 0); | ||
244 | } | ||
245 | sklen = ASN1_object_size(1, skcontlen, sktag); | ||
246 | /* If EXPLICIT need length of surrounding tag */ | ||
247 | if(flags & ASN1_TFLG_EXPTAG) | ||
248 | ret = ASN1_object_size(1, sklen, tt->tag); | ||
249 | else ret = sklen; | ||
250 | |||
251 | if(!out) return ret; | ||
252 | |||
253 | /* Now encode this lot... */ | ||
254 | /* EXPLICIT tag */ | ||
255 | if(flags & ASN1_TFLG_EXPTAG) | ||
256 | ASN1_put_object(out, 1, sklen, tt->tag, aclass); | ||
257 | /* SET or SEQUENCE and IMPLICIT tag */ | ||
258 | ASN1_put_object(out, 1, skcontlen, sktag, skaclass); | ||
259 | /* And finally the stuff itself */ | ||
260 | asn1_set_seq_out(sk, out, skcontlen, ASN1_ITEM_ptr(tt->item), isset); | ||
261 | |||
262 | return ret; | ||
263 | } | ||
264 | |||
265 | if(flags & ASN1_TFLG_EXPTAG) { | ||
266 | /* EXPLICIT tagging */ | ||
267 | /* Find length of tagged item */ | ||
268 | i = ASN1_item_ex_i2d(pval, NULL, ASN1_ITEM_ptr(tt->item), -1, 0); | ||
269 | if(!i) return 0; | ||
270 | /* Find length of EXPLICIT tag */ | ||
271 | ret = ASN1_object_size(1, i, tt->tag); | ||
272 | if(out) { | ||
273 | /* Output tag and item */ | ||
274 | ASN1_put_object(out, 1, i, tt->tag, aclass); | ||
275 | ASN1_item_ex_i2d(pval, out, ASN1_ITEM_ptr(tt->item), -1, 0); | ||
276 | } | ||
277 | return ret; | ||
278 | } | ||
279 | if(flags & ASN1_TFLG_IMPTAG) { | ||
280 | /* IMPLICIT tagging */ | ||
281 | return ASN1_item_ex_i2d(pval, out, ASN1_ITEM_ptr(tt->item), tt->tag, aclass); | ||
282 | } | ||
283 | /* Nothing special: treat as normal */ | ||
284 | return ASN1_item_ex_i2d(pval, out, ASN1_ITEM_ptr(tt->item), -1, 0); | ||
285 | } | ||
286 | |||
287 | /* Temporary structure used to hold DER encoding of items for SET OF */ | ||
288 | |||
289 | typedef struct { | ||
290 | unsigned char *data; | ||
291 | int length; | ||
292 | ASN1_VALUE *field; | ||
293 | } DER_ENC; | ||
294 | |||
295 | static int der_cmp(const void *a, const void *b) | ||
296 | { | ||
297 | const DER_ENC *d1 = a, *d2 = b; | ||
298 | int cmplen, i; | ||
299 | cmplen = (d1->length < d2->length) ? d1->length : d2->length; | ||
300 | i = memcmp(d1->data, d2->data, cmplen); | ||
301 | if(i) return i; | ||
302 | return d1->length - d2->length; | ||
303 | } | ||
304 | |||
305 | /* Output the content octets of SET OF or SEQUENCE OF */ | ||
306 | |||
307 | static int asn1_set_seq_out(STACK_OF(ASN1_VALUE) *sk, unsigned char **out, int skcontlen, const ASN1_ITEM *item, int do_sort) | ||
308 | { | ||
309 | int i; | ||
310 | ASN1_VALUE *skitem; | ||
311 | unsigned char *tmpdat = NULL, *p = NULL; | ||
312 | DER_ENC *derlst = NULL, *tder; | ||
313 | if(do_sort) { | ||
314 | /* Don't need to sort less than 2 items */ | ||
315 | if(sk_ASN1_VALUE_num(sk) < 2) do_sort = 0; | ||
316 | else { | ||
317 | derlst = OPENSSL_malloc(sk_ASN1_VALUE_num(sk) * sizeof(*derlst)); | ||
318 | tmpdat = OPENSSL_malloc(skcontlen); | ||
319 | if(!derlst || !tmpdat) return 0; | ||
320 | } | ||
321 | } | ||
322 | /* If not sorting just output each item */ | ||
323 | if(!do_sort) { | ||
324 | for(i = 0; i < sk_ASN1_VALUE_num(sk); i++) { | ||
325 | skitem = sk_ASN1_VALUE_value(sk, i); | ||
326 | ASN1_item_i2d(skitem, out, item); | ||
327 | } | ||
328 | return 1; | ||
329 | } | ||
330 | p = tmpdat; | ||
331 | /* Doing sort: build up a list of each member's DER encoding */ | ||
332 | for(i = 0, tder = derlst; i < sk_ASN1_VALUE_num(sk); i++, tder++) { | ||
333 | skitem = sk_ASN1_VALUE_value(sk, i); | ||
334 | tder->data = p; | ||
335 | tder->length = ASN1_item_i2d(skitem, &p, item); | ||
336 | tder->field = skitem; | ||
337 | } | ||
338 | /* Now sort them */ | ||
339 | qsort(derlst, sk_ASN1_VALUE_num(sk), sizeof(*derlst), der_cmp); | ||
340 | /* Output sorted DER encoding */ | ||
341 | p = *out; | ||
342 | for(i = 0, tder = derlst; i < sk_ASN1_VALUE_num(sk); i++, tder++) { | ||
343 | memcpy(p, tder->data, tder->length); | ||
344 | p += tder->length; | ||
345 | } | ||
346 | *out = p; | ||
347 | /* If do_sort is 2 then reorder the STACK */ | ||
348 | if(do_sort == 2) { | ||
349 | for(i = 0, tder = derlst; i < sk_ASN1_VALUE_num(sk); i++, tder++) | ||
350 | sk_ASN1_VALUE_set(sk, i, tder->field); | ||
351 | } | ||
352 | OPENSSL_free(derlst); | ||
353 | OPENSSL_free(tmpdat); | ||
354 | return 1; | ||
355 | } | ||
356 | |||
357 | static int asn1_i2d_ex_primitive(ASN1_VALUE **pval, unsigned char **out, const ASN1_ITEM *it, int tag, int aclass) | ||
358 | { | ||
359 | int len; | ||
360 | int utype; | ||
361 | int usetag; | ||
362 | |||
363 | utype = it->utype; | ||
364 | |||
365 | /* Get length of content octets and maybe find | ||
366 | * out the underlying type. | ||
367 | */ | ||
368 | |||
369 | len = asn1_ex_i2c(pval, NULL, &utype, it); | ||
370 | |||
371 | /* If SEQUENCE, SET or OTHER then header is | ||
372 | * included in pseudo content octets so don't | ||
373 | * include tag+length. We need to check here | ||
374 | * because the call to asn1_ex_i2c() could change | ||
375 | * utype. | ||
376 | */ | ||
377 | if((utype == V_ASN1_SEQUENCE) || (utype == V_ASN1_SET) || | ||
378 | (utype == V_ASN1_OTHER)) | ||
379 | usetag = 0; | ||
380 | else usetag = 1; | ||
381 | |||
382 | /* -1 means omit type */ | ||
383 | |||
384 | if(len == -1) return 0; | ||
385 | |||
386 | /* If not implicitly tagged get tag from underlying type */ | ||
387 | if(tag == -1) tag = utype; | ||
388 | |||
389 | /* Output tag+length followed by content octets */ | ||
390 | if(out) { | ||
391 | if(usetag) ASN1_put_object(out, 0, len, tag, aclass); | ||
392 | asn1_ex_i2c(pval, *out, &utype, it); | ||
393 | *out += len; | ||
394 | } | ||
395 | |||
396 | if(usetag) return ASN1_object_size(0, len, tag); | ||
397 | return len; | ||
398 | } | ||
399 | |||
400 | /* Produce content octets from a structure */ | ||
401 | |||
402 | int asn1_ex_i2c(ASN1_VALUE **pval, unsigned char *cout, int *putype, const ASN1_ITEM *it) | ||
403 | { | ||
404 | ASN1_BOOLEAN *tbool = NULL; | ||
405 | ASN1_STRING *strtmp; | ||
406 | ASN1_OBJECT *otmp; | ||
407 | int utype; | ||
408 | unsigned char *cont, c; | ||
409 | int len; | ||
410 | const ASN1_PRIMITIVE_FUNCS *pf; | ||
411 | pf = it->funcs; | ||
412 | if(pf && pf->prim_i2c) return pf->prim_i2c(pval, cout, putype, it); | ||
413 | |||
414 | /* Should type be omitted? */ | ||
415 | if((it->itype != ASN1_ITYPE_PRIMITIVE) || (it->utype != V_ASN1_BOOLEAN)) { | ||
416 | if(!*pval) return -1; | ||
417 | } | ||
418 | |||
419 | if(it->itype == ASN1_ITYPE_MSTRING) { | ||
420 | /* If MSTRING type set the underlying type */ | ||
421 | strtmp = (ASN1_STRING *)*pval; | ||
422 | utype = strtmp->type; | ||
423 | *putype = utype; | ||
424 | } else if(it->utype == V_ASN1_ANY) { | ||
425 | /* If ANY set type and pointer to value */ | ||
426 | ASN1_TYPE *typ; | ||
427 | typ = (ASN1_TYPE *)*pval; | ||
428 | utype = typ->type; | ||
429 | *putype = utype; | ||
430 | pval = (ASN1_VALUE **)&typ->value.ptr; | ||
431 | } else utype = *putype; | ||
432 | |||
433 | switch(utype) { | ||
434 | case V_ASN1_OBJECT: | ||
435 | otmp = (ASN1_OBJECT *)*pval; | ||
436 | cont = otmp->data; | ||
437 | len = otmp->length; | ||
438 | break; | ||
439 | |||
440 | case V_ASN1_NULL: | ||
441 | cont = NULL; | ||
442 | len = 0; | ||
443 | break; | ||
444 | |||
445 | case V_ASN1_BOOLEAN: | ||
446 | tbool = (ASN1_BOOLEAN *)pval; | ||
447 | if(*tbool == -1) return -1; | ||
448 | /* Default handling if value == size field then omit */ | ||
449 | if(*tbool && (it->size > 0)) return -1; | ||
450 | if(!*tbool && !it->size) return -1; | ||
451 | c = (unsigned char)*tbool; | ||
452 | cont = &c; | ||
453 | len = 1; | ||
454 | break; | ||
455 | |||
456 | case V_ASN1_BIT_STRING: | ||
457 | return i2c_ASN1_BIT_STRING((ASN1_BIT_STRING *)*pval, cout ? &cout : NULL); | ||
458 | break; | ||
459 | |||
460 | case V_ASN1_INTEGER: | ||
461 | case V_ASN1_NEG_INTEGER: | ||
462 | case V_ASN1_ENUMERATED: | ||
463 | case V_ASN1_NEG_ENUMERATED: | ||
464 | /* These are all have the same content format | ||
465 | * as ASN1_INTEGER | ||
466 | */ | ||
467 | return i2c_ASN1_INTEGER((ASN1_INTEGER *)*pval, cout ? &cout : NULL); | ||
468 | break; | ||
469 | |||
470 | case V_ASN1_OCTET_STRING: | ||
471 | case V_ASN1_NUMERICSTRING: | ||
472 | case V_ASN1_PRINTABLESTRING: | ||
473 | case V_ASN1_T61STRING: | ||
474 | case V_ASN1_VIDEOTEXSTRING: | ||
475 | case V_ASN1_IA5STRING: | ||
476 | case V_ASN1_UTCTIME: | ||
477 | case V_ASN1_GENERALIZEDTIME: | ||
478 | case V_ASN1_GRAPHICSTRING: | ||
479 | case V_ASN1_VISIBLESTRING: | ||
480 | case V_ASN1_GENERALSTRING: | ||
481 | case V_ASN1_UNIVERSALSTRING: | ||
482 | case V_ASN1_BMPSTRING: | ||
483 | case V_ASN1_UTF8STRING: | ||
484 | case V_ASN1_SEQUENCE: | ||
485 | case V_ASN1_SET: | ||
486 | default: | ||
487 | /* All based on ASN1_STRING and handled the same */ | ||
488 | strtmp = (ASN1_STRING *)*pval; | ||
489 | cont = strtmp->data; | ||
490 | len = strtmp->length; | ||
491 | |||
492 | break; | ||
493 | |||
494 | } | ||
495 | if(cout && len) memcpy(cout, cont, len); | ||
496 | return len; | ||
497 | } | ||
diff --git a/src/lib/libcrypto/asn1/tasn_fre.c b/src/lib/libcrypto/asn1/tasn_fre.c new file mode 100644 index 0000000000..c7610776f2 --- /dev/null +++ b/src/lib/libcrypto/asn1/tasn_fre.c | |||
@@ -0,0 +1,226 @@ | |||
1 | /* tasn_fre.c */ | ||
2 | /* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL | ||
3 | * project 2000. | ||
4 | */ | ||
5 | /* ==================================================================== | ||
6 | * Copyright (c) 2000 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 <stddef.h> | ||
61 | #include <openssl/asn1.h> | ||
62 | #include <openssl/asn1t.h> | ||
63 | #include <openssl/objects.h> | ||
64 | |||
65 | static void asn1_item_combine_free(ASN1_VALUE **pval, const ASN1_ITEM *it, int combine); | ||
66 | |||
67 | /* Free up an ASN1 structure */ | ||
68 | |||
69 | void ASN1_item_free(ASN1_VALUE *val, const ASN1_ITEM *it) | ||
70 | { | ||
71 | asn1_item_combine_free(&val, it, 0); | ||
72 | } | ||
73 | |||
74 | void ASN1_item_ex_free(ASN1_VALUE **pval, const ASN1_ITEM *it) | ||
75 | { | ||
76 | asn1_item_combine_free(pval, it, 0); | ||
77 | } | ||
78 | |||
79 | static void asn1_item_combine_free(ASN1_VALUE **pval, const ASN1_ITEM *it, int combine) | ||
80 | { | ||
81 | const ASN1_TEMPLATE *tt = NULL, *seqtt; | ||
82 | const ASN1_EXTERN_FUNCS *ef; | ||
83 | const ASN1_COMPAT_FUNCS *cf; | ||
84 | const ASN1_AUX *aux = it->funcs; | ||
85 | ASN1_aux_cb *asn1_cb; | ||
86 | int i; | ||
87 | if(!pval) return; | ||
88 | if((it->itype != ASN1_ITYPE_PRIMITIVE) && !*pval) return; | ||
89 | if(aux && aux->asn1_cb) asn1_cb = aux->asn1_cb; | ||
90 | else asn1_cb = 0; | ||
91 | |||
92 | switch(it->itype) { | ||
93 | |||
94 | case ASN1_ITYPE_PRIMITIVE: | ||
95 | if(it->templates) ASN1_template_free(pval, it->templates); | ||
96 | else ASN1_primitive_free(pval, it); | ||
97 | break; | ||
98 | |||
99 | case ASN1_ITYPE_MSTRING: | ||
100 | ASN1_primitive_free(pval, it); | ||
101 | break; | ||
102 | |||
103 | case ASN1_ITYPE_CHOICE: | ||
104 | if(asn1_cb) { | ||
105 | i = asn1_cb(ASN1_OP_FREE_PRE, pval, it); | ||
106 | if(i == 2) return; | ||
107 | } | ||
108 | i = asn1_get_choice_selector(pval, it); | ||
109 | if(asn1_cb) asn1_cb(ASN1_OP_FREE_PRE, pval, it); | ||
110 | if((i >= 0) && (i < it->tcount)) { | ||
111 | ASN1_VALUE **pchval; | ||
112 | tt = it->templates + i; | ||
113 | pchval = asn1_get_field_ptr(pval, tt); | ||
114 | ASN1_template_free(pchval, tt); | ||
115 | } | ||
116 | if(asn1_cb) asn1_cb(ASN1_OP_FREE_POST, pval, it); | ||
117 | if(!combine) { | ||
118 | OPENSSL_free(*pval); | ||
119 | *pval = NULL; | ||
120 | } | ||
121 | break; | ||
122 | |||
123 | case ASN1_ITYPE_COMPAT: | ||
124 | cf = it->funcs; | ||
125 | if(cf && cf->asn1_free) cf->asn1_free(*pval); | ||
126 | break; | ||
127 | |||
128 | case ASN1_ITYPE_EXTERN: | ||
129 | ef = it->funcs; | ||
130 | if(ef && ef->asn1_ex_free) ef->asn1_ex_free(pval, it); | ||
131 | break; | ||
132 | |||
133 | case ASN1_ITYPE_SEQUENCE: | ||
134 | if(asn1_do_lock(pval, -1, it) > 0) return; | ||
135 | if(asn1_cb) { | ||
136 | i = asn1_cb(ASN1_OP_FREE_PRE, pval, it); | ||
137 | if(i == 2) return; | ||
138 | } | ||
139 | asn1_enc_free(pval, it); | ||
140 | /* If we free up as normal we will invalidate any | ||
141 | * ANY DEFINED BY field and we wont be able to | ||
142 | * determine the type of the field it defines. So | ||
143 | * free up in reverse order. | ||
144 | */ | ||
145 | tt = it->templates + it->tcount - 1; | ||
146 | for(i = 0; i < it->tcount; tt--, i++) { | ||
147 | ASN1_VALUE **pseqval; | ||
148 | seqtt = asn1_do_adb(pval, tt, 0); | ||
149 | if(!seqtt) continue; | ||
150 | pseqval = asn1_get_field_ptr(pval, seqtt); | ||
151 | ASN1_template_free(pseqval, seqtt); | ||
152 | } | ||
153 | if(asn1_cb) asn1_cb(ASN1_OP_FREE_POST, pval, it); | ||
154 | if(!combine) { | ||
155 | OPENSSL_free(*pval); | ||
156 | *pval = NULL; | ||
157 | } | ||
158 | break; | ||
159 | } | ||
160 | } | ||
161 | |||
162 | void ASN1_template_free(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt) | ||
163 | { | ||
164 | int i; | ||
165 | if(tt->flags & ASN1_TFLG_SK_MASK) { | ||
166 | STACK_OF(ASN1_VALUE) *sk = (STACK_OF(ASN1_VALUE) *)*pval; | ||
167 | for(i = 0; i < sk_ASN1_VALUE_num(sk); i++) { | ||
168 | ASN1_VALUE *vtmp; | ||
169 | vtmp = sk_ASN1_VALUE_value(sk, i); | ||
170 | asn1_item_combine_free(&vtmp, ASN1_ITEM_ptr(tt->item), 0); | ||
171 | } | ||
172 | sk_ASN1_VALUE_free(sk); | ||
173 | *pval = NULL; | ||
174 | } else asn1_item_combine_free(pval, ASN1_ITEM_ptr(tt->item), | ||
175 | tt->flags & ASN1_TFLG_COMBINE); | ||
176 | } | ||
177 | |||
178 | void ASN1_primitive_free(ASN1_VALUE **pval, const ASN1_ITEM *it) | ||
179 | { | ||
180 | int utype; | ||
181 | if(it) { | ||
182 | const ASN1_PRIMITIVE_FUNCS *pf; | ||
183 | pf = it->funcs; | ||
184 | if(pf && pf->prim_free) { | ||
185 | pf->prim_free(pval, it); | ||
186 | return; | ||
187 | } | ||
188 | } | ||
189 | /* Special case: if 'it' is NULL free contents of ASN1_TYPE */ | ||
190 | if(!it) { | ||
191 | ASN1_TYPE *typ = (ASN1_TYPE *)*pval; | ||
192 | utype = typ->type; | ||
193 | pval = (ASN1_VALUE **)&typ->value.ptr; | ||
194 | if(!*pval) return; | ||
195 | } else if(it->itype == ASN1_ITYPE_MSTRING) { | ||
196 | utype = -1; | ||
197 | if(!*pval) return; | ||
198 | } else { | ||
199 | utype = it->utype; | ||
200 | if((utype != V_ASN1_BOOLEAN) && !*pval) return; | ||
201 | } | ||
202 | |||
203 | switch(utype) { | ||
204 | case V_ASN1_OBJECT: | ||
205 | ASN1_OBJECT_free((ASN1_OBJECT *)*pval); | ||
206 | break; | ||
207 | |||
208 | case V_ASN1_BOOLEAN: | ||
209 | *(ASN1_BOOLEAN *)pval = it->size; | ||
210 | return; | ||
211 | |||
212 | case V_ASN1_NULL: | ||
213 | break; | ||
214 | |||
215 | case V_ASN1_ANY: | ||
216 | ASN1_primitive_free(pval, NULL); | ||
217 | OPENSSL_free(*pval); | ||
218 | break; | ||
219 | |||
220 | default: | ||
221 | ASN1_STRING_free((ASN1_STRING *)*pval); | ||
222 | *pval = NULL; | ||
223 | break; | ||
224 | } | ||
225 | *pval = NULL; | ||
226 | } | ||
diff --git a/src/lib/libcrypto/asn1/tasn_new.c b/src/lib/libcrypto/asn1/tasn_new.c new file mode 100644 index 0000000000..e33861f864 --- /dev/null +++ b/src/lib/libcrypto/asn1/tasn_new.c | |||
@@ -0,0 +1,348 @@ | |||
1 | /* tasn_new.c */ | ||
2 | /* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL | ||
3 | * project 2000. | ||
4 | */ | ||
5 | /* ==================================================================== | ||
6 | * Copyright (c) 2000 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 <stddef.h> | ||
61 | #include <openssl/asn1.h> | ||
62 | #include <openssl/objects.h> | ||
63 | #include <openssl/err.h> | ||
64 | #include <openssl/asn1t.h> | ||
65 | #include <string.h> | ||
66 | |||
67 | static int asn1_item_ex_combine_new(ASN1_VALUE **pval, const ASN1_ITEM *it, int combine); | ||
68 | static void asn1_item_clear(ASN1_VALUE **pval, const ASN1_ITEM *it); | ||
69 | static void asn1_template_clear(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt); | ||
70 | void asn1_primitive_clear(ASN1_VALUE **pval, const ASN1_ITEM *it); | ||
71 | |||
72 | ASN1_VALUE *ASN1_item_new(const ASN1_ITEM *it) | ||
73 | { | ||
74 | ASN1_VALUE *ret = NULL; | ||
75 | if(ASN1_item_ex_new(&ret, it) > 0) return ret; | ||
76 | return NULL; | ||
77 | } | ||
78 | |||
79 | /* Allocate an ASN1 structure */ | ||
80 | |||
81 | int ASN1_item_ex_new(ASN1_VALUE **pval, const ASN1_ITEM *it) | ||
82 | { | ||
83 | return asn1_item_ex_combine_new(pval, it, 0); | ||
84 | } | ||
85 | |||
86 | static int asn1_item_ex_combine_new(ASN1_VALUE **pval, const ASN1_ITEM *it, int combine) | ||
87 | { | ||
88 | const ASN1_TEMPLATE *tt = NULL; | ||
89 | const ASN1_COMPAT_FUNCS *cf; | ||
90 | const ASN1_EXTERN_FUNCS *ef; | ||
91 | const ASN1_AUX *aux = it->funcs; | ||
92 | ASN1_aux_cb *asn1_cb; | ||
93 | ASN1_VALUE **pseqval; | ||
94 | int i; | ||
95 | if(aux && aux->asn1_cb) asn1_cb = aux->asn1_cb; | ||
96 | else asn1_cb = 0; | ||
97 | |||
98 | if(!combine) *pval = NULL; | ||
99 | |||
100 | #ifdef CRYPTO_MDEBUG | ||
101 | if(it->sname) CRYPTO_push_info(it->sname); | ||
102 | #endif | ||
103 | |||
104 | switch(it->itype) { | ||
105 | |||
106 | case ASN1_ITYPE_EXTERN: | ||
107 | ef = it->funcs; | ||
108 | if(ef && ef->asn1_ex_new) { | ||
109 | if(!ef->asn1_ex_new(pval, it)) | ||
110 | goto memerr; | ||
111 | } | ||
112 | break; | ||
113 | |||
114 | case ASN1_ITYPE_COMPAT: | ||
115 | cf = it->funcs; | ||
116 | if(cf && cf->asn1_new) { | ||
117 | *pval = cf->asn1_new(); | ||
118 | if(!*pval) goto memerr; | ||
119 | } | ||
120 | break; | ||
121 | |||
122 | case ASN1_ITYPE_PRIMITIVE: | ||
123 | if(it->templates) { | ||
124 | if(!ASN1_template_new(pval, it->templates)) | ||
125 | goto memerr; | ||
126 | } else { | ||
127 | if(!ASN1_primitive_new(pval, it)) | ||
128 | goto memerr; | ||
129 | } | ||
130 | break; | ||
131 | |||
132 | case ASN1_ITYPE_MSTRING: | ||
133 | if(!ASN1_primitive_new(pval, it)) | ||
134 | goto memerr; | ||
135 | break; | ||
136 | |||
137 | case ASN1_ITYPE_CHOICE: | ||
138 | if(asn1_cb) { | ||
139 | i = asn1_cb(ASN1_OP_NEW_PRE, pval, it); | ||
140 | if(!i) goto auxerr; | ||
141 | if(i==2) { | ||
142 | #ifdef CRYPTO_MDEBUG | ||
143 | if(it->sname) CRYPTO_pop_info(); | ||
144 | #endif | ||
145 | return 1; | ||
146 | } | ||
147 | } | ||
148 | if(!combine) { | ||
149 | *pval = OPENSSL_malloc(it->size); | ||
150 | if(!*pval) goto memerr; | ||
151 | memset(*pval, 0, it->size); | ||
152 | } | ||
153 | asn1_set_choice_selector(pval, -1, it); | ||
154 | if(asn1_cb && !asn1_cb(ASN1_OP_NEW_POST, pval, it)) | ||
155 | goto auxerr; | ||
156 | break; | ||
157 | |||
158 | case ASN1_ITYPE_SEQUENCE: | ||
159 | if(asn1_cb) { | ||
160 | i = asn1_cb(ASN1_OP_NEW_PRE, pval, it); | ||
161 | if(!i) goto auxerr; | ||
162 | if(i==2) { | ||
163 | #ifdef CRYPTO_MDEBUG | ||
164 | if(it->sname) CRYPTO_pop_info(); | ||
165 | #endif | ||
166 | return 1; | ||
167 | } | ||
168 | } | ||
169 | if(!combine) { | ||
170 | *pval = OPENSSL_malloc(it->size); | ||
171 | if(!*pval) goto memerr; | ||
172 | memset(*pval, 0, it->size); | ||
173 | asn1_do_lock(pval, 0, it); | ||
174 | asn1_enc_init(pval, it); | ||
175 | } | ||
176 | for(i = 0, tt = it->templates; i < it->tcount; tt++, i++) { | ||
177 | pseqval = asn1_get_field_ptr(pval, tt); | ||
178 | if(!ASN1_template_new(pseqval, tt)) goto memerr; | ||
179 | } | ||
180 | if(asn1_cb && !asn1_cb(ASN1_OP_NEW_POST, pval, it)) | ||
181 | goto auxerr; | ||
182 | break; | ||
183 | } | ||
184 | #ifdef CRYPTO_MDEBUG | ||
185 | if(it->sname) CRYPTO_pop_info(); | ||
186 | #endif | ||
187 | return 1; | ||
188 | |||
189 | memerr: | ||
190 | ASN1err(ASN1_F_ASN1_ITEM_NEW, ERR_R_MALLOC_FAILURE); | ||
191 | #ifdef CRYPTO_MDEBUG | ||
192 | if(it->sname) CRYPTO_pop_info(); | ||
193 | #endif | ||
194 | return 0; | ||
195 | |||
196 | auxerr: | ||
197 | ASN1err(ASN1_F_ASN1_ITEM_NEW, ASN1_R_AUX_ERROR); | ||
198 | ASN1_item_ex_free(pval, it); | ||
199 | #ifdef CRYPTO_MDEBUG | ||
200 | if(it->sname) CRYPTO_pop_info(); | ||
201 | #endif | ||
202 | return 0; | ||
203 | |||
204 | } | ||
205 | |||
206 | static void asn1_item_clear(ASN1_VALUE **pval, const ASN1_ITEM *it) | ||
207 | { | ||
208 | const ASN1_EXTERN_FUNCS *ef; | ||
209 | |||
210 | switch(it->itype) { | ||
211 | |||
212 | case ASN1_ITYPE_EXTERN: | ||
213 | ef = it->funcs; | ||
214 | if(ef && ef->asn1_ex_clear) | ||
215 | ef->asn1_ex_clear(pval, it); | ||
216 | else *pval = NULL; | ||
217 | break; | ||
218 | |||
219 | |||
220 | case ASN1_ITYPE_PRIMITIVE: | ||
221 | if(it->templates) | ||
222 | asn1_template_clear(pval, it->templates); | ||
223 | else | ||
224 | asn1_primitive_clear(pval, it); | ||
225 | break; | ||
226 | |||
227 | case ASN1_ITYPE_MSTRING: | ||
228 | asn1_primitive_clear(pval, it); | ||
229 | break; | ||
230 | |||
231 | case ASN1_ITYPE_COMPAT: | ||
232 | case ASN1_ITYPE_CHOICE: | ||
233 | case ASN1_ITYPE_SEQUENCE: | ||
234 | *pval = NULL; | ||
235 | break; | ||
236 | } | ||
237 | } | ||
238 | |||
239 | |||
240 | int ASN1_template_new(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt) | ||
241 | { | ||
242 | const ASN1_ITEM *it = ASN1_ITEM_ptr(tt->item); | ||
243 | int ret; | ||
244 | if(tt->flags & ASN1_TFLG_OPTIONAL) { | ||
245 | asn1_template_clear(pval, tt); | ||
246 | return 1; | ||
247 | } | ||
248 | /* If ANY DEFINED BY nothing to do */ | ||
249 | |||
250 | if(tt->flags & ASN1_TFLG_ADB_MASK) { | ||
251 | *pval = NULL; | ||
252 | return 1; | ||
253 | } | ||
254 | #ifdef CRYPTO_MDEBUG | ||
255 | if(tt->field_name) CRYPTO_push_info(tt->field_name); | ||
256 | #endif | ||
257 | /* If SET OF or SEQUENCE OF, its a STACK */ | ||
258 | if(tt->flags & ASN1_TFLG_SK_MASK) { | ||
259 | STACK_OF(ASN1_VALUE) *skval; | ||
260 | skval = sk_ASN1_VALUE_new_null(); | ||
261 | if(!skval) { | ||
262 | ASN1err(ASN1_F_ASN1_TEMPLATE_NEW, ERR_R_MALLOC_FAILURE); | ||
263 | ret = 0; | ||
264 | goto done; | ||
265 | } | ||
266 | *pval = (ASN1_VALUE *)skval; | ||
267 | ret = 1; | ||
268 | goto done; | ||
269 | } | ||
270 | /* Otherwise pass it back to the item routine */ | ||
271 | ret = asn1_item_ex_combine_new(pval, it, tt->flags & ASN1_TFLG_COMBINE); | ||
272 | done: | ||
273 | #ifdef CRYPTO_MDEBUG | ||
274 | if(it->sname) CRYPTO_pop_info(); | ||
275 | #endif | ||
276 | return ret; | ||
277 | } | ||
278 | |||
279 | static void asn1_template_clear(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt) | ||
280 | { | ||
281 | /* If ADB or STACK just NULL the field */ | ||
282 | if(tt->flags & (ASN1_TFLG_ADB_MASK|ASN1_TFLG_SK_MASK)) | ||
283 | *pval = NULL; | ||
284 | else | ||
285 | asn1_item_clear(pval, ASN1_ITEM_ptr(tt->item)); | ||
286 | } | ||
287 | |||
288 | |||
289 | /* NB: could probably combine most of the real XXX_new() behaviour and junk all the old | ||
290 | * functions. | ||
291 | */ | ||
292 | |||
293 | int ASN1_primitive_new(ASN1_VALUE **pval, const ASN1_ITEM *it) | ||
294 | { | ||
295 | ASN1_TYPE *typ; | ||
296 | int utype; | ||
297 | const ASN1_PRIMITIVE_FUNCS *pf; | ||
298 | pf = it->funcs; | ||
299 | if(pf && pf->prim_new) return pf->prim_new(pval, it); | ||
300 | if(!it || (it->itype == ASN1_ITYPE_MSTRING)) utype = -1; | ||
301 | else utype = it->utype; | ||
302 | switch(utype) { | ||
303 | case V_ASN1_OBJECT: | ||
304 | *pval = (ASN1_VALUE *)OBJ_nid2obj(NID_undef); | ||
305 | return 1; | ||
306 | |||
307 | case V_ASN1_BOOLEAN: | ||
308 | *(ASN1_BOOLEAN *)pval = it->size; | ||
309 | return 1; | ||
310 | |||
311 | case V_ASN1_NULL: | ||
312 | *pval = (ASN1_VALUE *)1; | ||
313 | return 1; | ||
314 | |||
315 | case V_ASN1_ANY: | ||
316 | typ = OPENSSL_malloc(sizeof(ASN1_TYPE)); | ||
317 | if(!typ) return 0; | ||
318 | typ->value.ptr = NULL; | ||
319 | typ->type = -1; | ||
320 | *pval = (ASN1_VALUE *)typ; | ||
321 | break; | ||
322 | |||
323 | default: | ||
324 | *pval = (ASN1_VALUE *)ASN1_STRING_type_new(utype); | ||
325 | break; | ||
326 | } | ||
327 | if(*pval) return 1; | ||
328 | return 0; | ||
329 | } | ||
330 | |||
331 | void asn1_primitive_clear(ASN1_VALUE **pval, const ASN1_ITEM *it) | ||
332 | { | ||
333 | int utype; | ||
334 | const ASN1_PRIMITIVE_FUNCS *pf; | ||
335 | pf = it->funcs; | ||
336 | if(pf) { | ||
337 | if(pf->prim_clear) | ||
338 | pf->prim_clear(pval, it); | ||
339 | else | ||
340 | *pval = NULL; | ||
341 | return; | ||
342 | } | ||
343 | if(!it || (it->itype == ASN1_ITYPE_MSTRING)) utype = -1; | ||
344 | else utype = it->utype; | ||
345 | if(utype == V_ASN1_BOOLEAN) | ||
346 | *(ASN1_BOOLEAN *)pval = it->size; | ||
347 | else *pval = NULL; | ||
348 | } | ||
diff --git a/src/lib/libcrypto/asn1/tasn_prn.c b/src/lib/libcrypto/asn1/tasn_prn.c new file mode 100644 index 0000000000..fab67ae5ac --- /dev/null +++ b/src/lib/libcrypto/asn1/tasn_prn.c | |||
@@ -0,0 +1,198 @@ | |||
1 | /* tasn_prn.c */ | ||
2 | /* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL | ||
3 | * project 2000. | ||
4 | */ | ||
5 | /* ==================================================================== | ||
6 | * Copyright (c) 2000 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 <stddef.h> | ||
61 | #include <openssl/asn1.h> | ||
62 | #include <openssl/objects.h> | ||
63 | #include <openssl/buffer.h> | ||
64 | #include <openssl/err.h> | ||
65 | #include <openssl/nasn.h> | ||
66 | |||
67 | /* Print routines. Print out a whole structure from a template. | ||
68 | */ | ||
69 | |||
70 | static int asn1_item_print_nm(BIO *out, void *fld, int indent, const ASN1_ITEM *it, const char *name); | ||
71 | |||
72 | int ASN1_item_print(BIO *out, void *fld, int indent, const ASN1_ITEM *it) | ||
73 | { | ||
74 | return asn1_item_print_nm(out, fld, indent, it, it->sname); | ||
75 | } | ||
76 | |||
77 | static int asn1_item_print_nm(BIO *out, void *fld, int indent, const ASN1_ITEM *it, const char *name) | ||
78 | { | ||
79 | ASN1_STRING *str; | ||
80 | const ASN1_TEMPLATE *tt; | ||
81 | void *tmpfld; | ||
82 | int i; | ||
83 | if(!fld) { | ||
84 | BIO_printf(out, "%*s%s ABSENT\n", indent, "", name); | ||
85 | return 1; | ||
86 | } | ||
87 | switch(it->itype) { | ||
88 | |||
89 | case ASN1_ITYPE_PRIMITIVE: | ||
90 | if(it->templates) | ||
91 | return ASN1_template_print(out, fld, indent, it->templates); | ||
92 | return asn1_primitive_print(out, fld, it->utype, indent, name); | ||
93 | break; | ||
94 | |||
95 | case ASN1_ITYPE_MSTRING: | ||
96 | str = fld; | ||
97 | return asn1_primitive_print(out, fld, str->type, indent, name); | ||
98 | |||
99 | case ASN1_ITYPE_EXTERN: | ||
100 | BIO_printf(out, "%*s%s:EXTERNAL TYPE %s %s\n", indent, "", name, it->sname, fld ? "" : "ABSENT"); | ||
101 | return 1; | ||
102 | case ASN1_ITYPE_COMPAT: | ||
103 | BIO_printf(out, "%*s%s:COMPATIBLE TYPE %s %s\n", indent, "", name, it->sname, fld ? "" : "ABSENT"); | ||
104 | return 1; | ||
105 | |||
106 | |||
107 | case ASN1_ITYPE_CHOICE: | ||
108 | /* CHOICE type, get selector */ | ||
109 | i = asn1_get_choice_selector(fld, it); | ||
110 | /* This should never happen... */ | ||
111 | if((i < 0) || (i >= it->tcount)) { | ||
112 | BIO_printf(out, "%s selector [%d] out of range\n", it->sname, i); | ||
113 | return 1; | ||
114 | } | ||
115 | tt = it->templates + i; | ||
116 | tmpfld = asn1_get_field(fld, tt); | ||
117 | return ASN1_template_print(out, tmpfld, indent, tt); | ||
118 | |||
119 | case ASN1_ITYPE_SEQUENCE: | ||
120 | BIO_printf(out, "%*s%s {\n", indent, "", name); | ||
121 | /* Get each field entry */ | ||
122 | for(i = 0, tt = it->templates; i < it->tcount; i++, tt++) { | ||
123 | tmpfld = asn1_get_field(fld, tt); | ||
124 | ASN1_template_print(out, tmpfld, indent + 2, tt); | ||
125 | } | ||
126 | BIO_printf(out, "%*s}\n", indent, ""); | ||
127 | return 1; | ||
128 | |||
129 | default: | ||
130 | return 0; | ||
131 | } | ||
132 | } | ||
133 | |||
134 | int ASN1_template_print(BIO *out, void *fld, int indent, const ASN1_TEMPLATE *tt) | ||
135 | { | ||
136 | int i, flags; | ||
137 | #if 0 | ||
138 | if(!fld) return 0; | ||
139 | #endif | ||
140 | flags = tt->flags; | ||
141 | if(flags & ASN1_TFLG_SK_MASK) { | ||
142 | char *tname; | ||
143 | void *skitem; | ||
144 | /* SET OF, SEQUENCE OF */ | ||
145 | if(flags & ASN1_TFLG_SET_OF) tname = "SET"; | ||
146 | else tname = "SEQUENCE"; | ||
147 | if(fld) { | ||
148 | BIO_printf(out, "%*s%s OF %s {\n", indent, "", tname, tt->field_name); | ||
149 | for(i = 0; i < sk_num(fld); i++) { | ||
150 | skitem = sk_value(fld, i); | ||
151 | asn1_item_print_nm(out, skitem, indent + 2, tt->item, ""); | ||
152 | } | ||
153 | BIO_printf(out, "%*s}\n", indent, ""); | ||
154 | } else | ||
155 | BIO_printf(out, "%*s%s OF %s ABSENT\n", indent, "", tname, tt->field_name); | ||
156 | return 1; | ||
157 | } | ||
158 | return asn1_item_print_nm(out, fld, indent, tt->item, tt->field_name); | ||
159 | } | ||
160 | |||
161 | static int asn1_primitive_print(BIO *out, void *fld, long utype, int indent, const char *name) | ||
162 | { | ||
163 | ASN1_STRING *str = fld; | ||
164 | if(fld) { | ||
165 | if(utype == V_ASN1_BOOLEAN) { | ||
166 | int *bool = fld; | ||
167 | if(*bool == -1) printf("BOOL MISSING\n"); | ||
168 | BIO_printf(out, "%*s%s:%s", indent, "", "BOOLEAN", *bool ? "TRUE" : "FALSE"); | ||
169 | } else if((utype == V_ASN1_INTEGER) | ||
170 | || (utype == V_ASN1_ENUMERATED)) { | ||
171 | char *s, *nm; | ||
172 | s = i2s_ASN1_INTEGER(NULL, fld); | ||
173 | if(utype == V_ASN1_INTEGER) nm = "INTEGER"; | ||
174 | else nm = "ENUMERATED"; | ||
175 | BIO_printf(out, "%*s%s:%s", indent, "", nm, s); | ||
176 | OPENSSL_free(s); | ||
177 | } else if(utype == V_ASN1_NULL) { | ||
178 | BIO_printf(out, "%*s%s", indent, "", "NULL"); | ||
179 | } else if(utype == V_ASN1_UTCTIME) { | ||
180 | BIO_printf(out, "%*s%s:%s:", indent, "", name, "UTCTIME"); | ||
181 | ASN1_UTCTIME_print(out, str); | ||
182 | } else if(utype == V_ASN1_GENERALIZEDTIME) { | ||
183 | BIO_printf(out, "%*s%s:%s:", indent, "", name, "GENERALIZEDTIME"); | ||
184 | ASN1_GENERALIZEDTIME_print(out, str); | ||
185 | } else if(utype == V_ASN1_OBJECT) { | ||
186 | char objbuf[80], *ln; | ||
187 | ln = OBJ_nid2ln(OBJ_obj2nid(fld)); | ||
188 | if(!ln) ln = ""; | ||
189 | OBJ_obj2txt(objbuf, 80, fld, 1); | ||
190 | BIO_printf(out, "%*s%s:%s (%s)", indent, "", "OBJECT", ln, objbuf); | ||
191 | } else { | ||
192 | BIO_printf(out, "%*s%s:", indent, "", name); | ||
193 | ASN1_STRING_print_ex(out, str, ASN1_STRFLGS_DUMP_UNKNOWN|ASN1_STRFLGS_SHOW_TYPE); | ||
194 | } | ||
195 | BIO_printf(out, "\n"); | ||
196 | } else BIO_printf(out, "%*s%s [ABSENT]\n", indent, "", name); | ||
197 | return 1; | ||
198 | } | ||
diff --git a/src/lib/libcrypto/asn1/tasn_typ.c b/src/lib/libcrypto/asn1/tasn_typ.c new file mode 100644 index 0000000000..804d2eeba2 --- /dev/null +++ b/src/lib/libcrypto/asn1/tasn_typ.c | |||
@@ -0,0 +1,133 @@ | |||
1 | /* tasn_typ.c */ | ||
2 | /* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL | ||
3 | * project 2000. | ||
4 | */ | ||
5 | /* ==================================================================== | ||
6 | * Copyright (c) 2000 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 | #include <stdio.h> | ||
59 | #include <openssl/asn1.h> | ||
60 | #include <openssl/asn1t.h> | ||
61 | |||
62 | /* Declarations for string types */ | ||
63 | |||
64 | |||
65 | IMPLEMENT_ASN1_TYPE(ASN1_INTEGER) | ||
66 | IMPLEMENT_ASN1_FUNCTIONS(ASN1_INTEGER) | ||
67 | |||
68 | IMPLEMENT_ASN1_TYPE(ASN1_ENUMERATED) | ||
69 | IMPLEMENT_ASN1_FUNCTIONS(ASN1_ENUMERATED) | ||
70 | |||
71 | IMPLEMENT_ASN1_TYPE(ASN1_BIT_STRING) | ||
72 | IMPLEMENT_ASN1_FUNCTIONS(ASN1_BIT_STRING) | ||
73 | |||
74 | IMPLEMENT_ASN1_TYPE(ASN1_OCTET_STRING) | ||
75 | IMPLEMENT_ASN1_FUNCTIONS(ASN1_OCTET_STRING) | ||
76 | |||
77 | IMPLEMENT_ASN1_TYPE(ASN1_NULL) | ||
78 | IMPLEMENT_ASN1_FUNCTIONS(ASN1_NULL) | ||
79 | |||
80 | IMPLEMENT_ASN1_TYPE(ASN1_OBJECT) | ||
81 | |||
82 | IMPLEMENT_ASN1_TYPE(ASN1_UTF8STRING) | ||
83 | IMPLEMENT_ASN1_FUNCTIONS(ASN1_UTF8STRING) | ||
84 | |||
85 | IMPLEMENT_ASN1_TYPE(ASN1_PRINTABLESTRING) | ||
86 | IMPLEMENT_ASN1_FUNCTIONS(ASN1_PRINTABLESTRING) | ||
87 | |||
88 | IMPLEMENT_ASN1_TYPE(ASN1_T61STRING) | ||
89 | IMPLEMENT_ASN1_FUNCTIONS(ASN1_T61STRING) | ||
90 | |||
91 | IMPLEMENT_ASN1_TYPE(ASN1_IA5STRING) | ||
92 | IMPLEMENT_ASN1_FUNCTIONS(ASN1_IA5STRING) | ||
93 | |||
94 | IMPLEMENT_ASN1_TYPE(ASN1_GENERALSTRING) | ||
95 | IMPLEMENT_ASN1_FUNCTIONS(ASN1_GENERALSTRING) | ||
96 | |||
97 | IMPLEMENT_ASN1_TYPE(ASN1_UTCTIME) | ||
98 | IMPLEMENT_ASN1_FUNCTIONS(ASN1_UTCTIME) | ||
99 | |||
100 | IMPLEMENT_ASN1_TYPE(ASN1_GENERALIZEDTIME) | ||
101 | IMPLEMENT_ASN1_FUNCTIONS(ASN1_GENERALIZEDTIME) | ||
102 | |||
103 | IMPLEMENT_ASN1_TYPE(ASN1_VISIBLESTRING) | ||
104 | IMPLEMENT_ASN1_FUNCTIONS(ASN1_VISIBLESTRING) | ||
105 | |||
106 | IMPLEMENT_ASN1_TYPE(ASN1_UNIVERSALSTRING) | ||
107 | IMPLEMENT_ASN1_FUNCTIONS(ASN1_UNIVERSALSTRING) | ||
108 | |||
109 | IMPLEMENT_ASN1_TYPE(ASN1_BMPSTRING) | ||
110 | IMPLEMENT_ASN1_FUNCTIONS(ASN1_BMPSTRING) | ||
111 | |||
112 | IMPLEMENT_ASN1_TYPE(ASN1_ANY) | ||
113 | |||
114 | /* Just swallow an ASN1_SEQUENCE in an ASN1_STRING */ | ||
115 | IMPLEMENT_ASN1_TYPE(ASN1_SEQUENCE) | ||
116 | |||
117 | IMPLEMENT_ASN1_FUNCTIONS_fname(ASN1_TYPE, ASN1_ANY, ASN1_TYPE) | ||
118 | |||
119 | /* Multistring types */ | ||
120 | |||
121 | IMPLEMENT_ASN1_MSTRING(ASN1_PRINTABLE, B_ASN1_PRINTABLE) | ||
122 | IMPLEMENT_ASN1_FUNCTIONS_name(ASN1_STRING, ASN1_PRINTABLE) | ||
123 | |||
124 | IMPLEMENT_ASN1_MSTRING(DISPLAYTEXT, B_ASN1_DISPLAYTEXT) | ||
125 | IMPLEMENT_ASN1_FUNCTIONS_name(ASN1_STRING, DISPLAYTEXT) | ||
126 | |||
127 | IMPLEMENT_ASN1_MSTRING(DIRECTORYSTRING, B_ASN1_DIRECTORYSTRING) | ||
128 | IMPLEMENT_ASN1_FUNCTIONS_name(ASN1_STRING, DIRECTORYSTRING) | ||
129 | |||
130 | /* Three separate BOOLEAN type: normal, DEFAULT TRUE and DEFAULT FALSE */ | ||
131 | IMPLEMENT_ASN1_TYPE_ex(ASN1_BOOLEAN, ASN1_BOOLEAN, -1) | ||
132 | IMPLEMENT_ASN1_TYPE_ex(ASN1_TBOOLEAN, ASN1_BOOLEAN, 1) | ||
133 | IMPLEMENT_ASN1_TYPE_ex(ASN1_FBOOLEAN, ASN1_BOOLEAN, 0) | ||
diff --git a/src/lib/libcrypto/asn1/tasn_utl.c b/src/lib/libcrypto/asn1/tasn_utl.c new file mode 100644 index 0000000000..8996ce8c13 --- /dev/null +++ b/src/lib/libcrypto/asn1/tasn_utl.c | |||
@@ -0,0 +1,253 @@ | |||
1 | /* tasn_utl.c */ | ||
2 | /* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL | ||
3 | * project 2000. | ||
4 | */ | ||
5 | /* ==================================================================== | ||
6 | * Copyright (c) 2000 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 <stddef.h> | ||
61 | #include <string.h> | ||
62 | #include <openssl/asn1.h> | ||
63 | #include <openssl/asn1t.h> | ||
64 | #include <openssl/objects.h> | ||
65 | #include <openssl/err.h> | ||
66 | |||
67 | /* Utility functions for manipulating fields and offsets */ | ||
68 | |||
69 | /* Add 'offset' to 'addr' */ | ||
70 | #define offset2ptr(addr, offset) (void *)(((char *) addr) + offset) | ||
71 | |||
72 | /* Given an ASN1_ITEM CHOICE type return | ||
73 | * the selector value | ||
74 | */ | ||
75 | |||
76 | int asn1_get_choice_selector(ASN1_VALUE **pval, const ASN1_ITEM *it) | ||
77 | { | ||
78 | int *sel = offset2ptr(*pval, it->utype); | ||
79 | return *sel; | ||
80 | } | ||
81 | |||
82 | /* Given an ASN1_ITEM CHOICE type set | ||
83 | * the selector value, return old value. | ||
84 | */ | ||
85 | |||
86 | int asn1_set_choice_selector(ASN1_VALUE **pval, int value, const ASN1_ITEM *it) | ||
87 | { | ||
88 | int *sel, ret; | ||
89 | sel = offset2ptr(*pval, it->utype); | ||
90 | ret = *sel; | ||
91 | *sel = value; | ||
92 | return ret; | ||
93 | } | ||
94 | |||
95 | /* Do reference counting. The value 'op' decides what to do. | ||
96 | * if it is +1 then the count is incremented. If op is 0 count is | ||
97 | * set to 1. If op is -1 count is decremented and the return value | ||
98 | * is the current refrence count or 0 if no reference count exists. | ||
99 | */ | ||
100 | |||
101 | int asn1_do_lock(ASN1_VALUE **pval, int op, const ASN1_ITEM *it) | ||
102 | { | ||
103 | const ASN1_AUX *aux; | ||
104 | int *lck, ret; | ||
105 | if(it->itype != ASN1_ITYPE_SEQUENCE) return 0; | ||
106 | aux = it->funcs; | ||
107 | if(!aux || !(aux->flags & ASN1_AFLG_REFCOUNT)) return 0; | ||
108 | lck = offset2ptr(*pval, aux->ref_offset); | ||
109 | if(op == 0) { | ||
110 | *lck = 1; | ||
111 | return 1; | ||
112 | } | ||
113 | ret = CRYPTO_add(lck, op, aux->ref_lock); | ||
114 | #ifdef REF_PRINT | ||
115 | fprintf(stderr, "%s: Reference Count: %d\n", it->sname, *lck); | ||
116 | #endif | ||
117 | #ifdef REF_CHECK | ||
118 | if(ret < 0) | ||
119 | fprintf(stderr, "%s, bad reference count\n", it->sname); | ||
120 | #endif | ||
121 | return ret; | ||
122 | } | ||
123 | |||
124 | static ASN1_ENCODING *asn1_get_enc_ptr(ASN1_VALUE **pval, const ASN1_ITEM *it) | ||
125 | { | ||
126 | const ASN1_AUX *aux; | ||
127 | if(!pval || !*pval) return NULL; | ||
128 | aux = it->funcs; | ||
129 | if(!aux || !(aux->flags & ASN1_AFLG_ENCODING)) return NULL; | ||
130 | return offset2ptr(*pval, aux->enc_offset); | ||
131 | } | ||
132 | |||
133 | void asn1_enc_init(ASN1_VALUE **pval, const ASN1_ITEM *it) | ||
134 | { | ||
135 | ASN1_ENCODING *enc; | ||
136 | enc = asn1_get_enc_ptr(pval, it); | ||
137 | if(enc) { | ||
138 | enc->enc = NULL; | ||
139 | enc->len = 0; | ||
140 | enc->modified = 1; | ||
141 | } | ||
142 | } | ||
143 | |||
144 | void asn1_enc_free(ASN1_VALUE **pval, const ASN1_ITEM *it) | ||
145 | { | ||
146 | ASN1_ENCODING *enc; | ||
147 | enc = asn1_get_enc_ptr(pval, it); | ||
148 | if(enc) { | ||
149 | if(enc->enc) OPENSSL_free(enc->enc); | ||
150 | enc->enc = NULL; | ||
151 | enc->len = 0; | ||
152 | enc->modified = 1; | ||
153 | } | ||
154 | } | ||
155 | |||
156 | int asn1_enc_save(ASN1_VALUE **pval, unsigned char *in, int inlen, const ASN1_ITEM *it) | ||
157 | { | ||
158 | ASN1_ENCODING *enc; | ||
159 | enc = asn1_get_enc_ptr(pval, it); | ||
160 | if(!enc) return 1; | ||
161 | |||
162 | if(enc->enc) OPENSSL_free(enc->enc); | ||
163 | enc->enc = OPENSSL_malloc(inlen); | ||
164 | if(!enc->enc) return 0; | ||
165 | memcpy(enc->enc, in, inlen); | ||
166 | enc->len = inlen; | ||
167 | enc->modified = 0; | ||
168 | |||
169 | return 1; | ||
170 | } | ||
171 | |||
172 | int asn1_enc_restore(int *len, unsigned char **out, ASN1_VALUE **pval, const ASN1_ITEM *it) | ||
173 | { | ||
174 | ASN1_ENCODING *enc; | ||
175 | enc = asn1_get_enc_ptr(pval, it); | ||
176 | if(!enc || enc->modified) return 0; | ||
177 | if(out) { | ||
178 | memcpy(*out, enc->enc, enc->len); | ||
179 | *out += enc->len; | ||
180 | } | ||
181 | if(len) *len = enc->len; | ||
182 | return 1; | ||
183 | } | ||
184 | |||
185 | /* Given an ASN1_TEMPLATE get a pointer to a field */ | ||
186 | ASN1_VALUE ** asn1_get_field_ptr(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt) | ||
187 | { | ||
188 | ASN1_VALUE **pvaltmp; | ||
189 | if(tt->flags & ASN1_TFLG_COMBINE) return pval; | ||
190 | pvaltmp = offset2ptr(*pval, tt->offset); | ||
191 | /* NOTE for BOOLEAN types the field is just a plain | ||
192 | * int so we can't return int **, so settle for | ||
193 | * (int *). | ||
194 | */ | ||
195 | return pvaltmp; | ||
196 | } | ||
197 | |||
198 | /* Handle ANY DEFINED BY template, find the selector, look up | ||
199 | * the relevant ASN1_TEMPLATE in the table and return it. | ||
200 | */ | ||
201 | |||
202 | const ASN1_TEMPLATE *asn1_do_adb(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt, int nullerr) | ||
203 | { | ||
204 | const ASN1_ADB *adb; | ||
205 | const ASN1_ADB_TABLE *atbl; | ||
206 | long selector; | ||
207 | ASN1_VALUE **sfld; | ||
208 | int i; | ||
209 | if(!(tt->flags & ASN1_TFLG_ADB_MASK)) return tt; | ||
210 | |||
211 | /* Else ANY DEFINED BY ... get the table */ | ||
212 | adb = ASN1_ADB_ptr(tt->item); | ||
213 | |||
214 | /* Get the selector field */ | ||
215 | sfld = offset2ptr(*pval, adb->offset); | ||
216 | |||
217 | /* Check if NULL */ | ||
218 | if(!sfld) { | ||
219 | if(!adb->null_tt) goto err; | ||
220 | return adb->null_tt; | ||
221 | } | ||
222 | |||
223 | /* Convert type to a long: | ||
224 | * NB: don't check for NID_undef here because it | ||
225 | * might be a legitimate value in the table | ||
226 | */ | ||
227 | if(tt->flags & ASN1_TFLG_ADB_OID) | ||
228 | selector = OBJ_obj2nid((ASN1_OBJECT *)*sfld); | ||
229 | else | ||
230 | selector = ASN1_INTEGER_get((ASN1_INTEGER *)*sfld); | ||
231 | |||
232 | /* Try to find matching entry in table | ||
233 | * Maybe should check application types first to | ||
234 | * allow application override? Might also be useful | ||
235 | * to have a flag which indicates table is sorted and | ||
236 | * we can do a binary search. For now stick to a | ||
237 | * linear search. | ||
238 | */ | ||
239 | |||
240 | for(atbl = adb->tbl, i = 0; i < adb->tblcount; i++, atbl++) | ||
241 | if(atbl->value == selector) return &atbl->tt; | ||
242 | |||
243 | /* FIXME: need to search application table too */ | ||
244 | |||
245 | /* No match, return default type */ | ||
246 | if(!adb->default_tt) goto err; | ||
247 | return adb->default_tt; | ||
248 | |||
249 | err: | ||
250 | /* FIXME: should log the value or OID of unsupported type */ | ||
251 | if(nullerr) ASN1err(ASN1_F_ASN1_DO_ADB, ASN1_R_UNSUPPORTED_ANY_DEFINED_BY_TYPE); | ||
252 | return NULL; | ||
253 | } | ||
diff --git a/src/lib/libcrypto/asn1/x_bignum.c b/src/lib/libcrypto/asn1/x_bignum.c new file mode 100644 index 0000000000..848c7a0877 --- /dev/null +++ b/src/lib/libcrypto/asn1/x_bignum.c | |||
@@ -0,0 +1,137 @@ | |||
1 | /* x_bignum.c */ | ||
2 | /* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL | ||
3 | * project 2000. | ||
4 | */ | ||
5 | /* ==================================================================== | ||
6 | * Copyright (c) 2000 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 | #include "cryptlib.h" | ||
61 | #include <openssl/asn1t.h> | ||
62 | |||
63 | /* Custom primitive type for BIGNUM handling. This reads in an ASN1_INTEGER as a | ||
64 | * BIGNUM directly. Currently it ignores the sign which isn't a problem since all | ||
65 | * BIGNUMs used are non negative and anything that looks negative is normally due | ||
66 | * to an encoding error. | ||
67 | */ | ||
68 | |||
69 | #define BN_SENSITIVE 1 | ||
70 | |||
71 | static int bn_new(ASN1_VALUE **pval, const ASN1_ITEM *it); | ||
72 | static void bn_free(ASN1_VALUE **pval, const ASN1_ITEM *it); | ||
73 | |||
74 | static int bn_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype, const ASN1_ITEM *it); | ||
75 | static int bn_c2i(ASN1_VALUE **pval, unsigned char *cont, int len, int utype, char *free_cont, const ASN1_ITEM *it); | ||
76 | |||
77 | static ASN1_PRIMITIVE_FUNCS bignum_pf = { | ||
78 | NULL, 0, | ||
79 | bn_new, | ||
80 | bn_free, | ||
81 | 0, | ||
82 | bn_c2i, | ||
83 | bn_i2c | ||
84 | }; | ||
85 | |||
86 | ASN1_ITEM_start(BIGNUM) | ||
87 | ASN1_ITYPE_PRIMITIVE, V_ASN1_INTEGER, NULL, 0, &bignum_pf, 0, "BIGNUM" | ||
88 | ASN1_ITEM_end(BIGNUM) | ||
89 | |||
90 | ASN1_ITEM_start(CBIGNUM) | ||
91 | ASN1_ITYPE_PRIMITIVE, V_ASN1_INTEGER, NULL, 0, &bignum_pf, BN_SENSITIVE, "BIGNUM" | ||
92 | ASN1_ITEM_end(CBIGNUM) | ||
93 | |||
94 | static int bn_new(ASN1_VALUE **pval, const ASN1_ITEM *it) | ||
95 | { | ||
96 | *pval = (ASN1_VALUE *)BN_new(); | ||
97 | if(*pval) return 1; | ||
98 | else return 0; | ||
99 | } | ||
100 | |||
101 | static void bn_free(ASN1_VALUE **pval, const ASN1_ITEM *it) | ||
102 | { | ||
103 | if(!*pval) return; | ||
104 | if(it->size & BN_SENSITIVE) BN_clear_free((BIGNUM *)*pval); | ||
105 | else BN_free((BIGNUM *)*pval); | ||
106 | *pval = NULL; | ||
107 | } | ||
108 | |||
109 | static int bn_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype, const ASN1_ITEM *it) | ||
110 | { | ||
111 | BIGNUM *bn; | ||
112 | int pad; | ||
113 | if(!*pval) return -1; | ||
114 | bn = (BIGNUM *)*pval; | ||
115 | /* If MSB set in an octet we need a padding byte */ | ||
116 | if(BN_num_bits(bn) & 0x7) pad = 0; | ||
117 | else pad = 1; | ||
118 | if(cont) { | ||
119 | if(pad) *cont++ = 0; | ||
120 | BN_bn2bin(bn, cont); | ||
121 | } | ||
122 | return pad + BN_num_bytes(bn); | ||
123 | } | ||
124 | |||
125 | static int bn_c2i(ASN1_VALUE **pval, unsigned char *cont, int len, int utype, char *free_cont, const ASN1_ITEM *it) | ||
126 | { | ||
127 | BIGNUM *bn; | ||
128 | if(!*pval) bn_new(pval, it); | ||
129 | bn = (BIGNUM *)*pval; | ||
130 | if(!BN_bin2bn(cont, len, bn)) { | ||
131 | bn_free(pval, it); | ||
132 | return 0; | ||
133 | } | ||
134 | return 1; | ||
135 | } | ||
136 | |||
137 | |||
diff --git a/src/lib/libcrypto/asn1/x_long.c b/src/lib/libcrypto/asn1/x_long.c new file mode 100644 index 0000000000..c5f25956cb --- /dev/null +++ b/src/lib/libcrypto/asn1/x_long.c | |||
@@ -0,0 +1,169 @@ | |||
1 | /* x_long.c */ | ||
2 | /* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL | ||
3 | * project 2000. | ||
4 | */ | ||
5 | /* ==================================================================== | ||
6 | * Copyright (c) 2000 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 | #include "cryptlib.h" | ||
61 | #include <openssl/asn1t.h> | ||
62 | |||
63 | /* Custom primitive type for long handling. This converts between an ASN1_INTEGER | ||
64 | * and a long directly. | ||
65 | */ | ||
66 | |||
67 | |||
68 | static int long_new(ASN1_VALUE **pval, const ASN1_ITEM *it); | ||
69 | static void long_free(ASN1_VALUE **pval, const ASN1_ITEM *it); | ||
70 | |||
71 | static int long_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype, const ASN1_ITEM *it); | ||
72 | static int long_c2i(ASN1_VALUE **pval, unsigned char *cont, int len, int utype, char *free_cont, const ASN1_ITEM *it); | ||
73 | |||
74 | static ASN1_PRIMITIVE_FUNCS long_pf = { | ||
75 | NULL, 0, | ||
76 | long_new, | ||
77 | long_free, | ||
78 | long_free, /* Clear should set to initial value */ | ||
79 | long_c2i, | ||
80 | long_i2c | ||
81 | }; | ||
82 | |||
83 | ASN1_ITEM_start(LONG) | ||
84 | ASN1_ITYPE_PRIMITIVE, V_ASN1_INTEGER, NULL, 0, &long_pf, ASN1_LONG_UNDEF, "LONG" | ||
85 | ASN1_ITEM_end(LONG) | ||
86 | |||
87 | ASN1_ITEM_start(ZLONG) | ||
88 | ASN1_ITYPE_PRIMITIVE, V_ASN1_INTEGER, NULL, 0, &long_pf, 0, "ZLONG" | ||
89 | ASN1_ITEM_end(ZLONG) | ||
90 | |||
91 | static int long_new(ASN1_VALUE **pval, const ASN1_ITEM *it) | ||
92 | { | ||
93 | *(long *)pval = it->size; | ||
94 | return 1; | ||
95 | } | ||
96 | |||
97 | static void long_free(ASN1_VALUE **pval, const ASN1_ITEM *it) | ||
98 | { | ||
99 | *(long *)pval = it->size; | ||
100 | } | ||
101 | |||
102 | static int long_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype, const ASN1_ITEM *it) | ||
103 | { | ||
104 | long ltmp; | ||
105 | unsigned long utmp; | ||
106 | int clen, pad, i; | ||
107 | /* this exists to bypass broken gcc optimization */ | ||
108 | char *cp = (char *)pval; | ||
109 | |||
110 | /* use memcpy, because we may not be long aligned */ | ||
111 | memcpy(<mp, cp, sizeof(long)); | ||
112 | |||
113 | if(ltmp == it->size) return -1; | ||
114 | /* Convert the long to positive: we subtract one if negative so | ||
115 | * we can cleanly handle the padding if only the MSB of the leading | ||
116 | * octet is set. | ||
117 | */ | ||
118 | if(ltmp < 0) utmp = -ltmp - 1; | ||
119 | else utmp = ltmp; | ||
120 | clen = BN_num_bits_word(utmp); | ||
121 | /* If MSB of leading octet set we need to pad */ | ||
122 | if(!(clen & 0x7)) pad = 1; | ||
123 | else pad = 0; | ||
124 | |||
125 | /* Convert number of bits to number of octets */ | ||
126 | clen = (clen + 7) >> 3; | ||
127 | |||
128 | if(cont) { | ||
129 | if(pad) *cont++ = (ltmp < 0) ? 0xff : 0; | ||
130 | for(i = clen - 1; i >= 0; i--) { | ||
131 | cont[i] = (unsigned char)(utmp & 0xff); | ||
132 | if(ltmp < 0) cont[i] ^= 0xff; | ||
133 | utmp >>= 8; | ||
134 | } | ||
135 | } | ||
136 | return clen + pad; | ||
137 | } | ||
138 | |||
139 | static int long_c2i(ASN1_VALUE **pval, unsigned char *cont, int len, int utype, char *free_cont, const ASN1_ITEM *it) | ||
140 | { | ||
141 | int neg, i; | ||
142 | long ltmp; | ||
143 | unsigned long utmp = 0; | ||
144 | char *cp = (char *)pval; | ||
145 | if(len > sizeof(long)) { | ||
146 | ASN1err(ASN1_F_LONG_C2I, ASN1_R_INTEGER_TOO_LARGE_FOR_LONG); | ||
147 | return 0; | ||
148 | } | ||
149 | /* Is it negative? */ | ||
150 | if(len && (cont[0] & 0x80)) neg = 1; | ||
151 | else neg = 0; | ||
152 | utmp = 0; | ||
153 | for(i = 0; i < len; i++) { | ||
154 | utmp <<= 8; | ||
155 | if(neg) utmp |= cont[i] ^ 0xff; | ||
156 | else utmp |= cont[i]; | ||
157 | } | ||
158 | ltmp = (long)utmp; | ||
159 | if(neg) { | ||
160 | ltmp++; | ||
161 | ltmp = -ltmp; | ||
162 | } | ||
163 | if(ltmp == it->size) { | ||
164 | ASN1err(ASN1_F_LONG_C2I, ASN1_R_INTEGER_TOO_LARGE_FOR_LONG); | ||
165 | return 0; | ||
166 | } | ||
167 | memcpy(cp, <mp, sizeof(long)); | ||
168 | return 1; | ||
169 | } | ||
diff --git a/src/lib/libcrypto/asn1/x_x509a.c b/src/lib/libcrypto/asn1/x_x509a.c new file mode 100644 index 0000000000..b9987ea968 --- /dev/null +++ b/src/lib/libcrypto/asn1/x_x509a.c | |||
@@ -0,0 +1,200 @@ | |||
1 | /* a_x509a.c */ | ||
2 | /* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL | ||
3 | * project 1999. | ||
4 | */ | ||
5 | /* ==================================================================== | ||
6 | * Copyright (c) 1999 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 | #include "cryptlib.h" | ||
61 | #include <openssl/evp.h> | ||
62 | #include <openssl/asn1_mac.h> | ||
63 | #include <openssl/x509.h> | ||
64 | |||
65 | /* X509_CERT_AUX routines. These are used to encode additional | ||
66 | * user modifiable data about a certificate. This data is | ||
67 | * appended to the X509 encoding when the *_X509_AUX routines | ||
68 | * are used. This means that the "traditional" X509 routines | ||
69 | * will simply ignore the extra data. | ||
70 | */ | ||
71 | |||
72 | static X509_CERT_AUX *aux_get(X509 *x); | ||
73 | |||
74 | X509_CERT_AUX *d2i_X509_CERT_AUX(X509_CERT_AUX **a, unsigned char **pp, long length) | ||
75 | { | ||
76 | M_ASN1_D2I_vars(a, X509_CERT_AUX *, X509_CERT_AUX_new); | ||
77 | |||
78 | M_ASN1_D2I_Init(); | ||
79 | M_ASN1_D2I_start_sequence(); | ||
80 | |||
81 | M_ASN1_D2I_get_seq_opt_type(ASN1_OBJECT, ret->trust, | ||
82 | d2i_ASN1_OBJECT, ASN1_OBJECT_free); | ||
83 | M_ASN1_D2I_get_IMP_set_opt_type(ASN1_OBJECT, ret->reject, | ||
84 | d2i_ASN1_OBJECT, ASN1_OBJECT_free, 0); | ||
85 | M_ASN1_D2I_get_opt(ret->alias, d2i_ASN1_UTF8STRING, V_ASN1_UTF8STRING); | ||
86 | M_ASN1_D2I_get_opt(ret->keyid, d2i_ASN1_OCTET_STRING, V_ASN1_OCTET_STRING); | ||
87 | M_ASN1_D2I_get_IMP_set_opt_type(X509_ALGOR, ret->other, | ||
88 | d2i_X509_ALGOR, X509_ALGOR_free, 1); | ||
89 | |||
90 | M_ASN1_D2I_Finish(a, X509_CERT_AUX_free, ASN1_F_D2I_X509_CERT_AUX); | ||
91 | } | ||
92 | |||
93 | X509_CERT_AUX *X509_CERT_AUX_new() | ||
94 | { | ||
95 | X509_CERT_AUX *ret = NULL; | ||
96 | ASN1_CTX c; | ||
97 | M_ASN1_New_Malloc(ret, X509_CERT_AUX); | ||
98 | ret->trust = NULL; | ||
99 | ret->reject = NULL; | ||
100 | ret->alias = NULL; | ||
101 | ret->keyid = NULL; | ||
102 | ret->other = NULL; | ||
103 | return(ret); | ||
104 | M_ASN1_New_Error(ASN1_F_X509_CERT_AUX_NEW); | ||
105 | } | ||
106 | |||
107 | void X509_CERT_AUX_free(X509_CERT_AUX *a) | ||
108 | { | ||
109 | if(a == NULL) return; | ||
110 | sk_ASN1_OBJECT_pop_free(a->trust, ASN1_OBJECT_free); | ||
111 | sk_ASN1_OBJECT_pop_free(a->reject, ASN1_OBJECT_free); | ||
112 | ASN1_UTF8STRING_free(a->alias); | ||
113 | ASN1_OCTET_STRING_free(a->keyid); | ||
114 | sk_X509_ALGOR_pop_free(a->other, X509_ALGOR_free); | ||
115 | Free(a); | ||
116 | } | ||
117 | |||
118 | int i2d_X509_CERT_AUX(X509_CERT_AUX *a, unsigned char **pp) | ||
119 | { | ||
120 | M_ASN1_I2D_vars(a); | ||
121 | |||
122 | M_ASN1_I2D_len_SEQUENCE_opt_type(ASN1_OBJECT, a->trust, i2d_ASN1_OBJECT); | ||
123 | M_ASN1_I2D_len_IMP_SEQUENCE_opt_type(ASN1_OBJECT, a->reject, i2d_ASN1_OBJECT, 0); | ||
124 | |||
125 | M_ASN1_I2D_len(a->alias, i2d_ASN1_UTF8STRING); | ||
126 | M_ASN1_I2D_len(a->keyid, i2d_ASN1_OCTET_STRING); | ||
127 | M_ASN1_I2D_len_IMP_SEQUENCE_opt_type(X509_ALGOR, a->other, i2d_X509_ALGOR, 1); | ||
128 | |||
129 | M_ASN1_I2D_seq_total(); | ||
130 | |||
131 | M_ASN1_I2D_put_SEQUENCE_opt_type(ASN1_OBJECT, a->trust, i2d_ASN1_OBJECT); | ||
132 | M_ASN1_I2D_put_IMP_SEQUENCE_opt_type(ASN1_OBJECT, a->reject, i2d_ASN1_OBJECT, 0); | ||
133 | |||
134 | M_ASN1_I2D_put(a->alias, i2d_ASN1_UTF8STRING); | ||
135 | M_ASN1_I2D_put(a->keyid, i2d_ASN1_OCTET_STRING); | ||
136 | M_ASN1_I2D_put_IMP_SEQUENCE_opt_type(X509_ALGOR, a->other, i2d_X509_ALGOR, 1); | ||
137 | |||
138 | M_ASN1_I2D_finish(); | ||
139 | } | ||
140 | |||
141 | static X509_CERT_AUX *aux_get(X509 *x) | ||
142 | { | ||
143 | if(!x) return NULL; | ||
144 | if(!x->aux && !(x->aux = X509_CERT_AUX_new())) return NULL; | ||
145 | return x->aux; | ||
146 | } | ||
147 | |||
148 | int X509_alias_set1(X509 *x, unsigned char *name, int len) | ||
149 | { | ||
150 | X509_CERT_AUX *aux; | ||
151 | if(!(aux = aux_get(x))) return 0; | ||
152 | if(!aux->alias && !(aux->alias = ASN1_UTF8STRING_new())) return 0; | ||
153 | return ASN1_STRING_set(aux->alias, name, len); | ||
154 | } | ||
155 | |||
156 | unsigned char *X509_alias_get0(X509 *x, int *len) | ||
157 | { | ||
158 | if(!x->aux || !x->aux->alias) return NULL; | ||
159 | if(len) *len = x->aux->alias->length; | ||
160 | return x->aux->alias->data; | ||
161 | } | ||
162 | |||
163 | int X509_add1_trust_object(X509 *x, ASN1_OBJECT *obj) | ||
164 | { | ||
165 | X509_CERT_AUX *aux; | ||
166 | ASN1_OBJECT *objtmp; | ||
167 | if(!(objtmp = OBJ_dup(obj))) return 0; | ||
168 | if(!(aux = aux_get(x))) return 0; | ||
169 | if(!aux->trust | ||
170 | && !(aux->trust = sk_ASN1_OBJECT_new_null())) return 0; | ||
171 | return sk_ASN1_OBJECT_push(aux->trust, objtmp); | ||
172 | } | ||
173 | |||
174 | int X509_add1_reject_object(X509 *x, ASN1_OBJECT *obj) | ||
175 | { | ||
176 | X509_CERT_AUX *aux; | ||
177 | ASN1_OBJECT *objtmp; | ||
178 | if(!(objtmp = OBJ_dup(obj))) return 0; | ||
179 | if(!(aux = aux_get(x))) return 0; | ||
180 | if(!aux->reject | ||
181 | && !(aux->reject = sk_ASN1_OBJECT_new_null())) return 0; | ||
182 | return sk_ASN1_OBJECT_push(aux->reject, objtmp); | ||
183 | } | ||
184 | |||
185 | void X509_trust_clear(X509 *x) | ||
186 | { | ||
187 | if(x->aux && x->aux->trust) { | ||
188 | sk_ASN1_OBJECT_pop_free(x->aux->trust, ASN1_OBJECT_free); | ||
189 | x->aux->trust = NULL; | ||
190 | } | ||
191 | } | ||
192 | |||
193 | void X509_reject_clear(X509 *x) | ||
194 | { | ||
195 | if(x->aux && x->aux->reject) { | ||
196 | sk_ASN1_OBJECT_pop_free(x->aux->reject, ASN1_OBJECT_free); | ||
197 | x->aux->reject = NULL; | ||
198 | } | ||
199 | } | ||
200 | |||
diff --git a/src/lib/libcrypto/bf/bf_locl.h b/src/lib/libcrypto/bf/bf_locl.h new file mode 100644 index 0000000000..05756b5d3b --- /dev/null +++ b/src/lib/libcrypto/bf/bf_locl.h | |||
@@ -0,0 +1,219 @@ | |||
1 | /* crypto/bf/bf_locl.h */ | ||
2 | /* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) | ||
3 | * All rights reserved. | ||
4 | * | ||
5 | * This package is an SSL implementation written | ||
6 | * by Eric Young (eay@cryptsoft.com). | ||
7 | * The implementation was written so as to conform with Netscapes SSL. | ||
8 | * | ||
9 | * This library is free for commercial and non-commercial use as long as | ||
10 | * the following conditions are aheared to. The following conditions | ||
11 | * apply to all code found in this distribution, be it the RC4, RSA, | ||
12 | * lhash, DES, etc., code; not just the SSL code. The SSL documentation | ||
13 | * included with this distribution is covered by the same copyright terms | ||
14 | * except that the holder is Tim Hudson (tjh@cryptsoft.com). | ||
15 | * | ||
16 | * Copyright remains Eric Young's, and as such any Copyright notices in | ||
17 | * the code are not to be removed. | ||
18 | * If this package is used in a product, Eric Young should be given attribution | ||
19 | * as the author of the parts of the library used. | ||
20 | * This can be in the form of a textual message at program startup or | ||
21 | * in documentation (online or textual) provided with the package. | ||
22 | * | ||
23 | * Redistribution and use in source and binary forms, with or without | ||
24 | * modification, are permitted provided that the following conditions | ||
25 | * are met: | ||
26 | * 1. Redistributions of source code must retain the copyright | ||
27 | * notice, this list of conditions and the following disclaimer. | ||
28 | * 2. Redistributions in binary form must reproduce the above copyright | ||
29 | * notice, this list of conditions and the following disclaimer in the | ||
30 | * documentation and/or other materials provided with the distribution. | ||
31 | * 3. All advertising materials mentioning features or use of this software | ||
32 | * must display the following acknowledgement: | ||
33 | * "This product includes cryptographic software written by | ||
34 | * Eric Young (eay@cryptsoft.com)" | ||
35 | * The word 'cryptographic' can be left out if the rouines from the library | ||
36 | * being used are not cryptographic related :-). | ||
37 | * 4. If you include any Windows specific code (or a derivative thereof) from | ||
38 | * the apps directory (application code) you must include an acknowledgement: | ||
39 | * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" | ||
40 | * | ||
41 | * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND | ||
42 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
43 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
44 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | ||
45 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
46 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
47 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
48 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
49 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
50 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
51 | * SUCH DAMAGE. | ||
52 | * | ||
53 | * The licence and distribution terms for any publically available version or | ||
54 | * derivative of this code cannot be changed. i.e. this code cannot simply be | ||
55 | * copied and put under another distribution licence | ||
56 | * [including the GNU Public Licence.] | ||
57 | */ | ||
58 | |||
59 | #ifndef HEADER_BF_LOCL_H | ||
60 | #define HEADER_BF_LOCL_H | ||
61 | #include <openssl/opensslconf.h> /* BF_PTR, BF_PTR2 */ | ||
62 | |||
63 | #undef c2l | ||
64 | #define c2l(c,l) (l =((unsigned long)(*((c)++))) , \ | ||
65 | l|=((unsigned long)(*((c)++)))<< 8L, \ | ||
66 | l|=((unsigned long)(*((c)++)))<<16L, \ | ||
67 | l|=((unsigned long)(*((c)++)))<<24L) | ||
68 | |||
69 | /* NOTE - c is not incremented as per c2l */ | ||
70 | #undef c2ln | ||
71 | #define c2ln(c,l1,l2,n) { \ | ||
72 | c+=n; \ | ||
73 | l1=l2=0; \ | ||
74 | switch (n) { \ | ||
75 | case 8: l2 =((unsigned long)(*(--(c))))<<24L; \ | ||
76 | case 7: l2|=((unsigned long)(*(--(c))))<<16L; \ | ||
77 | case 6: l2|=((unsigned long)(*(--(c))))<< 8L; \ | ||
78 | case 5: l2|=((unsigned long)(*(--(c)))); \ | ||
79 | case 4: l1 =((unsigned long)(*(--(c))))<<24L; \ | ||
80 | case 3: l1|=((unsigned long)(*(--(c))))<<16L; \ | ||
81 | case 2: l1|=((unsigned long)(*(--(c))))<< 8L; \ | ||
82 | case 1: l1|=((unsigned long)(*(--(c)))); \ | ||
83 | } \ | ||
84 | } | ||
85 | |||
86 | #undef l2c | ||
87 | #define l2c(l,c) (*((c)++)=(unsigned char)(((l) )&0xff), \ | ||
88 | *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \ | ||
89 | *((c)++)=(unsigned char)(((l)>>16L)&0xff), \ | ||
90 | *((c)++)=(unsigned char)(((l)>>24L)&0xff)) | ||
91 | |||
92 | /* NOTE - c is not incremented as per l2c */ | ||
93 | #undef l2cn | ||
94 | #define l2cn(l1,l2,c,n) { \ | ||
95 | c+=n; \ | ||
96 | switch (n) { \ | ||
97 | case 8: *(--(c))=(unsigned char)(((l2)>>24L)&0xff); \ | ||
98 | case 7: *(--(c))=(unsigned char)(((l2)>>16L)&0xff); \ | ||
99 | case 6: *(--(c))=(unsigned char)(((l2)>> 8L)&0xff); \ | ||
100 | case 5: *(--(c))=(unsigned char)(((l2) )&0xff); \ | ||
101 | case 4: *(--(c))=(unsigned char)(((l1)>>24L)&0xff); \ | ||
102 | case 3: *(--(c))=(unsigned char)(((l1)>>16L)&0xff); \ | ||
103 | case 2: *(--(c))=(unsigned char)(((l1)>> 8L)&0xff); \ | ||
104 | case 1: *(--(c))=(unsigned char)(((l1) )&0xff); \ | ||
105 | } \ | ||
106 | } | ||
107 | |||
108 | /* NOTE - c is not incremented as per n2l */ | ||
109 | #define n2ln(c,l1,l2,n) { \ | ||
110 | c+=n; \ | ||
111 | l1=l2=0; \ | ||
112 | switch (n) { \ | ||
113 | case 8: l2 =((unsigned long)(*(--(c)))) ; \ | ||
114 | case 7: l2|=((unsigned long)(*(--(c))))<< 8; \ | ||
115 | case 6: l2|=((unsigned long)(*(--(c))))<<16; \ | ||
116 | case 5: l2|=((unsigned long)(*(--(c))))<<24; \ | ||
117 | case 4: l1 =((unsigned long)(*(--(c)))) ; \ | ||
118 | case 3: l1|=((unsigned long)(*(--(c))))<< 8; \ | ||
119 | case 2: l1|=((unsigned long)(*(--(c))))<<16; \ | ||
120 | case 1: l1|=((unsigned long)(*(--(c))))<<24; \ | ||
121 | } \ | ||
122 | } | ||
123 | |||
124 | /* NOTE - c is not incremented as per l2n */ | ||
125 | #define l2nn(l1,l2,c,n) { \ | ||
126 | c+=n; \ | ||
127 | switch (n) { \ | ||
128 | case 8: *(--(c))=(unsigned char)(((l2) )&0xff); \ | ||
129 | case 7: *(--(c))=(unsigned char)(((l2)>> 8)&0xff); \ | ||
130 | case 6: *(--(c))=(unsigned char)(((l2)>>16)&0xff); \ | ||
131 | case 5: *(--(c))=(unsigned char)(((l2)>>24)&0xff); \ | ||
132 | case 4: *(--(c))=(unsigned char)(((l1) )&0xff); \ | ||
133 | case 3: *(--(c))=(unsigned char)(((l1)>> 8)&0xff); \ | ||
134 | case 2: *(--(c))=(unsigned char)(((l1)>>16)&0xff); \ | ||
135 | case 1: *(--(c))=(unsigned char)(((l1)>>24)&0xff); \ | ||
136 | } \ | ||
137 | } | ||
138 | |||
139 | #undef n2l | ||
140 | #define n2l(c,l) (l =((unsigned long)(*((c)++)))<<24L, \ | ||
141 | l|=((unsigned long)(*((c)++)))<<16L, \ | ||
142 | l|=((unsigned long)(*((c)++)))<< 8L, \ | ||
143 | l|=((unsigned long)(*((c)++)))) | ||
144 | |||
145 | #undef l2n | ||
146 | #define l2n(l,c) (*((c)++)=(unsigned char)(((l)>>24L)&0xff), \ | ||
147 | *((c)++)=(unsigned char)(((l)>>16L)&0xff), \ | ||
148 | *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \ | ||
149 | *((c)++)=(unsigned char)(((l) )&0xff)) | ||
150 | |||
151 | /* This is actually a big endian algorithm, the most significate byte | ||
152 | * is used to lookup array 0 */ | ||
153 | |||
154 | #if defined(BF_PTR2) | ||
155 | |||
156 | /* | ||
157 | * This is basically a special Intel version. Point is that Intel | ||
158 | * doesn't have many registers, but offers a reach choice of addressing | ||
159 | * modes. So we spare some registers by directly traversing BF_KEY | ||
160 | * structure and hiring the most decorated addressing mode. The code | ||
161 | * generated by EGCS is *perfectly* competitive with assembler | ||
162 | * implementation! | ||
163 | */ | ||
164 | #define BF_ENC(LL,R,KEY,Pi) (\ | ||
165 | LL^=KEY[Pi], \ | ||
166 | t= KEY[BF_ROUNDS+2 + 0 + ((R>>24)&0xFF)], \ | ||
167 | t+= KEY[BF_ROUNDS+2 + 256 + ((R>>16)&0xFF)], \ | ||
168 | t^= KEY[BF_ROUNDS+2 + 512 + ((R>>8 )&0xFF)], \ | ||
169 | t+= KEY[BF_ROUNDS+2 + 768 + ((R )&0xFF)], \ | ||
170 | LL^=t \ | ||
171 | ) | ||
172 | |||
173 | #elif defined(BF_PTR) | ||
174 | |||
175 | #ifndef BF_LONG_LOG2 | ||
176 | #define BF_LONG_LOG2 2 /* default to BF_LONG being 32 bits */ | ||
177 | #endif | ||
178 | #define BF_M (0xFF<<BF_LONG_LOG2) | ||
179 | #define BF_0 (24-BF_LONG_LOG2) | ||
180 | #define BF_1 (16-BF_LONG_LOG2) | ||
181 | #define BF_2 ( 8-BF_LONG_LOG2) | ||
182 | #define BF_3 BF_LONG_LOG2 /* left shift */ | ||
183 | |||
184 | /* | ||
185 | * This is normally very good on RISC platforms where normally you | ||
186 | * have to explicitely "multiplicate" array index by sizeof(BF_LONG) | ||
187 | * in order to caclulate the effective address. This implementation | ||
188 | * excuses CPU from this extra work. Power[PC] uses should have most | ||
189 | * fun as (R>>BF_i)&BF_M gets folded into a single instruction, namely | ||
190 | * rlwinm. So let'em double-check if their compiler does it. | ||
191 | */ | ||
192 | |||
193 | #define BF_ENC(LL,R,S,P) ( \ | ||
194 | LL^=P, \ | ||
195 | LL^= (((*(BF_LONG *)((unsigned char *)&(S[ 0])+((R>>BF_0)&BF_M))+ \ | ||
196 | *(BF_LONG *)((unsigned char *)&(S[256])+((R>>BF_1)&BF_M)))^ \ | ||
197 | *(BF_LONG *)((unsigned char *)&(S[512])+((R>>BF_2)&BF_M)))+ \ | ||
198 | *(BF_LONG *)((unsigned char *)&(S[768])+((R<<BF_3)&BF_M))) \ | ||
199 | ) | ||
200 | #else | ||
201 | |||
202 | /* | ||
203 | * This is a *generic* version. Seem to perform best on platforms that | ||
204 | * offer explicit support for extraction of 8-bit nibbles preferably | ||
205 | * complemented with "multiplying" of array index by sizeof(BF_LONG). | ||
206 | * For the moment of this writing the list comprises Alpha CPU featuring | ||
207 | * extbl and s[48]addq instructions. | ||
208 | */ | ||
209 | |||
210 | #define BF_ENC(LL,R,S,P) ( \ | ||
211 | LL^=P, \ | ||
212 | LL^=((( S[ ((int)(R>>24)&0xff)] + \ | ||
213 | S[0x0100+((int)(R>>16)&0xff)])^ \ | ||
214 | S[0x0200+((int)(R>> 8)&0xff)])+ \ | ||
215 | S[0x0300+((int)(R )&0xff)])&0xffffffffL \ | ||
216 | ) | ||
217 | #endif | ||
218 | |||
219 | #endif | ||
diff --git a/src/lib/libcrypto/bio/bf_lbuf.c b/src/lib/libcrypto/bio/bf_lbuf.c new file mode 100644 index 0000000000..7bcf8ed941 --- /dev/null +++ b/src/lib/libcrypto/bio/bf_lbuf.c | |||
@@ -0,0 +1,397 @@ | |||
1 | /* crypto/bio/bf_buff.c */ | ||
2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) | ||
3 | * All rights reserved. | ||
4 | * | ||
5 | * This package is an SSL implementation written | ||
6 | * by Eric Young (eay@cryptsoft.com). | ||
7 | * The implementation was written so as to conform with Netscapes SSL. | ||
8 | * | ||
9 | * This library is free for commercial and non-commercial use as long as | ||
10 | * the following conditions are aheared to. The following conditions | ||
11 | * apply to all code found in this distribution, be it the RC4, RSA, | ||
12 | * lhash, DES, etc., code; not just the SSL code. The SSL documentation | ||
13 | * included with this distribution is covered by the same copyright terms | ||
14 | * except that the holder is Tim Hudson (tjh@cryptsoft.com). | ||
15 | * | ||
16 | * Copyright remains Eric Young's, and as such any Copyright notices in | ||
17 | * the code are not to be removed. | ||
18 | * If this package is used in a product, Eric Young should be given attribution | ||
19 | * as the author of the parts of the library used. | ||
20 | * This can be in the form of a textual message at program startup or | ||
21 | * in documentation (online or textual) provided with the package. | ||
22 | * | ||
23 | * Redistribution and use in source and binary forms, with or without | ||
24 | * modification, are permitted provided that the following conditions | ||
25 | * are met: | ||
26 | * 1. Redistributions of source code must retain the copyright | ||
27 | * notice, this list of conditions and the following disclaimer. | ||
28 | * 2. Redistributions in binary form must reproduce the above copyright | ||
29 | * notice, this list of conditions and the following disclaimer in the | ||
30 | * documentation and/or other materials provided with the distribution. | ||
31 | * 3. All advertising materials mentioning features or use of this software | ||
32 | * must display the following acknowledgement: | ||
33 | * "This product includes cryptographic software written by | ||
34 | * Eric Young (eay@cryptsoft.com)" | ||
35 | * The word 'cryptographic' can be left out if the rouines from the library | ||
36 | * being used are not cryptographic related :-). | ||
37 | * 4. If you include any Windows specific code (or a derivative thereof) from | ||
38 | * the apps directory (application code) you must include an acknowledgement: | ||
39 | * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" | ||
40 | * | ||
41 | * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND | ||
42 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
43 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
44 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | ||
45 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
46 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
47 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
48 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
49 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
50 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
51 | * SUCH DAMAGE. | ||
52 | * | ||
53 | * The licence and distribution terms for any publically available version or | ||
54 | * derivative of this code cannot be changed. i.e. this code cannot simply be | ||
55 | * copied and put under another distribution licence | ||
56 | * [including the GNU Public Licence.] | ||
57 | */ | ||
58 | |||
59 | #include <stdio.h> | ||
60 | #include <errno.h> | ||
61 | #include "cryptlib.h" | ||
62 | #include <openssl/bio.h> | ||
63 | #include <openssl/evp.h> | ||
64 | |||
65 | static int linebuffer_write(BIO *h, const char *buf,int num); | ||
66 | static int linebuffer_read(BIO *h, char *buf, int size); | ||
67 | static int linebuffer_puts(BIO *h, const char *str); | ||
68 | static int linebuffer_gets(BIO *h, char *str, int size); | ||
69 | static long linebuffer_ctrl(BIO *h, int cmd, long arg1, void *arg2); | ||
70 | static int linebuffer_new(BIO *h); | ||
71 | static int linebuffer_free(BIO *data); | ||
72 | static long linebuffer_callback_ctrl(BIO *h, int cmd, bio_info_cb *fp); | ||
73 | |||
74 | /* A 10k maximum should be enough for most purposes */ | ||
75 | #define DEFAULT_LINEBUFFER_SIZE 1024*10 | ||
76 | |||
77 | /* #define DEBUG */ | ||
78 | |||
79 | static BIO_METHOD methods_linebuffer= | ||
80 | { | ||
81 | BIO_TYPE_LINEBUFFER, | ||
82 | "linebuffer", | ||
83 | linebuffer_write, | ||
84 | linebuffer_read, | ||
85 | linebuffer_puts, | ||
86 | linebuffer_gets, | ||
87 | linebuffer_ctrl, | ||
88 | linebuffer_new, | ||
89 | linebuffer_free, | ||
90 | linebuffer_callback_ctrl, | ||
91 | }; | ||
92 | |||
93 | BIO_METHOD *BIO_f_linebuffer(void) | ||
94 | { | ||
95 | return(&methods_linebuffer); | ||
96 | } | ||
97 | |||
98 | typedef struct bio_linebuffer_ctx_struct | ||
99 | { | ||
100 | char *obuf; /* the output char array */ | ||
101 | int obuf_size; /* how big is the output buffer */ | ||
102 | int obuf_len; /* how many bytes are in it */ | ||
103 | } BIO_LINEBUFFER_CTX; | ||
104 | |||
105 | static int linebuffer_new(BIO *bi) | ||
106 | { | ||
107 | BIO_LINEBUFFER_CTX *ctx; | ||
108 | |||
109 | ctx=(BIO_LINEBUFFER_CTX *)OPENSSL_malloc(sizeof(BIO_LINEBUFFER_CTX)); | ||
110 | if (ctx == NULL) return(0); | ||
111 | ctx->obuf=(char *)OPENSSL_malloc(DEFAULT_LINEBUFFER_SIZE); | ||
112 | if (ctx->obuf == NULL) { OPENSSL_free(ctx); return(0); } | ||
113 | ctx->obuf_size=DEFAULT_LINEBUFFER_SIZE; | ||
114 | ctx->obuf_len=0; | ||
115 | |||
116 | bi->init=1; | ||
117 | bi->ptr=(char *)ctx; | ||
118 | bi->flags=0; | ||
119 | return(1); | ||
120 | } | ||
121 | |||
122 | static int linebuffer_free(BIO *a) | ||
123 | { | ||
124 | BIO_LINEBUFFER_CTX *b; | ||
125 | |||
126 | if (a == NULL) return(0); | ||
127 | b=(BIO_LINEBUFFER_CTX *)a->ptr; | ||
128 | if (b->obuf != NULL) OPENSSL_free(b->obuf); | ||
129 | OPENSSL_free(a->ptr); | ||
130 | a->ptr=NULL; | ||
131 | a->init=0; | ||
132 | a->flags=0; | ||
133 | return(1); | ||
134 | } | ||
135 | |||
136 | static int linebuffer_read(BIO *b, char *out, int outl) | ||
137 | { | ||
138 | int ret=0; | ||
139 | |||
140 | if (out == NULL) return(0); | ||
141 | if (b->next_bio == NULL) return(0); | ||
142 | ret=BIO_read(b->next_bio,out,outl); | ||
143 | BIO_clear_retry_flags(b); | ||
144 | BIO_copy_next_retry(b); | ||
145 | return(ret); | ||
146 | } | ||
147 | |||
148 | static int linebuffer_write(BIO *b, const char *in, int inl) | ||
149 | { | ||
150 | int i,num=0,foundnl; | ||
151 | BIO_LINEBUFFER_CTX *ctx; | ||
152 | |||
153 | if ((in == NULL) || (inl <= 0)) return(0); | ||
154 | ctx=(BIO_LINEBUFFER_CTX *)b->ptr; | ||
155 | if ((ctx == NULL) || (b->next_bio == NULL)) return(0); | ||
156 | |||
157 | BIO_clear_retry_flags(b); | ||
158 | |||
159 | do | ||
160 | { | ||
161 | const char *p; | ||
162 | |||
163 | for(p = in; p < in + inl && *p != '\n'; p++) | ||
164 | ; | ||
165 | if (*p == '\n') | ||
166 | { | ||
167 | p++; | ||
168 | foundnl = 1; | ||
169 | } | ||
170 | else | ||
171 | foundnl = 0; | ||
172 | |||
173 | /* If a NL was found and we already have text in the save | ||
174 | buffer, concatenate them and write */ | ||
175 | while ((foundnl || p - in > ctx->obuf_size - ctx->obuf_len) | ||
176 | && ctx->obuf_len > 0) | ||
177 | { | ||
178 | int orig_olen = ctx->obuf_len; | ||
179 | |||
180 | i = ctx->obuf_size - ctx->obuf_len; | ||
181 | if (p - in > 0) | ||
182 | { | ||
183 | if (i >= p - in) | ||
184 | { | ||
185 | memcpy(&(ctx->obuf[ctx->obuf_len]), | ||
186 | in,p - in); | ||
187 | ctx->obuf_len += p - in; | ||
188 | inl -= p - in; | ||
189 | num += p - in; | ||
190 | in = p; | ||
191 | } | ||
192 | else | ||
193 | { | ||
194 | memcpy(&(ctx->obuf[ctx->obuf_len]), | ||
195 | in,i); | ||
196 | ctx->obuf_len += i; | ||
197 | inl -= i; | ||
198 | in += i; | ||
199 | num += i; | ||
200 | } | ||
201 | } | ||
202 | |||
203 | #ifdef DEBUG | ||
204 | BIO_write(b->next_bio, "<*<", 3); | ||
205 | #endif | ||
206 | i=BIO_write(b->next_bio, | ||
207 | ctx->obuf, ctx->obuf_len); | ||
208 | if (i <= 0) | ||
209 | { | ||
210 | ctx->obuf_len = orig_olen; | ||
211 | BIO_copy_next_retry(b); | ||
212 | |||
213 | #ifdef DEBUG | ||
214 | BIO_write(b->next_bio, ">*>", 3); | ||
215 | #endif | ||
216 | if (i < 0) return((num > 0)?num:i); | ||
217 | if (i == 0) return(num); | ||
218 | } | ||
219 | #ifdef DEBUG | ||
220 | BIO_write(b->next_bio, ">*>", 3); | ||
221 | #endif | ||
222 | if (i < ctx->obuf_len) | ||
223 | memmove(ctx->obuf, ctx->obuf + i, | ||
224 | ctx->obuf_len - i); | ||
225 | ctx->obuf_len-=i; | ||
226 | } | ||
227 | |||
228 | /* Now that the save buffer is emptied, let's write the input | ||
229 | buffer if a NL was found and there is anything to write. */ | ||
230 | if ((foundnl || p - in > ctx->obuf_size) && p - in > 0) | ||
231 | { | ||
232 | #ifdef DEBUG | ||
233 | BIO_write(b->next_bio, "<*<", 3); | ||
234 | #endif | ||
235 | i=BIO_write(b->next_bio,in,p - in); | ||
236 | if (i <= 0) | ||
237 | { | ||
238 | BIO_copy_next_retry(b); | ||
239 | #ifdef DEBUG | ||
240 | BIO_write(b->next_bio, ">*>", 3); | ||
241 | #endif | ||
242 | if (i < 0) return((num > 0)?num:i); | ||
243 | if (i == 0) return(num); | ||
244 | } | ||
245 | #ifdef DEBUG | ||
246 | BIO_write(b->next_bio, ">*>", 3); | ||
247 | #endif | ||
248 | num+=i; | ||
249 | in+=i; | ||
250 | inl-=i; | ||
251 | } | ||
252 | } | ||
253 | while(foundnl && inl > 0); | ||
254 | /* We've written as much as we can. The rest of the input buffer, if | ||
255 | any, is text that doesn't and with a NL and therefore needs to be | ||
256 | saved for the next trip. */ | ||
257 | if (inl > 0) | ||
258 | { | ||
259 | memcpy(&(ctx->obuf[ctx->obuf_len]), in, inl); | ||
260 | ctx->obuf_len += inl; | ||
261 | num += inl; | ||
262 | } | ||
263 | return num; | ||
264 | } | ||
265 | |||
266 | static long linebuffer_ctrl(BIO *b, int cmd, long num, void *ptr) | ||
267 | { | ||
268 | BIO *dbio; | ||
269 | BIO_LINEBUFFER_CTX *ctx; | ||
270 | long ret=1; | ||
271 | char *p; | ||
272 | int r; | ||
273 | int obs; | ||
274 | |||
275 | ctx=(BIO_LINEBUFFER_CTX *)b->ptr; | ||
276 | |||
277 | switch (cmd) | ||
278 | { | ||
279 | case BIO_CTRL_RESET: | ||
280 | ctx->obuf_len=0; | ||
281 | if (b->next_bio == NULL) return(0); | ||
282 | ret=BIO_ctrl(b->next_bio,cmd,num,ptr); | ||
283 | break; | ||
284 | case BIO_CTRL_INFO: | ||
285 | ret=(long)ctx->obuf_len; | ||
286 | break; | ||
287 | case BIO_CTRL_WPENDING: | ||
288 | ret=(long)ctx->obuf_len; | ||
289 | if (ret == 0) | ||
290 | { | ||
291 | if (b->next_bio == NULL) return(0); | ||
292 | ret=BIO_ctrl(b->next_bio,cmd,num,ptr); | ||
293 | } | ||
294 | break; | ||
295 | case BIO_C_SET_BUFF_SIZE: | ||
296 | obs=(int)num; | ||
297 | p=ctx->obuf; | ||
298 | if ((obs > DEFAULT_LINEBUFFER_SIZE) && (obs != ctx->obuf_size)) | ||
299 | { | ||
300 | p=(char *)OPENSSL_malloc((int)num); | ||
301 | if (p == NULL) | ||
302 | goto malloc_error; | ||
303 | } | ||
304 | if (ctx->obuf != p) | ||
305 | { | ||
306 | if (ctx->obuf_len > obs) | ||
307 | { | ||
308 | ctx->obuf_len = obs; | ||
309 | } | ||
310 | memcpy(p, ctx->obuf, ctx->obuf_len); | ||
311 | OPENSSL_free(ctx->obuf); | ||
312 | ctx->obuf=p; | ||
313 | ctx->obuf_size=obs; | ||
314 | } | ||
315 | break; | ||
316 | case BIO_C_DO_STATE_MACHINE: | ||
317 | if (b->next_bio == NULL) return(0); | ||
318 | BIO_clear_retry_flags(b); | ||
319 | ret=BIO_ctrl(b->next_bio,cmd,num,ptr); | ||
320 | BIO_copy_next_retry(b); | ||
321 | break; | ||
322 | |||
323 | case BIO_CTRL_FLUSH: | ||
324 | if (b->next_bio == NULL) return(0); | ||
325 | if (ctx->obuf_len <= 0) | ||
326 | { | ||
327 | ret=BIO_ctrl(b->next_bio,cmd,num,ptr); | ||
328 | break; | ||
329 | } | ||
330 | |||
331 | for (;;) | ||
332 | { | ||
333 | BIO_clear_retry_flags(b); | ||
334 | if (ctx->obuf_len > 0) | ||
335 | { | ||
336 | r=BIO_write(b->next_bio, | ||
337 | ctx->obuf, ctx->obuf_len); | ||
338 | #if 0 | ||
339 | fprintf(stderr,"FLUSH %3d -> %3d\n",ctx->obuf_len,r); | ||
340 | #endif | ||
341 | BIO_copy_next_retry(b); | ||
342 | if (r <= 0) return((long)r); | ||
343 | if (r < ctx->obuf_len) | ||
344 | memmove(ctx->obuf, ctx->obuf + r, | ||
345 | ctx->obuf_len - r); | ||
346 | ctx->obuf_len-=r; | ||
347 | } | ||
348 | else | ||
349 | { | ||
350 | ctx->obuf_len=0; | ||
351 | ret=1; | ||
352 | break; | ||
353 | } | ||
354 | } | ||
355 | ret=BIO_ctrl(b->next_bio,cmd,num,ptr); | ||
356 | break; | ||
357 | case BIO_CTRL_DUP: | ||
358 | dbio=(BIO *)ptr; | ||
359 | if ( !BIO_set_write_buffer_size(dbio,ctx->obuf_size)) | ||
360 | ret=0; | ||
361 | break; | ||
362 | default: | ||
363 | if (b->next_bio == NULL) return(0); | ||
364 | ret=BIO_ctrl(b->next_bio,cmd,num,ptr); | ||
365 | break; | ||
366 | } | ||
367 | return(ret); | ||
368 | malloc_error: | ||
369 | BIOerr(BIO_F_LINEBUFFER_CTRL,ERR_R_MALLOC_FAILURE); | ||
370 | return(0); | ||
371 | } | ||
372 | |||
373 | static long linebuffer_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp) | ||
374 | { | ||
375 | long ret=1; | ||
376 | |||
377 | if (b->next_bio == NULL) return(0); | ||
378 | switch (cmd) | ||
379 | { | ||
380 | default: | ||
381 | ret=BIO_callback_ctrl(b->next_bio,cmd,fp); | ||
382 | break; | ||
383 | } | ||
384 | return(ret); | ||
385 | } | ||
386 | |||
387 | static int linebuffer_gets(BIO *b, char *buf, int size) | ||
388 | { | ||
389 | if (b->next_bio == NULL) return(0); | ||
390 | return(BIO_gets(b->next_bio,buf,size)); | ||
391 | } | ||
392 | |||
393 | static int linebuffer_puts(BIO *b, const char *str) | ||
394 | { | ||
395 | return(linebuffer_write(b,str,strlen(str))); | ||
396 | } | ||
397 | |||
diff --git a/src/lib/libcrypto/bio/bss_bio.c b/src/lib/libcrypto/bio/bss_bio.c new file mode 100644 index 0000000000..562e9d8de2 --- /dev/null +++ b/src/lib/libcrypto/bio/bss_bio.c | |||
@@ -0,0 +1,588 @@ | |||
1 | /* crypto/bio/bss_bio.c -*- Mode: C; c-file-style: "eay" -*- */ | ||
2 | |||
3 | /* Special method for a BIO where the other endpoint is also a BIO | ||
4 | * of this kind, handled by the same thread (i.e. the "peer" is actually | ||
5 | * ourselves, wearing a different hat). | ||
6 | * Such "BIO pairs" are mainly for using the SSL library with I/O interfaces | ||
7 | * for which no specific BIO method is available. | ||
8 | * See ssl/ssltest.c for some hints on how this can be used. */ | ||
9 | |||
10 | #ifndef BIO_PAIR_DEBUG | ||
11 | # undef NDEBUG /* avoid conflicting definitions */ | ||
12 | # define NDEBUG | ||
13 | #endif | ||
14 | |||
15 | #include <assert.h> | ||
16 | #include <stdlib.h> | ||
17 | #include <string.h> | ||
18 | |||
19 | #include <openssl/bio.h> | ||
20 | #include <openssl/err.h> | ||
21 | #include <openssl/crypto.h> | ||
22 | |||
23 | static int bio_new(BIO *bio); | ||
24 | static int bio_free(BIO *bio); | ||
25 | static int bio_read(BIO *bio, char *buf, int size); | ||
26 | static int bio_write(BIO *bio, char *buf, int num); | ||
27 | static long bio_ctrl(BIO *bio, int cmd, long num, void *ptr); | ||
28 | static int bio_puts(BIO *bio, char *str); | ||
29 | |||
30 | static int bio_make_pair(BIO *bio1, BIO *bio2); | ||
31 | static void bio_destroy_pair(BIO *bio); | ||
32 | |||
33 | static BIO_METHOD methods_biop = | ||
34 | { | ||
35 | BIO_TYPE_BIO, | ||
36 | "BIO pair", | ||
37 | bio_write, | ||
38 | bio_read, | ||
39 | bio_puts, | ||
40 | NULL /* no bio_gets */, | ||
41 | bio_ctrl, | ||
42 | bio_new, | ||
43 | bio_free | ||
44 | }; | ||
45 | |||
46 | BIO_METHOD *BIO_s_bio(void) | ||
47 | { | ||
48 | return &methods_biop; | ||
49 | } | ||
50 | |||
51 | struct bio_bio_st | ||
52 | { | ||
53 | BIO *peer; /* NULL if buf == NULL. | ||
54 | * If peer != NULL, then peer->ptr is also a bio_bio_st, | ||
55 | * and its "peer" member points back to us. | ||
56 | * peer != NULL iff init != 0 in the BIO. */ | ||
57 | |||
58 | /* This is for what we write (i.e. reading uses peer's struct): */ | ||
59 | int closed; /* valid iff peer != NULL */ | ||
60 | size_t len; /* valid iff buf != NULL; 0 if peer == NULL */ | ||
61 | size_t offset; /* valid iff buf != NULL; 0 if len == 0 */ | ||
62 | size_t size; | ||
63 | char *buf; /* "size" elements (if != NULL) */ | ||
64 | |||
65 | size_t request; /* valid iff peer != NULL; 0 if len != 0, | ||
66 | * otherwise set by peer to number of bytes | ||
67 | * it (unsuccesfully) tried to read, | ||
68 | * never more than buffer space (size-len) warrants. */ | ||
69 | }; | ||
70 | |||
71 | static int bio_new(BIO *bio) | ||
72 | { | ||
73 | struct bio_bio_st *b; | ||
74 | |||
75 | b = Malloc(sizeof *b); | ||
76 | if (b == NULL) | ||
77 | return 0; | ||
78 | |||
79 | b->peer = NULL; | ||
80 | b->size = 17*1024; /* enough for one TLS record (just a default) */ | ||
81 | b->buf = NULL; | ||
82 | |||
83 | bio->ptr = b; | ||
84 | return 1; | ||
85 | } | ||
86 | |||
87 | |||
88 | static int bio_free(BIO *bio) | ||
89 | { | ||
90 | struct bio_bio_st *b; | ||
91 | |||
92 | if (bio == NULL) | ||
93 | return 0; | ||
94 | b = bio->ptr; | ||
95 | |||
96 | assert(b != NULL); | ||
97 | |||
98 | if (b->peer) | ||
99 | bio_destroy_pair(bio); | ||
100 | |||
101 | if (b->buf != NULL) | ||
102 | { | ||
103 | Free(b->buf); | ||
104 | } | ||
105 | |||
106 | Free(b); | ||
107 | |||
108 | return 1; | ||
109 | } | ||
110 | |||
111 | |||
112 | |||
113 | static int bio_read(BIO *bio, char *buf, int size_) | ||
114 | { | ||
115 | size_t size = size_; | ||
116 | size_t rest; | ||
117 | struct bio_bio_st *b, *peer_b; | ||
118 | |||
119 | BIO_clear_retry_flags(bio); | ||
120 | |||
121 | if (!bio->init) | ||
122 | return 0; | ||
123 | |||
124 | b = bio->ptr; | ||
125 | assert(b != NULL); | ||
126 | assert(b->peer != NULL); | ||
127 | peer_b = b->peer->ptr; | ||
128 | assert(peer_b != NULL); | ||
129 | assert(peer_b->buf != NULL); | ||
130 | |||
131 | peer_b->request = 0; /* will be set in "retry_read" situation */ | ||
132 | |||
133 | if (buf == NULL || size == 0) | ||
134 | return 0; | ||
135 | |||
136 | if (peer_b->len == 0) | ||
137 | { | ||
138 | if (peer_b->closed) | ||
139 | return 0; /* writer has closed, and no data is left */ | ||
140 | else | ||
141 | { | ||
142 | BIO_set_retry_read(bio); /* buffer is empty */ | ||
143 | if (size <= peer_b->size) | ||
144 | peer_b->request = size; | ||
145 | else | ||
146 | /* don't ask for more than the peer can | ||
147 | * deliver in one write */ | ||
148 | peer_b->request = peer_b->size; | ||
149 | return -1; | ||
150 | } | ||
151 | } | ||
152 | |||
153 | /* we can read */ | ||
154 | if (peer_b->len < size) | ||
155 | size = peer_b->len; | ||
156 | |||
157 | /* now read "size" bytes */ | ||
158 | |||
159 | rest = size; | ||
160 | |||
161 | assert(rest > 0); | ||
162 | do /* one or two iterations */ | ||
163 | { | ||
164 | size_t chunk; | ||
165 | |||
166 | assert(rest <= peer_b->len); | ||
167 | if (peer_b->offset + rest <= peer_b->size) | ||
168 | chunk = rest; | ||
169 | else | ||
170 | /* wrap around ring buffer */ | ||
171 | chunk = peer_b->size - peer_b->offset; | ||
172 | assert(peer_b->offset + chunk <= peer_b->size); | ||
173 | |||
174 | memcpy(buf, peer_b->buf + peer_b->offset, chunk); | ||
175 | |||
176 | peer_b->len -= chunk; | ||
177 | if (peer_b->len) | ||
178 | { | ||
179 | peer_b->offset += chunk; | ||
180 | assert(peer_b->offset <= peer_b->size); | ||
181 | if (peer_b->offset == peer_b->size) | ||
182 | peer_b->offset = 0; | ||
183 | buf += chunk; | ||
184 | } | ||
185 | else | ||
186 | { | ||
187 | /* buffer now empty, no need to advance "buf" */ | ||
188 | assert(chunk == rest); | ||
189 | peer_b->offset = 0; | ||
190 | } | ||
191 | rest -= chunk; | ||
192 | } | ||
193 | while (rest); | ||
194 | |||
195 | return size; | ||
196 | } | ||
197 | |||
198 | static int bio_write(BIO *bio, char *buf, int num_) | ||
199 | { | ||
200 | size_t num = num_; | ||
201 | size_t rest; | ||
202 | struct bio_bio_st *b; | ||
203 | |||
204 | BIO_clear_retry_flags(bio); | ||
205 | |||
206 | if (!bio->init || buf == NULL || num == 0) | ||
207 | return 0; | ||
208 | |||
209 | b = bio->ptr; | ||
210 | assert(b != NULL); | ||
211 | assert(b->peer != NULL); | ||
212 | assert(b->buf != NULL); | ||
213 | |||
214 | b->request = 0; | ||
215 | if (b->closed) | ||
216 | { | ||
217 | /* we already closed */ | ||
218 | BIOerr(BIO_F_BIO_WRITE, BIO_R_BROKEN_PIPE); | ||
219 | return -1; | ||
220 | } | ||
221 | |||
222 | assert(b->len <= b->size); | ||
223 | |||
224 | if (b->len == b->size) | ||
225 | { | ||
226 | BIO_set_retry_write(bio); /* buffer is full */ | ||
227 | return -1; | ||
228 | } | ||
229 | |||
230 | /* we can write */ | ||
231 | if (num > b->size - b->len) | ||
232 | num = b->size - b->len; | ||
233 | |||
234 | /* now write "num" bytes */ | ||
235 | |||
236 | rest = num; | ||
237 | |||
238 | assert(rest > 0); | ||
239 | do /* one or two iterations */ | ||
240 | { | ||
241 | size_t write_offset; | ||
242 | size_t chunk; | ||
243 | |||
244 | assert(b->len + rest <= b->size); | ||
245 | |||
246 | write_offset = b->offset + b->len; | ||
247 | if (write_offset >= b->size) | ||
248 | write_offset -= b->size; | ||
249 | /* b->buf[write_offset] is the first byte we can write to. */ | ||
250 | |||
251 | if (write_offset + rest <= b->size) | ||
252 | chunk = rest; | ||
253 | else | ||
254 | /* wrap around ring buffer */ | ||
255 | chunk = b->size - write_offset; | ||
256 | |||
257 | memcpy(b->buf + write_offset, buf, chunk); | ||
258 | |||
259 | b->len += chunk; | ||
260 | |||
261 | assert(b->len <= b->size); | ||
262 | |||
263 | rest -= chunk; | ||
264 | buf += chunk; | ||
265 | } | ||
266 | while (rest); | ||
267 | |||
268 | return num; | ||
269 | } | ||
270 | |||
271 | |||
272 | static long bio_ctrl(BIO *bio, int cmd, long num, void *ptr) | ||
273 | { | ||
274 | long ret; | ||
275 | struct bio_bio_st *b = bio->ptr; | ||
276 | |||
277 | assert(b != NULL); | ||
278 | |||
279 | switch (cmd) | ||
280 | { | ||
281 | /* specific CTRL codes */ | ||
282 | |||
283 | case BIO_C_SET_WRITE_BUF_SIZE: | ||
284 | if (b->peer) | ||
285 | { | ||
286 | BIOerr(BIO_F_BIO_CTRL, BIO_R_IN_USE); | ||
287 | ret = 0; | ||
288 | } | ||
289 | else if (num == 0) | ||
290 | { | ||
291 | BIOerr(BIO_F_BIO_CTRL, BIO_R_INVALID_ARGUMENT); | ||
292 | ret = 0; | ||
293 | } | ||
294 | else | ||
295 | { | ||
296 | size_t new_size = num; | ||
297 | |||
298 | if (b->size != new_size) | ||
299 | { | ||
300 | if (b->buf) | ||
301 | { | ||
302 | Free(b->buf); | ||
303 | b->buf = NULL; | ||
304 | } | ||
305 | b->size = new_size; | ||
306 | } | ||
307 | ret = 1; | ||
308 | } | ||
309 | break; | ||
310 | |||
311 | case BIO_C_GET_WRITE_BUF_SIZE: | ||
312 | num = (long) b->size; | ||
313 | |||
314 | case BIO_C_MAKE_BIO_PAIR: | ||
315 | { | ||
316 | BIO *other_bio = ptr; | ||
317 | |||
318 | if (bio_make_pair(bio, other_bio)) | ||
319 | ret = 1; | ||
320 | else | ||
321 | ret = 0; | ||
322 | } | ||
323 | break; | ||
324 | |||
325 | case BIO_C_DESTROY_BIO_PAIR: | ||
326 | /* Effects both BIOs in the pair -- call just once! | ||
327 | * Or let BIO_free(bio1); BIO_free(bio2); do the job. */ | ||
328 | bio_destroy_pair(bio); | ||
329 | ret = 1; | ||
330 | break; | ||
331 | |||
332 | case BIO_C_GET_WRITE_GUARANTEE: | ||
333 | /* How many bytes can the caller feed to the next write | ||
334 | * withouth having to keep any? */ | ||
335 | if (b->peer == NULL || b->closed) | ||
336 | ret = 0; | ||
337 | else | ||
338 | ret = (long) b->size - b->len; | ||
339 | break; | ||
340 | |||
341 | case BIO_C_GET_READ_REQUEST: | ||
342 | /* If the peer unsuccesfully tried to read, how many bytes | ||
343 | * were requested? (As with BIO_CTRL_PENDING, that number | ||
344 | * can usually be treated as boolean.) */ | ||
345 | ret = (long) b->request; | ||
346 | break; | ||
347 | |||
348 | case BIO_C_SHUTDOWN_WR: | ||
349 | /* similar to shutdown(..., SHUT_WR) */ | ||
350 | b->closed = 1; | ||
351 | ret = 1; | ||
352 | break; | ||
353 | |||
354 | |||
355 | /* standard CTRL codes follow */ | ||
356 | |||
357 | case BIO_CTRL_RESET: | ||
358 | if (b->buf != NULL) | ||
359 | { | ||
360 | b->len = 0; | ||
361 | b->offset = 0; | ||
362 | } | ||
363 | ret = 0; | ||
364 | break; | ||
365 | |||
366 | case BIO_CTRL_GET_CLOSE: | ||
367 | ret = bio->shutdown; | ||
368 | break; | ||
369 | |||
370 | case BIO_CTRL_SET_CLOSE: | ||
371 | bio->shutdown = (int) num; | ||
372 | ret = 1; | ||
373 | break; | ||
374 | |||
375 | case BIO_CTRL_PENDING: | ||
376 | if (b->peer != NULL) | ||
377 | { | ||
378 | struct bio_bio_st *peer_b = b->peer->ptr; | ||
379 | |||
380 | ret = (long) peer_b->len; | ||
381 | } | ||
382 | else | ||
383 | ret = 0; | ||
384 | break; | ||
385 | |||
386 | case BIO_CTRL_WPENDING: | ||
387 | if (b->buf != NULL) | ||
388 | ret = (long) b->len; | ||
389 | else | ||
390 | ret = 0; | ||
391 | break; | ||
392 | |||
393 | case BIO_CTRL_DUP: | ||
394 | /* See BIO_dup_chain for circumstances we have to expect. */ | ||
395 | { | ||
396 | BIO *other_bio = ptr; | ||
397 | struct bio_bio_st *other_b; | ||
398 | |||
399 | assert(other_bio != NULL); | ||
400 | other_b = other_bio->ptr; | ||
401 | assert(other_b != NULL); | ||
402 | |||
403 | assert(other_b->buf == NULL); /* other_bio is always fresh */ | ||
404 | |||
405 | other_b->size = b->size; | ||
406 | } | ||
407 | |||
408 | ret = 1; | ||
409 | break; | ||
410 | |||
411 | case BIO_CTRL_FLUSH: | ||
412 | ret = 1; | ||
413 | break; | ||
414 | |||
415 | case BIO_CTRL_EOF: | ||
416 | { | ||
417 | BIO *other_bio = ptr; | ||
418 | |||
419 | if (other_bio) | ||
420 | { | ||
421 | struct bio_bio_st *other_b = other_bio->ptr; | ||
422 | |||
423 | assert(other_b != NULL); | ||
424 | ret = other_b->len == 0 && other_b->closed; | ||
425 | } | ||
426 | else | ||
427 | ret = 1; | ||
428 | } | ||
429 | break; | ||
430 | |||
431 | default: | ||
432 | ret = 0; | ||
433 | } | ||
434 | return ret; | ||
435 | } | ||
436 | |||
437 | static int bio_puts(BIO *bio, char *str) | ||
438 | { | ||
439 | return bio_write(bio, str, strlen(str)); | ||
440 | } | ||
441 | |||
442 | |||
443 | static int bio_make_pair(BIO *bio1, BIO *bio2) | ||
444 | { | ||
445 | struct bio_bio_st *b1, *b2; | ||
446 | |||
447 | assert(bio1 != NULL); | ||
448 | assert(bio2 != NULL); | ||
449 | |||
450 | b1 = bio1->ptr; | ||
451 | b2 = bio2->ptr; | ||
452 | |||
453 | if (b1->peer != NULL || b2->peer != NULL) | ||
454 | { | ||
455 | BIOerr(BIO_F_BIO_MAKE_PAIR, BIO_R_IN_USE); | ||
456 | return 0; | ||
457 | } | ||
458 | |||
459 | if (b1->buf == NULL) | ||
460 | { | ||
461 | b1->buf = Malloc(b1->size); | ||
462 | if (b1->buf == NULL) | ||
463 | { | ||
464 | BIOerr(BIO_F_BIO_MAKE_PAIR, ERR_R_MALLOC_FAILURE); | ||
465 | return 0; | ||
466 | } | ||
467 | b1->len = 0; | ||
468 | b1->offset = 0; | ||
469 | } | ||
470 | |||
471 | if (b2->buf == NULL) | ||
472 | { | ||
473 | b2->buf = Malloc(b2->size); | ||
474 | if (b2->buf == NULL) | ||
475 | { | ||
476 | BIOerr(BIO_F_BIO_MAKE_PAIR, ERR_R_MALLOC_FAILURE); | ||
477 | return 0; | ||
478 | } | ||
479 | b2->len = 0; | ||
480 | b2->offset = 0; | ||
481 | } | ||
482 | |||
483 | b1->peer = bio2; | ||
484 | b1->closed = 0; | ||
485 | b1->request = 0; | ||
486 | b2->peer = bio1; | ||
487 | b2->closed = 0; | ||
488 | b2->request = 0; | ||
489 | |||
490 | bio1->init = 1; | ||
491 | bio2->init = 1; | ||
492 | |||
493 | return 1; | ||
494 | } | ||
495 | |||
496 | static void bio_destroy_pair(BIO *bio) | ||
497 | { | ||
498 | struct bio_bio_st *b = bio->ptr; | ||
499 | |||
500 | if (b != NULL) | ||
501 | { | ||
502 | BIO *peer_bio = b->peer; | ||
503 | |||
504 | if (peer_bio != NULL) | ||
505 | { | ||
506 | struct bio_bio_st *peer_b = peer_bio->ptr; | ||
507 | |||
508 | assert(peer_b != NULL); | ||
509 | assert(peer_b->peer == bio); | ||
510 | |||
511 | peer_b->peer = NULL; | ||
512 | peer_bio->init = 0; | ||
513 | assert(peer_b->buf != NULL); | ||
514 | peer_b->len = 0; | ||
515 | peer_b->offset = 0; | ||
516 | |||
517 | b->peer = NULL; | ||
518 | bio->init = 0; | ||
519 | assert(b->buf != NULL); | ||
520 | b->len = 0; | ||
521 | b->offset = 0; | ||
522 | } | ||
523 | } | ||
524 | } | ||
525 | |||
526 | |||
527 | /* Exported convenience functions */ | ||
528 | int BIO_new_bio_pair(BIO **bio1_p, size_t writebuf1, | ||
529 | BIO **bio2_p, size_t writebuf2) | ||
530 | { | ||
531 | BIO *bio1 = NULL, *bio2 = NULL; | ||
532 | long r; | ||
533 | int ret = 0; | ||
534 | |||
535 | bio1 = BIO_new(BIO_s_bio()); | ||
536 | if (bio1 == NULL) | ||
537 | goto err; | ||
538 | bio2 = BIO_new(BIO_s_bio()); | ||
539 | if (bio2 == NULL) | ||
540 | goto err; | ||
541 | |||
542 | if (writebuf1) | ||
543 | { | ||
544 | r = BIO_set_write_buf_size(bio1, writebuf1); | ||
545 | if (!r) | ||
546 | goto err; | ||
547 | } | ||
548 | if (writebuf2) | ||
549 | { | ||
550 | r = BIO_set_write_buf_size(bio2, writebuf2); | ||
551 | if (!r) | ||
552 | goto err; | ||
553 | } | ||
554 | |||
555 | r = BIO_make_bio_pair(bio1, bio2); | ||
556 | if (!r) | ||
557 | goto err; | ||
558 | ret = 1; | ||
559 | |||
560 | err: | ||
561 | if (ret == 0) | ||
562 | { | ||
563 | if (bio1) | ||
564 | { | ||
565 | BIO_free(bio1); | ||
566 | bio1 = NULL; | ||
567 | } | ||
568 | if (bio2) | ||
569 | { | ||
570 | BIO_free(bio2); | ||
571 | bio2 = NULL; | ||
572 | } | ||
573 | } | ||
574 | |||
575 | *bio1_p = bio1; | ||
576 | *bio2_p = bio2; | ||
577 | return ret; | ||
578 | } | ||
579 | |||
580 | size_t BIO_ctrl_get_write_guarantee(BIO *bio) | ||
581 | { | ||
582 | return BIO_ctrl(bio, BIO_C_GET_WRITE_GUARANTEE, 0, NULL); | ||
583 | } | ||
584 | |||
585 | size_t BIO_ctrl_get_read_request(BIO *bio) | ||
586 | { | ||
587 | return BIO_ctrl(bio, BIO_C_GET_READ_REQUEST, 0, NULL); | ||
588 | } | ||
diff --git a/src/lib/libcrypto/bio/bss_log.c b/src/lib/libcrypto/bio/bss_log.c new file mode 100644 index 0000000000..db82e757e7 --- /dev/null +++ b/src/lib/libcrypto/bio/bss_log.c | |||
@@ -0,0 +1,232 @@ | |||
1 | /* crypto/bio/bss_log.c */ | ||
2 | /* ==================================================================== | ||
3 | * Copyright (c) 1999 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 | /* | ||
57 | Why BIO_s_log? | ||
58 | |||
59 | BIO_s_log is useful for system daemons (or services under NT). | ||
60 | It is one-way BIO, it sends all stuff to syslogd (or event log | ||
61 | under NT). | ||
62 | |||
63 | */ | ||
64 | |||
65 | |||
66 | #include <stdio.h> | ||
67 | #include <errno.h> | ||
68 | |||
69 | #ifndef WIN32 | ||
70 | #ifdef __ultrix | ||
71 | #include <sys/syslog.h> | ||
72 | #else | ||
73 | #include <syslog.h> | ||
74 | #endif | ||
75 | #endif | ||
76 | |||
77 | #include "cryptlib.h" | ||
78 | #include <openssl/buffer.h> | ||
79 | #include <openssl/err.h> | ||
80 | #ifndef NO_SYSLOG | ||
81 | |||
82 | |||
83 | static int MS_CALLBACK slg_write(BIO *h,char *buf,int num); | ||
84 | static int MS_CALLBACK slg_puts(BIO *h,char *str); | ||
85 | static long MS_CALLBACK slg_ctrl(BIO *h,int cmd,long arg1,char *arg2); | ||
86 | static int MS_CALLBACK slg_new(BIO *h); | ||
87 | static int MS_CALLBACK slg_free(BIO *data); | ||
88 | static int xopenlog(BIO* bp, const char* name, int level); | ||
89 | static int xcloselog(BIO* bp); | ||
90 | |||
91 | static BIO_METHOD methods_slg= | ||
92 | { | ||
93 | BIO_TYPE_MEM,"syslog", | ||
94 | slg_write, | ||
95 | NULL, | ||
96 | slg_puts, | ||
97 | NULL, | ||
98 | slg_ctrl, | ||
99 | slg_new, | ||
100 | slg_free, | ||
101 | }; | ||
102 | |||
103 | BIO_METHOD *BIO_s_log(void) | ||
104 | { | ||
105 | return(&methods_slg); | ||
106 | } | ||
107 | |||
108 | static int MS_CALLBACK slg_new(BIO *bi) | ||
109 | { | ||
110 | bi->init=1; | ||
111 | bi->num=0; | ||
112 | bi->ptr=NULL; | ||
113 | #ifndef WIN32 | ||
114 | xopenlog(bi, "application", LOG_DAEMON); | ||
115 | #else | ||
116 | xopenlog(bi, "application", 0); | ||
117 | #endif | ||
118 | return(1); | ||
119 | } | ||
120 | |||
121 | static int MS_CALLBACK slg_free(BIO *a) | ||
122 | { | ||
123 | if (a == NULL) return(0); | ||
124 | xcloselog(a); | ||
125 | return(1); | ||
126 | } | ||
127 | |||
128 | static int MS_CALLBACK slg_write(BIO *b, char *in, int inl) | ||
129 | { | ||
130 | int ret= inl; | ||
131 | char* buf= in; | ||
132 | char* pp; | ||
133 | #if defined(WIN32) | ||
134 | LPTSTR lpszStrings[1]; | ||
135 | WORD evtype= EVENTLOG_ERROR_TYPE; | ||
136 | #else | ||
137 | int priority; | ||
138 | #endif | ||
139 | |||
140 | if((buf= (char *)Malloc(inl+ 1)) == NULL){ | ||
141 | return(0); | ||
142 | } | ||
143 | strncpy(buf, in, inl); | ||
144 | buf[inl]= '\0'; | ||
145 | #if defined(WIN32) | ||
146 | if(strncmp(buf, "ERR ", 4) == 0){ | ||
147 | evtype= EVENTLOG_ERROR_TYPE; | ||
148 | pp= buf+ 4; | ||
149 | }else if(strncmp(buf, "WAR ", 4) == 0){ | ||
150 | evtype= EVENTLOG_WARNING_TYPE; | ||
151 | pp= buf+ 4; | ||
152 | }else if(strncmp(buf, "INF ", 4) == 0){ | ||
153 | evtype= EVENTLOG_INFORMATION_TYPE; | ||
154 | pp= buf+ 4; | ||
155 | }else{ | ||
156 | evtype= EVENTLOG_ERROR_TYPE; | ||
157 | pp= buf; | ||
158 | } | ||
159 | lpszStrings[0]= pp; | ||
160 | |||
161 | if(b->ptr) | ||
162 | ReportEvent(b->ptr, evtype, 0, 1024, NULL, 1, 0, | ||
163 | lpszStrings, NULL); | ||
164 | #else | ||
165 | if(strncmp(buf, "ERR ", 4) == 0){ | ||
166 | priority= LOG_ERR; | ||
167 | pp= buf+ 4; | ||
168 | }else if(strncmp(buf, "WAR ", 4) == 0){ | ||
169 | priority= LOG_WARNING; | ||
170 | pp= buf+ 4; | ||
171 | }else if(strncmp(buf, "INF ", 4) == 0){ | ||
172 | priority= LOG_INFO; | ||
173 | pp= buf+ 4; | ||
174 | }else{ | ||
175 | priority= LOG_ERR; | ||
176 | pp= buf; | ||
177 | } | ||
178 | |||
179 | syslog(priority, "%s", pp); | ||
180 | #endif | ||
181 | Free(buf); | ||
182 | return(ret); | ||
183 | } | ||
184 | |||
185 | static long MS_CALLBACK slg_ctrl(BIO *b, int cmd, long num, char *ptr) | ||
186 | { | ||
187 | switch (cmd) | ||
188 | { | ||
189 | case BIO_CTRL_SET: | ||
190 | xcloselog(b); | ||
191 | xopenlog(b, ptr, num); | ||
192 | break; | ||
193 | default: | ||
194 | break; | ||
195 | } | ||
196 | return(0); | ||
197 | } | ||
198 | |||
199 | static int MS_CALLBACK slg_puts(BIO *bp, char *str) | ||
200 | { | ||
201 | int n,ret; | ||
202 | |||
203 | n=strlen(str); | ||
204 | ret=slg_write(bp,str,n); | ||
205 | return(ret); | ||
206 | } | ||
207 | |||
208 | static int xopenlog(BIO* bp, const char* name, int level) | ||
209 | { | ||
210 | #if defined(WIN32) | ||
211 | if((bp->ptr= (char *)RegisterEventSource(NULL, name)) == NULL){ | ||
212 | return(0); | ||
213 | } | ||
214 | #else | ||
215 | openlog(name, LOG_PID|LOG_CONS, level); | ||
216 | #endif | ||
217 | return(1); | ||
218 | } | ||
219 | |||
220 | static int xcloselog(BIO* bp) | ||
221 | { | ||
222 | #if defined(WIN32) | ||
223 | if(bp->ptr) | ||
224 | DeregisterEventSource((HANDLE)(bp->ptr)); | ||
225 | bp->ptr= NULL; | ||
226 | #else | ||
227 | closelog(); | ||
228 | #endif | ||
229 | return(1); | ||
230 | } | ||
231 | |||
232 | #endif | ||
diff --git a/src/lib/libcrypto/bn/asm/co-586.pl b/src/lib/libcrypto/bn/asm/co-586.pl new file mode 100644 index 0000000000..5d962cb957 --- /dev/null +++ b/src/lib/libcrypto/bn/asm/co-586.pl | |||
@@ -0,0 +1,286 @@ | |||
1 | #!/usr/local/bin/perl | ||
2 | |||
3 | push(@INC,"perlasm","../../perlasm"); | ||
4 | require "x86asm.pl"; | ||
5 | |||
6 | &asm_init($ARGV[0],$0); | ||
7 | |||
8 | &bn_mul_comba("bn_mul_comba8",8); | ||
9 | &bn_mul_comba("bn_mul_comba4",4); | ||
10 | &bn_sqr_comba("bn_sqr_comba8",8); | ||
11 | &bn_sqr_comba("bn_sqr_comba4",4); | ||
12 | |||
13 | &asm_finish(); | ||
14 | |||
15 | sub mul_add_c | ||
16 | { | ||
17 | local($a,$ai,$b,$bi,$c0,$c1,$c2,$pos,$i,$na,$nb)=@_; | ||
18 | |||
19 | # pos == -1 if eax and edx are pre-loaded, 0 to load from next | ||
20 | # words, and 1 if load return value | ||
21 | |||
22 | &comment("mul a[$ai]*b[$bi]"); | ||
23 | |||
24 | # "eax" and "edx" will always be pre-loaded. | ||
25 | # &mov("eax",&DWP($ai*4,$a,"",0)) ; | ||
26 | # &mov("edx",&DWP($bi*4,$b,"",0)); | ||
27 | |||
28 | &mul("edx"); | ||
29 | &add($c0,"eax"); | ||
30 | &mov("eax",&DWP(($na)*4,$a,"",0)) if $pos == 0; # laod next a | ||
31 | &mov("eax",&wparam(0)) if $pos > 0; # load r[] | ||
32 | ### | ||
33 | &adc($c1,"edx"); | ||
34 | &mov("edx",&DWP(($nb)*4,$b,"",0)) if $pos == 0; # laod next b | ||
35 | &mov("edx",&DWP(($nb)*4,$b,"",0)) if $pos == 1; # laod next b | ||
36 | ### | ||
37 | &adc($c2,0); | ||
38 | # is pos > 1, it means it is the last loop | ||
39 | &mov(&DWP($i*4,"eax","",0),$c0) if $pos > 0; # save r[]; | ||
40 | &mov("eax",&DWP(($na)*4,$a,"",0)) if $pos == 1; # laod next a | ||
41 | } | ||
42 | |||
43 | sub sqr_add_c | ||
44 | { | ||
45 | local($r,$a,$ai,$bi,$c0,$c1,$c2,$pos,$i,$na,$nb)=@_; | ||
46 | |||
47 | # pos == -1 if eax and edx are pre-loaded, 0 to load from next | ||
48 | # words, and 1 if load return value | ||
49 | |||
50 | &comment("sqr a[$ai]*a[$bi]"); | ||
51 | |||
52 | # "eax" and "edx" will always be pre-loaded. | ||
53 | # &mov("eax",&DWP($ai*4,$a,"",0)) ; | ||
54 | # &mov("edx",&DWP($bi*4,$b,"",0)); | ||
55 | |||
56 | if ($ai == $bi) | ||
57 | { &mul("eax");} | ||
58 | else | ||
59 | { &mul("edx");} | ||
60 | &add($c0,"eax"); | ||
61 | &mov("eax",&DWP(($na)*4,$a,"",0)) if $pos == 0; # load next a | ||
62 | ### | ||
63 | &adc($c1,"edx"); | ||
64 | &mov("edx",&DWP(($nb)*4,$a,"",0)) if ($pos == 1) && ($na != $nb); | ||
65 | ### | ||
66 | &adc($c2,0); | ||
67 | # is pos > 1, it means it is the last loop | ||
68 | &mov(&DWP($i*4,$r,"",0),$c0) if $pos > 0; # save r[]; | ||
69 | &mov("eax",&DWP(($na)*4,$a,"",0)) if $pos == 1; # load next b | ||
70 | } | ||
71 | |||
72 | sub sqr_add_c2 | ||
73 | { | ||
74 | local($r,$a,$ai,$bi,$c0,$c1,$c2,$pos,$i,$na,$nb)=@_; | ||
75 | |||
76 | # pos == -1 if eax and edx are pre-loaded, 0 to load from next | ||
77 | # words, and 1 if load return value | ||
78 | |||
79 | &comment("sqr a[$ai]*a[$bi]"); | ||
80 | |||
81 | # "eax" and "edx" will always be pre-loaded. | ||
82 | # &mov("eax",&DWP($ai*4,$a,"",0)) ; | ||
83 | # &mov("edx",&DWP($bi*4,$a,"",0)); | ||
84 | |||
85 | if ($ai == $bi) | ||
86 | { &mul("eax");} | ||
87 | else | ||
88 | { &mul("edx");} | ||
89 | &add("eax","eax"); | ||
90 | ### | ||
91 | &adc("edx","edx"); | ||
92 | ### | ||
93 | &adc($c2,0); | ||
94 | &add($c0,"eax"); | ||
95 | &adc($c1,"edx"); | ||
96 | &mov("eax",&DWP(($na)*4,$a,"",0)) if $pos == 0; # load next a | ||
97 | &mov("eax",&DWP(($na)*4,$a,"",0)) if $pos == 1; # load next b | ||
98 | &adc($c2,0); | ||
99 | &mov(&DWP($i*4,$r,"",0),$c0) if $pos > 0; # save r[]; | ||
100 | &mov("edx",&DWP(($nb)*4,$a,"",0)) if ($pos <= 1) && ($na != $nb); | ||
101 | ### | ||
102 | } | ||
103 | |||
104 | sub bn_mul_comba | ||
105 | { | ||
106 | local($name,$num)=@_; | ||
107 | local($a,$b,$c0,$c1,$c2); | ||
108 | local($i,$as,$ae,$bs,$be,$ai,$bi); | ||
109 | local($tot,$end); | ||
110 | |||
111 | &function_begin_B($name,""); | ||
112 | |||
113 | $c0="ebx"; | ||
114 | $c1="ecx"; | ||
115 | $c2="ebp"; | ||
116 | $a="esi"; | ||
117 | $b="edi"; | ||
118 | |||
119 | $as=0; | ||
120 | $ae=0; | ||
121 | $bs=0; | ||
122 | $be=0; | ||
123 | $tot=$num+$num-1; | ||
124 | |||
125 | &push("esi"); | ||
126 | &mov($a,&wparam(1)); | ||
127 | &push("edi"); | ||
128 | &mov($b,&wparam(2)); | ||
129 | &push("ebp"); | ||
130 | &push("ebx"); | ||
131 | |||
132 | &xor($c0,$c0); | ||
133 | &mov("eax",&DWP(0,$a,"",0)); # load the first word | ||
134 | &xor($c1,$c1); | ||
135 | &mov("edx",&DWP(0,$b,"",0)); # load the first second | ||
136 | |||
137 | for ($i=0; $i<$tot; $i++) | ||
138 | { | ||
139 | $ai=$as; | ||
140 | $bi=$bs; | ||
141 | $end=$be+1; | ||
142 | |||
143 | &comment("################## Calculate word $i"); | ||
144 | |||
145 | for ($j=$bs; $j<$end; $j++) | ||
146 | { | ||
147 | &xor($c2,$c2) if ($j == $bs); | ||
148 | if (($j+1) == $end) | ||
149 | { | ||
150 | $v=1; | ||
151 | $v=2 if (($i+1) == $tot); | ||
152 | } | ||
153 | else | ||
154 | { $v=0; } | ||
155 | if (($j+1) != $end) | ||
156 | { | ||
157 | $na=($ai-1); | ||
158 | $nb=($bi+1); | ||
159 | } | ||
160 | else | ||
161 | { | ||
162 | $na=$as+($i < ($num-1)); | ||
163 | $nb=$bs+($i >= ($num-1)); | ||
164 | } | ||
165 | #printf STDERR "[$ai,$bi] -> [$na,$nb]\n"; | ||
166 | &mul_add_c($a,$ai,$b,$bi,$c0,$c1,$c2,$v,$i,$na,$nb); | ||
167 | if ($v) | ||
168 | { | ||
169 | &comment("saved r[$i]"); | ||
170 | # &mov("eax",&wparam(0)); | ||
171 | # &mov(&DWP($i*4,"eax","",0),$c0); | ||
172 | ($c0,$c1,$c2)=($c1,$c2,$c0); | ||
173 | } | ||
174 | $ai--; | ||
175 | $bi++; | ||
176 | } | ||
177 | $as++ if ($i < ($num-1)); | ||
178 | $ae++ if ($i >= ($num-1)); | ||
179 | |||
180 | $bs++ if ($i >= ($num-1)); | ||
181 | $be++ if ($i < ($num-1)); | ||
182 | } | ||
183 | &comment("save r[$i]"); | ||
184 | # &mov("eax",&wparam(0)); | ||
185 | &mov(&DWP($i*4,"eax","",0),$c0); | ||
186 | |||
187 | &pop("ebx"); | ||
188 | &pop("ebp"); | ||
189 | &pop("edi"); | ||
190 | &pop("esi"); | ||
191 | &ret(); | ||
192 | &function_end_B($name); | ||
193 | } | ||
194 | |||
195 | sub bn_sqr_comba | ||
196 | { | ||
197 | local($name,$num)=@_; | ||
198 | local($r,$a,$c0,$c1,$c2)=@_; | ||
199 | local($i,$as,$ae,$bs,$be,$ai,$bi); | ||
200 | local($b,$tot,$end,$half); | ||
201 | |||
202 | &function_begin_B($name,""); | ||
203 | |||
204 | $c0="ebx"; | ||
205 | $c1="ecx"; | ||
206 | $c2="ebp"; | ||
207 | $a="esi"; | ||
208 | $r="edi"; | ||
209 | |||
210 | &push("esi"); | ||
211 | &push("edi"); | ||
212 | &push("ebp"); | ||
213 | &push("ebx"); | ||
214 | &mov($r,&wparam(0)); | ||
215 | &mov($a,&wparam(1)); | ||
216 | &xor($c0,$c0); | ||
217 | &xor($c1,$c1); | ||
218 | &mov("eax",&DWP(0,$a,"",0)); # load the first word | ||
219 | |||
220 | $as=0; | ||
221 | $ae=0; | ||
222 | $bs=0; | ||
223 | $be=0; | ||
224 | $tot=$num+$num-1; | ||
225 | |||
226 | for ($i=0; $i<$tot; $i++) | ||
227 | { | ||
228 | $ai=$as; | ||
229 | $bi=$bs; | ||
230 | $end=$be+1; | ||
231 | |||
232 | &comment("############### Calculate word $i"); | ||
233 | for ($j=$bs; $j<$end; $j++) | ||
234 | { | ||
235 | &xor($c2,$c2) if ($j == $bs); | ||
236 | if (($ai-1) < ($bi+1)) | ||
237 | { | ||
238 | $v=1; | ||
239 | $v=2 if ($i+1) == $tot; | ||
240 | } | ||
241 | else | ||
242 | { $v=0; } | ||
243 | if (!$v) | ||
244 | { | ||
245 | $na=$ai-1; | ||
246 | $nb=$bi+1; | ||
247 | } | ||
248 | else | ||
249 | { | ||
250 | $na=$as+($i < ($num-1)); | ||
251 | $nb=$bs+($i >= ($num-1)); | ||
252 | } | ||
253 | if ($ai == $bi) | ||
254 | { | ||
255 | &sqr_add_c($r,$a,$ai,$bi, | ||
256 | $c0,$c1,$c2,$v,$i,$na,$nb); | ||
257 | } | ||
258 | else | ||
259 | { | ||
260 | &sqr_add_c2($r,$a,$ai,$bi, | ||
261 | $c0,$c1,$c2,$v,$i,$na,$nb); | ||
262 | } | ||
263 | if ($v) | ||
264 | { | ||
265 | &comment("saved r[$i]"); | ||
266 | #&mov(&DWP($i*4,$r,"",0),$c0); | ||
267 | ($c0,$c1,$c2)=($c1,$c2,$c0); | ||
268 | last; | ||
269 | } | ||
270 | $ai--; | ||
271 | $bi++; | ||
272 | } | ||
273 | $as++ if ($i < ($num-1)); | ||
274 | $ae++ if ($i >= ($num-1)); | ||
275 | |||
276 | $bs++ if ($i >= ($num-1)); | ||
277 | $be++ if ($i < ($num-1)); | ||
278 | } | ||
279 | &mov(&DWP($i*4,$r,"",0),$c0); | ||
280 | &pop("ebx"); | ||
281 | &pop("ebp"); | ||
282 | &pop("edi"); | ||
283 | &pop("esi"); | ||
284 | &ret(); | ||
285 | &function_end_B($name); | ||
286 | } | ||
diff --git a/src/lib/libcrypto/bn/asm/ia64.S b/src/lib/libcrypto/bn/asm/ia64.S new file mode 100644 index 0000000000..ae56066310 --- /dev/null +++ b/src/lib/libcrypto/bn/asm/ia64.S | |||
@@ -0,0 +1,1498 @@ | |||
1 | .explicit | ||
2 | .text | ||
3 | .ident "ia64.S, Version 1.1" | ||
4 | .ident "IA-64 ISA artwork by Andy Polyakov <appro@fy.chalmers.se>" | ||
5 | |||
6 | // | ||
7 | // ==================================================================== | ||
8 | // Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL | ||
9 | // project. | ||
10 | // | ||
11 | // Rights for redistribution and usage in source and binary forms are | ||
12 | // granted according to the OpenSSL license. Warranty of any kind is | ||
13 | // disclaimed. | ||
14 | // ==================================================================== | ||
15 | // | ||
16 | |||
17 | // Q. How much faster does it get? | ||
18 | // A. Here is the output from 'openssl speed rsa dsa' for vanilla | ||
19 | // 0.9.6a compiled with gcc version 2.96 20000731 (Red Hat | ||
20 | // Linux 7.1 2.96-81): | ||
21 | // | ||
22 | // sign verify sign/s verify/s | ||
23 | // rsa 512 bits 0.0036s 0.0003s 275.3 2999.2 | ||
24 | // rsa 1024 bits 0.0203s 0.0011s 49.3 894.1 | ||
25 | // rsa 2048 bits 0.1331s 0.0040s 7.5 250.9 | ||
26 | // rsa 4096 bits 0.9270s 0.0147s 1.1 68.1 | ||
27 | // sign verify sign/s verify/s | ||
28 | // dsa 512 bits 0.0035s 0.0043s 288.3 234.8 | ||
29 | // dsa 1024 bits 0.0111s 0.0135s 90.0 74.2 | ||
30 | // | ||
31 | // And here is similar output but for this assembler | ||
32 | // implementation:-) | ||
33 | // | ||
34 | // sign verify sign/s verify/s | ||
35 | // rsa 512 bits 0.0021s 0.0001s 549.4 9638.5 | ||
36 | // rsa 1024 bits 0.0055s 0.0002s 183.8 4481.1 | ||
37 | // rsa 2048 bits 0.0244s 0.0006s 41.4 1726.3 | ||
38 | // rsa 4096 bits 0.1295s 0.0018s 7.7 561.5 | ||
39 | // sign verify sign/s verify/s | ||
40 | // dsa 512 bits 0.0012s 0.0013s 891.9 756.6 | ||
41 | // dsa 1024 bits 0.0023s 0.0028s 440.4 376.2 | ||
42 | // | ||
43 | // Yes, you may argue that it's not fair comparison as it's | ||
44 | // possible to craft the C implementation with BN_UMULT_HIGH | ||
45 | // inline assembler macro. But of course! Here is the output | ||
46 | // with the macro: | ||
47 | // | ||
48 | // sign verify sign/s verify/s | ||
49 | // rsa 512 bits 0.0020s 0.0002s 495.0 6561.0 | ||
50 | // rsa 1024 bits 0.0086s 0.0004s 116.2 2235.7 | ||
51 | // rsa 2048 bits 0.0519s 0.0015s 19.3 667.3 | ||
52 | // rsa 4096 bits 0.3464s 0.0053s 2.9 187.7 | ||
53 | // sign verify sign/s verify/s | ||
54 | // dsa 512 bits 0.0016s 0.0020s 613.1 510.5 | ||
55 | // dsa 1024 bits 0.0045s 0.0054s 221.0 183.9 | ||
56 | // | ||
57 | // My code is still way faster, huh:-) And I believe that even | ||
58 | // higher performance can be achieved. Note that as keys get | ||
59 | // longer, performance gain is larger. Why? According to the | ||
60 | // profiler there is another player in the field, namely | ||
61 | // BN_from_montgomery consuming larger and larger portion of CPU | ||
62 | // time as keysize decreases. I therefore consider putting effort | ||
63 | // to assembler implementation of the following routine: | ||
64 | // | ||
65 | // void bn_mul_add_mont (BN_ULONG *rp,BN_ULONG *np,int nl,BN_ULONG n0) | ||
66 | // { | ||
67 | // int i,j; | ||
68 | // BN_ULONG v; | ||
69 | // | ||
70 | // for (i=0; i<nl; i++) | ||
71 | // { | ||
72 | // v=bn_mul_add_words(rp,np,nl,(rp[0]*n0)&BN_MASK2); | ||
73 | // nrp++; | ||
74 | // rp++; | ||
75 | // if (((nrp[-1]+=v)&BN_MASK2) < v) | ||
76 | // for (j=0; ((++nrp[j])&BN_MASK2) == 0; j++) ; | ||
77 | // } | ||
78 | // } | ||
79 | // | ||
80 | // It might as well be beneficial to implement even combaX | ||
81 | // variants, as it appears as it can literally unleash the | ||
82 | // performance (see comment section to bn_mul_comba8 below). | ||
83 | // | ||
84 | // And finally for your reference the output for 0.9.6a compiled | ||
85 | // with SGIcc version 0.01.0-12 (keep in mind that for the moment | ||
86 | // of this writing it's not possible to convince SGIcc to use | ||
87 | // BN_UMULT_HIGH inline assembler macro, yet the code is fast, | ||
88 | // i.e. for a compiler generated one:-): | ||
89 | // | ||
90 | // sign verify sign/s verify/s | ||
91 | // rsa 512 bits 0.0022s 0.0002s 452.7 5894.3 | ||
92 | // rsa 1024 bits 0.0097s 0.0005s 102.7 2002.9 | ||
93 | // rsa 2048 bits 0.0578s 0.0017s 17.3 600.2 | ||
94 | // rsa 4096 bits 0.3838s 0.0061s 2.6 164.5 | ||
95 | // sign verify sign/s verify/s | ||
96 | // dsa 512 bits 0.0018s 0.0022s 547.3 459.6 | ||
97 | // dsa 1024 bits 0.0051s 0.0062s 196.6 161.3 | ||
98 | // | ||
99 | // Oh! Benchmarks were performed on 733MHz Lion-class Itanium | ||
100 | // system running Redhat Linux 7.1 (very special thanks to Ray | ||
101 | // McCaffity of Williams Communications for providing an account). | ||
102 | // | ||
103 | // Q. What's the heck with 'rum 1<<5' at the end of every function? | ||
104 | // A. Well, by clearing the "upper FP registers written" bit of the | ||
105 | // User Mask I want to excuse the kernel from preserving upper | ||
106 | // (f32-f128) FP register bank over process context switch, thus | ||
107 | // minimizing bus bandwidth consumption during the switch (i.e. | ||
108 | // after PKI opration completes and the program is off doing | ||
109 | // something else like bulk symmetric encryption). Having said | ||
110 | // this, I also want to point out that it might be good idea | ||
111 | // to compile the whole toolkit (as well as majority of the | ||
112 | // programs for that matter) with -mfixed-range=f32-f127 command | ||
113 | // line option. No, it doesn't prevent the compiler from writing | ||
114 | // to upper bank, but at least discourages to do so. If you don't | ||
115 | // like the idea you have the option to compile the module with | ||
116 | // -Drum=nop.m in command line. | ||
117 | // | ||
118 | |||
119 | #if 1 | ||
120 | // | ||
121 | // bn_[add|sub]_words routines. | ||
122 | // | ||
123 | // Loops are spinning in 2*(n+5) ticks on Itanuim (provided that the | ||
124 | // data reside in L1 cache, i.e. 2 ticks away). It's possible to | ||
125 | // compress the epilogue and get down to 2*n+6, but at the cost of | ||
126 | // scalability (the neat feature of this implementation is that it | ||
127 | // shall automagically spin in n+5 on "wider" IA-64 implementations:-) | ||
128 | // I consider that the epilogue is short enough as it is to trade tiny | ||
129 | // performance loss on Itanium for scalability. | ||
130 | // | ||
131 | // BN_ULONG bn_add_words(BN_ULONG *rp, BN_ULONG *ap, BN_ULONG *bp,int num) | ||
132 | // | ||
133 | .global bn_add_words# | ||
134 | .proc bn_add_words# | ||
135 | .align 64 | ||
136 | .skip 32 // makes the loop body aligned at 64-byte boundary | ||
137 | bn_add_words: | ||
138 | .prologue | ||
139 | .fframe 0 | ||
140 | .save ar.pfs,r2 | ||
141 | { .mii; alloc r2=ar.pfs,4,12,0,16 | ||
142 | cmp4.le p6,p0=r35,r0 };; | ||
143 | { .mfb; mov r8=r0 // return value | ||
144 | (p6) br.ret.spnt.many b0 };; | ||
145 | |||
146 | .save ar.lc,r3 | ||
147 | { .mib; sub r10=r35,r0,1 | ||
148 | mov r3=ar.lc | ||
149 | brp.loop.imp .L_bn_add_words_ctop,.L_bn_add_words_cend-16 | ||
150 | } | ||
151 | .body | ||
152 | { .mib; mov r14=r32 // rp | ||
153 | mov r9=pr };; | ||
154 | { .mii; mov r15=r33 // ap | ||
155 | mov ar.lc=r10 | ||
156 | mov ar.ec=6 } | ||
157 | { .mib; mov r16=r34 // bp | ||
158 | mov pr.rot=1<<16 };; | ||
159 | |||
160 | .L_bn_add_words_ctop: | ||
161 | { .mii; (p16) ld8 r32=[r16],8 // b=*(bp++) | ||
162 | (p18) add r39=r37,r34 | ||
163 | (p19) cmp.ltu.unc p56,p0=r40,r38 } | ||
164 | { .mfb; (p0) nop.m 0x0 | ||
165 | (p0) nop.f 0x0 | ||
166 | (p0) nop.b 0x0 } | ||
167 | { .mii; (p16) ld8 r35=[r15],8 // a=*(ap++) | ||
168 | (p58) cmp.eq.or p57,p0=-1,r41 // (p20) | ||
169 | (p58) add r41=1,r41 } // (p20) | ||
170 | { .mfb; (p21) st8 [r14]=r42,8 // *(rp++)=r | ||
171 | (p0) nop.f 0x0 | ||
172 | br.ctop.sptk .L_bn_add_words_ctop };; | ||
173 | .L_bn_add_words_cend: | ||
174 | |||
175 | { .mii; | ||
176 | (p59) add r8=1,r8 // return value | ||
177 | mov pr=r9,-1 | ||
178 | mov ar.lc=r3 } | ||
179 | { .mbb; nop.b 0x0 | ||
180 | br.ret.sptk.many b0 };; | ||
181 | .endp bn_add_words# | ||
182 | |||
183 | // | ||
184 | // BN_ULONG bn_sub_words(BN_ULONG *rp, BN_ULONG *ap, BN_ULONG *bp,int num) | ||
185 | // | ||
186 | .global bn_sub_words# | ||
187 | .proc bn_sub_words# | ||
188 | .align 64 | ||
189 | .skip 32 // makes the loop body aligned at 64-byte boundary | ||
190 | bn_sub_words: | ||
191 | .prologue | ||
192 | .fframe 0 | ||
193 | .save ar.pfs,r2 | ||
194 | { .mii; alloc r2=ar.pfs,4,12,0,16 | ||
195 | cmp4.le p6,p0=r35,r0 };; | ||
196 | { .mfb; mov r8=r0 // return value | ||
197 | (p6) br.ret.spnt.many b0 };; | ||
198 | |||
199 | .save ar.lc,r3 | ||
200 | { .mib; sub r10=r35,r0,1 | ||
201 | mov r3=ar.lc | ||
202 | brp.loop.imp .L_bn_sub_words_ctop,.L_bn_sub_words_cend-16 | ||
203 | } | ||
204 | .body | ||
205 | { .mib; mov r14=r32 // rp | ||
206 | mov r9=pr };; | ||
207 | { .mii; mov r15=r33 // ap | ||
208 | mov ar.lc=r10 | ||
209 | mov ar.ec=6 } | ||
210 | { .mib; mov r16=r34 // bp | ||
211 | mov pr.rot=1<<16 };; | ||
212 | |||
213 | .L_bn_sub_words_ctop: | ||
214 | { .mii; (p16) ld8 r32=[r16],8 // b=*(bp++) | ||
215 | (p18) sub r39=r37,r34 | ||
216 | (p19) cmp.gtu.unc p56,p0=r40,r38 } | ||
217 | { .mfb; (p0) nop.m 0x0 | ||
218 | (p0) nop.f 0x0 | ||
219 | (p0) nop.b 0x0 } | ||
220 | { .mii; (p16) ld8 r35=[r15],8 // a=*(ap++) | ||
221 | (p58) cmp.eq.or p57,p0=0,r41 // (p20) | ||
222 | (p58) add r41=-1,r41 } // (p20) | ||
223 | { .mbb; (p21) st8 [r14]=r42,8 // *(rp++)=r | ||
224 | (p0) nop.b 0x0 | ||
225 | br.ctop.sptk .L_bn_sub_words_ctop };; | ||
226 | .L_bn_sub_words_cend: | ||
227 | |||
228 | { .mii; | ||
229 | (p59) add r8=1,r8 // return value | ||
230 | mov pr=r9,-1 | ||
231 | mov ar.lc=r3 } | ||
232 | { .mbb; nop.b 0x0 | ||
233 | br.ret.sptk.many b0 };; | ||
234 | .endp bn_sub_words# | ||
235 | #endif | ||
236 | |||
237 | #if 0 | ||
238 | #define XMA_TEMPTATION | ||
239 | #endif | ||
240 | |||
241 | #if 1 | ||
242 | // | ||
243 | // BN_ULONG bn_mul_words(BN_ULONG *rp, BN_ULONG *ap, int num, BN_ULONG w) | ||
244 | // | ||
245 | .global bn_mul_words# | ||
246 | .proc bn_mul_words# | ||
247 | .align 64 | ||
248 | .skip 32 // makes the loop body aligned at 64-byte boundary | ||
249 | bn_mul_words: | ||
250 | .prologue | ||
251 | .fframe 0 | ||
252 | .save ar.pfs,r2 | ||
253 | #ifdef XMA_TEMPTATION | ||
254 | { .mfi; alloc r2=ar.pfs,4,0,0,0 };; | ||
255 | #else | ||
256 | { .mfi; alloc r2=ar.pfs,4,4,0,8 };; | ||
257 | #endif | ||
258 | { .mib; mov r8=r0 // return value | ||
259 | cmp4.le p6,p0=r34,r0 | ||
260 | (p6) br.ret.spnt.many b0 };; | ||
261 | |||
262 | .save ar.lc,r3 | ||
263 | { .mii; sub r10=r34,r0,1 | ||
264 | mov r3=ar.lc | ||
265 | mov r9=pr };; | ||
266 | |||
267 | .body | ||
268 | { .mib; setf.sig f8=r35 // w | ||
269 | mov pr.rot=0x400001<<16 | ||
270 | // ------^----- serves as (p48) at first (p26) | ||
271 | brp.loop.imp .L_bn_mul_words_ctop,.L_bn_mul_words_cend-16 | ||
272 | } | ||
273 | |||
274 | #ifndef XMA_TEMPTATION | ||
275 | |||
276 | { .mii; mov r14=r32 // rp | ||
277 | mov r15=r33 // ap | ||
278 | mov ar.lc=r10 } | ||
279 | { .mii; mov r39=0 // serves as r33 at first (p26) | ||
280 | mov ar.ec=12 };; | ||
281 | |||
282 | // This loop spins in 2*(n+11) ticks. It's scheduled for data in L2 | ||
283 | // cache (i.e. 9 ticks away) as floating point load/store instructions | ||
284 | // bypass L1 cache and L2 latency is actually best-case scenario for | ||
285 | // ldf8. The loop is not scalable and shall run in 2*(n+11) even on | ||
286 | // "wider" IA-64 implementations. It's a trade-off here. n+22 loop | ||
287 | // would give us ~5% in *overall* performance improvement on "wider" | ||
288 | // IA-64, but would hurt Itanium for about same because of longer | ||
289 | // epilogue. As it's a matter of few percents in either case I've | ||
290 | // chosen to trade the scalability for development time (you can see | ||
291 | // this very instruction sequence in bn_mul_add_words loop which in | ||
292 | // turn is scalable). | ||
293 | .L_bn_mul_words_ctop: | ||
294 | { .mfi; (p25) getf.sig r36=f49 // low | ||
295 | (p21) xmpy.lu f45=f37,f8 | ||
296 | (p27) cmp.ltu p52,p48=r39,r38 } | ||
297 | { .mfi; (p16) ldf8 f32=[r15],8 | ||
298 | (p21) xmpy.hu f38=f37,f8 | ||
299 | (p0) nop.i 0x0 };; | ||
300 | { .mii; (p26) getf.sig r32=f43 // high | ||
301 | .pred.rel "mutex",p48,p52 | ||
302 | (p48) add r38=r37,r33 // (p26) | ||
303 | (p52) add r38=r37,r33,1 } // (p26) | ||
304 | { .mfb; (p27) st8 [r14]=r39,8 | ||
305 | (p0) nop.f 0x0 | ||
306 | br.ctop.sptk .L_bn_mul_words_ctop };; | ||
307 | .L_bn_mul_words_cend: | ||
308 | |||
309 | { .mii; nop.m 0x0 | ||
310 | .pred.rel "mutex",p49,p53 | ||
311 | (p49) add r8=r34,r0 | ||
312 | (p53) add r8=r34,r0,1 } | ||
313 | { .mfb; nop.m 0x0 | ||
314 | nop.f 0x0 | ||
315 | nop.b 0x0 } | ||
316 | |||
317 | #else // XMA_TEMPTATION | ||
318 | |||
319 | setf.sig f37=r0 // serves as carry at (p18) tick | ||
320 | mov ar.lc=r10 | ||
321 | mov ar.ec=5;; | ||
322 | |||
323 | // Most of you examining this code very likely wonder why in the name | ||
324 | // of Intel the following loop is commented out? Indeed, it looks so | ||
325 | // neat that you find it hard to believe that it's something wrong | ||
326 | // with it, right? The catch is that every iteration depends on the | ||
327 | // result from previous one and the latter isn't available instantly. | ||
328 | // The loop therefore spins at the latency of xma minus 1, or in other | ||
329 | // words at 6*(n+4) ticks:-( Compare to the "production" loop above | ||
330 | // that runs in 2*(n+11) where the low latency problem is worked around | ||
331 | // by moving the dependency to one-tick latent interger ALU. Note that | ||
332 | // "distance" between ldf8 and xma is not latency of ldf8, but the | ||
333 | // *difference* between xma and ldf8 latencies. | ||
334 | .L_bn_mul_words_ctop: | ||
335 | { .mfi; (p16) ldf8 f32=[r33],8 | ||
336 | (p18) xma.hu f38=f34,f8,f39 } | ||
337 | { .mfb; (p20) stf8 [r32]=f37,8 | ||
338 | (p18) xma.lu f35=f34,f8,f39 | ||
339 | br.ctop.sptk .L_bn_mul_words_ctop };; | ||
340 | .L_bn_mul_words_cend: | ||
341 | |||
342 | getf.sig r8=f41 // the return value | ||
343 | |||
344 | #endif // XMA_TEMPTATION | ||
345 | |||
346 | { .mii; nop.m 0x0 | ||
347 | mov pr=r9,-1 | ||
348 | mov ar.lc=r3 } | ||
349 | { .mfb; rum 1<<5 // clear um.mfh | ||
350 | nop.f 0x0 | ||
351 | br.ret.sptk.many b0 };; | ||
352 | .endp bn_mul_words# | ||
353 | #endif | ||
354 | |||
355 | #if 1 | ||
356 | // | ||
357 | // BN_ULONG bn_mul_add_words(BN_ULONG *rp, BN_ULONG *ap, int num, BN_ULONG w) | ||
358 | // | ||
359 | .global bn_mul_add_words# | ||
360 | .proc bn_mul_add_words# | ||
361 | .align 64 | ||
362 | //.skip 0 // makes the loop split at 64-byte boundary | ||
363 | bn_mul_add_words: | ||
364 | .prologue | ||
365 | .fframe 0 | ||
366 | .save ar.pfs,r2 | ||
367 | { .mii; alloc r2=ar.pfs,4,12,0,16 | ||
368 | cmp4.le p6,p0=r34,r0 };; | ||
369 | { .mfb; mov r8=r0 // return value | ||
370 | (p6) br.ret.spnt.many b0 };; | ||
371 | |||
372 | .save ar.lc,r3 | ||
373 | { .mii; sub r10=r34,r0,1 | ||
374 | mov r3=ar.lc | ||
375 | mov r9=pr };; | ||
376 | |||
377 | .body | ||
378 | { .mib; setf.sig f8=r35 // w | ||
379 | mov pr.rot=0x400001<<16 | ||
380 | // ------^----- serves as (p48) at first (p26) | ||
381 | brp.loop.imp .L_bn_mul_add_words_ctop,.L_bn_mul_add_words_cend-16 | ||
382 | } | ||
383 | { .mii; mov r14=r32 // rp | ||
384 | mov r15=r33 // ap | ||
385 | mov ar.lc=r10 } | ||
386 | { .mii; mov r39=0 // serves as r33 at first (p26) | ||
387 | mov r18=r32 // rp copy | ||
388 | mov ar.ec=14 };; | ||
389 | |||
390 | // This loop spins in 3*(n+13) ticks on Itanium and should spin in | ||
391 | // 2*(n+13) on "wider" IA-64 implementations (to be verified with new | ||
392 | // µ-architecture manuals as they become available). As usual it's | ||
393 | // possible to compress the epilogue, down to 10 in this case, at the | ||
394 | // cost of scalability. Compressed (and therefore non-scalable) loop | ||
395 | // running at 3*(n+10) would buy you ~10% on Itanium but take ~35% | ||
396 | // from "wider" IA-64 so let it be scalable! Special attention was | ||
397 | // paid for having the loop body split at 64-byte boundary. ld8 is | ||
398 | // scheduled for L1 cache as the data is more than likely there. | ||
399 | // Indeed, bn_mul_words has put it there a moment ago:-) | ||
400 | .L_bn_mul_add_words_ctop: | ||
401 | { .mfi; (p25) getf.sig r36=f49 // low | ||
402 | (p21) xmpy.lu f45=f37,f8 | ||
403 | (p27) cmp.ltu p52,p48=r39,r38 } | ||
404 | { .mfi; (p16) ldf8 f32=[r15],8 | ||
405 | (p21) xmpy.hu f38=f37,f8 | ||
406 | (p27) add r43=r43,r39 };; | ||
407 | { .mii; (p26) getf.sig r32=f43 // high | ||
408 | .pred.rel "mutex",p48,p52 | ||
409 | (p48) add r38=r37,r33 // (p26) | ||
410 | (p52) add r38=r37,r33,1 } // (p26) | ||
411 | { .mfb; (p27) cmp.ltu.unc p56,p0=r43,r39 | ||
412 | (p0) nop.f 0x0 | ||
413 | (p0) nop.b 0x0 } | ||
414 | { .mii; (p26) ld8 r42=[r18],8 | ||
415 | (p58) cmp.eq.or p57,p0=-1,r44 | ||
416 | (p58) add r44=1,r44 } | ||
417 | { .mfb; (p29) st8 [r14]=r45,8 | ||
418 | (p0) nop.f 0x0 | ||
419 | br.ctop.sptk .L_bn_mul_add_words_ctop};; | ||
420 | .L_bn_mul_add_words_cend: | ||
421 | |||
422 | { .mii; nop.m 0x0 | ||
423 | .pred.rel "mutex",p51,p55 | ||
424 | (p51) add r8=r36,r0 | ||
425 | (p55) add r8=r36,r0,1 } | ||
426 | { .mfb; nop.m 0x0 | ||
427 | nop.f 0x0 | ||
428 | nop.b 0x0 };; | ||
429 | { .mii; | ||
430 | (p59) add r8=1,r8 | ||
431 | mov pr=r9,-1 | ||
432 | mov ar.lc=r3 } | ||
433 | { .mfb; rum 1<<5 // clear um.mfh | ||
434 | nop.f 0x0 | ||
435 | br.ret.sptk.many b0 };; | ||
436 | .endp bn_mul_add_words# | ||
437 | #endif | ||
438 | |||
439 | #if 1 | ||
440 | // | ||
441 | // void bn_sqr_words(BN_ULONG *rp, BN_ULONG *ap, int num) | ||
442 | // | ||
443 | .global bn_sqr_words# | ||
444 | .proc bn_sqr_words# | ||
445 | .align 64 | ||
446 | .skip 32 // makes the loop body aligned at 64-byte boundary | ||
447 | bn_sqr_words: | ||
448 | .prologue | ||
449 | .fframe 0 | ||
450 | .save ar.pfs,r2 | ||
451 | { .mii; alloc r2=ar.pfs,3,0,0,0 | ||
452 | sxt4 r34=r34 };; | ||
453 | { .mii; cmp.le p6,p0=r34,r0 | ||
454 | mov r8=r0 } // return value | ||
455 | { .mfb; nop.f 0x0 | ||
456 | (p6) br.ret.spnt.many b0 };; | ||
457 | |||
458 | .save ar.lc,r3 | ||
459 | { .mii; sub r10=r34,r0,1 | ||
460 | mov r3=ar.lc | ||
461 | mov r9=pr };; | ||
462 | |||
463 | .body | ||
464 | { .mib; | ||
465 | mov pr.rot=1<<16 | ||
466 | brp.loop.imp .L_bn_sqr_words_ctop,.L_bn_sqr_words_cend-16 | ||
467 | } | ||
468 | { .mii; add r34=8,r32 | ||
469 | mov ar.lc=r10 | ||
470 | mov ar.ec=18 };; | ||
471 | |||
472 | // 2*(n+17) on Itanium, (n+17) on "wider" IA-64 implementations. It's | ||
473 | // possible to compress the epilogue (I'm getting tired to write this | ||
474 | // comment over and over) and get down to 2*n+16 at the cost of | ||
475 | // scalability. The decision will very likely be reconsidered after the | ||
476 | // benchmark program is profiled. I.e. if perfomance gain on Itanium | ||
477 | // will appear larger than loss on "wider" IA-64, then the loop should | ||
478 | // be explicitely split and the epilogue compressed. | ||
479 | .L_bn_sqr_words_ctop: | ||
480 | { .mfi; (p16) ldf8 f32=[r33],8 | ||
481 | (p25) xmpy.lu f42=f41,f41 | ||
482 | (p0) nop.i 0x0 } | ||
483 | { .mib; (p33) stf8 [r32]=f50,16 | ||
484 | (p0) nop.i 0x0 | ||
485 | (p0) nop.b 0x0 } | ||
486 | { .mfi; (p0) nop.m 0x0 | ||
487 | (p25) xmpy.hu f52=f41,f41 | ||
488 | (p0) nop.i 0x0 } | ||
489 | { .mib; (p33) stf8 [r34]=f60,16 | ||
490 | (p0) nop.i 0x0 | ||
491 | br.ctop.sptk .L_bn_sqr_words_ctop };; | ||
492 | .L_bn_sqr_words_cend: | ||
493 | |||
494 | { .mii; nop.m 0x0 | ||
495 | mov pr=r9,-1 | ||
496 | mov ar.lc=r3 } | ||
497 | { .mfb; rum 1<<5 // clear um.mfh | ||
498 | nop.f 0x0 | ||
499 | br.ret.sptk.many b0 };; | ||
500 | .endp bn_sqr_words# | ||
501 | #endif | ||
502 | |||
503 | #if 1 | ||
504 | // Apparently we win nothing by implementing special bn_sqr_comba8. | ||
505 | // Yes, it is possible to reduce the number of multiplications by | ||
506 | // almost factor of two, but then the amount of additions would | ||
507 | // increase by factor of two (as we would have to perform those | ||
508 | // otherwise performed by xma ourselves). Normally we would trade | ||
509 | // anyway as multiplications are way more expensive, but not this | ||
510 | // time... Multiplication kernel is fully pipelined and as we drain | ||
511 | // one 128-bit multiplication result per clock cycle multiplications | ||
512 | // are effectively as inexpensive as additions. Special implementation | ||
513 | // might become of interest for "wider" IA-64 implementation as you'll | ||
514 | // be able to get through the multiplication phase faster (there won't | ||
515 | // be any stall issues as discussed in the commentary section below and | ||
516 | // you therefore will be able to employ all 4 FP units)... But these | ||
517 | // Itanium days it's simply too hard to justify the effort so I just | ||
518 | // drop down to bn_mul_comba8 code:-) | ||
519 | // | ||
520 | // void bn_sqr_comba8(BN_ULONG *r, BN_ULONG *a) | ||
521 | // | ||
522 | .global bn_sqr_comba8# | ||
523 | .proc bn_sqr_comba8# | ||
524 | .align 64 | ||
525 | bn_sqr_comba8: | ||
526 | .prologue | ||
527 | .fframe 0 | ||
528 | .save ar.pfs,r2 | ||
529 | { .mii; alloc r2=ar.pfs,2,1,0,0 | ||
530 | mov r34=r33 | ||
531 | add r14=8,r33 };; | ||
532 | .body | ||
533 | { .mii; add r17=8,r34 | ||
534 | add r15=16,r33 | ||
535 | add r18=16,r34 } | ||
536 | { .mfb; add r16=24,r33 | ||
537 | br .L_cheat_entry_point8 };; | ||
538 | .endp bn_sqr_comba8# | ||
539 | #endif | ||
540 | |||
541 | #if 1 | ||
542 | // I've estimated this routine to run in ~120 ticks, but in reality | ||
543 | // (i.e. according to ar.itc) it takes ~160 ticks. Are those extra | ||
544 | // cycles consumed for instructions fetch? Or did I misinterpret some | ||
545 | // clause in Itanium µ-architecture manual? Comments are welcomed and | ||
546 | // highly appreciated. | ||
547 | // | ||
548 | // However! It should be noted that even 160 ticks is darn good result | ||
549 | // as it's over 10 (yes, ten, spelled as t-e-n) times faster than the | ||
550 | // C version (compiled with gcc with inline assembler). I really | ||
551 | // kicked compiler's butt here, didn't I? Yeah! This brings us to the | ||
552 | // following statement. It's damn shame that this routine isn't called | ||
553 | // very often nowadays! According to the profiler most CPU time is | ||
554 | // consumed by bn_mul_add_words called from BN_from_montgomery. In | ||
555 | // order to estimate what we're missing, I've compared the performance | ||
556 | // of this routine against "traditional" implementation, i.e. against | ||
557 | // following routine: | ||
558 | // | ||
559 | // void bn_mul_comba8(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b) | ||
560 | // { r[ 8]=bn_mul_words( &(r[0]),a,8,b[0]); | ||
561 | // r[ 9]=bn_mul_add_words(&(r[1]),a,8,b[1]); | ||
562 | // r[10]=bn_mul_add_words(&(r[2]),a,8,b[2]); | ||
563 | // r[11]=bn_mul_add_words(&(r[3]),a,8,b[3]); | ||
564 | // r[12]=bn_mul_add_words(&(r[4]),a,8,b[4]); | ||
565 | // r[13]=bn_mul_add_words(&(r[5]),a,8,b[5]); | ||
566 | // r[14]=bn_mul_add_words(&(r[6]),a,8,b[6]); | ||
567 | // r[15]=bn_mul_add_words(&(r[7]),a,8,b[7]); | ||
568 | // } | ||
569 | // | ||
570 | // The one below is over 8 times faster than the one above:-( Even | ||
571 | // more reasons to "combafy" bn_mul_add_mont... | ||
572 | // | ||
573 | // And yes, this routine really made me wish there were an optimizing | ||
574 | // assembler! It also feels like it deserves a dedication. | ||
575 | // | ||
576 | // To my wife for being there and to my kids... | ||
577 | // | ||
578 | // void bn_mul_comba8(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b) | ||
579 | // | ||
580 | #define carry1 r14 | ||
581 | #define carry2 r15 | ||
582 | #define carry3 r34 | ||
583 | .global bn_mul_comba8# | ||
584 | .proc bn_mul_comba8# | ||
585 | .align 64 | ||
586 | bn_mul_comba8: | ||
587 | .prologue | ||
588 | .fframe 0 | ||
589 | .save ar.pfs,r2 | ||
590 | { .mii; alloc r2=ar.pfs,3,0,0,0 | ||
591 | add r14=8,r33 | ||
592 | add r17=8,r34 } | ||
593 | .body | ||
594 | { .mii; add r15=16,r33 | ||
595 | add r18=16,r34 | ||
596 | add r16=24,r33 } | ||
597 | .L_cheat_entry_point8: | ||
598 | { .mmi; add r19=24,r34 | ||
599 | |||
600 | ldf8 f32=[r33],32 };; | ||
601 | |||
602 | { .mmi; ldf8 f120=[r34],32 | ||
603 | ldf8 f121=[r17],32 } | ||
604 | { .mmi; ldf8 f122=[r18],32 | ||
605 | ldf8 f123=[r19],32 };; | ||
606 | { .mmi; ldf8 f124=[r34] | ||
607 | ldf8 f125=[r17] } | ||
608 | { .mmi; ldf8 f126=[r18] | ||
609 | ldf8 f127=[r19] } | ||
610 | |||
611 | { .mmi; ldf8 f33=[r14],32 | ||
612 | ldf8 f34=[r15],32 } | ||
613 | { .mmi; ldf8 f35=[r16],32;; | ||
614 | ldf8 f36=[r33] } | ||
615 | { .mmi; ldf8 f37=[r14] | ||
616 | ldf8 f38=[r15] } | ||
617 | { .mfi; ldf8 f39=[r16] | ||
618 | // -------\ Entering multiplier's heaven /------- | ||
619 | // ------------\ /------------ | ||
620 | // -----------------\ /----------------- | ||
621 | // ----------------------\/---------------------- | ||
622 | xma.hu f41=f32,f120,f0 } | ||
623 | { .mfi; xma.lu f40=f32,f120,f0 };; // (*) | ||
624 | { .mfi; xma.hu f51=f32,f121,f0 } | ||
625 | { .mfi; xma.lu f50=f32,f121,f0 };; | ||
626 | { .mfi; xma.hu f61=f32,f122,f0 } | ||
627 | { .mfi; xma.lu f60=f32,f122,f0 };; | ||
628 | { .mfi; xma.hu f71=f32,f123,f0 } | ||
629 | { .mfi; xma.lu f70=f32,f123,f0 };; | ||
630 | { .mfi; xma.hu f81=f32,f124,f0 } | ||
631 | { .mfi; xma.lu f80=f32,f124,f0 };; | ||
632 | { .mfi; xma.hu f91=f32,f125,f0 } | ||
633 | { .mfi; xma.lu f90=f32,f125,f0 };; | ||
634 | { .mfi; xma.hu f101=f32,f126,f0 } | ||
635 | { .mfi; xma.lu f100=f32,f126,f0 };; | ||
636 | { .mfi; xma.hu f111=f32,f127,f0 } | ||
637 | { .mfi; xma.lu f110=f32,f127,f0 };;// | ||
638 | // (*) You can argue that splitting at every second bundle would | ||
639 | // prevent "wider" IA-64 implementations from achieving the peak | ||
640 | // performance. Well, not really... The catch is that if you | ||
641 | // intend to keep 4 FP units busy by splitting at every fourth | ||
642 | // bundle and thus perform these 16 multiplications in 4 ticks, | ||
643 | // the first bundle *below* would stall because the result from | ||
644 | // the first xma bundle *above* won't be available for another 3 | ||
645 | // ticks (if not more, being an optimist, I assume that "wider" | ||
646 | // implementation will have same latency:-). This stall will hold | ||
647 | // you back and the performance would be as if every second bundle | ||
648 | // were split *anyway*... | ||
649 | { .mfi; getf.sig r16=f40 | ||
650 | xma.hu f42=f33,f120,f41 | ||
651 | add r33=8,r32 } | ||
652 | { .mfi; xma.lu f41=f33,f120,f41 };; | ||
653 | { .mfi; getf.sig r24=f50 | ||
654 | xma.hu f52=f33,f121,f51 } | ||
655 | { .mfi; xma.lu f51=f33,f121,f51 };; | ||
656 | { .mfi; st8 [r32]=r16,16 | ||
657 | xma.hu f62=f33,f122,f61 } | ||
658 | { .mfi; xma.lu f61=f33,f122,f61 };; | ||
659 | { .mfi; xma.hu f72=f33,f123,f71 } | ||
660 | { .mfi; xma.lu f71=f33,f123,f71 };; | ||
661 | { .mfi; xma.hu f82=f33,f124,f81 } | ||
662 | { .mfi; xma.lu f81=f33,f124,f81 };; | ||
663 | { .mfi; xma.hu f92=f33,f125,f91 } | ||
664 | { .mfi; xma.lu f91=f33,f125,f91 };; | ||
665 | { .mfi; xma.hu f102=f33,f126,f101 } | ||
666 | { .mfi; xma.lu f101=f33,f126,f101 };; | ||
667 | { .mfi; xma.hu f112=f33,f127,f111 } | ||
668 | { .mfi; xma.lu f111=f33,f127,f111 };;// | ||
669 | //-------------------------------------------------// | ||
670 | { .mfi; getf.sig r25=f41 | ||
671 | xma.hu f43=f34,f120,f42 } | ||
672 | { .mfi; xma.lu f42=f34,f120,f42 };; | ||
673 | { .mfi; getf.sig r16=f60 | ||
674 | xma.hu f53=f34,f121,f52 } | ||
675 | { .mfi; xma.lu f52=f34,f121,f52 };; | ||
676 | { .mfi; getf.sig r17=f51 | ||
677 | xma.hu f63=f34,f122,f62 | ||
678 | add r25=r25,r24 } | ||
679 | { .mfi; xma.lu f62=f34,f122,f62 | ||
680 | mov carry1=0 };; | ||
681 | { .mfi; cmp.ltu p6,p0=r25,r24 | ||
682 | xma.hu f73=f34,f123,f72 } | ||
683 | { .mfi; xma.lu f72=f34,f123,f72 };; | ||
684 | { .mfi; st8 [r33]=r25,16 | ||
685 | xma.hu f83=f34,f124,f82 | ||
686 | (p6) add carry1=1,carry1 } | ||
687 | { .mfi; xma.lu f82=f34,f124,f82 };; | ||
688 | { .mfi; xma.hu f93=f34,f125,f92 } | ||
689 | { .mfi; xma.lu f92=f34,f125,f92 };; | ||
690 | { .mfi; xma.hu f103=f34,f126,f102 } | ||
691 | { .mfi; xma.lu f102=f34,f126,f102 };; | ||
692 | { .mfi; xma.hu f113=f34,f127,f112 } | ||
693 | { .mfi; xma.lu f112=f34,f127,f112 };;// | ||
694 | //-------------------------------------------------// | ||
695 | { .mfi; getf.sig r18=f42 | ||
696 | xma.hu f44=f35,f120,f43 | ||
697 | add r17=r17,r16 } | ||
698 | { .mfi; xma.lu f43=f35,f120,f43 };; | ||
699 | { .mfi; getf.sig r24=f70 | ||
700 | xma.hu f54=f35,f121,f53 } | ||
701 | { .mfi; mov carry2=0 | ||
702 | xma.lu f53=f35,f121,f53 };; | ||
703 | { .mfi; getf.sig r25=f61 | ||
704 | xma.hu f64=f35,f122,f63 | ||
705 | cmp.ltu p7,p0=r17,r16 } | ||
706 | { .mfi; add r18=r18,r17 | ||
707 | xma.lu f63=f35,f122,f63 };; | ||
708 | { .mfi; getf.sig r26=f52 | ||
709 | xma.hu f74=f35,f123,f73 | ||
710 | (p7) add carry2=1,carry2 } | ||
711 | { .mfi; cmp.ltu p7,p0=r18,r17 | ||
712 | xma.lu f73=f35,f123,f73 | ||
713 | add r18=r18,carry1 };; | ||
714 | { .mfi; | ||
715 | xma.hu f84=f35,f124,f83 | ||
716 | (p7) add carry2=1,carry2 } | ||
717 | { .mfi; cmp.ltu p7,p0=r18,carry1 | ||
718 | xma.lu f83=f35,f124,f83 };; | ||
719 | { .mfi; st8 [r32]=r18,16 | ||
720 | xma.hu f94=f35,f125,f93 | ||
721 | (p7) add carry2=1,carry2 } | ||
722 | { .mfi; xma.lu f93=f35,f125,f93 };; | ||
723 | { .mfi; xma.hu f104=f35,f126,f103 } | ||
724 | { .mfi; xma.lu f103=f35,f126,f103 };; | ||
725 | { .mfi; xma.hu f114=f35,f127,f113 } | ||
726 | { .mfi; mov carry1=0 | ||
727 | xma.lu f113=f35,f127,f113 | ||
728 | add r25=r25,r24 };;// | ||
729 | //-------------------------------------------------// | ||
730 | { .mfi; getf.sig r27=f43 | ||
731 | xma.hu f45=f36,f120,f44 | ||
732 | cmp.ltu p6,p0=r25,r24 } | ||
733 | { .mfi; xma.lu f44=f36,f120,f44 | ||
734 | add r26=r26,r25 };; | ||
735 | { .mfi; getf.sig r16=f80 | ||
736 | xma.hu f55=f36,f121,f54 | ||
737 | (p6) add carry1=1,carry1 } | ||
738 | { .mfi; xma.lu f54=f36,f121,f54 };; | ||
739 | { .mfi; getf.sig r17=f71 | ||
740 | xma.hu f65=f36,f122,f64 | ||
741 | cmp.ltu p6,p0=r26,r25 } | ||
742 | { .mfi; xma.lu f64=f36,f122,f64 | ||
743 | add r27=r27,r26 };; | ||
744 | { .mfi; getf.sig r18=f62 | ||
745 | xma.hu f75=f36,f123,f74 | ||
746 | (p6) add carry1=1,carry1 } | ||
747 | { .mfi; cmp.ltu p6,p0=r27,r26 | ||
748 | xma.lu f74=f36,f123,f74 | ||
749 | add r27=r27,carry2 };; | ||
750 | { .mfi; getf.sig r19=f53 | ||
751 | xma.hu f85=f36,f124,f84 | ||
752 | (p6) add carry1=1,carry1 } | ||
753 | { .mfi; xma.lu f84=f36,f124,f84 | ||
754 | cmp.ltu p6,p0=r27,carry2 };; | ||
755 | { .mfi; st8 [r33]=r27,16 | ||
756 | xma.hu f95=f36,f125,f94 | ||
757 | (p6) add carry1=1,carry1 } | ||
758 | { .mfi; xma.lu f94=f36,f125,f94 };; | ||
759 | { .mfi; xma.hu f105=f36,f126,f104 } | ||
760 | { .mfi; mov carry2=0 | ||
761 | xma.lu f104=f36,f126,f104 | ||
762 | add r17=r17,r16 };; | ||
763 | { .mfi; xma.hu f115=f36,f127,f114 | ||
764 | cmp.ltu p7,p0=r17,r16 } | ||
765 | { .mfi; xma.lu f114=f36,f127,f114 | ||
766 | add r18=r18,r17 };;// | ||
767 | //-------------------------------------------------// | ||
768 | { .mfi; getf.sig r20=f44 | ||
769 | xma.hu f46=f37,f120,f45 | ||
770 | (p7) add carry2=1,carry2 } | ||
771 | { .mfi; cmp.ltu p7,p0=r18,r17 | ||
772 | xma.lu f45=f37,f120,f45 | ||
773 | add r19=r19,r18 };; | ||
774 | { .mfi; getf.sig r24=f90 | ||
775 | xma.hu f56=f37,f121,f55 } | ||
776 | { .mfi; xma.lu f55=f37,f121,f55 };; | ||
777 | { .mfi; getf.sig r25=f81 | ||
778 | xma.hu f66=f37,f122,f65 | ||
779 | (p7) add carry2=1,carry2 } | ||
780 | { .mfi; cmp.ltu p7,p0=r19,r18 | ||
781 | xma.lu f65=f37,f122,f65 | ||
782 | add r20=r20,r19 };; | ||
783 | { .mfi; getf.sig r26=f72 | ||
784 | xma.hu f76=f37,f123,f75 | ||
785 | (p7) add carry2=1,carry2 } | ||
786 | { .mfi; cmp.ltu p7,p0=r20,r19 | ||
787 | xma.lu f75=f37,f123,f75 | ||
788 | add r20=r20,carry1 };; | ||
789 | { .mfi; getf.sig r27=f63 | ||
790 | xma.hu f86=f37,f124,f85 | ||
791 | (p7) add carry2=1,carry2 } | ||
792 | { .mfi; xma.lu f85=f37,f124,f85 | ||
793 | cmp.ltu p7,p0=r20,carry1 };; | ||
794 | { .mfi; getf.sig r28=f54 | ||
795 | xma.hu f96=f37,f125,f95 | ||
796 | (p7) add carry2=1,carry2 } | ||
797 | { .mfi; st8 [r32]=r20,16 | ||
798 | xma.lu f95=f37,f125,f95 };; | ||
799 | { .mfi; xma.hu f106=f37,f126,f105 } | ||
800 | { .mfi; mov carry1=0 | ||
801 | xma.lu f105=f37,f126,f105 | ||
802 | add r25=r25,r24 };; | ||
803 | { .mfi; xma.hu f116=f37,f127,f115 | ||
804 | cmp.ltu p6,p0=r25,r24 } | ||
805 | { .mfi; xma.lu f115=f37,f127,f115 | ||
806 | add r26=r26,r25 };;// | ||
807 | //-------------------------------------------------// | ||
808 | { .mfi; getf.sig r29=f45 | ||
809 | xma.hu f47=f38,f120,f46 | ||
810 | (p6) add carry1=1,carry1 } | ||
811 | { .mfi; cmp.ltu p6,p0=r26,r25 | ||
812 | xma.lu f46=f38,f120,f46 | ||
813 | add r27=r27,r26 };; | ||
814 | { .mfi; getf.sig r16=f100 | ||
815 | xma.hu f57=f38,f121,f56 | ||
816 | (p6) add carry1=1,carry1 } | ||
817 | { .mfi; cmp.ltu p6,p0=r27,r26 | ||
818 | xma.lu f56=f38,f121,f56 | ||
819 | add r28=r28,r27 };; | ||
820 | { .mfi; getf.sig r17=f91 | ||
821 | xma.hu f67=f38,f122,f66 | ||
822 | (p6) add carry1=1,carry1 } | ||
823 | { .mfi; cmp.ltu p6,p0=r28,r27 | ||
824 | xma.lu f66=f38,f122,f66 | ||
825 | add r29=r29,r28 };; | ||
826 | { .mfi; getf.sig r18=f82 | ||
827 | xma.hu f77=f38,f123,f76 | ||
828 | (p6) add carry1=1,carry1 } | ||
829 | { .mfi; cmp.ltu p6,p0=r29,r28 | ||
830 | xma.lu f76=f38,f123,f76 | ||
831 | add r29=r29,carry2 };; | ||
832 | { .mfi; getf.sig r19=f73 | ||
833 | xma.hu f87=f38,f124,f86 | ||
834 | (p6) add carry1=1,carry1 } | ||
835 | { .mfi; xma.lu f86=f38,f124,f86 | ||
836 | cmp.ltu p6,p0=r29,carry2 };; | ||
837 | { .mfi; getf.sig r20=f64 | ||
838 | xma.hu f97=f38,f125,f96 | ||
839 | (p6) add carry1=1,carry1 } | ||
840 | { .mfi; st8 [r33]=r29,16 | ||
841 | xma.lu f96=f38,f125,f96 };; | ||
842 | { .mfi; getf.sig r21=f55 | ||
843 | xma.hu f107=f38,f126,f106 } | ||
844 | { .mfi; mov carry2=0 | ||
845 | xma.lu f106=f38,f126,f106 | ||
846 | add r17=r17,r16 };; | ||
847 | { .mfi; xma.hu f117=f38,f127,f116 | ||
848 | cmp.ltu p7,p0=r17,r16 } | ||
849 | { .mfi; xma.lu f116=f38,f127,f116 | ||
850 | add r18=r18,r17 };;// | ||
851 | //-------------------------------------------------// | ||
852 | { .mfi; getf.sig r22=f46 | ||
853 | xma.hu f48=f39,f120,f47 | ||
854 | (p7) add carry2=1,carry2 } | ||
855 | { .mfi; cmp.ltu p7,p0=r18,r17 | ||
856 | xma.lu f47=f39,f120,f47 | ||
857 | add r19=r19,r18 };; | ||
858 | { .mfi; getf.sig r24=f110 | ||
859 | xma.hu f58=f39,f121,f57 | ||
860 | (p7) add carry2=1,carry2 } | ||
861 | { .mfi; cmp.ltu p7,p0=r19,r18 | ||
862 | xma.lu f57=f39,f121,f57 | ||
863 | add r20=r20,r19 };; | ||
864 | { .mfi; getf.sig r25=f101 | ||
865 | xma.hu f68=f39,f122,f67 | ||
866 | (p7) add carry2=1,carry2 } | ||
867 | { .mfi; cmp.ltu p7,p0=r20,r19 | ||
868 | xma.lu f67=f39,f122,f67 | ||
869 | add r21=r21,r20 };; | ||
870 | { .mfi; getf.sig r26=f92 | ||
871 | xma.hu f78=f39,f123,f77 | ||
872 | (p7) add carry2=1,carry2 } | ||
873 | { .mfi; cmp.ltu p7,p0=r21,r20 | ||
874 | xma.lu f77=f39,f123,f77 | ||
875 | add r22=r22,r21 };; | ||
876 | { .mfi; getf.sig r27=f83 | ||
877 | xma.hu f88=f39,f124,f87 | ||
878 | (p7) add carry2=1,carry2 } | ||
879 | { .mfi; cmp.ltu p7,p0=r22,r21 | ||
880 | xma.lu f87=f39,f124,f87 | ||
881 | add r22=r22,carry1 };; | ||
882 | { .mfi; getf.sig r28=f74 | ||
883 | xma.hu f98=f39,f125,f97 | ||
884 | (p7) add carry2=1,carry2 } | ||
885 | { .mfi; xma.lu f97=f39,f125,f97 | ||
886 | cmp.ltu p7,p0=r22,carry1 };; | ||
887 | { .mfi; getf.sig r29=f65 | ||
888 | xma.hu f108=f39,f126,f107 | ||
889 | (p7) add carry2=1,carry2 } | ||
890 | { .mfi; st8 [r32]=r22,16 | ||
891 | xma.lu f107=f39,f126,f107 };; | ||
892 | { .mfi; getf.sig r30=f56 | ||
893 | xma.hu f118=f39,f127,f117 } | ||
894 | { .mfi; xma.lu f117=f39,f127,f117 };;// | ||
895 | //-------------------------------------------------// | ||
896 | // Leaving muliplier's heaven... Quite a ride, huh? | ||
897 | |||
898 | { .mii; getf.sig r31=f47 | ||
899 | add r25=r25,r24 | ||
900 | mov carry1=0 };; | ||
901 | { .mii; getf.sig r16=f111 | ||
902 | cmp.ltu p6,p0=r25,r24 | ||
903 | add r26=r26,r25 };; | ||
904 | { .mfb; getf.sig r17=f102 } | ||
905 | { .mii; | ||
906 | (p6) add carry1=1,carry1 | ||
907 | cmp.ltu p6,p0=r26,r25 | ||
908 | add r27=r27,r26 };; | ||
909 | { .mfb; nop.m 0x0 } | ||
910 | { .mii; | ||
911 | (p6) add carry1=1,carry1 | ||
912 | cmp.ltu p6,p0=r27,r26 | ||
913 | add r28=r28,r27 };; | ||
914 | { .mii; getf.sig r18=f93 | ||
915 | add r17=r17,r16 | ||
916 | mov carry3=0 } | ||
917 | { .mii; | ||
918 | (p6) add carry1=1,carry1 | ||
919 | cmp.ltu p6,p0=r28,r27 | ||
920 | add r29=r29,r28 };; | ||
921 | { .mii; getf.sig r19=f84 | ||
922 | cmp.ltu p7,p0=r17,r16 } | ||
923 | { .mii; | ||
924 | (p6) add carry1=1,carry1 | ||
925 | cmp.ltu p6,p0=r29,r28 | ||
926 | add r30=r30,r29 };; | ||
927 | { .mii; getf.sig r20=f75 | ||
928 | add r18=r18,r17 } | ||
929 | { .mii; | ||
930 | (p6) add carry1=1,carry1 | ||
931 | cmp.ltu p6,p0=r30,r29 | ||
932 | add r31=r31,r30 };; | ||
933 | { .mfb; getf.sig r21=f66 } | ||
934 | { .mii; (p7) add carry3=1,carry3 | ||
935 | cmp.ltu p7,p0=r18,r17 | ||
936 | add r19=r19,r18 } | ||
937 | { .mfb; nop.m 0x0 } | ||
938 | { .mii; | ||
939 | (p6) add carry1=1,carry1 | ||
940 | cmp.ltu p6,p0=r31,r30 | ||
941 | add r31=r31,carry2 };; | ||
942 | { .mfb; getf.sig r22=f57 } | ||
943 | { .mii; (p7) add carry3=1,carry3 | ||
944 | cmp.ltu p7,p0=r19,r18 | ||
945 | add r20=r20,r19 } | ||
946 | { .mfb; nop.m 0x0 } | ||
947 | { .mii; | ||
948 | (p6) add carry1=1,carry1 | ||
949 | cmp.ltu p6,p0=r31,carry2 };; | ||
950 | { .mfb; getf.sig r23=f48 } | ||
951 | { .mii; (p7) add carry3=1,carry3 | ||
952 | cmp.ltu p7,p0=r20,r19 | ||
953 | add r21=r21,r20 } | ||
954 | { .mii; | ||
955 | (p6) add carry1=1,carry1 } | ||
956 | { .mfb; st8 [r33]=r31,16 };; | ||
957 | |||
958 | { .mfb; getf.sig r24=f112 } | ||
959 | { .mii; (p7) add carry3=1,carry3 | ||
960 | cmp.ltu p7,p0=r21,r20 | ||
961 | add r22=r22,r21 };; | ||
962 | { .mfb; getf.sig r25=f103 } | ||
963 | { .mii; (p7) add carry3=1,carry3 | ||
964 | cmp.ltu p7,p0=r22,r21 | ||
965 | add r23=r23,r22 };; | ||
966 | { .mfb; getf.sig r26=f94 } | ||
967 | { .mii; (p7) add carry3=1,carry3 | ||
968 | cmp.ltu p7,p0=r23,r22 | ||
969 | add r23=r23,carry1 };; | ||
970 | { .mfb; getf.sig r27=f85 } | ||
971 | { .mii; (p7) add carry3=1,carry3 | ||
972 | cmp.ltu p7,p8=r23,carry1};; | ||
973 | { .mii; getf.sig r28=f76 | ||
974 | add r25=r25,r24 | ||
975 | mov carry1=0 } | ||
976 | { .mii; st8 [r32]=r23,16 | ||
977 | (p7) add carry2=1,carry3 | ||
978 | (p8) add carry2=0,carry3 };; | ||
979 | |||
980 | { .mfb; nop.m 0x0 } | ||
981 | { .mii; getf.sig r29=f67 | ||
982 | cmp.ltu p6,p0=r25,r24 | ||
983 | add r26=r26,r25 };; | ||
984 | { .mfb; getf.sig r30=f58 } | ||
985 | { .mii; | ||
986 | (p6) add carry1=1,carry1 | ||
987 | cmp.ltu p6,p0=r26,r25 | ||
988 | add r27=r27,r26 };; | ||
989 | { .mfb; getf.sig r16=f113 } | ||
990 | { .mii; | ||
991 | (p6) add carry1=1,carry1 | ||
992 | cmp.ltu p6,p0=r27,r26 | ||
993 | add r28=r28,r27 };; | ||
994 | { .mfb; getf.sig r17=f104 } | ||
995 | { .mii; | ||
996 | (p6) add carry1=1,carry1 | ||
997 | cmp.ltu p6,p0=r28,r27 | ||
998 | add r29=r29,r28 };; | ||
999 | { .mfb; getf.sig r18=f95 } | ||
1000 | { .mii; | ||
1001 | (p6) add carry1=1,carry1 | ||
1002 | cmp.ltu p6,p0=r29,r28 | ||
1003 | add r30=r30,r29 };; | ||
1004 | { .mii; getf.sig r19=f86 | ||
1005 | add r17=r17,r16 | ||
1006 | mov carry3=0 } | ||
1007 | { .mii; | ||
1008 | (p6) add carry1=1,carry1 | ||
1009 | cmp.ltu p6,p0=r30,r29 | ||
1010 | add r30=r30,carry2 };; | ||
1011 | { .mii; getf.sig r20=f77 | ||
1012 | cmp.ltu p7,p0=r17,r16 | ||
1013 | add r18=r18,r17 } | ||
1014 | { .mii; | ||
1015 | (p6) add carry1=1,carry1 | ||
1016 | cmp.ltu p6,p0=r30,carry2 };; | ||
1017 | { .mfb; getf.sig r21=f68 } | ||
1018 | { .mii; st8 [r33]=r30,16 | ||
1019 | (p6) add carry1=1,carry1 };; | ||
1020 | |||
1021 | { .mfb; getf.sig r24=f114 } | ||
1022 | { .mii; (p7) add carry3=1,carry3 | ||
1023 | cmp.ltu p7,p0=r18,r17 | ||
1024 | add r19=r19,r18 };; | ||
1025 | { .mfb; getf.sig r25=f105 } | ||
1026 | { .mii; (p7) add carry3=1,carry3 | ||
1027 | cmp.ltu p7,p0=r19,r18 | ||
1028 | add r20=r20,r19 };; | ||
1029 | { .mfb; getf.sig r26=f96 } | ||
1030 | { .mii; (p7) add carry3=1,carry3 | ||
1031 | cmp.ltu p7,p0=r20,r19 | ||
1032 | add r21=r21,r20 };; | ||
1033 | { .mfb; getf.sig r27=f87 } | ||
1034 | { .mii; (p7) add carry3=1,carry3 | ||
1035 | cmp.ltu p7,p0=r21,r20 | ||
1036 | add r21=r21,carry1 };; | ||
1037 | { .mib; getf.sig r28=f78 | ||
1038 | add r25=r25,r24 } | ||
1039 | { .mib; (p7) add carry3=1,carry3 | ||
1040 | cmp.ltu p7,p8=r21,carry1};; | ||
1041 | { .mii; st8 [r32]=r21,16 | ||
1042 | (p7) add carry2=1,carry3 | ||
1043 | (p8) add carry2=0,carry3 } | ||
1044 | |||
1045 | { .mii; mov carry1=0 | ||
1046 | cmp.ltu p6,p0=r25,r24 | ||
1047 | add r26=r26,r25 };; | ||
1048 | { .mfb; getf.sig r16=f115 } | ||
1049 | { .mii; | ||
1050 | (p6) add carry1=1,carry1 | ||
1051 | cmp.ltu p6,p0=r26,r25 | ||
1052 | add r27=r27,r26 };; | ||
1053 | { .mfb; getf.sig r17=f106 } | ||
1054 | { .mii; | ||
1055 | (p6) add carry1=1,carry1 | ||
1056 | cmp.ltu p6,p0=r27,r26 | ||
1057 | add r28=r28,r27 };; | ||
1058 | { .mfb; getf.sig r18=f97 } | ||
1059 | { .mii; | ||
1060 | (p6) add carry1=1,carry1 | ||
1061 | cmp.ltu p6,p0=r28,r27 | ||
1062 | add r28=r28,carry2 };; | ||
1063 | { .mib; getf.sig r19=f88 | ||
1064 | add r17=r17,r16 } | ||
1065 | { .mib; | ||
1066 | (p6) add carry1=1,carry1 | ||
1067 | cmp.ltu p6,p0=r28,carry2 };; | ||
1068 | { .mii; st8 [r33]=r28,16 | ||
1069 | (p6) add carry1=1,carry1 } | ||
1070 | |||
1071 | { .mii; mov carry2=0 | ||
1072 | cmp.ltu p7,p0=r17,r16 | ||
1073 | add r18=r18,r17 };; | ||
1074 | { .mfb; getf.sig r24=f116 } | ||
1075 | { .mii; (p7) add carry2=1,carry2 | ||
1076 | cmp.ltu p7,p0=r18,r17 | ||
1077 | add r19=r19,r18 };; | ||
1078 | { .mfb; getf.sig r25=f107 } | ||
1079 | { .mii; (p7) add carry2=1,carry2 | ||
1080 | cmp.ltu p7,p0=r19,r18 | ||
1081 | add r19=r19,carry1 };; | ||
1082 | { .mfb; getf.sig r26=f98 } | ||
1083 | { .mii; (p7) add carry2=1,carry2 | ||
1084 | cmp.ltu p7,p0=r19,carry1};; | ||
1085 | { .mii; st8 [r32]=r19,16 | ||
1086 | (p7) add carry2=1,carry2 } | ||
1087 | |||
1088 | { .mfb; add r25=r25,r24 };; | ||
1089 | |||
1090 | { .mfb; getf.sig r16=f117 } | ||
1091 | { .mii; mov carry1=0 | ||
1092 | cmp.ltu p6,p0=r25,r24 | ||
1093 | add r26=r26,r25 };; | ||
1094 | { .mfb; getf.sig r17=f108 } | ||
1095 | { .mii; | ||
1096 | (p6) add carry1=1,carry1 | ||
1097 | cmp.ltu p6,p0=r26,r25 | ||
1098 | add r26=r26,carry2 };; | ||
1099 | { .mfb; nop.m 0x0 } | ||
1100 | { .mii; | ||
1101 | (p6) add carry1=1,carry1 | ||
1102 | cmp.ltu p6,p0=r26,carry2 };; | ||
1103 | { .mii; st8 [r33]=r26,16 | ||
1104 | (p6) add carry1=1,carry1 } | ||
1105 | |||
1106 | { .mfb; add r17=r17,r16 };; | ||
1107 | { .mfb; getf.sig r24=f118 } | ||
1108 | { .mii; mov carry2=0 | ||
1109 | cmp.ltu p7,p0=r17,r16 | ||
1110 | add r17=r17,carry1 };; | ||
1111 | { .mii; (p7) add carry2=1,carry2 | ||
1112 | cmp.ltu p7,p0=r17,carry1};; | ||
1113 | { .mii; st8 [r32]=r17 | ||
1114 | (p7) add carry2=1,carry2 };; | ||
1115 | { .mfb; add r24=r24,carry2 };; | ||
1116 | { .mib; st8 [r33]=r24 } | ||
1117 | |||
1118 | { .mib; rum 1<<5 // clear um.mfh | ||
1119 | br.ret.sptk.many b0 };; | ||
1120 | .endp bn_mul_comba8# | ||
1121 | #undef carry3 | ||
1122 | #undef carry2 | ||
1123 | #undef carry1 | ||
1124 | #endif | ||
1125 | |||
1126 | #if 1 | ||
1127 | // It's possible to make it faster (see comment to bn_sqr_comba8), but | ||
1128 | // I reckon it doesn't worth the effort. Basically because the routine | ||
1129 | // (actually both of them) practically never called... So I just play | ||
1130 | // same trick as with bn_sqr_comba8. | ||
1131 | // | ||
1132 | // void bn_sqr_comba4(BN_ULONG *r, BN_ULONG *a) | ||
1133 | // | ||
1134 | .global bn_sqr_comba4# | ||
1135 | .proc bn_sqr_comba4# | ||
1136 | .align 64 | ||
1137 | bn_sqr_comba4: | ||
1138 | .prologue | ||
1139 | .fframe 0 | ||
1140 | .save ar.pfs,r2 | ||
1141 | { .mii; alloc r2=ar.pfs,2,1,0,0 | ||
1142 | mov r34=r33 | ||
1143 | add r14=8,r33 };; | ||
1144 | .body | ||
1145 | { .mii; add r17=8,r34 | ||
1146 | add r15=16,r33 | ||
1147 | add r18=16,r34 } | ||
1148 | { .mfb; add r16=24,r33 | ||
1149 | br .L_cheat_entry_point4 };; | ||
1150 | .endp bn_sqr_comba4# | ||
1151 | #endif | ||
1152 | |||
1153 | #if 1 | ||
1154 | // Runs in ~115 cycles and ~4.5 times faster than C. Well, whatever... | ||
1155 | // | ||
1156 | // void bn_mul_comba4(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b) | ||
1157 | // | ||
1158 | #define carry1 r14 | ||
1159 | #define carry2 r15 | ||
1160 | .global bn_mul_comba4# | ||
1161 | .proc bn_mul_comba4# | ||
1162 | .align 64 | ||
1163 | bn_mul_comba4: | ||
1164 | .prologue | ||
1165 | .fframe 0 | ||
1166 | .save ar.pfs,r2 | ||
1167 | { .mii; alloc r2=ar.pfs,3,0,0,0 | ||
1168 | add r14=8,r33 | ||
1169 | add r17=8,r34 } | ||
1170 | .body | ||
1171 | { .mii; add r15=16,r33 | ||
1172 | add r18=16,r34 | ||
1173 | add r16=24,r33 };; | ||
1174 | .L_cheat_entry_point4: | ||
1175 | { .mmi; add r19=24,r34 | ||
1176 | |||
1177 | ldf8 f32=[r33] } | ||
1178 | |||
1179 | { .mmi; ldf8 f120=[r34] | ||
1180 | ldf8 f121=[r17] };; | ||
1181 | { .mmi; ldf8 f122=[r18] | ||
1182 | ldf8 f123=[r19] } | ||
1183 | |||
1184 | { .mmi; ldf8 f33=[r14] | ||
1185 | ldf8 f34=[r15] } | ||
1186 | { .mfi; ldf8 f35=[r16] | ||
1187 | |||
1188 | xma.hu f41=f32,f120,f0 } | ||
1189 | { .mfi; xma.lu f40=f32,f120,f0 };; | ||
1190 | { .mfi; xma.hu f51=f32,f121,f0 } | ||
1191 | { .mfi; xma.lu f50=f32,f121,f0 };; | ||
1192 | { .mfi; xma.hu f61=f32,f122,f0 } | ||
1193 | { .mfi; xma.lu f60=f32,f122,f0 };; | ||
1194 | { .mfi; xma.hu f71=f32,f123,f0 } | ||
1195 | { .mfi; xma.lu f70=f32,f123,f0 };;// | ||
1196 | // Major stall takes place here, and 3 more places below. Result from | ||
1197 | // first xma is not available for another 3 ticks. | ||
1198 | { .mfi; getf.sig r16=f40 | ||
1199 | xma.hu f42=f33,f120,f41 | ||
1200 | add r33=8,r32 } | ||
1201 | { .mfi; xma.lu f41=f33,f120,f41 };; | ||
1202 | { .mfi; getf.sig r24=f50 | ||
1203 | xma.hu f52=f33,f121,f51 } | ||
1204 | { .mfi; xma.lu f51=f33,f121,f51 };; | ||
1205 | { .mfi; st8 [r32]=r16,16 | ||
1206 | xma.hu f62=f33,f122,f61 } | ||
1207 | { .mfi; xma.lu f61=f33,f122,f61 };; | ||
1208 | { .mfi; xma.hu f72=f33,f123,f71 } | ||
1209 | { .mfi; xma.lu f71=f33,f123,f71 };;// | ||
1210 | //-------------------------------------------------// | ||
1211 | { .mfi; getf.sig r25=f41 | ||
1212 | xma.hu f43=f34,f120,f42 } | ||
1213 | { .mfi; xma.lu f42=f34,f120,f42 };; | ||
1214 | { .mfi; getf.sig r16=f60 | ||
1215 | xma.hu f53=f34,f121,f52 } | ||
1216 | { .mfi; xma.lu f52=f34,f121,f52 };; | ||
1217 | { .mfi; getf.sig r17=f51 | ||
1218 | xma.hu f63=f34,f122,f62 | ||
1219 | add r25=r25,r24 } | ||
1220 | { .mfi; mov carry1=0 | ||
1221 | xma.lu f62=f34,f122,f62 };; | ||
1222 | { .mfi; st8 [r33]=r25,16 | ||
1223 | xma.hu f73=f34,f123,f72 | ||
1224 | cmp.ltu p6,p0=r25,r24 } | ||
1225 | { .mfi; xma.lu f72=f34,f123,f72 };;// | ||
1226 | //-------------------------------------------------// | ||
1227 | { .mfi; getf.sig r18=f42 | ||
1228 | xma.hu f44=f35,f120,f43 | ||
1229 | (p6) add carry1=1,carry1 } | ||
1230 | { .mfi; add r17=r17,r16 | ||
1231 | xma.lu f43=f35,f120,f43 | ||
1232 | mov carry2=0 };; | ||
1233 | { .mfi; getf.sig r24=f70 | ||
1234 | xma.hu f54=f35,f121,f53 | ||
1235 | cmp.ltu p7,p0=r17,r16 } | ||
1236 | { .mfi; xma.lu f53=f35,f121,f53 };; | ||
1237 | { .mfi; getf.sig r25=f61 | ||
1238 | xma.hu f64=f35,f122,f63 | ||
1239 | add r18=r18,r17 } | ||
1240 | { .mfi; xma.lu f63=f35,f122,f63 | ||
1241 | (p7) add carry2=1,carry2 };; | ||
1242 | { .mfi; getf.sig r26=f52 | ||
1243 | xma.hu f74=f35,f123,f73 | ||
1244 | cmp.ltu p7,p0=r18,r17 } | ||
1245 | { .mfi; xma.lu f73=f35,f123,f73 | ||
1246 | add r18=r18,carry1 };; | ||
1247 | //-------------------------------------------------// | ||
1248 | { .mii; st8 [r32]=r18,16 | ||
1249 | (p7) add carry2=1,carry2 | ||
1250 | cmp.ltu p7,p0=r18,carry1 };; | ||
1251 | |||
1252 | { .mfi; getf.sig r27=f43 // last major stall | ||
1253 | (p7) add carry2=1,carry2 };; | ||
1254 | { .mii; getf.sig r16=f71 | ||
1255 | add r25=r25,r24 | ||
1256 | mov carry1=0 };; | ||
1257 | { .mii; getf.sig r17=f62 | ||
1258 | cmp.ltu p6,p0=r25,r24 | ||
1259 | add r26=r26,r25 };; | ||
1260 | { .mii; | ||
1261 | (p6) add carry1=1,carry1 | ||
1262 | cmp.ltu p6,p0=r26,r25 | ||
1263 | add r27=r27,r26 };; | ||
1264 | { .mii; | ||
1265 | (p6) add carry1=1,carry1 | ||
1266 | cmp.ltu p6,p0=r27,r26 | ||
1267 | add r27=r27,carry2 };; | ||
1268 | { .mii; getf.sig r18=f53 | ||
1269 | (p6) add carry1=1,carry1 | ||
1270 | cmp.ltu p6,p0=r27,carry2 };; | ||
1271 | { .mfi; st8 [r33]=r27,16 | ||
1272 | (p6) add carry1=1,carry1 } | ||
1273 | |||
1274 | { .mii; getf.sig r19=f44 | ||
1275 | add r17=r17,r16 | ||
1276 | mov carry2=0 };; | ||
1277 | { .mii; getf.sig r24=f72 | ||
1278 | cmp.ltu p7,p0=r17,r16 | ||
1279 | add r18=r18,r17 };; | ||
1280 | { .mii; (p7) add carry2=1,carry2 | ||
1281 | cmp.ltu p7,p0=r18,r17 | ||
1282 | add r19=r19,r18 };; | ||
1283 | { .mii; (p7) add carry2=1,carry2 | ||
1284 | cmp.ltu p7,p0=r19,r18 | ||
1285 | add r19=r19,carry1 };; | ||
1286 | { .mii; getf.sig r25=f63 | ||
1287 | (p7) add carry2=1,carry2 | ||
1288 | cmp.ltu p7,p0=r19,carry1};; | ||
1289 | { .mii; st8 [r32]=r19,16 | ||
1290 | (p7) add carry2=1,carry2 } | ||
1291 | |||
1292 | { .mii; getf.sig r26=f54 | ||
1293 | add r25=r25,r24 | ||
1294 | mov carry1=0 };; | ||
1295 | { .mii; getf.sig r16=f73 | ||
1296 | cmp.ltu p6,p0=r25,r24 | ||
1297 | add r26=r26,r25 };; | ||
1298 | { .mii; | ||
1299 | (p6) add carry1=1,carry1 | ||
1300 | cmp.ltu p6,p0=r26,r25 | ||
1301 | add r26=r26,carry2 };; | ||
1302 | { .mii; getf.sig r17=f64 | ||
1303 | (p6) add carry1=1,carry1 | ||
1304 | cmp.ltu p6,p0=r26,carry2 };; | ||
1305 | { .mii; st8 [r33]=r26,16 | ||
1306 | (p6) add carry1=1,carry1 } | ||
1307 | |||
1308 | { .mii; getf.sig r24=f74 | ||
1309 | add r17=r17,r16 | ||
1310 | mov carry2=0 };; | ||
1311 | { .mii; cmp.ltu p7,p0=r17,r16 | ||
1312 | add r17=r17,carry1 };; | ||
1313 | |||
1314 | { .mii; (p7) add carry2=1,carry2 | ||
1315 | cmp.ltu p7,p0=r17,carry1};; | ||
1316 | { .mii; st8 [r32]=r17,16 | ||
1317 | (p7) add carry2=1,carry2 };; | ||
1318 | |||
1319 | { .mii; add r24=r24,carry2 };; | ||
1320 | { .mii; st8 [r33]=r24 } | ||
1321 | |||
1322 | { .mib; rum 1<<5 // clear um.mfh | ||
1323 | br.ret.sptk.many b0 };; | ||
1324 | .endp bn_mul_comba4# | ||
1325 | #undef carry2 | ||
1326 | #undef carry1 | ||
1327 | #endif | ||
1328 | |||
1329 | #if 1 | ||
1330 | // | ||
1331 | // BN_ULONG bn_div_words(BN_ULONG h, BN_ULONG l, BN_ULONG d) | ||
1332 | // | ||
1333 | // In the nutshell it's a port of my MIPS III/IV implementation. | ||
1334 | // | ||
1335 | #define AT r14 | ||
1336 | #define H r16 | ||
1337 | #define HH r20 | ||
1338 | #define L r17 | ||
1339 | #define D r18 | ||
1340 | #define DH r22 | ||
1341 | #define I r21 | ||
1342 | |||
1343 | #if 0 | ||
1344 | // Some preprocessors (most notably HP-UX) apper to be allergic to | ||
1345 | // macros enclosed to parenthesis as these three will be. | ||
1346 | #define cont p16 | ||
1347 | #define break p0 // p20 | ||
1348 | #define equ p24 | ||
1349 | #else | ||
1350 | cont=p16 | ||
1351 | break=p0 | ||
1352 | equ=p24 | ||
1353 | #endif | ||
1354 | |||
1355 | .global abort# | ||
1356 | .global bn_div_words# | ||
1357 | .proc bn_div_words# | ||
1358 | .align 64 | ||
1359 | bn_div_words: | ||
1360 | .prologue | ||
1361 | .fframe 0 | ||
1362 | .save ar.pfs,r2 | ||
1363 | .save b0,r3 | ||
1364 | { .mii; alloc r2=ar.pfs,3,5,0,8 | ||
1365 | mov r3=b0 | ||
1366 | mov r10=pr };; | ||
1367 | { .mmb; cmp.eq p6,p0=r34,r0 | ||
1368 | mov r8=-1 | ||
1369 | (p6) br.ret.spnt.many b0 };; | ||
1370 | |||
1371 | .body | ||
1372 | { .mii; mov H=r32 // save h | ||
1373 | mov ar.ec=0 // don't rotate at exit | ||
1374 | mov pr.rot=0 } | ||
1375 | { .mii; mov L=r33 // save l | ||
1376 | mov r36=r0 };; | ||
1377 | |||
1378 | .L_divw_shift: // -vv- note signed comparison | ||
1379 | { .mfi; (p0) cmp.lt p16,p0=r0,r34 // d | ||
1380 | (p0) shladd r33=r34,1,r0 } | ||
1381 | { .mfb; (p0) add r35=1,r36 | ||
1382 | (p0) nop.f 0x0 | ||
1383 | (p16) br.wtop.dpnt .L_divw_shift };; | ||
1384 | |||
1385 | { .mii; mov D=r34 | ||
1386 | shr.u DH=r34,32 | ||
1387 | sub r35=64,r36 };; | ||
1388 | { .mii; setf.sig f7=DH | ||
1389 | shr.u AT=H,r35 | ||
1390 | mov I=r36 };; | ||
1391 | { .mib; cmp.ne p6,p0=r0,AT | ||
1392 | shl H=H,r36 | ||
1393 | (p6) br.call.spnt.clr b0=abort };; // overflow, die... | ||
1394 | |||
1395 | { .mfi; fcvt.xuf.s1 f7=f7 | ||
1396 | shr.u AT=L,r35 };; | ||
1397 | { .mii; shl L=L,r36 | ||
1398 | or H=H,AT };; | ||
1399 | |||
1400 | { .mii; nop.m 0x0 | ||
1401 | cmp.leu p6,p0=D,H;; | ||
1402 | (p6) sub H=H,D } | ||
1403 | |||
1404 | { .mlx; setf.sig f14=D | ||
1405 | movl AT=0xffffffff };; | ||
1406 | /////////////////////////////////////////////////////////// | ||
1407 | { .mii; setf.sig f6=H | ||
1408 | shr.u HH=H,32;; | ||
1409 | cmp.eq p6,p7=HH,DH };; | ||
1410 | { .mfb; | ||
1411 | (p6) setf.sig f8=AT | ||
1412 | (p7) fcvt.xuf.s1 f6=f6 | ||
1413 | (p7) br.call.sptk b6=.L_udiv64_32_b6 };; | ||
1414 | |||
1415 | { .mfi; getf.sig r33=f8 // q | ||
1416 | xmpy.lu f9=f8,f14 } | ||
1417 | { .mfi; xmpy.hu f10=f8,f14 | ||
1418 | shrp H=H,L,32 };; | ||
1419 | |||
1420 | { .mmi; getf.sig r35=f9 // tl | ||
1421 | getf.sig r31=f10 };; // th | ||
1422 | |||
1423 | .L_divw_1st_iter: | ||
1424 | { .mii; (p0) add r32=-1,r33 | ||
1425 | (p0) cmp.eq equ,cont=HH,r31 };; | ||
1426 | { .mii; (p0) cmp.ltu p8,p0=r35,D | ||
1427 | (p0) sub r34=r35,D | ||
1428 | (equ) cmp.leu break,cont=r35,H };; | ||
1429 | { .mib; (cont) cmp.leu cont,break=HH,r31 | ||
1430 | (p8) add r31=-1,r31 | ||
1431 | (cont) br.wtop.spnt .L_divw_1st_iter };; | ||
1432 | /////////////////////////////////////////////////////////// | ||
1433 | { .mii; sub H=H,r35 | ||
1434 | shl r8=r33,32 | ||
1435 | shl L=L,32 };; | ||
1436 | /////////////////////////////////////////////////////////// | ||
1437 | { .mii; setf.sig f6=H | ||
1438 | shr.u HH=H,32;; | ||
1439 | cmp.eq p6,p7=HH,DH };; | ||
1440 | { .mfb; | ||
1441 | (p6) setf.sig f8=AT | ||
1442 | (p7) fcvt.xuf.s1 f6=f6 | ||
1443 | (p7) br.call.sptk b6=.L_udiv64_32_b6 };; | ||
1444 | |||
1445 | { .mfi; getf.sig r33=f8 // q | ||
1446 | xmpy.lu f9=f8,f14 } | ||
1447 | { .mfi; xmpy.hu f10=f8,f14 | ||
1448 | shrp H=H,L,32 };; | ||
1449 | |||
1450 | { .mmi; getf.sig r35=f9 // tl | ||
1451 | getf.sig r31=f10 };; // th | ||
1452 | |||
1453 | .L_divw_2nd_iter: | ||
1454 | { .mii; (p0) add r32=-1,r33 | ||
1455 | (p0) cmp.eq equ,cont=HH,r31 };; | ||
1456 | { .mii; (p0) cmp.ltu p8,p0=r35,D | ||
1457 | (p0) sub r34=r35,D | ||
1458 | (equ) cmp.leu break,cont=r35,H };; | ||
1459 | { .mib; (cont) cmp.leu cont,break=HH,r31 | ||
1460 | (p8) add r31=-1,r31 | ||
1461 | (cont) br.wtop.spnt .L_divw_2nd_iter };; | ||
1462 | /////////////////////////////////////////////////////////// | ||
1463 | { .mii; sub H=H,r35 | ||
1464 | or r8=r8,r33 | ||
1465 | mov ar.pfs=r2 };; | ||
1466 | { .mii; shr.u r9=H,I // remainder if anybody wants it | ||
1467 | mov pr=r10,-1 } | ||
1468 | { .mfb; br.ret.sptk.many b0 };; | ||
1469 | |||
1470 | // Unsigned 64 by 32 (well, by 64 for the moment) bit integer division | ||
1471 | // procedure. | ||
1472 | // | ||
1473 | // inputs: f6 = (double)a, f7 = (double)b | ||
1474 | // output: f8 = (int)(a/b) | ||
1475 | // clobbered: f8,f9,f10,f11,pred | ||
1476 | pred=p15 | ||
1477 | // This procedure is essentially Intel code and therefore is | ||
1478 | // copyrighted to Intel Corporation (I suppose...). It's sligtly | ||
1479 | // modified for specific needs. | ||
1480 | .align 32 | ||
1481 | .skip 16 | ||
1482 | .L_udiv64_32_b6: | ||
1483 | frcpa.s1 f8,pred=f6,f7;; // [0] y0 = 1 / b | ||
1484 | |||
1485 | (pred) fnma.s1 f9=f7,f8,f1 // [5] e0 = 1 - b * y0 | ||
1486 | (pred) fmpy.s1 f10=f6,f8;; // [5] q0 = a * y0 | ||
1487 | (pred) fmpy.s1 f11=f9,f9 // [10] e1 = e0 * e0 | ||
1488 | (pred) fma.s1 f10=f9,f10,f10;; // [10] q1 = q0 + e0 * q0 | ||
1489 | (pred) fma.s1 f8=f9,f8,f8 //;; // [15] y1 = y0 + e0 * y0 | ||
1490 | (pred) fma.s1 f9=f11,f10,f10;; // [15] q2 = q1 + e1 * q1 | ||
1491 | (pred) fma.s1 f8=f11,f8,f8 //;; // [20] y2 = y1 + e1 * y1 | ||
1492 | (pred) fnma.s1 f10=f7,f9,f6;; // [20] r2 = a - b * q2 | ||
1493 | (pred) fma.s1 f8=f10,f8,f9;; // [25] q3 = q2 + r2 * y2 | ||
1494 | |||
1495 | fcvt.fxu.trunc.s1 f8=f8 // [30] q = trunc(q3) | ||
1496 | br.ret.sptk.many b6;; | ||
1497 | .endp bn_div_words# | ||
1498 | #endif | ||
diff --git a/src/lib/libcrypto/bn/asm/pa-risc2W.s b/src/lib/libcrypto/bn/asm/pa-risc2W.s new file mode 100644 index 0000000000..54b6606252 --- /dev/null +++ b/src/lib/libcrypto/bn/asm/pa-risc2W.s | |||
@@ -0,0 +1,1605 @@ | |||
1 | ; | ||
2 | ; PA-RISC 64-bit implementation of bn_asm code | ||
3 | ; | ||
4 | ; This code is approximately 2x faster than the C version | ||
5 | ; for RSA/DSA. | ||
6 | ; | ||
7 | ; See http://devresource.hp.com/ for more details on the PA-RISC | ||
8 | ; architecture. Also see the book "PA-RISC 2.0 Architecture" | ||
9 | ; by Gerry Kane for information on the instruction set architecture. | ||
10 | ; | ||
11 | ; Code written by Chris Ruemmler (with some help from the HP C | ||
12 | ; compiler). | ||
13 | ; | ||
14 | ; The code compiles with HP's assembler | ||
15 | ; | ||
16 | |||
17 | .level 2.0W | ||
18 | .space $TEXT$ | ||
19 | .subspa $CODE$,QUAD=0,ALIGN=8,ACCESS=0x2c,CODE_ONLY | ||
20 | |||
21 | ; | ||
22 | ; Global Register definitions used for the routines. | ||
23 | ; | ||
24 | ; Some information about HP's runtime architecture for 64-bits. | ||
25 | ; | ||
26 | ; "Caller save" means the calling function must save the register | ||
27 | ; if it wants the register to be preserved. | ||
28 | ; "Callee save" means if a function uses the register, it must save | ||
29 | ; the value before using it. | ||
30 | ; | ||
31 | ; For the floating point registers | ||
32 | ; | ||
33 | ; "caller save" registers: fr4-fr11, fr22-fr31 | ||
34 | ; "callee save" registers: fr12-fr21 | ||
35 | ; "special" registers: fr0-fr3 (status and exception registers) | ||
36 | ; | ||
37 | ; For the integer registers | ||
38 | ; value zero : r0 | ||
39 | ; "caller save" registers: r1,r19-r26 | ||
40 | ; "callee save" registers: r3-r18 | ||
41 | ; return register : r2 (rp) | ||
42 | ; return values ; r28 (ret0,ret1) | ||
43 | ; Stack pointer ; r30 (sp) | ||
44 | ; global data pointer ; r27 (dp) | ||
45 | ; argument pointer ; r29 (ap) | ||
46 | ; millicode return ptr ; r31 (also a caller save register) | ||
47 | |||
48 | |||
49 | ; | ||
50 | ; Arguments to the routines | ||
51 | ; | ||
52 | r_ptr .reg %r26 | ||
53 | a_ptr .reg %r25 | ||
54 | b_ptr .reg %r24 | ||
55 | num .reg %r24 | ||
56 | w .reg %r23 | ||
57 | n .reg %r23 | ||
58 | |||
59 | |||
60 | ; | ||
61 | ; Globals used in some routines | ||
62 | ; | ||
63 | |||
64 | top_overflow .reg %r29 | ||
65 | high_mask .reg %r22 ; value 0xffffffff80000000L | ||
66 | |||
67 | |||
68 | ;------------------------------------------------------------------------------ | ||
69 | ; | ||
70 | ; bn_mul_add_words | ||
71 | ; | ||
72 | ;BN_ULONG bn_mul_add_words(BN_ULONG *r_ptr, BN_ULONG *a_ptr, | ||
73 | ; int num, BN_ULONG w) | ||
74 | ; | ||
75 | ; arg0 = r_ptr | ||
76 | ; arg1 = a_ptr | ||
77 | ; arg2 = num | ||
78 | ; arg3 = w | ||
79 | ; | ||
80 | ; Local register definitions | ||
81 | ; | ||
82 | |||
83 | fm1 .reg %fr22 | ||
84 | fm .reg %fr23 | ||
85 | ht_temp .reg %fr24 | ||
86 | ht_temp_1 .reg %fr25 | ||
87 | lt_temp .reg %fr26 | ||
88 | lt_temp_1 .reg %fr27 | ||
89 | fm1_1 .reg %fr28 | ||
90 | fm_1 .reg %fr29 | ||
91 | |||
92 | fw_h .reg %fr7L | ||
93 | fw_l .reg %fr7R | ||
94 | fw .reg %fr7 | ||
95 | |||
96 | fht_0 .reg %fr8L | ||
97 | flt_0 .reg %fr8R | ||
98 | t_float_0 .reg %fr8 | ||
99 | |||
100 | fht_1 .reg %fr9L | ||
101 | flt_1 .reg %fr9R | ||
102 | t_float_1 .reg %fr9 | ||
103 | |||
104 | tmp_0 .reg %r31 | ||
105 | tmp_1 .reg %r21 | ||
106 | m_0 .reg %r20 | ||
107 | m_1 .reg %r19 | ||
108 | ht_0 .reg %r1 | ||
109 | ht_1 .reg %r3 | ||
110 | lt_0 .reg %r4 | ||
111 | lt_1 .reg %r5 | ||
112 | m1_0 .reg %r6 | ||
113 | m1_1 .reg %r7 | ||
114 | rp_val .reg %r8 | ||
115 | rp_val_1 .reg %r9 | ||
116 | |||
117 | bn_mul_add_words | ||
118 | .export bn_mul_add_words,entry,NO_RELOCATION,LONG_RETURN | ||
119 | .proc | ||
120 | .callinfo frame=128 | ||
121 | .entry | ||
122 | .align 64 | ||
123 | |||
124 | STD %r3,0(%sp) ; save r3 | ||
125 | STD %r4,8(%sp) ; save r4 | ||
126 | NOP ; Needed to make the loop 16-byte aligned | ||
127 | NOP ; Needed to make the loop 16-byte aligned | ||
128 | |||
129 | STD %r5,16(%sp) ; save r5 | ||
130 | STD %r6,24(%sp) ; save r6 | ||
131 | STD %r7,32(%sp) ; save r7 | ||
132 | STD %r8,40(%sp) ; save r8 | ||
133 | |||
134 | STD %r9,48(%sp) ; save r9 | ||
135 | COPY %r0,%ret0 ; return 0 by default | ||
136 | DEPDI,Z 1,31,1,top_overflow ; top_overflow = 1 << 32 | ||
137 | STD w,56(%sp) ; store w on stack | ||
138 | |||
139 | CMPIB,>= 0,num,bn_mul_add_words_exit ; if (num <= 0) then exit | ||
140 | LDO 128(%sp),%sp ; bump stack | ||
141 | |||
142 | ; | ||
143 | ; The loop is unrolled twice, so if there is only 1 number | ||
144 | ; then go straight to the cleanup code. | ||
145 | ; | ||
146 | CMPIB,= 1,num,bn_mul_add_words_single_top | ||
147 | FLDD -72(%sp),fw ; load up w into fp register fw (fw_h/fw_l) | ||
148 | |||
149 | ; | ||
150 | ; This loop is unrolled 2 times (64-byte aligned as well) | ||
151 | ; | ||
152 | ; PA-RISC 2.0 chips have two fully pipelined multipliers, thus | ||
153 | ; two 32-bit mutiplies can be issued per cycle. | ||
154 | ; | ||
155 | bn_mul_add_words_unroll2 | ||
156 | |||
157 | FLDD 0(a_ptr),t_float_0 ; load up 64-bit value (fr8L) ht(L)/lt(R) | ||
158 | FLDD 8(a_ptr),t_float_1 ; load up 64-bit value (fr8L) ht(L)/lt(R) | ||
159 | LDD 0(r_ptr),rp_val ; rp[0] | ||
160 | LDD 8(r_ptr),rp_val_1 ; rp[1] | ||
161 | |||
162 | XMPYU fht_0,fw_l,fm1 ; m1[0] = fht_0*fw_l | ||
163 | XMPYU fht_1,fw_l,fm1_1 ; m1[1] = fht_1*fw_l | ||
164 | FSTD fm1,-16(%sp) ; -16(sp) = m1[0] | ||
165 | FSTD fm1_1,-48(%sp) ; -48(sp) = m1[1] | ||
166 | |||
167 | XMPYU flt_0,fw_h,fm ; m[0] = flt_0*fw_h | ||
168 | XMPYU flt_1,fw_h,fm_1 ; m[1] = flt_1*fw_h | ||
169 | FSTD fm,-8(%sp) ; -8(sp) = m[0] | ||
170 | FSTD fm_1,-40(%sp) ; -40(sp) = m[1] | ||
171 | |||
172 | XMPYU fht_0,fw_h,ht_temp ; ht_temp = fht_0*fw_h | ||
173 | XMPYU fht_1,fw_h,ht_temp_1 ; ht_temp_1 = fht_1*fw_h | ||
174 | FSTD ht_temp,-24(%sp) ; -24(sp) = ht_temp | ||
175 | FSTD ht_temp_1,-56(%sp) ; -56(sp) = ht_temp_1 | ||
176 | |||
177 | XMPYU flt_0,fw_l,lt_temp ; lt_temp = lt*fw_l | ||
178 | XMPYU flt_1,fw_l,lt_temp_1 ; lt_temp = lt*fw_l | ||
179 | FSTD lt_temp,-32(%sp) ; -32(sp) = lt_temp | ||
180 | FSTD lt_temp_1,-64(%sp) ; -64(sp) = lt_temp_1 | ||
181 | |||
182 | LDD -8(%sp),m_0 ; m[0] | ||
183 | LDD -40(%sp),m_1 ; m[1] | ||
184 | LDD -16(%sp),m1_0 ; m1[0] | ||
185 | LDD -48(%sp),m1_1 ; m1[1] | ||
186 | |||
187 | LDD -24(%sp),ht_0 ; ht[0] | ||
188 | LDD -56(%sp),ht_1 ; ht[1] | ||
189 | ADD,L m1_0,m_0,tmp_0 ; tmp_0 = m[0] + m1[0]; | ||
190 | ADD,L m1_1,m_1,tmp_1 ; tmp_1 = m[1] + m1[1]; | ||
191 | |||
192 | LDD -32(%sp),lt_0 | ||
193 | LDD -64(%sp),lt_1 | ||
194 | CMPCLR,*>>= tmp_0,m1_0, %r0 ; if (m[0] < m1[0]) | ||
195 | ADD,L ht_0,top_overflow,ht_0 ; ht[0] += (1<<32) | ||
196 | |||
197 | CMPCLR,*>>= tmp_1,m1_1,%r0 ; if (m[1] < m1[1]) | ||
198 | ADD,L ht_1,top_overflow,ht_1 ; ht[1] += (1<<32) | ||
199 | EXTRD,U tmp_0,31,32,m_0 ; m[0]>>32 | ||
200 | DEPD,Z tmp_0,31,32,m1_0 ; m1[0] = m[0]<<32 | ||
201 | |||
202 | EXTRD,U tmp_1,31,32,m_1 ; m[1]>>32 | ||
203 | DEPD,Z tmp_1,31,32,m1_1 ; m1[1] = m[1]<<32 | ||
204 | ADD,L ht_0,m_0,ht_0 ; ht[0]+= (m[0]>>32) | ||
205 | ADD,L ht_1,m_1,ht_1 ; ht[1]+= (m[1]>>32) | ||
206 | |||
207 | ADD lt_0,m1_0,lt_0 ; lt[0] = lt[0]+m1[0]; | ||
208 | ADD,DC ht_0,%r0,ht_0 ; ht[0]++ | ||
209 | ADD lt_1,m1_1,lt_1 ; lt[1] = lt[1]+m1[1]; | ||
210 | ADD,DC ht_1,%r0,ht_1 ; ht[1]++ | ||
211 | |||
212 | ADD %ret0,lt_0,lt_0 ; lt[0] = lt[0] + c; | ||
213 | ADD,DC ht_0,%r0,ht_0 ; ht[0]++ | ||
214 | ADD lt_0,rp_val,lt_0 ; lt[0] = lt[0]+rp[0] | ||
215 | ADD,DC ht_0,%r0,ht_0 ; ht[0]++ | ||
216 | |||
217 | LDO -2(num),num ; num = num - 2; | ||
218 | ADD ht_0,lt_1,lt_1 ; lt[1] = lt[1] + ht_0 (c); | ||
219 | ADD,DC ht_1,%r0,ht_1 ; ht[1]++ | ||
220 | STD lt_0,0(r_ptr) ; rp[0] = lt[0] | ||
221 | |||
222 | ADD lt_1,rp_val_1,lt_1 ; lt[1] = lt[1]+rp[1] | ||
223 | ADD,DC ht_1,%r0,%ret0 ; ht[1]++ | ||
224 | LDO 16(a_ptr),a_ptr ; a_ptr += 2 | ||
225 | |||
226 | STD lt_1,8(r_ptr) ; rp[1] = lt[1] | ||
227 | CMPIB,<= 2,num,bn_mul_add_words_unroll2 ; go again if more to do | ||
228 | LDO 16(r_ptr),r_ptr ; r_ptr += 2 | ||
229 | |||
230 | CMPIB,=,N 0,num,bn_mul_add_words_exit ; are we done, or cleanup last one | ||
231 | |||
232 | ; | ||
233 | ; Top of loop aligned on 64-byte boundary | ||
234 | ; | ||
235 | bn_mul_add_words_single_top | ||
236 | FLDD 0(a_ptr),t_float_0 ; load up 64-bit value (fr8L) ht(L)/lt(R) | ||
237 | LDD 0(r_ptr),rp_val ; rp[0] | ||
238 | LDO 8(a_ptr),a_ptr ; a_ptr++ | ||
239 | XMPYU fht_0,fw_l,fm1 ; m1 = ht*fw_l | ||
240 | FSTD fm1,-16(%sp) ; -16(sp) = m1 | ||
241 | XMPYU flt_0,fw_h,fm ; m = lt*fw_h | ||
242 | FSTD fm,-8(%sp) ; -8(sp) = m | ||
243 | XMPYU fht_0,fw_h,ht_temp ; ht_temp = ht*fw_h | ||
244 | FSTD ht_temp,-24(%sp) ; -24(sp) = ht | ||
245 | XMPYU flt_0,fw_l,lt_temp ; lt_temp = lt*fw_l | ||
246 | FSTD lt_temp,-32(%sp) ; -32(sp) = lt | ||
247 | |||
248 | LDD -8(%sp),m_0 | ||
249 | LDD -16(%sp),m1_0 ; m1 = temp1 | ||
250 | ADD,L m_0,m1_0,tmp_0 ; tmp_0 = m + m1; | ||
251 | LDD -24(%sp),ht_0 | ||
252 | LDD -32(%sp),lt_0 | ||
253 | |||
254 | CMPCLR,*>>= tmp_0,m1_0,%r0 ; if (m < m1) | ||
255 | ADD,L ht_0,top_overflow,ht_0 ; ht += (1<<32) | ||
256 | |||
257 | EXTRD,U tmp_0,31,32,m_0 ; m>>32 | ||
258 | DEPD,Z tmp_0,31,32,m1_0 ; m1 = m<<32 | ||
259 | |||
260 | ADD,L ht_0,m_0,ht_0 ; ht+= (m>>32) | ||
261 | ADD lt_0,m1_0,tmp_0 ; tmp_0 = lt+m1; | ||
262 | ADD,DC ht_0,%r0,ht_0 ; ht++ | ||
263 | ADD %ret0,tmp_0,lt_0 ; lt = lt + c; | ||
264 | ADD,DC ht_0,%r0,ht_0 ; ht++ | ||
265 | ADD lt_0,rp_val,lt_0 ; lt = lt+rp[0] | ||
266 | ADD,DC ht_0,%r0,%ret0 ; ht++ | ||
267 | STD lt_0,0(r_ptr) ; rp[0] = lt | ||
268 | |||
269 | bn_mul_add_words_exit | ||
270 | .EXIT | ||
271 | LDD -80(%sp),%r9 ; restore r9 | ||
272 | LDD -88(%sp),%r8 ; restore r8 | ||
273 | LDD -96(%sp),%r7 ; restore r7 | ||
274 | LDD -104(%sp),%r6 ; restore r6 | ||
275 | LDD -112(%sp),%r5 ; restore r5 | ||
276 | LDD -120(%sp),%r4 ; restore r4 | ||
277 | BVE (%rp) | ||
278 | LDD,MB -128(%sp),%r3 ; restore r3 | ||
279 | .PROCEND ;in=23,24,25,26,29;out=28; | ||
280 | |||
281 | ;---------------------------------------------------------------------------- | ||
282 | ; | ||
283 | ;BN_ULONG bn_mul_words(BN_ULONG *rp, BN_ULONG *ap, int num, BN_ULONG w) | ||
284 | ; | ||
285 | ; arg0 = rp | ||
286 | ; arg1 = ap | ||
287 | ; arg2 = num | ||
288 | ; arg3 = w | ||
289 | |||
290 | bn_mul_words | ||
291 | .proc | ||
292 | .callinfo frame=128 | ||
293 | .entry | ||
294 | .EXPORT bn_mul_words,ENTRY,PRIV_LEV=3,NO_RELOCATION,LONG_RETURN | ||
295 | .align 64 | ||
296 | |||
297 | STD %r3,0(%sp) ; save r3 | ||
298 | STD %r4,8(%sp) ; save r4 | ||
299 | STD %r5,16(%sp) ; save r5 | ||
300 | STD %r6,24(%sp) ; save r6 | ||
301 | |||
302 | STD %r7,32(%sp) ; save r7 | ||
303 | COPY %r0,%ret0 ; return 0 by default | ||
304 | DEPDI,Z 1,31,1,top_overflow ; top_overflow = 1 << 32 | ||
305 | STD w,56(%sp) ; w on stack | ||
306 | |||
307 | CMPIB,>= 0,num,bn_mul_words_exit | ||
308 | LDO 128(%sp),%sp ; bump stack | ||
309 | |||
310 | ; | ||
311 | ; See if only 1 word to do, thus just do cleanup | ||
312 | ; | ||
313 | CMPIB,= 1,num,bn_mul_words_single_top | ||
314 | FLDD -72(%sp),fw ; load up w into fp register fw (fw_h/fw_l) | ||
315 | |||
316 | ; | ||
317 | ; This loop is unrolled 2 times (64-byte aligned as well) | ||
318 | ; | ||
319 | ; PA-RISC 2.0 chips have two fully pipelined multipliers, thus | ||
320 | ; two 32-bit mutiplies can be issued per cycle. | ||
321 | ; | ||
322 | bn_mul_words_unroll2 | ||
323 | |||
324 | FLDD 0(a_ptr),t_float_0 ; load up 64-bit value (fr8L) ht(L)/lt(R) | ||
325 | FLDD 8(a_ptr),t_float_1 ; load up 64-bit value (fr8L) ht(L)/lt(R) | ||
326 | XMPYU fht_0,fw_l,fm1 ; m1[0] = fht_0*fw_l | ||
327 | XMPYU fht_1,fw_l,fm1_1 ; m1[1] = ht*fw_l | ||
328 | |||
329 | FSTD fm1,-16(%sp) ; -16(sp) = m1 | ||
330 | FSTD fm1_1,-48(%sp) ; -48(sp) = m1 | ||
331 | XMPYU flt_0,fw_h,fm ; m = lt*fw_h | ||
332 | XMPYU flt_1,fw_h,fm_1 ; m = lt*fw_h | ||
333 | |||
334 | FSTD fm,-8(%sp) ; -8(sp) = m | ||
335 | FSTD fm_1,-40(%sp) ; -40(sp) = m | ||
336 | XMPYU fht_0,fw_h,ht_temp ; ht_temp = fht_0*fw_h | ||
337 | XMPYU fht_1,fw_h,ht_temp_1 ; ht_temp = ht*fw_h | ||
338 | |||
339 | FSTD ht_temp,-24(%sp) ; -24(sp) = ht | ||
340 | FSTD ht_temp_1,-56(%sp) ; -56(sp) = ht | ||
341 | XMPYU flt_0,fw_l,lt_temp ; lt_temp = lt*fw_l | ||
342 | XMPYU flt_1,fw_l,lt_temp_1 ; lt_temp = lt*fw_l | ||
343 | |||
344 | FSTD lt_temp,-32(%sp) ; -32(sp) = lt | ||
345 | FSTD lt_temp_1,-64(%sp) ; -64(sp) = lt | ||
346 | LDD -8(%sp),m_0 | ||
347 | LDD -40(%sp),m_1 | ||
348 | |||
349 | LDD -16(%sp),m1_0 | ||
350 | LDD -48(%sp),m1_1 | ||
351 | LDD -24(%sp),ht_0 | ||
352 | LDD -56(%sp),ht_1 | ||
353 | |||
354 | ADD,L m1_0,m_0,tmp_0 ; tmp_0 = m + m1; | ||
355 | ADD,L m1_1,m_1,tmp_1 ; tmp_1 = m + m1; | ||
356 | LDD -32(%sp),lt_0 | ||
357 | LDD -64(%sp),lt_1 | ||
358 | |||
359 | CMPCLR,*>>= tmp_0,m1_0, %r0 ; if (m < m1) | ||
360 | ADD,L ht_0,top_overflow,ht_0 ; ht += (1<<32) | ||
361 | CMPCLR,*>>= tmp_1,m1_1,%r0 ; if (m < m1) | ||
362 | ADD,L ht_1,top_overflow,ht_1 ; ht += (1<<32) | ||
363 | |||
364 | EXTRD,U tmp_0,31,32,m_0 ; m>>32 | ||
365 | DEPD,Z tmp_0,31,32,m1_0 ; m1 = m<<32 | ||
366 | EXTRD,U tmp_1,31,32,m_1 ; m>>32 | ||
367 | DEPD,Z tmp_1,31,32,m1_1 ; m1 = m<<32 | ||
368 | |||
369 | ADD,L ht_0,m_0,ht_0 ; ht+= (m>>32) | ||
370 | ADD,L ht_1,m_1,ht_1 ; ht+= (m>>32) | ||
371 | ADD lt_0,m1_0,lt_0 ; lt = lt+m1; | ||
372 | ADD,DC ht_0,%r0,ht_0 ; ht++ | ||
373 | |||
374 | ADD lt_1,m1_1,lt_1 ; lt = lt+m1; | ||
375 | ADD,DC ht_1,%r0,ht_1 ; ht++ | ||
376 | ADD %ret0,lt_0,lt_0 ; lt = lt + c (ret0); | ||
377 | ADD,DC ht_0,%r0,ht_0 ; ht++ | ||
378 | |||
379 | ADD ht_0,lt_1,lt_1 ; lt = lt + c (ht_0) | ||
380 | ADD,DC ht_1,%r0,ht_1 ; ht++ | ||
381 | STD lt_0,0(r_ptr) ; rp[0] = lt | ||
382 | STD lt_1,8(r_ptr) ; rp[1] = lt | ||
383 | |||
384 | COPY ht_1,%ret0 ; carry = ht | ||
385 | LDO -2(num),num ; num = num - 2; | ||
386 | LDO 16(a_ptr),a_ptr ; ap += 2 | ||
387 | CMPIB,<= 2,num,bn_mul_words_unroll2 | ||
388 | LDO 16(r_ptr),r_ptr ; rp++ | ||
389 | |||
390 | CMPIB,=,N 0,num,bn_mul_words_exit ; are we done? | ||
391 | |||
392 | ; | ||
393 | ; Top of loop aligned on 64-byte boundary | ||
394 | ; | ||
395 | bn_mul_words_single_top | ||
396 | FLDD 0(a_ptr),t_float_0 ; load up 64-bit value (fr8L) ht(L)/lt(R) | ||
397 | |||
398 | XMPYU fht_0,fw_l,fm1 ; m1 = ht*fw_l | ||
399 | FSTD fm1,-16(%sp) ; -16(sp) = m1 | ||
400 | XMPYU flt_0,fw_h,fm ; m = lt*fw_h | ||
401 | FSTD fm,-8(%sp) ; -8(sp) = m | ||
402 | XMPYU fht_0,fw_h,ht_temp ; ht_temp = ht*fw_h | ||
403 | FSTD ht_temp,-24(%sp) ; -24(sp) = ht | ||
404 | XMPYU flt_0,fw_l,lt_temp ; lt_temp = lt*fw_l | ||
405 | FSTD lt_temp,-32(%sp) ; -32(sp) = lt | ||
406 | |||
407 | LDD -8(%sp),m_0 | ||
408 | LDD -16(%sp),m1_0 | ||
409 | ADD,L m_0,m1_0,tmp_0 ; tmp_0 = m + m1; | ||
410 | LDD -24(%sp),ht_0 | ||
411 | LDD -32(%sp),lt_0 | ||
412 | |||
413 | CMPCLR,*>>= tmp_0,m1_0,%r0 ; if (m < m1) | ||
414 | ADD,L ht_0,top_overflow,ht_0 ; ht += (1<<32) | ||
415 | |||
416 | EXTRD,U tmp_0,31,32,m_0 ; m>>32 | ||
417 | DEPD,Z tmp_0,31,32,m1_0 ; m1 = m<<32 | ||
418 | |||
419 | ADD,L ht_0,m_0,ht_0 ; ht+= (m>>32) | ||
420 | ADD lt_0,m1_0,lt_0 ; lt= lt+m1; | ||
421 | ADD,DC ht_0,%r0,ht_0 ; ht++ | ||
422 | |||
423 | ADD %ret0,lt_0,lt_0 ; lt = lt + c; | ||
424 | ADD,DC ht_0,%r0,ht_0 ; ht++ | ||
425 | |||
426 | COPY ht_0,%ret0 ; copy carry | ||
427 | STD lt_0,0(r_ptr) ; rp[0] = lt | ||
428 | |||
429 | bn_mul_words_exit | ||
430 | .EXIT | ||
431 | LDD -96(%sp),%r7 ; restore r7 | ||
432 | LDD -104(%sp),%r6 ; restore r6 | ||
433 | LDD -112(%sp),%r5 ; restore r5 | ||
434 | LDD -120(%sp),%r4 ; restore r4 | ||
435 | BVE (%rp) | ||
436 | LDD,MB -128(%sp),%r3 ; restore r3 | ||
437 | .PROCEND ;in=23,24,25,26,29;out=28; | ||
438 | |||
439 | ;---------------------------------------------------------------------------- | ||
440 | ; | ||
441 | ;void bn_sqr_words(BN_ULONG *rp, BN_ULONG *ap, int num) | ||
442 | ; | ||
443 | ; arg0 = rp | ||
444 | ; arg1 = ap | ||
445 | ; arg2 = num | ||
446 | ; | ||
447 | |||
448 | bn_sqr_words | ||
449 | .proc | ||
450 | .callinfo FRAME=128,ENTRY_GR=%r3,ARGS_SAVED,ORDERING_AWARE | ||
451 | .EXPORT bn_sqr_words,ENTRY,PRIV_LEV=3,NO_RELOCATION,LONG_RETURN | ||
452 | .entry | ||
453 | .align 64 | ||
454 | |||
455 | STD %r3,0(%sp) ; save r3 | ||
456 | STD %r4,8(%sp) ; save r4 | ||
457 | NOP | ||
458 | STD %r5,16(%sp) ; save r5 | ||
459 | |||
460 | CMPIB,>= 0,num,bn_sqr_words_exit | ||
461 | LDO 128(%sp),%sp ; bump stack | ||
462 | |||
463 | ; | ||
464 | ; If only 1, the goto straight to cleanup | ||
465 | ; | ||
466 | CMPIB,= 1,num,bn_sqr_words_single_top | ||
467 | DEPDI,Z -1,32,33,high_mask ; Create Mask 0xffffffff80000000L | ||
468 | |||
469 | ; | ||
470 | ; This loop is unrolled 2 times (64-byte aligned as well) | ||
471 | ; | ||
472 | |||
473 | bn_sqr_words_unroll2 | ||
474 | FLDD 0(a_ptr),t_float_0 ; a[0] | ||
475 | FLDD 8(a_ptr),t_float_1 ; a[1] | ||
476 | XMPYU fht_0,flt_0,fm ; m[0] | ||
477 | XMPYU fht_1,flt_1,fm_1 ; m[1] | ||
478 | |||
479 | FSTD fm,-24(%sp) ; store m[0] | ||
480 | FSTD fm_1,-56(%sp) ; store m[1] | ||
481 | XMPYU flt_0,flt_0,lt_temp ; lt[0] | ||
482 | XMPYU flt_1,flt_1,lt_temp_1 ; lt[1] | ||
483 | |||
484 | FSTD lt_temp,-16(%sp) ; store lt[0] | ||
485 | FSTD lt_temp_1,-48(%sp) ; store lt[1] | ||
486 | XMPYU fht_0,fht_0,ht_temp ; ht[0] | ||
487 | XMPYU fht_1,fht_1,ht_temp_1 ; ht[1] | ||
488 | |||
489 | FSTD ht_temp,-8(%sp) ; store ht[0] | ||
490 | FSTD ht_temp_1,-40(%sp) ; store ht[1] | ||
491 | LDD -24(%sp),m_0 | ||
492 | LDD -56(%sp),m_1 | ||
493 | |||
494 | AND m_0,high_mask,tmp_0 ; m[0] & Mask | ||
495 | AND m_1,high_mask,tmp_1 ; m[1] & Mask | ||
496 | DEPD,Z m_0,30,31,m_0 ; m[0] << 32+1 | ||
497 | DEPD,Z m_1,30,31,m_1 ; m[1] << 32+1 | ||
498 | |||
499 | LDD -16(%sp),lt_0 | ||
500 | LDD -48(%sp),lt_1 | ||
501 | EXTRD,U tmp_0,32,33,tmp_0 ; tmp_0 = m[0]&Mask >> 32-1 | ||
502 | EXTRD,U tmp_1,32,33,tmp_1 ; tmp_1 = m[1]&Mask >> 32-1 | ||
503 | |||
504 | LDD -8(%sp),ht_0 | ||
505 | LDD -40(%sp),ht_1 | ||
506 | ADD,L ht_0,tmp_0,ht_0 ; ht[0] += tmp_0 | ||
507 | ADD,L ht_1,tmp_1,ht_1 ; ht[1] += tmp_1 | ||
508 | |||
509 | ADD lt_0,m_0,lt_0 ; lt = lt+m | ||
510 | ADD,DC ht_0,%r0,ht_0 ; ht[0]++ | ||
511 | STD lt_0,0(r_ptr) ; rp[0] = lt[0] | ||
512 | STD ht_0,8(r_ptr) ; rp[1] = ht[1] | ||
513 | |||
514 | ADD lt_1,m_1,lt_1 ; lt = lt+m | ||
515 | ADD,DC ht_1,%r0,ht_1 ; ht[1]++ | ||
516 | STD lt_1,16(r_ptr) ; rp[2] = lt[1] | ||
517 | STD ht_1,24(r_ptr) ; rp[3] = ht[1] | ||
518 | |||
519 | LDO -2(num),num ; num = num - 2; | ||
520 | LDO 16(a_ptr),a_ptr ; ap += 2 | ||
521 | CMPIB,<= 2,num,bn_sqr_words_unroll2 | ||
522 | LDO 32(r_ptr),r_ptr ; rp += 4 | ||
523 | |||
524 | CMPIB,=,N 0,num,bn_sqr_words_exit ; are we done? | ||
525 | |||
526 | ; | ||
527 | ; Top of loop aligned on 64-byte boundary | ||
528 | ; | ||
529 | bn_sqr_words_single_top | ||
530 | FLDD 0(a_ptr),t_float_0 ; load up 64-bit value (fr8L) ht(L)/lt(R) | ||
531 | |||
532 | XMPYU fht_0,flt_0,fm ; m | ||
533 | FSTD fm,-24(%sp) ; store m | ||
534 | |||
535 | XMPYU flt_0,flt_0,lt_temp ; lt | ||
536 | FSTD lt_temp,-16(%sp) ; store lt | ||
537 | |||
538 | XMPYU fht_0,fht_0,ht_temp ; ht | ||
539 | FSTD ht_temp,-8(%sp) ; store ht | ||
540 | |||
541 | LDD -24(%sp),m_0 ; load m | ||
542 | AND m_0,high_mask,tmp_0 ; m & Mask | ||
543 | DEPD,Z m_0,30,31,m_0 ; m << 32+1 | ||
544 | LDD -16(%sp),lt_0 ; lt | ||
545 | |||
546 | LDD -8(%sp),ht_0 ; ht | ||
547 | EXTRD,U tmp_0,32,33,tmp_0 ; tmp_0 = m&Mask >> 32-1 | ||
548 | ADD m_0,lt_0,lt_0 ; lt = lt+m | ||
549 | ADD,L ht_0,tmp_0,ht_0 ; ht += tmp_0 | ||
550 | ADD,DC ht_0,%r0,ht_0 ; ht++ | ||
551 | |||
552 | STD lt_0,0(r_ptr) ; rp[0] = lt | ||
553 | STD ht_0,8(r_ptr) ; rp[1] = ht | ||
554 | |||
555 | bn_sqr_words_exit | ||
556 | .EXIT | ||
557 | LDD -112(%sp),%r5 ; restore r5 | ||
558 | LDD -120(%sp),%r4 ; restore r4 | ||
559 | BVE (%rp) | ||
560 | LDD,MB -128(%sp),%r3 | ||
561 | .PROCEND ;in=23,24,25,26,29;out=28; | ||
562 | |||
563 | |||
564 | ;---------------------------------------------------------------------------- | ||
565 | ; | ||
566 | ;BN_ULONG bn_add_words(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n) | ||
567 | ; | ||
568 | ; arg0 = rp | ||
569 | ; arg1 = ap | ||
570 | ; arg2 = bp | ||
571 | ; arg3 = n | ||
572 | |||
573 | t .reg %r22 | ||
574 | b .reg %r21 | ||
575 | l .reg %r20 | ||
576 | |||
577 | bn_add_words | ||
578 | .proc | ||
579 | .entry | ||
580 | .callinfo | ||
581 | .EXPORT bn_add_words,ENTRY,PRIV_LEV=3,NO_RELOCATION,LONG_RETURN | ||
582 | .align 64 | ||
583 | |||
584 | CMPIB,>= 0,n,bn_add_words_exit | ||
585 | COPY %r0,%ret0 ; return 0 by default | ||
586 | |||
587 | ; | ||
588 | ; If 2 or more numbers do the loop | ||
589 | ; | ||
590 | CMPIB,= 1,n,bn_add_words_single_top | ||
591 | NOP | ||
592 | |||
593 | ; | ||
594 | ; This loop is unrolled 2 times (64-byte aligned as well) | ||
595 | ; | ||
596 | bn_add_words_unroll2 | ||
597 | LDD 0(a_ptr),t | ||
598 | LDD 0(b_ptr),b | ||
599 | ADD t,%ret0,t ; t = t+c; | ||
600 | ADD,DC %r0,%r0,%ret0 ; set c to carry | ||
601 | ADD t,b,l ; l = t + b[0] | ||
602 | ADD,DC %ret0,%r0,%ret0 ; c+= carry | ||
603 | STD l,0(r_ptr) | ||
604 | |||
605 | LDD 8(a_ptr),t | ||
606 | LDD 8(b_ptr),b | ||
607 | ADD t,%ret0,t ; t = t+c; | ||
608 | ADD,DC %r0,%r0,%ret0 ; set c to carry | ||
609 | ADD t,b,l ; l = t + b[0] | ||
610 | ADD,DC %ret0,%r0,%ret0 ; c+= carry | ||
611 | STD l,8(r_ptr) | ||
612 | |||
613 | LDO -2(n),n | ||
614 | LDO 16(a_ptr),a_ptr | ||
615 | LDO 16(b_ptr),b_ptr | ||
616 | |||
617 | CMPIB,<= 2,n,bn_add_words_unroll2 | ||
618 | LDO 16(r_ptr),r_ptr | ||
619 | |||
620 | CMPIB,=,N 0,n,bn_add_words_exit ; are we done? | ||
621 | |||
622 | bn_add_words_single_top | ||
623 | LDD 0(a_ptr),t | ||
624 | LDD 0(b_ptr),b | ||
625 | |||
626 | ADD t,%ret0,t ; t = t+c; | ||
627 | ADD,DC %r0,%r0,%ret0 ; set c to carry (could use CMPCLR??) | ||
628 | ADD t,b,l ; l = t + b[0] | ||
629 | ADD,DC %ret0,%r0,%ret0 ; c+= carry | ||
630 | STD l,0(r_ptr) | ||
631 | |||
632 | bn_add_words_exit | ||
633 | .EXIT | ||
634 | BVE (%rp) | ||
635 | NOP | ||
636 | .PROCEND ;in=23,24,25,26,29;out=28; | ||
637 | |||
638 | ;---------------------------------------------------------------------------- | ||
639 | ; | ||
640 | ;BN_ULONG bn_sub_words(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n) | ||
641 | ; | ||
642 | ; arg0 = rp | ||
643 | ; arg1 = ap | ||
644 | ; arg2 = bp | ||
645 | ; arg3 = n | ||
646 | |||
647 | t1 .reg %r22 | ||
648 | t2 .reg %r21 | ||
649 | sub_tmp1 .reg %r20 | ||
650 | sub_tmp2 .reg %r19 | ||
651 | |||
652 | |||
653 | bn_sub_words | ||
654 | .proc | ||
655 | .callinfo | ||
656 | .EXPORT bn_sub_words,ENTRY,PRIV_LEV=3,NO_RELOCATION,LONG_RETURN | ||
657 | .entry | ||
658 | .align 64 | ||
659 | |||
660 | CMPIB,>= 0,n,bn_sub_words_exit | ||
661 | COPY %r0,%ret0 ; return 0 by default | ||
662 | |||
663 | ; | ||
664 | ; If 2 or more numbers do the loop | ||
665 | ; | ||
666 | CMPIB,= 1,n,bn_sub_words_single_top | ||
667 | NOP | ||
668 | |||
669 | ; | ||
670 | ; This loop is unrolled 2 times (64-byte aligned as well) | ||
671 | ; | ||
672 | bn_sub_words_unroll2 | ||
673 | LDD 0(a_ptr),t1 | ||
674 | LDD 0(b_ptr),t2 | ||
675 | SUB t1,t2,sub_tmp1 ; t3 = t1-t2; | ||
676 | SUB sub_tmp1,%ret0,sub_tmp1 ; t3 = t3- c; | ||
677 | |||
678 | CMPCLR,*>> t1,t2,sub_tmp2 ; clear if t1 > t2 | ||
679 | LDO 1(%r0),sub_tmp2 | ||
680 | |||
681 | CMPCLR,*= t1,t2,%r0 | ||
682 | COPY sub_tmp2,%ret0 | ||
683 | STD sub_tmp1,0(r_ptr) | ||
684 | |||
685 | LDD 8(a_ptr),t1 | ||
686 | LDD 8(b_ptr),t2 | ||
687 | SUB t1,t2,sub_tmp1 ; t3 = t1-t2; | ||
688 | SUB sub_tmp1,%ret0,sub_tmp1 ; t3 = t3- c; | ||
689 | CMPCLR,*>> t1,t2,sub_tmp2 ; clear if t1 > t2 | ||
690 | LDO 1(%r0),sub_tmp2 | ||
691 | |||
692 | CMPCLR,*= t1,t2,%r0 | ||
693 | COPY sub_tmp2,%ret0 | ||
694 | STD sub_tmp1,8(r_ptr) | ||
695 | |||
696 | LDO -2(n),n | ||
697 | LDO 16(a_ptr),a_ptr | ||
698 | LDO 16(b_ptr),b_ptr | ||
699 | |||
700 | CMPIB,<= 2,n,bn_sub_words_unroll2 | ||
701 | LDO 16(r_ptr),r_ptr | ||
702 | |||
703 | CMPIB,=,N 0,n,bn_sub_words_exit ; are we done? | ||
704 | |||
705 | bn_sub_words_single_top | ||
706 | LDD 0(a_ptr),t1 | ||
707 | LDD 0(b_ptr),t2 | ||
708 | SUB t1,t2,sub_tmp1 ; t3 = t1-t2; | ||
709 | SUB sub_tmp1,%ret0,sub_tmp1 ; t3 = t3- c; | ||
710 | CMPCLR,*>> t1,t2,sub_tmp2 ; clear if t1 > t2 | ||
711 | LDO 1(%r0),sub_tmp2 | ||
712 | |||
713 | CMPCLR,*= t1,t2,%r0 | ||
714 | COPY sub_tmp2,%ret0 | ||
715 | |||
716 | STD sub_tmp1,0(r_ptr) | ||
717 | |||
718 | bn_sub_words_exit | ||
719 | .EXIT | ||
720 | BVE (%rp) | ||
721 | NOP | ||
722 | .PROCEND ;in=23,24,25,26,29;out=28; | ||
723 | |||
724 | ;------------------------------------------------------------------------------ | ||
725 | ; | ||
726 | ; unsigned long bn_div_words(unsigned long h, unsigned long l, unsigned long d) | ||
727 | ; | ||
728 | ; arg0 = h | ||
729 | ; arg1 = l | ||
730 | ; arg2 = d | ||
731 | ; | ||
732 | ; This is mainly just modified assembly from the compiler, thus the | ||
733 | ; lack of variable names. | ||
734 | ; | ||
735 | ;------------------------------------------------------------------------------ | ||
736 | bn_div_words | ||
737 | .proc | ||
738 | .callinfo CALLER,FRAME=272,ENTRY_GR=%r10,SAVE_RP,ARGS_SAVED,ORDERING_AWARE | ||
739 | .EXPORT bn_div_words,ENTRY,PRIV_LEV=3,NO_RELOCATION,LONG_RETURN | ||
740 | .IMPORT BN_num_bits_word,CODE,NO_RELOCATION | ||
741 | .IMPORT __iob,DATA | ||
742 | .IMPORT fprintf,CODE,NO_RELOCATION | ||
743 | .IMPORT abort,CODE,NO_RELOCATION | ||
744 | .IMPORT $$div2U,MILLICODE | ||
745 | .entry | ||
746 | STD %r2,-16(%r30) | ||
747 | STD,MA %r3,352(%r30) | ||
748 | STD %r4,-344(%r30) | ||
749 | STD %r5,-336(%r30) | ||
750 | STD %r6,-328(%r30) | ||
751 | STD %r7,-320(%r30) | ||
752 | STD %r8,-312(%r30) | ||
753 | STD %r9,-304(%r30) | ||
754 | STD %r10,-296(%r30) | ||
755 | |||
756 | STD %r27,-288(%r30) ; save gp | ||
757 | |||
758 | COPY %r24,%r3 ; save d | ||
759 | COPY %r26,%r4 ; save h (high 64-bits) | ||
760 | LDO -1(%r0),%ret0 ; return -1 by default | ||
761 | |||
762 | CMPB,*= %r0,%arg2,$D3 ; if (d == 0) | ||
763 | COPY %r25,%r5 ; save l (low 64-bits) | ||
764 | |||
765 | LDO -48(%r30),%r29 ; create ap | ||
766 | .CALL ;in=26,29;out=28; | ||
767 | B,L BN_num_bits_word,%r2 | ||
768 | COPY %r3,%r26 | ||
769 | LDD -288(%r30),%r27 ; restore gp | ||
770 | LDI 64,%r21 | ||
771 | |||
772 | CMPB,= %r21,%ret0,$00000012 ;if (i == 64) (forward) | ||
773 | COPY %ret0,%r24 ; i | ||
774 | MTSARCM %r24 | ||
775 | DEPDI,Z -1,%sar,1,%r29 | ||
776 | CMPB,*<<,N %r29,%r4,bn_div_err_case ; if (h > 1<<i) (forward) | ||
777 | |||
778 | $00000012 | ||
779 | SUBI 64,%r24,%r31 ; i = 64 - i; | ||
780 | CMPCLR,*<< %r4,%r3,%r0 ; if (h >= d) | ||
781 | SUB %r4,%r3,%r4 ; h -= d | ||
782 | CMPB,= %r31,%r0,$0000001A ; if (i) | ||
783 | COPY %r0,%r10 ; ret = 0 | ||
784 | MTSARCM %r31 ; i to shift | ||
785 | DEPD,Z %r3,%sar,64,%r3 ; d <<= i; | ||
786 | SUBI 64,%r31,%r19 ; 64 - i; redundent | ||
787 | MTSAR %r19 ; (64 -i) to shift | ||
788 | SHRPD %r4,%r5,%sar,%r4 ; l>> (64-i) | ||
789 | MTSARCM %r31 ; i to shift | ||
790 | DEPD,Z %r5,%sar,64,%r5 ; l <<= i; | ||
791 | |||
792 | $0000001A | ||
793 | DEPDI,Z -1,31,32,%r19 | ||
794 | EXTRD,U %r3,31,32,%r6 ; dh=(d&0xfff)>>32 | ||
795 | EXTRD,U %r3,63,32,%r8 ; dl = d&0xffffff | ||
796 | LDO 2(%r0),%r9 | ||
797 | STD %r3,-280(%r30) ; "d" to stack | ||
798 | |||
799 | $0000001C | ||
800 | DEPDI,Z -1,63,32,%r29 ; | ||
801 | EXTRD,U %r4,31,32,%r31 ; h >> 32 | ||
802 | CMPB,*=,N %r31,%r6,$D2 ; if ((h>>32) != dh)(forward) div | ||
803 | COPY %r4,%r26 | ||
804 | EXTRD,U %r4,31,32,%r25 | ||
805 | COPY %r6,%r24 | ||
806 | .CALL ;in=23,24,25,26;out=20,21,22,28,29; (MILLICALL) | ||
807 | B,L $$div2U,%r2 | ||
808 | EXTRD,U %r6,31,32,%r23 | ||
809 | DEPD %r28,31,32,%r29 | ||
810 | $D2 | ||
811 | STD %r29,-272(%r30) ; q | ||
812 | AND %r5,%r19,%r24 ; t & 0xffffffff00000000; | ||
813 | EXTRD,U %r24,31,32,%r24 ; ??? | ||
814 | FLDD -272(%r30),%fr7 ; q | ||
815 | FLDD -280(%r30),%fr8 ; d | ||
816 | XMPYU %fr8L,%fr7L,%fr10 | ||
817 | FSTD %fr10,-256(%r30) | ||
818 | XMPYU %fr8L,%fr7R,%fr22 | ||
819 | FSTD %fr22,-264(%r30) | ||
820 | XMPYU %fr8R,%fr7L,%fr11 | ||
821 | XMPYU %fr8R,%fr7R,%fr23 | ||
822 | FSTD %fr11,-232(%r30) | ||
823 | FSTD %fr23,-240(%r30) | ||
824 | LDD -256(%r30),%r28 | ||
825 | DEPD,Z %r28,31,32,%r2 | ||
826 | LDD -264(%r30),%r20 | ||
827 | ADD,L %r20,%r2,%r31 | ||
828 | LDD -232(%r30),%r22 | ||
829 | DEPD,Z %r22,31,32,%r22 | ||
830 | LDD -240(%r30),%r21 | ||
831 | B $00000024 ; enter loop | ||
832 | ADD,L %r21,%r22,%r23 | ||
833 | |||
834 | $0000002A | ||
835 | LDO -1(%r29),%r29 | ||
836 | SUB %r23,%r8,%r23 | ||
837 | $00000024 | ||
838 | SUB %r4,%r31,%r25 | ||
839 | AND %r25,%r19,%r26 | ||
840 | CMPB,*<>,N %r0,%r26,$00000046 ; (forward) | ||
841 | DEPD,Z %r25,31,32,%r20 | ||
842 | OR %r20,%r24,%r21 | ||
843 | CMPB,*<<,N %r21,%r23,$0000002A ;(backward) | ||
844 | SUB %r31,%r6,%r31 | ||
845 | ;-------------Break path--------------------- | ||
846 | |||
847 | $00000046 | ||
848 | DEPD,Z %r23,31,32,%r25 ;tl | ||
849 | EXTRD,U %r23,31,32,%r26 ;t | ||
850 | AND %r25,%r19,%r24 ;tl = (tl<<32)&0xfffffff0000000L | ||
851 | ADD,L %r31,%r26,%r31 ;th += t; | ||
852 | CMPCLR,*>>= %r5,%r24,%r0 ;if (l<tl) | ||
853 | LDO 1(%r31),%r31 ; th++; | ||
854 | CMPB,*<<=,N %r31,%r4,$00000036 ;if (n < th) (forward) | ||
855 | LDO -1(%r29),%r29 ;q--; | ||
856 | ADD,L %r4,%r3,%r4 ;h += d; | ||
857 | $00000036 | ||
858 | ADDIB,=,N -1,%r9,$D1 ;if (--count == 0) break (forward) | ||
859 | SUB %r5,%r24,%r28 ; l -= tl; | ||
860 | SUB %r4,%r31,%r24 ; h -= th; | ||
861 | SHRPD %r24,%r28,32,%r4 ; h = ((h<<32)|(l>>32)); | ||
862 | DEPD,Z %r29,31,32,%r10 ; ret = q<<32 | ||
863 | b $0000001C | ||
864 | DEPD,Z %r28,31,32,%r5 ; l = l << 32 | ||
865 | |||
866 | $D1 | ||
867 | OR %r10,%r29,%r28 ; ret |= q | ||
868 | $D3 | ||
869 | LDD -368(%r30),%r2 | ||
870 | $D0 | ||
871 | LDD -296(%r30),%r10 | ||
872 | LDD -304(%r30),%r9 | ||
873 | LDD -312(%r30),%r8 | ||
874 | LDD -320(%r30),%r7 | ||
875 | LDD -328(%r30),%r6 | ||
876 | LDD -336(%r30),%r5 | ||
877 | LDD -344(%r30),%r4 | ||
878 | BVE (%r2) | ||
879 | .EXIT | ||
880 | LDD,MB -352(%r30),%r3 | ||
881 | |||
882 | bn_div_err_case | ||
883 | MFIA %r6 | ||
884 | ADDIL L'bn_div_words-bn_div_err_case,%r6,%r1 | ||
885 | LDO R'bn_div_words-bn_div_err_case(%r1),%r6 | ||
886 | ADDIL LT'__iob,%r27,%r1 | ||
887 | LDD RT'__iob(%r1),%r26 | ||
888 | ADDIL L'C$4-bn_div_words,%r6,%r1 | ||
889 | LDO R'C$4-bn_div_words(%r1),%r25 | ||
890 | LDO 64(%r26),%r26 | ||
891 | .CALL ;in=24,25,26,29;out=28; | ||
892 | B,L fprintf,%r2 | ||
893 | LDO -48(%r30),%r29 | ||
894 | LDD -288(%r30),%r27 | ||
895 | .CALL ;in=29; | ||
896 | B,L abort,%r2 | ||
897 | LDO -48(%r30),%r29 | ||
898 | LDD -288(%r30),%r27 | ||
899 | B $D0 | ||
900 | LDD -368(%r30),%r2 | ||
901 | .PROCEND ;in=24,25,26,29;out=28; | ||
902 | |||
903 | ;---------------------------------------------------------------------------- | ||
904 | ; | ||
905 | ; Registers to hold 64-bit values to manipulate. The "L" part | ||
906 | ; of the register corresponds to the upper 32-bits, while the "R" | ||
907 | ; part corresponds to the lower 32-bits | ||
908 | ; | ||
909 | ; Note, that when using b6 and b7, the code must save these before | ||
910 | ; using them because they are callee save registers | ||
911 | ; | ||
912 | ; | ||
913 | ; Floating point registers to use to save values that | ||
914 | ; are manipulated. These don't collide with ftemp1-6 and | ||
915 | ; are all caller save registers | ||
916 | ; | ||
917 | a0 .reg %fr22 | ||
918 | a0L .reg %fr22L | ||
919 | a0R .reg %fr22R | ||
920 | |||
921 | a1 .reg %fr23 | ||
922 | a1L .reg %fr23L | ||
923 | a1R .reg %fr23R | ||
924 | |||
925 | a2 .reg %fr24 | ||
926 | a2L .reg %fr24L | ||
927 | a2R .reg %fr24R | ||
928 | |||
929 | a3 .reg %fr25 | ||
930 | a3L .reg %fr25L | ||
931 | a3R .reg %fr25R | ||
932 | |||
933 | a4 .reg %fr26 | ||
934 | a4L .reg %fr26L | ||
935 | a4R .reg %fr26R | ||
936 | |||
937 | a5 .reg %fr27 | ||
938 | a5L .reg %fr27L | ||
939 | a5R .reg %fr27R | ||
940 | |||
941 | a6 .reg %fr28 | ||
942 | a6L .reg %fr28L | ||
943 | a6R .reg %fr28R | ||
944 | |||
945 | a7 .reg %fr29 | ||
946 | a7L .reg %fr29L | ||
947 | a7R .reg %fr29R | ||
948 | |||
949 | b0 .reg %fr30 | ||
950 | b0L .reg %fr30L | ||
951 | b0R .reg %fr30R | ||
952 | |||
953 | b1 .reg %fr31 | ||
954 | b1L .reg %fr31L | ||
955 | b1R .reg %fr31R | ||
956 | |||
957 | ; | ||
958 | ; Temporary floating point variables, these are all caller save | ||
959 | ; registers | ||
960 | ; | ||
961 | ftemp1 .reg %fr4 | ||
962 | ftemp2 .reg %fr5 | ||
963 | ftemp3 .reg %fr6 | ||
964 | ftemp4 .reg %fr7 | ||
965 | |||
966 | ; | ||
967 | ; The B set of registers when used. | ||
968 | ; | ||
969 | |||
970 | b2 .reg %fr8 | ||
971 | b2L .reg %fr8L | ||
972 | b2R .reg %fr8R | ||
973 | |||
974 | b3 .reg %fr9 | ||
975 | b3L .reg %fr9L | ||
976 | b3R .reg %fr9R | ||
977 | |||
978 | b4 .reg %fr10 | ||
979 | b4L .reg %fr10L | ||
980 | b4R .reg %fr10R | ||
981 | |||
982 | b5 .reg %fr11 | ||
983 | b5L .reg %fr11L | ||
984 | b5R .reg %fr11R | ||
985 | |||
986 | b6 .reg %fr12 | ||
987 | b6L .reg %fr12L | ||
988 | b6R .reg %fr12R | ||
989 | |||
990 | b7 .reg %fr13 | ||
991 | b7L .reg %fr13L | ||
992 | b7R .reg %fr13R | ||
993 | |||
994 | c1 .reg %r21 ; only reg | ||
995 | temp1 .reg %r20 ; only reg | ||
996 | temp2 .reg %r19 ; only reg | ||
997 | temp3 .reg %r31 ; only reg | ||
998 | |||
999 | m1 .reg %r28 | ||
1000 | c2 .reg %r23 | ||
1001 | high_one .reg %r1 | ||
1002 | ht .reg %r6 | ||
1003 | lt .reg %r5 | ||
1004 | m .reg %r4 | ||
1005 | c3 .reg %r3 | ||
1006 | |||
1007 | SQR_ADD_C .macro A0L,A0R,C1,C2,C3 | ||
1008 | XMPYU A0L,A0R,ftemp1 ; m | ||
1009 | FSTD ftemp1,-24(%sp) ; store m | ||
1010 | |||
1011 | XMPYU A0R,A0R,ftemp2 ; lt | ||
1012 | FSTD ftemp2,-16(%sp) ; store lt | ||
1013 | |||
1014 | XMPYU A0L,A0L,ftemp3 ; ht | ||
1015 | FSTD ftemp3,-8(%sp) ; store ht | ||
1016 | |||
1017 | LDD -24(%sp),m ; load m | ||
1018 | AND m,high_mask,temp2 ; m & Mask | ||
1019 | DEPD,Z m,30,31,temp3 ; m << 32+1 | ||
1020 | LDD -16(%sp),lt ; lt | ||
1021 | |||
1022 | LDD -8(%sp),ht ; ht | ||
1023 | EXTRD,U temp2,32,33,temp1 ; temp1 = m&Mask >> 32-1 | ||
1024 | ADD temp3,lt,lt ; lt = lt+m | ||
1025 | ADD,L ht,temp1,ht ; ht += temp1 | ||
1026 | ADD,DC ht,%r0,ht ; ht++ | ||
1027 | |||
1028 | ADD C1,lt,C1 ; c1=c1+lt | ||
1029 | ADD,DC ht,%r0,ht ; ht++ | ||
1030 | |||
1031 | ADD C2,ht,C2 ; c2=c2+ht | ||
1032 | ADD,DC C3,%r0,C3 ; c3++ | ||
1033 | .endm | ||
1034 | |||
1035 | SQR_ADD_C2 .macro A0L,A0R,A1L,A1R,C1,C2,C3 | ||
1036 | XMPYU A0L,A1R,ftemp1 ; m1 = bl*ht | ||
1037 | FSTD ftemp1,-16(%sp) ; | ||
1038 | XMPYU A0R,A1L,ftemp2 ; m = bh*lt | ||
1039 | FSTD ftemp2,-8(%sp) ; | ||
1040 | XMPYU A0R,A1R,ftemp3 ; lt = bl*lt | ||
1041 | FSTD ftemp3,-32(%sp) | ||
1042 | XMPYU A0L,A1L,ftemp4 ; ht = bh*ht | ||
1043 | FSTD ftemp4,-24(%sp) ; | ||
1044 | |||
1045 | LDD -8(%sp),m ; r21 = m | ||
1046 | LDD -16(%sp),m1 ; r19 = m1 | ||
1047 | ADD,L m,m1,m ; m+m1 | ||
1048 | |||
1049 | DEPD,Z m,31,32,temp3 ; (m+m1<<32) | ||
1050 | LDD -24(%sp),ht ; r24 = ht | ||
1051 | |||
1052 | CMPCLR,*>>= m,m1,%r0 ; if (m < m1) | ||
1053 | ADD,L ht,high_one,ht ; ht+=high_one | ||
1054 | |||
1055 | EXTRD,U m,31,32,temp1 ; m >> 32 | ||
1056 | LDD -32(%sp),lt ; lt | ||
1057 | ADD,L ht,temp1,ht ; ht+= m>>32 | ||
1058 | ADD lt,temp3,lt ; lt = lt+m1 | ||
1059 | ADD,DC ht,%r0,ht ; ht++ | ||
1060 | |||
1061 | ADD ht,ht,ht ; ht=ht+ht; | ||
1062 | ADD,DC C3,%r0,C3 ; add in carry (c3++) | ||
1063 | |||
1064 | ADD lt,lt,lt ; lt=lt+lt; | ||
1065 | ADD,DC ht,%r0,ht ; add in carry (ht++) | ||
1066 | |||
1067 | ADD C1,lt,C1 ; c1=c1+lt | ||
1068 | ADD,DC,*NUV ht,%r0,ht ; add in carry (ht++) | ||
1069 | LDO 1(C3),C3 ; bump c3 if overflow,nullify otherwise | ||
1070 | |||
1071 | ADD C2,ht,C2 ; c2 = c2 + ht | ||
1072 | ADD,DC C3,%r0,C3 ; add in carry (c3++) | ||
1073 | .endm | ||
1074 | |||
1075 | ; | ||
1076 | ;void bn_sqr_comba8(BN_ULONG *r, BN_ULONG *a) | ||
1077 | ; arg0 = r_ptr | ||
1078 | ; arg1 = a_ptr | ||
1079 | ; | ||
1080 | |||
1081 | bn_sqr_comba8 | ||
1082 | .PROC | ||
1083 | .CALLINFO FRAME=128,ENTRY_GR=%r3,ARGS_SAVED,ORDERING_AWARE | ||
1084 | .EXPORT bn_sqr_comba8,ENTRY,PRIV_LEV=3,NO_RELOCATION,LONG_RETURN | ||
1085 | .ENTRY | ||
1086 | .align 64 | ||
1087 | |||
1088 | STD %r3,0(%sp) ; save r3 | ||
1089 | STD %r4,8(%sp) ; save r4 | ||
1090 | STD %r5,16(%sp) ; save r5 | ||
1091 | STD %r6,24(%sp) ; save r6 | ||
1092 | |||
1093 | ; | ||
1094 | ; Zero out carries | ||
1095 | ; | ||
1096 | COPY %r0,c1 | ||
1097 | COPY %r0,c2 | ||
1098 | COPY %r0,c3 | ||
1099 | |||
1100 | LDO 128(%sp),%sp ; bump stack | ||
1101 | DEPDI,Z -1,32,33,high_mask ; Create Mask 0xffffffff80000000L | ||
1102 | DEPDI,Z 1,31,1,high_one ; Create Value 1 << 32 | ||
1103 | |||
1104 | ; | ||
1105 | ; Load up all of the values we are going to use | ||
1106 | ; | ||
1107 | FLDD 0(a_ptr),a0 | ||
1108 | FLDD 8(a_ptr),a1 | ||
1109 | FLDD 16(a_ptr),a2 | ||
1110 | FLDD 24(a_ptr),a3 | ||
1111 | FLDD 32(a_ptr),a4 | ||
1112 | FLDD 40(a_ptr),a5 | ||
1113 | FLDD 48(a_ptr),a6 | ||
1114 | FLDD 56(a_ptr),a7 | ||
1115 | |||
1116 | SQR_ADD_C a0L,a0R,c1,c2,c3 | ||
1117 | STD c1,0(r_ptr) ; r[0] = c1; | ||
1118 | COPY %r0,c1 | ||
1119 | |||
1120 | SQR_ADD_C2 a1L,a1R,a0L,a0R,c2,c3,c1 | ||
1121 | STD c2,8(r_ptr) ; r[1] = c2; | ||
1122 | COPY %r0,c2 | ||
1123 | |||
1124 | SQR_ADD_C a1L,a1R,c3,c1,c2 | ||
1125 | SQR_ADD_C2 a2L,a2R,a0L,a0R,c3,c1,c2 | ||
1126 | STD c3,16(r_ptr) ; r[2] = c3; | ||
1127 | COPY %r0,c3 | ||
1128 | |||
1129 | SQR_ADD_C2 a3L,a3R,a0L,a0R,c1,c2,c3 | ||
1130 | SQR_ADD_C2 a2L,a2R,a1L,a1R,c1,c2,c3 | ||
1131 | STD c1,24(r_ptr) ; r[3] = c1; | ||
1132 | COPY %r0,c1 | ||
1133 | |||
1134 | SQR_ADD_C a2L,a2R,c2,c3,c1 | ||
1135 | SQR_ADD_C2 a3L,a3R,a1L,a1R,c2,c3,c1 | ||
1136 | SQR_ADD_C2 a4L,a4R,a0L,a0R,c2,c3,c1 | ||
1137 | STD c2,32(r_ptr) ; r[4] = c2; | ||
1138 | COPY %r0,c2 | ||
1139 | |||
1140 | SQR_ADD_C2 a5L,a5R,a0L,a0R,c3,c1,c2 | ||
1141 | SQR_ADD_C2 a4L,a4R,a1L,a1R,c3,c1,c2 | ||
1142 | SQR_ADD_C2 a3L,a3R,a2L,a2R,c3,c1,c2 | ||
1143 | STD c3,40(r_ptr) ; r[5] = c3; | ||
1144 | COPY %r0,c3 | ||
1145 | |||
1146 | SQR_ADD_C a3L,a3R,c1,c2,c3 | ||
1147 | SQR_ADD_C2 a4L,a4R,a2L,a2R,c1,c2,c3 | ||
1148 | SQR_ADD_C2 a5L,a5R,a1L,a1R,c1,c2,c3 | ||
1149 | SQR_ADD_C2 a6L,a6R,a0L,a0R,c1,c2,c3 | ||
1150 | STD c1,48(r_ptr) ; r[6] = c1; | ||
1151 | COPY %r0,c1 | ||
1152 | |||
1153 | SQR_ADD_C2 a7L,a7R,a0L,a0R,c2,c3,c1 | ||
1154 | SQR_ADD_C2 a6L,a6R,a1L,a1R,c2,c3,c1 | ||
1155 | SQR_ADD_C2 a5L,a5R,a2L,a2R,c2,c3,c1 | ||
1156 | SQR_ADD_C2 a4L,a4R,a3L,a3R,c2,c3,c1 | ||
1157 | STD c2,56(r_ptr) ; r[7] = c2; | ||
1158 | COPY %r0,c2 | ||
1159 | |||
1160 | SQR_ADD_C a4L,a4R,c3,c1,c2 | ||
1161 | SQR_ADD_C2 a5L,a5R,a3L,a3R,c3,c1,c2 | ||
1162 | SQR_ADD_C2 a6L,a6R,a2L,a2R,c3,c1,c2 | ||
1163 | SQR_ADD_C2 a7L,a7R,a1L,a1R,c3,c1,c2 | ||
1164 | STD c3,64(r_ptr) ; r[8] = c3; | ||
1165 | COPY %r0,c3 | ||
1166 | |||
1167 | SQR_ADD_C2 a7L,a7R,a2L,a2R,c1,c2,c3 | ||
1168 | SQR_ADD_C2 a6L,a6R,a3L,a3R,c1,c2,c3 | ||
1169 | SQR_ADD_C2 a5L,a5R,a4L,a4R,c1,c2,c3 | ||
1170 | STD c1,72(r_ptr) ; r[9] = c1; | ||
1171 | COPY %r0,c1 | ||
1172 | |||
1173 | SQR_ADD_C a5L,a5R,c2,c3,c1 | ||
1174 | SQR_ADD_C2 a6L,a6R,a4L,a4R,c2,c3,c1 | ||
1175 | SQR_ADD_C2 a7L,a7R,a3L,a3R,c2,c3,c1 | ||
1176 | STD c2,80(r_ptr) ; r[10] = c2; | ||
1177 | COPY %r0,c2 | ||
1178 | |||
1179 | SQR_ADD_C2 a7L,a7R,a4L,a4R,c3,c1,c2 | ||
1180 | SQR_ADD_C2 a6L,a6R,a5L,a5R,c3,c1,c2 | ||
1181 | STD c3,88(r_ptr) ; r[11] = c3; | ||
1182 | COPY %r0,c3 | ||
1183 | |||
1184 | SQR_ADD_C a6L,a6R,c1,c2,c3 | ||
1185 | SQR_ADD_C2 a7L,a7R,a5L,a5R,c1,c2,c3 | ||
1186 | STD c1,96(r_ptr) ; r[12] = c1; | ||
1187 | COPY %r0,c1 | ||
1188 | |||
1189 | SQR_ADD_C2 a7L,a7R,a6L,a6R,c2,c3,c1 | ||
1190 | STD c2,104(r_ptr) ; r[13] = c2; | ||
1191 | COPY %r0,c2 | ||
1192 | |||
1193 | SQR_ADD_C a7L,a7R,c3,c1,c2 | ||
1194 | STD c3, 112(r_ptr) ; r[14] = c3 | ||
1195 | STD c1, 120(r_ptr) ; r[15] = c1 | ||
1196 | |||
1197 | .EXIT | ||
1198 | LDD -104(%sp),%r6 ; restore r6 | ||
1199 | LDD -112(%sp),%r5 ; restore r5 | ||
1200 | LDD -120(%sp),%r4 ; restore r4 | ||
1201 | BVE (%rp) | ||
1202 | LDD,MB -128(%sp),%r3 | ||
1203 | |||
1204 | .PROCEND | ||
1205 | |||
1206 | ;----------------------------------------------------------------------------- | ||
1207 | ; | ||
1208 | ;void bn_sqr_comba4(BN_ULONG *r, BN_ULONG *a) | ||
1209 | ; arg0 = r_ptr | ||
1210 | ; arg1 = a_ptr | ||
1211 | ; | ||
1212 | |||
1213 | bn_sqr_comba4 | ||
1214 | .proc | ||
1215 | .callinfo FRAME=128,ENTRY_GR=%r3,ARGS_SAVED,ORDERING_AWARE | ||
1216 | .EXPORT bn_sqr_comba4,ENTRY,PRIV_LEV=3,NO_RELOCATION,LONG_RETURN | ||
1217 | .entry | ||
1218 | .align 64 | ||
1219 | STD %r3,0(%sp) ; save r3 | ||
1220 | STD %r4,8(%sp) ; save r4 | ||
1221 | STD %r5,16(%sp) ; save r5 | ||
1222 | STD %r6,24(%sp) ; save r6 | ||
1223 | |||
1224 | ; | ||
1225 | ; Zero out carries | ||
1226 | ; | ||
1227 | COPY %r0,c1 | ||
1228 | COPY %r0,c2 | ||
1229 | COPY %r0,c3 | ||
1230 | |||
1231 | LDO 128(%sp),%sp ; bump stack | ||
1232 | DEPDI,Z -1,32,33,high_mask ; Create Mask 0xffffffff80000000L | ||
1233 | DEPDI,Z 1,31,1,high_one ; Create Value 1 << 32 | ||
1234 | |||
1235 | ; | ||
1236 | ; Load up all of the values we are going to use | ||
1237 | ; | ||
1238 | FLDD 0(a_ptr),a0 | ||
1239 | FLDD 8(a_ptr),a1 | ||
1240 | FLDD 16(a_ptr),a2 | ||
1241 | FLDD 24(a_ptr),a3 | ||
1242 | FLDD 32(a_ptr),a4 | ||
1243 | FLDD 40(a_ptr),a5 | ||
1244 | FLDD 48(a_ptr),a6 | ||
1245 | FLDD 56(a_ptr),a7 | ||
1246 | |||
1247 | SQR_ADD_C a0L,a0R,c1,c2,c3 | ||
1248 | |||
1249 | STD c1,0(r_ptr) ; r[0] = c1; | ||
1250 | COPY %r0,c1 | ||
1251 | |||
1252 | SQR_ADD_C2 a1L,a1R,a0L,a0R,c2,c3,c1 | ||
1253 | |||
1254 | STD c2,8(r_ptr) ; r[1] = c2; | ||
1255 | COPY %r0,c2 | ||
1256 | |||
1257 | SQR_ADD_C a1L,a1R,c3,c1,c2 | ||
1258 | SQR_ADD_C2 a2L,a2R,a0L,a0R,c3,c1,c2 | ||
1259 | |||
1260 | STD c3,16(r_ptr) ; r[2] = c3; | ||
1261 | COPY %r0,c3 | ||
1262 | |||
1263 | SQR_ADD_C2 a3L,a3R,a0L,a0R,c1,c2,c3 | ||
1264 | SQR_ADD_C2 a2L,a2R,a1L,a1R,c1,c2,c3 | ||
1265 | |||
1266 | STD c1,24(r_ptr) ; r[3] = c1; | ||
1267 | COPY %r0,c1 | ||
1268 | |||
1269 | SQR_ADD_C a2L,a2R,c2,c3,c1 | ||
1270 | SQR_ADD_C2 a3L,a3R,a1L,a1R,c2,c3,c1 | ||
1271 | |||
1272 | STD c2,32(r_ptr) ; r[4] = c2; | ||
1273 | COPY %r0,c2 | ||
1274 | |||
1275 | SQR_ADD_C2 a3L,a3R,a2L,a2R,c3,c1,c2 | ||
1276 | STD c3,40(r_ptr) ; r[5] = c3; | ||
1277 | COPY %r0,c3 | ||
1278 | |||
1279 | SQR_ADD_C a3L,a3R,c1,c2,c3 | ||
1280 | STD c1,48(r_ptr) ; r[6] = c1; | ||
1281 | STD c2,56(r_ptr) ; r[7] = c2; | ||
1282 | |||
1283 | .EXIT | ||
1284 | LDD -104(%sp),%r6 ; restore r6 | ||
1285 | LDD -112(%sp),%r5 ; restore r5 | ||
1286 | LDD -120(%sp),%r4 ; restore r4 | ||
1287 | BVE (%rp) | ||
1288 | LDD,MB -128(%sp),%r3 | ||
1289 | |||
1290 | .PROCEND | ||
1291 | |||
1292 | |||
1293 | ;--------------------------------------------------------------------------- | ||
1294 | |||
1295 | MUL_ADD_C .macro A0L,A0R,B0L,B0R,C1,C2,C3 | ||
1296 | XMPYU A0L,B0R,ftemp1 ; m1 = bl*ht | ||
1297 | FSTD ftemp1,-16(%sp) ; | ||
1298 | XMPYU A0R,B0L,ftemp2 ; m = bh*lt | ||
1299 | FSTD ftemp2,-8(%sp) ; | ||
1300 | XMPYU A0R,B0R,ftemp3 ; lt = bl*lt | ||
1301 | FSTD ftemp3,-32(%sp) | ||
1302 | XMPYU A0L,B0L,ftemp4 ; ht = bh*ht | ||
1303 | FSTD ftemp4,-24(%sp) ; | ||
1304 | |||
1305 | LDD -8(%sp),m ; r21 = m | ||
1306 | LDD -16(%sp),m1 ; r19 = m1 | ||
1307 | ADD,L m,m1,m ; m+m1 | ||
1308 | |||
1309 | DEPD,Z m,31,32,temp3 ; (m+m1<<32) | ||
1310 | LDD -24(%sp),ht ; r24 = ht | ||
1311 | |||
1312 | CMPCLR,*>>= m,m1,%r0 ; if (m < m1) | ||
1313 | ADD,L ht,high_one,ht ; ht+=high_one | ||
1314 | |||
1315 | EXTRD,U m,31,32,temp1 ; m >> 32 | ||
1316 | LDD -32(%sp),lt ; lt | ||
1317 | ADD,L ht,temp1,ht ; ht+= m>>32 | ||
1318 | ADD lt,temp3,lt ; lt = lt+m1 | ||
1319 | ADD,DC ht,%r0,ht ; ht++ | ||
1320 | |||
1321 | ADD C1,lt,C1 ; c1=c1+lt | ||
1322 | ADD,DC ht,%r0,ht ; bump c3 if overflow,nullify otherwise | ||
1323 | |||
1324 | ADD C2,ht,C2 ; c2 = c2 + ht | ||
1325 | ADD,DC C3,%r0,C3 ; add in carry (c3++) | ||
1326 | .endm | ||
1327 | |||
1328 | |||
1329 | ; | ||
1330 | ;void bn_mul_comba8(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b) | ||
1331 | ; arg0 = r_ptr | ||
1332 | ; arg1 = a_ptr | ||
1333 | ; arg2 = b_ptr | ||
1334 | ; | ||
1335 | |||
1336 | bn_mul_comba8 | ||
1337 | .proc | ||
1338 | .callinfo FRAME=128,ENTRY_GR=%r3,ARGS_SAVED,ORDERING_AWARE | ||
1339 | .EXPORT bn_mul_comba8,ENTRY,PRIV_LEV=3,NO_RELOCATION,LONG_RETURN | ||
1340 | .entry | ||
1341 | .align 64 | ||
1342 | |||
1343 | STD %r3,0(%sp) ; save r3 | ||
1344 | STD %r4,8(%sp) ; save r4 | ||
1345 | STD %r5,16(%sp) ; save r5 | ||
1346 | STD %r6,24(%sp) ; save r6 | ||
1347 | FSTD %fr12,32(%sp) ; save r6 | ||
1348 | FSTD %fr13,40(%sp) ; save r7 | ||
1349 | |||
1350 | ; | ||
1351 | ; Zero out carries | ||
1352 | ; | ||
1353 | COPY %r0,c1 | ||
1354 | COPY %r0,c2 | ||
1355 | COPY %r0,c3 | ||
1356 | |||
1357 | LDO 128(%sp),%sp ; bump stack | ||
1358 | DEPDI,Z 1,31,1,high_one ; Create Value 1 << 32 | ||
1359 | |||
1360 | ; | ||
1361 | ; Load up all of the values we are going to use | ||
1362 | ; | ||
1363 | FLDD 0(a_ptr),a0 | ||
1364 | FLDD 8(a_ptr),a1 | ||
1365 | FLDD 16(a_ptr),a2 | ||
1366 | FLDD 24(a_ptr),a3 | ||
1367 | FLDD 32(a_ptr),a4 | ||
1368 | FLDD 40(a_ptr),a5 | ||
1369 | FLDD 48(a_ptr),a6 | ||
1370 | FLDD 56(a_ptr),a7 | ||
1371 | |||
1372 | FLDD 0(b_ptr),b0 | ||
1373 | FLDD 8(b_ptr),b1 | ||
1374 | FLDD 16(b_ptr),b2 | ||
1375 | FLDD 24(b_ptr),b3 | ||
1376 | FLDD 32(b_ptr),b4 | ||
1377 | FLDD 40(b_ptr),b5 | ||
1378 | FLDD 48(b_ptr),b6 | ||
1379 | FLDD 56(b_ptr),b7 | ||
1380 | |||
1381 | MUL_ADD_C a0L,a0R,b0L,b0R,c1,c2,c3 | ||
1382 | STD c1,0(r_ptr) | ||
1383 | COPY %r0,c1 | ||
1384 | |||
1385 | MUL_ADD_C a0L,a0R,b1L,b1R,c2,c3,c1 | ||
1386 | MUL_ADD_C a1L,a1R,b0L,b0R,c2,c3,c1 | ||
1387 | STD c2,8(r_ptr) | ||
1388 | COPY %r0,c2 | ||
1389 | |||
1390 | MUL_ADD_C a2L,a2R,b0L,b0R,c3,c1,c2 | ||
1391 | MUL_ADD_C a1L,a1R,b1L,b1R,c3,c1,c2 | ||
1392 | MUL_ADD_C a0L,a0R,b2L,b2R,c3,c1,c2 | ||
1393 | STD c3,16(r_ptr) | ||
1394 | COPY %r0,c3 | ||
1395 | |||
1396 | MUL_ADD_C a0L,a0R,b3L,b3R,c1,c2,c3 | ||
1397 | MUL_ADD_C a1L,a1R,b2L,b2R,c1,c2,c3 | ||
1398 | MUL_ADD_C a2L,a2R,b1L,b1R,c1,c2,c3 | ||
1399 | MUL_ADD_C a3L,a3R,b0L,b0R,c1,c2,c3 | ||
1400 | STD c1,24(r_ptr) | ||
1401 | COPY %r0,c1 | ||
1402 | |||
1403 | MUL_ADD_C a4L,a4R,b0L,b0R,c2,c3,c1 | ||
1404 | MUL_ADD_C a3L,a3R,b1L,b1R,c2,c3,c1 | ||
1405 | MUL_ADD_C a2L,a2R,b2L,b2R,c2,c3,c1 | ||
1406 | MUL_ADD_C a1L,a1R,b3L,b3R,c2,c3,c1 | ||
1407 | MUL_ADD_C a0L,a0R,b4L,b4R,c2,c3,c1 | ||
1408 | STD c2,32(r_ptr) | ||
1409 | COPY %r0,c2 | ||
1410 | |||
1411 | MUL_ADD_C a0L,a0R,b5L,b5R,c3,c1,c2 | ||
1412 | MUL_ADD_C a1L,a1R,b4L,b4R,c3,c1,c2 | ||
1413 | MUL_ADD_C a2L,a2R,b3L,b3R,c3,c1,c2 | ||
1414 | MUL_ADD_C a3L,a3R,b2L,b2R,c3,c1,c2 | ||
1415 | MUL_ADD_C a4L,a4R,b1L,b1R,c3,c1,c2 | ||
1416 | MUL_ADD_C a5L,a5R,b0L,b0R,c3,c1,c2 | ||
1417 | STD c3,40(r_ptr) | ||
1418 | COPY %r0,c3 | ||
1419 | |||
1420 | MUL_ADD_C a6L,a6R,b0L,b0R,c1,c2,c3 | ||
1421 | MUL_ADD_C a5L,a5R,b1L,b1R,c1,c2,c3 | ||
1422 | MUL_ADD_C a4L,a4R,b2L,b2R,c1,c2,c3 | ||
1423 | MUL_ADD_C a3L,a3R,b3L,b3R,c1,c2,c3 | ||
1424 | MUL_ADD_C a2L,a2R,b4L,b4R,c1,c2,c3 | ||
1425 | MUL_ADD_C a1L,a1R,b5L,b5R,c1,c2,c3 | ||
1426 | MUL_ADD_C a0L,a0R,b6L,b6R,c1,c2,c3 | ||
1427 | STD c1,48(r_ptr) | ||
1428 | COPY %r0,c1 | ||
1429 | |||
1430 | MUL_ADD_C a0L,a0R,b7L,b7R,c2,c3,c1 | ||
1431 | MUL_ADD_C a1L,a1R,b6L,b6R,c2,c3,c1 | ||
1432 | MUL_ADD_C a2L,a2R,b5L,b5R,c2,c3,c1 | ||
1433 | MUL_ADD_C a3L,a3R,b4L,b4R,c2,c3,c1 | ||
1434 | MUL_ADD_C a4L,a4R,b3L,b3R,c2,c3,c1 | ||
1435 | MUL_ADD_C a5L,a5R,b2L,b2R,c2,c3,c1 | ||
1436 | MUL_ADD_C a6L,a6R,b1L,b1R,c2,c3,c1 | ||
1437 | MUL_ADD_C a7L,a7R,b0L,b0R,c2,c3,c1 | ||
1438 | STD c2,56(r_ptr) | ||
1439 | COPY %r0,c2 | ||
1440 | |||
1441 | MUL_ADD_C a7L,a7R,b1L,b1R,c3,c1,c2 | ||
1442 | MUL_ADD_C a6L,a6R,b2L,b2R,c3,c1,c2 | ||
1443 | MUL_ADD_C a5L,a5R,b3L,b3R,c3,c1,c2 | ||
1444 | MUL_ADD_C a4L,a4R,b4L,b4R,c3,c1,c2 | ||
1445 | MUL_ADD_C a3L,a3R,b5L,b5R,c3,c1,c2 | ||
1446 | MUL_ADD_C a2L,a2R,b6L,b6R,c3,c1,c2 | ||
1447 | MUL_ADD_C a1L,a1R,b7L,b7R,c3,c1,c2 | ||
1448 | STD c3,64(r_ptr) | ||
1449 | COPY %r0,c3 | ||
1450 | |||
1451 | MUL_ADD_C a2L,a2R,b7L,b7R,c1,c2,c3 | ||
1452 | MUL_ADD_C a3L,a3R,b6L,b6R,c1,c2,c3 | ||
1453 | MUL_ADD_C a4L,a4R,b5L,b5R,c1,c2,c3 | ||
1454 | MUL_ADD_C a5L,a5R,b4L,b4R,c1,c2,c3 | ||
1455 | MUL_ADD_C a6L,a6R,b3L,b3R,c1,c2,c3 | ||
1456 | MUL_ADD_C a7L,a7R,b2L,b2R,c1,c2,c3 | ||
1457 | STD c1,72(r_ptr) | ||
1458 | COPY %r0,c1 | ||
1459 | |||
1460 | MUL_ADD_C a7L,a7R,b3L,b3R,c2,c3,c1 | ||
1461 | MUL_ADD_C a6L,a6R,b4L,b4R,c2,c3,c1 | ||
1462 | MUL_ADD_C a5L,a5R,b5L,b5R,c2,c3,c1 | ||
1463 | MUL_ADD_C a4L,a4R,b6L,b6R,c2,c3,c1 | ||
1464 | MUL_ADD_C a3L,a3R,b7L,b7R,c2,c3,c1 | ||
1465 | STD c2,80(r_ptr) | ||
1466 | COPY %r0,c2 | ||
1467 | |||
1468 | MUL_ADD_C a4L,a4R,b7L,b7R,c3,c1,c2 | ||
1469 | MUL_ADD_C a5L,a5R,b6L,b6R,c3,c1,c2 | ||
1470 | MUL_ADD_C a6L,a6R,b5L,b5R,c3,c1,c2 | ||
1471 | MUL_ADD_C a7L,a7R,b4L,b4R,c3,c1,c2 | ||
1472 | STD c3,88(r_ptr) | ||
1473 | COPY %r0,c3 | ||
1474 | |||
1475 | MUL_ADD_C a7L,a7R,b5L,b5R,c1,c2,c3 | ||
1476 | MUL_ADD_C a6L,a6R,b6L,b6R,c1,c2,c3 | ||
1477 | MUL_ADD_C a5L,a5R,b7L,b7R,c1,c2,c3 | ||
1478 | STD c1,96(r_ptr) | ||
1479 | COPY %r0,c1 | ||
1480 | |||
1481 | MUL_ADD_C a6L,a6R,b7L,b7R,c2,c3,c1 | ||
1482 | MUL_ADD_C a7L,a7R,b6L,b6R,c2,c3,c1 | ||
1483 | STD c2,104(r_ptr) | ||
1484 | COPY %r0,c2 | ||
1485 | |||
1486 | MUL_ADD_C a7L,a7R,b7L,b7R,c3,c1,c2 | ||
1487 | STD c3,112(r_ptr) | ||
1488 | STD c1,120(r_ptr) | ||
1489 | |||
1490 | .EXIT | ||
1491 | FLDD -88(%sp),%fr13 | ||
1492 | FLDD -96(%sp),%fr12 | ||
1493 | LDD -104(%sp),%r6 ; restore r6 | ||
1494 | LDD -112(%sp),%r5 ; restore r5 | ||
1495 | LDD -120(%sp),%r4 ; restore r4 | ||
1496 | BVE (%rp) | ||
1497 | LDD,MB -128(%sp),%r3 | ||
1498 | |||
1499 | .PROCEND | ||
1500 | |||
1501 | ;----------------------------------------------------------------------------- | ||
1502 | ; | ||
1503 | ;void bn_mul_comba4(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b) | ||
1504 | ; arg0 = r_ptr | ||
1505 | ; arg1 = a_ptr | ||
1506 | ; arg2 = b_ptr | ||
1507 | ; | ||
1508 | |||
1509 | bn_mul_comba4 | ||
1510 | .proc | ||
1511 | .callinfo FRAME=128,ENTRY_GR=%r3,ARGS_SAVED,ORDERING_AWARE | ||
1512 | .EXPORT bn_mul_comba4,ENTRY,PRIV_LEV=3,NO_RELOCATION,LONG_RETURN | ||
1513 | .entry | ||
1514 | .align 64 | ||
1515 | |||
1516 | STD %r3,0(%sp) ; save r3 | ||
1517 | STD %r4,8(%sp) ; save r4 | ||
1518 | STD %r5,16(%sp) ; save r5 | ||
1519 | STD %r6,24(%sp) ; save r6 | ||
1520 | FSTD %fr12,32(%sp) ; save r6 | ||
1521 | FSTD %fr13,40(%sp) ; save r7 | ||
1522 | |||
1523 | ; | ||
1524 | ; Zero out carries | ||
1525 | ; | ||
1526 | COPY %r0,c1 | ||
1527 | COPY %r0,c2 | ||
1528 | COPY %r0,c3 | ||
1529 | |||
1530 | LDO 128(%sp),%sp ; bump stack | ||
1531 | DEPDI,Z 1,31,1,high_one ; Create Value 1 << 32 | ||
1532 | |||
1533 | ; | ||
1534 | ; Load up all of the values we are going to use | ||
1535 | ; | ||
1536 | FLDD 0(a_ptr),a0 | ||
1537 | FLDD 8(a_ptr),a1 | ||
1538 | FLDD 16(a_ptr),a2 | ||
1539 | FLDD 24(a_ptr),a3 | ||
1540 | |||
1541 | FLDD 0(b_ptr),b0 | ||
1542 | FLDD 8(b_ptr),b1 | ||
1543 | FLDD 16(b_ptr),b2 | ||
1544 | FLDD 24(b_ptr),b3 | ||
1545 | |||
1546 | MUL_ADD_C a0L,a0R,b0L,b0R,c1,c2,c3 | ||
1547 | STD c1,0(r_ptr) | ||
1548 | COPY %r0,c1 | ||
1549 | |||
1550 | MUL_ADD_C a0L,a0R,b1L,b1R,c2,c3,c1 | ||
1551 | MUL_ADD_C a1L,a1R,b0L,b0R,c2,c3,c1 | ||
1552 | STD c2,8(r_ptr) | ||
1553 | COPY %r0,c2 | ||
1554 | |||
1555 | MUL_ADD_C a2L,a2R,b0L,b0R,c3,c1,c2 | ||
1556 | MUL_ADD_C a1L,a1R,b1L,b1R,c3,c1,c2 | ||
1557 | MUL_ADD_C a0L,a0R,b2L,b2R,c3,c1,c2 | ||
1558 | STD c3,16(r_ptr) | ||
1559 | COPY %r0,c3 | ||
1560 | |||
1561 | MUL_ADD_C a0L,a0R,b3L,b3R,c1,c2,c3 | ||
1562 | MUL_ADD_C a1L,a1R,b2L,b2R,c1,c2,c3 | ||
1563 | MUL_ADD_C a2L,a2R,b1L,b1R,c1,c2,c3 | ||
1564 | MUL_ADD_C a3L,a3R,b0L,b0R,c1,c2,c3 | ||
1565 | STD c1,24(r_ptr) | ||
1566 | COPY %r0,c1 | ||
1567 | |||
1568 | MUL_ADD_C a3L,a3R,b1L,b1R,c2,c3,c1 | ||
1569 | MUL_ADD_C a2L,a2R,b2L,b2R,c2,c3,c1 | ||
1570 | MUL_ADD_C a1L,a1R,b3L,b3R,c2,c3,c1 | ||
1571 | STD c2,32(r_ptr) | ||
1572 | COPY %r0,c2 | ||
1573 | |||
1574 | MUL_ADD_C a2L,a2R,b3L,b3R,c3,c1,c2 | ||
1575 | MUL_ADD_C a3L,a3R,b2L,b2R,c3,c1,c2 | ||
1576 | STD c3,40(r_ptr) | ||
1577 | COPY %r0,c3 | ||
1578 | |||
1579 | MUL_ADD_C a3L,a3R,b3L,b3R,c1,c2,c3 | ||
1580 | STD c1,48(r_ptr) | ||
1581 | STD c2,56(r_ptr) | ||
1582 | |||
1583 | .EXIT | ||
1584 | FLDD -88(%sp),%fr13 | ||
1585 | FLDD -96(%sp),%fr12 | ||
1586 | LDD -104(%sp),%r6 ; restore r6 | ||
1587 | LDD -112(%sp),%r5 ; restore r5 | ||
1588 | LDD -120(%sp),%r4 ; restore r4 | ||
1589 | BVE (%rp) | ||
1590 | LDD,MB -128(%sp),%r3 | ||
1591 | |||
1592 | .PROCEND | ||
1593 | |||
1594 | |||
1595 | .SPACE $TEXT$ | ||
1596 | .SUBSPA $CODE$ | ||
1597 | .SPACE $PRIVATE$,SORT=16 | ||
1598 | .IMPORT $global$,DATA | ||
1599 | .SPACE $TEXT$ | ||
1600 | .SUBSPA $CODE$ | ||
1601 | .SUBSPA $LIT$,QUAD=0,ALIGN=8,ACCESS=0x2c,SORT=16 | ||
1602 | C$4 | ||
1603 | .ALIGN 8 | ||
1604 | .STRINGZ "Division would overflow (%d)\n" | ||
1605 | .END | ||
diff --git a/src/lib/libcrypto/bn/asm/sparcv8.S b/src/lib/libcrypto/bn/asm/sparcv8.S new file mode 100644 index 0000000000..88c5dc480a --- /dev/null +++ b/src/lib/libcrypto/bn/asm/sparcv8.S | |||
@@ -0,0 +1,1458 @@ | |||
1 | .ident "sparcv8.s, Version 1.4" | ||
2 | .ident "SPARC v8 ISA artwork by Andy Polyakov <appro@fy.chalmers.se>" | ||
3 | |||
4 | /* | ||
5 | * ==================================================================== | ||
6 | * Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL | ||
7 | * project. | ||
8 | * | ||
9 | * Rights for redistribution and usage in source and binary forms are | ||
10 | * granted according to the OpenSSL license. Warranty of any kind is | ||
11 | * disclaimed. | ||
12 | * ==================================================================== | ||
13 | */ | ||
14 | |||
15 | /* | ||
16 | * This is my modest contributon to OpenSSL project (see | ||
17 | * http://www.openssl.org/ for more information about it) and is | ||
18 | * a drop-in SuperSPARC ISA replacement for crypto/bn/bn_asm.c | ||
19 | * module. For updates see http://fy.chalmers.se/~appro/hpe/. | ||
20 | * | ||
21 | * See bn_asm.sparc.v8plus.S for more details. | ||
22 | */ | ||
23 | |||
24 | /* | ||
25 | * Revision history. | ||
26 | * | ||
27 | * 1.1 - new loop unrolling model(*); | ||
28 | * 1.2 - made gas friendly; | ||
29 | * 1.3 - fixed problem with /usr/ccs/lib/cpp; | ||
30 | * 1.4 - some retunes; | ||
31 | * | ||
32 | * (*) see bn_asm.sparc.v8plus.S for details | ||
33 | */ | ||
34 | |||
35 | .section ".text",#alloc,#execinstr | ||
36 | .file "bn_asm.sparc.v8.S" | ||
37 | |||
38 | .align 32 | ||
39 | |||
40 | .global bn_mul_add_words | ||
41 | /* | ||
42 | * BN_ULONG bn_mul_add_words(rp,ap,num,w) | ||
43 | * BN_ULONG *rp,*ap; | ||
44 | * int num; | ||
45 | * BN_ULONG w; | ||
46 | */ | ||
47 | bn_mul_add_words: | ||
48 | cmp %o2,0 | ||
49 | bg,a .L_bn_mul_add_words_proceed | ||
50 | ld [%o1],%g2 | ||
51 | retl | ||
52 | clr %o0 | ||
53 | |||
54 | .L_bn_mul_add_words_proceed: | ||
55 | andcc %o2,-4,%g0 | ||
56 | bz .L_bn_mul_add_words_tail | ||
57 | clr %o5 | ||
58 | |||
59 | .L_bn_mul_add_words_loop: | ||
60 | ld [%o0],%o4 | ||
61 | ld [%o1+4],%g3 | ||
62 | umul %o3,%g2,%g2 | ||
63 | rd %y,%g1 | ||
64 | addcc %o4,%o5,%o4 | ||
65 | addx %g1,0,%g1 | ||
66 | addcc %o4,%g2,%o4 | ||
67 | st %o4,[%o0] | ||
68 | addx %g1,0,%o5 | ||
69 | |||
70 | ld [%o0+4],%o4 | ||
71 | ld [%o1+8],%g2 | ||
72 | umul %o3,%g3,%g3 | ||
73 | dec 4,%o2 | ||
74 | rd %y,%g1 | ||
75 | addcc %o4,%o5,%o4 | ||
76 | addx %g1,0,%g1 | ||
77 | addcc %o4,%g3,%o4 | ||
78 | st %o4,[%o0+4] | ||
79 | addx %g1,0,%o5 | ||
80 | |||
81 | ld [%o0+8],%o4 | ||
82 | ld [%o1+12],%g3 | ||
83 | umul %o3,%g2,%g2 | ||
84 | inc 16,%o1 | ||
85 | rd %y,%g1 | ||
86 | addcc %o4,%o5,%o4 | ||
87 | addx %g1,0,%g1 | ||
88 | addcc %o4,%g2,%o4 | ||
89 | st %o4,[%o0+8] | ||
90 | addx %g1,0,%o5 | ||
91 | |||
92 | ld [%o0+12],%o4 | ||
93 | umul %o3,%g3,%g3 | ||
94 | inc 16,%o0 | ||
95 | rd %y,%g1 | ||
96 | addcc %o4,%o5,%o4 | ||
97 | addx %g1,0,%g1 | ||
98 | addcc %o4,%g3,%o4 | ||
99 | st %o4,[%o0-4] | ||
100 | addx %g1,0,%o5 | ||
101 | andcc %o2,-4,%g0 | ||
102 | bnz,a .L_bn_mul_add_words_loop | ||
103 | ld [%o1],%g2 | ||
104 | |||
105 | tst %o2 | ||
106 | bnz,a .L_bn_mul_add_words_tail | ||
107 | ld [%o1],%g2 | ||
108 | .L_bn_mul_add_words_return: | ||
109 | retl | ||
110 | mov %o5,%o0 | ||
111 | nop | ||
112 | |||
113 | .L_bn_mul_add_words_tail: | ||
114 | ld [%o0],%o4 | ||
115 | umul %o3,%g2,%g2 | ||
116 | addcc %o4,%o5,%o4 | ||
117 | rd %y,%g1 | ||
118 | addx %g1,0,%g1 | ||
119 | addcc %o4,%g2,%o4 | ||
120 | addx %g1,0,%o5 | ||
121 | deccc %o2 | ||
122 | bz .L_bn_mul_add_words_return | ||
123 | st %o4,[%o0] | ||
124 | |||
125 | ld [%o1+4],%g2 | ||
126 | ld [%o0+4],%o4 | ||
127 | umul %o3,%g2,%g2 | ||
128 | rd %y,%g1 | ||
129 | addcc %o4,%o5,%o4 | ||
130 | addx %g1,0,%g1 | ||
131 | addcc %o4,%g2,%o4 | ||
132 | addx %g1,0,%o5 | ||
133 | deccc %o2 | ||
134 | bz .L_bn_mul_add_words_return | ||
135 | st %o4,[%o0+4] | ||
136 | |||
137 | ld [%o1+8],%g2 | ||
138 | ld [%o0+8],%o4 | ||
139 | umul %o3,%g2,%g2 | ||
140 | rd %y,%g1 | ||
141 | addcc %o4,%o5,%o4 | ||
142 | addx %g1,0,%g1 | ||
143 | addcc %o4,%g2,%o4 | ||
144 | st %o4,[%o0+8] | ||
145 | retl | ||
146 | addx %g1,0,%o0 | ||
147 | |||
148 | .type bn_mul_add_words,#function | ||
149 | .size bn_mul_add_words,(.-bn_mul_add_words) | ||
150 | |||
151 | .align 32 | ||
152 | |||
153 | .global bn_mul_words | ||
154 | /* | ||
155 | * BN_ULONG bn_mul_words(rp,ap,num,w) | ||
156 | * BN_ULONG *rp,*ap; | ||
157 | * int num; | ||
158 | * BN_ULONG w; | ||
159 | */ | ||
160 | bn_mul_words: | ||
161 | cmp %o2,0 | ||
162 | bg,a .L_bn_mul_words_proceeed | ||
163 | ld [%o1],%g2 | ||
164 | retl | ||
165 | clr %o0 | ||
166 | |||
167 | .L_bn_mul_words_proceeed: | ||
168 | andcc %o2,-4,%g0 | ||
169 | bz .L_bn_mul_words_tail | ||
170 | clr %o5 | ||
171 | |||
172 | .L_bn_mul_words_loop: | ||
173 | ld [%o1+4],%g3 | ||
174 | umul %o3,%g2,%g2 | ||
175 | addcc %g2,%o5,%g2 | ||
176 | rd %y,%g1 | ||
177 | addx %g1,0,%o5 | ||
178 | st %g2,[%o0] | ||
179 | |||
180 | ld [%o1+8],%g2 | ||
181 | umul %o3,%g3,%g3 | ||
182 | addcc %g3,%o5,%g3 | ||
183 | rd %y,%g1 | ||
184 | dec 4,%o2 | ||
185 | addx %g1,0,%o5 | ||
186 | st %g3,[%o0+4] | ||
187 | |||
188 | ld [%o1+12],%g3 | ||
189 | umul %o3,%g2,%g2 | ||
190 | addcc %g2,%o5,%g2 | ||
191 | rd %y,%g1 | ||
192 | inc 16,%o1 | ||
193 | st %g2,[%o0+8] | ||
194 | addx %g1,0,%o5 | ||
195 | |||
196 | umul %o3,%g3,%g3 | ||
197 | addcc %g3,%o5,%g3 | ||
198 | rd %y,%g1 | ||
199 | inc 16,%o0 | ||
200 | addx %g1,0,%o5 | ||
201 | st %g3,[%o0-4] | ||
202 | andcc %o2,-4,%g0 | ||
203 | nop | ||
204 | bnz,a .L_bn_mul_words_loop | ||
205 | ld [%o1],%g2 | ||
206 | |||
207 | tst %o2 | ||
208 | bnz,a .L_bn_mul_words_tail | ||
209 | ld [%o1],%g2 | ||
210 | .L_bn_mul_words_return: | ||
211 | retl | ||
212 | mov %o5,%o0 | ||
213 | nop | ||
214 | |||
215 | .L_bn_mul_words_tail: | ||
216 | umul %o3,%g2,%g2 | ||
217 | addcc %g2,%o5,%g2 | ||
218 | rd %y,%g1 | ||
219 | addx %g1,0,%o5 | ||
220 | deccc %o2 | ||
221 | bz .L_bn_mul_words_return | ||
222 | st %g2,[%o0] | ||
223 | nop | ||
224 | |||
225 | ld [%o1+4],%g2 | ||
226 | umul %o3,%g2,%g2 | ||
227 | addcc %g2,%o5,%g2 | ||
228 | rd %y,%g1 | ||
229 | addx %g1,0,%o5 | ||
230 | deccc %o2 | ||
231 | bz .L_bn_mul_words_return | ||
232 | st %g2,[%o0+4] | ||
233 | |||
234 | ld [%o1+8],%g2 | ||
235 | umul %o3,%g2,%g2 | ||
236 | addcc %g2,%o5,%g2 | ||
237 | rd %y,%g1 | ||
238 | st %g2,[%o0+8] | ||
239 | retl | ||
240 | addx %g1,0,%o0 | ||
241 | |||
242 | .type bn_mul_words,#function | ||
243 | .size bn_mul_words,(.-bn_mul_words) | ||
244 | |||
245 | .align 32 | ||
246 | .global bn_sqr_words | ||
247 | /* | ||
248 | * void bn_sqr_words(r,a,n) | ||
249 | * BN_ULONG *r,*a; | ||
250 | * int n; | ||
251 | */ | ||
252 | bn_sqr_words: | ||
253 | cmp %o2,0 | ||
254 | bg,a .L_bn_sqr_words_proceeed | ||
255 | ld [%o1],%g2 | ||
256 | retl | ||
257 | clr %o0 | ||
258 | |||
259 | .L_bn_sqr_words_proceeed: | ||
260 | andcc %o2,-4,%g0 | ||
261 | bz .L_bn_sqr_words_tail | ||
262 | clr %o5 | ||
263 | |||
264 | .L_bn_sqr_words_loop: | ||
265 | ld [%o1+4],%g3 | ||
266 | umul %g2,%g2,%o4 | ||
267 | st %o4,[%o0] | ||
268 | rd %y,%o5 | ||
269 | st %o5,[%o0+4] | ||
270 | |||
271 | ld [%o1+8],%g2 | ||
272 | umul %g3,%g3,%o4 | ||
273 | dec 4,%o2 | ||
274 | st %o4,[%o0+8] | ||
275 | rd %y,%o5 | ||
276 | st %o5,[%o0+12] | ||
277 | nop | ||
278 | |||
279 | ld [%o1+12],%g3 | ||
280 | umul %g2,%g2,%o4 | ||
281 | st %o4,[%o0+16] | ||
282 | rd %y,%o5 | ||
283 | inc 16,%o1 | ||
284 | st %o5,[%o0+20] | ||
285 | |||
286 | umul %g3,%g3,%o4 | ||
287 | inc 32,%o0 | ||
288 | st %o4,[%o0-8] | ||
289 | rd %y,%o5 | ||
290 | st %o5,[%o0-4] | ||
291 | andcc %o2,-4,%g2 | ||
292 | bnz,a .L_bn_sqr_words_loop | ||
293 | ld [%o1],%g2 | ||
294 | |||
295 | tst %o2 | ||
296 | nop | ||
297 | bnz,a .L_bn_sqr_words_tail | ||
298 | ld [%o1],%g2 | ||
299 | .L_bn_sqr_words_return: | ||
300 | retl | ||
301 | clr %o0 | ||
302 | |||
303 | .L_bn_sqr_words_tail: | ||
304 | umul %g2,%g2,%o4 | ||
305 | st %o4,[%o0] | ||
306 | deccc %o2 | ||
307 | rd %y,%o5 | ||
308 | bz .L_bn_sqr_words_return | ||
309 | st %o5,[%o0+4] | ||
310 | |||
311 | ld [%o1+4],%g2 | ||
312 | umul %g2,%g2,%o4 | ||
313 | st %o4,[%o0+8] | ||
314 | deccc %o2 | ||
315 | rd %y,%o5 | ||
316 | nop | ||
317 | bz .L_bn_sqr_words_return | ||
318 | st %o5,[%o0+12] | ||
319 | |||
320 | ld [%o1+8],%g2 | ||
321 | umul %g2,%g2,%o4 | ||
322 | st %o4,[%o0+16] | ||
323 | rd %y,%o5 | ||
324 | st %o5,[%o0+20] | ||
325 | retl | ||
326 | clr %o0 | ||
327 | |||
328 | .type bn_sqr_words,#function | ||
329 | .size bn_sqr_words,(.-bn_sqr_words) | ||
330 | |||
331 | .align 32 | ||
332 | |||
333 | .global bn_div_words | ||
334 | /* | ||
335 | * BN_ULONG bn_div_words(h,l,d) | ||
336 | * BN_ULONG h,l,d; | ||
337 | */ | ||
338 | bn_div_words: | ||
339 | wr %o0,%y | ||
340 | udiv %o1,%o2,%o0 | ||
341 | retl | ||
342 | nop | ||
343 | |||
344 | .type bn_div_words,#function | ||
345 | .size bn_div_words,(.-bn_div_words) | ||
346 | |||
347 | .align 32 | ||
348 | |||
349 | .global bn_add_words | ||
350 | /* | ||
351 | * BN_ULONG bn_add_words(rp,ap,bp,n) | ||
352 | * BN_ULONG *rp,*ap,*bp; | ||
353 | * int n; | ||
354 | */ | ||
355 | bn_add_words: | ||
356 | cmp %o3,0 | ||
357 | bg,a .L_bn_add_words_proceed | ||
358 | ld [%o1],%o4 | ||
359 | retl | ||
360 | clr %o0 | ||
361 | |||
362 | .L_bn_add_words_proceed: | ||
363 | andcc %o3,-4,%g0 | ||
364 | bz .L_bn_add_words_tail | ||
365 | clr %g1 | ||
366 | ba .L_bn_add_words_warn_loop | ||
367 | addcc %g0,0,%g0 ! clear carry flag | ||
368 | |||
369 | .L_bn_add_words_loop: | ||
370 | ld [%o1],%o4 | ||
371 | .L_bn_add_words_warn_loop: | ||
372 | ld [%o2],%o5 | ||
373 | ld [%o1+4],%g3 | ||
374 | ld [%o2+4],%g4 | ||
375 | dec 4,%o3 | ||
376 | addxcc %o5,%o4,%o5 | ||
377 | st %o5,[%o0] | ||
378 | |||
379 | ld [%o1+8],%o4 | ||
380 | ld [%o2+8],%o5 | ||
381 | inc 16,%o1 | ||
382 | addxcc %g3,%g4,%g3 | ||
383 | st %g3,[%o0+4] | ||
384 | |||
385 | ld [%o1-4],%g3 | ||
386 | ld [%o2+12],%g4 | ||
387 | inc 16,%o2 | ||
388 | addxcc %o5,%o4,%o5 | ||
389 | st %o5,[%o0+8] | ||
390 | |||
391 | inc 16,%o0 | ||
392 | addxcc %g3,%g4,%g3 | ||
393 | st %g3,[%o0-4] | ||
394 | addx %g0,0,%g1 | ||
395 | andcc %o3,-4,%g0 | ||
396 | bnz,a .L_bn_add_words_loop | ||
397 | addcc %g1,-1,%g0 | ||
398 | |||
399 | tst %o3 | ||
400 | bnz,a .L_bn_add_words_tail | ||
401 | ld [%o1],%o4 | ||
402 | .L_bn_add_words_return: | ||
403 | retl | ||
404 | mov %g1,%o0 | ||
405 | |||
406 | .L_bn_add_words_tail: | ||
407 | addcc %g1,-1,%g0 | ||
408 | ld [%o2],%o5 | ||
409 | addxcc %o5,%o4,%o5 | ||
410 | addx %g0,0,%g1 | ||
411 | deccc %o3 | ||
412 | bz .L_bn_add_words_return | ||
413 | st %o5,[%o0] | ||
414 | |||
415 | ld [%o1+4],%o4 | ||
416 | addcc %g1,-1,%g0 | ||
417 | ld [%o2+4],%o5 | ||
418 | addxcc %o5,%o4,%o5 | ||
419 | addx %g0,0,%g1 | ||
420 | deccc %o3 | ||
421 | bz .L_bn_add_words_return | ||
422 | st %o5,[%o0+4] | ||
423 | |||
424 | ld [%o1+8],%o4 | ||
425 | addcc %g1,-1,%g0 | ||
426 | ld [%o2+8],%o5 | ||
427 | addxcc %o5,%o4,%o5 | ||
428 | st %o5,[%o0+8] | ||
429 | retl | ||
430 | addx %g0,0,%o0 | ||
431 | |||
432 | .type bn_add_words,#function | ||
433 | .size bn_add_words,(.-bn_add_words) | ||
434 | |||
435 | .align 32 | ||
436 | |||
437 | .global bn_sub_words | ||
438 | /* | ||
439 | * BN_ULONG bn_sub_words(rp,ap,bp,n) | ||
440 | * BN_ULONG *rp,*ap,*bp; | ||
441 | * int n; | ||
442 | */ | ||
443 | bn_sub_words: | ||
444 | cmp %o3,0 | ||
445 | bg,a .L_bn_sub_words_proceed | ||
446 | ld [%o1],%o4 | ||
447 | retl | ||
448 | clr %o0 | ||
449 | |||
450 | .L_bn_sub_words_proceed: | ||
451 | andcc %o3,-4,%g0 | ||
452 | bz .L_bn_sub_words_tail | ||
453 | clr %g1 | ||
454 | ba .L_bn_sub_words_warm_loop | ||
455 | addcc %g0,0,%g0 ! clear carry flag | ||
456 | |||
457 | .L_bn_sub_words_loop: | ||
458 | ld [%o1],%o4 | ||
459 | .L_bn_sub_words_warm_loop: | ||
460 | ld [%o2],%o5 | ||
461 | ld [%o1+4],%g3 | ||
462 | ld [%o2+4],%g4 | ||
463 | dec 4,%o3 | ||
464 | subxcc %o4,%o5,%o5 | ||
465 | st %o5,[%o0] | ||
466 | |||
467 | ld [%o1+8],%o4 | ||
468 | ld [%o2+8],%o5 | ||
469 | inc 16,%o1 | ||
470 | subxcc %g3,%g4,%g4 | ||
471 | st %g4,[%o0+4] | ||
472 | |||
473 | ld [%o1-4],%g3 | ||
474 | ld [%o2+12],%g4 | ||
475 | inc 16,%o2 | ||
476 | subxcc %o4,%o5,%o5 | ||
477 | st %o5,[%o0+8] | ||
478 | |||
479 | inc 16,%o0 | ||
480 | subxcc %g3,%g4,%g4 | ||
481 | st %g4,[%o0-4] | ||
482 | addx %g0,0,%g1 | ||
483 | andcc %o3,-4,%g0 | ||
484 | bnz,a .L_bn_sub_words_loop | ||
485 | addcc %g1,-1,%g0 | ||
486 | |||
487 | tst %o3 | ||
488 | nop | ||
489 | bnz,a .L_bn_sub_words_tail | ||
490 | ld [%o1],%o4 | ||
491 | .L_bn_sub_words_return: | ||
492 | retl | ||
493 | mov %g1,%o0 | ||
494 | |||
495 | .L_bn_sub_words_tail: | ||
496 | addcc %g1,-1,%g0 | ||
497 | ld [%o2],%o5 | ||
498 | subxcc %o4,%o5,%o5 | ||
499 | addx %g0,0,%g1 | ||
500 | deccc %o3 | ||
501 | bz .L_bn_sub_words_return | ||
502 | st %o5,[%o0] | ||
503 | nop | ||
504 | |||
505 | ld [%o1+4],%o4 | ||
506 | addcc %g1,-1,%g0 | ||
507 | ld [%o2+4],%o5 | ||
508 | subxcc %o4,%o5,%o5 | ||
509 | addx %g0,0,%g1 | ||
510 | deccc %o3 | ||
511 | bz .L_bn_sub_words_return | ||
512 | st %o5,[%o0+4] | ||
513 | |||
514 | ld [%o1+8],%o4 | ||
515 | addcc %g1,-1,%g0 | ||
516 | ld [%o2+8],%o5 | ||
517 | subxcc %o4,%o5,%o5 | ||
518 | st %o5,[%o0+8] | ||
519 | retl | ||
520 | addx %g0,0,%o0 | ||
521 | |||
522 | .type bn_sub_words,#function | ||
523 | .size bn_sub_words,(.-bn_sub_words) | ||
524 | |||
525 | #define FRAME_SIZE -96 | ||
526 | |||
527 | /* | ||
528 | * Here is register usage map for *all* routines below. | ||
529 | */ | ||
530 | #define t_1 %o0 | ||
531 | #define t_2 %o1 | ||
532 | #define c_1 %o2 | ||
533 | #define c_2 %o3 | ||
534 | #define c_3 %o4 | ||
535 | |||
536 | #define ap(I) [%i1+4*I] | ||
537 | #define bp(I) [%i2+4*I] | ||
538 | #define rp(I) [%i0+4*I] | ||
539 | |||
540 | #define a_0 %l0 | ||
541 | #define a_1 %l1 | ||
542 | #define a_2 %l2 | ||
543 | #define a_3 %l3 | ||
544 | #define a_4 %l4 | ||
545 | #define a_5 %l5 | ||
546 | #define a_6 %l6 | ||
547 | #define a_7 %l7 | ||
548 | |||
549 | #define b_0 %i3 | ||
550 | #define b_1 %i4 | ||
551 | #define b_2 %i5 | ||
552 | #define b_3 %o5 | ||
553 | #define b_4 %g1 | ||
554 | #define b_5 %g2 | ||
555 | #define b_6 %g3 | ||
556 | #define b_7 %g4 | ||
557 | |||
558 | .align 32 | ||
559 | .global bn_mul_comba8 | ||
560 | /* | ||
561 | * void bn_mul_comba8(r,a,b) | ||
562 | * BN_ULONG *r,*a,*b; | ||
563 | */ | ||
564 | bn_mul_comba8: | ||
565 | save %sp,FRAME_SIZE,%sp | ||
566 | ld ap(0),a_0 | ||
567 | ld bp(0),b_0 | ||
568 | umul a_0,b_0,c_1 !=!mul_add_c(a[0],b[0],c1,c2,c3); | ||
569 | ld bp(1),b_1 | ||
570 | rd %y,c_2 | ||
571 | st c_1,rp(0) !r[0]=c1; | ||
572 | |||
573 | umul a_0,b_1,t_1 !=!mul_add_c(a[0],b[1],c2,c3,c1); | ||
574 | ld ap(1),a_1 | ||
575 | addcc c_2,t_1,c_2 | ||
576 | rd %y,t_2 | ||
577 | addxcc %g0,t_2,c_3 != | ||
578 | addx %g0,%g0,c_1 | ||
579 | ld ap(2),a_2 | ||
580 | umul a_1,b_0,t_1 !mul_add_c(a[1],b[0],c2,c3,c1); | ||
581 | addcc c_2,t_1,c_2 != | ||
582 | rd %y,t_2 | ||
583 | addxcc c_3,t_2,c_3 | ||
584 | st c_2,rp(1) !r[1]=c2; | ||
585 | addx c_1,%g0,c_1 != | ||
586 | |||
587 | umul a_2,b_0,t_1 !mul_add_c(a[2],b[0],c3,c1,c2); | ||
588 | addcc c_3,t_1,c_3 | ||
589 | rd %y,t_2 | ||
590 | addxcc c_1,t_2,c_1 != | ||
591 | addx %g0,%g0,c_2 | ||
592 | ld bp(2),b_2 | ||
593 | umul a_1,b_1,t_1 !mul_add_c(a[1],b[1],c3,c1,c2); | ||
594 | addcc c_3,t_1,c_3 != | ||
595 | rd %y,t_2 | ||
596 | addxcc c_1,t_2,c_1 | ||
597 | ld bp(3),b_3 | ||
598 | addx c_2,%g0,c_2 != | ||
599 | umul a_0,b_2,t_1 !mul_add_c(a[0],b[2],c3,c1,c2); | ||
600 | addcc c_3,t_1,c_3 | ||
601 | rd %y,t_2 | ||
602 | addxcc c_1,t_2,c_1 != | ||
603 | addx c_2,%g0,c_2 | ||
604 | st c_3,rp(2) !r[2]=c3; | ||
605 | |||
606 | umul a_0,b_3,t_1 !mul_add_c(a[0],b[3],c1,c2,c3); | ||
607 | addcc c_1,t_1,c_1 != | ||
608 | rd %y,t_2 | ||
609 | addxcc c_2,t_2,c_2 | ||
610 | addx %g0,%g0,c_3 | ||
611 | umul a_1,b_2,t_1 !=!mul_add_c(a[1],b[2],c1,c2,c3); | ||
612 | addcc c_1,t_1,c_1 | ||
613 | rd %y,t_2 | ||
614 | addxcc c_2,t_2,c_2 | ||
615 | addx c_3,%g0,c_3 != | ||
616 | ld ap(3),a_3 | ||
617 | umul a_2,b_1,t_1 !mul_add_c(a[2],b[1],c1,c2,c3); | ||
618 | addcc c_1,t_1,c_1 | ||
619 | rd %y,t_2 != | ||
620 | addxcc c_2,t_2,c_2 | ||
621 | addx c_3,%g0,c_3 | ||
622 | ld ap(4),a_4 | ||
623 | umul a_3,b_0,t_1 !mul_add_c(a[3],b[0],c1,c2,c3);!= | ||
624 | addcc c_1,t_1,c_1 | ||
625 | rd %y,t_2 | ||
626 | addxcc c_2,t_2,c_2 | ||
627 | addx c_3,%g0,c_3 != | ||
628 | st c_1,rp(3) !r[3]=c1; | ||
629 | |||
630 | umul a_4,b_0,t_1 !mul_add_c(a[4],b[0],c2,c3,c1); | ||
631 | addcc c_2,t_1,c_2 | ||
632 | rd %y,t_2 != | ||
633 | addxcc c_3,t_2,c_3 | ||
634 | addx %g0,%g0,c_1 | ||
635 | umul a_3,b_1,t_1 !mul_add_c(a[3],b[1],c2,c3,c1); | ||
636 | addcc c_2,t_1,c_2 != | ||
637 | rd %y,t_2 | ||
638 | addxcc c_3,t_2,c_3 | ||
639 | addx c_1,%g0,c_1 | ||
640 | umul a_2,b_2,t_1 !=!mul_add_c(a[2],b[2],c2,c3,c1); | ||
641 | addcc c_2,t_1,c_2 | ||
642 | rd %y,t_2 | ||
643 | addxcc c_3,t_2,c_3 | ||
644 | addx c_1,%g0,c_1 != | ||
645 | ld bp(4),b_4 | ||
646 | umul a_1,b_3,t_1 !mul_add_c(a[1],b[3],c2,c3,c1); | ||
647 | addcc c_2,t_1,c_2 | ||
648 | rd %y,t_2 != | ||
649 | addxcc c_3,t_2,c_3 | ||
650 | addx c_1,%g0,c_1 | ||
651 | ld bp(5),b_5 | ||
652 | umul a_0,b_4,t_1 !=!mul_add_c(a[0],b[4],c2,c3,c1); | ||
653 | addcc c_2,t_1,c_2 | ||
654 | rd %y,t_2 | ||
655 | addxcc c_3,t_2,c_3 | ||
656 | addx c_1,%g0,c_1 != | ||
657 | st c_2,rp(4) !r[4]=c2; | ||
658 | |||
659 | umul a_0,b_5,t_1 !mul_add_c(a[0],b[5],c3,c1,c2); | ||
660 | addcc c_3,t_1,c_3 | ||
661 | rd %y,t_2 != | ||
662 | addxcc c_1,t_2,c_1 | ||
663 | addx %g0,%g0,c_2 | ||
664 | umul a_1,b_4,t_1 !mul_add_c(a[1],b[4],c3,c1,c2); | ||
665 | addcc c_3,t_1,c_3 != | ||
666 | rd %y,t_2 | ||
667 | addxcc c_1,t_2,c_1 | ||
668 | addx c_2,%g0,c_2 | ||
669 | umul a_2,b_3,t_1 !=!mul_add_c(a[2],b[3],c3,c1,c2); | ||
670 | addcc c_3,t_1,c_3 | ||
671 | rd %y,t_2 | ||
672 | addxcc c_1,t_2,c_1 | ||
673 | addx c_2,%g0,c_2 != | ||
674 | umul a_3,b_2,t_1 !mul_add_c(a[3],b[2],c3,c1,c2); | ||
675 | addcc c_3,t_1,c_3 | ||
676 | rd %y,t_2 | ||
677 | addxcc c_1,t_2,c_1 != | ||
678 | addx c_2,%g0,c_2 | ||
679 | ld ap(5),a_5 | ||
680 | umul a_4,b_1,t_1 !mul_add_c(a[4],b[1],c3,c1,c2); | ||
681 | addcc c_3,t_1,c_3 != | ||
682 | rd %y,t_2 | ||
683 | addxcc c_1,t_2,c_1 | ||
684 | ld ap(6),a_6 | ||
685 | addx c_2,%g0,c_2 != | ||
686 | umul a_5,b_0,t_1 !mul_add_c(a[5],b[0],c3,c1,c2); | ||
687 | addcc c_3,t_1,c_3 | ||
688 | rd %y,t_2 | ||
689 | addxcc c_1,t_2,c_1 != | ||
690 | addx c_2,%g0,c_2 | ||
691 | st c_3,rp(5) !r[5]=c3; | ||
692 | |||
693 | umul a_6,b_0,t_1 !mul_add_c(a[6],b[0],c1,c2,c3); | ||
694 | addcc c_1,t_1,c_1 != | ||
695 | rd %y,t_2 | ||
696 | addxcc c_2,t_2,c_2 | ||
697 | addx %g0,%g0,c_3 | ||
698 | umul a_5,b_1,t_1 !=!mul_add_c(a[5],b[1],c1,c2,c3); | ||
699 | addcc c_1,t_1,c_1 | ||
700 | rd %y,t_2 | ||
701 | addxcc c_2,t_2,c_2 | ||
702 | addx c_3,%g0,c_3 != | ||
703 | umul a_4,b_2,t_1 !mul_add_c(a[4],b[2],c1,c2,c3); | ||
704 | addcc c_1,t_1,c_1 | ||
705 | rd %y,t_2 | ||
706 | addxcc c_2,t_2,c_2 != | ||
707 | addx c_3,%g0,c_3 | ||
708 | umul a_3,b_3,t_1 !mul_add_c(a[3],b[3],c1,c2,c3); | ||
709 | addcc c_1,t_1,c_1 | ||
710 | rd %y,t_2 != | ||
711 | addxcc c_2,t_2,c_2 | ||
712 | addx c_3,%g0,c_3 | ||
713 | umul a_2,b_4,t_1 !mul_add_c(a[2],b[4],c1,c2,c3); | ||
714 | addcc c_1,t_1,c_1 != | ||
715 | rd %y,t_2 | ||
716 | addxcc c_2,t_2,c_2 | ||
717 | ld bp(6),b_6 | ||
718 | addx c_3,%g0,c_3 != | ||
719 | umul a_1,b_5,t_1 !mul_add_c(a[1],b[5],c1,c2,c3); | ||
720 | addcc c_1,t_1,c_1 | ||
721 | rd %y,t_2 | ||
722 | addxcc c_2,t_2,c_2 != | ||
723 | addx c_3,%g0,c_3 | ||
724 | ld bp(7),b_7 | ||
725 | umul a_0,b_6,t_1 !mul_add_c(a[0],b[6],c1,c2,c3); | ||
726 | addcc c_1,t_1,c_1 != | ||
727 | rd %y,t_2 | ||
728 | addxcc c_2,t_2,c_2 | ||
729 | st c_1,rp(6) !r[6]=c1; | ||
730 | addx c_3,%g0,c_3 != | ||
731 | |||
732 | umul a_0,b_7,t_1 !mul_add_c(a[0],b[7],c2,c3,c1); | ||
733 | addcc c_2,t_1,c_2 | ||
734 | rd %y,t_2 | ||
735 | addxcc c_3,t_2,c_3 != | ||
736 | addx %g0,%g0,c_1 | ||
737 | umul a_1,b_6,t_1 !mul_add_c(a[1],b[6],c2,c3,c1); | ||
738 | addcc c_2,t_1,c_2 | ||
739 | rd %y,t_2 != | ||
740 | addxcc c_3,t_2,c_3 | ||
741 | addx c_1,%g0,c_1 | ||
742 | umul a_2,b_5,t_1 !mul_add_c(a[2],b[5],c2,c3,c1); | ||
743 | addcc c_2,t_1,c_2 != | ||
744 | rd %y,t_2 | ||
745 | addxcc c_3,t_2,c_3 | ||
746 | addx c_1,%g0,c_1 | ||
747 | umul a_3,b_4,t_1 !=!mul_add_c(a[3],b[4],c2,c3,c1); | ||
748 | addcc c_2,t_1,c_2 | ||
749 | rd %y,t_2 | ||
750 | addxcc c_3,t_2,c_3 | ||
751 | addx c_1,%g0,c_1 != | ||
752 | umul a_4,b_3,t_1 !mul_add_c(a[4],b[3],c2,c3,c1); | ||
753 | addcc c_2,t_1,c_2 | ||
754 | rd %y,t_2 | ||
755 | addxcc c_3,t_2,c_3 != | ||
756 | addx c_1,%g0,c_1 | ||
757 | umul a_5,b_2,t_1 !mul_add_c(a[5],b[2],c2,c3,c1); | ||
758 | addcc c_2,t_1,c_2 | ||
759 | rd %y,t_2 != | ||
760 | addxcc c_3,t_2,c_3 | ||
761 | addx c_1,%g0,c_1 | ||
762 | ld ap(7),a_7 | ||
763 | umul a_6,b_1,t_1 !=!mul_add_c(a[6],b[1],c2,c3,c1); | ||
764 | addcc c_2,t_1,c_2 | ||
765 | rd %y,t_2 | ||
766 | addxcc c_3,t_2,c_3 | ||
767 | addx c_1,%g0,c_1 != | ||
768 | umul a_7,b_0,t_1 !mul_add_c(a[7],b[0],c2,c3,c1); | ||
769 | addcc c_2,t_1,c_2 | ||
770 | rd %y,t_2 | ||
771 | addxcc c_3,t_2,c_3 != | ||
772 | addx c_1,%g0,c_1 | ||
773 | st c_2,rp(7) !r[7]=c2; | ||
774 | |||
775 | umul a_7,b_1,t_1 !mul_add_c(a[7],b[1],c3,c1,c2); | ||
776 | addcc c_3,t_1,c_3 != | ||
777 | rd %y,t_2 | ||
778 | addxcc c_1,t_2,c_1 | ||
779 | addx %g0,%g0,c_2 | ||
780 | umul a_6,b_2,t_1 !=!mul_add_c(a[6],b[2],c3,c1,c2); | ||
781 | addcc c_3,t_1,c_3 | ||
782 | rd %y,t_2 | ||
783 | addxcc c_1,t_2,c_1 | ||
784 | addx c_2,%g0,c_2 != | ||
785 | umul a_5,b_3,t_1 !mul_add_c(a[5],b[3],c3,c1,c2); | ||
786 | addcc c_3,t_1,c_3 | ||
787 | rd %y,t_2 | ||
788 | addxcc c_1,t_2,c_1 != | ||
789 | addx c_2,%g0,c_2 | ||
790 | umul a_4,b_4,t_1 !mul_add_c(a[4],b[4],c3,c1,c2); | ||
791 | addcc c_3,t_1,c_3 | ||
792 | rd %y,t_2 != | ||
793 | addxcc c_1,t_2,c_1 | ||
794 | addx c_2,%g0,c_2 | ||
795 | umul a_3,b_5,t_1 !mul_add_c(a[3],b[5],c3,c1,c2); | ||
796 | addcc c_3,t_1,c_3 != | ||
797 | rd %y,t_2 | ||
798 | addxcc c_1,t_2,c_1 | ||
799 | addx c_2,%g0,c_2 | ||
800 | umul a_2,b_6,t_1 !=!mul_add_c(a[2],b[6],c3,c1,c2); | ||
801 | addcc c_3,t_1,c_3 | ||
802 | rd %y,t_2 | ||
803 | addxcc c_1,t_2,c_1 | ||
804 | addx c_2,%g0,c_2 != | ||
805 | umul a_1,b_7,t_1 !mul_add_c(a[1],b[7],c3,c1,c2); | ||
806 | addcc c_3,t_1,c_3 | ||
807 | rd %y,t_2 | ||
808 | addxcc c_1,t_2,c_1 ! | ||
809 | addx c_2,%g0,c_2 | ||
810 | st c_3,rp(8) !r[8]=c3; | ||
811 | |||
812 | umul a_2,b_7,t_1 !mul_add_c(a[2],b[7],c1,c2,c3); | ||
813 | addcc c_1,t_1,c_1 != | ||
814 | rd %y,t_2 | ||
815 | addxcc c_2,t_2,c_2 | ||
816 | addx %g0,%g0,c_3 | ||
817 | umul a_3,b_6,t_1 !=!mul_add_c(a[3],b[6],c1,c2,c3); | ||
818 | addcc c_1,t_1,c_1 | ||
819 | rd %y,t_2 | ||
820 | addxcc c_2,t_2,c_2 | ||
821 | addx c_3,%g0,c_3 != | ||
822 | umul a_4,b_5,t_1 !mul_add_c(a[4],b[5],c1,c2,c3); | ||
823 | addcc c_1,t_1,c_1 | ||
824 | rd %y,t_2 | ||
825 | addxcc c_2,t_2,c_2 != | ||
826 | addx c_3,%g0,c_3 | ||
827 | umul a_5,b_4,t_1 !mul_add_c(a[5],b[4],c1,c2,c3); | ||
828 | addcc c_1,t_1,c_1 | ||
829 | rd %y,t_2 != | ||
830 | addxcc c_2,t_2,c_2 | ||
831 | addx c_3,%g0,c_3 | ||
832 | umul a_6,b_3,t_1 !mul_add_c(a[6],b[3],c1,c2,c3); | ||
833 | addcc c_1,t_1,c_1 != | ||
834 | rd %y,t_2 | ||
835 | addxcc c_2,t_2,c_2 | ||
836 | addx c_3,%g0,c_3 | ||
837 | umul a_7,b_2,t_1 !=!mul_add_c(a[7],b[2],c1,c2,c3); | ||
838 | addcc c_1,t_1,c_1 | ||
839 | rd %y,t_2 | ||
840 | addxcc c_2,t_2,c_2 | ||
841 | addx c_3,%g0,c_3 != | ||
842 | st c_1,rp(9) !r[9]=c1; | ||
843 | |||
844 | umul a_7,b_3,t_1 !mul_add_c(a[7],b[3],c2,c3,c1); | ||
845 | addcc c_2,t_1,c_2 | ||
846 | rd %y,t_2 != | ||
847 | addxcc c_3,t_2,c_3 | ||
848 | addx %g0,%g0,c_1 | ||
849 | umul a_6,b_4,t_1 !mul_add_c(a[6],b[4],c2,c3,c1); | ||
850 | addcc c_2,t_1,c_2 != | ||
851 | rd %y,t_2 | ||
852 | addxcc c_3,t_2,c_3 | ||
853 | addx c_1,%g0,c_1 | ||
854 | umul a_5,b_5,t_1 !=!mul_add_c(a[5],b[5],c2,c3,c1); | ||
855 | addcc c_2,t_1,c_2 | ||
856 | rd %y,t_2 | ||
857 | addxcc c_3,t_2,c_3 | ||
858 | addx c_1,%g0,c_1 != | ||
859 | umul a_4,b_6,t_1 !mul_add_c(a[4],b[6],c2,c3,c1); | ||
860 | addcc c_2,t_1,c_2 | ||
861 | rd %y,t_2 | ||
862 | addxcc c_3,t_2,c_3 != | ||
863 | addx c_1,%g0,c_1 | ||
864 | umul a_3,b_7,t_1 !mul_add_c(a[3],b[7],c2,c3,c1); | ||
865 | addcc c_2,t_1,c_2 | ||
866 | rd %y,t_2 != | ||
867 | addxcc c_3,t_2,c_3 | ||
868 | addx c_1,%g0,c_1 | ||
869 | st c_2,rp(10) !r[10]=c2; | ||
870 | |||
871 | umul a_4,b_7,t_1 !=!mul_add_c(a[4],b[7],c3,c1,c2); | ||
872 | addcc c_3,t_1,c_3 | ||
873 | rd %y,t_2 | ||
874 | addxcc c_1,t_2,c_1 | ||
875 | addx %g0,%g0,c_2 != | ||
876 | umul a_5,b_6,t_1 !mul_add_c(a[5],b[6],c3,c1,c2); | ||
877 | addcc c_3,t_1,c_3 | ||
878 | rd %y,t_2 | ||
879 | addxcc c_1,t_2,c_1 != | ||
880 | addx c_2,%g0,c_2 | ||
881 | umul a_6,b_5,t_1 !mul_add_c(a[6],b[5],c3,c1,c2); | ||
882 | addcc c_3,t_1,c_3 | ||
883 | rd %y,t_2 != | ||
884 | addxcc c_1,t_2,c_1 | ||
885 | addx c_2,%g0,c_2 | ||
886 | umul a_7,b_4,t_1 !mul_add_c(a[7],b[4],c3,c1,c2); | ||
887 | addcc c_3,t_1,c_3 != | ||
888 | rd %y,t_2 | ||
889 | addxcc c_1,t_2,c_1 | ||
890 | st c_3,rp(11) !r[11]=c3; | ||
891 | addx c_2,%g0,c_2 != | ||
892 | |||
893 | umul a_7,b_5,t_1 !mul_add_c(a[7],b[5],c1,c2,c3); | ||
894 | addcc c_1,t_1,c_1 | ||
895 | rd %y,t_2 | ||
896 | addxcc c_2,t_2,c_2 != | ||
897 | addx %g0,%g0,c_3 | ||
898 | umul a_6,b_6,t_1 !mul_add_c(a[6],b[6],c1,c2,c3); | ||
899 | addcc c_1,t_1,c_1 | ||
900 | rd %y,t_2 != | ||
901 | addxcc c_2,t_2,c_2 | ||
902 | addx c_3,%g0,c_3 | ||
903 | umul a_5,b_7,t_1 !mul_add_c(a[5],b[7],c1,c2,c3); | ||
904 | addcc c_1,t_1,c_1 != | ||
905 | rd %y,t_2 | ||
906 | addxcc c_2,t_2,c_2 | ||
907 | st c_1,rp(12) !r[12]=c1; | ||
908 | addx c_3,%g0,c_3 != | ||
909 | |||
910 | umul a_6,b_7,t_1 !mul_add_c(a[6],b[7],c2,c3,c1); | ||
911 | addcc c_2,t_1,c_2 | ||
912 | rd %y,t_2 | ||
913 | addxcc c_3,t_2,c_3 != | ||
914 | addx %g0,%g0,c_1 | ||
915 | umul a_7,b_6,t_1 !mul_add_c(a[7],b[6],c2,c3,c1); | ||
916 | addcc c_2,t_1,c_2 | ||
917 | rd %y,t_2 != | ||
918 | addxcc c_3,t_2,c_3 | ||
919 | addx c_1,%g0,c_1 | ||
920 | st c_2,rp(13) !r[13]=c2; | ||
921 | |||
922 | umul a_7,b_7,t_1 !=!mul_add_c(a[7],b[7],c3,c1,c2); | ||
923 | addcc c_3,t_1,c_3 | ||
924 | rd %y,t_2 | ||
925 | addxcc c_1,t_2,c_1 | ||
926 | nop != | ||
927 | st c_3,rp(14) !r[14]=c3; | ||
928 | st c_1,rp(15) !r[15]=c1; | ||
929 | |||
930 | ret | ||
931 | restore %g0,%g0,%o0 | ||
932 | |||
933 | .type bn_mul_comba8,#function | ||
934 | .size bn_mul_comba8,(.-bn_mul_comba8) | ||
935 | |||
936 | .align 32 | ||
937 | |||
938 | .global bn_mul_comba4 | ||
939 | /* | ||
940 | * void bn_mul_comba4(r,a,b) | ||
941 | * BN_ULONG *r,*a,*b; | ||
942 | */ | ||
943 | bn_mul_comba4: | ||
944 | save %sp,FRAME_SIZE,%sp | ||
945 | ld ap(0),a_0 | ||
946 | ld bp(0),b_0 | ||
947 | umul a_0,b_0,c_1 !=!mul_add_c(a[0],b[0],c1,c2,c3); | ||
948 | ld bp(1),b_1 | ||
949 | rd %y,c_2 | ||
950 | st c_1,rp(0) !r[0]=c1; | ||
951 | |||
952 | umul a_0,b_1,t_1 !=!mul_add_c(a[0],b[1],c2,c3,c1); | ||
953 | ld ap(1),a_1 | ||
954 | addcc c_2,t_1,c_2 | ||
955 | rd %y,t_2 != | ||
956 | addxcc %g0,t_2,c_3 | ||
957 | addx %g0,%g0,c_1 | ||
958 | ld ap(2),a_2 | ||
959 | umul a_1,b_0,t_1 !=!mul_add_c(a[1],b[0],c2,c3,c1); | ||
960 | addcc c_2,t_1,c_2 | ||
961 | rd %y,t_2 | ||
962 | addxcc c_3,t_2,c_3 | ||
963 | addx c_1,%g0,c_1 != | ||
964 | st c_2,rp(1) !r[1]=c2; | ||
965 | |||
966 | umul a_2,b_0,t_1 !mul_add_c(a[2],b[0],c3,c1,c2); | ||
967 | addcc c_3,t_1,c_3 | ||
968 | rd %y,t_2 != | ||
969 | addxcc c_1,t_2,c_1 | ||
970 | addx %g0,%g0,c_2 | ||
971 | ld bp(2),b_2 | ||
972 | umul a_1,b_1,t_1 !=!mul_add_c(a[1],b[1],c3,c1,c2); | ||
973 | addcc c_3,t_1,c_3 | ||
974 | rd %y,t_2 | ||
975 | addxcc c_1,t_2,c_1 | ||
976 | addx c_2,%g0,c_2 != | ||
977 | ld bp(3),b_3 | ||
978 | umul a_0,b_2,t_1 !mul_add_c(a[0],b[2],c3,c1,c2); | ||
979 | addcc c_3,t_1,c_3 | ||
980 | rd %y,t_2 != | ||
981 | addxcc c_1,t_2,c_1 | ||
982 | addx c_2,%g0,c_2 | ||
983 | st c_3,rp(2) !r[2]=c3; | ||
984 | |||
985 | umul a_0,b_3,t_1 !=!mul_add_c(a[0],b[3],c1,c2,c3); | ||
986 | addcc c_1,t_1,c_1 | ||
987 | rd %y,t_2 | ||
988 | addxcc c_2,t_2,c_2 | ||
989 | addx %g0,%g0,c_3 != | ||
990 | umul a_1,b_2,t_1 !mul_add_c(a[1],b[2],c1,c2,c3); | ||
991 | addcc c_1,t_1,c_1 | ||
992 | rd %y,t_2 | ||
993 | addxcc c_2,t_2,c_2 != | ||
994 | addx c_3,%g0,c_3 | ||
995 | ld ap(3),a_3 | ||
996 | umul a_2,b_1,t_1 !mul_add_c(a[2],b[1],c1,c2,c3); | ||
997 | addcc c_1,t_1,c_1 != | ||
998 | rd %y,t_2 | ||
999 | addxcc c_2,t_2,c_2 | ||
1000 | addx c_3,%g0,c_3 | ||
1001 | umul a_3,b_0,t_1 !=!mul_add_c(a[3],b[0],c1,c2,c3); | ||
1002 | addcc c_1,t_1,c_1 | ||
1003 | rd %y,t_2 | ||
1004 | addxcc c_2,t_2,c_2 | ||
1005 | addx c_3,%g0,c_3 != | ||
1006 | st c_1,rp(3) !r[3]=c1; | ||
1007 | |||
1008 | umul a_3,b_1,t_1 !mul_add_c(a[3],b[1],c2,c3,c1); | ||
1009 | addcc c_2,t_1,c_2 | ||
1010 | rd %y,t_2 != | ||
1011 | addxcc c_3,t_2,c_3 | ||
1012 | addx %g0,%g0,c_1 | ||
1013 | umul a_2,b_2,t_1 !mul_add_c(a[2],b[2],c2,c3,c1); | ||
1014 | addcc c_2,t_1,c_2 != | ||
1015 | rd %y,t_2 | ||
1016 | addxcc c_3,t_2,c_3 | ||
1017 | addx c_1,%g0,c_1 | ||
1018 | umul a_1,b_3,t_1 !=!mul_add_c(a[1],b[3],c2,c3,c1); | ||
1019 | addcc c_2,t_1,c_2 | ||
1020 | rd %y,t_2 | ||
1021 | addxcc c_3,t_2,c_3 | ||
1022 | addx c_1,%g0,c_1 != | ||
1023 | st c_2,rp(4) !r[4]=c2; | ||
1024 | |||
1025 | umul a_2,b_3,t_1 !mul_add_c(a[2],b[3],c3,c1,c2); | ||
1026 | addcc c_3,t_1,c_3 | ||
1027 | rd %y,t_2 != | ||
1028 | addxcc c_1,t_2,c_1 | ||
1029 | addx %g0,%g0,c_2 | ||
1030 | umul a_3,b_2,t_1 !mul_add_c(a[3],b[2],c3,c1,c2); | ||
1031 | addcc c_3,t_1,c_3 != | ||
1032 | rd %y,t_2 | ||
1033 | addxcc c_1,t_2,c_1 | ||
1034 | st c_3,rp(5) !r[5]=c3; | ||
1035 | addx c_2,%g0,c_2 != | ||
1036 | |||
1037 | umul a_3,b_3,t_1 !mul_add_c(a[3],b[3],c1,c2,c3); | ||
1038 | addcc c_1,t_1,c_1 | ||
1039 | rd %y,t_2 | ||
1040 | addxcc c_2,t_2,c_2 != | ||
1041 | st c_1,rp(6) !r[6]=c1; | ||
1042 | st c_2,rp(7) !r[7]=c2; | ||
1043 | |||
1044 | ret | ||
1045 | restore %g0,%g0,%o0 | ||
1046 | |||
1047 | .type bn_mul_comba4,#function | ||
1048 | .size bn_mul_comba4,(.-bn_mul_comba4) | ||
1049 | |||
1050 | .align 32 | ||
1051 | |||
1052 | .global bn_sqr_comba8 | ||
1053 | bn_sqr_comba8: | ||
1054 | save %sp,FRAME_SIZE,%sp | ||
1055 | ld ap(0),a_0 | ||
1056 | ld ap(1),a_1 | ||
1057 | umul a_0,a_0,c_1 !=!sqr_add_c(a,0,c1,c2,c3); | ||
1058 | rd %y,c_2 | ||
1059 | st c_1,rp(0) !r[0]=c1; | ||
1060 | |||
1061 | ld ap(2),a_2 | ||
1062 | umul a_0,a_1,t_1 !=!sqr_add_c2(a,1,0,c2,c3,c1); | ||
1063 | addcc c_2,t_1,c_2 | ||
1064 | rd %y,t_2 | ||
1065 | addxcc %g0,t_2,c_3 | ||
1066 | addx %g0,%g0,c_1 != | ||
1067 | addcc c_2,t_1,c_2 | ||
1068 | addxcc c_3,t_2,c_3 | ||
1069 | st c_2,rp(1) !r[1]=c2; | ||
1070 | addx c_1,%g0,c_1 != | ||
1071 | |||
1072 | umul a_2,a_0,t_1 !sqr_add_c2(a,2,0,c3,c1,c2); | ||
1073 | addcc c_3,t_1,c_3 | ||
1074 | rd %y,t_2 | ||
1075 | addxcc c_1,t_2,c_1 != | ||
1076 | addx %g0,%g0,c_2 | ||
1077 | addcc c_3,t_1,c_3 | ||
1078 | addxcc c_1,t_2,c_1 | ||
1079 | addx c_2,%g0,c_2 != | ||
1080 | ld ap(3),a_3 | ||
1081 | umul a_1,a_1,t_1 !sqr_add_c(a,1,c3,c1,c2); | ||
1082 | addcc c_3,t_1,c_3 | ||
1083 | rd %y,t_2 != | ||
1084 | addxcc c_1,t_2,c_1 | ||
1085 | addx c_2,%g0,c_2 | ||
1086 | st c_3,rp(2) !r[2]=c3; | ||
1087 | |||
1088 | umul a_0,a_3,t_1 !=!sqr_add_c2(a,3,0,c1,c2,c3); | ||
1089 | addcc c_1,t_1,c_1 | ||
1090 | rd %y,t_2 | ||
1091 | addxcc c_2,t_2,c_2 | ||
1092 | addx %g0,%g0,c_3 != | ||
1093 | addcc c_1,t_1,c_1 | ||
1094 | addxcc c_2,t_2,c_2 | ||
1095 | ld ap(4),a_4 | ||
1096 | addx c_3,%g0,c_3 != | ||
1097 | umul a_1,a_2,t_1 !sqr_add_c2(a,2,1,c1,c2,c3); | ||
1098 | addcc c_1,t_1,c_1 | ||
1099 | rd %y,t_2 | ||
1100 | addxcc c_2,t_2,c_2 != | ||
1101 | addx c_3,%g0,c_3 | ||
1102 | addcc c_1,t_1,c_1 | ||
1103 | addxcc c_2,t_2,c_2 | ||
1104 | addx c_3,%g0,c_3 != | ||
1105 | st c_1,rp(3) !r[3]=c1; | ||
1106 | |||
1107 | umul a_4,a_0,t_1 !sqr_add_c2(a,4,0,c2,c3,c1); | ||
1108 | addcc c_2,t_1,c_2 | ||
1109 | rd %y,t_2 != | ||
1110 | addxcc c_3,t_2,c_3 | ||
1111 | addx %g0,%g0,c_1 | ||
1112 | addcc c_2,t_1,c_2 | ||
1113 | addxcc c_3,t_2,c_3 != | ||
1114 | addx c_1,%g0,c_1 | ||
1115 | umul a_3,a_1,t_1 !sqr_add_c2(a,3,1,c2,c3,c1); | ||
1116 | addcc c_2,t_1,c_2 | ||
1117 | rd %y,t_2 != | ||
1118 | addxcc c_3,t_2,c_3 | ||
1119 | addx c_1,%g0,c_1 | ||
1120 | addcc c_2,t_1,c_2 | ||
1121 | addxcc c_3,t_2,c_3 != | ||
1122 | addx c_1,%g0,c_1 | ||
1123 | ld ap(5),a_5 | ||
1124 | umul a_2,a_2,t_1 !sqr_add_c(a,2,c2,c3,c1); | ||
1125 | addcc c_2,t_1,c_2 != | ||
1126 | rd %y,t_2 | ||
1127 | addxcc c_3,t_2,c_3 | ||
1128 | st c_2,rp(4) !r[4]=c2; | ||
1129 | addx c_1,%g0,c_1 != | ||
1130 | |||
1131 | umul a_0,a_5,t_1 !sqr_add_c2(a,5,0,c3,c1,c2); | ||
1132 | addcc c_3,t_1,c_3 | ||
1133 | rd %y,t_2 | ||
1134 | addxcc c_1,t_2,c_1 != | ||
1135 | addx %g0,%g0,c_2 | ||
1136 | addcc c_3,t_1,c_3 | ||
1137 | addxcc c_1,t_2,c_1 | ||
1138 | addx c_2,%g0,c_2 != | ||
1139 | umul a_1,a_4,t_1 !sqr_add_c2(a,4,1,c3,c1,c2); | ||
1140 | addcc c_3,t_1,c_3 | ||
1141 | rd %y,t_2 | ||
1142 | addxcc c_1,t_2,c_1 != | ||
1143 | addx c_2,%g0,c_2 | ||
1144 | addcc c_3,t_1,c_3 | ||
1145 | addxcc c_1,t_2,c_1 | ||
1146 | addx c_2,%g0,c_2 != | ||
1147 | ld ap(6),a_6 | ||
1148 | umul a_2,a_3,t_1 !sqr_add_c2(a,3,2,c3,c1,c2); | ||
1149 | addcc c_3,t_1,c_3 | ||
1150 | rd %y,t_2 != | ||
1151 | addxcc c_1,t_2,c_1 | ||
1152 | addx c_2,%g0,c_2 | ||
1153 | addcc c_3,t_1,c_3 | ||
1154 | addxcc c_1,t_2,c_1 != | ||
1155 | addx c_2,%g0,c_2 | ||
1156 | st c_3,rp(5) !r[5]=c3; | ||
1157 | |||
1158 | umul a_6,a_0,t_1 !sqr_add_c2(a,6,0,c1,c2,c3); | ||
1159 | addcc c_1,t_1,c_1 != | ||
1160 | rd %y,t_2 | ||
1161 | addxcc c_2,t_2,c_2 | ||
1162 | addx %g0,%g0,c_3 | ||
1163 | addcc c_1,t_1,c_1 != | ||
1164 | addxcc c_2,t_2,c_2 | ||
1165 | addx c_3,%g0,c_3 | ||
1166 | umul a_5,a_1,t_1 !sqr_add_c2(a,5,1,c1,c2,c3); | ||
1167 | addcc c_1,t_1,c_1 != | ||
1168 | rd %y,t_2 | ||
1169 | addxcc c_2,t_2,c_2 | ||
1170 | addx c_3,%g0,c_3 | ||
1171 | addcc c_1,t_1,c_1 != | ||
1172 | addxcc c_2,t_2,c_2 | ||
1173 | addx c_3,%g0,c_3 | ||
1174 | umul a_4,a_2,t_1 !sqr_add_c2(a,4,2,c1,c2,c3); | ||
1175 | addcc c_1,t_1,c_1 != | ||
1176 | rd %y,t_2 | ||
1177 | addxcc c_2,t_2,c_2 | ||
1178 | addx c_3,%g0,c_3 | ||
1179 | addcc c_1,t_1,c_1 != | ||
1180 | addxcc c_2,t_2,c_2 | ||
1181 | addx c_3,%g0,c_3 | ||
1182 | ld ap(7),a_7 | ||
1183 | umul a_3,a_3,t_1 !=!sqr_add_c(a,3,c1,c2,c3); | ||
1184 | addcc c_1,t_1,c_1 | ||
1185 | rd %y,t_2 | ||
1186 | addxcc c_2,t_2,c_2 | ||
1187 | addx c_3,%g0,c_3 != | ||
1188 | st c_1,rp(6) !r[6]=c1; | ||
1189 | |||
1190 | umul a_0,a_7,t_1 !sqr_add_c2(a,7,0,c2,c3,c1); | ||
1191 | addcc c_2,t_1,c_2 | ||
1192 | rd %y,t_2 != | ||
1193 | addxcc c_3,t_2,c_3 | ||
1194 | addx %g0,%g0,c_1 | ||
1195 | addcc c_2,t_1,c_2 | ||
1196 | addxcc c_3,t_2,c_3 != | ||
1197 | addx c_1,%g0,c_1 | ||
1198 | umul a_1,a_6,t_1 !sqr_add_c2(a,6,1,c2,c3,c1); | ||
1199 | addcc c_2,t_1,c_2 | ||
1200 | rd %y,t_2 != | ||
1201 | addxcc c_3,t_2,c_3 | ||
1202 | addx c_1,%g0,c_1 | ||
1203 | addcc c_2,t_1,c_2 | ||
1204 | addxcc c_3,t_2,c_3 != | ||
1205 | addx c_1,%g0,c_1 | ||
1206 | umul a_2,a_5,t_1 !sqr_add_c2(a,5,2,c2,c3,c1); | ||
1207 | addcc c_2,t_1,c_2 | ||
1208 | rd %y,t_2 != | ||
1209 | addxcc c_3,t_2,c_3 | ||
1210 | addx c_1,%g0,c_1 | ||
1211 | addcc c_2,t_1,c_2 | ||
1212 | addxcc c_3,t_2,c_3 != | ||
1213 | addx c_1,%g0,c_1 | ||
1214 | umul a_3,a_4,t_1 !sqr_add_c2(a,4,3,c2,c3,c1); | ||
1215 | addcc c_2,t_1,c_2 | ||
1216 | rd %y,t_2 != | ||
1217 | addxcc c_3,t_2,c_3 | ||
1218 | addx c_1,%g0,c_1 | ||
1219 | addcc c_2,t_1,c_2 | ||
1220 | addxcc c_3,t_2,c_3 != | ||
1221 | addx c_1,%g0,c_1 | ||
1222 | st c_2,rp(7) !r[7]=c2; | ||
1223 | |||
1224 | umul a_7,a_1,t_1 !sqr_add_c2(a,7,1,c3,c1,c2); | ||
1225 | addcc c_3,t_1,c_3 != | ||
1226 | rd %y,t_2 | ||
1227 | addxcc c_1,t_2,c_1 | ||
1228 | addx %g0,%g0,c_2 | ||
1229 | addcc c_3,t_1,c_3 != | ||
1230 | addxcc c_1,t_2,c_1 | ||
1231 | addx c_2,%g0,c_2 | ||
1232 | umul a_6,a_2,t_1 !sqr_add_c2(a,6,2,c3,c1,c2); | ||
1233 | addcc c_3,t_1,c_3 != | ||
1234 | rd %y,t_2 | ||
1235 | addxcc c_1,t_2,c_1 | ||
1236 | addx c_2,%g0,c_2 | ||
1237 | addcc c_3,t_1,c_3 != | ||
1238 | addxcc c_1,t_2,c_1 | ||
1239 | addx c_2,%g0,c_2 | ||
1240 | umul a_5,a_3,t_1 !sqr_add_c2(a,5,3,c3,c1,c2); | ||
1241 | addcc c_3,t_1,c_3 != | ||
1242 | rd %y,t_2 | ||
1243 | addxcc c_1,t_2,c_1 | ||
1244 | addx c_2,%g0,c_2 | ||
1245 | addcc c_3,t_1,c_3 != | ||
1246 | addxcc c_1,t_2,c_1 | ||
1247 | addx c_2,%g0,c_2 | ||
1248 | umul a_4,a_4,t_1 !sqr_add_c(a,4,c3,c1,c2); | ||
1249 | addcc c_3,t_1,c_3 != | ||
1250 | rd %y,t_2 | ||
1251 | addxcc c_1,t_2,c_1 | ||
1252 | st c_3,rp(8) !r[8]=c3; | ||
1253 | addx c_2,%g0,c_2 != | ||
1254 | |||
1255 | umul a_2,a_7,t_1 !sqr_add_c2(a,7,2,c1,c2,c3); | ||
1256 | addcc c_1,t_1,c_1 | ||
1257 | rd %y,t_2 | ||
1258 | addxcc c_2,t_2,c_2 != | ||
1259 | addx %g0,%g0,c_3 | ||
1260 | addcc c_1,t_1,c_1 | ||
1261 | addxcc c_2,t_2,c_2 | ||
1262 | addx c_3,%g0,c_3 != | ||
1263 | umul a_3,a_6,t_1 !sqr_add_c2(a,6,3,c1,c2,c3); | ||
1264 | addcc c_1,t_1,c_1 | ||
1265 | rd %y,t_2 | ||
1266 | addxcc c_2,t_2,c_2 != | ||
1267 | addx c_3,%g0,c_3 | ||
1268 | addcc c_1,t_1,c_1 | ||
1269 | addxcc c_2,t_2,c_2 | ||
1270 | addx c_3,%g0,c_3 != | ||
1271 | umul a_4,a_5,t_1 !sqr_add_c2(a,5,4,c1,c2,c3); | ||
1272 | addcc c_1,t_1,c_1 | ||
1273 | rd %y,t_2 | ||
1274 | addxcc c_2,t_2,c_2 != | ||
1275 | addx c_3,%g0,c_3 | ||
1276 | addcc c_1,t_1,c_1 | ||
1277 | addxcc c_2,t_2,c_2 | ||
1278 | addx c_3,%g0,c_3 != | ||
1279 | st c_1,rp(9) !r[9]=c1; | ||
1280 | |||
1281 | umul a_7,a_3,t_1 !sqr_add_c2(a,7,3,c2,c3,c1); | ||
1282 | addcc c_2,t_1,c_2 | ||
1283 | rd %y,t_2 != | ||
1284 | addxcc c_3,t_2,c_3 | ||
1285 | addx %g0,%g0,c_1 | ||
1286 | addcc c_2,t_1,c_2 | ||
1287 | addxcc c_3,t_2,c_3 != | ||
1288 | addx c_1,%g0,c_1 | ||
1289 | umul a_6,a_4,t_1 !sqr_add_c2(a,6,4,c2,c3,c1); | ||
1290 | addcc c_2,t_1,c_2 | ||
1291 | rd %y,t_2 != | ||
1292 | addxcc c_3,t_2,c_3 | ||
1293 | addx c_1,%g0,c_1 | ||
1294 | addcc c_2,t_1,c_2 | ||
1295 | addxcc c_3,t_2,c_3 != | ||
1296 | addx c_1,%g0,c_1 | ||
1297 | umul a_5,a_5,t_1 !sqr_add_c(a,5,c2,c3,c1); | ||
1298 | addcc c_2,t_1,c_2 | ||
1299 | rd %y,t_2 != | ||
1300 | addxcc c_3,t_2,c_3 | ||
1301 | addx c_1,%g0,c_1 | ||
1302 | st c_2,rp(10) !r[10]=c2; | ||
1303 | |||
1304 | umul a_4,a_7,t_1 !=!sqr_add_c2(a,7,4,c3,c1,c2); | ||
1305 | addcc c_3,t_1,c_3 | ||
1306 | rd %y,t_2 | ||
1307 | addxcc c_1,t_2,c_1 | ||
1308 | addx %g0,%g0,c_2 != | ||
1309 | addcc c_3,t_1,c_3 | ||
1310 | addxcc c_1,t_2,c_1 | ||
1311 | addx c_2,%g0,c_2 | ||
1312 | umul a_5,a_6,t_1 !=!sqr_add_c2(a,6,5,c3,c1,c2); | ||
1313 | addcc c_3,t_1,c_3 | ||
1314 | rd %y,t_2 | ||
1315 | addxcc c_1,t_2,c_1 | ||
1316 | addx c_2,%g0,c_2 != | ||
1317 | addcc c_3,t_1,c_3 | ||
1318 | addxcc c_1,t_2,c_1 | ||
1319 | st c_3,rp(11) !r[11]=c3; | ||
1320 | addx c_2,%g0,c_2 != | ||
1321 | |||
1322 | umul a_7,a_5,t_1 !sqr_add_c2(a,7,5,c1,c2,c3); | ||
1323 | addcc c_1,t_1,c_1 | ||
1324 | rd %y,t_2 | ||
1325 | addxcc c_2,t_2,c_2 != | ||
1326 | addx %g0,%g0,c_3 | ||
1327 | addcc c_1,t_1,c_1 | ||
1328 | addxcc c_2,t_2,c_2 | ||
1329 | addx c_3,%g0,c_3 != | ||
1330 | umul a_6,a_6,t_1 !sqr_add_c(a,6,c1,c2,c3); | ||
1331 | addcc c_1,t_1,c_1 | ||
1332 | rd %y,t_2 | ||
1333 | addxcc c_2,t_2,c_2 != | ||
1334 | addx c_3,%g0,c_3 | ||
1335 | st c_1,rp(12) !r[12]=c1; | ||
1336 | |||
1337 | umul a_6,a_7,t_1 !sqr_add_c2(a,7,6,c2,c3,c1); | ||
1338 | addcc c_2,t_1,c_2 != | ||
1339 | rd %y,t_2 | ||
1340 | addxcc c_3,t_2,c_3 | ||
1341 | addx %g0,%g0,c_1 | ||
1342 | addcc c_2,t_1,c_2 != | ||
1343 | addxcc c_3,t_2,c_3 | ||
1344 | st c_2,rp(13) !r[13]=c2; | ||
1345 | addx c_1,%g0,c_1 != | ||
1346 | |||
1347 | umul a_7,a_7,t_1 !sqr_add_c(a,7,c3,c1,c2); | ||
1348 | addcc c_3,t_1,c_3 | ||
1349 | rd %y,t_2 | ||
1350 | addxcc c_1,t_2,c_1 != | ||
1351 | st c_3,rp(14) !r[14]=c3; | ||
1352 | st c_1,rp(15) !r[15]=c1; | ||
1353 | |||
1354 | ret | ||
1355 | restore %g0,%g0,%o0 | ||
1356 | |||
1357 | .type bn_sqr_comba8,#function | ||
1358 | .size bn_sqr_comba8,(.-bn_sqr_comba8) | ||
1359 | |||
1360 | .align 32 | ||
1361 | |||
1362 | .global bn_sqr_comba4 | ||
1363 | /* | ||
1364 | * void bn_sqr_comba4(r,a) | ||
1365 | * BN_ULONG *r,*a; | ||
1366 | */ | ||
1367 | bn_sqr_comba4: | ||
1368 | save %sp,FRAME_SIZE,%sp | ||
1369 | ld ap(0),a_0 | ||
1370 | umul a_0,a_0,c_1 !sqr_add_c(a,0,c1,c2,c3); | ||
1371 | ld ap(1),a_1 != | ||
1372 | rd %y,c_2 | ||
1373 | st c_1,rp(0) !r[0]=c1; | ||
1374 | |||
1375 | ld ap(2),a_2 | ||
1376 | umul a_0,a_1,t_1 !=!sqr_add_c2(a,1,0,c2,c3,c1); | ||
1377 | addcc c_2,t_1,c_2 | ||
1378 | rd %y,t_2 | ||
1379 | addxcc %g0,t_2,c_3 | ||
1380 | addx %g0,%g0,c_1 != | ||
1381 | addcc c_2,t_1,c_2 | ||
1382 | addxcc c_3,t_2,c_3 | ||
1383 | addx c_1,%g0,c_1 != | ||
1384 | st c_2,rp(1) !r[1]=c2; | ||
1385 | |||
1386 | umul a_2,a_0,t_1 !sqr_add_c2(a,2,0,c3,c1,c2); | ||
1387 | addcc c_3,t_1,c_3 | ||
1388 | rd %y,t_2 != | ||
1389 | addxcc c_1,t_2,c_1 | ||
1390 | addx %g0,%g0,c_2 | ||
1391 | addcc c_3,t_1,c_3 | ||
1392 | addxcc c_1,t_2,c_1 != | ||
1393 | addx c_2,%g0,c_2 | ||
1394 | ld ap(3),a_3 | ||
1395 | umul a_1,a_1,t_1 !sqr_add_c(a,1,c3,c1,c2); | ||
1396 | addcc c_3,t_1,c_3 != | ||
1397 | rd %y,t_2 | ||
1398 | addxcc c_1,t_2,c_1 | ||
1399 | st c_3,rp(2) !r[2]=c3; | ||
1400 | addx c_2,%g0,c_2 != | ||
1401 | |||
1402 | umul a_0,a_3,t_1 !sqr_add_c2(a,3,0,c1,c2,c3); | ||
1403 | addcc c_1,t_1,c_1 | ||
1404 | rd %y,t_2 | ||
1405 | addxcc c_2,t_2,c_2 != | ||
1406 | addx %g0,%g0,c_3 | ||
1407 | addcc c_1,t_1,c_1 | ||
1408 | addxcc c_2,t_2,c_2 | ||
1409 | addx c_3,%g0,c_3 != | ||
1410 | umul a_1,a_2,t_1 !sqr_add_c2(a,2,1,c1,c2,c3); | ||
1411 | addcc c_1,t_1,c_1 | ||
1412 | rd %y,t_2 | ||
1413 | addxcc c_2,t_2,c_2 != | ||
1414 | addx c_3,%g0,c_3 | ||
1415 | addcc c_1,t_1,c_1 | ||
1416 | addxcc c_2,t_2,c_2 | ||
1417 | addx c_3,%g0,c_3 != | ||
1418 | st c_1,rp(3) !r[3]=c1; | ||
1419 | |||
1420 | umul a_3,a_1,t_1 !sqr_add_c2(a,3,1,c2,c3,c1); | ||
1421 | addcc c_2,t_1,c_2 | ||
1422 | rd %y,t_2 != | ||
1423 | addxcc c_3,t_2,c_3 | ||
1424 | addx %g0,%g0,c_1 | ||
1425 | addcc c_2,t_1,c_2 | ||
1426 | addxcc c_3,t_2,c_3 != | ||
1427 | addx c_1,%g0,c_1 | ||
1428 | umul a_2,a_2,t_1 !sqr_add_c(a,2,c2,c3,c1); | ||
1429 | addcc c_2,t_1,c_2 | ||
1430 | rd %y,t_2 != | ||
1431 | addxcc c_3,t_2,c_3 | ||
1432 | addx c_1,%g0,c_1 | ||
1433 | st c_2,rp(4) !r[4]=c2; | ||
1434 | |||
1435 | umul a_2,a_3,t_1 !=!sqr_add_c2(a,3,2,c3,c1,c2); | ||
1436 | addcc c_3,t_1,c_3 | ||
1437 | rd %y,t_2 | ||
1438 | addxcc c_1,t_2,c_1 | ||
1439 | addx %g0,%g0,c_2 != | ||
1440 | addcc c_3,t_1,c_3 | ||
1441 | addxcc c_1,t_2,c_1 | ||
1442 | st c_3,rp(5) !r[5]=c3; | ||
1443 | addx c_2,%g0,c_2 != | ||
1444 | |||
1445 | umul a_3,a_3,t_1 !sqr_add_c(a,3,c1,c2,c3); | ||
1446 | addcc c_1,t_1,c_1 | ||
1447 | rd %y,t_2 | ||
1448 | addxcc c_2,t_2,c_2 != | ||
1449 | st c_1,rp(6) !r[6]=c1; | ||
1450 | st c_2,rp(7) !r[7]=c2; | ||
1451 | |||
1452 | ret | ||
1453 | restore %g0,%g0,%o0 | ||
1454 | |||
1455 | .type bn_sqr_comba4,#function | ||
1456 | .size bn_sqr_comba4,(.-bn_sqr_comba4) | ||
1457 | |||
1458 | .align 32 | ||
diff --git a/src/lib/libcrypto/bn/asm/sparcv8plus.S b/src/lib/libcrypto/bn/asm/sparcv8plus.S new file mode 100644 index 0000000000..0074dfdb75 --- /dev/null +++ b/src/lib/libcrypto/bn/asm/sparcv8plus.S | |||
@@ -0,0 +1,1535 @@ | |||
1 | .ident "sparcv8plus.s, Version 1.4" | ||
2 | .ident "SPARC v9 ISA artwork by Andy Polyakov <appro@fy.chalmers.se>" | ||
3 | |||
4 | /* | ||
5 | * ==================================================================== | ||
6 | * Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL | ||
7 | * project. | ||
8 | * | ||
9 | * Rights for redistribution and usage in source and binary forms are | ||
10 | * granted according to the OpenSSL license. Warranty of any kind is | ||
11 | * disclaimed. | ||
12 | * ==================================================================== | ||
13 | */ | ||
14 | |||
15 | /* | ||
16 | * This is my modest contributon to OpenSSL project (see | ||
17 | * http://www.openssl.org/ for more information about it) and is | ||
18 | * a drop-in UltraSPARC ISA replacement for crypto/bn/bn_asm.c | ||
19 | * module. For updates see http://fy.chalmers.se/~appro/hpe/. | ||
20 | * | ||
21 | * Questions-n-answers. | ||
22 | * | ||
23 | * Q. How to compile? | ||
24 | * A. With SC4.x/SC5.x: | ||
25 | * | ||
26 | * cc -xarch=v8plus -c bn_asm.sparc.v8plus.S -o bn_asm.o | ||
27 | * | ||
28 | * and with gcc: | ||
29 | * | ||
30 | * gcc -mcpu=ultrasparc -c bn_asm.sparc.v8plus.S -o bn_asm.o | ||
31 | * | ||
32 | * or if above fails (it does if you have gas installed): | ||
33 | * | ||
34 | * gcc -E bn_asm.sparc.v8plus.S | as -xarch=v8plus /dev/fd/0 -o bn_asm.o | ||
35 | * | ||
36 | * Quick-n-dirty way to fuse the module into the library. | ||
37 | * Provided that the library is already configured and built | ||
38 | * (in 0.9.2 case with no-asm option): | ||
39 | * | ||
40 | * # cd crypto/bn | ||
41 | * # cp /some/place/bn_asm.sparc.v8plus.S . | ||
42 | * # cc -xarch=v8plus -c bn_asm.sparc.v8plus.S -o bn_asm.o | ||
43 | * # make | ||
44 | * # cd ../.. | ||
45 | * # make; make test | ||
46 | * | ||
47 | * Quick-n-dirty way to get rid of it: | ||
48 | * | ||
49 | * # cd crypto/bn | ||
50 | * # touch bn_asm.c | ||
51 | * # make | ||
52 | * # cd ../.. | ||
53 | * # make; make test | ||
54 | * | ||
55 | * Q. V8plus achitecture? What kind of beast is that? | ||
56 | * A. Well, it's rather a programming model than an architecture... | ||
57 | * It's actually v9-compliant, i.e. *any* UltraSPARC, CPU under | ||
58 | * special conditions, namely when kernel doesn't preserve upper | ||
59 | * 32 bits of otherwise 64-bit registers during a context switch. | ||
60 | * | ||
61 | * Q. Why just UltraSPARC? What about SuperSPARC? | ||
62 | * A. Original release did target UltraSPARC only. Now SuperSPARC | ||
63 | * version is provided along. Both version share bn_*comba[48] | ||
64 | * implementations (see comment later in code for explanation). | ||
65 | * But what's so special about this UltraSPARC implementation? | ||
66 | * Why didn't I let compiler do the job? Trouble is that most of | ||
67 | * available compilers (well, SC5.0 is the only exception) don't | ||
68 | * attempt to take advantage of UltraSPARC's 64-bitness under | ||
69 | * 32-bit kernels even though it's perfectly possible (see next | ||
70 | * question). | ||
71 | * | ||
72 | * Q. 64-bit registers under 32-bit kernels? Didn't you just say it | ||
73 | * doesn't work? | ||
74 | * A. You can't adress *all* registers as 64-bit wide:-( The catch is | ||
75 | * that you actually may rely upon %o0-%o5 and %g1-%g4 being fully | ||
76 | * preserved if you're in a leaf function, i.e. such never calling | ||
77 | * any other functions. All functions in this module are leaf and | ||
78 | * 10 registers is a handful. And as a matter of fact none-"comba" | ||
79 | * routines don't require even that much and I could even afford to | ||
80 | * not allocate own stack frame for 'em:-) | ||
81 | * | ||
82 | * Q. What about 64-bit kernels? | ||
83 | * A. What about 'em? Just kidding:-) Pure 64-bit version is currently | ||
84 | * under evaluation and development... | ||
85 | * | ||
86 | * Q. What about shared libraries? | ||
87 | * A. What about 'em? Kidding again:-) Code does *not* contain any | ||
88 | * code position dependencies and it's safe to include it into | ||
89 | * shared library as is. | ||
90 | * | ||
91 | * Q. How much faster does it go? | ||
92 | * A. Do you have a good benchmark? In either case below is what I | ||
93 | * experience with crypto/bn/expspeed.c test program: | ||
94 | * | ||
95 | * v8plus module on U10/300MHz against bn_asm.c compiled with: | ||
96 | * | ||
97 | * cc-5.0 -xarch=v8plus -xO5 -xdepend +7-12% | ||
98 | * cc-4.2 -xarch=v8plus -xO5 -xdepend +25-35% | ||
99 | * egcs-1.1.2 -mcpu=ultrasparc -O3 +35-45% | ||
100 | * | ||
101 | * v8 module on SS10/60MHz against bn_asm.c compiled with: | ||
102 | * | ||
103 | * cc-5.0 -xarch=v8 -xO5 -xdepend +7-10% | ||
104 | * cc-4.2 -xarch=v8 -xO5 -xdepend +10% | ||
105 | * egcs-1.1.2 -mv8 -O3 +35-45% | ||
106 | * | ||
107 | * As you can see it's damn hard to beat the new Sun C compiler | ||
108 | * and it's in first place GNU C users who will appreciate this | ||
109 | * assembler implementation:-) | ||
110 | */ | ||
111 | |||
112 | /* | ||
113 | * Revision history. | ||
114 | * | ||
115 | * 1.0 - initial release; | ||
116 | * 1.1 - new loop unrolling model(*); | ||
117 | * - some more fine tuning; | ||
118 | * 1.2 - made gas friendly; | ||
119 | * - updates to documentation concerning v9; | ||
120 | * - new performance comparison matrix; | ||
121 | * 1.3 - fixed problem with /usr/ccs/lib/cpp; | ||
122 | * 1.4 - native V9 bn_*_comba[48] implementation (15% more efficient) | ||
123 | * resulting in slight overall performance kick; | ||
124 | * - some retunes; | ||
125 | * - support for GNU as added; | ||
126 | * | ||
127 | * (*) Originally unrolled loop looked like this: | ||
128 | * for (;;) { | ||
129 | * op(p+0); if (--n==0) break; | ||
130 | * op(p+1); if (--n==0) break; | ||
131 | * op(p+2); if (--n==0) break; | ||
132 | * op(p+3); if (--n==0) break; | ||
133 | * p+=4; | ||
134 | * } | ||
135 | * I unroll according to following: | ||
136 | * while (n&~3) { | ||
137 | * op(p+0); op(p+1); op(p+2); op(p+3); | ||
138 | * p+=4; n=-4; | ||
139 | * } | ||
140 | * if (n) { | ||
141 | * op(p+0); if (--n==0) return; | ||
142 | * op(p+2); if (--n==0) return; | ||
143 | * op(p+3); return; | ||
144 | * } | ||
145 | */ | ||
146 | |||
147 | /* | ||
148 | * GNU assembler can't stand stuw:-( | ||
149 | */ | ||
150 | #define stuw st | ||
151 | |||
152 | .section ".text",#alloc,#execinstr | ||
153 | .file "bn_asm.sparc.v8plus.S" | ||
154 | |||
155 | .align 32 | ||
156 | |||
157 | .global bn_mul_add_words | ||
158 | /* | ||
159 | * BN_ULONG bn_mul_add_words(rp,ap,num,w) | ||
160 | * BN_ULONG *rp,*ap; | ||
161 | * int num; | ||
162 | * BN_ULONG w; | ||
163 | */ | ||
164 | bn_mul_add_words: | ||
165 | brgz,a %o2,.L_bn_mul_add_words_proceed | ||
166 | lduw [%o1],%g2 | ||
167 | retl | ||
168 | clr %o0 | ||
169 | |||
170 | .L_bn_mul_add_words_proceed: | ||
171 | srl %o3,%g0,%o3 ! clruw %o3 | ||
172 | andcc %o2,-4,%g0 | ||
173 | bz,pn %icc,.L_bn_mul_add_words_tail | ||
174 | clr %o5 | ||
175 | |||
176 | .L_bn_mul_add_words_loop: ! wow! 32 aligned! | ||
177 | lduw [%o0],%g1 | ||
178 | lduw [%o1+4],%g3 | ||
179 | mulx %o3,%g2,%g2 | ||
180 | add %g1,%o5,%o4 | ||
181 | nop | ||
182 | add %o4,%g2,%o4 | ||
183 | stuw %o4,[%o0] | ||
184 | srlx %o4,32,%o5 | ||
185 | |||
186 | lduw [%o0+4],%g1 | ||
187 | lduw [%o1+8],%g2 | ||
188 | mulx %o3,%g3,%g3 | ||
189 | add %g1,%o5,%o4 | ||
190 | dec 4,%o2 | ||
191 | add %o4,%g3,%o4 | ||
192 | stuw %o4,[%o0+4] | ||
193 | srlx %o4,32,%o5 | ||
194 | |||
195 | lduw [%o0+8],%g1 | ||
196 | lduw [%o1+12],%g3 | ||
197 | mulx %o3,%g2,%g2 | ||
198 | add %g1,%o5,%o4 | ||
199 | inc 16,%o1 | ||
200 | add %o4,%g2,%o4 | ||
201 | stuw %o4,[%o0+8] | ||
202 | srlx %o4,32,%o5 | ||
203 | |||
204 | lduw [%o0+12],%g1 | ||
205 | mulx %o3,%g3,%g3 | ||
206 | add %g1,%o5,%o4 | ||
207 | inc 16,%o0 | ||
208 | add %o4,%g3,%o4 | ||
209 | andcc %o2,-4,%g0 | ||
210 | stuw %o4,[%o0-4] | ||
211 | srlx %o4,32,%o5 | ||
212 | bnz,a,pt %icc,.L_bn_mul_add_words_loop | ||
213 | lduw [%o1],%g2 | ||
214 | |||
215 | brnz,a,pn %o2,.L_bn_mul_add_words_tail | ||
216 | lduw [%o1],%g2 | ||
217 | .L_bn_mul_add_words_return: | ||
218 | retl | ||
219 | mov %o5,%o0 | ||
220 | |||
221 | .L_bn_mul_add_words_tail: | ||
222 | lduw [%o0],%g1 | ||
223 | mulx %o3,%g2,%g2 | ||
224 | add %g1,%o5,%o4 | ||
225 | dec %o2 | ||
226 | add %o4,%g2,%o4 | ||
227 | srlx %o4,32,%o5 | ||
228 | brz,pt %o2,.L_bn_mul_add_words_return | ||
229 | stuw %o4,[%o0] | ||
230 | |||
231 | lduw [%o1+4],%g2 | ||
232 | lduw [%o0+4],%g1 | ||
233 | mulx %o3,%g2,%g2 | ||
234 | add %g1,%o5,%o4 | ||
235 | dec %o2 | ||
236 | add %o4,%g2,%o4 | ||
237 | srlx %o4,32,%o5 | ||
238 | brz,pt %o2,.L_bn_mul_add_words_return | ||
239 | stuw %o4,[%o0+4] | ||
240 | |||
241 | lduw [%o1+8],%g2 | ||
242 | lduw [%o0+8],%g1 | ||
243 | mulx %o3,%g2,%g2 | ||
244 | add %g1,%o5,%o4 | ||
245 | add %o4,%g2,%o4 | ||
246 | stuw %o4,[%o0+8] | ||
247 | retl | ||
248 | srlx %o4,32,%o0 | ||
249 | |||
250 | .type bn_mul_add_words,#function | ||
251 | .size bn_mul_add_words,(.-bn_mul_add_words) | ||
252 | |||
253 | .align 32 | ||
254 | |||
255 | .global bn_mul_words | ||
256 | /* | ||
257 | * BN_ULONG bn_mul_words(rp,ap,num,w) | ||
258 | * BN_ULONG *rp,*ap; | ||
259 | * int num; | ||
260 | * BN_ULONG w; | ||
261 | */ | ||
262 | bn_mul_words: | ||
263 | brgz,a %o2,.L_bn_mul_words_proceeed | ||
264 | lduw [%o1],%g2 | ||
265 | retl | ||
266 | clr %o0 | ||
267 | |||
268 | .L_bn_mul_words_proceeed: | ||
269 | srl %o3,%g0,%o3 ! clruw %o3 | ||
270 | andcc %o2,-4,%g0 | ||
271 | bz,pn %icc,.L_bn_mul_words_tail | ||
272 | clr %o5 | ||
273 | |||
274 | .L_bn_mul_words_loop: ! wow! 32 aligned! | ||
275 | lduw [%o1+4],%g3 | ||
276 | mulx %o3,%g2,%g2 | ||
277 | add %g2,%o5,%o4 | ||
278 | nop | ||
279 | stuw %o4,[%o0] | ||
280 | srlx %o4,32,%o5 | ||
281 | |||
282 | lduw [%o1+8],%g2 | ||
283 | mulx %o3,%g3,%g3 | ||
284 | add %g3,%o5,%o4 | ||
285 | dec 4,%o2 | ||
286 | stuw %o4,[%o0+4] | ||
287 | srlx %o4,32,%o5 | ||
288 | |||
289 | lduw [%o1+12],%g3 | ||
290 | mulx %o3,%g2,%g2 | ||
291 | add %g2,%o5,%o4 | ||
292 | inc 16,%o1 | ||
293 | stuw %o4,[%o0+8] | ||
294 | srlx %o4,32,%o5 | ||
295 | |||
296 | mulx %o3,%g3,%g3 | ||
297 | add %g3,%o5,%o4 | ||
298 | inc 16,%o0 | ||
299 | stuw %o4,[%o0-4] | ||
300 | srlx %o4,32,%o5 | ||
301 | andcc %o2,-4,%g0 | ||
302 | bnz,a,pt %icc,.L_bn_mul_words_loop | ||
303 | lduw [%o1],%g2 | ||
304 | nop | ||
305 | nop | ||
306 | |||
307 | brnz,a,pn %o2,.L_bn_mul_words_tail | ||
308 | lduw [%o1],%g2 | ||
309 | .L_bn_mul_words_return: | ||
310 | retl | ||
311 | mov %o5,%o0 | ||
312 | |||
313 | .L_bn_mul_words_tail: | ||
314 | mulx %o3,%g2,%g2 | ||
315 | add %g2,%o5,%o4 | ||
316 | dec %o2 | ||
317 | srlx %o4,32,%o5 | ||
318 | brz,pt %o2,.L_bn_mul_words_return | ||
319 | stuw %o4,[%o0] | ||
320 | |||
321 | lduw [%o1+4],%g2 | ||
322 | mulx %o3,%g2,%g2 | ||
323 | add %g2,%o5,%o4 | ||
324 | dec %o2 | ||
325 | srlx %o4,32,%o5 | ||
326 | brz,pt %o2,.L_bn_mul_words_return | ||
327 | stuw %o4,[%o0+4] | ||
328 | |||
329 | lduw [%o1+8],%g2 | ||
330 | mulx %o3,%g2,%g2 | ||
331 | add %g2,%o5,%o4 | ||
332 | stuw %o4,[%o0+8] | ||
333 | retl | ||
334 | srlx %o4,32,%o0 | ||
335 | |||
336 | .type bn_mul_words,#function | ||
337 | .size bn_mul_words,(.-bn_mul_words) | ||
338 | |||
339 | .align 32 | ||
340 | .global bn_sqr_words | ||
341 | /* | ||
342 | * void bn_sqr_words(r,a,n) | ||
343 | * BN_ULONG *r,*a; | ||
344 | * int n; | ||
345 | */ | ||
346 | bn_sqr_words: | ||
347 | brgz,a %o2,.L_bn_sqr_words_proceeed | ||
348 | lduw [%o1],%g2 | ||
349 | retl | ||
350 | clr %o0 | ||
351 | |||
352 | .L_bn_sqr_words_proceeed: | ||
353 | andcc %o2,-4,%g0 | ||
354 | nop | ||
355 | bz,pn %icc,.L_bn_sqr_words_tail | ||
356 | nop | ||
357 | |||
358 | .L_bn_sqr_words_loop: ! wow! 32 aligned! | ||
359 | lduw [%o1+4],%g3 | ||
360 | mulx %g2,%g2,%o4 | ||
361 | stuw %o4,[%o0] | ||
362 | srlx %o4,32,%o5 | ||
363 | stuw %o5,[%o0+4] | ||
364 | nop | ||
365 | |||
366 | lduw [%o1+8],%g2 | ||
367 | mulx %g3,%g3,%o4 | ||
368 | dec 4,%o2 | ||
369 | stuw %o4,[%o0+8] | ||
370 | srlx %o4,32,%o5 | ||
371 | stuw %o5,[%o0+12] | ||
372 | |||
373 | lduw [%o1+12],%g3 | ||
374 | mulx %g2,%g2,%o4 | ||
375 | srlx %o4,32,%o5 | ||
376 | stuw %o4,[%o0+16] | ||
377 | inc 16,%o1 | ||
378 | stuw %o5,[%o0+20] | ||
379 | |||
380 | mulx %g3,%g3,%o4 | ||
381 | inc 32,%o0 | ||
382 | stuw %o4,[%o0-8] | ||
383 | srlx %o4,32,%o5 | ||
384 | andcc %o2,-4,%g2 | ||
385 | stuw %o5,[%o0-4] | ||
386 | bnz,a,pt %icc,.L_bn_sqr_words_loop | ||
387 | lduw [%o1],%g2 | ||
388 | nop | ||
389 | |||
390 | brnz,a,pn %o2,.L_bn_sqr_words_tail | ||
391 | lduw [%o1],%g2 | ||
392 | .L_bn_sqr_words_return: | ||
393 | retl | ||
394 | clr %o0 | ||
395 | |||
396 | .L_bn_sqr_words_tail: | ||
397 | mulx %g2,%g2,%o4 | ||
398 | dec %o2 | ||
399 | stuw %o4,[%o0] | ||
400 | srlx %o4,32,%o5 | ||
401 | brz,pt %o2,.L_bn_sqr_words_return | ||
402 | stuw %o5,[%o0+4] | ||
403 | |||
404 | lduw [%o1+4],%g2 | ||
405 | mulx %g2,%g2,%o4 | ||
406 | dec %o2 | ||
407 | stuw %o4,[%o0+8] | ||
408 | srlx %o4,32,%o5 | ||
409 | brz,pt %o2,.L_bn_sqr_words_return | ||
410 | stuw %o5,[%o0+12] | ||
411 | |||
412 | lduw [%o1+8],%g2 | ||
413 | mulx %g2,%g2,%o4 | ||
414 | srlx %o4,32,%o5 | ||
415 | stuw %o4,[%o0+16] | ||
416 | stuw %o5,[%o0+20] | ||
417 | retl | ||
418 | clr %o0 | ||
419 | |||
420 | .type bn_sqr_words,#function | ||
421 | .size bn_sqr_words,(.-bn_sqr_words) | ||
422 | |||
423 | .align 32 | ||
424 | .global bn_div_words | ||
425 | /* | ||
426 | * BN_ULONG bn_div_words(h,l,d) | ||
427 | * BN_ULONG h,l,d; | ||
428 | */ | ||
429 | bn_div_words: | ||
430 | sllx %o0,32,%o0 | ||
431 | or %o0,%o1,%o0 | ||
432 | udivx %o0,%o2,%o0 | ||
433 | retl | ||
434 | srl %o0,%g0,%o0 ! clruw %o0 | ||
435 | |||
436 | .type bn_div_words,#function | ||
437 | .size bn_div_words,(.-bn_div_words) | ||
438 | |||
439 | .align 32 | ||
440 | |||
441 | .global bn_add_words | ||
442 | /* | ||
443 | * BN_ULONG bn_add_words(rp,ap,bp,n) | ||
444 | * BN_ULONG *rp,*ap,*bp; | ||
445 | * int n; | ||
446 | */ | ||
447 | bn_add_words: | ||
448 | brgz,a %o3,.L_bn_add_words_proceed | ||
449 | lduw [%o1],%o4 | ||
450 | retl | ||
451 | clr %o0 | ||
452 | |||
453 | .L_bn_add_words_proceed: | ||
454 | andcc %o3,-4,%g0 | ||
455 | bz,pn %icc,.L_bn_add_words_tail | ||
456 | addcc %g0,0,%g0 ! clear carry flag | ||
457 | nop | ||
458 | |||
459 | .L_bn_add_words_loop: ! wow! 32 aligned! | ||
460 | dec 4,%o3 | ||
461 | lduw [%o2],%o5 | ||
462 | lduw [%o1+4],%g1 | ||
463 | lduw [%o2+4],%g2 | ||
464 | lduw [%o1+8],%g3 | ||
465 | lduw [%o2+8],%g4 | ||
466 | addccc %o5,%o4,%o5 | ||
467 | stuw %o5,[%o0] | ||
468 | |||
469 | lduw [%o1+12],%o4 | ||
470 | lduw [%o2+12],%o5 | ||
471 | inc 16,%o1 | ||
472 | addccc %g1,%g2,%g1 | ||
473 | stuw %g1,[%o0+4] | ||
474 | |||
475 | inc 16,%o2 | ||
476 | addccc %g3,%g4,%g3 | ||
477 | stuw %g3,[%o0+8] | ||
478 | |||
479 | inc 16,%o0 | ||
480 | addccc %o5,%o4,%o5 | ||
481 | stuw %o5,[%o0-4] | ||
482 | and %o3,-4,%g1 | ||
483 | brnz,a,pt %g1,.L_bn_add_words_loop | ||
484 | lduw [%o1],%o4 | ||
485 | |||
486 | brnz,a,pn %o3,.L_bn_add_words_tail | ||
487 | lduw [%o1],%o4 | ||
488 | .L_bn_add_words_return: | ||
489 | clr %o0 | ||
490 | retl | ||
491 | movcs %icc,1,%o0 | ||
492 | nop | ||
493 | |||
494 | .L_bn_add_words_tail: | ||
495 | lduw [%o2],%o5 | ||
496 | dec %o3 | ||
497 | addccc %o5,%o4,%o5 | ||
498 | brz,pt %o3,.L_bn_add_words_return | ||
499 | stuw %o5,[%o0] | ||
500 | |||
501 | lduw [%o1+4],%o4 | ||
502 | lduw [%o2+4],%o5 | ||
503 | dec %o3 | ||
504 | addccc %o5,%o4,%o5 | ||
505 | brz,pt %o3,.L_bn_add_words_return | ||
506 | stuw %o5,[%o0+4] | ||
507 | |||
508 | lduw [%o1+8],%o4 | ||
509 | lduw [%o2+8],%o5 | ||
510 | addccc %o5,%o4,%o5 | ||
511 | stuw %o5,[%o0+8] | ||
512 | clr %o0 | ||
513 | retl | ||
514 | movcs %icc,1,%o0 | ||
515 | |||
516 | .type bn_add_words,#function | ||
517 | .size bn_add_words,(.-bn_add_words) | ||
518 | |||
519 | .global bn_sub_words | ||
520 | /* | ||
521 | * BN_ULONG bn_sub_words(rp,ap,bp,n) | ||
522 | * BN_ULONG *rp,*ap,*bp; | ||
523 | * int n; | ||
524 | */ | ||
525 | bn_sub_words: | ||
526 | brgz,a %o3,.L_bn_sub_words_proceed | ||
527 | lduw [%o1],%o4 | ||
528 | retl | ||
529 | clr %o0 | ||
530 | |||
531 | .L_bn_sub_words_proceed: | ||
532 | andcc %o3,-4,%g0 | ||
533 | bz,pn %icc,.L_bn_sub_words_tail | ||
534 | addcc %g0,0,%g0 ! clear carry flag | ||
535 | nop | ||
536 | |||
537 | .L_bn_sub_words_loop: ! wow! 32 aligned! | ||
538 | dec 4,%o3 | ||
539 | lduw [%o2],%o5 | ||
540 | lduw [%o1+4],%g1 | ||
541 | lduw [%o2+4],%g2 | ||
542 | lduw [%o1+8],%g3 | ||
543 | lduw [%o2+8],%g4 | ||
544 | subccc %o4,%o5,%o5 | ||
545 | stuw %o5,[%o0] | ||
546 | |||
547 | lduw [%o1+12],%o4 | ||
548 | lduw [%o2+12],%o5 | ||
549 | inc 16,%o1 | ||
550 | subccc %g1,%g2,%g2 | ||
551 | stuw %g2,[%o0+4] | ||
552 | |||
553 | inc 16,%o2 | ||
554 | subccc %g3,%g4,%g4 | ||
555 | stuw %g4,[%o0+8] | ||
556 | |||
557 | inc 16,%o0 | ||
558 | subccc %o4,%o5,%o5 | ||
559 | stuw %o5,[%o0-4] | ||
560 | and %o3,-4,%g1 | ||
561 | brnz,a,pt %g1,.L_bn_sub_words_loop | ||
562 | lduw [%o1],%o4 | ||
563 | |||
564 | brnz,a,pn %o3,.L_bn_sub_words_tail | ||
565 | lduw [%o1],%o4 | ||
566 | .L_bn_sub_words_return: | ||
567 | clr %o0 | ||
568 | retl | ||
569 | movcs %icc,1,%o0 | ||
570 | nop | ||
571 | |||
572 | .L_bn_sub_words_tail: ! wow! 32 aligned! | ||
573 | lduw [%o2],%o5 | ||
574 | dec %o3 | ||
575 | subccc %o4,%o5,%o5 | ||
576 | brz,pt %o3,.L_bn_sub_words_return | ||
577 | stuw %o5,[%o0] | ||
578 | |||
579 | lduw [%o1+4],%o4 | ||
580 | lduw [%o2+4],%o5 | ||
581 | dec %o3 | ||
582 | subccc %o4,%o5,%o5 | ||
583 | brz,pt %o3,.L_bn_sub_words_return | ||
584 | stuw %o5,[%o0+4] | ||
585 | |||
586 | lduw [%o1+8],%o4 | ||
587 | lduw [%o2+8],%o5 | ||
588 | subccc %o4,%o5,%o5 | ||
589 | stuw %o5,[%o0+8] | ||
590 | clr %o0 | ||
591 | retl | ||
592 | movcs %icc,1,%o0 | ||
593 | |||
594 | .type bn_sub_words,#function | ||
595 | .size bn_sub_words,(.-bn_sub_words) | ||
596 | |||
597 | /* | ||
598 | * Code below depends on the fact that upper parts of the %l0-%l7 | ||
599 | * and %i0-%i7 are zeroed by kernel after context switch. In | ||
600 | * previous versions this comment stated that "the trouble is that | ||
601 | * it's not feasible to implement the mumbo-jumbo in less V9 | ||
602 | * instructions:-(" which apparently isn't true thanks to | ||
603 | * 'bcs,a %xcc,.+8; inc %rd' pair. But the performance improvement | ||
604 | * results not from the shorter code, but from elimination of | ||
605 | * multicycle none-pairable 'rd %y,%rd' instructions. | ||
606 | * | ||
607 | * Andy. | ||
608 | */ | ||
609 | |||
610 | #define FRAME_SIZE -96 | ||
611 | |||
612 | /* | ||
613 | * Here is register usage map for *all* routines below. | ||
614 | */ | ||
615 | #define t_1 %o0 | ||
616 | #define t_2 %o1 | ||
617 | #define c_12 %o2 | ||
618 | #define c_3 %o3 | ||
619 | |||
620 | #define ap(I) [%i1+4*I] | ||
621 | #define bp(I) [%i2+4*I] | ||
622 | #define rp(I) [%i0+4*I] | ||
623 | |||
624 | #define a_0 %l0 | ||
625 | #define a_1 %l1 | ||
626 | #define a_2 %l2 | ||
627 | #define a_3 %l3 | ||
628 | #define a_4 %l4 | ||
629 | #define a_5 %l5 | ||
630 | #define a_6 %l6 | ||
631 | #define a_7 %l7 | ||
632 | |||
633 | #define b_0 %i3 | ||
634 | #define b_1 %i4 | ||
635 | #define b_2 %i5 | ||
636 | #define b_3 %o4 | ||
637 | #define b_4 %o5 | ||
638 | #define b_5 %o7 | ||
639 | #define b_6 %g1 | ||
640 | #define b_7 %g4 | ||
641 | |||
642 | .align 32 | ||
643 | .global bn_mul_comba8 | ||
644 | /* | ||
645 | * void bn_mul_comba8(r,a,b) | ||
646 | * BN_ULONG *r,*a,*b; | ||
647 | */ | ||
648 | bn_mul_comba8: | ||
649 | save %sp,FRAME_SIZE,%sp | ||
650 | mov 1,t_2 | ||
651 | lduw ap(0),a_0 | ||
652 | sllx t_2,32,t_2 | ||
653 | lduw bp(0),b_0 != | ||
654 | lduw bp(1),b_1 | ||
655 | mulx a_0,b_0,t_1 !mul_add_c(a[0],b[0],c1,c2,c3); | ||
656 | srlx t_1,32,c_12 | ||
657 | stuw t_1,rp(0) !=!r[0]=c1; | ||
658 | |||
659 | lduw ap(1),a_1 | ||
660 | mulx a_0,b_1,t_1 !mul_add_c(a[0],b[1],c2,c3,c1); | ||
661 | addcc c_12,t_1,c_12 | ||
662 | clr c_3 != | ||
663 | bcs,a %xcc,.+8 | ||
664 | add c_3,t_2,c_3 | ||
665 | lduw ap(2),a_2 | ||
666 | mulx a_1,b_0,t_1 !=!mul_add_c(a[1],b[0],c2,c3,c1); | ||
667 | addcc c_12,t_1,t_1 | ||
668 | bcs,a %xcc,.+8 | ||
669 | add c_3,t_2,c_3 | ||
670 | srlx t_1,32,c_12 != | ||
671 | stuw t_1,rp(1) !r[1]=c2; | ||
672 | or c_12,c_3,c_12 | ||
673 | |||
674 | mulx a_2,b_0,t_1 !mul_add_c(a[2],b[0],c3,c1,c2); | ||
675 | addcc c_12,t_1,c_12 != | ||
676 | clr c_3 | ||
677 | bcs,a %xcc,.+8 | ||
678 | add c_3,t_2,c_3 | ||
679 | lduw bp(2),b_2 != | ||
680 | mulx a_1,b_1,t_1 !mul_add_c(a[1],b[1],c3,c1,c2); | ||
681 | addcc c_12,t_1,c_12 | ||
682 | bcs,a %xcc,.+8 | ||
683 | add c_3,t_2,c_3 != | ||
684 | lduw bp(3),b_3 | ||
685 | mulx a_0,b_2,t_1 !mul_add_c(a[0],b[2],c3,c1,c2); | ||
686 | addcc c_12,t_1,t_1 | ||
687 | bcs,a %xcc,.+8 != | ||
688 | add c_3,t_2,c_3 | ||
689 | srlx t_1,32,c_12 | ||
690 | stuw t_1,rp(2) !r[2]=c3; | ||
691 | or c_12,c_3,c_12 != | ||
692 | |||
693 | mulx a_0,b_3,t_1 !mul_add_c(a[0],b[3],c1,c2,c3); | ||
694 | addcc c_12,t_1,c_12 | ||
695 | clr c_3 | ||
696 | bcs,a %xcc,.+8 != | ||
697 | add c_3,t_2,c_3 | ||
698 | mulx a_1,b_2,t_1 !=!mul_add_c(a[1],b[2],c1,c2,c3); | ||
699 | addcc c_12,t_1,c_12 | ||
700 | bcs,a %xcc,.+8 != | ||
701 | add c_3,t_2,c_3 | ||
702 | lduw ap(3),a_3 | ||
703 | mulx a_2,b_1,t_1 !mul_add_c(a[2],b[1],c1,c2,c3); | ||
704 | addcc c_12,t_1,c_12 != | ||
705 | bcs,a %xcc,.+8 | ||
706 | add c_3,t_2,c_3 | ||
707 | lduw ap(4),a_4 | ||
708 | mulx a_3,b_0,t_1 !=!mul_add_c(a[3],b[0],c1,c2,c3);!= | ||
709 | addcc c_12,t_1,t_1 | ||
710 | bcs,a %xcc,.+8 | ||
711 | add c_3,t_2,c_3 | ||
712 | srlx t_1,32,c_12 != | ||
713 | stuw t_1,rp(3) !r[3]=c1; | ||
714 | or c_12,c_3,c_12 | ||
715 | |||
716 | mulx a_4,b_0,t_1 !mul_add_c(a[4],b[0],c2,c3,c1); | ||
717 | addcc c_12,t_1,c_12 != | ||
718 | clr c_3 | ||
719 | bcs,a %xcc,.+8 | ||
720 | add c_3,t_2,c_3 | ||
721 | mulx a_3,b_1,t_1 !=!mul_add_c(a[3],b[1],c2,c3,c1); | ||
722 | addcc c_12,t_1,c_12 | ||
723 | bcs,a %xcc,.+8 | ||
724 | add c_3,t_2,c_3 | ||
725 | mulx a_2,b_2,t_1 !=!mul_add_c(a[2],b[2],c2,c3,c1); | ||
726 | addcc c_12,t_1,c_12 | ||
727 | bcs,a %xcc,.+8 | ||
728 | add c_3,t_2,c_3 | ||
729 | lduw bp(4),b_4 != | ||
730 | mulx a_1,b_3,t_1 !mul_add_c(a[1],b[3],c2,c3,c1); | ||
731 | addcc c_12,t_1,c_12 | ||
732 | bcs,a %xcc,.+8 | ||
733 | add c_3,t_2,c_3 != | ||
734 | lduw bp(5),b_5 | ||
735 | mulx a_0,b_4,t_1 !mul_add_c(a[0],b[4],c2,c3,c1); | ||
736 | addcc c_12,t_1,t_1 | ||
737 | bcs,a %xcc,.+8 != | ||
738 | add c_3,t_2,c_3 | ||
739 | srlx t_1,32,c_12 | ||
740 | stuw t_1,rp(4) !r[4]=c2; | ||
741 | or c_12,c_3,c_12 != | ||
742 | |||
743 | mulx a_0,b_5,t_1 !mul_add_c(a[0],b[5],c3,c1,c2); | ||
744 | addcc c_12,t_1,c_12 | ||
745 | clr c_3 | ||
746 | bcs,a %xcc,.+8 != | ||
747 | add c_3,t_2,c_3 | ||
748 | mulx a_1,b_4,t_1 !mul_add_c(a[1],b[4],c3,c1,c2); | ||
749 | addcc c_12,t_1,c_12 | ||
750 | bcs,a %xcc,.+8 != | ||
751 | add c_3,t_2,c_3 | ||
752 | mulx a_2,b_3,t_1 !mul_add_c(a[2],b[3],c3,c1,c2); | ||
753 | addcc c_12,t_1,c_12 | ||
754 | bcs,a %xcc,.+8 != | ||
755 | add c_3,t_2,c_3 | ||
756 | mulx a_3,b_2,t_1 !mul_add_c(a[3],b[2],c3,c1,c2); | ||
757 | addcc c_12,t_1,c_12 | ||
758 | bcs,a %xcc,.+8 != | ||
759 | add c_3,t_2,c_3 | ||
760 | lduw ap(5),a_5 | ||
761 | mulx a_4,b_1,t_1 !mul_add_c(a[4],b[1],c3,c1,c2); | ||
762 | addcc c_12,t_1,c_12 != | ||
763 | bcs,a %xcc,.+8 | ||
764 | add c_3,t_2,c_3 | ||
765 | lduw ap(6),a_6 | ||
766 | mulx a_5,b_0,t_1 !=!mul_add_c(a[5],b[0],c3,c1,c2); | ||
767 | addcc c_12,t_1,t_1 | ||
768 | bcs,a %xcc,.+8 | ||
769 | add c_3,t_2,c_3 | ||
770 | srlx t_1,32,c_12 != | ||
771 | stuw t_1,rp(5) !r[5]=c3; | ||
772 | or c_12,c_3,c_12 | ||
773 | |||
774 | mulx a_6,b_0,t_1 !mul_add_c(a[6],b[0],c1,c2,c3); | ||
775 | addcc c_12,t_1,c_12 != | ||
776 | clr c_3 | ||
777 | bcs,a %xcc,.+8 | ||
778 | add c_3,t_2,c_3 | ||
779 | mulx a_5,b_1,t_1 !=!mul_add_c(a[5],b[1],c1,c2,c3); | ||
780 | addcc c_12,t_1,c_12 | ||
781 | bcs,a %xcc,.+8 | ||
782 | add c_3,t_2,c_3 | ||
783 | mulx a_4,b_2,t_1 !=!mul_add_c(a[4],b[2],c1,c2,c3); | ||
784 | addcc c_12,t_1,c_12 | ||
785 | bcs,a %xcc,.+8 | ||
786 | add c_3,t_2,c_3 | ||
787 | mulx a_3,b_3,t_1 !=!mul_add_c(a[3],b[3],c1,c2,c3); | ||
788 | addcc c_12,t_1,c_12 | ||
789 | bcs,a %xcc,.+8 | ||
790 | add c_3,t_2,c_3 | ||
791 | mulx a_2,b_4,t_1 !=!mul_add_c(a[2],b[4],c1,c2,c3); | ||
792 | addcc c_12,t_1,c_12 | ||
793 | bcs,a %xcc,.+8 | ||
794 | add c_3,t_2,c_3 | ||
795 | lduw bp(6),b_6 != | ||
796 | mulx a_1,b_5,t_1 !mul_add_c(a[1],b[5],c1,c2,c3); | ||
797 | addcc c_12,t_1,c_12 | ||
798 | bcs,a %xcc,.+8 | ||
799 | add c_3,t_2,c_3 != | ||
800 | lduw bp(7),b_7 | ||
801 | mulx a_0,b_6,t_1 !mul_add_c(a[0],b[6],c1,c2,c3); | ||
802 | addcc c_12,t_1,t_1 | ||
803 | bcs,a %xcc,.+8 != | ||
804 | add c_3,t_2,c_3 | ||
805 | srlx t_1,32,c_12 | ||
806 | stuw t_1,rp(6) !r[6]=c1; | ||
807 | or c_12,c_3,c_12 != | ||
808 | |||
809 | mulx a_0,b_7,t_1 !mul_add_c(a[0],b[7],c2,c3,c1); | ||
810 | addcc c_12,t_1,c_12 | ||
811 | clr c_3 | ||
812 | bcs,a %xcc,.+8 != | ||
813 | add c_3,t_2,c_3 | ||
814 | mulx a_1,b_6,t_1 !mul_add_c(a[1],b[6],c2,c3,c1); | ||
815 | addcc c_12,t_1,c_12 | ||
816 | bcs,a %xcc,.+8 != | ||
817 | add c_3,t_2,c_3 | ||
818 | mulx a_2,b_5,t_1 !mul_add_c(a[2],b[5],c2,c3,c1); | ||
819 | addcc c_12,t_1,c_12 | ||
820 | bcs,a %xcc,.+8 != | ||
821 | add c_3,t_2,c_3 | ||
822 | mulx a_3,b_4,t_1 !mul_add_c(a[3],b[4],c2,c3,c1); | ||
823 | addcc c_12,t_1,c_12 | ||
824 | bcs,a %xcc,.+8 != | ||
825 | add c_3,t_2,c_3 | ||
826 | mulx a_4,b_3,t_1 !mul_add_c(a[4],b[3],c2,c3,c1); | ||
827 | addcc c_12,t_1,c_12 | ||
828 | bcs,a %xcc,.+8 != | ||
829 | add c_3,t_2,c_3 | ||
830 | mulx a_5,b_2,t_1 !mul_add_c(a[5],b[2],c2,c3,c1); | ||
831 | addcc c_12,t_1,c_12 | ||
832 | bcs,a %xcc,.+8 != | ||
833 | add c_3,t_2,c_3 | ||
834 | lduw ap(7),a_7 | ||
835 | mulx a_6,b_1,t_1 !=!mul_add_c(a[6],b[1],c2,c3,c1); | ||
836 | addcc c_12,t_1,c_12 | ||
837 | bcs,a %xcc,.+8 | ||
838 | add c_3,t_2,c_3 | ||
839 | mulx a_7,b_0,t_1 !=!mul_add_c(a[7],b[0],c2,c3,c1); | ||
840 | addcc c_12,t_1,t_1 | ||
841 | bcs,a %xcc,.+8 | ||
842 | add c_3,t_2,c_3 | ||
843 | srlx t_1,32,c_12 != | ||
844 | stuw t_1,rp(7) !r[7]=c2; | ||
845 | or c_12,c_3,c_12 | ||
846 | |||
847 | mulx a_7,b_1,t_1 !=!mul_add_c(a[7],b[1],c3,c1,c2); | ||
848 | addcc c_12,t_1,c_12 | ||
849 | clr c_3 | ||
850 | bcs,a %xcc,.+8 | ||
851 | add c_3,t_2,c_3 != | ||
852 | mulx a_6,b_2,t_1 !mul_add_c(a[6],b[2],c3,c1,c2); | ||
853 | addcc c_12,t_1,c_12 | ||
854 | bcs,a %xcc,.+8 | ||
855 | add c_3,t_2,c_3 != | ||
856 | mulx a_5,b_3,t_1 !mul_add_c(a[5],b[3],c3,c1,c2); | ||
857 | addcc c_12,t_1,c_12 | ||
858 | bcs,a %xcc,.+8 | ||
859 | add c_3,t_2,c_3 != | ||
860 | mulx a_4,b_4,t_1 !mul_add_c(a[4],b[4],c3,c1,c2); | ||
861 | addcc c_12,t_1,c_12 | ||
862 | bcs,a %xcc,.+8 | ||
863 | add c_3,t_2,c_3 != | ||
864 | mulx a_3,b_5,t_1 !mul_add_c(a[3],b[5],c3,c1,c2); | ||
865 | addcc c_12,t_1,c_12 | ||
866 | bcs,a %xcc,.+8 | ||
867 | add c_3,t_2,c_3 != | ||
868 | mulx a_2,b_6,t_1 !mul_add_c(a[2],b[6],c3,c1,c2); | ||
869 | addcc c_12,t_1,c_12 | ||
870 | bcs,a %xcc,.+8 | ||
871 | add c_3,t_2,c_3 != | ||
872 | mulx a_1,b_7,t_1 !mul_add_c(a[1],b[7],c3,c1,c2); | ||
873 | addcc c_12,t_1,t_1 | ||
874 | bcs,a %xcc,.+8 | ||
875 | add c_3,t_2,c_3 != | ||
876 | srlx t_1,32,c_12 | ||
877 | stuw t_1,rp(8) !r[8]=c3; | ||
878 | or c_12,c_3,c_12 | ||
879 | |||
880 | mulx a_2,b_7,t_1 !=!mul_add_c(a[2],b[7],c1,c2,c3); | ||
881 | addcc c_12,t_1,c_12 | ||
882 | clr c_3 | ||
883 | bcs,a %xcc,.+8 | ||
884 | add c_3,t_2,c_3 != | ||
885 | mulx a_3,b_6,t_1 !mul_add_c(a[3],b[6],c1,c2,c3); | ||
886 | addcc c_12,t_1,c_12 | ||
887 | bcs,a %xcc,.+8 != | ||
888 | add c_3,t_2,c_3 | ||
889 | mulx a_4,b_5,t_1 !mul_add_c(a[4],b[5],c1,c2,c3); | ||
890 | addcc c_12,t_1,c_12 | ||
891 | bcs,a %xcc,.+8 != | ||
892 | add c_3,t_2,c_3 | ||
893 | mulx a_5,b_4,t_1 !mul_add_c(a[5],b[4],c1,c2,c3); | ||
894 | addcc c_12,t_1,c_12 | ||
895 | bcs,a %xcc,.+8 != | ||
896 | add c_3,t_2,c_3 | ||
897 | mulx a_6,b_3,t_1 !mul_add_c(a[6],b[3],c1,c2,c3); | ||
898 | addcc c_12,t_1,c_12 | ||
899 | bcs,a %xcc,.+8 != | ||
900 | add c_3,t_2,c_3 | ||
901 | mulx a_7,b_2,t_1 !mul_add_c(a[7],b[2],c1,c2,c3); | ||
902 | addcc c_12,t_1,t_1 | ||
903 | bcs,a %xcc,.+8 != | ||
904 | add c_3,t_2,c_3 | ||
905 | srlx t_1,32,c_12 | ||
906 | stuw t_1,rp(9) !r[9]=c1; | ||
907 | or c_12,c_3,c_12 != | ||
908 | |||
909 | mulx a_7,b_3,t_1 !mul_add_c(a[7],b[3],c2,c3,c1); | ||
910 | addcc c_12,t_1,c_12 | ||
911 | clr c_3 | ||
912 | bcs,a %xcc,.+8 != | ||
913 | add c_3,t_2,c_3 | ||
914 | mulx a_6,b_4,t_1 !mul_add_c(a[6],b[4],c2,c3,c1); | ||
915 | addcc c_12,t_1,c_12 | ||
916 | bcs,a %xcc,.+8 != | ||
917 | add c_3,t_2,c_3 | ||
918 | mulx a_5,b_5,t_1 !mul_add_c(a[5],b[5],c2,c3,c1); | ||
919 | addcc c_12,t_1,c_12 | ||
920 | bcs,a %xcc,.+8 != | ||
921 | add c_3,t_2,c_3 | ||
922 | mulx a_4,b_6,t_1 !mul_add_c(a[4],b[6],c2,c3,c1); | ||
923 | addcc c_12,t_1,c_12 | ||
924 | bcs,a %xcc,.+8 != | ||
925 | add c_3,t_2,c_3 | ||
926 | mulx a_3,b_7,t_1 !mul_add_c(a[3],b[7],c2,c3,c1); | ||
927 | addcc c_12,t_1,t_1 | ||
928 | bcs,a %xcc,.+8 != | ||
929 | add c_3,t_2,c_3 | ||
930 | srlx t_1,32,c_12 | ||
931 | stuw t_1,rp(10) !r[10]=c2; | ||
932 | or c_12,c_3,c_12 != | ||
933 | |||
934 | mulx a_4,b_7,t_1 !mul_add_c(a[4],b[7],c3,c1,c2); | ||
935 | addcc c_12,t_1,c_12 | ||
936 | clr c_3 | ||
937 | bcs,a %xcc,.+8 != | ||
938 | add c_3,t_2,c_3 | ||
939 | mulx a_5,b_6,t_1 !mul_add_c(a[5],b[6],c3,c1,c2); | ||
940 | addcc c_12,t_1,c_12 | ||
941 | bcs,a %xcc,.+8 != | ||
942 | add c_3,t_2,c_3 | ||
943 | mulx a_6,b_5,t_1 !mul_add_c(a[6],b[5],c3,c1,c2); | ||
944 | addcc c_12,t_1,c_12 | ||
945 | bcs,a %xcc,.+8 != | ||
946 | add c_3,t_2,c_3 | ||
947 | mulx a_7,b_4,t_1 !mul_add_c(a[7],b[4],c3,c1,c2); | ||
948 | addcc c_12,t_1,t_1 | ||
949 | bcs,a %xcc,.+8 != | ||
950 | add c_3,t_2,c_3 | ||
951 | srlx t_1,32,c_12 | ||
952 | stuw t_1,rp(11) !r[11]=c3; | ||
953 | or c_12,c_3,c_12 != | ||
954 | |||
955 | mulx a_7,b_5,t_1 !mul_add_c(a[7],b[5],c1,c2,c3); | ||
956 | addcc c_12,t_1,c_12 | ||
957 | clr c_3 | ||
958 | bcs,a %xcc,.+8 != | ||
959 | add c_3,t_2,c_3 | ||
960 | mulx a_6,b_6,t_1 !mul_add_c(a[6],b[6],c1,c2,c3); | ||
961 | addcc c_12,t_1,c_12 | ||
962 | bcs,a %xcc,.+8 != | ||
963 | add c_3,t_2,c_3 | ||
964 | mulx a_5,b_7,t_1 !mul_add_c(a[5],b[7],c1,c2,c3); | ||
965 | addcc c_12,t_1,t_1 | ||
966 | bcs,a %xcc,.+8 != | ||
967 | add c_3,t_2,c_3 | ||
968 | srlx t_1,32,c_12 | ||
969 | stuw t_1,rp(12) !r[12]=c1; | ||
970 | or c_12,c_3,c_12 != | ||
971 | |||
972 | mulx a_6,b_7,t_1 !mul_add_c(a[6],b[7],c2,c3,c1); | ||
973 | addcc c_12,t_1,c_12 | ||
974 | clr c_3 | ||
975 | bcs,a %xcc,.+8 != | ||
976 | add c_3,t_2,c_3 | ||
977 | mulx a_7,b_6,t_1 !mul_add_c(a[7],b[6],c2,c3,c1); | ||
978 | addcc c_12,t_1,t_1 | ||
979 | bcs,a %xcc,.+8 != | ||
980 | add c_3,t_2,c_3 | ||
981 | srlx t_1,32,c_12 | ||
982 | st t_1,rp(13) !r[13]=c2; | ||
983 | or c_12,c_3,c_12 != | ||
984 | |||
985 | mulx a_7,b_7,t_1 !mul_add_c(a[7],b[7],c3,c1,c2); | ||
986 | addcc c_12,t_1,t_1 | ||
987 | srlx t_1,32,c_12 != | ||
988 | stuw t_1,rp(14) !r[14]=c3; | ||
989 | stuw c_12,rp(15) !r[15]=c1; | ||
990 | |||
991 | ret | ||
992 | restore %g0,%g0,%o0 != | ||
993 | |||
994 | .type bn_mul_comba8,#function | ||
995 | .size bn_mul_comba8,(.-bn_mul_comba8) | ||
996 | |||
997 | .align 32 | ||
998 | |||
999 | .global bn_mul_comba4 | ||
1000 | /* | ||
1001 | * void bn_mul_comba4(r,a,b) | ||
1002 | * BN_ULONG *r,*a,*b; | ||
1003 | */ | ||
1004 | bn_mul_comba4: | ||
1005 | save %sp,FRAME_SIZE,%sp | ||
1006 | lduw ap(0),a_0 | ||
1007 | mov 1,t_2 | ||
1008 | lduw bp(0),b_0 | ||
1009 | sllx t_2,32,t_2 != | ||
1010 | lduw bp(1),b_1 | ||
1011 | mulx a_0,b_0,t_1 !mul_add_c(a[0],b[0],c1,c2,c3); | ||
1012 | srlx t_1,32,c_12 | ||
1013 | stuw t_1,rp(0) !=!r[0]=c1; | ||
1014 | |||
1015 | lduw ap(1),a_1 | ||
1016 | mulx a_0,b_1,t_1 !mul_add_c(a[0],b[1],c2,c3,c1); | ||
1017 | addcc c_12,t_1,c_12 | ||
1018 | clr c_3 != | ||
1019 | bcs,a %xcc,.+8 | ||
1020 | add c_3,t_2,c_3 | ||
1021 | lduw ap(2),a_2 | ||
1022 | mulx a_1,b_0,t_1 !=!mul_add_c(a[1],b[0],c2,c3,c1); | ||
1023 | addcc c_12,t_1,t_1 | ||
1024 | bcs,a %xcc,.+8 | ||
1025 | add c_3,t_2,c_3 | ||
1026 | srlx t_1,32,c_12 != | ||
1027 | stuw t_1,rp(1) !r[1]=c2; | ||
1028 | or c_12,c_3,c_12 | ||
1029 | |||
1030 | mulx a_2,b_0,t_1 !mul_add_c(a[2],b[0],c3,c1,c2); | ||
1031 | addcc c_12,t_1,c_12 != | ||
1032 | clr c_3 | ||
1033 | bcs,a %xcc,.+8 | ||
1034 | add c_3,t_2,c_3 | ||
1035 | lduw bp(2),b_2 != | ||
1036 | mulx a_1,b_1,t_1 !mul_add_c(a[1],b[1],c3,c1,c2); | ||
1037 | addcc c_12,t_1,c_12 | ||
1038 | bcs,a %xcc,.+8 | ||
1039 | add c_3,t_2,c_3 != | ||
1040 | lduw bp(3),b_3 | ||
1041 | mulx a_0,b_2,t_1 !mul_add_c(a[0],b[2],c3,c1,c2); | ||
1042 | addcc c_12,t_1,t_1 | ||
1043 | bcs,a %xcc,.+8 != | ||
1044 | add c_3,t_2,c_3 | ||
1045 | srlx t_1,32,c_12 | ||
1046 | stuw t_1,rp(2) !r[2]=c3; | ||
1047 | or c_12,c_3,c_12 != | ||
1048 | |||
1049 | mulx a_0,b_3,t_1 !mul_add_c(a[0],b[3],c1,c2,c3); | ||
1050 | addcc c_12,t_1,c_12 | ||
1051 | clr c_3 | ||
1052 | bcs,a %xcc,.+8 != | ||
1053 | add c_3,t_2,c_3 | ||
1054 | mulx a_1,b_2,t_1 !mul_add_c(a[1],b[2],c1,c2,c3); | ||
1055 | addcc c_12,t_1,c_12 | ||
1056 | bcs,a %xcc,.+8 != | ||
1057 | add c_3,t_2,c_3 | ||
1058 | lduw ap(3),a_3 | ||
1059 | mulx a_2,b_1,t_1 !mul_add_c(a[2],b[1],c1,c2,c3); | ||
1060 | addcc c_12,t_1,c_12 != | ||
1061 | bcs,a %xcc,.+8 | ||
1062 | add c_3,t_2,c_3 | ||
1063 | mulx a_3,b_0,t_1 !mul_add_c(a[3],b[0],c1,c2,c3);!= | ||
1064 | addcc c_12,t_1,t_1 != | ||
1065 | bcs,a %xcc,.+8 | ||
1066 | add c_3,t_2,c_3 | ||
1067 | srlx t_1,32,c_12 | ||
1068 | stuw t_1,rp(3) !=!r[3]=c1; | ||
1069 | or c_12,c_3,c_12 | ||
1070 | |||
1071 | mulx a_3,b_1,t_1 !mul_add_c(a[3],b[1],c2,c3,c1); | ||
1072 | addcc c_12,t_1,c_12 | ||
1073 | clr c_3 != | ||
1074 | bcs,a %xcc,.+8 | ||
1075 | add c_3,t_2,c_3 | ||
1076 | mulx a_2,b_2,t_1 !mul_add_c(a[2],b[2],c2,c3,c1); | ||
1077 | addcc c_12,t_1,c_12 != | ||
1078 | bcs,a %xcc,.+8 | ||
1079 | add c_3,t_2,c_3 | ||
1080 | mulx a_1,b_3,t_1 !mul_add_c(a[1],b[3],c2,c3,c1); | ||
1081 | addcc c_12,t_1,t_1 != | ||
1082 | bcs,a %xcc,.+8 | ||
1083 | add c_3,t_2,c_3 | ||
1084 | srlx t_1,32,c_12 | ||
1085 | stuw t_1,rp(4) !=!r[4]=c2; | ||
1086 | or c_12,c_3,c_12 | ||
1087 | |||
1088 | mulx a_2,b_3,t_1 !mul_add_c(a[2],b[3],c3,c1,c2); | ||
1089 | addcc c_12,t_1,c_12 | ||
1090 | clr c_3 != | ||
1091 | bcs,a %xcc,.+8 | ||
1092 | add c_3,t_2,c_3 | ||
1093 | mulx a_3,b_2,t_1 !mul_add_c(a[3],b[2],c3,c1,c2); | ||
1094 | addcc c_12,t_1,t_1 != | ||
1095 | bcs,a %xcc,.+8 | ||
1096 | add c_3,t_2,c_3 | ||
1097 | srlx t_1,32,c_12 | ||
1098 | stuw t_1,rp(5) !=!r[5]=c3; | ||
1099 | or c_12,c_3,c_12 | ||
1100 | |||
1101 | mulx a_3,b_3,t_1 !mul_add_c(a[3],b[3],c1,c2,c3); | ||
1102 | addcc c_12,t_1,t_1 | ||
1103 | srlx t_1,32,c_12 != | ||
1104 | stuw t_1,rp(6) !r[6]=c1; | ||
1105 | stuw c_12,rp(7) !r[7]=c2; | ||
1106 | |||
1107 | ret | ||
1108 | restore %g0,%g0,%o0 | ||
1109 | |||
1110 | .type bn_mul_comba4,#function | ||
1111 | .size bn_mul_comba4,(.-bn_mul_comba4) | ||
1112 | |||
1113 | .align 32 | ||
1114 | |||
1115 | .global bn_sqr_comba8 | ||
1116 | bn_sqr_comba8: | ||
1117 | save %sp,FRAME_SIZE,%sp | ||
1118 | mov 1,t_2 | ||
1119 | lduw ap(0),a_0 | ||
1120 | sllx t_2,32,t_2 | ||
1121 | lduw ap(1),a_1 | ||
1122 | mulx a_0,a_0,t_1 !sqr_add_c(a,0,c1,c2,c3); | ||
1123 | srlx t_1,32,c_12 | ||
1124 | stuw t_1,rp(0) !r[0]=c1; | ||
1125 | |||
1126 | lduw ap(2),a_2 | ||
1127 | mulx a_0,a_1,t_1 !=!sqr_add_c2(a,1,0,c2,c3,c1); | ||
1128 | addcc c_12,t_1,c_12 | ||
1129 | clr c_3 | ||
1130 | bcs,a %xcc,.+8 | ||
1131 | add c_3,t_2,c_3 | ||
1132 | addcc c_12,t_1,t_1 | ||
1133 | bcs,a %xcc,.+8 | ||
1134 | add c_3,t_2,c_3 | ||
1135 | srlx t_1,32,c_12 | ||
1136 | stuw t_1,rp(1) !r[1]=c2; | ||
1137 | or c_12,c_3,c_12 | ||
1138 | |||
1139 | mulx a_2,a_0,t_1 !sqr_add_c2(a,2,0,c3,c1,c2); | ||
1140 | addcc c_12,t_1,c_12 | ||
1141 | clr c_3 | ||
1142 | bcs,a %xcc,.+8 | ||
1143 | add c_3,t_2,c_3 | ||
1144 | addcc c_12,t_1,c_12 | ||
1145 | bcs,a %xcc,.+8 | ||
1146 | add c_3,t_2,c_3 | ||
1147 | lduw ap(3),a_3 | ||
1148 | mulx a_1,a_1,t_1 !sqr_add_c(a,1,c3,c1,c2); | ||
1149 | addcc c_12,t_1,t_1 | ||
1150 | bcs,a %xcc,.+8 | ||
1151 | add c_3,t_2,c_3 | ||
1152 | srlx t_1,32,c_12 | ||
1153 | stuw t_1,rp(2) !r[2]=c3; | ||
1154 | or c_12,c_3,c_12 | ||
1155 | |||
1156 | mulx a_0,a_3,t_1 !sqr_add_c2(a,3,0,c1,c2,c3); | ||
1157 | addcc c_12,t_1,c_12 | ||
1158 | clr c_3 | ||
1159 | bcs,a %xcc,.+8 | ||
1160 | add c_3,t_2,c_3 | ||
1161 | addcc c_12,t_1,c_12 | ||
1162 | bcs,a %xcc,.+8 | ||
1163 | add c_3,t_2,c_3 | ||
1164 | lduw ap(4),a_4 | ||
1165 | mulx a_1,a_2,t_1 !sqr_add_c2(a,2,1,c1,c2,c3); | ||
1166 | addcc c_12,t_1,c_12 | ||
1167 | bcs,a %xcc,.+8 | ||
1168 | add c_3,t_2,c_3 | ||
1169 | addcc c_12,t_1,t_1 | ||
1170 | bcs,a %xcc,.+8 | ||
1171 | add c_3,t_2,c_3 | ||
1172 | srlx t_1,32,c_12 | ||
1173 | st t_1,rp(3) !r[3]=c1; | ||
1174 | or c_12,c_3,c_12 | ||
1175 | |||
1176 | mulx a_4,a_0,t_1 !sqr_add_c2(a,4,0,c2,c3,c1); | ||
1177 | addcc c_12,t_1,c_12 | ||
1178 | clr c_3 | ||
1179 | bcs,a %xcc,.+8 | ||
1180 | add c_3,t_2,c_3 | ||
1181 | addcc c_12,t_1,c_12 | ||
1182 | bcs,a %xcc,.+8 | ||
1183 | add c_3,t_2,c_3 | ||
1184 | mulx a_3,a_1,t_1 !sqr_add_c2(a,3,1,c2,c3,c1); | ||
1185 | addcc c_12,t_1,c_12 | ||
1186 | bcs,a %xcc,.+8 | ||
1187 | add c_3,t_2,c_3 | ||
1188 | addcc c_12,t_1,c_12 | ||
1189 | bcs,a %xcc,.+8 | ||
1190 | add c_3,t_2,c_3 | ||
1191 | lduw ap(5),a_5 | ||
1192 | mulx a_2,a_2,t_1 !sqr_add_c(a,2,c2,c3,c1); | ||
1193 | addcc c_12,t_1,t_1 | ||
1194 | bcs,a %xcc,.+8 | ||
1195 | add c_3,t_2,c_3 | ||
1196 | srlx t_1,32,c_12 | ||
1197 | stuw t_1,rp(4) !r[4]=c2; | ||
1198 | or c_12,c_3,c_12 | ||
1199 | |||
1200 | mulx a_0,a_5,t_1 !sqr_add_c2(a,5,0,c3,c1,c2); | ||
1201 | addcc c_12,t_1,c_12 | ||
1202 | clr c_3 | ||
1203 | bcs,a %xcc,.+8 | ||
1204 | add c_3,t_2,c_3 | ||
1205 | addcc c_12,t_1,c_12 | ||
1206 | bcs,a %xcc,.+8 | ||
1207 | add c_3,t_2,c_3 | ||
1208 | mulx a_1,a_4,t_1 !sqr_add_c2(a,4,1,c3,c1,c2); | ||
1209 | addcc c_12,t_1,c_12 | ||
1210 | bcs,a %xcc,.+8 | ||
1211 | add c_3,t_2,c_3 | ||
1212 | addcc c_12,t_1,c_12 | ||
1213 | bcs,a %xcc,.+8 | ||
1214 | add c_3,t_2,c_3 | ||
1215 | lduw ap(6),a_6 | ||
1216 | mulx a_2,a_3,t_1 !sqr_add_c2(a,3,2,c3,c1,c2); | ||
1217 | addcc c_12,t_1,c_12 | ||
1218 | bcs,a %xcc,.+8 | ||
1219 | add c_3,t_2,c_3 | ||
1220 | addcc c_12,t_1,t_1 | ||
1221 | bcs,a %xcc,.+8 | ||
1222 | add c_3,t_2,c_3 | ||
1223 | srlx t_1,32,c_12 | ||
1224 | stuw t_1,rp(5) !r[5]=c3; | ||
1225 | or c_12,c_3,c_12 | ||
1226 | |||
1227 | mulx a_6,a_0,t_1 !sqr_add_c2(a,6,0,c1,c2,c3); | ||
1228 | addcc c_12,t_1,c_12 | ||
1229 | clr c_3 | ||
1230 | bcs,a %xcc,.+8 | ||
1231 | add c_3,t_2,c_3 | ||
1232 | addcc c_12,t_1,c_12 | ||
1233 | bcs,a %xcc,.+8 | ||
1234 | add c_3,t_2,c_3 | ||
1235 | mulx a_5,a_1,t_1 !sqr_add_c2(a,5,1,c1,c2,c3); | ||
1236 | addcc c_12,t_1,c_12 | ||
1237 | bcs,a %xcc,.+8 | ||
1238 | add c_3,t_2,c_3 | ||
1239 | addcc c_12,t_1,c_12 | ||
1240 | bcs,a %xcc,.+8 | ||
1241 | add c_3,t_2,c_3 | ||
1242 | mulx a_4,a_2,t_1 !sqr_add_c2(a,4,2,c1,c2,c3); | ||
1243 | addcc c_12,t_1,c_12 | ||
1244 | bcs,a %xcc,.+8 | ||
1245 | add c_3,t_2,c_3 | ||
1246 | addcc c_12,t_1,c_12 | ||
1247 | bcs,a %xcc,.+8 | ||
1248 | add c_3,t_2,c_3 | ||
1249 | lduw ap(7),a_7 | ||
1250 | mulx a_3,a_3,t_1 !=!sqr_add_c(a,3,c1,c2,c3); | ||
1251 | addcc c_12,t_1,t_1 | ||
1252 | bcs,a %xcc,.+8 | ||
1253 | add c_3,t_2,c_3 | ||
1254 | srlx t_1,32,c_12 | ||
1255 | stuw t_1,rp(6) !r[6]=c1; | ||
1256 | or c_12,c_3,c_12 | ||
1257 | |||
1258 | mulx a_0,a_7,t_1 !sqr_add_c2(a,7,0,c2,c3,c1); | ||
1259 | addcc c_12,t_1,c_12 | ||
1260 | clr c_3 | ||
1261 | bcs,a %xcc,.+8 | ||
1262 | add c_3,t_2,c_3 | ||
1263 | addcc c_12,t_1,c_12 | ||
1264 | bcs,a %xcc,.+8 | ||
1265 | add c_3,t_2,c_3 | ||
1266 | mulx a_1,a_6,t_1 !sqr_add_c2(a,6,1,c2,c3,c1); | ||
1267 | addcc c_12,t_1,c_12 | ||
1268 | bcs,a %xcc,.+8 | ||
1269 | add c_3,t_2,c_3 | ||
1270 | addcc c_12,t_1,c_12 | ||
1271 | bcs,a %xcc,.+8 | ||
1272 | add c_3,t_2,c_3 | ||
1273 | mulx a_2,a_5,t_1 !sqr_add_c2(a,5,2,c2,c3,c1); | ||
1274 | addcc c_12,t_1,c_12 | ||
1275 | bcs,a %xcc,.+8 | ||
1276 | add c_3,t_2,c_3 | ||
1277 | addcc c_12,t_1,c_12 | ||
1278 | bcs,a %xcc,.+8 | ||
1279 | add c_3,t_2,c_3 | ||
1280 | mulx a_3,a_4,t_1 !sqr_add_c2(a,4,3,c2,c3,c1); | ||
1281 | addcc c_12,t_1,c_12 | ||
1282 | bcs,a %xcc,.+8 | ||
1283 | add c_3,t_2,c_3 | ||
1284 | addcc c_12,t_1,t_1 | ||
1285 | bcs,a %xcc,.+8 | ||
1286 | add c_3,t_2,c_3 | ||
1287 | srlx t_1,32,c_12 | ||
1288 | stuw t_1,rp(7) !r[7]=c2; | ||
1289 | or c_12,c_3,c_12 | ||
1290 | |||
1291 | mulx a_7,a_1,t_1 !sqr_add_c2(a,7,1,c3,c1,c2); | ||
1292 | addcc c_12,t_1,c_12 | ||
1293 | clr c_3 | ||
1294 | bcs,a %xcc,.+8 | ||
1295 | add c_3,t_2,c_3 | ||
1296 | addcc c_12,t_1,c_12 | ||
1297 | bcs,a %xcc,.+8 | ||
1298 | add c_3,t_2,c_3 | ||
1299 | mulx a_6,a_2,t_1 !sqr_add_c2(a,6,2,c3,c1,c2); | ||
1300 | addcc c_12,t_1,c_12 | ||
1301 | bcs,a %xcc,.+8 | ||
1302 | add c_3,t_2,c_3 | ||
1303 | addcc c_12,t_1,c_12 | ||
1304 | bcs,a %xcc,.+8 | ||
1305 | add c_3,t_2,c_3 | ||
1306 | mulx a_5,a_3,t_1 !sqr_add_c2(a,5,3,c3,c1,c2); | ||
1307 | addcc c_12,t_1,c_12 | ||
1308 | bcs,a %xcc,.+8 | ||
1309 | add c_3,t_2,c_3 | ||
1310 | addcc c_12,t_1,c_12 | ||
1311 | bcs,a %xcc,.+8 | ||
1312 | add c_3,t_2,c_3 | ||
1313 | mulx a_4,a_4,t_1 !sqr_add_c(a,4,c3,c1,c2); | ||
1314 | addcc c_12,t_1,t_1 | ||
1315 | bcs,a %xcc,.+8 | ||
1316 | add c_3,t_2,c_3 | ||
1317 | srlx t_1,32,c_12 | ||
1318 | stuw t_1,rp(8) !r[8]=c3; | ||
1319 | or c_12,c_3,c_12 | ||
1320 | |||
1321 | mulx a_2,a_7,t_1 !sqr_add_c2(a,7,2,c1,c2,c3); | ||
1322 | addcc c_12,t_1,c_12 | ||
1323 | clr c_3 | ||
1324 | bcs,a %xcc,.+8 | ||
1325 | add c_3,t_2,c_3 | ||
1326 | addcc c_12,t_1,c_12 | ||
1327 | bcs,a %xcc,.+8 | ||
1328 | add c_3,t_2,c_3 | ||
1329 | mulx a_3,a_6,t_1 !sqr_add_c2(a,6,3,c1,c2,c3); | ||
1330 | addcc c_12,t_1,c_12 | ||
1331 | bcs,a %xcc,.+8 | ||
1332 | add c_3,t_2,c_3 | ||
1333 | addcc c_12,t_1,c_12 | ||
1334 | bcs,a %xcc,.+8 | ||
1335 | add c_3,t_2,c_3 | ||
1336 | mulx a_4,a_5,t_1 !sqr_add_c2(a,5,4,c1,c2,c3); | ||
1337 | addcc c_12,t_1,c_12 | ||
1338 | bcs,a %xcc,.+8 | ||
1339 | add c_3,t_2,c_3 | ||
1340 | addcc c_12,t_1,t_1 | ||
1341 | bcs,a %xcc,.+8 | ||
1342 | add c_3,t_2,c_3 | ||
1343 | srlx t_1,32,c_12 | ||
1344 | stuw t_1,rp(9) !r[9]=c1; | ||
1345 | or c_12,c_3,c_12 | ||
1346 | |||
1347 | mulx a_7,a_3,t_1 !sqr_add_c2(a,7,3,c2,c3,c1); | ||
1348 | addcc c_12,t_1,c_12 | ||
1349 | clr c_3 | ||
1350 | bcs,a %xcc,.+8 | ||
1351 | add c_3,t_2,c_3 | ||
1352 | addcc c_12,t_1,c_12 | ||
1353 | bcs,a %xcc,.+8 | ||
1354 | add c_3,t_2,c_3 | ||
1355 | mulx a_6,a_4,t_1 !sqr_add_c2(a,6,4,c2,c3,c1); | ||
1356 | addcc c_12,t_1,c_12 | ||
1357 | bcs,a %xcc,.+8 | ||
1358 | add c_3,t_2,c_3 | ||
1359 | addcc c_12,t_1,c_12 | ||
1360 | bcs,a %xcc,.+8 | ||
1361 | add c_3,t_2,c_3 | ||
1362 | mulx a_5,a_5,t_1 !sqr_add_c(a,5,c2,c3,c1); | ||
1363 | addcc c_12,t_1,t_1 | ||
1364 | bcs,a %xcc,.+8 | ||
1365 | add c_3,t_2,c_3 | ||
1366 | srlx t_1,32,c_12 | ||
1367 | stuw t_1,rp(10) !r[10]=c2; | ||
1368 | or c_12,c_3,c_12 | ||
1369 | |||
1370 | mulx a_4,a_7,t_1 !sqr_add_c2(a,7,4,c3,c1,c2); | ||
1371 | addcc c_12,t_1,c_12 | ||
1372 | clr c_3 | ||
1373 | bcs,a %xcc,.+8 | ||
1374 | add c_3,t_2,c_3 | ||
1375 | addcc c_12,t_1,c_12 | ||
1376 | bcs,a %xcc,.+8 | ||
1377 | add c_3,t_2,c_3 | ||
1378 | mulx a_5,a_6,t_1 !sqr_add_c2(a,6,5,c3,c1,c2); | ||
1379 | addcc c_12,t_1,c_12 | ||
1380 | bcs,a %xcc,.+8 | ||
1381 | add c_3,t_2,c_3 | ||
1382 | addcc c_12,t_1,t_1 | ||
1383 | bcs,a %xcc,.+8 | ||
1384 | add c_3,t_2,c_3 | ||
1385 | srlx t_1,32,c_12 | ||
1386 | stuw t_1,rp(11) !r[11]=c3; | ||
1387 | or c_12,c_3,c_12 | ||
1388 | |||
1389 | mulx a_7,a_5,t_1 !sqr_add_c2(a,7,5,c1,c2,c3); | ||
1390 | addcc c_12,t_1,c_12 | ||
1391 | clr c_3 | ||
1392 | bcs,a %xcc,.+8 | ||
1393 | add c_3,t_2,c_3 | ||
1394 | addcc c_12,t_1,c_12 | ||
1395 | bcs,a %xcc,.+8 | ||
1396 | add c_3,t_2,c_3 | ||
1397 | mulx a_6,a_6,t_1 !sqr_add_c(a,6,c1,c2,c3); | ||
1398 | addcc c_12,t_1,t_1 | ||
1399 | bcs,a %xcc,.+8 | ||
1400 | add c_3,t_2,c_3 | ||
1401 | srlx t_1,32,c_12 | ||
1402 | stuw t_1,rp(12) !r[12]=c1; | ||
1403 | or c_12,c_3,c_12 | ||
1404 | |||
1405 | mulx a_6,a_7,t_1 !sqr_add_c2(a,7,6,c2,c3,c1); | ||
1406 | addcc c_12,t_1,c_12 | ||
1407 | clr c_3 | ||
1408 | bcs,a %xcc,.+8 | ||
1409 | add c_3,t_2,c_3 | ||
1410 | addcc c_12,t_1,t_1 | ||
1411 | bcs,a %xcc,.+8 | ||
1412 | add c_3,t_2,c_3 | ||
1413 | srlx t_1,32,c_12 | ||
1414 | stuw t_1,rp(13) !r[13]=c2; | ||
1415 | or c_12,c_3,c_12 | ||
1416 | |||
1417 | mulx a_7,a_7,t_1 !sqr_add_c(a,7,c3,c1,c2); | ||
1418 | addcc c_12,t_1,t_1 | ||
1419 | srlx t_1,32,c_12 | ||
1420 | stuw t_1,rp(14) !r[14]=c3; | ||
1421 | stuw c_12,rp(15) !r[15]=c1; | ||
1422 | |||
1423 | ret | ||
1424 | restore %g0,%g0,%o0 | ||
1425 | |||
1426 | .type bn_sqr_comba8,#function | ||
1427 | .size bn_sqr_comba8,(.-bn_sqr_comba8) | ||
1428 | |||
1429 | .align 32 | ||
1430 | |||
1431 | .global bn_sqr_comba4 | ||
1432 | /* | ||
1433 | * void bn_sqr_comba4(r,a) | ||
1434 | * BN_ULONG *r,*a; | ||
1435 | */ | ||
1436 | bn_sqr_comba4: | ||
1437 | save %sp,FRAME_SIZE,%sp | ||
1438 | mov 1,t_2 | ||
1439 | lduw ap(0),a_0 | ||
1440 | sllx t_2,32,t_2 | ||
1441 | lduw ap(1),a_1 | ||
1442 | mulx a_0,a_0,t_1 !sqr_add_c(a,0,c1,c2,c3); | ||
1443 | srlx t_1,32,c_12 | ||
1444 | stuw t_1,rp(0) !r[0]=c1; | ||
1445 | |||
1446 | lduw ap(2),a_2 | ||
1447 | mulx a_0,a_1,t_1 !sqr_add_c2(a,1,0,c2,c3,c1); | ||
1448 | addcc c_12,t_1,c_12 | ||
1449 | clr c_3 | ||
1450 | bcs,a %xcc,.+8 | ||
1451 | add c_3,t_2,c_3 | ||
1452 | addcc c_12,t_1,t_1 | ||
1453 | bcs,a %xcc,.+8 | ||
1454 | add c_3,t_2,c_3 | ||
1455 | srlx t_1,32,c_12 | ||
1456 | stuw t_1,rp(1) !r[1]=c2; | ||
1457 | or c_12,c_3,c_12 | ||
1458 | |||
1459 | mulx a_2,a_0,t_1 !sqr_add_c2(a,2,0,c3,c1,c2); | ||
1460 | addcc c_12,t_1,c_12 | ||
1461 | clr c_3 | ||
1462 | bcs,a %xcc,.+8 | ||
1463 | add c_3,t_2,c_3 | ||
1464 | addcc c_12,t_1,c_12 | ||
1465 | bcs,a %xcc,.+8 | ||
1466 | add c_3,t_2,c_3 | ||
1467 | lduw ap(3),a_3 | ||
1468 | mulx a_1,a_1,t_1 !sqr_add_c(a,1,c3,c1,c2); | ||
1469 | addcc c_12,t_1,t_1 | ||
1470 | bcs,a %xcc,.+8 | ||
1471 | add c_3,t_2,c_3 | ||
1472 | srlx t_1,32,c_12 | ||
1473 | stuw t_1,rp(2) !r[2]=c3; | ||
1474 | or c_12,c_3,c_12 | ||
1475 | |||
1476 | mulx a_0,a_3,t_1 !sqr_add_c2(a,3,0,c1,c2,c3); | ||
1477 | addcc c_12,t_1,c_12 | ||
1478 | clr c_3 | ||
1479 | bcs,a %xcc,.+8 | ||
1480 | add c_3,t_2,c_3 | ||
1481 | addcc c_12,t_1,c_12 | ||
1482 | bcs,a %xcc,.+8 | ||
1483 | add c_3,t_2,c_3 | ||
1484 | mulx a_1,a_2,t_1 !sqr_add_c2(a,2,1,c1,c2,c3); | ||
1485 | addcc c_12,t_1,c_12 | ||
1486 | bcs,a %xcc,.+8 | ||
1487 | add c_3,t_2,c_3 | ||
1488 | addcc c_12,t_1,t_1 | ||
1489 | bcs,a %xcc,.+8 | ||
1490 | add c_3,t_2,c_3 | ||
1491 | srlx t_1,32,c_12 | ||
1492 | stuw t_1,rp(3) !r[3]=c1; | ||
1493 | or c_12,c_3,c_12 | ||
1494 | |||
1495 | mulx a_3,a_1,t_1 !sqr_add_c2(a,3,1,c2,c3,c1); | ||
1496 | addcc c_12,t_1,c_12 | ||
1497 | clr c_3 | ||
1498 | bcs,a %xcc,.+8 | ||
1499 | add c_3,t_2,c_3 | ||
1500 | addcc c_12,t_1,c_12 | ||
1501 | bcs,a %xcc,.+8 | ||
1502 | add c_3,t_2,c_3 | ||
1503 | mulx a_2,a_2,t_1 !sqr_add_c(a,2,c2,c3,c1); | ||
1504 | addcc c_12,t_1,t_1 | ||
1505 | bcs,a %xcc,.+8 | ||
1506 | add c_3,t_2,c_3 | ||
1507 | srlx t_1,32,c_12 | ||
1508 | stuw t_1,rp(4) !r[4]=c2; | ||
1509 | or c_12,c_3,c_12 | ||
1510 | |||
1511 | mulx a_2,a_3,t_1 !sqr_add_c2(a,3,2,c3,c1,c2); | ||
1512 | addcc c_12,t_1,c_12 | ||
1513 | clr c_3 | ||
1514 | bcs,a %xcc,.+8 | ||
1515 | add c_3,t_2,c_3 | ||
1516 | addcc c_12,t_1,t_1 | ||
1517 | bcs,a %xcc,.+8 | ||
1518 | add c_3,t_2,c_3 | ||
1519 | srlx t_1,32,c_12 | ||
1520 | stuw t_1,rp(5) !r[5]=c3; | ||
1521 | or c_12,c_3,c_12 | ||
1522 | |||
1523 | mulx a_3,a_3,t_1 !sqr_add_c(a,3,c1,c2,c3); | ||
1524 | addcc c_12,t_1,t_1 | ||
1525 | srlx t_1,32,c_12 | ||
1526 | stuw t_1,rp(6) !r[6]=c1; | ||
1527 | stuw c_12,rp(7) !r[7]=c2; | ||
1528 | |||
1529 | ret | ||
1530 | restore %g0,%g0,%o0 | ||
1531 | |||
1532 | .type bn_sqr_comba4,#function | ||
1533 | .size bn_sqr_comba4,(.-bn_sqr_comba4) | ||
1534 | |||
1535 | .align 32 | ||
diff --git a/src/lib/libcrypto/bn/asm/x86.pl b/src/lib/libcrypto/bn/asm/x86.pl new file mode 100644 index 0000000000..1bc4f1bb27 --- /dev/null +++ b/src/lib/libcrypto/bn/asm/x86.pl | |||
@@ -0,0 +1,28 @@ | |||
1 | #!/usr/local/bin/perl | ||
2 | |||
3 | push(@INC,"perlasm","../../perlasm"); | ||
4 | require "x86asm.pl"; | ||
5 | |||
6 | require("x86/mul_add.pl"); | ||
7 | require("x86/mul.pl"); | ||
8 | require("x86/sqr.pl"); | ||
9 | require("x86/div.pl"); | ||
10 | require("x86/add.pl"); | ||
11 | require("x86/sub.pl"); | ||
12 | require("x86/comba.pl"); | ||
13 | |||
14 | &asm_init($ARGV[0],$0); | ||
15 | |||
16 | &bn_mul_add_words("bn_mul_add_words"); | ||
17 | &bn_mul_words("bn_mul_words"); | ||
18 | &bn_sqr_words("bn_sqr_words"); | ||
19 | &bn_div_words("bn_div_words"); | ||
20 | &bn_add_words("bn_add_words"); | ||
21 | &bn_sub_words("bn_sub_words"); | ||
22 | &bn_mul_comba("bn_mul_comba8",8); | ||
23 | &bn_mul_comba("bn_mul_comba4",4); | ||
24 | &bn_sqr_comba("bn_sqr_comba8",8); | ||
25 | &bn_sqr_comba("bn_sqr_comba4",4); | ||
26 | |||
27 | &asm_finish(); | ||
28 | |||
diff --git a/src/lib/libcrypto/bn/asm/x86/add.pl b/src/lib/libcrypto/bn/asm/x86/add.pl new file mode 100644 index 0000000000..0b5cf583e3 --- /dev/null +++ b/src/lib/libcrypto/bn/asm/x86/add.pl | |||
@@ -0,0 +1,76 @@ | |||
1 | #!/usr/local/bin/perl | ||
2 | # x86 assember | ||
3 | |||
4 | sub bn_add_words | ||
5 | { | ||
6 | local($name)=@_; | ||
7 | |||
8 | &function_begin($name,""); | ||
9 | |||
10 | &comment(""); | ||
11 | $a="esi"; | ||
12 | $b="edi"; | ||
13 | $c="eax"; | ||
14 | $r="ebx"; | ||
15 | $tmp1="ecx"; | ||
16 | $tmp2="edx"; | ||
17 | $num="ebp"; | ||
18 | |||
19 | &mov($r,&wparam(0)); # get r | ||
20 | &mov($a,&wparam(1)); # get a | ||
21 | &mov($b,&wparam(2)); # get b | ||
22 | &mov($num,&wparam(3)); # get num | ||
23 | &xor($c,$c); # clear carry | ||
24 | &and($num,0xfffffff8); # num / 8 | ||
25 | |||
26 | &jz(&label("aw_finish")); | ||
27 | |||
28 | &set_label("aw_loop",0); | ||
29 | for ($i=0; $i<8; $i++) | ||
30 | { | ||
31 | &comment("Round $i"); | ||
32 | |||
33 | &mov($tmp1,&DWP($i*4,$a,"",0)); # *a | ||
34 | &mov($tmp2,&DWP($i*4,$b,"",0)); # *b | ||
35 | &add($tmp1,$c); | ||
36 | &mov($c,0); | ||
37 | &adc($c,$c); | ||
38 | &add($tmp1,$tmp2); | ||
39 | &adc($c,0); | ||
40 | &mov(&DWP($i*4,$r,"",0),$tmp1); # *r | ||
41 | } | ||
42 | |||
43 | &comment(""); | ||
44 | &add($a,32); | ||
45 | &add($b,32); | ||
46 | &add($r,32); | ||
47 | &sub($num,8); | ||
48 | &jnz(&label("aw_loop")); | ||
49 | |||
50 | &set_label("aw_finish",0); | ||
51 | &mov($num,&wparam(3)); # get num | ||
52 | &and($num,7); | ||
53 | &jz(&label("aw_end")); | ||
54 | |||
55 | for ($i=0; $i<7; $i++) | ||
56 | { | ||
57 | &comment("Tail Round $i"); | ||
58 | &mov($tmp1,&DWP($i*4,$a,"",0)); # *a | ||
59 | &mov($tmp2,&DWP($i*4,$b,"",0));# *b | ||
60 | &add($tmp1,$c); | ||
61 | &mov($c,0); | ||
62 | &adc($c,$c); | ||
63 | &add($tmp1,$tmp2); | ||
64 | &adc($c,0); | ||
65 | &dec($num) if ($i != 6); | ||
66 | &mov(&DWP($i*4,$r,"",0),$tmp1); # *a | ||
67 | &jz(&label("aw_end")) if ($i != 6); | ||
68 | } | ||
69 | &set_label("aw_end",0); | ||
70 | |||
71 | # &mov("eax",$c); # $c is "eax" | ||
72 | |||
73 | &function_end($name); | ||
74 | } | ||
75 | |||
76 | 1; | ||
diff --git a/src/lib/libcrypto/bn/asm/x86/comba.pl b/src/lib/libcrypto/bn/asm/x86/comba.pl new file mode 100644 index 0000000000..2291253629 --- /dev/null +++ b/src/lib/libcrypto/bn/asm/x86/comba.pl | |||
@@ -0,0 +1,277 @@ | |||
1 | #!/usr/local/bin/perl | ||
2 | # x86 assember | ||
3 | |||
4 | sub mul_add_c | ||
5 | { | ||
6 | local($a,$ai,$b,$bi,$c0,$c1,$c2,$pos,$i,$na,$nb)=@_; | ||
7 | |||
8 | # pos == -1 if eax and edx are pre-loaded, 0 to load from next | ||
9 | # words, and 1 if load return value | ||
10 | |||
11 | &comment("mul a[$ai]*b[$bi]"); | ||
12 | |||
13 | # "eax" and "edx" will always be pre-loaded. | ||
14 | # &mov("eax",&DWP($ai*4,$a,"",0)) ; | ||
15 | # &mov("edx",&DWP($bi*4,$b,"",0)); | ||
16 | |||
17 | &mul("edx"); | ||
18 | &add($c0,"eax"); | ||
19 | &mov("eax",&DWP(($na)*4,$a,"",0)) if $pos == 0; # laod next a | ||
20 | &mov("eax",&wparam(0)) if $pos > 0; # load r[] | ||
21 | ### | ||
22 | &adc($c1,"edx"); | ||
23 | &mov("edx",&DWP(($nb)*4,$b,"",0)) if $pos == 0; # laod next b | ||
24 | &mov("edx",&DWP(($nb)*4,$b,"",0)) if $pos == 1; # laod next b | ||
25 | ### | ||
26 | &adc($c2,0); | ||
27 | # is pos > 1, it means it is the last loop | ||
28 | &mov(&DWP($i*4,"eax","",0),$c0) if $pos > 0; # save r[]; | ||
29 | &mov("eax",&DWP(($na)*4,$a,"",0)) if $pos == 1; # laod next a | ||
30 | } | ||
31 | |||
32 | sub sqr_add_c | ||
33 | { | ||
34 | local($r,$a,$ai,$bi,$c0,$c1,$c2,$pos,$i,$na,$nb)=@_; | ||
35 | |||
36 | # pos == -1 if eax and edx are pre-loaded, 0 to load from next | ||
37 | # words, and 1 if load return value | ||
38 | |||
39 | &comment("sqr a[$ai]*a[$bi]"); | ||
40 | |||
41 | # "eax" and "edx" will always be pre-loaded. | ||
42 | # &mov("eax",&DWP($ai*4,$a,"",0)) ; | ||
43 | # &mov("edx",&DWP($bi*4,$b,"",0)); | ||
44 | |||
45 | if ($ai == $bi) | ||
46 | { &mul("eax");} | ||
47 | else | ||
48 | { &mul("edx");} | ||
49 | &add($c0,"eax"); | ||
50 | &mov("eax",&DWP(($na)*4,$a,"",0)) if $pos == 0; # load next a | ||
51 | ### | ||
52 | &adc($c1,"edx"); | ||
53 | &mov("edx",&DWP(($nb)*4,$a,"",0)) if ($pos == 1) && ($na != $nb); | ||
54 | ### | ||
55 | &adc($c2,0); | ||
56 | # is pos > 1, it means it is the last loop | ||
57 | &mov(&DWP($i*4,$r,"",0),$c0) if $pos > 0; # save r[]; | ||
58 | &mov("eax",&DWP(($na)*4,$a,"",0)) if $pos == 1; # load next b | ||
59 | } | ||
60 | |||
61 | sub sqr_add_c2 | ||
62 | { | ||
63 | local($r,$a,$ai,$bi,$c0,$c1,$c2,$pos,$i,$na,$nb)=@_; | ||
64 | |||
65 | # pos == -1 if eax and edx are pre-loaded, 0 to load from next | ||
66 | # words, and 1 if load return value | ||
67 | |||
68 | &comment("sqr a[$ai]*a[$bi]"); | ||
69 | |||
70 | # "eax" and "edx" will always be pre-loaded. | ||
71 | # &mov("eax",&DWP($ai*4,$a,"",0)) ; | ||
72 | # &mov("edx",&DWP($bi*4,$a,"",0)); | ||
73 | |||
74 | if ($ai == $bi) | ||
75 | { &mul("eax");} | ||
76 | else | ||
77 | { &mul("edx");} | ||
78 | &add("eax","eax"); | ||
79 | ### | ||
80 | &adc("edx","edx"); | ||
81 | ### | ||
82 | &adc($c2,0); | ||
83 | &add($c0,"eax"); | ||
84 | &adc($c1,"edx"); | ||
85 | &mov("eax",&DWP(($na)*4,$a,"",0)) if $pos == 0; # load next a | ||
86 | &mov("eax",&DWP(($na)*4,$a,"",0)) if $pos == 1; # load next b | ||
87 | &adc($c2,0); | ||
88 | &mov(&DWP($i*4,$r,"",0),$c0) if $pos > 0; # save r[]; | ||
89 | &mov("edx",&DWP(($nb)*4,$a,"",0)) if ($pos <= 1) && ($na != $nb); | ||
90 | ### | ||
91 | } | ||
92 | |||
93 | sub bn_mul_comba | ||
94 | { | ||
95 | local($name,$num)=@_; | ||
96 | local($a,$b,$c0,$c1,$c2); | ||
97 | local($i,$as,$ae,$bs,$be,$ai,$bi); | ||
98 | local($tot,$end); | ||
99 | |||
100 | &function_begin_B($name,""); | ||
101 | |||
102 | $c0="ebx"; | ||
103 | $c1="ecx"; | ||
104 | $c2="ebp"; | ||
105 | $a="esi"; | ||
106 | $b="edi"; | ||
107 | |||
108 | $as=0; | ||
109 | $ae=0; | ||
110 | $bs=0; | ||
111 | $be=0; | ||
112 | $tot=$num+$num-1; | ||
113 | |||
114 | &push("esi"); | ||
115 | &mov($a,&wparam(1)); | ||
116 | &push("edi"); | ||
117 | &mov($b,&wparam(2)); | ||
118 | &push("ebp"); | ||
119 | &push("ebx"); | ||
120 | |||
121 | &xor($c0,$c0); | ||
122 | &mov("eax",&DWP(0,$a,"",0)); # load the first word | ||
123 | &xor($c1,$c1); | ||
124 | &mov("edx",&DWP(0,$b,"",0)); # load the first second | ||
125 | |||
126 | for ($i=0; $i<$tot; $i++) | ||
127 | { | ||
128 | $ai=$as; | ||
129 | $bi=$bs; | ||
130 | $end=$be+1; | ||
131 | |||
132 | &comment("################## Calculate word $i"); | ||
133 | |||
134 | for ($j=$bs; $j<$end; $j++) | ||
135 | { | ||
136 | &xor($c2,$c2) if ($j == $bs); | ||
137 | if (($j+1) == $end) | ||
138 | { | ||
139 | $v=1; | ||
140 | $v=2 if (($i+1) == $tot); | ||
141 | } | ||
142 | else | ||
143 | { $v=0; } | ||
144 | if (($j+1) != $end) | ||
145 | { | ||
146 | $na=($ai-1); | ||
147 | $nb=($bi+1); | ||
148 | } | ||
149 | else | ||
150 | { | ||
151 | $na=$as+($i < ($num-1)); | ||
152 | $nb=$bs+($i >= ($num-1)); | ||
153 | } | ||
154 | #printf STDERR "[$ai,$bi] -> [$na,$nb]\n"; | ||
155 | &mul_add_c($a,$ai,$b,$bi,$c0,$c1,$c2,$v,$i,$na,$nb); | ||
156 | if ($v) | ||
157 | { | ||
158 | &comment("saved r[$i]"); | ||
159 | # &mov("eax",&wparam(0)); | ||
160 | # &mov(&DWP($i*4,"eax","",0),$c0); | ||
161 | ($c0,$c1,$c2)=($c1,$c2,$c0); | ||
162 | } | ||
163 | $ai--; | ||
164 | $bi++; | ||
165 | } | ||
166 | $as++ if ($i < ($num-1)); | ||
167 | $ae++ if ($i >= ($num-1)); | ||
168 | |||
169 | $bs++ if ($i >= ($num-1)); | ||
170 | $be++ if ($i < ($num-1)); | ||
171 | } | ||
172 | &comment("save r[$i]"); | ||
173 | # &mov("eax",&wparam(0)); | ||
174 | &mov(&DWP($i*4,"eax","",0),$c0); | ||
175 | |||
176 | &pop("ebx"); | ||
177 | &pop("ebp"); | ||
178 | &pop("edi"); | ||
179 | &pop("esi"); | ||
180 | &ret(); | ||
181 | &function_end_B($name); | ||
182 | } | ||
183 | |||
184 | sub bn_sqr_comba | ||
185 | { | ||
186 | local($name,$num)=@_; | ||
187 | local($r,$a,$c0,$c1,$c2)=@_; | ||
188 | local($i,$as,$ae,$bs,$be,$ai,$bi); | ||
189 | local($b,$tot,$end,$half); | ||
190 | |||
191 | &function_begin_B($name,""); | ||
192 | |||
193 | $c0="ebx"; | ||
194 | $c1="ecx"; | ||
195 | $c2="ebp"; | ||
196 | $a="esi"; | ||
197 | $r="edi"; | ||
198 | |||
199 | &push("esi"); | ||
200 | &push("edi"); | ||
201 | &push("ebp"); | ||
202 | &push("ebx"); | ||
203 | &mov($r,&wparam(0)); | ||
204 | &mov($a,&wparam(1)); | ||
205 | &xor($c0,$c0); | ||
206 | &xor($c1,$c1); | ||
207 | &mov("eax",&DWP(0,$a,"",0)); # load the first word | ||
208 | |||
209 | $as=0; | ||
210 | $ae=0; | ||
211 | $bs=0; | ||
212 | $be=0; | ||
213 | $tot=$num+$num-1; | ||
214 | |||
215 | for ($i=0; $i<$tot; $i++) | ||
216 | { | ||
217 | $ai=$as; | ||
218 | $bi=$bs; | ||
219 | $end=$be+1; | ||
220 | |||
221 | &comment("############### Calculate word $i"); | ||
222 | for ($j=$bs; $j<$end; $j++) | ||
223 | { | ||
224 | &xor($c2,$c2) if ($j == $bs); | ||
225 | if (($ai-1) < ($bi+1)) | ||
226 | { | ||
227 | $v=1; | ||
228 | $v=2 if ($i+1) == $tot; | ||
229 | } | ||
230 | else | ||
231 | { $v=0; } | ||
232 | if (!$v) | ||
233 | { | ||
234 | $na=$ai-1; | ||
235 | $nb=$bi+1; | ||
236 | } | ||
237 | else | ||
238 | { | ||
239 | $na=$as+($i < ($num-1)); | ||
240 | $nb=$bs+($i >= ($num-1)); | ||
241 | } | ||
242 | if ($ai == $bi) | ||
243 | { | ||
244 | &sqr_add_c($r,$a,$ai,$bi, | ||
245 | $c0,$c1,$c2,$v,$i,$na,$nb); | ||
246 | } | ||
247 | else | ||
248 | { | ||
249 | &sqr_add_c2($r,$a,$ai,$bi, | ||
250 | $c0,$c1,$c2,$v,$i,$na,$nb); | ||
251 | } | ||
252 | if ($v) | ||
253 | { | ||
254 | &comment("saved r[$i]"); | ||
255 | #&mov(&DWP($i*4,$r,"",0),$c0); | ||
256 | ($c0,$c1,$c2)=($c1,$c2,$c0); | ||
257 | last; | ||
258 | } | ||
259 | $ai--; | ||
260 | $bi++; | ||
261 | } | ||
262 | $as++ if ($i < ($num-1)); | ||
263 | $ae++ if ($i >= ($num-1)); | ||
264 | |||
265 | $bs++ if ($i >= ($num-1)); | ||
266 | $be++ if ($i < ($num-1)); | ||
267 | } | ||
268 | &mov(&DWP($i*4,$r,"",0),$c0); | ||
269 | &pop("ebx"); | ||
270 | &pop("ebp"); | ||
271 | &pop("edi"); | ||
272 | &pop("esi"); | ||
273 | &ret(); | ||
274 | &function_end_B($name); | ||
275 | } | ||
276 | |||
277 | 1; | ||
diff --git a/src/lib/libcrypto/bn/asm/x86/div.pl b/src/lib/libcrypto/bn/asm/x86/div.pl new file mode 100644 index 0000000000..0e90152caa --- /dev/null +++ b/src/lib/libcrypto/bn/asm/x86/div.pl | |||
@@ -0,0 +1,15 @@ | |||
1 | #!/usr/local/bin/perl | ||
2 | # x86 assember | ||
3 | |||
4 | sub bn_div_words | ||
5 | { | ||
6 | local($name)=@_; | ||
7 | |||
8 | &function_begin($name,""); | ||
9 | &mov("edx",&wparam(0)); # | ||
10 | &mov("eax",&wparam(1)); # | ||
11 | &mov("ebx",&wparam(2)); # | ||
12 | &div("ebx"); | ||
13 | &function_end($name); | ||
14 | } | ||
15 | 1; | ||
diff --git a/src/lib/libcrypto/bn/asm/x86/mul.pl b/src/lib/libcrypto/bn/asm/x86/mul.pl new file mode 100644 index 0000000000..674cb9b055 --- /dev/null +++ b/src/lib/libcrypto/bn/asm/x86/mul.pl | |||
@@ -0,0 +1,77 @@ | |||
1 | #!/usr/local/bin/perl | ||
2 | # x86 assember | ||
3 | |||
4 | sub bn_mul_words | ||
5 | { | ||
6 | local($name)=@_; | ||
7 | |||
8 | &function_begin($name,""); | ||
9 | |||
10 | &comment(""); | ||
11 | $Low="eax"; | ||
12 | $High="edx"; | ||
13 | $a="ebx"; | ||
14 | $w="ecx"; | ||
15 | $r="edi"; | ||
16 | $c="esi"; | ||
17 | $num="ebp"; | ||
18 | |||
19 | &xor($c,$c); # clear carry | ||
20 | &mov($r,&wparam(0)); # | ||
21 | &mov($a,&wparam(1)); # | ||
22 | &mov($num,&wparam(2)); # | ||
23 | &mov($w,&wparam(3)); # | ||
24 | |||
25 | &and($num,0xfffffff8); # num / 8 | ||
26 | &jz(&label("mw_finish")); | ||
27 | |||
28 | &set_label("mw_loop",0); | ||
29 | for ($i=0; $i<32; $i+=4) | ||
30 | { | ||
31 | &comment("Round $i"); | ||
32 | |||
33 | &mov("eax",&DWP($i,$a,"",0)); # *a | ||
34 | &mul($w); # *a * w | ||
35 | &add("eax",$c); # L(t)+=c | ||
36 | # XXX | ||
37 | |||
38 | &adc("edx",0); # H(t)+=carry | ||
39 | &mov(&DWP($i,$r,"",0),"eax"); # *r= L(t); | ||
40 | |||
41 | &mov($c,"edx"); # c= H(t); | ||
42 | } | ||
43 | |||
44 | &comment(""); | ||
45 | &add($a,32); | ||
46 | &add($r,32); | ||
47 | &sub($num,8); | ||
48 | &jz(&label("mw_finish")); | ||
49 | &jmp(&label("mw_loop")); | ||
50 | |||
51 | &set_label("mw_finish",0); | ||
52 | &mov($num,&wparam(2)); # get num | ||
53 | &and($num,7); | ||
54 | &jnz(&label("mw_finish2")); | ||
55 | &jmp(&label("mw_end")); | ||
56 | |||
57 | &set_label("mw_finish2",1); | ||
58 | for ($i=0; $i<7; $i++) | ||
59 | { | ||
60 | &comment("Tail Round $i"); | ||
61 | &mov("eax",&DWP($i*4,$a,"",0));# *a | ||
62 | &mul($w); # *a * w | ||
63 | &add("eax",$c); # L(t)+=c | ||
64 | # XXX | ||
65 | &adc("edx",0); # H(t)+=carry | ||
66 | &mov(&DWP($i*4,$r,"",0),"eax");# *r= L(t); | ||
67 | &mov($c,"edx"); # c= H(t); | ||
68 | &dec($num) if ($i != 7-1); | ||
69 | &jz(&label("mw_end")) if ($i != 7-1); | ||
70 | } | ||
71 | &set_label("mw_end",0); | ||
72 | &mov("eax",$c); | ||
73 | |||
74 | &function_end($name); | ||
75 | } | ||
76 | |||
77 | 1; | ||
diff --git a/src/lib/libcrypto/bn/asm/x86/mul_add.pl b/src/lib/libcrypto/bn/asm/x86/mul_add.pl new file mode 100644 index 0000000000..61830d3a90 --- /dev/null +++ b/src/lib/libcrypto/bn/asm/x86/mul_add.pl | |||
@@ -0,0 +1,87 @@ | |||
1 | #!/usr/local/bin/perl | ||
2 | # x86 assember | ||
3 | |||
4 | sub bn_mul_add_words | ||
5 | { | ||
6 | local($name)=@_; | ||
7 | |||
8 | &function_begin($name,""); | ||
9 | |||
10 | &comment(""); | ||
11 | $Low="eax"; | ||
12 | $High="edx"; | ||
13 | $a="ebx"; | ||
14 | $w="ebp"; | ||
15 | $r="edi"; | ||
16 | $c="esi"; | ||
17 | |||
18 | &xor($c,$c); # clear carry | ||
19 | &mov($r,&wparam(0)); # | ||
20 | |||
21 | &mov("ecx",&wparam(2)); # | ||
22 | &mov($a,&wparam(1)); # | ||
23 | |||
24 | &and("ecx",0xfffffff8); # num / 8 | ||
25 | &mov($w,&wparam(3)); # | ||
26 | |||
27 | &push("ecx"); # Up the stack for a tmp variable | ||
28 | |||
29 | &jz(&label("maw_finish")); | ||
30 | |||
31 | &set_label("maw_loop",0); | ||
32 | |||
33 | &mov(&swtmp(0),"ecx"); # | ||
34 | |||
35 | for ($i=0; $i<32; $i+=4) | ||
36 | { | ||
37 | &comment("Round $i"); | ||
38 | |||
39 | &mov("eax",&DWP($i,$a,"",0)); # *a | ||
40 | &mul($w); # *a * w | ||
41 | &add("eax",$c); # L(t)+= *r | ||
42 | &mov($c,&DWP($i,$r,"",0)); # L(t)+= *r | ||
43 | &adc("edx",0); # H(t)+=carry | ||
44 | &add("eax",$c); # L(t)+=c | ||
45 | &adc("edx",0); # H(t)+=carry | ||
46 | &mov(&DWP($i,$r,"",0),"eax"); # *r= L(t); | ||
47 | &mov($c,"edx"); # c= H(t); | ||
48 | } | ||
49 | |||
50 | &comment(""); | ||
51 | &mov("ecx",&swtmp(0)); # | ||
52 | &add($a,32); | ||
53 | &add($r,32); | ||
54 | &sub("ecx",8); | ||
55 | &jnz(&label("maw_loop")); | ||
56 | |||
57 | &set_label("maw_finish",0); | ||
58 | &mov("ecx",&wparam(2)); # get num | ||
59 | &and("ecx",7); | ||
60 | &jnz(&label("maw_finish2")); # helps branch prediction | ||
61 | &jmp(&label("maw_end")); | ||
62 | |||
63 | &set_label("maw_finish2",1); | ||
64 | for ($i=0; $i<7; $i++) | ||
65 | { | ||
66 | &comment("Tail Round $i"); | ||
67 | &mov("eax",&DWP($i*4,$a,"",0));# *a | ||
68 | &mul($w); # *a * w | ||
69 | &add("eax",$c); # L(t)+=c | ||
70 | &mov($c,&DWP($i*4,$r,"",0)); # L(t)+= *r | ||
71 | &adc("edx",0); # H(t)+=carry | ||
72 | &add("eax",$c); | ||
73 | &adc("edx",0); # H(t)+=carry | ||
74 | &dec("ecx") if ($i != 7-1); | ||
75 | &mov(&DWP($i*4,$r,"",0),"eax"); # *r= L(t); | ||
76 | &mov($c,"edx"); # c= H(t); | ||
77 | &jz(&label("maw_end")) if ($i != 7-1); | ||
78 | } | ||
79 | &set_label("maw_end",0); | ||
80 | &mov("eax",$c); | ||
81 | |||
82 | &pop("ecx"); # clear variable from | ||
83 | |||
84 | &function_end($name); | ||
85 | } | ||
86 | |||
87 | 1; | ||
diff --git a/src/lib/libcrypto/bn/asm/x86/sqr.pl b/src/lib/libcrypto/bn/asm/x86/sqr.pl new file mode 100644 index 0000000000..1f90993cf6 --- /dev/null +++ b/src/lib/libcrypto/bn/asm/x86/sqr.pl | |||
@@ -0,0 +1,60 @@ | |||
1 | #!/usr/local/bin/perl | ||
2 | # x86 assember | ||
3 | |||
4 | sub bn_sqr_words | ||
5 | { | ||
6 | local($name)=@_; | ||
7 | |||
8 | &function_begin($name,""); | ||
9 | |||
10 | &comment(""); | ||
11 | $r="esi"; | ||
12 | $a="edi"; | ||
13 | $num="ebx"; | ||
14 | |||
15 | &mov($r,&wparam(0)); # | ||
16 | &mov($a,&wparam(1)); # | ||
17 | &mov($num,&wparam(2)); # | ||
18 | |||
19 | &and($num,0xfffffff8); # num / 8 | ||
20 | &jz(&label("sw_finish")); | ||
21 | |||
22 | &set_label("sw_loop",0); | ||
23 | for ($i=0; $i<32; $i+=4) | ||
24 | { | ||
25 | &comment("Round $i"); | ||
26 | &mov("eax",&DWP($i,$a,"",0)); # *a | ||
27 | # XXX | ||
28 | &mul("eax"); # *a * *a | ||
29 | &mov(&DWP($i*2,$r,"",0),"eax"); # | ||
30 | &mov(&DWP($i*2+4,$r,"",0),"edx");# | ||
31 | } | ||
32 | |||
33 | &comment(""); | ||
34 | &add($a,32); | ||
35 | &add($r,64); | ||
36 | &sub($num,8); | ||
37 | &jnz(&label("sw_loop")); | ||
38 | |||
39 | &set_label("sw_finish",0); | ||
40 | &mov($num,&wparam(2)); # get num | ||
41 | &and($num,7); | ||
42 | &jz(&label("sw_end")); | ||
43 | |||
44 | for ($i=0; $i<7; $i++) | ||
45 | { | ||
46 | &comment("Tail Round $i"); | ||
47 | &mov("eax",&DWP($i*4,$a,"",0)); # *a | ||
48 | # XXX | ||
49 | &mul("eax"); # *a * *a | ||
50 | &mov(&DWP($i*8,$r,"",0),"eax"); # | ||
51 | &dec($num) if ($i != 7-1); | ||
52 | &mov(&DWP($i*8+4,$r,"",0),"edx"); | ||
53 | &jz(&label("sw_end")) if ($i != 7-1); | ||
54 | } | ||
55 | &set_label("sw_end",0); | ||
56 | |||
57 | &function_end($name); | ||
58 | } | ||
59 | |||
60 | 1; | ||
diff --git a/src/lib/libcrypto/bn/asm/x86/sub.pl b/src/lib/libcrypto/bn/asm/x86/sub.pl new file mode 100644 index 0000000000..837b0e1b07 --- /dev/null +++ b/src/lib/libcrypto/bn/asm/x86/sub.pl | |||
@@ -0,0 +1,76 @@ | |||
1 | #!/usr/local/bin/perl | ||
2 | # x86 assember | ||
3 | |||
4 | sub bn_sub_words | ||
5 | { | ||
6 | local($name)=@_; | ||
7 | |||
8 | &function_begin($name,""); | ||
9 | |||
10 | &comment(""); | ||
11 | $a="esi"; | ||
12 | $b="edi"; | ||
13 | $c="eax"; | ||
14 | $r="ebx"; | ||
15 | $tmp1="ecx"; | ||
16 | $tmp2="edx"; | ||
17 | $num="ebp"; | ||
18 | |||
19 | &mov($r,&wparam(0)); # get r | ||
20 | &mov($a,&wparam(1)); # get a | ||
21 | &mov($b,&wparam(2)); # get b | ||
22 | &mov($num,&wparam(3)); # get num | ||
23 | &xor($c,$c); # clear carry | ||
24 | &and($num,0xfffffff8); # num / 8 | ||
25 | |||
26 | &jz(&label("aw_finish")); | ||
27 | |||
28 | &set_label("aw_loop",0); | ||
29 | for ($i=0; $i<8; $i++) | ||
30 | { | ||
31 | &comment("Round $i"); | ||
32 | |||
33 | &mov($tmp1,&DWP($i*4,$a,"",0)); # *a | ||
34 | &mov($tmp2,&DWP($i*4,$b,"",0)); # *b | ||
35 | &sub($tmp1,$c); | ||
36 | &mov($c,0); | ||
37 | &adc($c,$c); | ||
38 | &sub($tmp1,$tmp2); | ||
39 | &adc($c,0); | ||
40 | &mov(&DWP($i*4,$r,"",0),$tmp1); # *r | ||
41 | } | ||
42 | |||
43 | &comment(""); | ||
44 | &add($a,32); | ||
45 | &add($b,32); | ||
46 | &add($r,32); | ||
47 | &sub($num,8); | ||
48 | &jnz(&label("aw_loop")); | ||
49 | |||
50 | &set_label("aw_finish",0); | ||
51 | &mov($num,&wparam(3)); # get num | ||
52 | &and($num,7); | ||
53 | &jz(&label("aw_end")); | ||
54 | |||
55 | for ($i=0; $i<7; $i++) | ||
56 | { | ||
57 | &comment("Tail Round $i"); | ||
58 | &mov($tmp1,&DWP($i*4,$a,"",0)); # *a | ||
59 | &mov($tmp2,&DWP($i*4,$b,"",0));# *b | ||
60 | &sub($tmp1,$c); | ||
61 | &mov($c,0); | ||
62 | &adc($c,$c); | ||
63 | &sub($tmp1,$tmp2); | ||
64 | &adc($c,0); | ||
65 | &dec($num) if ($i != 6); | ||
66 | &mov(&DWP($i*4,$r,"",0),$tmp1); # *a | ||
67 | &jz(&label("aw_end")) if ($i != 6); | ||
68 | } | ||
69 | &set_label("aw_end",0); | ||
70 | |||
71 | # &mov("eax",$c); # $c is "eax" | ||
72 | |||
73 | &function_end($name); | ||
74 | } | ||
75 | |||
76 | 1; | ||
diff --git a/src/lib/libcrypto/bn/bn.h b/src/lib/libcrypto/bn/bn.h new file mode 100644 index 0000000000..f935e1ca79 --- /dev/null +++ b/src/lib/libcrypto/bn/bn.h | |||
@@ -0,0 +1,467 @@ | |||
1 | /* crypto/bn/bn.h */ | ||
2 | /* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) | ||
3 | * All rights reserved. | ||
4 | * | ||
5 | * This package is an SSL implementation written | ||
6 | * by Eric Young (eay@cryptsoft.com). | ||
7 | * The implementation was written so as to conform with Netscapes SSL. | ||
8 | * | ||
9 | * This library is free for commercial and non-commercial use as long as | ||
10 | * the following conditions are aheared to. The following conditions | ||
11 | * apply to all code found in this distribution, be it the RC4, RSA, | ||
12 | * lhash, DES, etc., code; not just the SSL code. The SSL documentation | ||
13 | * included with this distribution is covered by the same copyright terms | ||
14 | * except that the holder is Tim Hudson (tjh@cryptsoft.com). | ||
15 | * | ||
16 | * Copyright remains Eric Young's, and as such any Copyright notices in | ||
17 | * the code are not to be removed. | ||
18 | * If this package is used in a product, Eric Young should be given attribution | ||
19 | * as the author of the parts of the library used. | ||
20 | * This can be in the form of a textual message at program startup or | ||
21 | * in documentation (online or textual) provided with the package. | ||
22 | * | ||
23 | * Redistribution and use in source and binary forms, with or without | ||
24 | * modification, are permitted provided that the following conditions | ||
25 | * are met: | ||
26 | * 1. Redistributions of source code must retain the copyright | ||
27 | * notice, this list of conditions and the following disclaimer. | ||
28 | * 2. Redistributions in binary form must reproduce the above copyright | ||
29 | * notice, this list of conditions and the following disclaimer in the | ||
30 | * documentation and/or other materials provided with the distribution. | ||
31 | * 3. All advertising materials mentioning features or use of this software | ||
32 | * must display the following acknowledgement: | ||
33 | * "This product includes cryptographic software written by | ||
34 | * Eric Young (eay@cryptsoft.com)" | ||
35 | * The word 'cryptographic' can be left out if the rouines from the library | ||
36 | * being used are not cryptographic related :-). | ||
37 | * 4. If you include any Windows specific code (or a derivative thereof) from | ||
38 | * the apps directory (application code) you must include an acknowledgement: | ||
39 | * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" | ||
40 | * | ||
41 | * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND | ||
42 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
43 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
44 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | ||
45 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
46 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
47 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
48 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
49 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
50 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
51 | * SUCH DAMAGE. | ||
52 | * | ||
53 | * The licence and distribution terms for any publically available version or | ||
54 | * derivative of this code cannot be changed. i.e. this code cannot simply be | ||
55 | * copied and put under another distribution licence | ||
56 | * [including the GNU Public Licence.] | ||
57 | */ | ||
58 | |||
59 | #ifndef HEADER_BN_H | ||
60 | #define HEADER_BN_H | ||
61 | |||
62 | #ifndef WIN16 | ||
63 | #include <stdio.h> /* FILE */ | ||
64 | #endif | ||
65 | #include <openssl/opensslconf.h> | ||
66 | |||
67 | #ifdef __cplusplus | ||
68 | extern "C" { | ||
69 | #endif | ||
70 | |||
71 | #ifdef VMS | ||
72 | #undef BN_LLONG /* experimental, so far... */ | ||
73 | #endif | ||
74 | |||
75 | #define BN_MUL_COMBA | ||
76 | #define BN_SQR_COMBA | ||
77 | #define BN_RECURSION | ||
78 | #define RECP_MUL_MOD | ||
79 | #define MONT_MUL_MOD | ||
80 | |||
81 | /* This next option uses the C libraries (2 word)/(1 word) function. | ||
82 | * If it is not defined, I use my C version (which is slower). | ||
83 | * The reason for this flag is that when the particular C compiler | ||
84 | * library routine is used, and the library is linked with a different | ||
85 | * compiler, the library is missing. This mostly happens when the | ||
86 | * library is built with gcc and then linked using nornal cc. This would | ||
87 | * be a common occurance because gcc normally produces code that is | ||
88 | * 2 times faster than system compilers for the big number stuff. | ||
89 | * For machines with only one compiler (or shared libraries), this should | ||
90 | * be on. Again this in only really a problem on machines | ||
91 | * using "long long's", are 32bit, and are not using my assember code. */ | ||
92 | #if defined(MSDOS) || defined(WINDOWS) || defined(linux) | ||
93 | #define BN_DIV2W | ||
94 | #endif | ||
95 | |||
96 | /* assuming long is 64bit - this is the DEC Alpha | ||
97 | * unsigned long long is only 64 bits :-(, don't define | ||
98 | * BN_LLONG for the DEC Alpha */ | ||
99 | #ifdef SIXTY_FOUR_BIT_LONG | ||
100 | #define BN_ULLONG unsigned long long | ||
101 | #define BN_ULONG unsigned long | ||
102 | #define BN_LONG long | ||
103 | #define BN_BITS 128 | ||
104 | #define BN_BYTES 8 | ||
105 | #define BN_BITS2 64 | ||
106 | #define BN_BITS4 32 | ||
107 | #define BN_MASK (0xffffffffffffffffffffffffffffffffLL) | ||
108 | #define BN_MASK2 (0xffffffffffffffffL) | ||
109 | #define BN_MASK2l (0xffffffffL) | ||
110 | #define BN_MASK2h (0xffffffff00000000L) | ||
111 | #define BN_MASK2h1 (0xffffffff80000000L) | ||
112 | #define BN_TBIT (0x8000000000000000L) | ||
113 | #define BN_DEC_CONV (10000000000000000000UL) | ||
114 | #define BN_DEC_FMT1 "%lu" | ||
115 | #define BN_DEC_FMT2 "%019lu" | ||
116 | #define BN_DEC_NUM 19 | ||
117 | #endif | ||
118 | |||
119 | /* This is where the long long data type is 64 bits, but long is 32. | ||
120 | * For machines where there are 64bit registers, this is the mode to use. | ||
121 | * IRIX, on R4000 and above should use this mode, along with the relevent | ||
122 | * assember code :-). Do NOT define BN_LLONG. | ||
123 | */ | ||
124 | #ifdef SIXTY_FOUR_BIT | ||
125 | #undef BN_LLONG | ||
126 | #undef BN_ULLONG | ||
127 | #define BN_ULONG unsigned long long | ||
128 | #define BN_LONG long long | ||
129 | #define BN_BITS 128 | ||
130 | #define BN_BYTES 8 | ||
131 | #define BN_BITS2 64 | ||
132 | #define BN_BITS4 32 | ||
133 | #define BN_MASK2 (0xffffffffffffffffLL) | ||
134 | #define BN_MASK2l (0xffffffffL) | ||
135 | #define BN_MASK2h (0xffffffff00000000LL) | ||
136 | #define BN_MASK2h1 (0xffffffff80000000LL) | ||
137 | #define BN_TBIT (0x8000000000000000LL) | ||
138 | #define BN_DEC_CONV (10000000000000000000LL) | ||
139 | #define BN_DEC_FMT1 "%llu" | ||
140 | #define BN_DEC_FMT2 "%019llu" | ||
141 | #define BN_DEC_NUM 19 | ||
142 | #endif | ||
143 | |||
144 | #ifdef THIRTY_TWO_BIT | ||
145 | #if defined(WIN32) && !defined(__GNUC__) | ||
146 | #define BN_ULLONG unsigned _int64 | ||
147 | #else | ||
148 | #define BN_ULLONG unsigned long long | ||
149 | #endif | ||
150 | #define BN_ULONG unsigned long | ||
151 | #define BN_LONG long | ||
152 | #define BN_BITS 64 | ||
153 | #define BN_BYTES 4 | ||
154 | #define BN_BITS2 32 | ||
155 | #define BN_BITS4 16 | ||
156 | #ifdef WIN32 | ||
157 | /* VC++ doesn't like the LL suffix */ | ||
158 | #define BN_MASK (0xffffffffffffffffL) | ||
159 | #else | ||
160 | #define BN_MASK (0xffffffffffffffffLL) | ||
161 | #endif | ||
162 | #define BN_MASK2 (0xffffffffL) | ||
163 | #define BN_MASK2l (0xffff) | ||
164 | #define BN_MASK2h1 (0xffff8000L) | ||
165 | #define BN_MASK2h (0xffff0000L) | ||
166 | #define BN_TBIT (0x80000000L) | ||
167 | #define BN_DEC_CONV (1000000000L) | ||
168 | #define BN_DEC_FMT1 "%lu" | ||
169 | #define BN_DEC_FMT2 "%09lu" | ||
170 | #define BN_DEC_NUM 9 | ||
171 | #endif | ||
172 | |||
173 | #ifdef SIXTEEN_BIT | ||
174 | #ifndef BN_DIV2W | ||
175 | #define BN_DIV2W | ||
176 | #endif | ||
177 | #define BN_ULLONG unsigned long | ||
178 | #define BN_ULONG unsigned short | ||
179 | #define BN_LONG short | ||
180 | #define BN_BITS 32 | ||
181 | #define BN_BYTES 2 | ||
182 | #define BN_BITS2 16 | ||
183 | #define BN_BITS4 8 | ||
184 | #define BN_MASK (0xffffffff) | ||
185 | #define BN_MASK2 (0xffff) | ||
186 | #define BN_MASK2l (0xff) | ||
187 | #define BN_MASK2h1 (0xff80) | ||
188 | #define BN_MASK2h (0xff00) | ||
189 | #define BN_TBIT (0x8000) | ||
190 | #define BN_DEC_CONV (100000) | ||
191 | #define BN_DEC_FMT1 "%u" | ||
192 | #define BN_DEC_FMT2 "%05u" | ||
193 | #define BN_DEC_NUM 5 | ||
194 | #endif | ||
195 | |||
196 | #ifdef EIGHT_BIT | ||
197 | #ifndef BN_DIV2W | ||
198 | #define BN_DIV2W | ||
199 | #endif | ||
200 | #define BN_ULLONG unsigned short | ||
201 | #define BN_ULONG unsigned char | ||
202 | #define BN_LONG char | ||
203 | #define BN_BITS 16 | ||
204 | #define BN_BYTES 1 | ||
205 | #define BN_BITS2 8 | ||
206 | #define BN_BITS4 4 | ||
207 | #define BN_MASK (0xffff) | ||
208 | #define BN_MASK2 (0xff) | ||
209 | #define BN_MASK2l (0xf) | ||
210 | #define BN_MASK2h1 (0xf8) | ||
211 | #define BN_MASK2h (0xf0) | ||
212 | #define BN_TBIT (0x80) | ||
213 | #define BN_DEC_CONV (100) | ||
214 | #define BN_DEC_FMT1 "%u" | ||
215 | #define BN_DEC_FMT2 "%02u" | ||
216 | #define BN_DEC_NUM 2 | ||
217 | #endif | ||
218 | |||
219 | #define BN_DEFAULT_BITS 1280 | ||
220 | |||
221 | #ifdef BIGNUM | ||
222 | #undef BIGNUM | ||
223 | #endif | ||
224 | |||
225 | #define BN_FLG_MALLOCED 0x01 | ||
226 | #define BN_FLG_STATIC_DATA 0x02 | ||
227 | #define BN_FLG_FREE 0x8000 /* used for debuging */ | ||
228 | #define BN_set_flags(b,n) ((b)->flags|=(n)) | ||
229 | #define BN_get_flags(b,n) ((b)->flags&(n)) | ||
230 | |||
231 | typedef struct bignum_st | ||
232 | { | ||
233 | BN_ULONG *d; /* Pointer to an array of 'BN_BITS2' bit chunks. */ | ||
234 | int top; /* Index of last used d +1. */ | ||
235 | /* The next are internal book keeping for bn_expand. */ | ||
236 | int max; /* Size of the d array. */ | ||
237 | int neg; /* one if the number is negative */ | ||
238 | int flags; | ||
239 | } BIGNUM; | ||
240 | |||
241 | /* Used for temp variables */ | ||
242 | #define BN_CTX_NUM 12 | ||
243 | typedef struct bignum_ctx | ||
244 | { | ||
245 | int tos; | ||
246 | BIGNUM bn[BN_CTX_NUM+1]; | ||
247 | int flags; | ||
248 | } BN_CTX; | ||
249 | |||
250 | typedef struct bn_blinding_st | ||
251 | { | ||
252 | int init; | ||
253 | BIGNUM *A; | ||
254 | BIGNUM *Ai; | ||
255 | BIGNUM *mod; /* just a reference */ | ||
256 | } BN_BLINDING; | ||
257 | |||
258 | /* Used for montgomery multiplication */ | ||
259 | typedef struct bn_mont_ctx_st | ||
260 | { | ||
261 | int use_word; /* 0 for word form, 1 for long form */ | ||
262 | int ri; /* number of bits in R */ | ||
263 | BIGNUM RR; /* used to convert to montgomery form */ | ||
264 | BIGNUM N; /* The modulus */ | ||
265 | BIGNUM Ni; /* The inverse of N */ | ||
266 | BN_ULONG n0; /* word form of inverse, normally only one of | ||
267 | * Ni or n0 is defined */ | ||
268 | int flags; | ||
269 | } BN_MONT_CTX; | ||
270 | |||
271 | /* Used for reciprocal division/mod functions | ||
272 | * It cannot be shared between threads | ||
273 | */ | ||
274 | typedef struct bn_recp_ctx_st | ||
275 | { | ||
276 | BIGNUM N; /* the divisor */ | ||
277 | BIGNUM Nr; /* the reciprocal */ | ||
278 | int num_bits; | ||
279 | int shift; | ||
280 | int flags; | ||
281 | } BN_RECP_CTX; | ||
282 | |||
283 | #define BN_to_montgomery(r,a,mont,ctx) BN_mod_mul_montgomery(\ | ||
284 | r,a,&((mont)->RR),(mont),ctx) | ||
285 | |||
286 | #define BN_prime_checks (5) | ||
287 | |||
288 | #define BN_num_bytes(a) ((BN_num_bits(a)+7)/8) | ||
289 | #define BN_is_word(a,w) (((a)->top == 1) && ((a)->d[0] == (BN_ULONG)(w))) | ||
290 | #define BN_is_zero(a) (((a)->top == 0) || BN_is_word(a,0)) | ||
291 | #define BN_is_one(a) (BN_is_word((a),1)) | ||
292 | #define BN_is_odd(a) (((a)->top > 0) && ((a)->d[0] & 1)) | ||
293 | #define BN_one(a) (BN_set_word((a),1)) | ||
294 | #define BN_zero(a) (BN_set_word((a),0)) | ||
295 | |||
296 | /*#define BN_ascii2bn(a) BN_hex2bn(a) */ | ||
297 | /*#define BN_bn2ascii(a) BN_bn2hex(a) */ | ||
298 | |||
299 | #define bn_expand(n,b) ((((((b+BN_BITS2-1))/BN_BITS2)) <= (n)->max)?\ | ||
300 | (n):bn_expand2((n),(b)/BN_BITS2+1)) | ||
301 | #define bn_wexpand(n,b) (((b) <= (n)->max)?(n):bn_expand2((n),(b))) | ||
302 | |||
303 | #define bn_fix_top(a) \ | ||
304 | { \ | ||
305 | BN_ULONG *ftl; \ | ||
306 | if ((a)->top > 0) \ | ||
307 | { \ | ||
308 | for (ftl= &((a)->d[(a)->top-1]); (a)->top > 0; (a)->top--) \ | ||
309 | if (*(ftl--)) break; \ | ||
310 | } \ | ||
311 | } | ||
312 | |||
313 | BIGNUM *BN_value_one(void); | ||
314 | char * BN_options(void); | ||
315 | BN_CTX *BN_CTX_new(void); | ||
316 | void BN_CTX_init(BN_CTX *c); | ||
317 | void BN_CTX_free(BN_CTX *c); | ||
318 | int BN_rand(BIGNUM *rnd, int bits, int top,int bottom); | ||
319 | int BN_num_bits(const BIGNUM *a); | ||
320 | int BN_num_bits_word(BN_ULONG); | ||
321 | BIGNUM *BN_new(void); | ||
322 | void BN_init(BIGNUM *); | ||
323 | void BN_clear_free(BIGNUM *a); | ||
324 | BIGNUM *BN_copy(BIGNUM *a, const BIGNUM *b); | ||
325 | BIGNUM *BN_bin2bn(const unsigned char *s,int len,BIGNUM *ret); | ||
326 | int BN_bn2bin(const BIGNUM *a, unsigned char *to); | ||
327 | BIGNUM *BN_mpi2bn(unsigned char *s,int len,BIGNUM *ret); | ||
328 | int BN_bn2mpi(const BIGNUM *a, unsigned char *to); | ||
329 | int BN_sub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b); | ||
330 | int BN_usub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b); | ||
331 | int BN_uadd(BIGNUM *r, const BIGNUM *a, const BIGNUM *b); | ||
332 | int BN_add(BIGNUM *r, BIGNUM *a, BIGNUM *b); | ||
333 | int BN_mod(BIGNUM *rem, const BIGNUM *m, const BIGNUM *d, BN_CTX *ctx); | ||
334 | int BN_div(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m, const BIGNUM *d, | ||
335 | BN_CTX *ctx); | ||
336 | int BN_mul(BIGNUM *r, BIGNUM *a, BIGNUM *b,BN_CTX *ctx); | ||
337 | int BN_sqr(BIGNUM *r, BIGNUM *a,BN_CTX *ctx); | ||
338 | BN_ULONG BN_mod_word(BIGNUM *a, BN_ULONG w); | ||
339 | BN_ULONG BN_div_word(BIGNUM *a, BN_ULONG w); | ||
340 | int BN_mul_word(BIGNUM *a, BN_ULONG w); | ||
341 | int BN_add_word(BIGNUM *a, BN_ULONG w); | ||
342 | int BN_sub_word(BIGNUM *a, BN_ULONG w); | ||
343 | int BN_set_word(BIGNUM *a, BN_ULONG w); | ||
344 | BN_ULONG BN_get_word(BIGNUM *a); | ||
345 | int BN_cmp(const BIGNUM *a, const BIGNUM *b); | ||
346 | void BN_free(BIGNUM *a); | ||
347 | int BN_is_bit_set(const BIGNUM *a, int n); | ||
348 | int BN_lshift(BIGNUM *r, const BIGNUM *a, int n); | ||
349 | int BN_lshift1(BIGNUM *r, BIGNUM *a); | ||
350 | int BN_exp(BIGNUM *r, BIGNUM *a, BIGNUM *p,BN_CTX *ctx); | ||
351 | int BN_mod_exp(BIGNUM *r, BIGNUM *a, const BIGNUM *p, | ||
352 | const BIGNUM *m,BN_CTX *ctx); | ||
353 | int BN_mod_exp_mont(BIGNUM *r, BIGNUM *a, const BIGNUM *p, | ||
354 | const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx); | ||
355 | int BN_mod_exp2_mont(BIGNUM *r, BIGNUM *a1, BIGNUM *p1,BIGNUM *a2, | ||
356 | BIGNUM *p2,BIGNUM *m,BN_CTX *ctx,BN_MONT_CTX *m_ctx); | ||
357 | int BN_mod_exp_simple(BIGNUM *r, BIGNUM *a, BIGNUM *p, | ||
358 | BIGNUM *m,BN_CTX *ctx); | ||
359 | int BN_mask_bits(BIGNUM *a,int n); | ||
360 | int BN_mod_mul(BIGNUM *ret, BIGNUM *a, BIGNUM *b, const BIGNUM *m, BN_CTX *ctx); | ||
361 | #ifndef WIN16 | ||
362 | int BN_print_fp(FILE *fp, BIGNUM *a); | ||
363 | #endif | ||
364 | #ifdef HEADER_BIO_H | ||
365 | int BN_print(BIO *fp, const BIGNUM *a); | ||
366 | #else | ||
367 | int BN_print(char *fp, const BIGNUM *a); | ||
368 | #endif | ||
369 | int BN_reciprocal(BIGNUM *r, BIGNUM *m, int len, BN_CTX *ctx); | ||
370 | int BN_rshift(BIGNUM *r, BIGNUM *a, int n); | ||
371 | int BN_rshift1(BIGNUM *r, BIGNUM *a); | ||
372 | void BN_clear(BIGNUM *a); | ||
373 | BIGNUM *bn_expand2(BIGNUM *b, int bits); | ||
374 | BIGNUM *BN_dup(const BIGNUM *a); | ||
375 | int BN_ucmp(const BIGNUM *a, const BIGNUM *b); | ||
376 | int BN_set_bit(BIGNUM *a, int n); | ||
377 | int BN_clear_bit(BIGNUM *a, int n); | ||
378 | char * BN_bn2hex(const BIGNUM *a); | ||
379 | char * BN_bn2dec(const BIGNUM *a); | ||
380 | int BN_hex2bn(BIGNUM **a, const char *str); | ||
381 | int BN_dec2bn(BIGNUM **a, const char *str); | ||
382 | int BN_gcd(BIGNUM *r,BIGNUM *in_a,BIGNUM *in_b,BN_CTX *ctx); | ||
383 | BIGNUM *BN_mod_inverse(BIGNUM *ret,BIGNUM *a, const BIGNUM *n,BN_CTX *ctx); | ||
384 | BIGNUM *BN_generate_prime(BIGNUM *ret,int bits,int strong,BIGNUM *add, | ||
385 | BIGNUM *rem,void (*callback)(int,int,void *),void *cb_arg); | ||
386 | int BN_is_prime(BIGNUM *p,int nchecks,void (*callback)(int,int,void *), | ||
387 | BN_CTX *ctx,void *cb_arg); | ||
388 | void ERR_load_BN_strings(void ); | ||
389 | |||
390 | BN_ULONG bn_mul_add_words(BN_ULONG *rp, BN_ULONG *ap, int num, BN_ULONG w); | ||
391 | BN_ULONG bn_mul_words(BN_ULONG *rp, BN_ULONG *ap, int num, BN_ULONG w); | ||
392 | void bn_sqr_words(BN_ULONG *rp, BN_ULONG *ap, int num); | ||
393 | BN_ULONG bn_div_words(BN_ULONG h, BN_ULONG l, BN_ULONG d); | ||
394 | BN_ULONG bn_add_words(BN_ULONG *rp, BN_ULONG *ap, BN_ULONG *bp,int num); | ||
395 | BN_ULONG bn_sub_words(BN_ULONG *rp, BN_ULONG *ap, BN_ULONG *bp,int num); | ||
396 | |||
397 | BN_MONT_CTX *BN_MONT_CTX_new(void ); | ||
398 | void BN_MONT_CTX_init(BN_MONT_CTX *ctx); | ||
399 | int BN_mod_mul_montgomery(BIGNUM *r,BIGNUM *a,BIGNUM *b,BN_MONT_CTX *mont, | ||
400 | BN_CTX *ctx); | ||
401 | int BN_from_montgomery(BIGNUM *r,BIGNUM *a,BN_MONT_CTX *mont,BN_CTX *ctx); | ||
402 | void BN_MONT_CTX_free(BN_MONT_CTX *mont); | ||
403 | int BN_MONT_CTX_set(BN_MONT_CTX *mont,const BIGNUM *modulus,BN_CTX *ctx); | ||
404 | BN_MONT_CTX *BN_MONT_CTX_copy(BN_MONT_CTX *to,BN_MONT_CTX *from); | ||
405 | |||
406 | BN_BLINDING *BN_BLINDING_new(BIGNUM *A,BIGNUM *Ai,BIGNUM *mod); | ||
407 | void BN_BLINDING_free(BN_BLINDING *b); | ||
408 | int BN_BLINDING_update(BN_BLINDING *b,BN_CTX *ctx); | ||
409 | int BN_BLINDING_convert(BIGNUM *n, BN_BLINDING *r, BN_CTX *ctx); | ||
410 | int BN_BLINDING_invert(BIGNUM *n, BN_BLINDING *b, BN_CTX *ctx); | ||
411 | |||
412 | void BN_set_params(int mul,int high,int low,int mont); | ||
413 | int BN_get_params(int which); /* 0, mul, 1 high, 2 low, 3 mont */ | ||
414 | |||
415 | void BN_RECP_CTX_init(BN_RECP_CTX *recp); | ||
416 | BN_RECP_CTX *BN_RECP_CTX_new(void); | ||
417 | void BN_RECP_CTX_free(BN_RECP_CTX *recp); | ||
418 | int BN_RECP_CTX_set(BN_RECP_CTX *recp,const BIGNUM *rdiv,BN_CTX *ctx); | ||
419 | int BN_mod_mul_reciprocal(BIGNUM *r, BIGNUM *x, BIGNUM *y, | ||
420 | BN_RECP_CTX *recp,BN_CTX *ctx); | ||
421 | int BN_mod_exp_recp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, | ||
422 | const BIGNUM *m, BN_CTX *ctx); | ||
423 | int BN_div_recp(BIGNUM *dv, BIGNUM *rem, BIGNUM *m, | ||
424 | BN_RECP_CTX *recp, BN_CTX *ctx); | ||
425 | |||
426 | |||
427 | /* BEGIN ERROR CODES */ | ||
428 | /* The following lines are auto generated by the script mkerr.pl. Any changes | ||
429 | * made after this point may be overwritten when the script is next run. | ||
430 | */ | ||
431 | |||
432 | /* Error codes for the BN functions. */ | ||
433 | |||
434 | /* Function codes. */ | ||
435 | #define BN_F_BN_BLINDING_CONVERT 100 | ||
436 | #define BN_F_BN_BLINDING_INVERT 101 | ||
437 | #define BN_F_BN_BLINDING_NEW 102 | ||
438 | #define BN_F_BN_BLINDING_UPDATE 103 | ||
439 | #define BN_F_BN_BN2DEC 104 | ||
440 | #define BN_F_BN_BN2HEX 105 | ||
441 | #define BN_F_BN_CTX_NEW 106 | ||
442 | #define BN_F_BN_DIV 107 | ||
443 | #define BN_F_BN_EXPAND2 108 | ||
444 | #define BN_F_BN_MOD_EXP_MONT 109 | ||
445 | #define BN_F_BN_MOD_INVERSE 110 | ||
446 | #define BN_F_BN_MOD_MUL_RECIPROCAL 111 | ||
447 | #define BN_F_BN_MPI2BN 112 | ||
448 | #define BN_F_BN_NEW 113 | ||
449 | #define BN_F_BN_RAND 114 | ||
450 | #define BN_F_BN_USUB 115 | ||
451 | |||
452 | /* Reason codes. */ | ||
453 | #define BN_R_ARG2_LT_ARG3 100 | ||
454 | #define BN_R_BAD_RECIPROCAL 101 | ||
455 | #define BN_R_CALLED_WITH_EVEN_MODULUS 102 | ||
456 | #define BN_R_DIV_BY_ZERO 103 | ||
457 | #define BN_R_ENCODING_ERROR 104 | ||
458 | #define BN_R_EXPAND_ON_STATIC_BIGNUM_DATA 105 | ||
459 | #define BN_R_INVALID_LENGTH 106 | ||
460 | #define BN_R_NOT_INITIALIZED 107 | ||
461 | #define BN_R_NO_INVERSE 108 | ||
462 | |||
463 | #ifdef __cplusplus | ||
464 | } | ||
465 | #endif | ||
466 | #endif | ||
467 | |||
diff --git a/src/lib/libcrypto/bn/bn_asm.c b/src/lib/libcrypto/bn/bn_asm.c new file mode 100644 index 0000000000..4d3da16a0c --- /dev/null +++ b/src/lib/libcrypto/bn/bn_asm.c | |||
@@ -0,0 +1,802 @@ | |||
1 | /* crypto/bn/bn_asm.c */ | ||
2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) | ||
3 | * All rights reserved. | ||
4 | * | ||
5 | * This package is an SSL implementation written | ||
6 | * by Eric Young (eay@cryptsoft.com). | ||
7 | * The implementation was written so as to conform with Netscapes SSL. | ||
8 | * | ||
9 | * This library is free for commercial and non-commercial use as long as | ||
10 | * the following conditions are aheared to. The following conditions | ||
11 | * apply to all code found in this distribution, be it the RC4, RSA, | ||
12 | * lhash, DES, etc., code; not just the SSL code. The SSL documentation | ||
13 | * included with this distribution is covered by the same copyright terms | ||
14 | * except that the holder is Tim Hudson (tjh@cryptsoft.com). | ||
15 | * | ||
16 | * Copyright remains Eric Young's, and as such any Copyright notices in | ||
17 | * the code are not to be removed. | ||
18 | * If this package is used in a product, Eric Young should be given attribution | ||
19 | * as the author of the parts of the library used. | ||
20 | * This can be in the form of a textual message at program startup or | ||
21 | * in documentation (online or textual) provided with the package. | ||
22 | * | ||
23 | * Redistribution and use in source and binary forms, with or without | ||
24 | * modification, are permitted provided that the following conditions | ||
25 | * are met: | ||
26 | * 1. Redistributions of source code must retain the copyright | ||
27 | * notice, this list of conditions and the following disclaimer. | ||
28 | * 2. Redistributions in binary form must reproduce the above copyright | ||
29 | * notice, this list of conditions and the following disclaimer in the | ||
30 | * documentation and/or other materials provided with the distribution. | ||
31 | * 3. All advertising materials mentioning features or use of this software | ||
32 | * must display the following acknowledgement: | ||
33 | * "This product includes cryptographic software written by | ||
34 | * Eric Young (eay@cryptsoft.com)" | ||
35 | * The word 'cryptographic' can be left out if the rouines from the library | ||
36 | * being used are not cryptographic related :-). | ||
37 | * 4. If you include any Windows specific code (or a derivative thereof) from | ||
38 | * the apps directory (application code) you must include an acknowledgement: | ||
39 | * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" | ||
40 | * | ||
41 | * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND | ||
42 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
43 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
44 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | ||
45 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
46 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
47 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
48 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
49 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
50 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
51 | * SUCH DAMAGE. | ||
52 | * | ||
53 | * The licence and distribution terms for any publically available version or | ||
54 | * derivative of this code cannot be changed. i.e. this code cannot simply be | ||
55 | * copied and put under another distribution licence | ||
56 | * [including the GNU Public Licence.] | ||
57 | */ | ||
58 | |||
59 | #include <stdio.h> | ||
60 | #include "cryptlib.h" | ||
61 | #include "bn_lcl.h" | ||
62 | |||
63 | #ifdef BN_LLONG | ||
64 | |||
65 | BN_ULONG bn_mul_add_words(BN_ULONG *rp, BN_ULONG *ap, int num, BN_ULONG w) | ||
66 | { | ||
67 | BN_ULONG c1=0; | ||
68 | |||
69 | bn_check_num(num); | ||
70 | if (num <= 0) return(c1); | ||
71 | |||
72 | for (;;) | ||
73 | { | ||
74 | mul_add(rp[0],ap[0],w,c1); | ||
75 | if (--num == 0) break; | ||
76 | mul_add(rp[1],ap[1],w,c1); | ||
77 | if (--num == 0) break; | ||
78 | mul_add(rp[2],ap[2],w,c1); | ||
79 | if (--num == 0) break; | ||
80 | mul_add(rp[3],ap[3],w,c1); | ||
81 | if (--num == 0) break; | ||
82 | ap+=4; | ||
83 | rp+=4; | ||
84 | } | ||
85 | |||
86 | return(c1); | ||
87 | } | ||
88 | |||
89 | BN_ULONG bn_mul_words(BN_ULONG *rp, BN_ULONG *ap, int num, BN_ULONG w) | ||
90 | { | ||
91 | BN_ULONG c1=0; | ||
92 | |||
93 | bn_check_num(num); | ||
94 | if (num <= 0) return(c1); | ||
95 | |||
96 | /* for (;;) */ | ||
97 | while (1) /* circumvent egcs-1.1.2 bug */ | ||
98 | { | ||
99 | mul(rp[0],ap[0],w,c1); | ||
100 | if (--num == 0) break; | ||
101 | mul(rp[1],ap[1],w,c1); | ||
102 | if (--num == 0) break; | ||
103 | mul(rp[2],ap[2],w,c1); | ||
104 | if (--num == 0) break; | ||
105 | mul(rp[3],ap[3],w,c1); | ||
106 | if (--num == 0) break; | ||
107 | ap+=4; | ||
108 | rp+=4; | ||
109 | } | ||
110 | return(c1); | ||
111 | } | ||
112 | |||
113 | void bn_sqr_words(BN_ULONG *r, BN_ULONG *a, int n) | ||
114 | { | ||
115 | bn_check_num(n); | ||
116 | if (n <= 0) return; | ||
117 | for (;;) | ||
118 | { | ||
119 | BN_ULLONG t; | ||
120 | |||
121 | t=(BN_ULLONG)(a[0])*(a[0]); | ||
122 | r[0]=Lw(t); r[1]=Hw(t); | ||
123 | if (--n == 0) break; | ||
124 | |||
125 | t=(BN_ULLONG)(a[1])*(a[1]); | ||
126 | r[2]=Lw(t); r[3]=Hw(t); | ||
127 | if (--n == 0) break; | ||
128 | |||
129 | t=(BN_ULLONG)(a[2])*(a[2]); | ||
130 | r[4]=Lw(t); r[5]=Hw(t); | ||
131 | if (--n == 0) break; | ||
132 | |||
133 | t=(BN_ULLONG)(a[3])*(a[3]); | ||
134 | r[6]=Lw(t); r[7]=Hw(t); | ||
135 | if (--n == 0) break; | ||
136 | |||
137 | a+=4; | ||
138 | r+=8; | ||
139 | } | ||
140 | } | ||
141 | |||
142 | #else | ||
143 | |||
144 | BN_ULONG bn_mul_add_words(BN_ULONG *rp, BN_ULONG *ap, int num, BN_ULONG w) | ||
145 | { | ||
146 | BN_ULONG c=0; | ||
147 | BN_ULONG bl,bh; | ||
148 | |||
149 | bn_check_num(num); | ||
150 | if (num <= 0) return((BN_ULONG)0); | ||
151 | |||
152 | bl=LBITS(w); | ||
153 | bh=HBITS(w); | ||
154 | |||
155 | for (;;) | ||
156 | { | ||
157 | mul_add(rp[0],ap[0],bl,bh,c); | ||
158 | if (--num == 0) break; | ||
159 | mul_add(rp[1],ap[1],bl,bh,c); | ||
160 | if (--num == 0) break; | ||
161 | mul_add(rp[2],ap[2],bl,bh,c); | ||
162 | if (--num == 0) break; | ||
163 | mul_add(rp[3],ap[3],bl,bh,c); | ||
164 | if (--num == 0) break; | ||
165 | ap+=4; | ||
166 | rp+=4; | ||
167 | } | ||
168 | return(c); | ||
169 | } | ||
170 | |||
171 | BN_ULONG bn_mul_words(BN_ULONG *rp, BN_ULONG *ap, int num, BN_ULONG w) | ||
172 | { | ||
173 | BN_ULONG carry=0; | ||
174 | BN_ULONG bl,bh; | ||
175 | |||
176 | bn_check_num(num); | ||
177 | if (num <= 0) return((BN_ULONG)0); | ||
178 | |||
179 | bl=LBITS(w); | ||
180 | bh=HBITS(w); | ||
181 | |||
182 | for (;;) | ||
183 | { | ||
184 | mul(rp[0],ap[0],bl,bh,carry); | ||
185 | if (--num == 0) break; | ||
186 | mul(rp[1],ap[1],bl,bh,carry); | ||
187 | if (--num == 0) break; | ||
188 | mul(rp[2],ap[2],bl,bh,carry); | ||
189 | if (--num == 0) break; | ||
190 | mul(rp[3],ap[3],bl,bh,carry); | ||
191 | if (--num == 0) break; | ||
192 | ap+=4; | ||
193 | rp+=4; | ||
194 | } | ||
195 | return(carry); | ||
196 | } | ||
197 | |||
198 | void bn_sqr_words(BN_ULONG *r, BN_ULONG *a, int n) | ||
199 | { | ||
200 | bn_check_num(n); | ||
201 | if (n <= 0) return; | ||
202 | for (;;) | ||
203 | { | ||
204 | sqr64(r[0],r[1],a[0]); | ||
205 | if (--n == 0) break; | ||
206 | |||
207 | sqr64(r[2],r[3],a[1]); | ||
208 | if (--n == 0) break; | ||
209 | |||
210 | sqr64(r[4],r[5],a[2]); | ||
211 | if (--n == 0) break; | ||
212 | |||
213 | sqr64(r[6],r[7],a[3]); | ||
214 | if (--n == 0) break; | ||
215 | |||
216 | a+=4; | ||
217 | r+=8; | ||
218 | } | ||
219 | } | ||
220 | |||
221 | #endif | ||
222 | |||
223 | #if defined(BN_LLONG) && defined(BN_DIV2W) | ||
224 | |||
225 | BN_ULONG bn_div_words(BN_ULONG h, BN_ULONG l, BN_ULONG d) | ||
226 | { | ||
227 | return((BN_ULONG)(((((BN_ULLONG)h)<<BN_BITS2)|l)/(BN_ULLONG)d)); | ||
228 | } | ||
229 | |||
230 | #else | ||
231 | |||
232 | /* Divide h-l by d and return the result. */ | ||
233 | /* I need to test this some more :-( */ | ||
234 | BN_ULONG bn_div_words(BN_ULONG h, BN_ULONG l, BN_ULONG d) | ||
235 | { | ||
236 | BN_ULONG dh,dl,q,ret=0,th,tl,t; | ||
237 | int i,count=2; | ||
238 | |||
239 | if (d == 0) return(BN_MASK2); | ||
240 | |||
241 | i=BN_num_bits_word(d); | ||
242 | if ((i != BN_BITS2) && (h > (BN_ULONG)1<<i)) | ||
243 | { | ||
244 | #if !defined(NO_STDIO) && !defined(WIN16) | ||
245 | fprintf(stderr,"Division would overflow (%d)\n",i); | ||
246 | #endif | ||
247 | abort(); | ||
248 | } | ||
249 | i=BN_BITS2-i; | ||
250 | if (h >= d) h-=d; | ||
251 | |||
252 | if (i) | ||
253 | { | ||
254 | d<<=i; | ||
255 | h=(h<<i)|(l>>(BN_BITS2-i)); | ||
256 | l<<=i; | ||
257 | } | ||
258 | dh=(d&BN_MASK2h)>>BN_BITS4; | ||
259 | dl=(d&BN_MASK2l); | ||
260 | for (;;) | ||
261 | { | ||
262 | if ((h>>BN_BITS4) == dh) | ||
263 | q=BN_MASK2l; | ||
264 | else | ||
265 | q=h/dh; | ||
266 | |||
267 | th=q*dh; | ||
268 | tl=dl*q; | ||
269 | for (;;) | ||
270 | { | ||
271 | t=h-th; | ||
272 | if ((t&BN_MASK2h) || | ||
273 | ((tl) <= ( | ||
274 | (t<<BN_BITS4)| | ||
275 | ((l&BN_MASK2h)>>BN_BITS4)))) | ||
276 | break; | ||
277 | q--; | ||
278 | th-=dh; | ||
279 | tl-=dl; | ||
280 | } | ||
281 | t=(tl>>BN_BITS4); | ||
282 | tl=(tl<<BN_BITS4)&BN_MASK2h; | ||
283 | th+=t; | ||
284 | |||
285 | if (l < tl) th++; | ||
286 | l-=tl; | ||
287 | if (h < th) | ||
288 | { | ||
289 | h+=d; | ||
290 | q--; | ||
291 | } | ||
292 | h-=th; | ||
293 | |||
294 | if (--count == 0) break; | ||
295 | |||
296 | ret=q<<BN_BITS4; | ||
297 | h=((h<<BN_BITS4)|(l>>BN_BITS4))&BN_MASK2; | ||
298 | l=(l&BN_MASK2l)<<BN_BITS4; | ||
299 | } | ||
300 | ret|=q; | ||
301 | return(ret); | ||
302 | } | ||
303 | #endif | ||
304 | |||
305 | #ifdef BN_LLONG | ||
306 | BN_ULONG bn_add_words(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n) | ||
307 | { | ||
308 | BN_ULLONG ll=0; | ||
309 | |||
310 | bn_check_num(n); | ||
311 | if (n <= 0) return((BN_ULONG)0); | ||
312 | |||
313 | for (;;) | ||
314 | { | ||
315 | ll+=(BN_ULLONG)a[0]+b[0]; | ||
316 | r[0]=(BN_ULONG)ll&BN_MASK2; | ||
317 | ll>>=BN_BITS2; | ||
318 | if (--n <= 0) break; | ||
319 | |||
320 | ll+=(BN_ULLONG)a[1]+b[1]; | ||
321 | r[1]=(BN_ULONG)ll&BN_MASK2; | ||
322 | ll>>=BN_BITS2; | ||
323 | if (--n <= 0) break; | ||
324 | |||
325 | ll+=(BN_ULLONG)a[2]+b[2]; | ||
326 | r[2]=(BN_ULONG)ll&BN_MASK2; | ||
327 | ll>>=BN_BITS2; | ||
328 | if (--n <= 0) break; | ||
329 | |||
330 | ll+=(BN_ULLONG)a[3]+b[3]; | ||
331 | r[3]=(BN_ULONG)ll&BN_MASK2; | ||
332 | ll>>=BN_BITS2; | ||
333 | if (--n <= 0) break; | ||
334 | |||
335 | a+=4; | ||
336 | b+=4; | ||
337 | r+=4; | ||
338 | } | ||
339 | return((BN_ULONG)ll); | ||
340 | } | ||
341 | #else | ||
342 | BN_ULONG bn_add_words(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n) | ||
343 | { | ||
344 | BN_ULONG c,l,t; | ||
345 | |||
346 | bn_check_num(n); | ||
347 | if (n <= 0) return((BN_ULONG)0); | ||
348 | |||
349 | c=0; | ||
350 | for (;;) | ||
351 | { | ||
352 | t=a[0]; | ||
353 | t=(t+c)&BN_MASK2; | ||
354 | c=(t < c); | ||
355 | l=(t+b[0])&BN_MASK2; | ||
356 | c+=(l < t); | ||
357 | r[0]=l; | ||
358 | if (--n <= 0) break; | ||
359 | |||
360 | t=a[1]; | ||
361 | t=(t+c)&BN_MASK2; | ||
362 | c=(t < c); | ||
363 | l=(t+b[1])&BN_MASK2; | ||
364 | c+=(l < t); | ||
365 | r[1]=l; | ||
366 | if (--n <= 0) break; | ||
367 | |||
368 | t=a[2]; | ||
369 | t=(t+c)&BN_MASK2; | ||
370 | c=(t < c); | ||
371 | l=(t+b[2])&BN_MASK2; | ||
372 | c+=(l < t); | ||
373 | r[2]=l; | ||
374 | if (--n <= 0) break; | ||
375 | |||
376 | t=a[3]; | ||
377 | t=(t+c)&BN_MASK2; | ||
378 | c=(t < c); | ||
379 | l=(t+b[3])&BN_MASK2; | ||
380 | c+=(l < t); | ||
381 | r[3]=l; | ||
382 | if (--n <= 0) break; | ||
383 | |||
384 | a+=4; | ||
385 | b+=4; | ||
386 | r+=4; | ||
387 | } | ||
388 | return((BN_ULONG)c); | ||
389 | } | ||
390 | #endif | ||
391 | |||
392 | BN_ULONG bn_sub_words(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n) | ||
393 | { | ||
394 | BN_ULONG t1,t2; | ||
395 | int c=0; | ||
396 | |||
397 | bn_check_num(n); | ||
398 | if (n <= 0) return((BN_ULONG)0); | ||
399 | |||
400 | for (;;) | ||
401 | { | ||
402 | t1=a[0]; t2=b[0]; | ||
403 | r[0]=(t1-t2-c)&BN_MASK2; | ||
404 | if (t1 != t2) c=(t1 < t2); | ||
405 | if (--n <= 0) break; | ||
406 | |||
407 | t1=a[1]; t2=b[1]; | ||
408 | r[1]=(t1-t2-c)&BN_MASK2; | ||
409 | if (t1 != t2) c=(t1 < t2); | ||
410 | if (--n <= 0) break; | ||
411 | |||
412 | t1=a[2]; t2=b[2]; | ||
413 | r[2]=(t1-t2-c)&BN_MASK2; | ||
414 | if (t1 != t2) c=(t1 < t2); | ||
415 | if (--n <= 0) break; | ||
416 | |||
417 | t1=a[3]; t2=b[3]; | ||
418 | r[3]=(t1-t2-c)&BN_MASK2; | ||
419 | if (t1 != t2) c=(t1 < t2); | ||
420 | if (--n <= 0) break; | ||
421 | |||
422 | a+=4; | ||
423 | b+=4; | ||
424 | r+=4; | ||
425 | } | ||
426 | return(c); | ||
427 | } | ||
428 | |||
429 | #ifdef BN_MUL_COMBA | ||
430 | |||
431 | #undef bn_mul_comba8 | ||
432 | #undef bn_mul_comba4 | ||
433 | #undef bn_sqr_comba8 | ||
434 | #undef bn_sqr_comba4 | ||
435 | |||
436 | #ifdef BN_LLONG | ||
437 | #define mul_add_c(a,b,c0,c1,c2) \ | ||
438 | t=(BN_ULLONG)a*b; \ | ||
439 | t1=(BN_ULONG)Lw(t); \ | ||
440 | t2=(BN_ULONG)Hw(t); \ | ||
441 | c0=(c0+t1)&BN_MASK2; if ((c0) < t1) t2++; \ | ||
442 | c1=(c1+t2)&BN_MASK2; if ((c1) < t2) c2++; | ||
443 | |||
444 | #define mul_add_c2(a,b,c0,c1,c2) \ | ||
445 | t=(BN_ULLONG)a*b; \ | ||
446 | tt=(t+t)&BN_MASK; \ | ||
447 | if (tt < t) c2++; \ | ||
448 | t1=(BN_ULONG)Lw(tt); \ | ||
449 | t2=(BN_ULONG)Hw(tt); \ | ||
450 | c0=(c0+t1)&BN_MASK2; \ | ||
451 | if ((c0 < t1) && (((++t2)&BN_MASK2) == 0)) c2++; \ | ||
452 | c1=(c1+t2)&BN_MASK2; if ((c1) < t2) c2++; | ||
453 | |||
454 | #define sqr_add_c(a,i,c0,c1,c2) \ | ||
455 | t=(BN_ULLONG)a[i]*a[i]; \ | ||
456 | t1=(BN_ULONG)Lw(t); \ | ||
457 | t2=(BN_ULONG)Hw(t); \ | ||
458 | c0=(c0+t1)&BN_MASK2; if ((c0) < t1) t2++; \ | ||
459 | c1=(c1+t2)&BN_MASK2; if ((c1) < t2) c2++; | ||
460 | |||
461 | #define sqr_add_c2(a,i,j,c0,c1,c2) \ | ||
462 | mul_add_c2((a)[i],(a)[j],c0,c1,c2) | ||
463 | #else | ||
464 | #define mul_add_c(a,b,c0,c1,c2) \ | ||
465 | t1=LBITS(a); t2=HBITS(a); \ | ||
466 | bl=LBITS(b); bh=HBITS(b); \ | ||
467 | mul64(t1,t2,bl,bh); \ | ||
468 | c0=(c0+t1)&BN_MASK2; if ((c0) < t1) t2++; \ | ||
469 | c1=(c1+t2)&BN_MASK2; if ((c1) < t2) c2++; | ||
470 | |||
471 | #define mul_add_c2(a,b,c0,c1,c2) \ | ||
472 | t1=LBITS(a); t2=HBITS(a); \ | ||
473 | bl=LBITS(b); bh=HBITS(b); \ | ||
474 | mul64(t1,t2,bl,bh); \ | ||
475 | if (t2 & BN_TBIT) c2++; \ | ||
476 | t2=(t2+t2)&BN_MASK2; \ | ||
477 | if (t1 & BN_TBIT) t2++; \ | ||
478 | t1=(t1+t1)&BN_MASK2; \ | ||
479 | c0=(c0+t1)&BN_MASK2; \ | ||
480 | if ((c0 < t1) && (((++t2)&BN_MASK2) == 0)) c2++; \ | ||
481 | c1=(c1+t2)&BN_MASK2; if ((c1) < t2) c2++; | ||
482 | |||
483 | #define sqr_add_c(a,i,c0,c1,c2) \ | ||
484 | sqr64(t1,t2,(a)[i]); \ | ||
485 | c0=(c0+t1)&BN_MASK2; if ((c0) < t1) t2++; \ | ||
486 | c1=(c1+t2)&BN_MASK2; if ((c1) < t2) c2++; | ||
487 | |||
488 | #define sqr_add_c2(a,i,j,c0,c1,c2) \ | ||
489 | mul_add_c2((a)[i],(a)[j],c0,c1,c2) | ||
490 | #endif | ||
491 | |||
492 | void bn_mul_comba8(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b) | ||
493 | { | ||
494 | #ifdef BN_LLONG | ||
495 | BN_ULLONG t; | ||
496 | #else | ||
497 | BN_ULONG bl,bh; | ||
498 | #endif | ||
499 | BN_ULONG t1,t2; | ||
500 | BN_ULONG c1,c2,c3; | ||
501 | |||
502 | c1=0; | ||
503 | c2=0; | ||
504 | c3=0; | ||
505 | mul_add_c(a[0],b[0],c1,c2,c3); | ||
506 | r[0]=c1; | ||
507 | c1=0; | ||
508 | mul_add_c(a[0],b[1],c2,c3,c1); | ||
509 | mul_add_c(a[1],b[0],c2,c3,c1); | ||
510 | r[1]=c2; | ||
511 | c2=0; | ||
512 | mul_add_c(a[2],b[0],c3,c1,c2); | ||
513 | mul_add_c(a[1],b[1],c3,c1,c2); | ||
514 | mul_add_c(a[0],b[2],c3,c1,c2); | ||
515 | r[2]=c3; | ||
516 | c3=0; | ||
517 | mul_add_c(a[0],b[3],c1,c2,c3); | ||
518 | mul_add_c(a[1],b[2],c1,c2,c3); | ||
519 | mul_add_c(a[2],b[1],c1,c2,c3); | ||
520 | mul_add_c(a[3],b[0],c1,c2,c3); | ||
521 | r[3]=c1; | ||
522 | c1=0; | ||
523 | mul_add_c(a[4],b[0],c2,c3,c1); | ||
524 | mul_add_c(a[3],b[1],c2,c3,c1); | ||
525 | mul_add_c(a[2],b[2],c2,c3,c1); | ||
526 | mul_add_c(a[1],b[3],c2,c3,c1); | ||
527 | mul_add_c(a[0],b[4],c2,c3,c1); | ||
528 | r[4]=c2; | ||
529 | c2=0; | ||
530 | mul_add_c(a[0],b[5],c3,c1,c2); | ||
531 | mul_add_c(a[1],b[4],c3,c1,c2); | ||
532 | mul_add_c(a[2],b[3],c3,c1,c2); | ||
533 | mul_add_c(a[3],b[2],c3,c1,c2); | ||
534 | mul_add_c(a[4],b[1],c3,c1,c2); | ||
535 | mul_add_c(a[5],b[0],c3,c1,c2); | ||
536 | r[5]=c3; | ||
537 | c3=0; | ||
538 | mul_add_c(a[6],b[0],c1,c2,c3); | ||
539 | mul_add_c(a[5],b[1],c1,c2,c3); | ||
540 | mul_add_c(a[4],b[2],c1,c2,c3); | ||
541 | mul_add_c(a[3],b[3],c1,c2,c3); | ||
542 | mul_add_c(a[2],b[4],c1,c2,c3); | ||
543 | mul_add_c(a[1],b[5],c1,c2,c3); | ||
544 | mul_add_c(a[0],b[6],c1,c2,c3); | ||
545 | r[6]=c1; | ||
546 | c1=0; | ||
547 | mul_add_c(a[0],b[7],c2,c3,c1); | ||
548 | mul_add_c(a[1],b[6],c2,c3,c1); | ||
549 | mul_add_c(a[2],b[5],c2,c3,c1); | ||
550 | mul_add_c(a[3],b[4],c2,c3,c1); | ||
551 | mul_add_c(a[4],b[3],c2,c3,c1); | ||
552 | mul_add_c(a[5],b[2],c2,c3,c1); | ||
553 | mul_add_c(a[6],b[1],c2,c3,c1); | ||
554 | mul_add_c(a[7],b[0],c2,c3,c1); | ||
555 | r[7]=c2; | ||
556 | c2=0; | ||
557 | mul_add_c(a[7],b[1],c3,c1,c2); | ||
558 | mul_add_c(a[6],b[2],c3,c1,c2); | ||
559 | mul_add_c(a[5],b[3],c3,c1,c2); | ||
560 | mul_add_c(a[4],b[4],c3,c1,c2); | ||
561 | mul_add_c(a[3],b[5],c3,c1,c2); | ||
562 | mul_add_c(a[2],b[6],c3,c1,c2); | ||
563 | mul_add_c(a[1],b[7],c3,c1,c2); | ||
564 | r[8]=c3; | ||
565 | c3=0; | ||
566 | mul_add_c(a[2],b[7],c1,c2,c3); | ||
567 | mul_add_c(a[3],b[6],c1,c2,c3); | ||
568 | mul_add_c(a[4],b[5],c1,c2,c3); | ||
569 | mul_add_c(a[5],b[4],c1,c2,c3); | ||
570 | mul_add_c(a[6],b[3],c1,c2,c3); | ||
571 | mul_add_c(a[7],b[2],c1,c2,c3); | ||
572 | r[9]=c1; | ||
573 | c1=0; | ||
574 | mul_add_c(a[7],b[3],c2,c3,c1); | ||
575 | mul_add_c(a[6],b[4],c2,c3,c1); | ||
576 | mul_add_c(a[5],b[5],c2,c3,c1); | ||
577 | mul_add_c(a[4],b[6],c2,c3,c1); | ||
578 | mul_add_c(a[3],b[7],c2,c3,c1); | ||
579 | r[10]=c2; | ||
580 | c2=0; | ||
581 | mul_add_c(a[4],b[7],c3,c1,c2); | ||
582 | mul_add_c(a[5],b[6],c3,c1,c2); | ||
583 | mul_add_c(a[6],b[5],c3,c1,c2); | ||
584 | mul_add_c(a[7],b[4],c3,c1,c2); | ||
585 | r[11]=c3; | ||
586 | c3=0; | ||
587 | mul_add_c(a[7],b[5],c1,c2,c3); | ||
588 | mul_add_c(a[6],b[6],c1,c2,c3); | ||
589 | mul_add_c(a[5],b[7],c1,c2,c3); | ||
590 | r[12]=c1; | ||
591 | c1=0; | ||
592 | mul_add_c(a[6],b[7],c2,c3,c1); | ||
593 | mul_add_c(a[7],b[6],c2,c3,c1); | ||
594 | r[13]=c2; | ||
595 | c2=0; | ||
596 | mul_add_c(a[7],b[7],c3,c1,c2); | ||
597 | r[14]=c3; | ||
598 | r[15]=c1; | ||
599 | } | ||
600 | |||
601 | void bn_mul_comba4(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b) | ||
602 | { | ||
603 | #ifdef BN_LLONG | ||
604 | BN_ULLONG t; | ||
605 | #else | ||
606 | BN_ULONG bl,bh; | ||
607 | #endif | ||
608 | BN_ULONG t1,t2; | ||
609 | BN_ULONG c1,c2,c3; | ||
610 | |||
611 | c1=0; | ||
612 | c2=0; | ||
613 | c3=0; | ||
614 | mul_add_c(a[0],b[0],c1,c2,c3); | ||
615 | r[0]=c1; | ||
616 | c1=0; | ||
617 | mul_add_c(a[0],b[1],c2,c3,c1); | ||
618 | mul_add_c(a[1],b[0],c2,c3,c1); | ||
619 | r[1]=c2; | ||
620 | c2=0; | ||
621 | mul_add_c(a[2],b[0],c3,c1,c2); | ||
622 | mul_add_c(a[1],b[1],c3,c1,c2); | ||
623 | mul_add_c(a[0],b[2],c3,c1,c2); | ||
624 | r[2]=c3; | ||
625 | c3=0; | ||
626 | mul_add_c(a[0],b[3],c1,c2,c3); | ||
627 | mul_add_c(a[1],b[2],c1,c2,c3); | ||
628 | mul_add_c(a[2],b[1],c1,c2,c3); | ||
629 | mul_add_c(a[3],b[0],c1,c2,c3); | ||
630 | r[3]=c1; | ||
631 | c1=0; | ||
632 | mul_add_c(a[3],b[1],c2,c3,c1); | ||
633 | mul_add_c(a[2],b[2],c2,c3,c1); | ||
634 | mul_add_c(a[1],b[3],c2,c3,c1); | ||
635 | r[4]=c2; | ||
636 | c2=0; | ||
637 | mul_add_c(a[2],b[3],c3,c1,c2); | ||
638 | mul_add_c(a[3],b[2],c3,c1,c2); | ||
639 | r[5]=c3; | ||
640 | c3=0; | ||
641 | mul_add_c(a[3],b[3],c1,c2,c3); | ||
642 | r[6]=c1; | ||
643 | r[7]=c2; | ||
644 | } | ||
645 | |||
646 | void bn_sqr_comba8(BN_ULONG *r, BN_ULONG *a) | ||
647 | { | ||
648 | #ifdef BN_LLONG | ||
649 | BN_ULLONG t,tt; | ||
650 | #else | ||
651 | BN_ULONG bl,bh; | ||
652 | #endif | ||
653 | BN_ULONG t1,t2; | ||
654 | BN_ULONG c1,c2,c3; | ||
655 | |||
656 | c1=0; | ||
657 | c2=0; | ||
658 | c3=0; | ||
659 | sqr_add_c(a,0,c1,c2,c3); | ||
660 | r[0]=c1; | ||
661 | c1=0; | ||
662 | sqr_add_c2(a,1,0,c2,c3,c1); | ||
663 | r[1]=c2; | ||
664 | c2=0; | ||
665 | sqr_add_c(a,1,c3,c1,c2); | ||
666 | sqr_add_c2(a,2,0,c3,c1,c2); | ||
667 | r[2]=c3; | ||
668 | c3=0; | ||
669 | sqr_add_c2(a,3,0,c1,c2,c3); | ||
670 | sqr_add_c2(a,2,1,c1,c2,c3); | ||
671 | r[3]=c1; | ||
672 | c1=0; | ||
673 | sqr_add_c(a,2,c2,c3,c1); | ||
674 | sqr_add_c2(a,3,1,c2,c3,c1); | ||
675 | sqr_add_c2(a,4,0,c2,c3,c1); | ||
676 | r[4]=c2; | ||
677 | c2=0; | ||
678 | sqr_add_c2(a,5,0,c3,c1,c2); | ||
679 | sqr_add_c2(a,4,1,c3,c1,c2); | ||
680 | sqr_add_c2(a,3,2,c3,c1,c2); | ||
681 | r[5]=c3; | ||
682 | c3=0; | ||
683 | sqr_add_c(a,3,c1,c2,c3); | ||
684 | sqr_add_c2(a,4,2,c1,c2,c3); | ||
685 | sqr_add_c2(a,5,1,c1,c2,c3); | ||
686 | sqr_add_c2(a,6,0,c1,c2,c3); | ||
687 | r[6]=c1; | ||
688 | c1=0; | ||
689 | sqr_add_c2(a,7,0,c2,c3,c1); | ||
690 | sqr_add_c2(a,6,1,c2,c3,c1); | ||
691 | sqr_add_c2(a,5,2,c2,c3,c1); | ||
692 | sqr_add_c2(a,4,3,c2,c3,c1); | ||
693 | r[7]=c2; | ||
694 | c2=0; | ||
695 | sqr_add_c(a,4,c3,c1,c2); | ||
696 | sqr_add_c2(a,5,3,c3,c1,c2); | ||
697 | sqr_add_c2(a,6,2,c3,c1,c2); | ||
698 | sqr_add_c2(a,7,1,c3,c1,c2); | ||
699 | r[8]=c3; | ||
700 | c3=0; | ||
701 | sqr_add_c2(a,7,2,c1,c2,c3); | ||
702 | sqr_add_c2(a,6,3,c1,c2,c3); | ||
703 | sqr_add_c2(a,5,4,c1,c2,c3); | ||
704 | r[9]=c1; | ||
705 | c1=0; | ||
706 | sqr_add_c(a,5,c2,c3,c1); | ||
707 | sqr_add_c2(a,6,4,c2,c3,c1); | ||
708 | sqr_add_c2(a,7,3,c2,c3,c1); | ||
709 | r[10]=c2; | ||
710 | c2=0; | ||
711 | sqr_add_c2(a,7,4,c3,c1,c2); | ||
712 | sqr_add_c2(a,6,5,c3,c1,c2); | ||
713 | r[11]=c3; | ||
714 | c3=0; | ||
715 | sqr_add_c(a,6,c1,c2,c3); | ||
716 | sqr_add_c2(a,7,5,c1,c2,c3); | ||
717 | r[12]=c1; | ||
718 | c1=0; | ||
719 | sqr_add_c2(a,7,6,c2,c3,c1); | ||
720 | r[13]=c2; | ||
721 | c2=0; | ||
722 | sqr_add_c(a,7,c3,c1,c2); | ||
723 | r[14]=c3; | ||
724 | r[15]=c1; | ||
725 | } | ||
726 | |||
727 | void bn_sqr_comba4(BN_ULONG *r, BN_ULONG *a) | ||
728 | { | ||
729 | #ifdef BN_LLONG | ||
730 | BN_ULLONG t,tt; | ||
731 | #else | ||
732 | BN_ULONG bl,bh; | ||
733 | #endif | ||
734 | BN_ULONG t1,t2; | ||
735 | BN_ULONG c1,c2,c3; | ||
736 | |||
737 | c1=0; | ||
738 | c2=0; | ||
739 | c3=0; | ||
740 | sqr_add_c(a,0,c1,c2,c3); | ||
741 | r[0]=c1; | ||
742 | c1=0; | ||
743 | sqr_add_c2(a,1,0,c2,c3,c1); | ||
744 | r[1]=c2; | ||
745 | c2=0; | ||
746 | sqr_add_c(a,1,c3,c1,c2); | ||
747 | sqr_add_c2(a,2,0,c3,c1,c2); | ||
748 | r[2]=c3; | ||
749 | c3=0; | ||
750 | sqr_add_c2(a,3,0,c1,c2,c3); | ||
751 | sqr_add_c2(a,2,1,c1,c2,c3); | ||
752 | r[3]=c1; | ||
753 | c1=0; | ||
754 | sqr_add_c(a,2,c2,c3,c1); | ||
755 | sqr_add_c2(a,3,1,c2,c3,c1); | ||
756 | r[4]=c2; | ||
757 | c2=0; | ||
758 | sqr_add_c2(a,3,2,c3,c1,c2); | ||
759 | r[5]=c3; | ||
760 | c3=0; | ||
761 | sqr_add_c(a,3,c1,c2,c3); | ||
762 | r[6]=c1; | ||
763 | r[7]=c2; | ||
764 | } | ||
765 | #else | ||
766 | |||
767 | /* hmm... is it faster just to do a multiply? */ | ||
768 | #undef bn_sqr_comba4 | ||
769 | void bn_sqr_comba4(BN_ULONG *r, BN_ULONG *a) | ||
770 | { | ||
771 | BN_ULONG t[8]; | ||
772 | bn_sqr_normal(r,a,4,t); | ||
773 | } | ||
774 | |||
775 | #undef bn_sqr_comba8 | ||
776 | void bn_sqr_comba8(BN_ULONG *r, BN_ULONG *a) | ||
777 | { | ||
778 | BN_ULONG t[16]; | ||
779 | bn_sqr_normal(r,a,8,t); | ||
780 | } | ||
781 | |||
782 | void bn_mul_comba4(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b) | ||
783 | { | ||
784 | r[4]=bn_mul_words( &(r[0]),a,4,b[0]); | ||
785 | r[5]=bn_mul_add_words(&(r[1]),a,4,b[1]); | ||
786 | r[6]=bn_mul_add_words(&(r[2]),a,4,b[2]); | ||
787 | r[7]=bn_mul_add_words(&(r[3]),a,4,b[3]); | ||
788 | } | ||
789 | |||
790 | void bn_mul_comba8(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b) | ||
791 | { | ||
792 | r[ 8]=bn_mul_words( &(r[0]),a,8,b[0]); | ||
793 | r[ 9]=bn_mul_add_words(&(r[1]),a,8,b[1]); | ||
794 | r[10]=bn_mul_add_words(&(r[2]),a,8,b[2]); | ||
795 | r[11]=bn_mul_add_words(&(r[3]),a,8,b[3]); | ||
796 | r[12]=bn_mul_add_words(&(r[4]),a,8,b[4]); | ||
797 | r[13]=bn_mul_add_words(&(r[5]),a,8,b[5]); | ||
798 | r[14]=bn_mul_add_words(&(r[6]),a,8,b[6]); | ||
799 | r[15]=bn_mul_add_words(&(r[7]),a,8,b[7]); | ||
800 | } | ||
801 | |||
802 | #endif /* BN_COMBA */ | ||
diff --git a/src/lib/libcrypto/bn/bn_ctx.c b/src/lib/libcrypto/bn/bn_ctx.c new file mode 100644 index 0000000000..46132fd180 --- /dev/null +++ b/src/lib/libcrypto/bn/bn_ctx.c | |||
@@ -0,0 +1,144 @@ | |||
1 | /* crypto/bn/bn_ctx.c */ | ||
2 | /* Written by Ulf Moeller for the OpenSSL project. */ | ||
3 | /* ==================================================================== | ||
4 | * Copyright (c) 1998-2000 The OpenSSL Project. All rights reserved. | ||
5 | * | ||
6 | * Redistribution and use in source and binary forms, with or without | ||
7 | * modification, are permitted provided that the following conditions | ||
8 | * are met: | ||
9 | * | ||
10 | * 1. Redistributions of source code must retain the above copyright | ||
11 | * notice, this list of conditions and the following disclaimer. | ||
12 | * | ||
13 | * 2. Redistributions in binary form must reproduce the above copyright | ||
14 | * notice, this list of conditions and the following disclaimer in | ||
15 | * the documentation and/or other materials provided with the | ||
16 | * distribution. | ||
17 | * | ||
18 | * 3. All advertising materials mentioning features or use of this | ||
19 | * software must display the following acknowledgment: | ||
20 | * "This product includes software developed by the OpenSSL Project | ||
21 | * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" | ||
22 | * | ||
23 | * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to | ||
24 | * endorse or promote products derived from this software without | ||
25 | * prior written permission. For written permission, please contact | ||
26 | * openssl-core@openssl.org. | ||
27 | * | ||
28 | * 5. Products derived from this software may not be called "OpenSSL" | ||
29 | * nor may "OpenSSL" appear in their names without prior written | ||
30 | * permission of the OpenSSL Project. | ||
31 | * | ||
32 | * 6. Redistributions of any form whatsoever must retain the following | ||
33 | * acknowledgment: | ||
34 | * "This product includes software developed by the OpenSSL Project | ||
35 | * for use in the OpenSSL Toolkit (http://www.openssl.org/)" | ||
36 | * | ||
37 | * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY | ||
38 | * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
39 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | ||
40 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR | ||
41 | * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
42 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
43 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
44 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
45 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
46 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
47 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED | ||
48 | * OF THE POSSIBILITY OF SUCH DAMAGE. | ||
49 | * ==================================================================== | ||
50 | * | ||
51 | * This product includes cryptographic software written by Eric Young | ||
52 | * (eay@cryptsoft.com). This product includes software written by Tim | ||
53 | * Hudson (tjh@cryptsoft.com). | ||
54 | * | ||
55 | */ | ||
56 | |||
57 | #ifndef BN_CTX_DEBUG | ||
58 | # undef NDEBUG /* avoid conflicting definitions */ | ||
59 | # define NDEBUG | ||
60 | #endif | ||
61 | |||
62 | #include <stdio.h> | ||
63 | #include <assert.h> | ||
64 | #include "cryptlib.h" | ||
65 | #include <openssl/bn.h> | ||
66 | |||
67 | |||
68 | BN_CTX *BN_CTX_new(void) | ||
69 | { | ||
70 | BN_CTX *ret; | ||
71 | |||
72 | ret=(BN_CTX *)Malloc(sizeof(BN_CTX)); | ||
73 | if (ret == NULL) | ||
74 | { | ||
75 | BNerr(BN_F_BN_CTX_NEW,ERR_R_MALLOC_FAILURE); | ||
76 | return(NULL); | ||
77 | } | ||
78 | |||
79 | BN_CTX_init(ret); | ||
80 | ret->flags=BN_FLG_MALLOCED; | ||
81 | return(ret); | ||
82 | } | ||
83 | |||
84 | void BN_CTX_init(BN_CTX *ctx) | ||
85 | { | ||
86 | int i; | ||
87 | ctx->tos = 0; | ||
88 | ctx->flags = 0; | ||
89 | ctx->depth = 0; | ||
90 | ctx->too_many = 0; | ||
91 | for (i = 0; i < BN_CTX_NUM; i++) | ||
92 | BN_init(&(ctx->bn[i])); | ||
93 | } | ||
94 | |||
95 | void BN_CTX_free(BN_CTX *ctx) | ||
96 | { | ||
97 | int i; | ||
98 | |||
99 | if (ctx == NULL) return; | ||
100 | assert(ctx->depth == 0); | ||
101 | |||
102 | for (i=0; i < BN_CTX_NUM; i++) | ||
103 | BN_clear_free(&(ctx->bn[i])); | ||
104 | if (ctx->flags & BN_FLG_MALLOCED) | ||
105 | Free(ctx); | ||
106 | } | ||
107 | |||
108 | void BN_CTX_start(BN_CTX *ctx) | ||
109 | { | ||
110 | if (ctx->depth < BN_CTX_NUM_POS) | ||
111 | ctx->pos[ctx->depth] = ctx->tos; | ||
112 | ctx->depth++; | ||
113 | } | ||
114 | |||
115 | BIGNUM *BN_CTX_get(BN_CTX *ctx) | ||
116 | { | ||
117 | if (ctx->depth > BN_CTX_NUM_POS || ctx->tos >= BN_CTX_NUM) | ||
118 | { | ||
119 | if (!ctx->too_many) | ||
120 | { | ||
121 | BNerr(BN_F_BN_CTX_GET,BN_R_TOO_MANY_TEMPORARY_VARIABLES); | ||
122 | /* disable error code until BN_CTX_end is called: */ | ||
123 | ctx->too_many = 1; | ||
124 | } | ||
125 | return NULL; | ||
126 | } | ||
127 | return (&(ctx->bn[ctx->tos++])); | ||
128 | } | ||
129 | |||
130 | void BN_CTX_end(BN_CTX *ctx) | ||
131 | { | ||
132 | if (ctx == NULL) return; | ||
133 | assert(ctx->depth > 0); | ||
134 | if (ctx->depth == 0) | ||
135 | /* should never happen, but we can tolerate it if not in | ||
136 | * debug mode (could be a 'goto err' in the calling function | ||
137 | * before BN_CTX_start was reached) */ | ||
138 | BN_CTX_start(ctx); | ||
139 | |||
140 | ctx->too_many = 0; | ||
141 | ctx->depth--; | ||
142 | if (ctx->depth < BN_CTX_NUM_POS) | ||
143 | ctx->tos = ctx->pos[ctx->depth]; | ||
144 | } | ||
diff --git a/src/lib/libcrypto/bn/bn_exp2.c b/src/lib/libcrypto/bn/bn_exp2.c new file mode 100644 index 0000000000..1132d53365 --- /dev/null +++ b/src/lib/libcrypto/bn/bn_exp2.c | |||
@@ -0,0 +1,195 @@ | |||
1 | #include <stdio.h> | ||
2 | #include "cryptlib.h" | ||
3 | #include "bn_lcl.h" | ||
4 | |||
5 | /* I've done some timing with different table sizes. | ||
6 | * The main hassle is that even with bits set at 3, this requires | ||
7 | * 63 BIGNUMs to store the pre-calculated values. | ||
8 | * 512 1024 | ||
9 | * bits=1 75.4% 79.4% | ||
10 | * bits=2 61.2% 62.4% | ||
11 | * bits=3 61.3% 59.3% | ||
12 | * The lack of speed improvment is also a function of the pre-calculation | ||
13 | * which could be removed. | ||
14 | */ | ||
15 | #define EXP2_TABLE_BITS 2 /* 1 2 3 4 5 */ | ||
16 | #define EXP2_TABLE_SIZE 4 /* 2 4 8 16 32 */ | ||
17 | |||
18 | int BN_mod_exp2_mont(BIGNUM *rr, BIGNUM *a1, BIGNUM *p1, BIGNUM *a2, | ||
19 | BIGNUM *p2, BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *in_mont) | ||
20 | { | ||
21 | int i,j,k,bits,bits1,bits2,ret=0,wstart,wend,window,xvalue,yvalue; | ||
22 | int start=1,ts=0,x,y; | ||
23 | BIGNUM *d,*aa1,*aa2,*r; | ||
24 | BIGNUM val[EXP2_TABLE_SIZE][EXP2_TABLE_SIZE]; | ||
25 | BN_MONT_CTX *mont=NULL; | ||
26 | |||
27 | bn_check_top(a1); | ||
28 | bn_check_top(p1); | ||
29 | bn_check_top(a2); | ||
30 | bn_check_top(p2); | ||
31 | bn_check_top(m); | ||
32 | |||
33 | if (!(m->d[0] & 1)) | ||
34 | { | ||
35 | BNerr(BN_F_BN_MOD_EXP_MONT,BN_R_CALLED_WITH_EVEN_MODULUS); | ||
36 | return(0); | ||
37 | } | ||
38 | d= &(ctx->bn[ctx->tos++]); | ||
39 | r= &(ctx->bn[ctx->tos++]); | ||
40 | bits1=BN_num_bits(p1); | ||
41 | bits2=BN_num_bits(p2); | ||
42 | if ((bits1 == 0) && (bits2 == 0)) | ||
43 | { | ||
44 | BN_one(r); | ||
45 | return(1); | ||
46 | } | ||
47 | bits=(bits1 > bits2)?bits1:bits2; | ||
48 | |||
49 | /* If this is not done, things will break in the montgomery | ||
50 | * part */ | ||
51 | |||
52 | if (in_mont != NULL) | ||
53 | mont=in_mont; | ||
54 | else | ||
55 | { | ||
56 | if ((mont=BN_MONT_CTX_new()) == NULL) goto err; | ||
57 | if (!BN_MONT_CTX_set(mont,m,ctx)) goto err; | ||
58 | } | ||
59 | |||
60 | BN_init(&(val[0][0])); | ||
61 | BN_init(&(val[1][1])); | ||
62 | BN_init(&(val[0][1])); | ||
63 | BN_init(&(val[1][0])); | ||
64 | ts=1; | ||
65 | if (BN_ucmp(a1,m) >= 0) | ||
66 | { | ||
67 | BN_mod(&(val[1][0]),a1,m,ctx); | ||
68 | aa1= &(val[1][0]); | ||
69 | } | ||
70 | else | ||
71 | aa1=a1; | ||
72 | if (BN_ucmp(a2,m) >= 0) | ||
73 | { | ||
74 | BN_mod(&(val[0][1]),a2,m,ctx); | ||
75 | aa2= &(val[0][1]); | ||
76 | } | ||
77 | else | ||
78 | aa2=a2; | ||
79 | if (!BN_to_montgomery(&(val[1][0]),aa1,mont,ctx)) goto err; | ||
80 | if (!BN_to_montgomery(&(val[0][1]),aa2,mont,ctx)) goto err; | ||
81 | if (!BN_mod_mul_montgomery(&(val[1][1]), | ||
82 | &(val[1][0]),&(val[0][1]),mont,ctx)) | ||
83 | goto err; | ||
84 | |||
85 | #if 0 | ||
86 | if (bits <= 20) /* This is probably 3 or 0x10001, so just do singles */ | ||
87 | window=1; | ||
88 | else if (bits > 250) | ||
89 | window=5; /* max size of window */ | ||
90 | else if (bits >= 120) | ||
91 | window=4; | ||
92 | else | ||
93 | window=3; | ||
94 | #else | ||
95 | window=EXP2_TABLE_BITS; | ||
96 | #endif | ||
97 | |||
98 | k=1<<window; | ||
99 | for (x=0; x<k; x++) | ||
100 | { | ||
101 | if (x >= 2) | ||
102 | { | ||
103 | BN_init(&(val[x][0])); | ||
104 | BN_init(&(val[x][1])); | ||
105 | if (!BN_mod_mul_montgomery(&(val[x][0]), | ||
106 | &(val[1][0]),&(val[x-1][0]),mont,ctx)) goto err; | ||
107 | if (!BN_mod_mul_montgomery(&(val[x][1]), | ||
108 | &(val[1][0]),&(val[x-1][1]),mont,ctx)) goto err; | ||
109 | } | ||
110 | for (y=2; y<k; y++) | ||
111 | { | ||
112 | BN_init(&(val[x][y])); | ||
113 | if (!BN_mod_mul_montgomery(&(val[x][y]), | ||
114 | &(val[x][y-1]),&(val[0][1]),mont,ctx)) | ||
115 | goto err; | ||
116 | } | ||
117 | } | ||
118 | ts=k; | ||
119 | |||
120 | start=1; /* This is used to avoid multiplication etc | ||
121 | * when there is only the value '1' in the | ||
122 | * buffer. */ | ||
123 | xvalue=0; /* The 'x value' of the window */ | ||
124 | yvalue=0; /* The 'y value' of the window */ | ||
125 | wstart=bits-1; /* The top bit of the window */ | ||
126 | wend=0; /* The bottom bit of the window */ | ||
127 | |||
128 | if (!BN_to_montgomery(r,BN_value_one(),mont,ctx)) goto err; | ||
129 | for (;;) | ||
130 | { | ||
131 | xvalue=BN_is_bit_set(p1,wstart); | ||
132 | yvalue=BN_is_bit_set(p2,wstart); | ||
133 | if (!(xvalue || yvalue)) | ||
134 | { | ||
135 | if (!start) | ||
136 | { | ||
137 | if (!BN_mod_mul_montgomery(r,r,r,mont,ctx)) | ||
138 | goto err; | ||
139 | } | ||
140 | wstart--; | ||
141 | if (wstart < 0) break; | ||
142 | continue; | ||
143 | } | ||
144 | /* We now have wstart on a 'set' bit, we now need to work out | ||
145 | * how bit a window to do. To do this we need to scan | ||
146 | * forward until the last set bit before the end of the | ||
147 | * window */ | ||
148 | j=wstart; | ||
149 | /* xvalue=BN_is_bit_set(p1,wstart); already set */ | ||
150 | /* yvalue=BN_is_bit_set(p1,wstart); already set */ | ||
151 | wend=0; | ||
152 | for (i=1; i<window; i++) | ||
153 | { | ||
154 | if (wstart-i < 0) break; | ||
155 | xvalue+=xvalue; | ||
156 | xvalue|=BN_is_bit_set(p1,wstart-i); | ||
157 | yvalue+=yvalue; | ||
158 | yvalue|=BN_is_bit_set(p2,wstart-i); | ||
159 | } | ||
160 | |||
161 | /* i is the size of the current window */ | ||
162 | /* add the 'bytes above' */ | ||
163 | if (!start) | ||
164 | for (j=0; j<i; j++) | ||
165 | { | ||
166 | if (!BN_mod_mul_montgomery(r,r,r,mont,ctx)) | ||
167 | goto err; | ||
168 | } | ||
169 | |||
170 | /* wvalue will be an odd number < 2^window */ | ||
171 | if (xvalue || yvalue) | ||
172 | { | ||
173 | if (!BN_mod_mul_montgomery(r,r,&(val[xvalue][yvalue]), | ||
174 | mont,ctx)) goto err; | ||
175 | } | ||
176 | |||
177 | /* move the 'window' down further */ | ||
178 | wstart-=i; | ||
179 | start=0; | ||
180 | if (wstart < 0) break; | ||
181 | } | ||
182 | BN_from_montgomery(rr,r,mont,ctx); | ||
183 | ret=1; | ||
184 | err: | ||
185 | if ((in_mont == NULL) && (mont != NULL)) BN_MONT_CTX_free(mont); | ||
186 | ctx->tos-=2; | ||
187 | for (i=0; i<ts; i++) | ||
188 | { | ||
189 | for (j=0; j<ts; j++) | ||
190 | { | ||
191 | BN_clear_free(&(val[i][j])); | ||
192 | } | ||
193 | } | ||
194 | return(ret); | ||
195 | } | ||
diff --git a/src/lib/libcrypto/bn/bn_kron.c b/src/lib/libcrypto/bn/bn_kron.c new file mode 100644 index 0000000000..49f75594ae --- /dev/null +++ b/src/lib/libcrypto/bn/bn_kron.c | |||
@@ -0,0 +1,182 @@ | |||
1 | /* crypto/bn/bn_kron.c */ | ||
2 | /* ==================================================================== | ||
3 | * Copyright (c) 1998-2000 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 "bn_lcl.h" | ||
57 | |||
58 | |||
59 | /* least significant word */ | ||
60 | #define BN_lsw(n) (((n)->top == 0) ? (BN_ULONG) 0 : (n)->d[0]) | ||
61 | |||
62 | /* Returns -2 for errors because both -1 and 0 are valid results. */ | ||
63 | int BN_kronecker(const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx) | ||
64 | { | ||
65 | int i; | ||
66 | int ret = -2; /* avoid 'uninitialized' warning */ | ||
67 | int err = 0; | ||
68 | BIGNUM *A, *B, *tmp; | ||
69 | /* In 'tab', only odd-indexed entries are relevant: | ||
70 | * For any odd BIGNUM n, | ||
71 | * tab[BN_lsw(n) & 7] | ||
72 | * is $(-1)^{(n^2-1)/8}$ (using TeX notation). | ||
73 | * Note that the sign of n does not matter. | ||
74 | */ | ||
75 | static const int tab[8] = {0, 1, 0, -1, 0, -1, 0, 1}; | ||
76 | |||
77 | BN_CTX_start(ctx); | ||
78 | A = BN_CTX_get(ctx); | ||
79 | B = BN_CTX_get(ctx); | ||
80 | if (B == NULL) goto end; | ||
81 | |||
82 | err = !BN_copy(A, a); | ||
83 | if (err) goto end; | ||
84 | err = !BN_copy(B, b); | ||
85 | if (err) goto end; | ||
86 | |||
87 | /* | ||
88 | * Kronecker symbol, imlemented according to Henri Cohen, | ||
89 | * "A Course in Computational Algebraic Number Theory" | ||
90 | * (algorithm 1.4.10). | ||
91 | */ | ||
92 | |||
93 | /* Cohen's step 1: */ | ||
94 | |||
95 | if (BN_is_zero(B)) | ||
96 | { | ||
97 | ret = BN_abs_is_word(A, 1); | ||
98 | goto end; | ||
99 | } | ||
100 | |||
101 | /* Cohen's step 2: */ | ||
102 | |||
103 | if (!BN_is_odd(A) && !BN_is_odd(B)) | ||
104 | { | ||
105 | ret = 0; | ||
106 | goto end; | ||
107 | } | ||
108 | |||
109 | /* now B is non-zero */ | ||
110 | i = 0; | ||
111 | while (!BN_is_bit_set(B, i)) | ||
112 | i++; | ||
113 | err = !BN_rshift(B, B, i); | ||
114 | if (err) goto end; | ||
115 | if (i & 1) | ||
116 | { | ||
117 | /* i is odd */ | ||
118 | /* (thus B was even, thus A must be odd!) */ | ||
119 | |||
120 | /* set 'ret' to $(-1)^{(A^2-1)/8}$ */ | ||
121 | ret = tab[BN_lsw(A) & 7]; | ||
122 | } | ||
123 | else | ||
124 | { | ||
125 | /* i is even */ | ||
126 | ret = 1; | ||
127 | } | ||
128 | |||
129 | if (B->neg) | ||
130 | { | ||
131 | B->neg = 0; | ||
132 | if (A->neg) | ||
133 | ret = -ret; | ||
134 | } | ||
135 | |||
136 | /* now B is positive and odd, so what remains to be done is | ||
137 | * to compute the Jacobi symbol (A/B) and multiply it by 'ret' */ | ||
138 | |||
139 | while (1) | ||
140 | { | ||
141 | /* Cohen's step 3: */ | ||
142 | |||
143 | /* B is positive and odd */ | ||
144 | |||
145 | if (BN_is_zero(A)) | ||
146 | { | ||
147 | ret = BN_is_one(B) ? ret : 0; | ||
148 | goto end; | ||
149 | } | ||
150 | |||
151 | /* now A is non-zero */ | ||
152 | i = 0; | ||
153 | while (!BN_is_bit_set(A, i)) | ||
154 | i++; | ||
155 | err = !BN_rshift(A, A, i); | ||
156 | if (err) goto end; | ||
157 | if (i & 1) | ||
158 | { | ||
159 | /* i is odd */ | ||
160 | /* multiply 'ret' by $(-1)^{(B^2-1)/8}$ */ | ||
161 | ret = ret * tab[BN_lsw(B) & 7]; | ||
162 | } | ||
163 | |||
164 | /* Cohen's step 4: */ | ||
165 | /* multiply 'ret' by $(-1)^{(A-1)(B-1)/4}$ */ | ||
166 | if ((A->neg ? ~BN_lsw(A) : BN_lsw(A)) & BN_lsw(B) & 2) | ||
167 | ret = -ret; | ||
168 | |||
169 | /* (A, B) := (B mod |A|, |A|) */ | ||
170 | err = !BN_nnmod(B, B, A, ctx); | ||
171 | if (err) goto end; | ||
172 | tmp = A; A = B; B = tmp; | ||
173 | tmp->neg = 0; | ||
174 | } | ||
175 | |||
176 | end: | ||
177 | BN_CTX_end(ctx); | ||
178 | if (err) | ||
179 | return -2; | ||
180 | else | ||
181 | return ret; | ||
182 | } | ||
diff --git a/src/lib/libcrypto/bn/bn_sqrt.c b/src/lib/libcrypto/bn/bn_sqrt.c new file mode 100644 index 0000000000..e2a1105dc8 --- /dev/null +++ b/src/lib/libcrypto/bn/bn_sqrt.c | |||
@@ -0,0 +1,387 @@ | |||
1 | /* crypto/bn/bn_mod.c */ | ||
2 | /* Written by Lenka Fibikova <fibikova@exp-math.uni-essen.de> | ||
3 | * and Bodo Moeller for the OpenSSL project. */ | ||
4 | /* ==================================================================== | ||
5 | * Copyright (c) 1998-2000 The OpenSSL Project. All rights reserved. | ||
6 | * | ||
7 | * Redistribution and use in source and binary forms, with or without | ||
8 | * modification, are permitted provided that the following conditions | ||
9 | * are met: | ||
10 | * | ||
11 | * 1. Redistributions of source code must retain the above copyright | ||
12 | * notice, this list of conditions and the following disclaimer. | ||
13 | * | ||
14 | * 2. Redistributions in binary form must reproduce the above copyright | ||
15 | * notice, this list of conditions and the following disclaimer in | ||
16 | * the documentation and/or other materials provided with the | ||
17 | * distribution. | ||
18 | * | ||
19 | * 3. All advertising materials mentioning features or use of this | ||
20 | * software must display the following acknowledgment: | ||
21 | * "This product includes software developed by the OpenSSL Project | ||
22 | * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" | ||
23 | * | ||
24 | * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to | ||
25 | * endorse or promote products derived from this software without | ||
26 | * prior written permission. For written permission, please contact | ||
27 | * openssl-core@openssl.org. | ||
28 | * | ||
29 | * 5. Products derived from this software may not be called "OpenSSL" | ||
30 | * nor may "OpenSSL" appear in their names without prior written | ||
31 | * permission of the OpenSSL Project. | ||
32 | * | ||
33 | * 6. Redistributions of any form whatsoever must retain the following | ||
34 | * acknowledgment: | ||
35 | * "This product includes software developed by the OpenSSL Project | ||
36 | * for use in the OpenSSL Toolkit (http://www.openssl.org/)" | ||
37 | * | ||
38 | * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY | ||
39 | * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
40 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | ||
41 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR | ||
42 | * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
43 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
44 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
45 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
46 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
47 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
48 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED | ||
49 | * OF THE POSSIBILITY OF SUCH DAMAGE. | ||
50 | * ==================================================================== | ||
51 | * | ||
52 | * This product includes cryptographic software written by Eric Young | ||
53 | * (eay@cryptsoft.com). This product includes software written by Tim | ||
54 | * Hudson (tjh@cryptsoft.com). | ||
55 | * | ||
56 | */ | ||
57 | |||
58 | #include "cryptlib.h" | ||
59 | #include "bn_lcl.h" | ||
60 | |||
61 | |||
62 | BIGNUM *BN_mod_sqrt(BIGNUM *in, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx) | ||
63 | /* Returns 'ret' such that | ||
64 | * ret^2 == a (mod p), | ||
65 | * using the Tonelli/Shanks algorithm (cf. Henri Cohen, "A Course | ||
66 | * in Algebraic Computational Number Theory", algorithm 1.5.1). | ||
67 | * 'p' must be prime! | ||
68 | * If 'a' is not a square, this is not necessarily detected by | ||
69 | * the algorithms; a bogus result must be expected in this case. | ||
70 | */ | ||
71 | { | ||
72 | BIGNUM *ret = in; | ||
73 | int err = 1; | ||
74 | int r; | ||
75 | BIGNUM *b, *q, *t, *x, *y; | ||
76 | int e, i, j; | ||
77 | |||
78 | if (!BN_is_odd(p) || BN_abs_is_word(p, 1)) | ||
79 | { | ||
80 | if (BN_abs_is_word(p, 2)) | ||
81 | { | ||
82 | if (ret == NULL) | ||
83 | ret = BN_new(); | ||
84 | if (ret == NULL) | ||
85 | goto end; | ||
86 | if (!BN_set_word(ret, BN_is_bit_set(a, 0))) | ||
87 | { | ||
88 | BN_free(ret); | ||
89 | return NULL; | ||
90 | } | ||
91 | return ret; | ||
92 | } | ||
93 | |||
94 | BNerr(BN_F_BN_MOD_SQRT, BN_R_P_IS_NOT_PRIME); | ||
95 | return(NULL); | ||
96 | } | ||
97 | |||
98 | if (BN_is_zero(a) || BN_is_one(a)) | ||
99 | { | ||
100 | if (ret == NULL) | ||
101 | ret = BN_new(); | ||
102 | if (ret == NULL) | ||
103 | goto end; | ||
104 | if (!BN_set_word(ret, BN_is_one(a))) | ||
105 | { | ||
106 | BN_free(ret); | ||
107 | return NULL; | ||
108 | } | ||
109 | return ret; | ||
110 | } | ||
111 | |||
112 | #if 0 /* if BN_mod_sqrt is used with correct input, this just wastes time */ | ||
113 | r = BN_kronecker(a, p, ctx); | ||
114 | if (r < -1) return NULL; | ||
115 | if (r == -1) | ||
116 | { | ||
117 | BNerr(BN_F_BN_MOD_SQRT, BN_R_NOT_A_SQUARE); | ||
118 | return(NULL); | ||
119 | } | ||
120 | #endif | ||
121 | |||
122 | BN_CTX_start(ctx); | ||
123 | b = BN_CTX_get(ctx); | ||
124 | q = BN_CTX_get(ctx); | ||
125 | t = BN_CTX_get(ctx); | ||
126 | x = BN_CTX_get(ctx); | ||
127 | y = BN_CTX_get(ctx); | ||
128 | if (y == NULL) goto end; | ||
129 | |||
130 | if (ret == NULL) | ||
131 | ret = BN_new(); | ||
132 | if (ret == NULL) goto end; | ||
133 | |||
134 | /* now write |p| - 1 as 2^e*q where q is odd */ | ||
135 | e = 1; | ||
136 | while (!BN_is_bit_set(p, e)) | ||
137 | e++; | ||
138 | /* we'll set q later (if needed) */ | ||
139 | |||
140 | if (e == 1) | ||
141 | { | ||
142 | /* The easy case: (|p|-1)/2 is odd, so 2 has an inverse | ||
143 | * modulo (|p|-1)/2, and square roots can be computed | ||
144 | * directly by modular exponentiation. | ||
145 | * We have | ||
146 | * 2 * (|p|+1)/4 == 1 (mod (|p|-1)/2), | ||
147 | * so we can use exponent (|p|+1)/4, i.e. (|p|-3)/4 + 1. | ||
148 | */ | ||
149 | if (!BN_rshift(q, p, 2)) goto end; | ||
150 | q->neg = 0; | ||
151 | if (!BN_add_word(q, 1)) goto end; | ||
152 | if (!BN_mod_exp(ret, a, q, p, ctx)) goto end; | ||
153 | err = 0; | ||
154 | goto end; | ||
155 | } | ||
156 | |||
157 | if (e == 2) | ||
158 | { | ||
159 | /* |p| == 5 (mod 8) | ||
160 | * | ||
161 | * In this case 2 is always a non-square since | ||
162 | * Legendre(2,p) = (-1)^((p^2-1)/8) for any odd prime. | ||
163 | * So if a really is a square, then 2*a is a non-square. | ||
164 | * Thus for | ||
165 | * b := (2*a)^((|p|-5)/8), | ||
166 | * i := (2*a)*b^2 | ||
167 | * we have | ||
168 | * i^2 = (2*a)^((1 + (|p|-5)/4)*2) | ||
169 | * = (2*a)^((p-1)/2) | ||
170 | * = -1; | ||
171 | * so if we set | ||
172 | * x := a*b*(i-1), | ||
173 | * then | ||
174 | * x^2 = a^2 * b^2 * (i^2 - 2*i + 1) | ||
175 | * = a^2 * b^2 * (-2*i) | ||
176 | * = a*(-i)*(2*a*b^2) | ||
177 | * = a*(-i)*i | ||
178 | * = a. | ||
179 | * | ||
180 | * (This is due to A.O.L. Atkin, | ||
181 | * <URL: http://listserv.nodak.edu/scripts/wa.exe?A2=ind9211&L=nmbrthry&O=T&P=562>, | ||
182 | * November 1992.) | ||
183 | */ | ||
184 | |||
185 | /* make sure that a is reduced modulo p */ | ||
186 | if (a->neg || BN_ucmp(a, p) >= 0) | ||
187 | { | ||
188 | if (!BN_nnmod(x, a, p, ctx)) goto end; | ||
189 | a = x; /* use x as temporary variable */ | ||
190 | } | ||
191 | |||
192 | /* t := 2*a */ | ||
193 | if (!BN_mod_lshift1_quick(t, a, p)) goto end; | ||
194 | |||
195 | /* b := (2*a)^((|p|-5)/8) */ | ||
196 | if (!BN_rshift(q, p, 3)) goto end; | ||
197 | q->neg = 0; | ||
198 | if (!BN_mod_exp(b, t, q, p, ctx)) goto end; | ||
199 | |||
200 | /* y := b^2 */ | ||
201 | if (!BN_mod_sqr(y, b, p, ctx)) goto end; | ||
202 | |||
203 | /* t := (2*a)*b^2 - 1*/ | ||
204 | if (!BN_mod_mul(t, t, y, p, ctx)) goto end; | ||
205 | if (!BN_sub_word(t, 1)) goto end; | ||
206 | |||
207 | /* x = a*b*t */ | ||
208 | if (!BN_mod_mul(x, a, b, p, ctx)) goto end; | ||
209 | if (!BN_mod_mul(x, x, t, p, ctx)) goto end; | ||
210 | |||
211 | if (!BN_copy(ret, x)) goto end; | ||
212 | err = 0; | ||
213 | goto end; | ||
214 | } | ||
215 | |||
216 | /* e > 2, so we really have to use the Tonelli/Shanks algorithm. | ||
217 | * First, find some y that is not a square. */ | ||
218 | if (!BN_copy(q, p)) goto end; /* use 'q' as temp */ | ||
219 | q->neg = 0; | ||
220 | i = 2; | ||
221 | do | ||
222 | { | ||
223 | /* For efficiency, try small numbers first; | ||
224 | * if this fails, try random numbers. | ||
225 | */ | ||
226 | if (i < 22) | ||
227 | { | ||
228 | if (!BN_set_word(y, i)) goto end; | ||
229 | } | ||
230 | else | ||
231 | { | ||
232 | if (!BN_pseudo_rand(y, BN_num_bits(p), 0, 0)) goto end; | ||
233 | if (BN_ucmp(y, p) >= 0) | ||
234 | { | ||
235 | if (!(p->neg ? BN_add : BN_sub)(y, y, p)) goto end; | ||
236 | } | ||
237 | /* now 0 <= y < |p| */ | ||
238 | if (BN_is_zero(y)) | ||
239 | if (!BN_set_word(y, i)) goto end; | ||
240 | } | ||
241 | |||
242 | r = BN_kronecker(y, q, ctx); /* here 'q' is |p| */ | ||
243 | if (r < -1) goto end; | ||
244 | if (r == 0) | ||
245 | { | ||
246 | /* m divides p */ | ||
247 | BNerr(BN_F_BN_MOD_SQRT, BN_R_P_IS_NOT_PRIME); | ||
248 | goto end; | ||
249 | } | ||
250 | } | ||
251 | while (r == 1 && ++i < 82); | ||
252 | |||
253 | if (r != -1) | ||
254 | { | ||
255 | /* Many rounds and still no non-square -- this is more likely | ||
256 | * a bug than just bad luck. | ||
257 | * Even if p is not prime, we should have found some y | ||
258 | * such that r == -1. | ||
259 | */ | ||
260 | BNerr(BN_F_BN_MOD_SQRT, BN_R_TOO_MANY_ITERATIONS); | ||
261 | goto end; | ||
262 | } | ||
263 | |||
264 | /* Here's our actual 'q': */ | ||
265 | if (!BN_rshift(q, q, e)) goto end; | ||
266 | |||
267 | /* Now that we have some non-square, we can find an element | ||
268 | * of order 2^e by computing its q'th power. */ | ||
269 | if (!BN_mod_exp(y, y, q, p, ctx)) goto end; | ||
270 | if (BN_is_one(y)) | ||
271 | { | ||
272 | BNerr(BN_F_BN_MOD_SQRT, BN_R_P_IS_NOT_PRIME); | ||
273 | goto end; | ||
274 | } | ||
275 | |||
276 | /* Now we know that (if p is indeed prime) there is an integer | ||
277 | * k, 0 <= k < 2^e, such that | ||
278 | * | ||
279 | * a^q * y^k == 1 (mod p). | ||
280 | * | ||
281 | * As a^q is a square and y is not, k must be even. | ||
282 | * q+1 is even, too, so there is an element | ||
283 | * | ||
284 | * X := a^((q+1)/2) * y^(k/2), | ||
285 | * | ||
286 | * and it satisfies | ||
287 | * | ||
288 | * X^2 = a^q * a * y^k | ||
289 | * = a, | ||
290 | * | ||
291 | * so it is the square root that we are looking for. | ||
292 | */ | ||
293 | |||
294 | /* t := (q-1)/2 (note that q is odd) */ | ||
295 | if (!BN_rshift1(t, q)) goto end; | ||
296 | |||
297 | /* x := a^((q-1)/2) */ | ||
298 | if (BN_is_zero(t)) /* special case: p = 2^e + 1 */ | ||
299 | { | ||
300 | if (!BN_nnmod(t, a, p, ctx)) goto end; | ||
301 | if (BN_is_zero(t)) | ||
302 | { | ||
303 | /* special case: a == 0 (mod p) */ | ||
304 | if (!BN_zero(ret)) goto end; | ||
305 | err = 0; | ||
306 | goto end; | ||
307 | } | ||
308 | else | ||
309 | if (!BN_one(x)) goto end; | ||
310 | } | ||
311 | else | ||
312 | { | ||
313 | if (!BN_mod_exp(x, a, t, p, ctx)) goto end; | ||
314 | if (BN_is_zero(x)) | ||
315 | { | ||
316 | /* special case: a == 0 (mod p) */ | ||
317 | if (!BN_zero(ret)) goto end; | ||
318 | err = 0; | ||
319 | goto end; | ||
320 | } | ||
321 | } | ||
322 | |||
323 | /* b := a*x^2 (= a^q) */ | ||
324 | if (!BN_mod_sqr(b, x, p, ctx)) goto end; | ||
325 | if (!BN_mod_mul(b, b, a, p, ctx)) goto end; | ||
326 | |||
327 | /* x := a*x (= a^((q+1)/2)) */ | ||
328 | if (!BN_mod_mul(x, x, a, p, ctx)) goto end; | ||
329 | |||
330 | while (1) | ||
331 | { | ||
332 | /* Now b is a^q * y^k for some even k (0 <= k < 2^E | ||
333 | * where E refers to the original value of e, which we | ||
334 | * don't keep in a variable), and x is a^((q+1)/2) * y^(k/2). | ||
335 | * | ||
336 | * We have a*b = x^2, | ||
337 | * y^2^(e-1) = -1, | ||
338 | * b^2^(e-1) = 1. | ||
339 | */ | ||
340 | |||
341 | if (BN_is_one(b)) | ||
342 | { | ||
343 | if (!BN_copy(ret, x)) goto end; | ||
344 | err = 0; | ||
345 | goto end; | ||
346 | } | ||
347 | |||
348 | |||
349 | /* find smallest i such that b^(2^i) = 1 */ | ||
350 | i = 1; | ||
351 | if (!BN_mod_sqr(t, b, p, ctx)) goto end; | ||
352 | while (!BN_is_one(t)) | ||
353 | { | ||
354 | i++; | ||
355 | if (i == e) | ||
356 | { | ||
357 | BNerr(BN_F_BN_MOD_SQRT, BN_R_NOT_A_SQUARE); | ||
358 | goto end; | ||
359 | } | ||
360 | if (!BN_mod_mul(t, t, t, p, ctx)) goto end; | ||
361 | } | ||
362 | |||
363 | |||
364 | /* t := y^2^(e - i - 1) */ | ||
365 | if (!BN_copy(t, y)) goto end; | ||
366 | for (j = e - i - 1; j > 0; j--) | ||
367 | { | ||
368 | if (!BN_mod_sqr(t, t, p, ctx)) goto end; | ||
369 | } | ||
370 | if (!BN_mod_mul(y, t, t, p, ctx)) goto end; | ||
371 | if (!BN_mod_mul(x, x, t, p, ctx)) goto end; | ||
372 | if (!BN_mod_mul(b, b, y, p, ctx)) goto end; | ||
373 | e = i; | ||
374 | } | ||
375 | |||
376 | end: | ||
377 | if (err) | ||
378 | { | ||
379 | if (ret != NULL && ret != in) | ||
380 | { | ||
381 | BN_clear_free(ret); | ||
382 | } | ||
383 | ret = NULL; | ||
384 | } | ||
385 | BN_CTX_end(ctx); | ||
386 | return ret; | ||
387 | } | ||
diff --git a/src/lib/libcrypto/comp/c_rle.c b/src/lib/libcrypto/comp/c_rle.c new file mode 100644 index 0000000000..1a819e3737 --- /dev/null +++ b/src/lib/libcrypto/comp/c_rle.c | |||
@@ -0,0 +1,61 @@ | |||
1 | #include <stdio.h> | ||
2 | #include <stdlib.h> | ||
3 | #include <string.h> | ||
4 | #include <openssl/objects.h> | ||
5 | #include <openssl/comp.h> | ||
6 | |||
7 | static int rle_compress_block(COMP_CTX *ctx, unsigned char *out, | ||
8 | unsigned int olen, unsigned char *in, unsigned int ilen); | ||
9 | static int rle_expand_block(COMP_CTX *ctx, unsigned char *out, | ||
10 | unsigned int olen, unsigned char *in, unsigned int ilen); | ||
11 | |||
12 | static COMP_METHOD rle_method={ | ||
13 | NID_rle_compression, | ||
14 | LN_rle_compression, | ||
15 | NULL, | ||
16 | NULL, | ||
17 | rle_compress_block, | ||
18 | rle_expand_block, | ||
19 | NULL, | ||
20 | }; | ||
21 | |||
22 | COMP_METHOD *COMP_rle(void) | ||
23 | { | ||
24 | return(&rle_method); | ||
25 | } | ||
26 | |||
27 | static int rle_compress_block(COMP_CTX *ctx, unsigned char *out, | ||
28 | unsigned int olen, unsigned char *in, unsigned int ilen) | ||
29 | { | ||
30 | /* int i; */ | ||
31 | |||
32 | if (olen < (ilen+1)) | ||
33 | { | ||
34 | /* ZZZZZZZZZZZZZZZZZZZZZZ */ | ||
35 | return(-1); | ||
36 | } | ||
37 | |||
38 | *(out++)=0; | ||
39 | memcpy(out,in,ilen); | ||
40 | return(ilen+1); | ||
41 | } | ||
42 | |||
43 | static int rle_expand_block(COMP_CTX *ctx, unsigned char *out, | ||
44 | unsigned int olen, unsigned char *in, unsigned int ilen) | ||
45 | { | ||
46 | int i; | ||
47 | |||
48 | if (olen < (ilen-1)) | ||
49 | { | ||
50 | /* ZZZZZZZZZZZZZZZZZZZZZZ */ | ||
51 | return(-1); | ||
52 | } | ||
53 | |||
54 | i= *(in++); | ||
55 | if (i == 0) | ||
56 | { | ||
57 | memcpy(out,in,ilen-1); | ||
58 | } | ||
59 | return(ilen-1); | ||
60 | } | ||
61 | |||
diff --git a/src/lib/libcrypto/comp/c_zlib.c b/src/lib/libcrypto/comp/c_zlib.c new file mode 100644 index 0000000000..6684ab4841 --- /dev/null +++ b/src/lib/libcrypto/comp/c_zlib.c | |||
@@ -0,0 +1,133 @@ | |||
1 | #include <stdio.h> | ||
2 | #include <stdlib.h> | ||
3 | #include <string.h> | ||
4 | #include <openssl/objects.h> | ||
5 | #include <openssl/comp.h> | ||
6 | |||
7 | COMP_METHOD *COMP_zlib(void ); | ||
8 | |||
9 | #ifndef ZLIB | ||
10 | |||
11 | static COMP_METHOD zlib_method={ | ||
12 | NID_undef, | ||
13 | "(null)", | ||
14 | NULL, | ||
15 | NULL, | ||
16 | NULL, | ||
17 | NULL, | ||
18 | NULL, | ||
19 | }; | ||
20 | |||
21 | #else | ||
22 | |||
23 | #include <zlib.h> | ||
24 | |||
25 | static int zlib_compress_block(COMP_CTX *ctx, unsigned char *out, | ||
26 | unsigned int olen, unsigned char *in, unsigned int ilen); | ||
27 | static int zlib_expand_block(COMP_CTX *ctx, unsigned char *out, | ||
28 | unsigned int olen, unsigned char *in, unsigned int ilen); | ||
29 | |||
30 | static int zz_uncompress(Bytef *dest, uLongf *destLen, const Bytef *source, | ||
31 | uLong sourceLen); | ||
32 | |||
33 | static COMP_METHOD zlib_method={ | ||
34 | NID_zlib_compression, | ||
35 | LN_zlib_compression, | ||
36 | NULL, | ||
37 | NULL, | ||
38 | zlib_compress_block, | ||
39 | zlib_expand_block, | ||
40 | NULL, | ||
41 | }; | ||
42 | |||
43 | static int zlib_compress_block(COMP_CTX *ctx, unsigned char *out, | ||
44 | unsigned int olen, unsigned char *in, unsigned int ilen) | ||
45 | { | ||
46 | unsigned long l; | ||
47 | int i; | ||
48 | int clear=1; | ||
49 | |||
50 | if (ilen > 128) | ||
51 | { | ||
52 | out[0]=1; | ||
53 | l=olen-1; | ||
54 | i=compress(&(out[1]),&l,in,(unsigned long)ilen); | ||
55 | if (i != Z_OK) | ||
56 | return(-1); | ||
57 | if (ilen > l) | ||
58 | { | ||
59 | clear=0; | ||
60 | l++; | ||
61 | } | ||
62 | } | ||
63 | if (clear) | ||
64 | { | ||
65 | out[0]=0; | ||
66 | memcpy(&(out[1]),in,ilen); | ||
67 | l=ilen+1; | ||
68 | } | ||
69 | fprintf(stderr,"compress(%4d)->%4d %s\n",ilen,(int)l,(clear)?"clear":"zlib"); | ||
70 | return((int)l); | ||
71 | } | ||
72 | |||
73 | static int zlib_expand_block(COMP_CTX *ctx, unsigned char *out, | ||
74 | unsigned int olen, unsigned char *in, unsigned int ilen) | ||
75 | { | ||
76 | unsigned long l; | ||
77 | int i; | ||
78 | |||
79 | if (in[0]) | ||
80 | { | ||
81 | l=olen; | ||
82 | i=zz_uncompress(out,&l,&(in[1]),(unsigned long)ilen-1); | ||
83 | if (i != Z_OK) | ||
84 | return(-1); | ||
85 | } | ||
86 | else | ||
87 | { | ||
88 | memcpy(out,&(in[1]),ilen-1); | ||
89 | l=ilen-1; | ||
90 | } | ||
91 | fprintf(stderr,"expand (%4d)->%4d %s\n",ilen,(int)l,in[0]?"zlib":"clear"); | ||
92 | return((int)l); | ||
93 | } | ||
94 | |||
95 | static int zz_uncompress (Bytef *dest, uLongf *destLen, const Bytef *source, | ||
96 | uLong sourceLen) | ||
97 | { | ||
98 | z_stream stream; | ||
99 | int err; | ||
100 | |||
101 | stream.next_in = (Bytef*)source; | ||
102 | stream.avail_in = (uInt)sourceLen; | ||
103 | /* Check for source > 64K on 16-bit machine: */ | ||
104 | if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR; | ||
105 | |||
106 | stream.next_out = dest; | ||
107 | stream.avail_out = (uInt)*destLen; | ||
108 | if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR; | ||
109 | |||
110 | stream.zalloc = (alloc_func)0; | ||
111 | stream.zfree = (free_func)0; | ||
112 | |||
113 | err = inflateInit(&stream); | ||
114 | if (err != Z_OK) return err; | ||
115 | |||
116 | err = inflate(&stream, Z_FINISH); | ||
117 | if (err != Z_STREAM_END) { | ||
118 | inflateEnd(&stream); | ||
119 | return err; | ||
120 | } | ||
121 | *destLen = stream.total_out; | ||
122 | |||
123 | err = inflateEnd(&stream); | ||
124 | return err; | ||
125 | } | ||
126 | |||
127 | #endif | ||
128 | |||
129 | COMP_METHOD *COMP_zlib(void) | ||
130 | { | ||
131 | return(&zlib_method); | ||
132 | } | ||
133 | |||
diff --git a/src/lib/libcrypto/comp/comp.h b/src/lib/libcrypto/comp/comp.h new file mode 100644 index 0000000000..93bd9c34c8 --- /dev/null +++ b/src/lib/libcrypto/comp/comp.h | |||
@@ -0,0 +1,60 @@ | |||
1 | |||
2 | #ifndef HEADER_COMP_H | ||
3 | #define HEADER_COMP_H | ||
4 | |||
5 | #ifdef __cplusplus | ||
6 | extern "C" { | ||
7 | #endif | ||
8 | |||
9 | #include <openssl/crypto.h> | ||
10 | |||
11 | typedef struct comp_method_st | ||
12 | { | ||
13 | int type; /* NID for compression library */ | ||
14 | const char *name; /* A text string to identify the library */ | ||
15 | int (*init)(); | ||
16 | void (*finish)(); | ||
17 | int (*compress)(); | ||
18 | int (*expand)(); | ||
19 | long (*ctrl)(); | ||
20 | } COMP_METHOD; | ||
21 | |||
22 | typedef struct comp_ctx_st | ||
23 | { | ||
24 | COMP_METHOD *meth; | ||
25 | unsigned long compress_in; | ||
26 | unsigned long compress_out; | ||
27 | unsigned long expand_in; | ||
28 | unsigned long expand_out; | ||
29 | |||
30 | CRYPTO_EX_DATA ex_data; | ||
31 | } COMP_CTX; | ||
32 | |||
33 | |||
34 | COMP_CTX *COMP_CTX_new(COMP_METHOD *meth); | ||
35 | void COMP_CTX_free(COMP_CTX *ctx); | ||
36 | int COMP_compress_block(COMP_CTX *ctx, unsigned char *out, int olen, | ||
37 | unsigned char *in, int ilen); | ||
38 | int COMP_expand_block(COMP_CTX *ctx, unsigned char *out, int olen, | ||
39 | unsigned char *in, int ilen); | ||
40 | COMP_METHOD *COMP_rle(void ); | ||
41 | #ifdef ZLIB | ||
42 | COMP_METHOD *COMP_zlib(void ); | ||
43 | #endif | ||
44 | |||
45 | /* BEGIN ERROR CODES */ | ||
46 | /* The following lines are auto generated by the script mkerr.pl. Any changes | ||
47 | * made after this point may be overwritten when the script is next run. | ||
48 | */ | ||
49 | |||
50 | /* Error codes for the COMP functions. */ | ||
51 | |||
52 | /* Function codes. */ | ||
53 | |||
54 | /* Reason codes. */ | ||
55 | |||
56 | #ifdef __cplusplus | ||
57 | } | ||
58 | #endif | ||
59 | #endif | ||
60 | |||
diff --git a/src/lib/libcrypto/comp/comp_err.c b/src/lib/libcrypto/comp/comp_err.c new file mode 100644 index 0000000000..77a3f7070c --- /dev/null +++ b/src/lib/libcrypto/comp/comp_err.c | |||
@@ -0,0 +1,91 @@ | |||
1 | /* crypto/comp/comp_err.c */ | ||
2 | /* ==================================================================== | ||
3 | * Copyright (c) 1999 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 | */ | ||
59 | |||
60 | #include <stdio.h> | ||
61 | #include <openssl/err.h> | ||
62 | #include <openssl/comp.h> | ||
63 | |||
64 | /* BEGIN ERROR CODES */ | ||
65 | #ifndef NO_ERR | ||
66 | static ERR_STRING_DATA COMP_str_functs[]= | ||
67 | { | ||
68 | {0,NULL} | ||
69 | }; | ||
70 | |||
71 | static ERR_STRING_DATA COMP_str_reasons[]= | ||
72 | { | ||
73 | {0,NULL} | ||
74 | }; | ||
75 | |||
76 | #endif | ||
77 | |||
78 | void ERR_load_COMP_strings(void) | ||
79 | { | ||
80 | static int init=1; | ||
81 | |||
82 | if (init) | ||
83 | { | ||
84 | init=0; | ||
85 | #ifndef NO_ERR | ||
86 | ERR_load_strings(ERR_LIB_COMP,COMP_str_functs); | ||
87 | ERR_load_strings(ERR_LIB_COMP,COMP_str_reasons); | ||
88 | #endif | ||
89 | |||
90 | } | ||
91 | } | ||
diff --git a/src/lib/libcrypto/comp/comp_lib.c b/src/lib/libcrypto/comp/comp_lib.c new file mode 100644 index 0000000000..a67ef23bc0 --- /dev/null +++ b/src/lib/libcrypto/comp/comp_lib.c | |||
@@ -0,0 +1,78 @@ | |||
1 | #include <stdio.h> | ||
2 | #include <stdlib.h> | ||
3 | #include <string.h> | ||
4 | #include <openssl/objects.h> | ||
5 | #include <openssl/comp.h> | ||
6 | |||
7 | COMP_CTX *COMP_CTX_new(COMP_METHOD *meth) | ||
8 | { | ||
9 | COMP_CTX *ret; | ||
10 | |||
11 | if ((ret=(COMP_CTX *)Malloc(sizeof(COMP_CTX))) == NULL) | ||
12 | { | ||
13 | /* ZZZZZZZZZZZZZZZZ */ | ||
14 | return(NULL); | ||
15 | } | ||
16 | memset(ret,0,sizeof(COMP_CTX)); | ||
17 | ret->meth=meth; | ||
18 | if ((ret->meth->init != NULL) && !ret->meth->init(ret)) | ||
19 | { | ||
20 | Free(ret); | ||
21 | ret=NULL; | ||
22 | } | ||
23 | #if 0 | ||
24 | else | ||
25 | CRYPTO_new_ex_data(rsa_meth,(char *)ret,&ret->ex_data); | ||
26 | #endif | ||
27 | return(ret); | ||
28 | } | ||
29 | |||
30 | void COMP_CTX_free(COMP_CTX *ctx) | ||
31 | { | ||
32 | /* CRYPTO_free_ex_data(rsa_meth,(char *)ctx,&ctx->ex_data); */ | ||
33 | |||
34 | if(ctx == NULL) | ||
35 | return; | ||
36 | |||
37 | if (ctx->meth->finish != NULL) | ||
38 | ctx->meth->finish(ctx); | ||
39 | |||
40 | Free(ctx); | ||
41 | } | ||
42 | |||
43 | int COMP_compress_block(COMP_CTX *ctx, unsigned char *out, int olen, | ||
44 | unsigned char *in, int ilen) | ||
45 | { | ||
46 | int ret; | ||
47 | if (ctx->meth->compress == NULL) | ||
48 | { | ||
49 | /* ZZZZZZZZZZZZZZZZZ */ | ||
50 | return(-1); | ||
51 | } | ||
52 | ret=ctx->meth->compress(ctx,out,olen,in,ilen); | ||
53 | if (ret > 0) | ||
54 | { | ||
55 | ctx->compress_in+=ilen; | ||
56 | ctx->compress_out+=ret; | ||
57 | } | ||
58 | return(ret); | ||
59 | } | ||
60 | |||
61 | int COMP_expand_block(COMP_CTX *ctx, unsigned char *out, int olen, | ||
62 | unsigned char *in, int ilen) | ||
63 | { | ||
64 | int ret; | ||
65 | |||
66 | if (ctx->meth->expand == NULL) | ||
67 | { | ||
68 | /* ZZZZZZZZZZZZZZZZZ */ | ||
69 | return(-1); | ||
70 | } | ||
71 | ret=ctx->meth->expand(ctx,out,olen,in,ilen); | ||
72 | if (ret > 0) | ||
73 | { | ||
74 | ctx->expand_in+=ilen; | ||
75 | ctx->expand_out+=ret; | ||
76 | } | ||
77 | return(ret); | ||
78 | } | ||
diff --git a/src/lib/libcrypto/conf/README b/src/lib/libcrypto/conf/README new file mode 100644 index 0000000000..ca58d0240f --- /dev/null +++ b/src/lib/libcrypto/conf/README | |||
@@ -0,0 +1,78 @@ | |||
1 | WARNING WARNING WARNING!!! | ||
2 | |||
3 | This stuff is experimental, may change radically or be deleted altogether | ||
4 | before OpenSSL 0.9.7 release. You have been warned! | ||
5 | |||
6 | Configuration modules. These are a set of modules which can perform | ||
7 | various configuration functions. | ||
8 | |||
9 | Currently the routines should be called at most once when an application | ||
10 | starts up: that is before it starts any threads. | ||
11 | |||
12 | The routines read a configuration file set up like this: | ||
13 | |||
14 | ----- | ||
15 | #default section | ||
16 | openssl_init=init_section | ||
17 | |||
18 | [init_section] | ||
19 | |||
20 | module1=value1 | ||
21 | #Second instance of module1 | ||
22 | module1.1=valueX | ||
23 | module2=value2 | ||
24 | module3=dso_literal | ||
25 | module4=dso_section | ||
26 | |||
27 | [dso_section] | ||
28 | |||
29 | path=/some/path/to/some/dso.so | ||
30 | other_stuff=other_value | ||
31 | ---- | ||
32 | |||
33 | When this file is loaded a configuration module with the specified | ||
34 | string (module* in the above example) is looked up and its init | ||
35 | function called as: | ||
36 | |||
37 | int conf_init_func(CONF_IMODULE *md, CONF *cnf); | ||
38 | |||
39 | The function can then take whatever action is appropriate, for example | ||
40 | further lookups based on the value. Multiple instances of the same | ||
41 | config module can be loaded. | ||
42 | |||
43 | When the application closes down the modules are cleaned up by calling | ||
44 | an optional finish function: | ||
45 | |||
46 | void conf_finish_func(CONF_IMODULE *md); | ||
47 | |||
48 | The finish functions are called in reverse order: that is the last module | ||
49 | loaded is the first one cleaned up. | ||
50 | |||
51 | If no module exists with a given name then an attempt is made to load | ||
52 | a DSO with the supplied name. This might mean that "module3" attempts | ||
53 | to load a DSO called libmodule3.so or module3.dll for example. An explicit | ||
54 | DSO name can be given by including a separate section as in the module4 example | ||
55 | above. | ||
56 | |||
57 | The DSO is expected to at least contain an initialization function: | ||
58 | |||
59 | int OPENSSL_init(CONF_IMODULE *md, CONF *cnf); | ||
60 | |||
61 | and may also include a finish function: | ||
62 | |||
63 | void OPENSSL_finish(CONF_IMODULE *md); | ||
64 | |||
65 | Static modules can also be added using, | ||
66 | |||
67 | int CONF_module_add(char *name, dso_mod_init_func *ifunc, dso_mod_finish_func *ffunc); | ||
68 | |||
69 | where "name" is the name in the configuration file this function corresponds to. | ||
70 | |||
71 | A set of builtin modules (currently only an ASN1 non functional test module) can be | ||
72 | added by calling OPENSSL_load_builtin_modules(). | ||
73 | |||
74 | The function OPENSSL_config() is intended as a simple configuration function that | ||
75 | any application can call to perform various default configuration tasks. It uses the | ||
76 | file openssl.cnf in the usual locations. | ||
77 | |||
78 | |||
diff --git a/src/lib/libcrypto/conf/conf_api.c b/src/lib/libcrypto/conf/conf_api.c new file mode 100644 index 0000000000..d05a778ff6 --- /dev/null +++ b/src/lib/libcrypto/conf/conf_api.c | |||
@@ -0,0 +1,289 @@ | |||
1 | /* conf_api.c */ | ||
2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) | ||
3 | * All rights reserved. | ||
4 | * | ||
5 | * This package is an SSL implementation written | ||
6 | * by Eric Young (eay@cryptsoft.com). | ||
7 | * The implementation was written so as to conform with Netscapes SSL. | ||
8 | * | ||
9 | * This library is free for commercial and non-commercial use as long as | ||
10 | * the following conditions are aheared to. The following conditions | ||
11 | * apply to all code found in this distribution, be it the RC4, RSA, | ||
12 | * lhash, DES, etc., code; not just the SSL code. The SSL documentation | ||
13 | * included with this distribution is covered by the same copyright terms | ||
14 | * except that the holder is Tim Hudson (tjh@cryptsoft.com). | ||
15 | * | ||
16 | * Copyright remains Eric Young's, and as such any Copyright notices in | ||
17 | * the code are not to be removed. | ||
18 | * If this package is used in a product, Eric Young should be given attribution | ||
19 | * as the author of the parts of the library used. | ||
20 | * This can be in the form of a textual message at program startup or | ||
21 | * in documentation (online or textual) provided with the package. | ||
22 | * | ||
23 | * Redistribution and use in source and binary forms, with or without | ||
24 | * modification, are permitted provided that the following conditions | ||
25 | * are met: | ||
26 | * 1. Redistributions of source code must retain the copyright | ||
27 | * notice, this list of conditions and the following disclaimer. | ||
28 | * 2. Redistributions in binary form must reproduce the above copyright | ||
29 | * notice, this list of conditions and the following disclaimer in the | ||
30 | * documentation and/or other materials provided with the distribution. | ||
31 | * 3. All advertising materials mentioning features or use of this software | ||
32 | * must display the following acknowledgement: | ||
33 | * "This product includes cryptographic software written by | ||
34 | * Eric Young (eay@cryptsoft.com)" | ||
35 | * The word 'cryptographic' can be left out if the rouines from the library | ||
36 | * being used are not cryptographic related :-). | ||
37 | * 4. If you include any Windows specific code (or a derivative thereof) from | ||
38 | * the apps directory (application code) you must include an acknowledgement: | ||
39 | * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" | ||
40 | * | ||
41 | * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND | ||
42 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
43 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
44 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | ||
45 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
46 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
47 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
48 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
49 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
50 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
51 | * SUCH DAMAGE. | ||
52 | * | ||
53 | * The licence and distribution terms for any publically available version or | ||
54 | * derivative of this code cannot be changed. i.e. this code cannot simply be | ||
55 | * copied and put under another distribution licence | ||
56 | * [including the GNU Public Licence.] | ||
57 | */ | ||
58 | |||
59 | /* Part of the code in here was originally in conf.c, which is now removed */ | ||
60 | |||
61 | #ifndef CONF_DEBUG | ||
62 | # undef NDEBUG /* avoid conflicting definitions */ | ||
63 | # define NDEBUG | ||
64 | #endif | ||
65 | |||
66 | #include <assert.h> | ||
67 | #include <string.h> | ||
68 | #include <openssl/conf.h> | ||
69 | #include <openssl/conf_api.h> | ||
70 | |||
71 | static void value_free_hash(CONF_VALUE *a, LHASH *conf); | ||
72 | static void value_free_stack(CONF_VALUE *a,LHASH *conf); | ||
73 | static unsigned long hash(CONF_VALUE *v); | ||
74 | static int cmp_conf(CONF_VALUE *a,CONF_VALUE *b); | ||
75 | |||
76 | /* Up until OpenSSL 0.9.5a, this was get_section */ | ||
77 | CONF_VALUE *_CONF_get_section(CONF *conf, char *section) | ||
78 | { | ||
79 | CONF_VALUE *v,vv; | ||
80 | |||
81 | if ((conf == NULL) || (section == NULL)) return(NULL); | ||
82 | vv.name=NULL; | ||
83 | vv.section=section; | ||
84 | v=(CONF_VALUE *)lh_retrieve(conf->data,&vv); | ||
85 | return(v); | ||
86 | } | ||
87 | |||
88 | /* Up until OpenSSL 0.9.5a, this was CONF_get_section */ | ||
89 | STACK_OF(CONF_VALUE) *_CONF_get_section_values(CONF *conf, char *section) | ||
90 | { | ||
91 | CONF_VALUE *v; | ||
92 | |||
93 | v=_CONF_get_section(conf,section); | ||
94 | if (v != NULL) | ||
95 | return((STACK_OF(CONF_VALUE) *)v->value); | ||
96 | else | ||
97 | return(NULL); | ||
98 | } | ||
99 | |||
100 | int _CONF_add_string(CONF *conf, CONF_VALUE *section, CONF_VALUE *value) | ||
101 | { | ||
102 | CONF_VALUE *v = NULL; | ||
103 | STACK_OF(CONF_VALUE) *ts; | ||
104 | |||
105 | ts = (STACK_OF(CONF_VALUE) *)section->value; | ||
106 | |||
107 | value->section=section->section; | ||
108 | if (!sk_CONF_VALUE_push(ts,value)) | ||
109 | { | ||
110 | return 0; | ||
111 | } | ||
112 | |||
113 | v = (CONF_VALUE *)lh_insert(conf->data, value); | ||
114 | if (v != NULL) | ||
115 | { | ||
116 | sk_CONF_VALUE_delete_ptr(ts,v); | ||
117 | OPENSSL_free(v->name); | ||
118 | OPENSSL_free(v->value); | ||
119 | OPENSSL_free(v); | ||
120 | } | ||
121 | return 1; | ||
122 | } | ||
123 | |||
124 | char *_CONF_get_string(CONF *conf, char *section, char *name) | ||
125 | { | ||
126 | CONF_VALUE *v,vv; | ||
127 | char *p; | ||
128 | |||
129 | if (name == NULL) return(NULL); | ||
130 | if (conf != NULL) | ||
131 | { | ||
132 | if (section != NULL) | ||
133 | { | ||
134 | vv.name=name; | ||
135 | vv.section=section; | ||
136 | v=(CONF_VALUE *)lh_retrieve(conf->data,&vv); | ||
137 | if (v != NULL) return(v->value); | ||
138 | if (strcmp(section,"ENV") == 0) | ||
139 | { | ||
140 | p=Getenv(name); | ||
141 | if (p != NULL) return(p); | ||
142 | } | ||
143 | } | ||
144 | vv.section="default"; | ||
145 | vv.name=name; | ||
146 | v=(CONF_VALUE *)lh_retrieve(conf->data,&vv); | ||
147 | if (v != NULL) | ||
148 | return(v->value); | ||
149 | else | ||
150 | return(NULL); | ||
151 | } | ||
152 | else | ||
153 | return(Getenv(name)); | ||
154 | } | ||
155 | |||
156 | long _CONF_get_number(CONF *conf, char *section, char *name) | ||
157 | { | ||
158 | char *str; | ||
159 | long ret=0; | ||
160 | |||
161 | str=_CONF_get_string(conf,section,name); | ||
162 | if (str == NULL) return(0); | ||
163 | for (;;) | ||
164 | { | ||
165 | if (conf->meth->is_number(conf, *str)) | ||
166 | ret=ret*10+conf->meth->to_int(conf, *str); | ||
167 | else | ||
168 | return(ret); | ||
169 | str++; | ||
170 | } | ||
171 | } | ||
172 | |||
173 | int _CONF_new_data(CONF *conf) | ||
174 | { | ||
175 | if (conf == NULL) | ||
176 | { | ||
177 | return 0; | ||
178 | } | ||
179 | if (conf->data == NULL) | ||
180 | if ((conf->data = lh_new(hash,cmp_conf)) == NULL) | ||
181 | { | ||
182 | return 0; | ||
183 | } | ||
184 | return 1; | ||
185 | } | ||
186 | |||
187 | void _CONF_free_data(CONF *conf) | ||
188 | { | ||
189 | if (conf == NULL || conf->data == NULL) return; | ||
190 | |||
191 | conf->data->down_load=0; /* evil thing to make sure the 'OPENSSL_free()' | ||
192 | * works as expected */ | ||
193 | lh_doall_arg(conf->data,(void (*)())value_free_hash,conf->data); | ||
194 | |||
195 | /* We now have only 'section' entries in the hash table. | ||
196 | * Due to problems with */ | ||
197 | |||
198 | lh_doall_arg(conf->data,(void (*)())value_free_stack,conf->data); | ||
199 | lh_free(conf->data); | ||
200 | } | ||
201 | |||
202 | static void value_free_hash(CONF_VALUE *a, LHASH *conf) | ||
203 | { | ||
204 | if (a->name != NULL) | ||
205 | { | ||
206 | a=(CONF_VALUE *)lh_delete(conf,a); | ||
207 | } | ||
208 | } | ||
209 | |||
210 | static void value_free_stack(CONF_VALUE *a, LHASH *conf) | ||
211 | { | ||
212 | CONF_VALUE *vv; | ||
213 | STACK *sk; | ||
214 | int i; | ||
215 | |||
216 | if (a->name != NULL) return; | ||
217 | |||
218 | sk=(STACK *)a->value; | ||
219 | for (i=sk_num(sk)-1; i>=0; i--) | ||
220 | { | ||
221 | vv=(CONF_VALUE *)sk_value(sk,i); | ||
222 | OPENSSL_free(vv->value); | ||
223 | OPENSSL_free(vv->name); | ||
224 | OPENSSL_free(vv); | ||
225 | } | ||
226 | if (sk != NULL) sk_free(sk); | ||
227 | OPENSSL_free(a->section); | ||
228 | OPENSSL_free(a); | ||
229 | } | ||
230 | |||
231 | static unsigned long hash(CONF_VALUE *v) | ||
232 | { | ||
233 | return((lh_strhash(v->section)<<2)^lh_strhash(v->name)); | ||
234 | } | ||
235 | |||
236 | static int cmp_conf(CONF_VALUE *a, CONF_VALUE *b) | ||
237 | { | ||
238 | int i; | ||
239 | |||
240 | if (a->section != b->section) | ||
241 | { | ||
242 | i=strcmp(a->section,b->section); | ||
243 | if (i) return(i); | ||
244 | } | ||
245 | |||
246 | if ((a->name != NULL) && (b->name != NULL)) | ||
247 | { | ||
248 | i=strcmp(a->name,b->name); | ||
249 | return(i); | ||
250 | } | ||
251 | else if (a->name == b->name) | ||
252 | return(0); | ||
253 | else | ||
254 | return((a->name == NULL)?-1:1); | ||
255 | } | ||
256 | |||
257 | /* Up until OpenSSL 0.9.5a, this was new_section */ | ||
258 | CONF_VALUE *_CONF_new_section(CONF *conf, char *section) | ||
259 | { | ||
260 | STACK *sk=NULL; | ||
261 | int ok=0,i; | ||
262 | CONF_VALUE *v=NULL,*vv; | ||
263 | |||
264 | if ((sk=sk_new_null()) == NULL) | ||
265 | goto err; | ||
266 | if ((v=(CONF_VALUE *)OPENSSL_malloc(sizeof(CONF_VALUE))) == NULL) | ||
267 | goto err; | ||
268 | i=strlen(section)+1; | ||
269 | if ((v->section=(char *)OPENSSL_malloc(i)) == NULL) | ||
270 | goto err; | ||
271 | |||
272 | memcpy(v->section,section,i); | ||
273 | v->name=NULL; | ||
274 | v->value=(char *)sk; | ||
275 | |||
276 | vv=(CONF_VALUE *)lh_insert(conf->data,v); | ||
277 | assert(vv == NULL); | ||
278 | ok=1; | ||
279 | err: | ||
280 | if (!ok) | ||
281 | { | ||
282 | if (sk != NULL) sk_free(sk); | ||
283 | if (v != NULL) OPENSSL_free(v); | ||
284 | v=NULL; | ||
285 | } | ||
286 | return(v); | ||
287 | } | ||
288 | |||
289 | IMPLEMENT_STACK_OF(CONF_VALUE) | ||
diff --git a/src/lib/libcrypto/conf/conf_api.h b/src/lib/libcrypto/conf/conf_api.h new file mode 100644 index 0000000000..a5cc17b233 --- /dev/null +++ b/src/lib/libcrypto/conf/conf_api.h | |||
@@ -0,0 +1,87 @@ | |||
1 | /* conf_api.h */ | ||
2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) | ||
3 | * All rights reserved. | ||
4 | * | ||
5 | * This package is an SSL implementation written | ||
6 | * by Eric Young (eay@cryptsoft.com). | ||
7 | * The implementation was written so as to conform with Netscapes SSL. | ||
8 | * | ||
9 | * This library is free for commercial and non-commercial use as long as | ||
10 | * the following conditions are aheared to. The following conditions | ||
11 | * apply to all code found in this distribution, be it the RC4, RSA, | ||
12 | * lhash, DES, etc., code; not just the SSL code. The SSL documentation | ||
13 | * included with this distribution is covered by the same copyright terms | ||
14 | * except that the holder is Tim Hudson (tjh@cryptsoft.com). | ||
15 | * | ||
16 | * Copyright remains Eric Young's, and as such any Copyright notices in | ||
17 | * the code are not to be removed. | ||
18 | * If this package is used in a product, Eric Young should be given attribution | ||
19 | * as the author of the parts of the library used. | ||
20 | * This can be in the form of a textual message at program startup or | ||
21 | * in documentation (online or textual) provided with the package. | ||
22 | * | ||
23 | * Redistribution and use in source and binary forms, with or without | ||
24 | * modification, are permitted provided that the following conditions | ||
25 | * are met: | ||
26 | * 1. Redistributions of source code must retain the copyright | ||
27 | * notice, this list of conditions and the following disclaimer. | ||
28 | * 2. Redistributions in binary form must reproduce the above copyright | ||
29 | * notice, this list of conditions and the following disclaimer in the | ||
30 | * documentation and/or other materials provided with the distribution. | ||
31 | * 3. All advertising materials mentioning features or use of this software | ||
32 | * must display the following acknowledgement: | ||
33 | * "This product includes cryptographic software written by | ||
34 | * Eric Young (eay@cryptsoft.com)" | ||
35 | * The word 'cryptographic' can be left out if the rouines from the library | ||
36 | * being used are not cryptographic related :-). | ||
37 | * 4. If you include any Windows specific code (or a derivative thereof) from | ||
38 | * the apps directory (application code) you must include an acknowledgement: | ||
39 | * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" | ||
40 | * | ||
41 | * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND | ||
42 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
43 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
44 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | ||
45 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
46 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
47 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
48 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
49 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
50 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
51 | * SUCH DAMAGE. | ||
52 | * | ||
53 | * The licence and distribution terms for any publically available version or | ||
54 | * derivative of this code cannot be changed. i.e. this code cannot simply be | ||
55 | * copied and put under another distribution licence | ||
56 | * [including the GNU Public Licence.] | ||
57 | */ | ||
58 | |||
59 | #ifndef HEADER_CONF_API_H | ||
60 | #define HEADER_CONF_API_H | ||
61 | |||
62 | #include <openssl/lhash.h> | ||
63 | #include <openssl/conf.h> | ||
64 | |||
65 | #ifdef __cplusplus | ||
66 | extern "C" { | ||
67 | #endif | ||
68 | |||
69 | /* Up until OpenSSL 0.9.5a, this was new_section */ | ||
70 | CONF_VALUE *_CONF_new_section(CONF *conf, char *section); | ||
71 | /* Up until OpenSSL 0.9.5a, this was get_section */ | ||
72 | CONF_VALUE *_CONF_get_section(CONF *conf, char *section); | ||
73 | /* Up until OpenSSL 0.9.5a, this was CONF_get_section */ | ||
74 | STACK_OF(CONF_VALUE) *_CONF_get_section_values(CONF *conf, char *section); | ||
75 | |||
76 | int _CONF_add_string(CONF *conf, CONF_VALUE *section, CONF_VALUE *value); | ||
77 | char *_CONF_get_string(CONF *conf, char *section, char *name); | ||
78 | long _CONF_get_number(CONF *conf, char *section, char *name); | ||
79 | |||
80 | int _CONF_new_data(CONF *conf); | ||
81 | void _CONF_free_data(CONF *conf); | ||
82 | |||
83 | #ifdef __cplusplus | ||
84 | } | ||
85 | #endif | ||
86 | #endif | ||
87 | |||
diff --git a/src/lib/libcrypto/conf/conf_def.c b/src/lib/libcrypto/conf/conf_def.c new file mode 100644 index 0000000000..773df32c68 --- /dev/null +++ b/src/lib/libcrypto/conf/conf_def.c | |||
@@ -0,0 +1,703 @@ | |||
1 | /* crypto/conf/conf.c */ | ||
2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) | ||
3 | * All rights reserved. | ||
4 | * | ||
5 | * This package is an SSL implementation written | ||
6 | * by Eric Young (eay@cryptsoft.com). | ||
7 | * The implementation was written so as to conform with Netscapes SSL. | ||
8 | * | ||
9 | * This library is free for commercial and non-commercial use as long as | ||
10 | * the following conditions are aheared to. The following conditions | ||
11 | * apply to all code found in this distribution, be it the RC4, RSA, | ||
12 | * lhash, DES, etc., code; not just the SSL code. The SSL documentation | ||
13 | * included with this distribution is covered by the same copyright terms | ||
14 | * except that the holder is Tim Hudson (tjh@cryptsoft.com). | ||
15 | * | ||
16 | * Copyright remains Eric Young's, and as such any Copyright notices in | ||
17 | * the code are not to be removed. | ||
18 | * If this package is used in a product, Eric Young should be given attribution | ||
19 | * as the author of the parts of the library used. | ||
20 | * This can be in the form of a textual message at program startup or | ||
21 | * in documentation (online or textual) provided with the package. | ||
22 | * | ||
23 | * Redistribution and use in source and binary forms, with or without | ||
24 | * modification, are permitted provided that the following conditions | ||
25 | * are met: | ||
26 | * 1. Redistributions of source code must retain the copyright | ||
27 | * notice, this list of conditions and the following disclaimer. | ||
28 | * 2. Redistributions in binary form must reproduce the above copyright | ||
29 | * notice, this list of conditions and the following disclaimer in the | ||
30 | * documentation and/or other materials provided with the distribution. | ||
31 | * 3. All advertising materials mentioning features or use of this software | ||
32 | * must display the following acknowledgement: | ||
33 | * "This product includes cryptographic software written by | ||
34 | * Eric Young (eay@cryptsoft.com)" | ||
35 | * The word 'cryptographic' can be left out if the rouines from the library | ||
36 | * being used are not cryptographic related :-). | ||
37 | * 4. If you include any Windows specific code (or a derivative thereof) from | ||
38 | * the apps directory (application code) you must include an acknowledgement: | ||
39 | * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" | ||
40 | * | ||
41 | * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND | ||
42 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
43 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
44 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | ||
45 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
46 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
47 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
48 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
49 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
50 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
51 | * SUCH DAMAGE. | ||
52 | * | ||
53 | * The licence and distribution terms for any publically available version or | ||
54 | * derivative of this code cannot be changed. i.e. this code cannot simply be | ||
55 | * copied and put under another distribution licence | ||
56 | * [including the GNU Public Licence.] | ||
57 | */ | ||
58 | |||
59 | /* Part of the code in here was originally in conf.c, which is now removed */ | ||
60 | |||
61 | #include <stdio.h> | ||
62 | #include <string.h> | ||
63 | #include <openssl/stack.h> | ||
64 | #include <openssl/lhash.h> | ||
65 | #include <openssl/conf.h> | ||
66 | #include <openssl/conf_api.h> | ||
67 | #include "conf_def.h" | ||
68 | #include <openssl/buffer.h> | ||
69 | #include <openssl/err.h> | ||
70 | |||
71 | static char *eat_ws(CONF *conf, char *p); | ||
72 | static char *eat_alpha_numeric(CONF *conf, char *p); | ||
73 | static void clear_comments(CONF *conf, char *p); | ||
74 | static int str_copy(CONF *conf,char *section,char **to, char *from); | ||
75 | static char *scan_quote(CONF *conf, char *p); | ||
76 | static char *scan_dquote(CONF *conf, char *p); | ||
77 | #define scan_esc(conf,p) (((IS_EOF((conf),(p)[1]))?((p)+1):((p)+2))) | ||
78 | |||
79 | static CONF *def_create(CONF_METHOD *meth); | ||
80 | static int def_init_default(CONF *conf); | ||
81 | static int def_init_WIN32(CONF *conf); | ||
82 | static int def_destroy(CONF *conf); | ||
83 | static int def_destroy_data(CONF *conf); | ||
84 | static int def_load(CONF *conf, BIO *bp, long *eline); | ||
85 | static int def_dump(CONF *conf, BIO *bp); | ||
86 | static int def_is_number(CONF *conf, char c); | ||
87 | static int def_to_int(CONF *conf, char c); | ||
88 | |||
89 | const char *CONF_def_version="CONF_def" OPENSSL_VERSION_PTEXT; | ||
90 | |||
91 | static CONF_METHOD default_method = { | ||
92 | "OpenSSL default", | ||
93 | def_create, | ||
94 | def_init_default, | ||
95 | def_destroy, | ||
96 | def_destroy_data, | ||
97 | def_load, | ||
98 | def_dump, | ||
99 | def_is_number, | ||
100 | def_to_int | ||
101 | }; | ||
102 | |||
103 | static CONF_METHOD WIN32_method = { | ||
104 | "WIN32", | ||
105 | def_create, | ||
106 | def_init_WIN32, | ||
107 | def_destroy, | ||
108 | def_destroy_data, | ||
109 | def_load, | ||
110 | def_dump, | ||
111 | def_is_number, | ||
112 | def_to_int | ||
113 | }; | ||
114 | |||
115 | CONF_METHOD *NCONF_default() | ||
116 | { | ||
117 | return &default_method; | ||
118 | } | ||
119 | CONF_METHOD *NCONF_WIN32() | ||
120 | { | ||
121 | return &WIN32_method; | ||
122 | } | ||
123 | |||
124 | static CONF *def_create(CONF_METHOD *meth) | ||
125 | { | ||
126 | CONF *ret; | ||
127 | |||
128 | ret = (CONF *)OPENSSL_malloc(sizeof(CONF) + sizeof(unsigned short *)); | ||
129 | if (ret) | ||
130 | if (meth->init(ret) == 0) | ||
131 | { | ||
132 | OPENSSL_free(ret); | ||
133 | ret = NULL; | ||
134 | } | ||
135 | return ret; | ||
136 | } | ||
137 | |||
138 | static int def_init_default(CONF *conf) | ||
139 | { | ||
140 | if (conf == NULL) | ||
141 | return 0; | ||
142 | |||
143 | conf->meth = &default_method; | ||
144 | conf->meth_data = (void *)CONF_type_default; | ||
145 | conf->data = NULL; | ||
146 | |||
147 | return 1; | ||
148 | } | ||
149 | |||
150 | static int def_init_WIN32(CONF *conf) | ||
151 | { | ||
152 | if (conf == NULL) | ||
153 | return 0; | ||
154 | |||
155 | conf->meth = &WIN32_method; | ||
156 | conf->meth_data = (void *)CONF_type_win32; | ||
157 | conf->data = NULL; | ||
158 | |||
159 | return 1; | ||
160 | } | ||
161 | |||
162 | static int def_destroy(CONF *conf) | ||
163 | { | ||
164 | if (def_destroy_data(conf)) | ||
165 | { | ||
166 | OPENSSL_free(conf); | ||
167 | return 1; | ||
168 | } | ||
169 | return 0; | ||
170 | } | ||
171 | |||
172 | static int def_destroy_data(CONF *conf) | ||
173 | { | ||
174 | if (conf == NULL) | ||
175 | return 0; | ||
176 | _CONF_free_data(conf); | ||
177 | return 1; | ||
178 | } | ||
179 | |||
180 | static int def_load(CONF *conf, BIO *in, long *line) | ||
181 | { | ||
182 | #define BUFSIZE 512 | ||
183 | char btmp[16]; | ||
184 | int bufnum=0,i,ii; | ||
185 | BUF_MEM *buff=NULL; | ||
186 | char *s,*p,*end; | ||
187 | int again,n; | ||
188 | long eline=0; | ||
189 | CONF_VALUE *v=NULL,*tv; | ||
190 | CONF_VALUE *sv=NULL; | ||
191 | char *section=NULL,*buf; | ||
192 | STACK_OF(CONF_VALUE) *section_sk=NULL,*ts; | ||
193 | char *start,*psection,*pname; | ||
194 | void *h = (void *)(conf->data); | ||
195 | |||
196 | if ((buff=BUF_MEM_new()) == NULL) | ||
197 | { | ||
198 | CONFerr(CONF_F_CONF_LOAD_BIO,ERR_R_BUF_LIB); | ||
199 | goto err; | ||
200 | } | ||
201 | |||
202 | section=(char *)OPENSSL_malloc(10); | ||
203 | if (section == NULL) | ||
204 | { | ||
205 | CONFerr(CONF_F_CONF_LOAD_BIO,ERR_R_MALLOC_FAILURE); | ||
206 | goto err; | ||
207 | } | ||
208 | strcpy(section,"default"); | ||
209 | |||
210 | if (_CONF_new_data(conf) == 0) | ||
211 | { | ||
212 | CONFerr(CONF_F_CONF_LOAD_BIO,ERR_R_MALLOC_FAILURE); | ||
213 | goto err; | ||
214 | } | ||
215 | |||
216 | sv=_CONF_new_section(conf,section); | ||
217 | if (sv == NULL) | ||
218 | { | ||
219 | CONFerr(CONF_F_CONF_LOAD_BIO, | ||
220 | CONF_R_UNABLE_TO_CREATE_NEW_SECTION); | ||
221 | goto err; | ||
222 | } | ||
223 | section_sk=(STACK_OF(CONF_VALUE) *)sv->value; | ||
224 | |||
225 | bufnum=0; | ||
226 | for (;;) | ||
227 | { | ||
228 | again=0; | ||
229 | if (!BUF_MEM_grow(buff,bufnum+BUFSIZE)) | ||
230 | { | ||
231 | CONFerr(CONF_F_CONF_LOAD_BIO,ERR_R_BUF_LIB); | ||
232 | goto err; | ||
233 | } | ||
234 | p= &(buff->data[bufnum]); | ||
235 | *p='\0'; | ||
236 | BIO_gets(in, p, BUFSIZE-1); | ||
237 | p[BUFSIZE-1]='\0'; | ||
238 | ii=i=strlen(p); | ||
239 | if (i == 0) break; | ||
240 | while (i > 0) | ||
241 | { | ||
242 | if ((p[i-1] != '\r') && (p[i-1] != '\n')) | ||
243 | break; | ||
244 | else | ||
245 | i--; | ||
246 | } | ||
247 | /* we removed some trailing stuff so there is a new | ||
248 | * line on the end. */ | ||
249 | if (i == ii) | ||
250 | again=1; /* long line */ | ||
251 | else | ||
252 | { | ||
253 | p[i]='\0'; | ||
254 | eline++; /* another input line */ | ||
255 | } | ||
256 | |||
257 | /* we now have a line with trailing \r\n removed */ | ||
258 | |||
259 | /* i is the number of bytes */ | ||
260 | bufnum+=i; | ||
261 | |||
262 | v=NULL; | ||
263 | /* check for line continuation */ | ||
264 | if (bufnum >= 1) | ||
265 | { | ||
266 | /* If we have bytes and the last char '\\' and | ||
267 | * second last char is not '\\' */ | ||
268 | p= &(buff->data[bufnum-1]); | ||
269 | if (IS_ESC(conf,p[0]) && | ||
270 | ((bufnum <= 1) || !IS_ESC(conf,p[-1]))) | ||
271 | { | ||
272 | bufnum--; | ||
273 | again=1; | ||
274 | } | ||
275 | } | ||
276 | if (again) continue; | ||
277 | bufnum=0; | ||
278 | buf=buff->data; | ||
279 | |||
280 | clear_comments(conf, buf); | ||
281 | n=strlen(buf); | ||
282 | s=eat_ws(conf, buf); | ||
283 | if (IS_EOF(conf,*s)) continue; /* blank line */ | ||
284 | if (*s == '[') | ||
285 | { | ||
286 | char *ss; | ||
287 | |||
288 | s++; | ||
289 | start=eat_ws(conf, s); | ||
290 | ss=start; | ||
291 | again: | ||
292 | end=eat_alpha_numeric(conf, ss); | ||
293 | p=eat_ws(conf, end); | ||
294 | if (*p != ']') | ||
295 | { | ||
296 | if (*p != '\0') | ||
297 | { | ||
298 | ss=p; | ||
299 | goto again; | ||
300 | } | ||
301 | CONFerr(CONF_F_CONF_LOAD_BIO, | ||
302 | CONF_R_MISSING_CLOSE_SQUARE_BRACKET); | ||
303 | goto err; | ||
304 | } | ||
305 | *end='\0'; | ||
306 | if (!str_copy(conf,NULL,§ion,start)) goto err; | ||
307 | if ((sv=_CONF_get_section(conf,section)) == NULL) | ||
308 | sv=_CONF_new_section(conf,section); | ||
309 | if (sv == NULL) | ||
310 | { | ||
311 | CONFerr(CONF_F_CONF_LOAD_BIO, | ||
312 | CONF_R_UNABLE_TO_CREATE_NEW_SECTION); | ||
313 | goto err; | ||
314 | } | ||
315 | section_sk=(STACK_OF(CONF_VALUE) *)sv->value; | ||
316 | continue; | ||
317 | } | ||
318 | else | ||
319 | { | ||
320 | pname=s; | ||
321 | psection=NULL; | ||
322 | end=eat_alpha_numeric(conf, s); | ||
323 | if ((end[0] == ':') && (end[1] == ':')) | ||
324 | { | ||
325 | *end='\0'; | ||
326 | end+=2; | ||
327 | psection=pname; | ||
328 | pname=end; | ||
329 | end=eat_alpha_numeric(conf, end); | ||
330 | } | ||
331 | p=eat_ws(conf, end); | ||
332 | if (*p != '=') | ||
333 | { | ||
334 | CONFerr(CONF_F_CONF_LOAD_BIO, | ||
335 | CONF_R_MISSING_EQUAL_SIGN); | ||
336 | goto err; | ||
337 | } | ||
338 | *end='\0'; | ||
339 | p++; | ||
340 | start=eat_ws(conf, p); | ||
341 | while (!IS_EOF(conf,*p)) | ||
342 | p++; | ||
343 | p--; | ||
344 | while ((p != start) && (IS_WS(conf,*p))) | ||
345 | p--; | ||
346 | p++; | ||
347 | *p='\0'; | ||
348 | |||
349 | if (!(v=(CONF_VALUE *)OPENSSL_malloc(sizeof(CONF_VALUE)))) | ||
350 | { | ||
351 | CONFerr(CONF_F_CONF_LOAD_BIO, | ||
352 | ERR_R_MALLOC_FAILURE); | ||
353 | goto err; | ||
354 | } | ||
355 | if (psection == NULL) psection=section; | ||
356 | v->name=(char *)OPENSSL_malloc(strlen(pname)+1); | ||
357 | v->value=NULL; | ||
358 | if (v->name == NULL) | ||
359 | { | ||
360 | CONFerr(CONF_F_CONF_LOAD_BIO, | ||
361 | ERR_R_MALLOC_FAILURE); | ||
362 | goto err; | ||
363 | } | ||
364 | strcpy(v->name,pname); | ||
365 | if (!str_copy(conf,psection,&(v->value),start)) goto err; | ||
366 | |||
367 | if (strcmp(psection,section) != 0) | ||
368 | { | ||
369 | if ((tv=_CONF_get_section(conf,psection)) | ||
370 | == NULL) | ||
371 | tv=_CONF_new_section(conf,psection); | ||
372 | if (tv == NULL) | ||
373 | { | ||
374 | CONFerr(CONF_F_CONF_LOAD_BIO, | ||
375 | CONF_R_UNABLE_TO_CREATE_NEW_SECTION); | ||
376 | goto err; | ||
377 | } | ||
378 | ts=(STACK_OF(CONF_VALUE) *)tv->value; | ||
379 | } | ||
380 | else | ||
381 | { | ||
382 | tv=sv; | ||
383 | ts=section_sk; | ||
384 | } | ||
385 | #if 1 | ||
386 | if (_CONF_add_string(conf, tv, v) == 0) | ||
387 | { | ||
388 | CONFerr(CONF_F_CONF_LOAD_BIO, | ||
389 | ERR_R_MALLOC_FAILURE); | ||
390 | goto err; | ||
391 | } | ||
392 | #else | ||
393 | v->section=tv->section; | ||
394 | if (!sk_CONF_VALUE_push(ts,v)) | ||
395 | { | ||
396 | CONFerr(CONF_F_CONF_LOAD_BIO, | ||
397 | ERR_R_MALLOC_FAILURE); | ||
398 | goto err; | ||
399 | } | ||
400 | vv=(CONF_VALUE *)lh_insert(conf->data,v); | ||
401 | if (vv != NULL) | ||
402 | { | ||
403 | sk_CONF_VALUE_delete_ptr(ts,vv); | ||
404 | OPENSSL_free(vv->name); | ||
405 | OPENSSL_free(vv->value); | ||
406 | OPENSSL_free(vv); | ||
407 | } | ||
408 | #endif | ||
409 | v=NULL; | ||
410 | } | ||
411 | } | ||
412 | if (buff != NULL) BUF_MEM_free(buff); | ||
413 | if (section != NULL) OPENSSL_free(section); | ||
414 | return(1); | ||
415 | err: | ||
416 | if (buff != NULL) BUF_MEM_free(buff); | ||
417 | if (section != NULL) OPENSSL_free(section); | ||
418 | if (line != NULL) *line=eline; | ||
419 | sprintf(btmp,"%ld",eline); | ||
420 | ERR_add_error_data(2,"line ",btmp); | ||
421 | if ((h != conf->data) && (conf->data != NULL)) CONF_free(conf->data); | ||
422 | if (v != NULL) | ||
423 | { | ||
424 | if (v->name != NULL) OPENSSL_free(v->name); | ||
425 | if (v->value != NULL) OPENSSL_free(v->value); | ||
426 | if (v != NULL) OPENSSL_free(v); | ||
427 | } | ||
428 | return(0); | ||
429 | } | ||
430 | |||
431 | static void clear_comments(CONF *conf, char *p) | ||
432 | { | ||
433 | char *to; | ||
434 | |||
435 | to=p; | ||
436 | for (;;) | ||
437 | { | ||
438 | if (IS_FCOMMENT(conf,*p)) | ||
439 | { | ||
440 | *p='\0'; | ||
441 | return; | ||
442 | } | ||
443 | if (!IS_WS(conf,*p)) | ||
444 | { | ||
445 | break; | ||
446 | } | ||
447 | p++; | ||
448 | } | ||
449 | |||
450 | for (;;) | ||
451 | { | ||
452 | if (IS_COMMENT(conf,*p)) | ||
453 | { | ||
454 | *p='\0'; | ||
455 | return; | ||
456 | } | ||
457 | if (IS_DQUOTE(conf,*p)) | ||
458 | { | ||
459 | p=scan_dquote(conf, p); | ||
460 | continue; | ||
461 | } | ||
462 | if (IS_QUOTE(conf,*p)) | ||
463 | { | ||
464 | p=scan_quote(conf, p); | ||
465 | continue; | ||
466 | } | ||
467 | if (IS_ESC(conf,*p)) | ||
468 | { | ||
469 | p=scan_esc(conf,p); | ||
470 | continue; | ||
471 | } | ||
472 | if (IS_EOF(conf,*p)) | ||
473 | return; | ||
474 | else | ||
475 | p++; | ||
476 | } | ||
477 | } | ||
478 | |||
479 | static int str_copy(CONF *conf, char *section, char **pto, char *from) | ||
480 | { | ||
481 | int q,r,rr=0,to=0,len=0; | ||
482 | char *s,*e,*rp,*p,*rrp,*np,*cp,v; | ||
483 | BUF_MEM *buf; | ||
484 | |||
485 | if ((buf=BUF_MEM_new()) == NULL) return(0); | ||
486 | |||
487 | len=strlen(from)+1; | ||
488 | if (!BUF_MEM_grow(buf,len)) goto err; | ||
489 | |||
490 | for (;;) | ||
491 | { | ||
492 | if (IS_QUOTE(conf,*from)) | ||
493 | { | ||
494 | q= *from; | ||
495 | from++; | ||
496 | while (!IS_EOF(conf,*from) && (*from != q)) | ||
497 | { | ||
498 | if (IS_ESC(conf,*from)) | ||
499 | { | ||
500 | from++; | ||
501 | if (IS_EOF(conf,*from)) break; | ||
502 | } | ||
503 | buf->data[to++]= *(from++); | ||
504 | } | ||
505 | if (*from == q) from++; | ||
506 | } | ||
507 | else if (IS_DQUOTE(conf,*from)) | ||
508 | { | ||
509 | q= *from; | ||
510 | from++; | ||
511 | while (!IS_EOF(conf,*from)) | ||
512 | { | ||
513 | if (*from == q) | ||
514 | { | ||
515 | if (*(from+1) == q) | ||
516 | { | ||
517 | from++; | ||
518 | } | ||
519 | else | ||
520 | { | ||
521 | break; | ||
522 | } | ||
523 | } | ||
524 | buf->data[to++]= *(from++); | ||
525 | } | ||
526 | if (*from == q) from++; | ||
527 | } | ||
528 | else if (IS_ESC(conf,*from)) | ||
529 | { | ||
530 | from++; | ||
531 | v= *(from++); | ||
532 | if (IS_EOF(conf,v)) break; | ||
533 | else if (v == 'r') v='\r'; | ||
534 | else if (v == 'n') v='\n'; | ||
535 | else if (v == 'b') v='\b'; | ||
536 | else if (v == 't') v='\t'; | ||
537 | buf->data[to++]= v; | ||
538 | } | ||
539 | else if (IS_EOF(conf,*from)) | ||
540 | break; | ||
541 | else if (*from == '$') | ||
542 | { | ||
543 | /* try to expand it */ | ||
544 | rrp=NULL; | ||
545 | s= &(from[1]); | ||
546 | if (*s == '{') | ||
547 | q='}'; | ||
548 | else if (*s == '(') | ||
549 | q=')'; | ||
550 | else q=0; | ||
551 | |||
552 | if (q) s++; | ||
553 | cp=section; | ||
554 | e=np=s; | ||
555 | while (IS_ALPHA_NUMERIC(conf,*e)) | ||
556 | e++; | ||
557 | if ((e[0] == ':') && (e[1] == ':')) | ||
558 | { | ||
559 | cp=np; | ||
560 | rrp=e; | ||
561 | rr= *e; | ||
562 | *rrp='\0'; | ||
563 | e+=2; | ||
564 | np=e; | ||
565 | while (IS_ALPHA_NUMERIC(conf,*e)) | ||
566 | e++; | ||
567 | } | ||
568 | r= *e; | ||
569 | *e='\0'; | ||
570 | rp=e; | ||
571 | if (q) | ||
572 | { | ||
573 | if (r != q) | ||
574 | { | ||
575 | CONFerr(CONF_F_STR_COPY,CONF_R_NO_CLOSE_BRACE); | ||
576 | goto err; | ||
577 | } | ||
578 | e++; | ||
579 | } | ||
580 | /* So at this point we have | ||
581 | * ns which is the start of the name string which is | ||
582 | * '\0' terminated. | ||
583 | * cs which is the start of the section string which is | ||
584 | * '\0' terminated. | ||
585 | * e is the 'next point after'. | ||
586 | * r and s are the chars replaced by the '\0' | ||
587 | * rp and sp is where 'r' and 's' came from. | ||
588 | */ | ||
589 | p=_CONF_get_string(conf,cp,np); | ||
590 | if (rrp != NULL) *rrp=rr; | ||
591 | *rp=r; | ||
592 | if (p == NULL) | ||
593 | { | ||
594 | CONFerr(CONF_F_STR_COPY,CONF_R_VARIABLE_HAS_NO_VALUE); | ||
595 | goto err; | ||
596 | } | ||
597 | BUF_MEM_grow(buf,(strlen(p)+len-(e-from))); | ||
598 | while (*p) | ||
599 | buf->data[to++]= *(p++); | ||
600 | from=e; | ||
601 | } | ||
602 | else | ||
603 | buf->data[to++]= *(from++); | ||
604 | } | ||
605 | buf->data[to]='\0'; | ||
606 | if (*pto != NULL) OPENSSL_free(*pto); | ||
607 | *pto=buf->data; | ||
608 | OPENSSL_free(buf); | ||
609 | return(1); | ||
610 | err: | ||
611 | if (buf != NULL) BUF_MEM_free(buf); | ||
612 | return(0); | ||
613 | } | ||
614 | |||
615 | static char *eat_ws(CONF *conf, char *p) | ||
616 | { | ||
617 | while (IS_WS(conf,*p) && (!IS_EOF(conf,*p))) | ||
618 | p++; | ||
619 | return(p); | ||
620 | } | ||
621 | |||
622 | static char *eat_alpha_numeric(CONF *conf, char *p) | ||
623 | { | ||
624 | for (;;) | ||
625 | { | ||
626 | if (IS_ESC(conf,*p)) | ||
627 | { | ||
628 | p=scan_esc(conf,p); | ||
629 | continue; | ||
630 | } | ||
631 | if (!IS_ALPHA_NUMERIC_PUNCT(conf,*p)) | ||
632 | return(p); | ||
633 | p++; | ||
634 | } | ||
635 | } | ||
636 | |||
637 | static char *scan_quote(CONF *conf, char *p) | ||
638 | { | ||
639 | int q= *p; | ||
640 | |||
641 | p++; | ||
642 | while (!(IS_EOF(conf,*p)) && (*p != q)) | ||
643 | { | ||
644 | if (IS_ESC(conf,*p)) | ||
645 | { | ||
646 | p++; | ||
647 | if (IS_EOF(conf,*p)) return(p); | ||
648 | } | ||
649 | p++; | ||
650 | } | ||
651 | if (*p == q) p++; | ||
652 | return(p); | ||
653 | } | ||
654 | |||
655 | |||
656 | static char *scan_dquote(CONF *conf, char *p) | ||
657 | { | ||
658 | int q= *p; | ||
659 | |||
660 | p++; | ||
661 | while (!(IS_EOF(conf,*p))) | ||
662 | { | ||
663 | if (*p == q) | ||
664 | { | ||
665 | if (*(p+1) == q) | ||
666 | { | ||
667 | p++; | ||
668 | } | ||
669 | else | ||
670 | { | ||
671 | break; | ||
672 | } | ||
673 | } | ||
674 | p++; | ||
675 | } | ||
676 | if (*p == q) p++; | ||
677 | return(p); | ||
678 | } | ||
679 | |||
680 | static void dump_value(CONF_VALUE *a, BIO *out) | ||
681 | { | ||
682 | if (a->name) | ||
683 | BIO_printf(out, "[%s] %s=%s\n", a->section, a->name, a->value); | ||
684 | else | ||
685 | BIO_printf(out, "[[%s]]\n", a->section); | ||
686 | } | ||
687 | |||
688 | static int def_dump(CONF *conf, BIO *out) | ||
689 | { | ||
690 | lh_doall_arg(conf->data, (void (*)())dump_value, out); | ||
691 | return 1; | ||
692 | } | ||
693 | |||
694 | static int def_is_number(CONF *conf, char c) | ||
695 | { | ||
696 | return IS_NUMBER(conf,c); | ||
697 | } | ||
698 | |||
699 | static int def_to_int(CONF *conf, char c) | ||
700 | { | ||
701 | return c - '0'; | ||
702 | } | ||
703 | |||
diff --git a/src/lib/libcrypto/conf/conf_def.h b/src/lib/libcrypto/conf/conf_def.h new file mode 100644 index 0000000000..3244d9a331 --- /dev/null +++ b/src/lib/libcrypto/conf/conf_def.h | |||
@@ -0,0 +1,145 @@ | |||
1 | /* crypto/conf/conf_def.h */ | ||
2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) | ||
3 | * All rights reserved. | ||
4 | * | ||
5 | * This package is an SSL implementation written | ||
6 | * by Eric Young (eay@cryptsoft.com). | ||
7 | * The implementation was written so as to conform with Netscapes SSL. | ||
8 | * | ||
9 | * This library is free for commercial and non-commercial use as long as | ||
10 | * the following conditions are aheared to. The following conditions | ||
11 | * apply to all code found in this distribution, be it the RC4, RSA, | ||
12 | * lhash, DES, etc., code; not just the SSL code. The SSL documentation | ||
13 | * included with this distribution is covered by the same copyright terms | ||
14 | * except that the holder is Tim Hudson (tjh@cryptsoft.com). | ||
15 | * | ||
16 | * Copyright remains Eric Young's, and as such any Copyright notices in | ||
17 | * the code are not to be removed. | ||
18 | * If this package is used in a product, Eric Young should be given attribution | ||
19 | * as the author of the parts of the library used. | ||
20 | * This can be in the form of a textual message at program startup or | ||
21 | * in documentation (online or textual) provided with the package. | ||
22 | * | ||
23 | * Redistribution and use in source and binary forms, with or without | ||
24 | * modification, are permitted provided that the following conditions | ||
25 | * are met: | ||
26 | * 1. Redistributions of source code must retain the copyright | ||
27 | * notice, this list of conditions and the following disclaimer. | ||
28 | * 2. Redistributions in binary form must reproduce the above copyright | ||
29 | * notice, this list of conditions and the following disclaimer in the | ||
30 | * documentation and/or other materials provided with the distribution. | ||
31 | * 3. All advertising materials mentioning features or use of this software | ||
32 | * must display the following acknowledgement: | ||
33 | * "This product includes cryptographic software written by | ||
34 | * Eric Young (eay@cryptsoft.com)" | ||
35 | * The word 'cryptographic' can be left out if the rouines from the library | ||
36 | * being used are not cryptographic related :-). | ||
37 | * 4. If you include any Windows specific code (or a derivative thereof) from | ||
38 | * the apps directory (application code) you must include an acknowledgement: | ||
39 | * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" | ||
40 | * | ||
41 | * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND | ||
42 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
43 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
44 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | ||
45 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
46 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
47 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
48 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
49 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
50 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
51 | * SUCH DAMAGE. | ||
52 | * | ||
53 | * The licence and distribution terms for any publically available version or | ||
54 | * derivative of this code cannot be changed. i.e. this code cannot simply be | ||
55 | * copied and put under another distribution licence | ||
56 | * [including the GNU Public Licence.] | ||
57 | */ | ||
58 | |||
59 | /* THIS FILE WAS AUTOMAGICALLY GENERATED! | ||
60 | Please modify and use keysets.pl to regenerate it. */ | ||
61 | |||
62 | #define CONF_NUMBER 1 | ||
63 | #define CONF_UPPER 2 | ||
64 | #define CONF_LOWER 4 | ||
65 | #define CONF_UNDER 256 | ||
66 | #define CONF_PUNCTUATION 512 | ||
67 | #define CONF_WS 16 | ||
68 | #define CONF_ESC 32 | ||
69 | #define CONF_QUOTE 64 | ||
70 | #define CONF_DQUOTE 1024 | ||
71 | #define CONF_COMMENT 128 | ||
72 | #define CONF_FCOMMENT 2048 | ||
73 | #define CONF_EOF 8 | ||
74 | #define CONF_ALPHA (CONF_UPPER|CONF_LOWER) | ||
75 | #define CONF_ALPHA_NUMERIC (CONF_ALPHA|CONF_NUMBER|CONF_UNDER) | ||
76 | #define CONF_ALPHA_NUMERIC_PUNCT (CONF_ALPHA|CONF_NUMBER|CONF_UNDER| \ | ||
77 | CONF_PUNCTUATION) | ||
78 | |||
79 | #define KEYTYPES(c) ((unsigned short *)((c)->meth_data)) | ||
80 | #ifndef CHARSET_EBCDIC | ||
81 | #define IS_COMMENT(c,a) (KEYTYPES(c)[(a)&0x7f]&CONF_COMMENT) | ||
82 | #define IS_FCOMMENT(c,a) (KEYTYPES(c)[(a)&0x7f]&CONF_FCOMMENT) | ||
83 | #define IS_EOF(c,a) (KEYTYPES(c)[(a)&0x7f]&CONF_EOF) | ||
84 | #define IS_ESC(c,a) (KEYTYPES(c)[(a)&0x7f]&CONF_ESC) | ||
85 | #define IS_NUMBER(c,a) (KEYTYPES(c)[(a)&0x7f]&CONF_NUMBER) | ||
86 | #define IS_WS(c,a) (KEYTYPES(c)[(a)&0x7f]&CONF_WS) | ||
87 | #define IS_ALPHA_NUMERIC(c,a) (KEYTYPES(c)[(a)&0x7f]&CONF_ALPHA_NUMERIC) | ||
88 | #define IS_ALPHA_NUMERIC_PUNCT(c,a) \ | ||
89 | (KEYTYPES(c)[(a)&0x7f]&CONF_ALPHA_NUMERIC_PUNCT) | ||
90 | #define IS_QUOTE(c,a) (KEYTYPES(c)[(a)&0x7f]&CONF_QUOTE) | ||
91 | #define IS_DQUOTE(c,a) (KEYTYPES(c)[(a)&0x7f]&CONF_DQUOTE) | ||
92 | |||
93 | #else /*CHARSET_EBCDIC*/ | ||
94 | |||
95 | #define IS_COMMENT(c,a) (KEYTYPES(c)[os_toascii[a]&0x7f]&CONF_COMMENT) | ||
96 | #define IS_FCOMMENT(c,a) (KEYTYPES(c)[os_toascii[a]&0x7f]&CONF_FCOMMENT) | ||
97 | #define IS_EOF(c,a) (KEYTYPES(c)[os_toascii[a]&0x7f]&CONF_EOF) | ||
98 | #define IS_ESC(c,a) (KEYTYPES(c)[os_toascii[a]&0x7f]&CONF_ESC) | ||
99 | #define IS_NUMBER(c,a) (KEYTYPES(c)[os_toascii[a]&0x7f]&CONF_NUMBER) | ||
100 | #define IS_WS(c,a) (KEYTYPES(c)[os_toascii[a]&0x7f]&CONF_WS) | ||
101 | #define IS_ALPHA_NUMERIC(c,a) (KEYTYPES(c)[os_toascii[a]&0x7f]&CONF_ALPHA_NUMERIC) | ||
102 | #define IS_ALPHA_NUMERIC_PUNCT(c,a) \ | ||
103 | (KEYTYPES(c)[os_toascii[a]&0x7f]&CONF_ALPHA_NUMERIC_PUNCT) | ||
104 | #define IS_QUOTE(c,a) (KEYTYPES(c)[os_toascii[a]&0x7f]&CONF_QUOTE) | ||
105 | #define IS_DQUOTE(c,a) (KEYTYPES(c)[os_toascii[a]&0x7f]&CONF_DQUOTE) | ||
106 | #endif /*CHARSET_EBCDIC*/ | ||
107 | |||
108 | static unsigned short CONF_type_default[128]={ | ||
109 | 0x008,0x000,0x000,0x000,0x000,0x000,0x000,0x000, | ||
110 | 0x000,0x010,0x010,0x000,0x000,0x010,0x000,0x000, | ||
111 | 0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000, | ||
112 | 0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000, | ||
113 | 0x010,0x200,0x040,0x080,0x000,0x200,0x200,0x040, | ||
114 | 0x000,0x000,0x200,0x200,0x200,0x200,0x200,0x200, | ||
115 | 0x001,0x001,0x001,0x001,0x001,0x001,0x001,0x001, | ||
116 | 0x001,0x001,0x000,0x200,0x000,0x000,0x000,0x200, | ||
117 | 0x200,0x002,0x002,0x002,0x002,0x002,0x002,0x002, | ||
118 | 0x002,0x002,0x002,0x002,0x002,0x002,0x002,0x002, | ||
119 | 0x002,0x002,0x002,0x002,0x002,0x002,0x002,0x002, | ||
120 | 0x002,0x002,0x002,0x000,0x020,0x000,0x200,0x100, | ||
121 | 0x040,0x004,0x004,0x004,0x004,0x004,0x004,0x004, | ||
122 | 0x004,0x004,0x004,0x004,0x004,0x004,0x004,0x004, | ||
123 | 0x004,0x004,0x004,0x004,0x004,0x004,0x004,0x004, | ||
124 | 0x004,0x004,0x004,0x000,0x200,0x000,0x200,0x000, | ||
125 | }; | ||
126 | |||
127 | static unsigned short CONF_type_win32[128]={ | ||
128 | 0x008,0x000,0x000,0x000,0x000,0x000,0x000,0x000, | ||
129 | 0x000,0x010,0x010,0x000,0x000,0x010,0x000,0x000, | ||
130 | 0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000, | ||
131 | 0x000,0x000,0x000,0x000,0x000,0x000,0x000,0x000, | ||
132 | 0x010,0x200,0x400,0x000,0x000,0x200,0x200,0x000, | ||
133 | 0x000,0x000,0x200,0x200,0x200,0x200,0x200,0x200, | ||
134 | 0x001,0x001,0x001,0x001,0x001,0x001,0x001,0x001, | ||
135 | 0x001,0x001,0x000,0xA00,0x000,0x000,0x000,0x200, | ||
136 | 0x200,0x002,0x002,0x002,0x002,0x002,0x002,0x002, | ||
137 | 0x002,0x002,0x002,0x002,0x002,0x002,0x002,0x002, | ||
138 | 0x002,0x002,0x002,0x002,0x002,0x002,0x002,0x002, | ||
139 | 0x002,0x002,0x002,0x000,0x000,0x000,0x200,0x100, | ||
140 | 0x000,0x004,0x004,0x004,0x004,0x004,0x004,0x004, | ||
141 | 0x004,0x004,0x004,0x004,0x004,0x004,0x004,0x004, | ||
142 | 0x004,0x004,0x004,0x004,0x004,0x004,0x004,0x004, | ||
143 | 0x004,0x004,0x004,0x000,0x200,0x000,0x200,0x000, | ||
144 | }; | ||
145 | |||
diff --git a/src/lib/libcrypto/conf/conf_lib.c b/src/lib/libcrypto/conf/conf_lib.c new file mode 100644 index 0000000000..4c8ca9e9ae --- /dev/null +++ b/src/lib/libcrypto/conf/conf_lib.c | |||
@@ -0,0 +1,352 @@ | |||
1 | /* conf_lib.c */ | ||
2 | /* Written by Richard Levitte (richard@levitte.org) for the OpenSSL | ||
3 | * project 2000. | ||
4 | */ | ||
5 | /* ==================================================================== | ||
6 | * Copyright (c) 2000 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 | #include <openssl/crypto.h> | ||
61 | #include <openssl/err.h> | ||
62 | #include <openssl/conf.h> | ||
63 | #include <openssl/conf_api.h> | ||
64 | #include <openssl/lhash.h> | ||
65 | |||
66 | const char *CONF_version="CONF" OPENSSL_VERSION_PTEXT; | ||
67 | |||
68 | static CONF_METHOD *default_CONF_method=NULL; | ||
69 | |||
70 | /* The following section contains the "CONF classic" functions, | ||
71 | rewritten in terms of the new CONF interface. */ | ||
72 | |||
73 | int CONF_set_default_method(CONF_METHOD *meth) | ||
74 | { | ||
75 | default_CONF_method = meth; | ||
76 | return 1; | ||
77 | } | ||
78 | |||
79 | LHASH *CONF_load(LHASH *conf, const char *file, long *eline) | ||
80 | { | ||
81 | LHASH *ltmp; | ||
82 | BIO *in=NULL; | ||
83 | |||
84 | #ifdef VMS | ||
85 | in=BIO_new_file(file, "r"); | ||
86 | #else | ||
87 | in=BIO_new_file(file, "rb"); | ||
88 | #endif | ||
89 | if (in == NULL) | ||
90 | { | ||
91 | CONFerr(CONF_F_CONF_LOAD,ERR_R_SYS_LIB); | ||
92 | return NULL; | ||
93 | } | ||
94 | |||
95 | ltmp = CONF_load_bio(conf, in, eline); | ||
96 | BIO_free(in); | ||
97 | |||
98 | return ltmp; | ||
99 | } | ||
100 | |||
101 | #ifndef NO_FP_API | ||
102 | LHASH *CONF_load_fp(LHASH *conf, FILE *fp,long *eline) | ||
103 | { | ||
104 | BIO *btmp; | ||
105 | LHASH *ltmp; | ||
106 | if(!(btmp = BIO_new_fp(fp, BIO_NOCLOSE))) { | ||
107 | CONFerr(CONF_F_CONF_LOAD_FP,ERR_R_BUF_LIB); | ||
108 | return NULL; | ||
109 | } | ||
110 | ltmp = CONF_load_bio(conf, btmp, eline); | ||
111 | BIO_free(btmp); | ||
112 | return ltmp; | ||
113 | } | ||
114 | #endif | ||
115 | |||
116 | LHASH *CONF_load_bio(LHASH *conf, BIO *bp,long *eline) | ||
117 | { | ||
118 | CONF ctmp; | ||
119 | int ret; | ||
120 | |||
121 | if (default_CONF_method == NULL) | ||
122 | default_CONF_method = NCONF_default(); | ||
123 | |||
124 | default_CONF_method->init(&ctmp); | ||
125 | ctmp.data = conf; | ||
126 | ret = NCONF_load_bio(&ctmp, bp, eline); | ||
127 | if (ret) | ||
128 | return ctmp.data; | ||
129 | return NULL; | ||
130 | } | ||
131 | |||
132 | STACK_OF(CONF_VALUE) *CONF_get_section(LHASH *conf,char *section) | ||
133 | { | ||
134 | CONF ctmp; | ||
135 | |||
136 | if (default_CONF_method == NULL) | ||
137 | default_CONF_method = NCONF_default(); | ||
138 | |||
139 | default_CONF_method->init(&ctmp); | ||
140 | ctmp.data = conf; | ||
141 | return NCONF_get_section(&ctmp, section); | ||
142 | } | ||
143 | |||
144 | char *CONF_get_string(LHASH *conf,char *group,char *name) | ||
145 | { | ||
146 | CONF ctmp; | ||
147 | |||
148 | if (default_CONF_method == NULL) | ||
149 | default_CONF_method = NCONF_default(); | ||
150 | |||
151 | default_CONF_method->init(&ctmp); | ||
152 | ctmp.data = conf; | ||
153 | return NCONF_get_string(&ctmp, group, name); | ||
154 | } | ||
155 | |||
156 | long CONF_get_number(LHASH *conf,char *group,char *name) | ||
157 | { | ||
158 | CONF ctmp; | ||
159 | |||
160 | if (default_CONF_method == NULL) | ||
161 | default_CONF_method = NCONF_default(); | ||
162 | |||
163 | default_CONF_method->init(&ctmp); | ||
164 | ctmp.data = conf; | ||
165 | return NCONF_get_number(&ctmp, group, name); | ||
166 | } | ||
167 | |||
168 | void CONF_free(LHASH *conf) | ||
169 | { | ||
170 | CONF ctmp; | ||
171 | |||
172 | if (default_CONF_method == NULL) | ||
173 | default_CONF_method = NCONF_default(); | ||
174 | |||
175 | default_CONF_method->init(&ctmp); | ||
176 | ctmp.data = conf; | ||
177 | NCONF_free_data(&ctmp); | ||
178 | } | ||
179 | |||
180 | #ifndef NO_FP_API | ||
181 | int CONF_dump_fp(LHASH *conf, FILE *out) | ||
182 | { | ||
183 | BIO *btmp; | ||
184 | int ret; | ||
185 | |||
186 | if(!(btmp = BIO_new_fp(out, BIO_NOCLOSE))) { | ||
187 | CONFerr(CONF_F_CONF_DUMP_FP,ERR_R_BUF_LIB); | ||
188 | return 0; | ||
189 | } | ||
190 | ret = CONF_dump_bio(conf, btmp); | ||
191 | BIO_free(btmp); | ||
192 | return ret; | ||
193 | } | ||
194 | #endif | ||
195 | |||
196 | int CONF_dump_bio(LHASH *conf, BIO *out) | ||
197 | { | ||
198 | CONF ctmp; | ||
199 | |||
200 | if (default_CONF_method == NULL) | ||
201 | default_CONF_method = NCONF_default(); | ||
202 | |||
203 | default_CONF_method->init(&ctmp); | ||
204 | ctmp.data = conf; | ||
205 | return NCONF_dump_bio(&ctmp, out); | ||
206 | } | ||
207 | |||
208 | /* The following section contains the "New CONF" functions. They are | ||
209 | completely centralised around a new CONF structure that may contain | ||
210 | basically anything, but at least a method pointer and a table of data. | ||
211 | These functions are also written in terms of the bridge functions used | ||
212 | by the "CONF classic" functions, for consistency. */ | ||
213 | |||
214 | CONF *NCONF_new(CONF_METHOD *meth) | ||
215 | { | ||
216 | CONF *ret; | ||
217 | |||
218 | if (meth == NULL) | ||
219 | meth = NCONF_default(); | ||
220 | |||
221 | ret = meth->create(meth); | ||
222 | if (ret == NULL) | ||
223 | { | ||
224 | CONFerr(CONF_F_NCONF_NEW,ERR_R_MALLOC_FAILURE); | ||
225 | return(NULL); | ||
226 | } | ||
227 | |||
228 | return ret; | ||
229 | } | ||
230 | |||
231 | void NCONF_free(CONF *conf) | ||
232 | { | ||
233 | if (conf == NULL) | ||
234 | return; | ||
235 | conf->meth->destroy(conf); | ||
236 | } | ||
237 | |||
238 | void NCONF_free_data(CONF *conf) | ||
239 | { | ||
240 | if (conf == NULL) | ||
241 | return; | ||
242 | conf->meth->destroy_data(conf); | ||
243 | } | ||
244 | |||
245 | int NCONF_load(CONF *conf, const char *file, long *eline) | ||
246 | { | ||
247 | int ret; | ||
248 | BIO *in=NULL; | ||
249 | |||
250 | #ifdef VMS | ||
251 | in=BIO_new_file(file, "r"); | ||
252 | #else | ||
253 | in=BIO_new_file(file, "rb"); | ||
254 | #endif | ||
255 | if (in == NULL) | ||
256 | { | ||
257 | CONFerr(CONF_F_CONF_LOAD,ERR_R_SYS_LIB); | ||
258 | return 0; | ||
259 | } | ||
260 | |||
261 | ret = NCONF_load_bio(conf, in, eline); | ||
262 | BIO_free(in); | ||
263 | |||
264 | return ret; | ||
265 | } | ||
266 | |||
267 | #ifndef NO_FP_API | ||
268 | int NCONF_load_fp(CONF *conf, FILE *fp,long *eline) | ||
269 | { | ||
270 | BIO *btmp; | ||
271 | int ret; | ||
272 | if(!(btmp = BIO_new_fp(fp, BIO_NOCLOSE))) | ||
273 | { | ||
274 | CONFerr(CONF_F_CONF_LOAD_FP,ERR_R_BUF_LIB); | ||
275 | return 0; | ||
276 | } | ||
277 | ret = NCONF_load_bio(conf, btmp, eline); | ||
278 | BIO_free(btmp); | ||
279 | return ret; | ||
280 | } | ||
281 | #endif | ||
282 | |||
283 | int NCONF_load_bio(CONF *conf, BIO *bp,long *eline) | ||
284 | { | ||
285 | if (conf == NULL) | ||
286 | { | ||
287 | CONFerr(CONF_F_NCONF_LOAD_BIO,CONF_R_NO_CONF); | ||
288 | return 0; | ||
289 | } | ||
290 | |||
291 | return conf->meth->load(conf, bp, eline); | ||
292 | } | ||
293 | |||
294 | STACK_OF(CONF_VALUE) *NCONF_get_section(CONF *conf,char *section) | ||
295 | { | ||
296 | if (conf == NULL) | ||
297 | { | ||
298 | CONFerr(CONF_F_NCONF_GET_SECTION,CONF_R_NO_CONF); | ||
299 | return NULL; | ||
300 | } | ||
301 | |||
302 | return _CONF_get_section_values(conf, section); | ||
303 | } | ||
304 | |||
305 | char *NCONF_get_string(CONF *conf,char *group,char *name) | ||
306 | { | ||
307 | if (conf == NULL) | ||
308 | { | ||
309 | CONFerr(CONF_F_NCONF_GET_STRING,CONF_R_NO_CONF); | ||
310 | return NULL; | ||
311 | } | ||
312 | |||
313 | return _CONF_get_string(conf, group, name); | ||
314 | } | ||
315 | |||
316 | long NCONF_get_number(CONF *conf,char *group,char *name) | ||
317 | { | ||
318 | if (conf == NULL) | ||
319 | { | ||
320 | CONFerr(CONF_F_NCONF_GET_NUMBER,CONF_R_NO_CONF); | ||
321 | return 0; | ||
322 | } | ||
323 | |||
324 | return _CONF_get_number(conf, group, name); | ||
325 | } | ||
326 | |||
327 | #ifndef NO_FP_API | ||
328 | int NCONF_dump_fp(CONF *conf, FILE *out) | ||
329 | { | ||
330 | BIO *btmp; | ||
331 | int ret; | ||
332 | if(!(btmp = BIO_new_fp(out, BIO_NOCLOSE))) { | ||
333 | CONFerr(CONF_F_NCONF_DUMP_FP,ERR_R_BUF_LIB); | ||
334 | return 0; | ||
335 | } | ||
336 | ret = NCONF_dump_bio(conf, btmp); | ||
337 | BIO_free(btmp); | ||
338 | return ret; | ||
339 | } | ||
340 | #endif | ||
341 | |||
342 | int NCONF_dump_bio(CONF *conf, BIO *out) | ||
343 | { | ||
344 | if (conf == NULL) | ||
345 | { | ||
346 | CONFerr(CONF_F_NCONF_DUMP_BIO,CONF_R_NO_CONF); | ||
347 | return 0; | ||
348 | } | ||
349 | |||
350 | return conf->meth->dump(conf, out); | ||
351 | } | ||
352 | |||
diff --git a/src/lib/libcrypto/conf/conf_mall.c b/src/lib/libcrypto/conf/conf_mall.c new file mode 100644 index 0000000000..d702af689b --- /dev/null +++ b/src/lib/libcrypto/conf/conf_mall.c | |||
@@ -0,0 +1,76 @@ | |||
1 | /* conf_mall.c */ | ||
2 | /* Written by Stephen Henson (shenson@bigfoot.com) for the OpenSSL | ||
3 | * project 2001. | ||
4 | */ | ||
5 | /* ==================================================================== | ||
6 | * Copyright (c) 2001 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 | #include <openssl/crypto.h> | ||
61 | #include "cryptlib.h" | ||
62 | #include <openssl/conf.h> | ||
63 | #include <openssl/dso.h> | ||
64 | #include <openssl/x509.h> | ||
65 | #include <openssl/asn1.h> | ||
66 | #include <openssl/engine.h> | ||
67 | |||
68 | /* Load all OpenSSL builtin modules */ | ||
69 | |||
70 | void OPENSSL_load_builtin_modules(void) | ||
71 | { | ||
72 | /* Add builtin modules here */ | ||
73 | ASN1_add_oid_module(); | ||
74 | ENGINE_add_conf_module(); | ||
75 | } | ||
76 | |||
diff --git a/src/lib/libcrypto/conf/conf_mod.c b/src/lib/libcrypto/conf/conf_mod.c new file mode 100644 index 0000000000..f92babc2e2 --- /dev/null +++ b/src/lib/libcrypto/conf/conf_mod.c | |||
@@ -0,0 +1,616 @@ | |||
1 | /* conf_mod.c */ | ||
2 | /* Written by Stephen Henson (shenson@bigfoot.com) for the OpenSSL | ||
3 | * project 2001. | ||
4 | */ | ||
5 | /* ==================================================================== | ||
6 | * Copyright (c) 2001 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 | #include <ctype.h> | ||
61 | #include <openssl/crypto.h> | ||
62 | #include "cryptlib.h" | ||
63 | #include <openssl/conf.h> | ||
64 | #include <openssl/dso.h> | ||
65 | #include <openssl/x509.h> | ||
66 | |||
67 | |||
68 | #define DSO_mod_init_name "OPENSSL_init" | ||
69 | #define DSO_mod_finish_name "OPENSSL_finish" | ||
70 | |||
71 | |||
72 | /* This structure contains a data about supported modules. | ||
73 | * entries in this table correspond to either dynamic or | ||
74 | * static modules. | ||
75 | */ | ||
76 | |||
77 | struct conf_module_st | ||
78 | { | ||
79 | /* DSO of this module or NULL if static */ | ||
80 | DSO *dso; | ||
81 | /* Name of the module */ | ||
82 | char *name; | ||
83 | /* Init function */ | ||
84 | conf_init_func *init; | ||
85 | /* Finish function */ | ||
86 | conf_finish_func *finish; | ||
87 | /* Number of successfully initialized modules */ | ||
88 | int links; | ||
89 | void *usr_data; | ||
90 | }; | ||
91 | |||
92 | |||
93 | /* This structure contains information about modules that have been | ||
94 | * successfully initialized. There may be more than one entry for a | ||
95 | * given module. | ||
96 | */ | ||
97 | |||
98 | struct conf_imodule_st | ||
99 | { | ||
100 | CONF_MODULE *pmod; | ||
101 | char *name; | ||
102 | char *value; | ||
103 | unsigned long flags; | ||
104 | void *usr_data; | ||
105 | }; | ||
106 | |||
107 | static STACK_OF(CONF_MODULE) *supported_modules = NULL; | ||
108 | static STACK_OF(CONF_IMODULE) *initialized_modules = NULL; | ||
109 | |||
110 | static void module_free(CONF_MODULE *md); | ||
111 | static void module_finish(CONF_IMODULE *imod); | ||
112 | static int module_run(const CONF *cnf, char *name, char *value, | ||
113 | unsigned long flags); | ||
114 | static CONF_MODULE *module_add(DSO *dso, const char *name, | ||
115 | conf_init_func *ifunc, conf_finish_func *ffunc); | ||
116 | static CONF_MODULE *module_find(char *name); | ||
117 | static int module_init(CONF_MODULE *pmod, char *name, char *value, | ||
118 | const CONF *cnf); | ||
119 | static CONF_MODULE *module_load_dso(const CONF *cnf, char *name, char *value, | ||
120 | unsigned long flags); | ||
121 | |||
122 | /* Main function: load modules from a CONF structure */ | ||
123 | |||
124 | int CONF_modules_load(const CONF *cnf, const char *appname, | ||
125 | unsigned long flags) | ||
126 | { | ||
127 | STACK_OF(CONF_VALUE) *values; | ||
128 | CONF_VALUE *vl; | ||
129 | char *vsection; | ||
130 | |||
131 | int ret, i; | ||
132 | |||
133 | if (!cnf) | ||
134 | return 1; | ||
135 | |||
136 | if (appname == NULL) | ||
137 | appname = "openssl_conf"; | ||
138 | |||
139 | vsection = NCONF_get_string(cnf, NULL, appname); | ||
140 | |||
141 | if (!vsection) | ||
142 | { | ||
143 | ERR_clear_error(); | ||
144 | return 1; | ||
145 | } | ||
146 | |||
147 | values = NCONF_get_section(cnf, vsection); | ||
148 | |||
149 | if (!values) | ||
150 | return 0; | ||
151 | |||
152 | for (i = 0; i < sk_CONF_VALUE_num(values); i++) | ||
153 | { | ||
154 | vl = sk_CONF_VALUE_value(values, i); | ||
155 | ret = module_run(cnf, vl->name, vl->value, flags); | ||
156 | if (ret <= 0) | ||
157 | if(!(flags & CONF_MFLAGS_IGNORE_ERRORS)) | ||
158 | return ret; | ||
159 | } | ||
160 | |||
161 | return 1; | ||
162 | |||
163 | } | ||
164 | |||
165 | int CONF_modules_load_file(const char *filename, const char *appname, | ||
166 | unsigned long flags) | ||
167 | { | ||
168 | char *file = NULL; | ||
169 | CONF *conf = NULL; | ||
170 | int ret = 0; | ||
171 | conf = NCONF_new(NULL); | ||
172 | if (!conf) | ||
173 | goto err; | ||
174 | |||
175 | if (filename == NULL) | ||
176 | { | ||
177 | file = CONF_get1_default_config_file(); | ||
178 | if (!file) | ||
179 | goto err; | ||
180 | } | ||
181 | else | ||
182 | file = (char *)filename; | ||
183 | |||
184 | if (NCONF_load(conf, file, NULL) <= 0) | ||
185 | { | ||
186 | if ((flags & CONF_MFLAGS_IGNORE_MISSING_FILE) && | ||
187 | (ERR_GET_REASON(ERR_peek_last_error()) == CONF_R_NO_SUCH_FILE)) | ||
188 | { | ||
189 | ERR_clear_error(); | ||
190 | ret = 1; | ||
191 | } | ||
192 | goto err; | ||
193 | } | ||
194 | |||
195 | ret = CONF_modules_load(conf, appname, flags); | ||
196 | |||
197 | err: | ||
198 | if (filename == NULL) | ||
199 | OPENSSL_free(file); | ||
200 | NCONF_free(conf); | ||
201 | |||
202 | return ret; | ||
203 | } | ||
204 | |||
205 | static int module_run(const CONF *cnf, char *name, char *value, | ||
206 | unsigned long flags) | ||
207 | { | ||
208 | CONF_MODULE *md; | ||
209 | int ret; | ||
210 | |||
211 | md = module_find(name); | ||
212 | |||
213 | /* Module not found: try to load DSO */ | ||
214 | if (!md && !(flags & CONF_MFLAGS_NO_DSO)) | ||
215 | md = module_load_dso(cnf, name, value, flags); | ||
216 | |||
217 | if (!md) | ||
218 | { | ||
219 | if (!(flags & CONF_MFLAGS_SILENT)) | ||
220 | { | ||
221 | CONFerr(CONF_F_MODULE_RUN, CONF_R_UNKNOWN_MODULE_NAME); | ||
222 | ERR_add_error_data(2, "module=", name); | ||
223 | } | ||
224 | return -1; | ||
225 | } | ||
226 | |||
227 | ret = module_init(md, name, value, cnf); | ||
228 | |||
229 | if (ret <= 0) | ||
230 | { | ||
231 | if (!(flags & CONF_MFLAGS_SILENT)) | ||
232 | { | ||
233 | char rcode[10]; | ||
234 | CONFerr(CONF_F_CONF_MODULES_LOAD, CONF_R_MODULE_INITIALIZATION_ERROR); | ||
235 | sprintf(rcode, "%-8d", ret); | ||
236 | ERR_add_error_data(6, "module=", name, ", value=", value, ", retcode=", rcode); | ||
237 | } | ||
238 | } | ||
239 | |||
240 | return ret; | ||
241 | } | ||
242 | |||
243 | /* Load a module from a DSO */ | ||
244 | static CONF_MODULE *module_load_dso(const CONF *cnf, char *name, char *value, | ||
245 | unsigned long flags) | ||
246 | { | ||
247 | DSO *dso = NULL; | ||
248 | conf_init_func *ifunc; | ||
249 | conf_finish_func *ffunc; | ||
250 | char *path = NULL; | ||
251 | int errcode = 0; | ||
252 | CONF_MODULE *md; | ||
253 | /* Look for alternative path in module section */ | ||
254 | path = NCONF_get_string(cnf, value, "path"); | ||
255 | if (!path) | ||
256 | { | ||
257 | ERR_get_error(); | ||
258 | path = name; | ||
259 | } | ||
260 | dso = DSO_load(NULL, path, NULL, 0); | ||
261 | if (!dso) | ||
262 | { | ||
263 | errcode = CONF_R_ERROR_LOADING_DSO; | ||
264 | goto err; | ||
265 | } | ||
266 | ifunc = (conf_init_func *)DSO_bind_func(dso, DSO_mod_init_name); | ||
267 | if (!ifunc) | ||
268 | { | ||
269 | errcode = CONF_R_MISSING_INIT_FUNCTION; | ||
270 | goto err; | ||
271 | } | ||
272 | ffunc = (conf_finish_func *)DSO_bind_func(dso, DSO_mod_finish_name); | ||
273 | /* All OK, add module */ | ||
274 | md = module_add(dso, name, ifunc, ffunc); | ||
275 | |||
276 | if (!md) | ||
277 | goto err; | ||
278 | |||
279 | return md; | ||
280 | |||
281 | err: | ||
282 | if (dso) | ||
283 | DSO_free(dso); | ||
284 | CONFerr(CONF_F_MODULE_LOAD_DSO, errcode); | ||
285 | ERR_add_error_data(4, "module=", name, ", path=", path); | ||
286 | return NULL; | ||
287 | } | ||
288 | |||
289 | /* add module to list */ | ||
290 | static CONF_MODULE *module_add(DSO *dso, const char *name, | ||
291 | conf_init_func *ifunc, conf_finish_func *ffunc) | ||
292 | { | ||
293 | CONF_MODULE *tmod = NULL; | ||
294 | if (supported_modules == NULL) | ||
295 | supported_modules = sk_CONF_MODULE_new_null(); | ||
296 | if (supported_modules == NULL) | ||
297 | return NULL; | ||
298 | tmod = OPENSSL_malloc(sizeof(CONF_MODULE)); | ||
299 | if (tmod == NULL) | ||
300 | return NULL; | ||
301 | |||
302 | tmod->dso = dso; | ||
303 | tmod->name = BUF_strdup(name); | ||
304 | tmod->init = ifunc; | ||
305 | tmod->finish = ffunc; | ||
306 | tmod->links = 0; | ||
307 | |||
308 | if (!sk_CONF_MODULE_push(supported_modules, tmod)) | ||
309 | { | ||
310 | OPENSSL_free(tmod); | ||
311 | return NULL; | ||
312 | } | ||
313 | |||
314 | return tmod; | ||
315 | } | ||
316 | |||
317 | /* Find a module from the list. We allow module names of the | ||
318 | * form modname.XXXX to just search for modname to allow the | ||
319 | * same module to be initialized more than once. | ||
320 | */ | ||
321 | |||
322 | static CONF_MODULE *module_find(char *name) | ||
323 | { | ||
324 | CONF_MODULE *tmod; | ||
325 | int i, nchar; | ||
326 | char *p; | ||
327 | p = strrchr(name, '.'); | ||
328 | |||
329 | if (p) | ||
330 | nchar = p - name; | ||
331 | else | ||
332 | nchar = strlen(name); | ||
333 | |||
334 | for (i = 0; i < sk_CONF_MODULE_num(supported_modules); i++) | ||
335 | { | ||
336 | tmod = sk_CONF_MODULE_value(supported_modules, i); | ||
337 | if (!strncmp(tmod->name, name, nchar)) | ||
338 | return tmod; | ||
339 | } | ||
340 | |||
341 | return NULL; | ||
342 | |||
343 | } | ||
344 | |||
345 | /* initialize a module */ | ||
346 | static int module_init(CONF_MODULE *pmod, char *name, char *value, | ||
347 | const CONF *cnf) | ||
348 | { | ||
349 | int ret = 1; | ||
350 | int init_called = 0; | ||
351 | CONF_IMODULE *imod = NULL; | ||
352 | |||
353 | /* Otherwise add initialized module to list */ | ||
354 | imod = OPENSSL_malloc(sizeof(CONF_IMODULE)); | ||
355 | if (!imod) | ||
356 | goto err; | ||
357 | |||
358 | imod->pmod = pmod; | ||
359 | imod->name = BUF_strdup(name); | ||
360 | imod->value = BUF_strdup(value); | ||
361 | imod->usr_data = NULL; | ||
362 | |||
363 | if (!imod->name || !imod->value) | ||
364 | goto memerr; | ||
365 | |||
366 | /* Try to initialize module */ | ||
367 | if(pmod->init) | ||
368 | { | ||
369 | ret = pmod->init(imod, cnf); | ||
370 | init_called = 1; | ||
371 | /* Error occurred, exit */ | ||
372 | if (ret <= 0) | ||
373 | goto err; | ||
374 | } | ||
375 | |||
376 | if (initialized_modules == NULL) | ||
377 | { | ||
378 | initialized_modules = sk_CONF_IMODULE_new_null(); | ||
379 | if (!initialized_modules) | ||
380 | { | ||
381 | CONFerr(CONF_F_MODULE_INIT, ERR_R_MALLOC_FAILURE); | ||
382 | goto err; | ||
383 | } | ||
384 | } | ||
385 | |||
386 | if (!sk_CONF_IMODULE_push(initialized_modules, imod)) | ||
387 | { | ||
388 | CONFerr(CONF_F_MODULE_INIT, ERR_R_MALLOC_FAILURE); | ||
389 | goto err; | ||
390 | } | ||
391 | |||
392 | pmod->links++; | ||
393 | |||
394 | return ret; | ||
395 | |||
396 | err: | ||
397 | |||
398 | /* We've started the module so we'd better finish it */ | ||
399 | if (pmod->finish && init_called) | ||
400 | pmod->finish(imod); | ||
401 | |||
402 | memerr: | ||
403 | if (imod) | ||
404 | { | ||
405 | if (imod->name) | ||
406 | OPENSSL_free(imod->name); | ||
407 | if (imod->value) | ||
408 | OPENSSL_free(imod->value); | ||
409 | OPENSSL_free(imod); | ||
410 | } | ||
411 | |||
412 | return -1; | ||
413 | |||
414 | } | ||
415 | |||
416 | /* Unload any dynamic modules that have a link count of zero: | ||
417 | * i.e. have no active initialized modules. If 'all' is set | ||
418 | * then all modules are unloaded including static ones. | ||
419 | */ | ||
420 | |||
421 | void CONF_modules_unload(int all) | ||
422 | { | ||
423 | int i; | ||
424 | CONF_MODULE *md; | ||
425 | CONF_modules_finish(); | ||
426 | /* unload modules in reverse order */ | ||
427 | for (i = sk_CONF_MODULE_num(supported_modules) - 1; i >= 0; i--) | ||
428 | { | ||
429 | md = sk_CONF_MODULE_value(supported_modules, i); | ||
430 | /* If static or in use and 'all' not set ignore it */ | ||
431 | if (((md->links > 0) || !md->dso) && !all) | ||
432 | continue; | ||
433 | /* Since we're working in reverse this is OK */ | ||
434 | sk_CONF_MODULE_delete(supported_modules, i); | ||
435 | module_free(md); | ||
436 | } | ||
437 | if (sk_CONF_MODULE_num(supported_modules) == 0) | ||
438 | { | ||
439 | sk_CONF_MODULE_free(supported_modules); | ||
440 | supported_modules = NULL; | ||
441 | } | ||
442 | } | ||
443 | |||
444 | /* unload a single module */ | ||
445 | static void module_free(CONF_MODULE *md) | ||
446 | { | ||
447 | if (md->dso) | ||
448 | DSO_free(md->dso); | ||
449 | OPENSSL_free(md->name); | ||
450 | OPENSSL_free(md); | ||
451 | } | ||
452 | |||
453 | /* finish and free up all modules instances */ | ||
454 | |||
455 | void CONF_modules_finish(void) | ||
456 | { | ||
457 | CONF_IMODULE *imod; | ||
458 | while (sk_CONF_IMODULE_num(initialized_modules) > 0) | ||
459 | { | ||
460 | imod = sk_CONF_IMODULE_pop(initialized_modules); | ||
461 | module_finish(imod); | ||
462 | } | ||
463 | sk_CONF_IMODULE_free(initialized_modules); | ||
464 | initialized_modules = NULL; | ||
465 | } | ||
466 | |||
467 | /* finish a module instance */ | ||
468 | |||
469 | static void module_finish(CONF_IMODULE *imod) | ||
470 | { | ||
471 | if (imod->pmod->finish) | ||
472 | imod->pmod->finish(imod); | ||
473 | imod->pmod->links--; | ||
474 | OPENSSL_free(imod->name); | ||
475 | OPENSSL_free(imod->value); | ||
476 | OPENSSL_free(imod); | ||
477 | } | ||
478 | |||
479 | /* Add a static module to OpenSSL */ | ||
480 | |||
481 | int CONF_module_add(const char *name, conf_init_func *ifunc, | ||
482 | conf_finish_func *ffunc) | ||
483 | { | ||
484 | if (module_add(NULL, name, ifunc, ffunc)) | ||
485 | return 1; | ||
486 | else | ||
487 | return 0; | ||
488 | } | ||
489 | |||
490 | void CONF_modules_free(void) | ||
491 | { | ||
492 | CONF_modules_finish(); | ||
493 | CONF_modules_unload(1); | ||
494 | } | ||
495 | |||
496 | /* Utility functions */ | ||
497 | |||
498 | const char *CONF_imodule_get_name(const CONF_IMODULE *md) | ||
499 | { | ||
500 | return md->name; | ||
501 | } | ||
502 | |||
503 | const char *CONF_imodule_get_value(const CONF_IMODULE *md) | ||
504 | { | ||
505 | return md->value; | ||
506 | } | ||
507 | |||
508 | void *CONF_imodule_get_usr_data(const CONF_IMODULE *md) | ||
509 | { | ||
510 | return md->usr_data; | ||
511 | } | ||
512 | |||
513 | void CONF_imodule_set_usr_data(CONF_IMODULE *md, void *usr_data) | ||
514 | { | ||
515 | md->usr_data = usr_data; | ||
516 | } | ||
517 | |||
518 | CONF_MODULE *CONF_imodule_get_module(const CONF_IMODULE *md) | ||
519 | { | ||
520 | return md->pmod; | ||
521 | } | ||
522 | |||
523 | unsigned long CONF_imodule_get_flags(const CONF_IMODULE *md) | ||
524 | { | ||
525 | return md->flags; | ||
526 | } | ||
527 | |||
528 | void CONF_imodule_set_flags(CONF_IMODULE *md, unsigned long flags) | ||
529 | { | ||
530 | md->flags = flags; | ||
531 | } | ||
532 | |||
533 | void *CONF_module_get_usr_data(CONF_MODULE *pmod) | ||
534 | { | ||
535 | return pmod->usr_data; | ||
536 | } | ||
537 | |||
538 | void CONF_module_set_usr_data(CONF_MODULE *pmod, void *usr_data) | ||
539 | { | ||
540 | pmod->usr_data = usr_data; | ||
541 | } | ||
542 | |||
543 | /* Return default config file name */ | ||
544 | |||
545 | char *CONF_get1_default_config_file(void) | ||
546 | { | ||
547 | char *file; | ||
548 | int len; | ||
549 | |||
550 | file = getenv("OPENSSL_CONF"); | ||
551 | if (file) | ||
552 | return BUF_strdup(file); | ||
553 | |||
554 | len = strlen(X509_get_default_cert_area()); | ||
555 | #ifndef OPENSSL_SYS_VMS | ||
556 | len++; | ||
557 | #endif | ||
558 | len += strlen(OPENSSL_CONF); | ||
559 | |||
560 | file = OPENSSL_malloc(len + 1); | ||
561 | |||
562 | if (!file) | ||
563 | return NULL; | ||
564 | strcpy(file,X509_get_default_cert_area()); | ||
565 | #ifndef OPENSSL_SYS_VMS | ||
566 | strcat(file,"/"); | ||
567 | #endif | ||
568 | strcat(file,OPENSSL_CONF); | ||
569 | |||
570 | return file; | ||
571 | } | ||
572 | |||
573 | /* This function takes a list separated by 'sep' and calls the | ||
574 | * callback function giving the start and length of each member | ||
575 | * optionally stripping leading and trailing whitespace. This can | ||
576 | * be used to parse comma separated lists for example. | ||
577 | */ | ||
578 | |||
579 | int CONF_parse_list(const char *list, int sep, int nospc, | ||
580 | int (*list_cb)(const char *elem, int len, void *usr), void *arg) | ||
581 | { | ||
582 | int ret; | ||
583 | const char *lstart, *tmpend, *p; | ||
584 | lstart = list; | ||
585 | |||
586 | for(;;) | ||
587 | { | ||
588 | if (nospc) | ||
589 | { | ||
590 | while(*lstart && isspace((unsigned char)*lstart)) | ||
591 | lstart++; | ||
592 | } | ||
593 | p = strchr(lstart, sep); | ||
594 | if (p == lstart || !*lstart) | ||
595 | ret = list_cb(NULL, 0, arg); | ||
596 | else | ||
597 | { | ||
598 | if (p) | ||
599 | tmpend = p - 1; | ||
600 | else | ||
601 | tmpend = lstart + strlen(lstart) - 1; | ||
602 | if (nospc) | ||
603 | { | ||
604 | while(isspace((unsigned char)*tmpend)) | ||
605 | tmpend--; | ||
606 | } | ||
607 | ret = list_cb(lstart, tmpend - lstart + 1, arg); | ||
608 | } | ||
609 | if (ret <= 0) | ||
610 | return ret; | ||
611 | if (p == NULL) | ||
612 | return 1; | ||
613 | lstart = p + 1; | ||
614 | } | ||
615 | } | ||
616 | |||
diff --git a/src/lib/libcrypto/conf/conf_sap.c b/src/lib/libcrypto/conf/conf_sap.c new file mode 100644 index 0000000000..97fb174303 --- /dev/null +++ b/src/lib/libcrypto/conf/conf_sap.c | |||
@@ -0,0 +1,107 @@ | |||
1 | /* conf_sap.c */ | ||
2 | /* Written by Stephen Henson (shenson@bigfoot.com) for the OpenSSL | ||
3 | * project 2001. | ||
4 | */ | ||
5 | /* ==================================================================== | ||
6 | * Copyright (c) 2001 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 | #include <openssl/crypto.h> | ||
61 | #include "cryptlib.h" | ||
62 | #include <openssl/conf.h> | ||
63 | #include <openssl/dso.h> | ||
64 | #include <openssl/x509.h> | ||
65 | #include <openssl/asn1.h> | ||
66 | #include <openssl/engine.h> | ||
67 | |||
68 | /* This is the automatic configuration loader: it is called automatically by | ||
69 | * OpenSSL when any of a number of standard initialisation functions are called, | ||
70 | * unless this is overridden by calling OPENSSL_no_config() | ||
71 | */ | ||
72 | |||
73 | static int openssl_configured = 0; | ||
74 | |||
75 | void OPENSSL_config(const char *config_name) | ||
76 | { | ||
77 | if (openssl_configured) | ||
78 | return; | ||
79 | |||
80 | OPENSSL_load_builtin_modules(); | ||
81 | /* Need to load ENGINEs */ | ||
82 | ENGINE_load_builtin_engines(); | ||
83 | /* Add others here? */ | ||
84 | |||
85 | |||
86 | ERR_clear_error(); | ||
87 | if (CONF_modules_load_file(NULL, NULL, | ||
88 | CONF_MFLAGS_IGNORE_MISSING_FILE) <= 0) | ||
89 | { | ||
90 | BIO *bio_err; | ||
91 | ERR_load_crypto_strings(); | ||
92 | if ((bio_err=BIO_new_fp(stderr, BIO_NOCLOSE)) != NULL) | ||
93 | { | ||
94 | BIO_printf(bio_err,"Auto configuration failed\n"); | ||
95 | ERR_print_errors(bio_err); | ||
96 | BIO_free(bio_err); | ||
97 | } | ||
98 | exit(1); | ||
99 | } | ||
100 | |||
101 | return; | ||
102 | } | ||
103 | |||
104 | void OPENSSL_no_config() | ||
105 | { | ||
106 | openssl_configured = 1; | ||
107 | } | ||
diff --git a/src/lib/libcrypto/des/des.h b/src/lib/libcrypto/des/des.h new file mode 100644 index 0000000000..67f90aaf17 --- /dev/null +++ b/src/lib/libcrypto/des/des.h | |||
@@ -0,0 +1,249 @@ | |||
1 | /* crypto/des/des.h */ | ||
2 | /* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) | ||
3 | * All rights reserved. | ||
4 | * | ||
5 | * This package is an SSL implementation written | ||
6 | * by Eric Young (eay@cryptsoft.com). | ||
7 | * The implementation was written so as to conform with Netscapes SSL. | ||
8 | * | ||
9 | * This library is free for commercial and non-commercial use as long as | ||
10 | * the following conditions are aheared to. The following conditions | ||
11 | * apply to all code found in this distribution, be it the RC4, RSA, | ||
12 | * lhash, DES, etc., code; not just the SSL code. The SSL documentation | ||
13 | * included with this distribution is covered by the same copyright terms | ||
14 | * except that the holder is Tim Hudson (tjh@cryptsoft.com). | ||
15 | * | ||
16 | * Copyright remains Eric Young's, and as such any Copyright notices in | ||
17 | * the code are not to be removed. | ||
18 | * If this package is used in a product, Eric Young should be given attribution | ||
19 | * as the author of the parts of the library used. | ||
20 | * This can be in the form of a textual message at program startup or | ||
21 | * in documentation (online or textual) provided with the package. | ||
22 | * | ||
23 | * Redistribution and use in source and binary forms, with or without | ||
24 | * modification, are permitted provided that the following conditions | ||
25 | * are met: | ||
26 | * 1. Redistributions of source code must retain the copyright | ||
27 | * notice, this list of conditions and the following disclaimer. | ||
28 | * 2. Redistributions in binary form must reproduce the above copyright | ||
29 | * notice, this list of conditions and the following disclaimer in the | ||
30 | * documentation and/or other materials provided with the distribution. | ||
31 | * 3. All advertising materials mentioning features or use of this software | ||
32 | * must display the following acknowledgement: | ||
33 | * "This product includes cryptographic software written by | ||
34 | * Eric Young (eay@cryptsoft.com)" | ||
35 | * The word 'cryptographic' can be left out if the rouines from the library | ||
36 | * being used are not cryptographic related :-). | ||
37 | * 4. If you include any Windows specific code (or a derivative thereof) from | ||
38 | * the apps directory (application code) you must include an acknowledgement: | ||
39 | * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" | ||
40 | * | ||
41 | * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND | ||
42 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
43 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
44 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | ||
45 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
46 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
47 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
48 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
49 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
50 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
51 | * SUCH DAMAGE. | ||
52 | * | ||
53 | * The licence and distribution terms for any publically available version or | ||
54 | * derivative of this code cannot be changed. i.e. this code cannot simply be | ||
55 | * copied and put under another distribution licence | ||
56 | * [including the GNU Public Licence.] | ||
57 | */ | ||
58 | |||
59 | #ifndef HEADER_DES_H | ||
60 | #define HEADER_DES_H | ||
61 | |||
62 | #ifdef __cplusplus | ||
63 | extern "C" { | ||
64 | #endif | ||
65 | |||
66 | #ifdef NO_DES | ||
67 | #error DES is disabled. | ||
68 | #endif | ||
69 | |||
70 | #ifdef _KERBEROS_DES_H | ||
71 | #error <openssl/des.h> replaces <kerberos/des.h>. | ||
72 | #endif | ||
73 | |||
74 | #include <stdio.h> | ||
75 | #include <openssl/opensslconf.h> /* DES_LONG */ | ||
76 | #include <openssl/e_os2.h> /* OPENSSL_EXTERN */ | ||
77 | |||
78 | typedef unsigned char des_cblock[8]; | ||
79 | typedef /* const */ unsigned char const_des_cblock[8]; | ||
80 | /* With "const", gcc 2.8.1 on Solaris thinks that des_cblock * | ||
81 | * and const_des_cblock * are incompatible pointer types. | ||
82 | * I haven't seen that warning on other systems ... I'll look | ||
83 | * what the standard says. */ | ||
84 | |||
85 | |||
86 | typedef struct des_ks_struct | ||
87 | { | ||
88 | union { | ||
89 | des_cblock cblock; | ||
90 | /* make sure things are correct size on machines with | ||
91 | * 8 byte longs */ | ||
92 | DES_LONG deslong[2]; | ||
93 | } ks; | ||
94 | int weak_key; | ||
95 | } des_key_schedule[16]; | ||
96 | |||
97 | #define DES_KEY_SZ (sizeof(des_cblock)) | ||
98 | #define DES_SCHEDULE_SZ (sizeof(des_key_schedule)) | ||
99 | |||
100 | #define DES_ENCRYPT 1 | ||
101 | #define DES_DECRYPT 0 | ||
102 | |||
103 | #define DES_CBC_MODE 0 | ||
104 | #define DES_PCBC_MODE 1 | ||
105 | |||
106 | #define des_ecb2_encrypt(i,o,k1,k2,e) \ | ||
107 | des_ecb3_encrypt((i),(o),(k1),(k2),(k1),(e)) | ||
108 | |||
109 | #define des_ede2_cbc_encrypt(i,o,l,k1,k2,iv,e) \ | ||
110 | des_ede3_cbc_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(e)) | ||
111 | |||
112 | #define des_ede2_cfb64_encrypt(i,o,l,k1,k2,iv,n,e) \ | ||
113 | des_ede3_cfb64_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(n),(e)) | ||
114 | |||
115 | #define des_ede2_ofb64_encrypt(i,o,l,k1,k2,iv,n) \ | ||
116 | des_ede3_ofb64_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(n)) | ||
117 | |||
118 | OPENSSL_EXTERN int des_check_key; /* defaults to false */ | ||
119 | OPENSSL_EXTERN int des_rw_mode; /* defaults to DES_PCBC_MODE */ | ||
120 | OPENSSL_EXTERN int des_set_weak_key_flag; /* set the weak key flag */ | ||
121 | |||
122 | const char *des_options(void); | ||
123 | void des_ecb3_encrypt(const_des_cblock *input, des_cblock *output, | ||
124 | des_key_schedule ks1,des_key_schedule ks2, | ||
125 | des_key_schedule ks3, int enc); | ||
126 | DES_LONG des_cbc_cksum(const unsigned char *input,des_cblock *output, | ||
127 | long length,des_key_schedule schedule, | ||
128 | const_des_cblock *ivec); | ||
129 | /* des_cbc_encrypt does not update the IV! Use des_ncbc_encrypt instead. */ | ||
130 | void des_cbc_encrypt(const unsigned char *input,unsigned char *output, | ||
131 | long length,des_key_schedule schedule,des_cblock *ivec, | ||
132 | int enc); | ||
133 | void des_ncbc_encrypt(const unsigned char *input,unsigned char *output, | ||
134 | long length,des_key_schedule schedule,des_cblock *ivec, | ||
135 | int enc); | ||
136 | void des_xcbc_encrypt(const unsigned char *input,unsigned char *output, | ||
137 | long length,des_key_schedule schedule,des_cblock *ivec, | ||
138 | const_des_cblock *inw,const_des_cblock *outw,int enc); | ||
139 | void des_cfb_encrypt(const unsigned char *in,unsigned char *out,int numbits, | ||
140 | long length,des_key_schedule schedule,des_cblock *ivec, | ||
141 | int enc); | ||
142 | void des_ecb_encrypt(const_des_cblock *input,des_cblock *output, | ||
143 | des_key_schedule ks,int enc); | ||
144 | void des_encrypt(DES_LONG *data,des_key_schedule ks, int enc); | ||
145 | void des_encrypt2(DES_LONG *data,des_key_schedule ks, int enc); | ||
146 | void des_encrypt3(DES_LONG *data, des_key_schedule ks1, | ||
147 | des_key_schedule ks2, des_key_schedule ks3); | ||
148 | void des_decrypt3(DES_LONG *data, des_key_schedule ks1, | ||
149 | des_key_schedule ks2, des_key_schedule ks3); | ||
150 | void des_ede3_cbc_encrypt(const unsigned char *input,unsigned char *output, | ||
151 | long length, | ||
152 | des_key_schedule ks1,des_key_schedule ks2, | ||
153 | des_key_schedule ks3,des_cblock *ivec,int enc); | ||
154 | void des_ede3_cbcm_encrypt(const unsigned char *in,unsigned char *out, | ||
155 | long length, | ||
156 | des_key_schedule ks1,des_key_schedule ks2, | ||
157 | des_key_schedule ks3, | ||
158 | des_cblock *ivec1,des_cblock *ivec2, | ||
159 | int enc); | ||
160 | void des_ede3_cfb64_encrypt(const unsigned char *in,unsigned char *out, | ||
161 | long length,des_key_schedule ks1, | ||
162 | des_key_schedule ks2,des_key_schedule ks3, | ||
163 | des_cblock *ivec,int *num,int enc); | ||
164 | void des_ede3_ofb64_encrypt(const unsigned char *in,unsigned char *out, | ||
165 | long length,des_key_schedule ks1, | ||
166 | des_key_schedule ks2,des_key_schedule ks3, | ||
167 | des_cblock *ivec,int *num); | ||
168 | |||
169 | void des_xwhite_in2out(const_des_cblock *des_key,const_des_cblock *in_white, | ||
170 | des_cblock *out_white); | ||
171 | |||
172 | int des_enc_read(int fd,void *buf,int len,des_key_schedule sched, | ||
173 | des_cblock *iv); | ||
174 | int des_enc_write(int fd,const void *buf,int len,des_key_schedule sched, | ||
175 | des_cblock *iv); | ||
176 | char *des_fcrypt(const char *buf,const char *salt, char *ret); | ||
177 | char *des_crypt(const char *buf,const char *salt); | ||
178 | #if !defined(PERL5) && !defined(__FreeBSD__) && !defined(NeXT) | ||
179 | char *crypt(const char *buf,const char *salt); | ||
180 | #endif | ||
181 | void des_ofb_encrypt(const unsigned char *in,unsigned char *out,int numbits, | ||
182 | long length,des_key_schedule schedule,des_cblock *ivec); | ||
183 | void des_pcbc_encrypt(const unsigned char *input,unsigned char *output, | ||
184 | long length,des_key_schedule schedule,des_cblock *ivec, | ||
185 | int enc); | ||
186 | DES_LONG des_quad_cksum(const unsigned char *input,des_cblock output[], | ||
187 | long length,int out_count,des_cblock *seed); | ||
188 | void des_random_seed(des_cblock *key); | ||
189 | void des_random_key(des_cblock *ret); | ||
190 | int des_read_password(des_cblock *key,const char *prompt,int verify); | ||
191 | int des_read_2passwords(des_cblock *key1,des_cblock *key2, | ||
192 | const char *prompt,int verify); | ||
193 | int des_read_pw_string(char *buf,int length,const char *prompt,int verify); | ||
194 | void des_set_odd_parity(des_cblock *key); | ||
195 | int des_is_weak_key(const_des_cblock *key); | ||
196 | int des_set_key(const_des_cblock *key,des_key_schedule schedule); | ||
197 | int des_key_sched(const_des_cblock *key,des_key_schedule schedule); | ||
198 | void des_string_to_key(const char *str,des_cblock *key); | ||
199 | void des_string_to_2keys(const char *str,des_cblock *key1,des_cblock *key2); | ||
200 | void des_cfb64_encrypt(const unsigned char *in,unsigned char *out,long length, | ||
201 | des_key_schedule schedule,des_cblock *ivec,int *num, | ||
202 | int enc); | ||
203 | void des_ofb64_encrypt(const unsigned char *in,unsigned char *out,long length, | ||
204 | des_key_schedule schedule,des_cblock *ivec,int *num); | ||
205 | int des_read_pw(char *buf,char *buff,int size,const char *prompt,int verify); | ||
206 | |||
207 | /* Extra functions from Mark Murray <mark@grondar.za> */ | ||
208 | void des_cblock_print_file(const_des_cblock *cb, FILE *fp); | ||
209 | |||
210 | /* The following definitions provide compatibility with the MIT Kerberos | ||
211 | * library. The des_key_schedule structure is not binary compatible. */ | ||
212 | |||
213 | #define _KERBEROS_DES_H | ||
214 | |||
215 | #define KRBDES_ENCRYPT DES_ENCRYPT | ||
216 | #define KRBDES_DECRYPT DES_DECRYPT | ||
217 | |||
218 | #ifdef KERBEROS | ||
219 | # define ENCRYPT DES_ENCRYPT | ||
220 | # define DECRYPT DES_DECRYPT | ||
221 | #endif | ||
222 | |||
223 | #ifndef NCOMPAT | ||
224 | # define C_Block des_cblock | ||
225 | # define Key_schedule des_key_schedule | ||
226 | # define KEY_SZ DES_KEY_SZ | ||
227 | # define string_to_key des_string_to_key | ||
228 | # define read_pw_string des_read_pw_string | ||
229 | # define random_key des_random_key | ||
230 | # define pcbc_encrypt des_pcbc_encrypt | ||
231 | # define set_key des_set_key | ||
232 | # define key_sched des_key_sched | ||
233 | # define ecb_encrypt des_ecb_encrypt | ||
234 | # define cbc_encrypt des_cbc_encrypt | ||
235 | # define ncbc_encrypt des_ncbc_encrypt | ||
236 | # define xcbc_encrypt des_xcbc_encrypt | ||
237 | # define cbc_cksum des_cbc_cksum | ||
238 | # define quad_cksum des_quad_cksum | ||
239 | #endif | ||
240 | |||
241 | typedef des_key_schedule bit_64; | ||
242 | #define des_fixup_key_parity des_set_odd_parity | ||
243 | #define des_check_key_parity check_parity | ||
244 | |||
245 | #ifdef __cplusplus | ||
246 | } | ||
247 | #endif | ||
248 | |||
249 | #endif | ||
diff --git a/src/lib/libcrypto/des/des_locl.h b/src/lib/libcrypto/des/des_locl.h new file mode 100644 index 0000000000..d6ea17cb68 --- /dev/null +++ b/src/lib/libcrypto/des/des_locl.h | |||
@@ -0,0 +1,408 @@ | |||
1 | /* crypto/des/des_locl.h */ | ||
2 | /* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) | ||
3 | * All rights reserved. | ||
4 | * | ||
5 | * This package is an SSL implementation written | ||
6 | * by Eric Young (eay@cryptsoft.com). | ||
7 | * The implementation was written so as to conform with Netscapes SSL. | ||
8 | * | ||
9 | * This library is free for commercial and non-commercial use as long as | ||
10 | * the following conditions are aheared to. The following conditions | ||
11 | * apply to all code found in this distribution, be it the RC4, RSA, | ||
12 | * lhash, DES, etc., code; not just the SSL code. The SSL documentation | ||
13 | * included with this distribution is covered by the same copyright terms | ||
14 | * except that the holder is Tim Hudson (tjh@cryptsoft.com). | ||
15 | * | ||
16 | * Copyright remains Eric Young's, and as such any Copyright notices in | ||
17 | * the code are not to be removed. | ||
18 | * If this package is used in a product, Eric Young should be given attribution | ||
19 | * as the author of the parts of the library used. | ||
20 | * This can be in the form of a textual message at program startup or | ||
21 | * in documentation (online or textual) provided with the package. | ||
22 | * | ||
23 | * Redistribution and use in source and binary forms, with or without | ||
24 | * modification, are permitted provided that the following conditions | ||
25 | * are met: | ||
26 | * 1. Redistributions of source code must retain the copyright | ||
27 | * notice, this list of conditions and the following disclaimer. | ||
28 | * 2. Redistributions in binary form must reproduce the above copyright | ||
29 | * notice, this list of conditions and the following disclaimer in the | ||
30 | * documentation and/or other materials provided with the distribution. | ||
31 | * 3. All advertising materials mentioning features or use of this software | ||
32 | * must display the following acknowledgement: | ||
33 | * "This product includes cryptographic software written by | ||
34 | * Eric Young (eay@cryptsoft.com)" | ||
35 | * The word 'cryptographic' can be left out if the rouines from the library | ||
36 | * being used are not cryptographic related :-). | ||
37 | * 4. If you include any Windows specific code (or a derivative thereof) from | ||
38 | * the apps directory (application code) you must include an acknowledgement: | ||
39 | * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" | ||
40 | * | ||
41 | * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND | ||
42 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
43 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
44 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | ||
45 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
46 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
47 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
48 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
49 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
50 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
51 | * SUCH DAMAGE. | ||
52 | * | ||
53 | * The licence and distribution terms for any publically available version or | ||
54 | * derivative of this code cannot be changed. i.e. this code cannot simply be | ||
55 | * copied and put under another distribution licence | ||
56 | * [including the GNU Public Licence.] | ||
57 | */ | ||
58 | |||
59 | #ifndef HEADER_DES_LOCL_H | ||
60 | #define HEADER_DES_LOCL_H | ||
61 | |||
62 | #if defined(WIN32) || defined(WIN16) | ||
63 | #ifndef MSDOS | ||
64 | #define MSDOS | ||
65 | #endif | ||
66 | #endif | ||
67 | |||
68 | #include <stdio.h> | ||
69 | #include <stdlib.h> | ||
70 | |||
71 | #include <openssl/opensslconf.h> | ||
72 | |||
73 | #ifndef MSDOS | ||
74 | #if !defined(VMS) || defined(__DECC) | ||
75 | #include OPENSSL_UNISTD | ||
76 | #include <math.h> | ||
77 | #endif | ||
78 | #endif | ||
79 | #include <openssl/des.h> | ||
80 | |||
81 | #ifdef MSDOS /* Visual C++ 2.1 (Windows NT/95) */ | ||
82 | #include <stdlib.h> | ||
83 | #include <errno.h> | ||
84 | #include <time.h> | ||
85 | #include <io.h> | ||
86 | #endif | ||
87 | |||
88 | #if defined(__STDC__) || defined(VMS) || defined(M_XENIX) || defined(MSDOS) | ||
89 | #include <string.h> | ||
90 | #endif | ||
91 | |||
92 | #define ITERATIONS 16 | ||
93 | #define HALF_ITERATIONS 8 | ||
94 | |||
95 | /* used in des_read and des_write */ | ||
96 | #define MAXWRITE (1024*16) | ||
97 | #define BSIZE (MAXWRITE+4) | ||
98 | |||
99 | #define c2l(c,l) (l =((DES_LONG)(*((c)++))) , \ | ||
100 | l|=((DES_LONG)(*((c)++)))<< 8L, \ | ||
101 | l|=((DES_LONG)(*((c)++)))<<16L, \ | ||
102 | l|=((DES_LONG)(*((c)++)))<<24L) | ||
103 | |||
104 | /* NOTE - c is not incremented as per c2l */ | ||
105 | #define c2ln(c,l1,l2,n) { \ | ||
106 | c+=n; \ | ||
107 | l1=l2=0; \ | ||
108 | switch (n) { \ | ||
109 | case 8: l2 =((DES_LONG)(*(--(c))))<<24L; \ | ||
110 | case 7: l2|=((DES_LONG)(*(--(c))))<<16L; \ | ||
111 | case 6: l2|=((DES_LONG)(*(--(c))))<< 8L; \ | ||
112 | case 5: l2|=((DES_LONG)(*(--(c)))); \ | ||
113 | case 4: l1 =((DES_LONG)(*(--(c))))<<24L; \ | ||
114 | case 3: l1|=((DES_LONG)(*(--(c))))<<16L; \ | ||
115 | case 2: l1|=((DES_LONG)(*(--(c))))<< 8L; \ | ||
116 | case 1: l1|=((DES_LONG)(*(--(c)))); \ | ||
117 | } \ | ||
118 | } | ||
119 | |||
120 | #define l2c(l,c) (*((c)++)=(unsigned char)(((l) )&0xff), \ | ||
121 | *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \ | ||
122 | *((c)++)=(unsigned char)(((l)>>16L)&0xff), \ | ||
123 | *((c)++)=(unsigned char)(((l)>>24L)&0xff)) | ||
124 | |||
125 | /* replacements for htonl and ntohl since I have no idea what to do | ||
126 | * when faced with machines with 8 byte longs. */ | ||
127 | #define HDRSIZE 4 | ||
128 | |||
129 | #define n2l(c,l) (l =((DES_LONG)(*((c)++)))<<24L, \ | ||
130 | l|=((DES_LONG)(*((c)++)))<<16L, \ | ||
131 | l|=((DES_LONG)(*((c)++)))<< 8L, \ | ||
132 | l|=((DES_LONG)(*((c)++)))) | ||
133 | |||
134 | #define l2n(l,c) (*((c)++)=(unsigned char)(((l)>>24L)&0xff), \ | ||
135 | *((c)++)=(unsigned char)(((l)>>16L)&0xff), \ | ||
136 | *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \ | ||
137 | *((c)++)=(unsigned char)(((l) )&0xff)) | ||
138 | |||
139 | /* NOTE - c is not incremented as per l2c */ | ||
140 | #define l2cn(l1,l2,c,n) { \ | ||
141 | c+=n; \ | ||
142 | switch (n) { \ | ||
143 | case 8: *(--(c))=(unsigned char)(((l2)>>24L)&0xff); \ | ||
144 | case 7: *(--(c))=(unsigned char)(((l2)>>16L)&0xff); \ | ||
145 | case 6: *(--(c))=(unsigned char)(((l2)>> 8L)&0xff); \ | ||
146 | case 5: *(--(c))=(unsigned char)(((l2) )&0xff); \ | ||
147 | case 4: *(--(c))=(unsigned char)(((l1)>>24L)&0xff); \ | ||
148 | case 3: *(--(c))=(unsigned char)(((l1)>>16L)&0xff); \ | ||
149 | case 2: *(--(c))=(unsigned char)(((l1)>> 8L)&0xff); \ | ||
150 | case 1: *(--(c))=(unsigned char)(((l1) )&0xff); \ | ||
151 | } \ | ||
152 | } | ||
153 | |||
154 | #if defined(WIN32) | ||
155 | #define ROTATE(a,n) (_lrotr(a,n)) | ||
156 | #else | ||
157 | #define ROTATE(a,n) (((a)>>(n))+((a)<<(32-(n)))) | ||
158 | #endif | ||
159 | |||
160 | /* Don't worry about the LOAD_DATA() stuff, that is used by | ||
161 | * fcrypt() to add it's little bit to the front */ | ||
162 | |||
163 | #ifdef DES_FCRYPT | ||
164 | |||
165 | #define LOAD_DATA_tmp(R,S,u,t,E0,E1) \ | ||
166 | { DES_LONG tmp; LOAD_DATA(R,S,u,t,E0,E1,tmp); } | ||
167 | |||
168 | #define LOAD_DATA(R,S,u,t,E0,E1,tmp) \ | ||
169 | t=R^(R>>16L); \ | ||
170 | u=t&E0; t&=E1; \ | ||
171 | tmp=(u<<16); u^=R^s[S ]; u^=tmp; \ | ||
172 | tmp=(t<<16); t^=R^s[S+1]; t^=tmp | ||
173 | #else | ||
174 | #define LOAD_DATA_tmp(a,b,c,d,e,f) LOAD_DATA(a,b,c,d,e,f,g) | ||
175 | #define LOAD_DATA(R,S,u,t,E0,E1,tmp) \ | ||
176 | u=R^s[S ]; \ | ||
177 | t=R^s[S+1] | ||
178 | #endif | ||
179 | |||
180 | /* The changes to this macro may help or hinder, depending on the | ||
181 | * compiler and the achitecture. gcc2 always seems to do well :-). | ||
182 | * Inspired by Dana How <how@isl.stanford.edu> | ||
183 | * DO NOT use the alternative version on machines with 8 byte longs. | ||
184 | * It does not seem to work on the Alpha, even when DES_LONG is 4 | ||
185 | * bytes, probably an issue of accessing non-word aligned objects :-( */ | ||
186 | #ifdef DES_PTR | ||
187 | |||
188 | /* It recently occured to me that 0^0^0^0^0^0^0 == 0, so there | ||
189 | * is no reason to not xor all the sub items together. This potentially | ||
190 | * saves a register since things can be xored directly into L */ | ||
191 | |||
192 | #if defined(DES_RISC1) || defined(DES_RISC2) | ||
193 | #ifdef DES_RISC1 | ||
194 | #define D_ENCRYPT(LL,R,S) { \ | ||
195 | unsigned int u1,u2,u3; \ | ||
196 | LOAD_DATA(R,S,u,t,E0,E1,u1); \ | ||
197 | u2=(int)u>>8L; \ | ||
198 | u1=(int)u&0xfc; \ | ||
199 | u2&=0xfc; \ | ||
200 | t=ROTATE(t,4); \ | ||
201 | u>>=16L; \ | ||
202 | LL^= *(const DES_LONG *)(des_SP +u1); \ | ||
203 | LL^= *(const DES_LONG *)(des_SP+0x200+u2); \ | ||
204 | u3=(int)(u>>8L); \ | ||
205 | u1=(int)u&0xfc; \ | ||
206 | u3&=0xfc; \ | ||
207 | LL^= *(const DES_LONG *)(des_SP+0x400+u1); \ | ||
208 | LL^= *(const DES_LONG *)(des_SP+0x600+u3); \ | ||
209 | u2=(int)t>>8L; \ | ||
210 | u1=(int)t&0xfc; \ | ||
211 | u2&=0xfc; \ | ||
212 | t>>=16L; \ | ||
213 | LL^= *(const DES_LONG *)(des_SP+0x100+u1); \ | ||
214 | LL^= *(const DES_LONG *)(des_SP+0x300+u2); \ | ||
215 | u3=(int)t>>8L; \ | ||
216 | u1=(int)t&0xfc; \ | ||
217 | u3&=0xfc; \ | ||
218 | LL^= *(const DES_LONG *)(des_SP+0x500+u1); \ | ||
219 | LL^= *(const DES_LONG *)(des_SP+0x700+u3); } | ||
220 | #endif | ||
221 | #ifdef DES_RISC2 | ||
222 | #define D_ENCRYPT(LL,R,S) { \ | ||
223 | unsigned int u1,u2,s1,s2; \ | ||
224 | LOAD_DATA(R,S,u,t,E0,E1,u1); \ | ||
225 | u2=(int)u>>8L; \ | ||
226 | u1=(int)u&0xfc; \ | ||
227 | u2&=0xfc; \ | ||
228 | t=ROTATE(t,4); \ | ||
229 | LL^= *(const DES_LONG *)(des_SP +u1); \ | ||
230 | LL^= *(const DES_LONG *)(des_SP+0x200+u2); \ | ||
231 | s1=(int)(u>>16L); \ | ||
232 | s2=(int)(u>>24L); \ | ||
233 | s1&=0xfc; \ | ||
234 | s2&=0xfc; \ | ||
235 | LL^= *(const DES_LONG *)(des_SP+0x400+s1); \ | ||
236 | LL^= *(const DES_LONG *)(des_SP+0x600+s2); \ | ||
237 | u2=(int)t>>8L; \ | ||
238 | u1=(int)t&0xfc; \ | ||
239 | u2&=0xfc; \ | ||
240 | LL^= *(const DES_LONG *)(des_SP+0x100+u1); \ | ||
241 | LL^= *(const DES_LONG *)(des_SP+0x300+u2); \ | ||
242 | s1=(int)(t>>16L); \ | ||
243 | s2=(int)(t>>24L); \ | ||
244 | s1&=0xfc; \ | ||
245 | s2&=0xfc; \ | ||
246 | LL^= *(const DES_LONG *)(des_SP+0x500+s1); \ | ||
247 | LL^= *(const DES_LONG *)(des_SP+0x700+s2); } | ||
248 | #endif | ||
249 | #else | ||
250 | #define D_ENCRYPT(LL,R,S) { \ | ||
251 | LOAD_DATA_tmp(R,S,u,t,E0,E1); \ | ||
252 | t=ROTATE(t,4); \ | ||
253 | LL^= \ | ||
254 | *(const DES_LONG *)(des_SP +((u )&0xfc))^ \ | ||
255 | *(const DES_LONG *)(des_SP+0x200+((u>> 8L)&0xfc))^ \ | ||
256 | *(const DES_LONG *)(des_SP+0x400+((u>>16L)&0xfc))^ \ | ||
257 | *(const DES_LONG *)(des_SP+0x600+((u>>24L)&0xfc))^ \ | ||
258 | *(const DES_LONG *)(des_SP+0x100+((t )&0xfc))^ \ | ||
259 | *(const DES_LONG *)(des_SP+0x300+((t>> 8L)&0xfc))^ \ | ||
260 | *(const DES_LONG *)(des_SP+0x500+((t>>16L)&0xfc))^ \ | ||
261 | *(const DES_LONG *)(des_SP+0x700+((t>>24L)&0xfc)); } | ||
262 | #endif | ||
263 | |||
264 | #else /* original version */ | ||
265 | |||
266 | #if defined(DES_RISC1) || defined(DES_RISC2) | ||
267 | #ifdef DES_RISC1 | ||
268 | #define D_ENCRYPT(LL,R,S) {\ | ||
269 | unsigned int u1,u2,u3; \ | ||
270 | LOAD_DATA(R,S,u,t,E0,E1,u1); \ | ||
271 | u>>=2L; \ | ||
272 | t=ROTATE(t,6); \ | ||
273 | u2=(int)u>>8L; \ | ||
274 | u1=(int)u&0x3f; \ | ||
275 | u2&=0x3f; \ | ||
276 | u>>=16L; \ | ||
277 | LL^=des_SPtrans[0][u1]; \ | ||
278 | LL^=des_SPtrans[2][u2]; \ | ||
279 | u3=(int)u>>8L; \ | ||
280 | u1=(int)u&0x3f; \ | ||
281 | u3&=0x3f; \ | ||
282 | LL^=des_SPtrans[4][u1]; \ | ||
283 | LL^=des_SPtrans[6][u3]; \ | ||
284 | u2=(int)t>>8L; \ | ||
285 | u1=(int)t&0x3f; \ | ||
286 | u2&=0x3f; \ | ||
287 | t>>=16L; \ | ||
288 | LL^=des_SPtrans[1][u1]; \ | ||
289 | LL^=des_SPtrans[3][u2]; \ | ||
290 | u3=(int)t>>8L; \ | ||
291 | u1=(int)t&0x3f; \ | ||
292 | u3&=0x3f; \ | ||
293 | LL^=des_SPtrans[5][u1]; \ | ||
294 | LL^=des_SPtrans[7][u3]; } | ||
295 | #endif | ||
296 | #ifdef DES_RISC2 | ||
297 | #define D_ENCRYPT(LL,R,S) {\ | ||
298 | unsigned int u1,u2,s1,s2; \ | ||
299 | LOAD_DATA(R,S,u,t,E0,E1,u1); \ | ||
300 | u>>=2L; \ | ||
301 | t=ROTATE(t,6); \ | ||
302 | u2=(int)u>>8L; \ | ||
303 | u1=(int)u&0x3f; \ | ||
304 | u2&=0x3f; \ | ||
305 | LL^=des_SPtrans[0][u1]; \ | ||
306 | LL^=des_SPtrans[2][u2]; \ | ||
307 | s1=(int)u>>16L; \ | ||
308 | s2=(int)u>>24L; \ | ||
309 | s1&=0x3f; \ | ||
310 | s2&=0x3f; \ | ||
311 | LL^=des_SPtrans[4][s1]; \ | ||
312 | LL^=des_SPtrans[6][s2]; \ | ||
313 | u2=(int)t>>8L; \ | ||
314 | u1=(int)t&0x3f; \ | ||
315 | u2&=0x3f; \ | ||
316 | LL^=des_SPtrans[1][u1]; \ | ||
317 | LL^=des_SPtrans[3][u2]; \ | ||
318 | s1=(int)t>>16; \ | ||
319 | s2=(int)t>>24L; \ | ||
320 | s1&=0x3f; \ | ||
321 | s2&=0x3f; \ | ||
322 | LL^=des_SPtrans[5][s1]; \ | ||
323 | LL^=des_SPtrans[7][s2]; } | ||
324 | #endif | ||
325 | |||
326 | #else | ||
327 | |||
328 | #define D_ENCRYPT(LL,R,S) {\ | ||
329 | LOAD_DATA_tmp(R,S,u,t,E0,E1); \ | ||
330 | t=ROTATE(t,4); \ | ||
331 | LL^=\ | ||
332 | des_SPtrans[0][(u>> 2L)&0x3f]^ \ | ||
333 | des_SPtrans[2][(u>>10L)&0x3f]^ \ | ||
334 | des_SPtrans[4][(u>>18L)&0x3f]^ \ | ||
335 | des_SPtrans[6][(u>>26L)&0x3f]^ \ | ||
336 | des_SPtrans[1][(t>> 2L)&0x3f]^ \ | ||
337 | des_SPtrans[3][(t>>10L)&0x3f]^ \ | ||
338 | des_SPtrans[5][(t>>18L)&0x3f]^ \ | ||
339 | des_SPtrans[7][(t>>26L)&0x3f]; } | ||
340 | #endif | ||
341 | #endif | ||
342 | |||
343 | /* IP and FP | ||
344 | * The problem is more of a geometric problem that random bit fiddling. | ||
345 | 0 1 2 3 4 5 6 7 62 54 46 38 30 22 14 6 | ||
346 | 8 9 10 11 12 13 14 15 60 52 44 36 28 20 12 4 | ||
347 | 16 17 18 19 20 21 22 23 58 50 42 34 26 18 10 2 | ||
348 | 24 25 26 27 28 29 30 31 to 56 48 40 32 24 16 8 0 | ||
349 | |||
350 | 32 33 34 35 36 37 38 39 63 55 47 39 31 23 15 7 | ||
351 | 40 41 42 43 44 45 46 47 61 53 45 37 29 21 13 5 | ||
352 | 48 49 50 51 52 53 54 55 59 51 43 35 27 19 11 3 | ||
353 | 56 57 58 59 60 61 62 63 57 49 41 33 25 17 9 1 | ||
354 | |||
355 | The output has been subject to swaps of the form | ||
356 | 0 1 -> 3 1 but the odd and even bits have been put into | ||
357 | 2 3 2 0 | ||
358 | different words. The main trick is to remember that | ||
359 | t=((l>>size)^r)&(mask); | ||
360 | r^=t; | ||
361 | l^=(t<<size); | ||
362 | can be used to swap and move bits between words. | ||
363 | |||
364 | So l = 0 1 2 3 r = 16 17 18 19 | ||
365 | 4 5 6 7 20 21 22 23 | ||
366 | 8 9 10 11 24 25 26 27 | ||
367 | 12 13 14 15 28 29 30 31 | ||
368 | becomes (for size == 2 and mask == 0x3333) | ||
369 | t = 2^16 3^17 -- -- l = 0 1 16 17 r = 2 3 18 19 | ||
370 | 6^20 7^21 -- -- 4 5 20 21 6 7 22 23 | ||
371 | 10^24 11^25 -- -- 8 9 24 25 10 11 24 25 | ||
372 | 14^28 15^29 -- -- 12 13 28 29 14 15 28 29 | ||
373 | |||
374 | Thanks for hints from Richard Outerbridge - he told me IP&FP | ||
375 | could be done in 15 xor, 10 shifts and 5 ands. | ||
376 | When I finally started to think of the problem in 2D | ||
377 | I first got ~42 operations without xors. When I remembered | ||
378 | how to use xors :-) I got it to its final state. | ||
379 | */ | ||
380 | #define PERM_OP(a,b,t,n,m) ((t)=((((a)>>(n))^(b))&(m)),\ | ||
381 | (b)^=(t),\ | ||
382 | (a)^=((t)<<(n))) | ||
383 | |||
384 | #define IP(l,r) \ | ||
385 | { \ | ||
386 | register DES_LONG tt; \ | ||
387 | PERM_OP(r,l,tt, 4,0x0f0f0f0fL); \ | ||
388 | PERM_OP(l,r,tt,16,0x0000ffffL); \ | ||
389 | PERM_OP(r,l,tt, 2,0x33333333L); \ | ||
390 | PERM_OP(l,r,tt, 8,0x00ff00ffL); \ | ||
391 | PERM_OP(r,l,tt, 1,0x55555555L); \ | ||
392 | } | ||
393 | |||
394 | #define FP(l,r) \ | ||
395 | { \ | ||
396 | register DES_LONG tt; \ | ||
397 | PERM_OP(l,r,tt, 1,0x55555555L); \ | ||
398 | PERM_OP(r,l,tt, 8,0x00ff00ffL); \ | ||
399 | PERM_OP(l,r,tt, 2,0x33333333L); \ | ||
400 | PERM_OP(r,l,tt,16,0x0000ffffL); \ | ||
401 | PERM_OP(l,r,tt, 4,0x0f0f0f0fL); \ | ||
402 | } | ||
403 | |||
404 | OPENSSL_EXTERN const DES_LONG des_SPtrans[8][64]; | ||
405 | |||
406 | void fcrypt_body(DES_LONG *out,des_key_schedule ks, | ||
407 | DES_LONG Eswap0, DES_LONG Eswap1); | ||
408 | #endif | ||
diff --git a/src/lib/libcrypto/des/ede_cbcm_enc.c b/src/lib/libcrypto/des/ede_cbcm_enc.c new file mode 100644 index 0000000000..c53062481d --- /dev/null +++ b/src/lib/libcrypto/des/ede_cbcm_enc.c | |||
@@ -0,0 +1,197 @@ | |||
1 | /* ede_cbcm_enc.c */ | ||
2 | /* Written by Ben Laurie <ben@algroup.co.uk> for the OpenSSL | ||
3 | * project 13 Feb 1999. | ||
4 | */ | ||
5 | /* ==================================================================== | ||
6 | * Copyright (c) 1999 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 | |||
61 | This is an implementation of Triple DES Cipher Block Chaining with Output | ||
62 | Feedback Masking, by Coppersmith, Johnson and Matyas, (IBM and Certicom). | ||
63 | |||
64 | Note that there is a known attack on this by Biham and Knudsen but it takes | ||
65 | a lot of work: | ||
66 | |||
67 | http://www.cs.technion.ac.il/users/wwwb/cgi-bin/tr-get.cgi/1998/CS/CS0928.ps.gz | ||
68 | |||
69 | */ | ||
70 | |||
71 | #ifndef NO_DESCBCM | ||
72 | #include "des_locl.h" | ||
73 | |||
74 | void des_ede3_cbcm_encrypt(const unsigned char *in, unsigned char *out, | ||
75 | long length, des_key_schedule ks1, des_key_schedule ks2, | ||
76 | des_key_schedule ks3, des_cblock *ivec1, des_cblock *ivec2, | ||
77 | int enc) | ||
78 | { | ||
79 | register DES_LONG tin0,tin1; | ||
80 | register DES_LONG tout0,tout1,xor0,xor1,m0,m1; | ||
81 | register long l=length; | ||
82 | DES_LONG tin[2]; | ||
83 | unsigned char *iv1,*iv2; | ||
84 | |||
85 | iv1 = &(*ivec1)[0]; | ||
86 | iv2 = &(*ivec2)[0]; | ||
87 | |||
88 | if (enc) | ||
89 | { | ||
90 | c2l(iv1,m0); | ||
91 | c2l(iv1,m1); | ||
92 | c2l(iv2,tout0); | ||
93 | c2l(iv2,tout1); | ||
94 | for (l-=8; l>=-7; l-=8) | ||
95 | { | ||
96 | tin[0]=m0; | ||
97 | tin[1]=m1; | ||
98 | des_encrypt(tin,ks3,1); | ||
99 | m0=tin[0]; | ||
100 | m1=tin[1]; | ||
101 | |||
102 | if(l < 0) | ||
103 | { | ||
104 | c2ln(in,tin0,tin1,l+8); | ||
105 | } | ||
106 | else | ||
107 | { | ||
108 | c2l(in,tin0); | ||
109 | c2l(in,tin1); | ||
110 | } | ||
111 | tin0^=tout0; | ||
112 | tin1^=tout1; | ||
113 | |||
114 | tin[0]=tin0; | ||
115 | tin[1]=tin1; | ||
116 | des_encrypt(tin,ks1,1); | ||
117 | tin[0]^=m0; | ||
118 | tin[1]^=m1; | ||
119 | des_encrypt(tin,ks2,0); | ||
120 | tin[0]^=m0; | ||
121 | tin[1]^=m1; | ||
122 | des_encrypt(tin,ks1,1); | ||
123 | tout0=tin[0]; | ||
124 | tout1=tin[1]; | ||
125 | |||
126 | l2c(tout0,out); | ||
127 | l2c(tout1,out); | ||
128 | } | ||
129 | iv1=&(*ivec1)[0]; | ||
130 | l2c(m0,iv1); | ||
131 | l2c(m1,iv1); | ||
132 | |||
133 | iv2=&(*ivec2)[0]; | ||
134 | l2c(tout0,iv2); | ||
135 | l2c(tout1,iv2); | ||
136 | } | ||
137 | else | ||
138 | { | ||
139 | register DES_LONG t0,t1; | ||
140 | |||
141 | c2l(iv1,m0); | ||
142 | c2l(iv1,m1); | ||
143 | c2l(iv2,xor0); | ||
144 | c2l(iv2,xor1); | ||
145 | for (l-=8; l>=-7; l-=8) | ||
146 | { | ||
147 | tin[0]=m0; | ||
148 | tin[1]=m1; | ||
149 | des_encrypt(tin,ks3,1); | ||
150 | m0=tin[0]; | ||
151 | m1=tin[1]; | ||
152 | |||
153 | c2l(in,tin0); | ||
154 | c2l(in,tin1); | ||
155 | |||
156 | t0=tin0; | ||
157 | t1=tin1; | ||
158 | |||
159 | tin[0]=tin0; | ||
160 | tin[1]=tin1; | ||
161 | des_encrypt(tin,ks1,0); | ||
162 | tin[0]^=m0; | ||
163 | tin[1]^=m1; | ||
164 | des_encrypt(tin,ks2,1); | ||
165 | tin[0]^=m0; | ||
166 | tin[1]^=m1; | ||
167 | des_encrypt(tin,ks1,0); | ||
168 | tout0=tin[0]; | ||
169 | tout1=tin[1]; | ||
170 | |||
171 | tout0^=xor0; | ||
172 | tout1^=xor1; | ||
173 | if(l < 0) | ||
174 | { | ||
175 | l2cn(tout0,tout1,out,l+8); | ||
176 | } | ||
177 | else | ||
178 | { | ||
179 | l2c(tout0,out); | ||
180 | l2c(tout1,out); | ||
181 | } | ||
182 | xor0=t0; | ||
183 | xor1=t1; | ||
184 | } | ||
185 | |||
186 | iv1=&(*ivec1)[0]; | ||
187 | l2c(m0,iv1); | ||
188 | l2c(m1,iv1); | ||
189 | |||
190 | iv2=&(*ivec2)[0]; | ||
191 | l2c(xor0,iv2); | ||
192 | l2c(xor1,iv2); | ||
193 | } | ||
194 | tin0=tin1=tout0=tout1=xor0=xor1=0; | ||
195 | tin[0]=tin[1]=0; | ||
196 | } | ||
197 | #endif | ||
diff --git a/src/lib/libcrypto/dh/dh_asn1.c b/src/lib/libcrypto/dh/dh_asn1.c new file mode 100644 index 0000000000..769b5b68c5 --- /dev/null +++ b/src/lib/libcrypto/dh/dh_asn1.c | |||
@@ -0,0 +1,87 @@ | |||
1 | /* dh_asn1.c */ | ||
2 | /* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL | ||
3 | * project 2000. | ||
4 | */ | ||
5 | /* ==================================================================== | ||
6 | * Copyright (c) 2000 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 | #include "cryptlib.h" | ||
61 | #include <openssl/bn.h> | ||
62 | #include <openssl/dh.h> | ||
63 | #include <openssl/objects.h> | ||
64 | #include <openssl/asn1t.h> | ||
65 | |||
66 | /* Override the default free and new methods */ | ||
67 | static int dh_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it) | ||
68 | { | ||
69 | if(operation == ASN1_OP_NEW_PRE) { | ||
70 | *pval = (ASN1_VALUE *)DH_new(); | ||
71 | if(*pval) return 2; | ||
72 | return 0; | ||
73 | } else if(operation == ASN1_OP_FREE_PRE) { | ||
74 | DH_free((DH *)*pval); | ||
75 | *pval = NULL; | ||
76 | return 2; | ||
77 | } | ||
78 | return 1; | ||
79 | } | ||
80 | |||
81 | ASN1_SEQUENCE_cb(DHparams, dh_cb) = { | ||
82 | ASN1_SIMPLE(DH, p, BIGNUM), | ||
83 | ASN1_SIMPLE(DH, g, BIGNUM), | ||
84 | ASN1_OPT(DH, length, ZLONG), | ||
85 | } ASN1_SEQUENCE_END_cb(DH, DHparams) | ||
86 | |||
87 | IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(DH, DHparams, DHparams) | ||
diff --git a/src/lib/libcrypto/doc/DH_generate_key.pod b/src/lib/libcrypto/doc/DH_generate_key.pod new file mode 100644 index 0000000000..920995b2e5 --- /dev/null +++ b/src/lib/libcrypto/doc/DH_generate_key.pod | |||
@@ -0,0 +1,50 @@ | |||
1 | =pod | ||
2 | |||
3 | =head1 NAME | ||
4 | |||
5 | DH_generate_key, DH_compute_key - perform Diffie-Hellman key exchange | ||
6 | |||
7 | =head1 SYNOPSIS | ||
8 | |||
9 | #include <openssl/dh.h> | ||
10 | |||
11 | int DH_generate_key(DH *dh); | ||
12 | |||
13 | int DH_compute_key(unsigned char *key, BIGNUM *pub_key, DH *dh); | ||
14 | |||
15 | =head1 DESCRIPTION | ||
16 | |||
17 | DH_generate_key() performs the first step of a Diffie-Hellman key | ||
18 | exchange by generating private and public DH values. By calling | ||
19 | DH_compute_key(), these are combined with the other party's public | ||
20 | value to compute the shared key. | ||
21 | |||
22 | DH_generate_key() expects B<dh> to contain the shared parameters | ||
23 | B<dh-E<gt>p> and B<dh-E<gt>g>. It generates a random private DH value | ||
24 | unless B<dh-E<gt>priv_key> is already set, and computes the | ||
25 | corresponding public value B<dh-E<gt>pub_key>, which can then be | ||
26 | published. | ||
27 | |||
28 | DH_compute_key() computes the shared secret from the private DH value | ||
29 | in B<dh> and the other party's public value in B<pub_key> and stores | ||
30 | it in B<key>. B<key> must point to B<DH_size(dh)> bytes of memory. | ||
31 | |||
32 | =head1 RETURN VALUES | ||
33 | |||
34 | DH_generate_key() returns 1 on success, 0 otherwise. | ||
35 | |||
36 | DH_compute_key() returns the size of the shared secret on success, -1 | ||
37 | on error. | ||
38 | |||
39 | The error codes can be obtained by L<ERR_get_error(3)|ERR_get_error(3)>. | ||
40 | |||
41 | =head1 SEE ALSO | ||
42 | |||
43 | L<dh(3)|dh(3)>, L<err(3)|err(3)>, L<rand(3)|rand(3)>, L<DH_size(3)|DH_size(3)> | ||
44 | |||
45 | =head1 HISTORY | ||
46 | |||
47 | DH_generate_key() and DH_compute_key() are available in all versions | ||
48 | of SSLeay and OpenSSL. | ||
49 | |||
50 | =cut | ||
diff --git a/src/lib/libcrypto/doc/DH_generate_parameters.pod b/src/lib/libcrypto/doc/DH_generate_parameters.pod new file mode 100644 index 0000000000..a7d0c75f0c --- /dev/null +++ b/src/lib/libcrypto/doc/DH_generate_parameters.pod | |||
@@ -0,0 +1,72 @@ | |||
1 | =pod | ||
2 | |||
3 | =head1 NAME | ||
4 | |||
5 | DH_generate_parameters, DH_check - generate and check Diffie-Hellman parameters | ||
6 | |||
7 | =head1 SYNOPSIS | ||
8 | |||
9 | #include <openssl/dh.h> | ||
10 | |||
11 | DH *DH_generate_parameters(int prime_len, int generator, | ||
12 | void (*callback)(int, int, void *), void *cb_arg); | ||
13 | |||
14 | int DH_check(DH *dh, int *codes); | ||
15 | |||
16 | =head1 DESCRIPTION | ||
17 | |||
18 | DH_generate_parameters() generates Diffie-Hellman parameters that can | ||
19 | be shared among a group of users, and returns them in a newly | ||
20 | allocated B<DH> structure. The pseudo-random number generator must be | ||
21 | seeded prior to calling DH_generate_parameters(). | ||
22 | |||
23 | B<prime_len> is the length in bits of the safe prime to be generated. | ||
24 | B<generator> is a small number E<gt> 1, typically 2 or 5. | ||
25 | |||
26 | A callback function may be used to provide feedback about the progress | ||
27 | of the key generation. If B<callback> is not B<NULL>, it will be | ||
28 | called as described in L<BN_generate_prime(3)|BN_generate_prime(3)> while a random prime | ||
29 | number is generated, and when a prime has been found, B<callback(3, | ||
30 | 0, cb_arg)> is called. | ||
31 | |||
32 | DH_check() validates Diffie-Hellman parameters. It checks that B<p> is | ||
33 | a safe prime, and that B<g> is a suitable generator. In the case of an | ||
34 | error, the bit flags DH_CHECK_P_NOT_SAFE_PRIME or | ||
35 | DH_NOT_SUITABLE_GENERATOR are set in B<*codes>. | ||
36 | DH_UNABLE_TO_CHECK_GENERATOR is set if the generator cannot be | ||
37 | checked, i.e. it does not equal 2 or 5. | ||
38 | |||
39 | =head1 RETURN VALUES | ||
40 | |||
41 | DH_generate_parameters() returns a pointer to the DH structure, or | ||
42 | NULL if the parameter generation fails. The error codes can be | ||
43 | obtained by L<ERR_get_error(3)|ERR_get_error(3)>. | ||
44 | |||
45 | DH_check() returns 1 if the check could be performed, 0 otherwise. | ||
46 | |||
47 | =head1 NOTES | ||
48 | |||
49 | DH_generate_parameters() may run for several hours before finding a | ||
50 | suitable prime. | ||
51 | |||
52 | The parameters generated by DH_generate_parameters() are not to be | ||
53 | used in signature schemes. | ||
54 | |||
55 | =head1 BUGS | ||
56 | |||
57 | If B<generator> is not 2 or 5, B<dh-E<gt>g>=B<generator> is not | ||
58 | a usable generator. | ||
59 | |||
60 | =head1 SEE ALSO | ||
61 | |||
62 | L<dh(3)|dh(3)>, L<err(3)|err(3)>, L<rand(3)|rand(3)>, L<DH_free(3)|DH_free(3)> | ||
63 | |||
64 | =head1 HISTORY | ||
65 | |||
66 | DH_check() is available in all versions of SSLeay and OpenSSL. | ||
67 | The B<cb_arg> argument to DH_generate_parameters() was added in SSLeay 0.9.0. | ||
68 | |||
69 | In versions before OpenSSL 0.9.5, DH_CHECK_P_NOT_STRONG_PRIME is used | ||
70 | instead of DH_CHECK_P_NOT_SAFE_PRIME. | ||
71 | |||
72 | =cut | ||
diff --git a/src/lib/libcrypto/doc/DH_get_ex_new_index.pod b/src/lib/libcrypto/doc/DH_get_ex_new_index.pod new file mode 100644 index 0000000000..82e2548bcd --- /dev/null +++ b/src/lib/libcrypto/doc/DH_get_ex_new_index.pod | |||
@@ -0,0 +1,36 @@ | |||
1 | =pod | ||
2 | |||
3 | =head1 NAME | ||
4 | |||
5 | DH_get_ex_new_index, DH_set_ex_data, DH_get_ex_data - add application specific data to DH structures | ||
6 | |||
7 | =head1 SYNOPSIS | ||
8 | |||
9 | #include <openssl/dh.h> | ||
10 | |||
11 | int DH_get_ex_new_index(long argl, void *argp, | ||
12 | CRYPTO_EX_new *new_func, | ||
13 | CRYPTO_EX_dup *dup_func, | ||
14 | CRYPTO_EX_free *free_func); | ||
15 | |||
16 | int DH_set_ex_data(DH *d, int idx, void *arg); | ||
17 | |||
18 | char *DH_get_ex_data(DH *d, int idx); | ||
19 | |||
20 | =head1 DESCRIPTION | ||
21 | |||
22 | These functions handle application specific data in DH | ||
23 | structures. Their usage is identical to that of | ||
24 | RSA_get_ex_new_index(), RSA_set_ex_data() and RSA_get_ex_data() | ||
25 | as described in L<RSA_get_ex_new_index(3)>. | ||
26 | |||
27 | =head1 SEE ALSO | ||
28 | |||
29 | L<RSA_get_ex_new_index()|RSA_get_ex_new_index()>, L<dh(3)|dh(3)> | ||
30 | |||
31 | =head1 HISTORY | ||
32 | |||
33 | DH_get_ex_new_index(), DH_set_ex_data() and DH_get_ex_data() are | ||
34 | available since OpenSSL 0.9.5. | ||
35 | |||
36 | =cut | ||
diff --git a/src/lib/libcrypto/doc/DH_new.pod b/src/lib/libcrypto/doc/DH_new.pod new file mode 100644 index 0000000000..64624b9d15 --- /dev/null +++ b/src/lib/libcrypto/doc/DH_new.pod | |||
@@ -0,0 +1,40 @@ | |||
1 | =pod | ||
2 | |||
3 | =head1 NAME | ||
4 | |||
5 | DH_new, DH_free - allocate and free DH objects | ||
6 | |||
7 | =head1 SYNOPSIS | ||
8 | |||
9 | #include <openssl/dh.h> | ||
10 | |||
11 | DH* DH_new(void); | ||
12 | |||
13 | void DH_free(DH *dh); | ||
14 | |||
15 | =head1 DESCRIPTION | ||
16 | |||
17 | DH_new() allocates and initializes a B<DH> structure. | ||
18 | |||
19 | DH_free() frees the B<DH> structure and its components. The values are | ||
20 | erased before the memory is returned to the system. | ||
21 | |||
22 | =head1 RETURN VALUES | ||
23 | |||
24 | If the allocation fails, DH_new() returns B<NULL> and sets an error | ||
25 | code that can be obtained by L<ERR_get_error(3)|ERR_get_error(3)>. Otherwise it returns | ||
26 | a pointer to the newly allocated structure. | ||
27 | |||
28 | DH_free() returns no value. | ||
29 | |||
30 | =head1 SEE ALSO | ||
31 | |||
32 | L<dh(3)|dh(3)>, L<err(3)|err(3)>, | ||
33 | L<DH_generate_parameters(3)|DH_generate_parameters(3)>, | ||
34 | L<DH_generate_key(3)|DH_generate_key(3)> | ||
35 | |||
36 | =head1 HISTORY | ||
37 | |||
38 | DH_new() and DH_free() are available in all versions of SSLeay and OpenSSL. | ||
39 | |||
40 | =cut | ||
diff --git a/src/lib/libcrypto/doc/DH_set_method.pod b/src/lib/libcrypto/doc/DH_set_method.pod new file mode 100644 index 0000000000..dca41d8dbc --- /dev/null +++ b/src/lib/libcrypto/doc/DH_set_method.pod | |||
@@ -0,0 +1,99 @@ | |||
1 | =pod | ||
2 | |||
3 | =head1 NAME | ||
4 | |||
5 | DH_set_default_method, DH_get_default_method, DH_set_method, | ||
6 | DH_new_method, DH_OpenSSL - select DH method | ||
7 | |||
8 | =head1 SYNOPSIS | ||
9 | |||
10 | #include <openssl/dh.h> | ||
11 | |||
12 | void DH_set_default_method(DH_METHOD *meth); | ||
13 | |||
14 | DH_METHOD *DH_get_default_method(void); | ||
15 | |||
16 | DH_METHOD *DH_set_method(DH *dh, DH_METHOD *meth); | ||
17 | |||
18 | DH *DH_new_method(DH_METHOD *meth); | ||
19 | |||
20 | DH_METHOD *DH_OpenSSL(void); | ||
21 | |||
22 | =head1 DESCRIPTION | ||
23 | |||
24 | A B<DH_METHOD> specifies the functions that OpenSSL uses for Diffie-Hellman | ||
25 | operations. By modifying the method, alternative implementations | ||
26 | such as hardware accelerators may be used. | ||
27 | |||
28 | Initially, the default is to use the OpenSSL internal implementation. | ||
29 | DH_OpenSSL() returns a pointer to that method. | ||
30 | |||
31 | DH_set_default_method() makes B<meth> the default method for all B<DH> | ||
32 | structures created later. | ||
33 | |||
34 | DH_get_default_method() returns a pointer to the current default | ||
35 | method. | ||
36 | |||
37 | DH_set_method() selects B<meth> for all operations using the structure B<dh>. | ||
38 | |||
39 | DH_get_method() returns a pointer to the method currently selected | ||
40 | for B<dh>. | ||
41 | |||
42 | DH_new_method() allocates and initializes a B<DH> structure so that | ||
43 | B<method> will be used for the DH operations. If B<method> is B<NULL>, | ||
44 | the default method is used. | ||
45 | |||
46 | =head1 THE DH_METHOD STRUCTURE | ||
47 | |||
48 | typedef struct dh_meth_st | ||
49 | { | ||
50 | /* name of the implementation */ | ||
51 | const char *name; | ||
52 | |||
53 | /* generate private and public DH values for key agreement */ | ||
54 | int (*generate_key)(DH *dh); | ||
55 | |||
56 | /* compute shared secret */ | ||
57 | int (*compute_key)(unsigned char *key, BIGNUM *pub_key, DH *dh); | ||
58 | |||
59 | /* compute r = a ^ p mod m. May be NULL */ | ||
60 | int (*bn_mod_exp)(DH *dh, BIGNUM *r, BIGNUM *a, const BIGNUM *p, | ||
61 | const BIGNUM *m, BN_CTX *ctx, | ||
62 | BN_MONT_CTX *m_ctx); | ||
63 | |||
64 | /* called at DH_new */ | ||
65 | int (*init)(DH *dh); | ||
66 | |||
67 | /* called at DH_free */ | ||
68 | int (*finish)(DH *dh); | ||
69 | |||
70 | int flags; | ||
71 | |||
72 | char *app_data; /* ?? */ | ||
73 | |||
74 | } DH_METHOD; | ||
75 | |||
76 | =head1 RETURN VALUES | ||
77 | |||
78 | DH_OpenSSL(), DH_get_default_method() and DH_get_method() return | ||
79 | pointers to the respective B<DH_METHOD>s. | ||
80 | |||
81 | DH_set_default_method() returns no value. | ||
82 | |||
83 | DH_set_method() returns a pointer to the B<DH_METHOD> previously | ||
84 | associated with B<dh>. | ||
85 | |||
86 | DH_new_method() returns B<NULL> and sets an error code that can be | ||
87 | obtained by L<ERR_get_error(3)|ERR_get_error(3)> if the allocation fails. Otherwise it | ||
88 | returns a pointer to the newly allocated structure. | ||
89 | |||
90 | =head1 SEE ALSO | ||
91 | |||
92 | L<dh(3)|dh(3)>, L<DH_new(3)|DH_new(3)> | ||
93 | |||
94 | =head1 HISTORY | ||
95 | |||
96 | DH_set_default_method(), DH_get_default_method(), DH_set_method(), | ||
97 | DH_new_method() and DH_OpenSSL() were added in OpenSSL 0.9.4. | ||
98 | |||
99 | =cut | ||
diff --git a/src/lib/libcrypto/doc/DH_size.pod b/src/lib/libcrypto/doc/DH_size.pod new file mode 100644 index 0000000000..97f26fda78 --- /dev/null +++ b/src/lib/libcrypto/doc/DH_size.pod | |||
@@ -0,0 +1,33 @@ | |||
1 | =pod | ||
2 | |||
3 | =head1 NAME | ||
4 | |||
5 | DH_size - get Diffie-Hellman prime size | ||
6 | |||
7 | =head1 SYNOPSIS | ||
8 | |||
9 | #include <openssl/dh.h> | ||
10 | |||
11 | int DH_size(DH *dh); | ||
12 | |||
13 | =head1 DESCRIPTION | ||
14 | |||
15 | This function returns the Diffie-Hellman size in bytes. It can be used | ||
16 | to determine how much memory must be allocated for the shared secret | ||
17 | computed by DH_compute_key(). | ||
18 | |||
19 | B<dh-E<gt>p> must not be B<NULL>. | ||
20 | |||
21 | =head1 RETURN VALUE | ||
22 | |||
23 | The size in bytes. | ||
24 | |||
25 | =head1 SEE ALSO | ||
26 | |||
27 | L<dh(3)|dh(3)>, L<DH_generate_key(3)|DH_generate_key(3)> | ||
28 | |||
29 | =head1 HISTORY | ||
30 | |||
31 | DH_size() is available in all versions of SSLeay and OpenSSL. | ||
32 | |||
33 | =cut | ||
diff --git a/src/lib/libcrypto/doc/DSA_SIG_new.pod b/src/lib/libcrypto/doc/DSA_SIG_new.pod new file mode 100644 index 0000000000..671655554a --- /dev/null +++ b/src/lib/libcrypto/doc/DSA_SIG_new.pod | |||
@@ -0,0 +1,39 @@ | |||
1 | =pod | ||
2 | |||
3 | =head1 NAME | ||
4 | |||
5 | DSA_SIG_new, DSA_SIG_free - allocate and free DSA signature objects | ||
6 | |||
7 | =head1 SYNOPSIS | ||
8 | |||
9 | #include <openssl/dsa.h> | ||
10 | |||
11 | DSA_SIG *DSA_SIG_new(void); | ||
12 | |||
13 | void DSA_SIG_free(DSA_SIG *a); | ||
14 | |||
15 | =head1 DESCRIPTION | ||
16 | |||
17 | DSA_SIG_new() allocates and initializes a B<DSA_SIG> structure. | ||
18 | |||
19 | DSA_SIG_free() frees the B<DSA_SIG> structure and its components. The | ||
20 | values are erased before the memory is returned to the system. | ||
21 | |||
22 | =head1 RETURN VALUES | ||
23 | |||
24 | If the allocation fails, DSA_SIG_new() returns B<NULL> and sets an | ||
25 | error code that can be obtained by | ||
26 | L<ERR_get_error(3)|ERR_get_error(3)>. Otherwise it returns a pointer | ||
27 | to the newly allocated structure. | ||
28 | |||
29 | DSA_SIG_free() returns no value. | ||
30 | |||
31 | =head1 SEE ALSO | ||
32 | |||
33 | L<dsa(3)|dsa(3)>, L<err(3)|err(3)>, L<DSA_do_sign(3)|DSA_do_sign(3)> | ||
34 | |||
35 | =head1 HISTORY | ||
36 | |||
37 | DSA_SIG_new() and DSA_SIG_free() were added in OpenSSL 0.9.3. | ||
38 | |||
39 | =cut | ||
diff --git a/src/lib/libcrypto/doc/DSA_do_sign.pod b/src/lib/libcrypto/doc/DSA_do_sign.pod new file mode 100644 index 0000000000..a24fd5714e --- /dev/null +++ b/src/lib/libcrypto/doc/DSA_do_sign.pod | |||
@@ -0,0 +1,47 @@ | |||
1 | =pod | ||
2 | |||
3 | =head1 NAME | ||
4 | |||
5 | DSA_do_sign, DSA_do_verify - raw DSA signature operations | ||
6 | |||
7 | =head1 SYNOPSIS | ||
8 | |||
9 | #include <openssl/dsa.h> | ||
10 | |||
11 | DSA_SIG *DSA_do_sign(const unsigned char *dgst, int dlen, DSA *dsa); | ||
12 | |||
13 | int DSA_do_verify(const unsigned char *dgst, int dgst_len, | ||
14 | DSA_SIG *sig, DSA *dsa); | ||
15 | |||
16 | =head1 DESCRIPTION | ||
17 | |||
18 | DSA_do_sign() computes a digital signature on the B<len> byte message | ||
19 | digest B<dgst> using the private key B<dsa> and returns it in a | ||
20 | newly allocated B<DSA_SIG> structure. | ||
21 | |||
22 | L<DSA_sign_setup(3)|DSA_sign_setup(3)> may be used to precompute part | ||
23 | of the signing operation in case signature generation is | ||
24 | time-critical. | ||
25 | |||
26 | DSA_do_verify() verifies that the signature B<sig> matches a given | ||
27 | message digest B<dgst> of size B<len>. B<dsa> is the signer's public | ||
28 | key. | ||
29 | |||
30 | =head1 RETURN VALUES | ||
31 | |||
32 | DSA_do_sign() returns the signature, NULL on error. DSA_do_verify() | ||
33 | returns 1 for a valid signature, 0 for an incorrect signature and -1 | ||
34 | on error. The error codes can be obtained by | ||
35 | L<ERR_get_error(3)|ERR_get_error(3)>. | ||
36 | |||
37 | =head1 SEE ALSO | ||
38 | |||
39 | L<dsa(3)|dsa(3)>, L<err(3)|err(3)>, L<rand(3)|rand(3)>, | ||
40 | L<DSA_SIG_new(3)|DSA_SIG_new(3)>, | ||
41 | L<DSA_sign(3)|DSA_sign(3)> | ||
42 | |||
43 | =head1 HISTORY | ||
44 | |||
45 | DSA_do_sign() and DSA_do_verify() were added in OpenSSL 0.9.3. | ||
46 | |||
47 | =cut | ||
diff --git a/src/lib/libcrypto/doc/DSA_dup_DH.pod b/src/lib/libcrypto/doc/DSA_dup_DH.pod new file mode 100644 index 0000000000..29cb1075d1 --- /dev/null +++ b/src/lib/libcrypto/doc/DSA_dup_DH.pod | |||
@@ -0,0 +1,36 @@ | |||
1 | =pod | ||
2 | |||
3 | =head1 NAME | ||
4 | |||
5 | DSA_dup_DH - create a DH structure out of DSA structure | ||
6 | |||
7 | =head1 SYNOPSIS | ||
8 | |||
9 | #include <openssl/dsa.h> | ||
10 | |||
11 | DH * DSA_dup_DH(DSA *r); | ||
12 | |||
13 | =head1 DESCRIPTION | ||
14 | |||
15 | DSA_dup_DH() duplicates DSA parameters/keys as DH parameters/keys. q | ||
16 | is lost during that conversion, but the resulting DH parameters | ||
17 | contain its length. | ||
18 | |||
19 | =head1 RETURN VALUE | ||
20 | |||
21 | DSA_dup_DH() returns the new B<DH> structure, and NULL on error. The | ||
22 | error codes can be obtained by L<ERR_get_error(3)|ERR_get_error(3)>. | ||
23 | |||
24 | =head1 NOTE | ||
25 | |||
26 | Be careful to avoid small subgroup attacks when using this. | ||
27 | |||
28 | =head1 SEE ALSO | ||
29 | |||
30 | L<dh(3)|dh(3)>, L<dsa(3)|dsa(3)>, L<err(3)|err(3)> | ||
31 | |||
32 | =head1 HISTORY | ||
33 | |||
34 | DSA_dup_DH() was added in OpenSSL 0.9.4. | ||
35 | |||
36 | =cut | ||
diff --git a/src/lib/libcrypto/doc/DSA_generate_key.pod b/src/lib/libcrypto/doc/DSA_generate_key.pod new file mode 100644 index 0000000000..52890db5be --- /dev/null +++ b/src/lib/libcrypto/doc/DSA_generate_key.pod | |||
@@ -0,0 +1,33 @@ | |||
1 | =pod | ||
2 | |||
3 | =head1 NAME | ||
4 | |||
5 | DSA_generate_key - generate DSA key pair | ||
6 | |||
7 | =head1 SYNOPSIS | ||
8 | |||
9 | #include <openssl/dsa.h> | ||
10 | |||
11 | int DSA_generate_key(DSA *a); | ||
12 | |||
13 | =head1 DESCRIPTION | ||
14 | |||
15 | DSA_generate_key() expects B<a> to contain DSA parameters. It generates | ||
16 | a new key pair and stores it in B<a-E<gt>pub_key> and B<a-E<gt>priv_key>. | ||
17 | |||
18 | The PRNG must be seeded prior to calling DSA_generate_key(). | ||
19 | |||
20 | =head1 RETURN VALUE | ||
21 | |||
22 | DSA_generate_key() returns 1 on success, 0 otherwise. | ||
23 | The error codes can be obtained by L<ERR_get_error(3)|ERR_get_error(3)>. | ||
24 | |||
25 | =head1 SEE ALSO | ||
26 | |||
27 | L<dsa(3)|dsa(3)>, L<err(3)|err(3)>, L<rand(3)|rand(3)>, L<DSA_generate_parameters(3)|DSA_generate_parameters(3)> | ||
28 | |||
29 | =head1 HISTORY | ||
30 | |||
31 | DSA_generate_key() is available since SSLeay 0.8. | ||
32 | |||
33 | =cut | ||
diff --git a/src/lib/libcrypto/doc/DSA_generate_parameters.pod b/src/lib/libcrypto/doc/DSA_generate_parameters.pod new file mode 100644 index 0000000000..43f60b0eb9 --- /dev/null +++ b/src/lib/libcrypto/doc/DSA_generate_parameters.pod | |||
@@ -0,0 +1,105 @@ | |||
1 | =pod | ||
2 | |||
3 | =head1 NAME | ||
4 | |||
5 | DSA_generate_parameters - generate DSA parameters | ||
6 | |||
7 | =head1 SYNOPSIS | ||
8 | |||
9 | #include <openssl/dsa.h> | ||
10 | |||
11 | DSA *DSA_generate_parameters(int bits, unsigned char *seed, | ||
12 | int seed_len, int *counter_ret, unsigned long *h_ret, | ||
13 | void (*callback)(int, int, void *), void *cb_arg); | ||
14 | |||
15 | =head1 DESCRIPTION | ||
16 | |||
17 | DSA_generate_parameters() generates primes p and q and a generator g | ||
18 | for use in the DSA. | ||
19 | |||
20 | B<bits> is the length of the prime to be generated; the DSS allows a | ||
21 | maximum of 1024 bits. | ||
22 | |||
23 | If B<seed> is B<NULL> or B<seed_len> E<lt> 20, the primes will be | ||
24 | generated at random. Otherwise, the seed is used to generate | ||
25 | them. If the given seed does not yield a prime q, a new random | ||
26 | seed is chosen and placed at B<seed>. | ||
27 | |||
28 | DSA_generate_parameters() places the iteration count in | ||
29 | *B<counter_ret> and a counter used for finding a generator in | ||
30 | *B<h_ret>, unless these are B<NULL>. | ||
31 | |||
32 | A callback function may be used to provide feedback about the progress | ||
33 | of the key generation. If B<callback> is not B<NULL>, it will be | ||
34 | called as follows: | ||
35 | |||
36 | =over 4 | ||
37 | |||
38 | =item * | ||
39 | |||
40 | When a candidate for q is generated, B<callback(0, m++, cb_arg)> is called | ||
41 | (m is 0 for the first candidate). | ||
42 | |||
43 | =item * | ||
44 | |||
45 | When a candidate for q has passed a test by trial division, | ||
46 | B<callback(1, -1, cb_arg)> is called. | ||
47 | While a candidate for q is tested by Miller-Rabin primality tests, | ||
48 | B<callback(1, i, cb_arg)> is called in the outer loop | ||
49 | (once for each witness that confirms that the candidate may be prime); | ||
50 | i is the loop counter (starting at 0). | ||
51 | |||
52 | =item * | ||
53 | |||
54 | When a prime q has been found, B<callback(2, 0, cb_arg)> and | ||
55 | B<callback(3, 0, cb_arg)> are called. | ||
56 | |||
57 | =item * | ||
58 | |||
59 | Before a candidate for p (other than the first) is generated and tested, | ||
60 | B<callback(0, counter, cb_arg)> is called. | ||
61 | |||
62 | =item * | ||
63 | |||
64 | When a candidate for p has passed the test by trial division, | ||
65 | B<callback(1, -1, cb_arg)> is called. | ||
66 | While it is tested by the Miller-Rabin primality test, | ||
67 | B<callback(1, i, cb_arg)> is called in the outer loop | ||
68 | (once for each witness that confirms that the candidate may be prime). | ||
69 | i is the loop counter (starting at 0). | ||
70 | |||
71 | =item * | ||
72 | |||
73 | When p has been found, B<callback(2, 1, cb_arg)> is called. | ||
74 | |||
75 | =item * | ||
76 | |||
77 | When the generator has been found, B<callback(3, 1, cb_arg)> is called. | ||
78 | |||
79 | =back | ||
80 | |||
81 | =head1 RETURN VALUE | ||
82 | |||
83 | DSA_generate_parameters() returns a pointer to the DSA structure, or | ||
84 | B<NULL> if the parameter generation fails. The error codes can be | ||
85 | obtained by L<ERR_get_error(3)|ERR_get_error(3)>. | ||
86 | |||
87 | =head1 BUGS | ||
88 | |||
89 | Seed lengths E<gt> 20 are not supported. | ||
90 | |||
91 | =head1 SEE ALSO | ||
92 | |||
93 | L<dsa(3)|dsa(3)>, L<err(3)|err(3)>, L<rand(3)|rand(3)>, | ||
94 | L<DSA_free(3)|DSA_free(3)> | ||
95 | |||
96 | =head1 HISTORY | ||
97 | |||
98 | DSA_generate_parameters() appeared in SSLeay 0.8. The B<cb_arg> | ||
99 | argument was added in SSLeay 0.9.0. | ||
100 | In versions up to OpenSSL 0.9.4, B<callback(1, ...)> was called | ||
101 | in the inner loop of the Miller-Rabin test whenever it reached the | ||
102 | squaring step (the parameters to B<callback> did not reveal how many | ||
103 | witnesses had been tested); since OpenSSL 0.9.5, B<callback(1, ...)> | ||
104 | is called as in BN_is_prime(3), i.e. once for each witness. | ||
105 | =cut | ||
diff --git a/src/lib/libcrypto/doc/DSA_get_ex_new_index.pod b/src/lib/libcrypto/doc/DSA_get_ex_new_index.pod new file mode 100644 index 0000000000..4612e708ec --- /dev/null +++ b/src/lib/libcrypto/doc/DSA_get_ex_new_index.pod | |||
@@ -0,0 +1,36 @@ | |||
1 | =pod | ||
2 | |||
3 | =head1 NAME | ||
4 | |||
5 | DSA_get_ex_new_index, DSA_set_ex_data, DSA_get_ex_data - add application specific data to DSA structures | ||
6 | |||
7 | =head1 SYNOPSIS | ||
8 | |||
9 | #include <openssl/DSA.h> | ||
10 | |||
11 | int DSA_get_ex_new_index(long argl, void *argp, | ||
12 | CRYPTO_EX_new *new_func, | ||
13 | CRYPTO_EX_dup *dup_func, | ||
14 | CRYPTO_EX_free *free_func); | ||
15 | |||
16 | int DSA_set_ex_data(DSA *d, int idx, void *arg); | ||
17 | |||
18 | char *DSA_get_ex_data(DSA *d, int idx); | ||
19 | |||
20 | =head1 DESCRIPTION | ||
21 | |||
22 | These functions handle application specific data in DSA | ||
23 | structures. Their usage is identical to that of | ||
24 | RSA_get_ex_new_index(), RSA_set_ex_data() and RSA_get_ex_data() | ||
25 | as described in L<RSA_get_ex_new_index(3)>. | ||
26 | |||
27 | =head1 SEE ALSO | ||
28 | |||
29 | L<RSA_get_ex_new_index(3)|RSA_get_ex_new_index(3)>, L<dsa(3)|dsa(3)> | ||
30 | |||
31 | =head1 HISTORY | ||
32 | |||
33 | DSA_get_ex_new_index(), DSA_set_ex_data() and DSA_get_ex_data() are | ||
34 | available since OpenSSL 0.9.5. | ||
35 | |||
36 | =cut | ||
diff --git a/src/lib/libcrypto/doc/DSA_new.pod b/src/lib/libcrypto/doc/DSA_new.pod new file mode 100644 index 0000000000..7dde54445b --- /dev/null +++ b/src/lib/libcrypto/doc/DSA_new.pod | |||
@@ -0,0 +1,41 @@ | |||
1 | =pod | ||
2 | |||
3 | =head1 NAME | ||
4 | |||
5 | DSA_new, DSA_free - allocate and free DSA objects | ||
6 | |||
7 | =head1 SYNOPSIS | ||
8 | |||
9 | #include <openssl/dsa.h> | ||
10 | |||
11 | DSA* DSA_new(void); | ||
12 | |||
13 | void DSA_free(DSA *dsa); | ||
14 | |||
15 | =head1 DESCRIPTION | ||
16 | |||
17 | DSA_new() allocates and initializes a B<DSA> structure. | ||
18 | |||
19 | DSA_free() frees the B<DSA> structure and its components. The values are | ||
20 | erased before the memory is returned to the system. | ||
21 | |||
22 | =head1 RETURN VALUES | ||
23 | |||
24 | If the allocation fails, DSA_new() returns B<NULL> and sets an error | ||
25 | code that can be obtained by | ||
26 | L<ERR_get_error(3)|ERR_get_error(3)>. Otherwise it returns a pointer | ||
27 | to the newly allocated structure. | ||
28 | |||
29 | DSA_free() returns no value. | ||
30 | |||
31 | =head1 SEE ALSO | ||
32 | |||
33 | L<dsa(3)|dsa(3)>, L<err(3)|err(3)>, | ||
34 | L<DSA_generate_parameters(3)|DSA_generate_parameters(3)>, | ||
35 | L<DSA_generate_key(3)|DSA_generate_key(3)> | ||
36 | |||
37 | =head1 HISTORY | ||
38 | |||
39 | DSA_new() and DSA_free() are available in all versions of SSLeay and OpenSSL. | ||
40 | |||
41 | =cut | ||
diff --git a/src/lib/libcrypto/doc/DSA_set_method.pod b/src/lib/libcrypto/doc/DSA_set_method.pod new file mode 100644 index 0000000000..0b13ec9237 --- /dev/null +++ b/src/lib/libcrypto/doc/DSA_set_method.pod | |||
@@ -0,0 +1,111 @@ | |||
1 | =pod | ||
2 | |||
3 | =head1 NAME | ||
4 | |||
5 | DSA_set_default_method, DSA_get_default_method, DSA_set_method, | ||
6 | DSA_new_method, DSA_OpenSSL - select RSA method | ||
7 | |||
8 | =head1 SYNOPSIS | ||
9 | |||
10 | #include <openssl/DSA.h> | ||
11 | |||
12 | void DSA_set_default_method(DSA_METHOD *meth); | ||
13 | |||
14 | DSA_METHOD *DSA_get_default_method(void); | ||
15 | |||
16 | DSA_METHOD *DSA_set_method(DSA *dsa, DSA_METHOD *meth); | ||
17 | |||
18 | DSA *DSA_new_method(DSA_METHOD *meth); | ||
19 | |||
20 | DSA_METHOD *DSA_OpenSSL(void); | ||
21 | |||
22 | =head1 DESCRIPTION | ||
23 | |||
24 | A B<DSA_METHOD> specifies the functions that OpenSSL uses for DSA | ||
25 | operations. By modifying the method, alternative implementations | ||
26 | such as hardware accelerators may be used. | ||
27 | |||
28 | Initially, the default is to use the OpenSSL internal implementation. | ||
29 | DSA_OpenSSL() returns a pointer to that method. | ||
30 | |||
31 | DSA_set_default_method() makes B<meth> the default method for all B<DSA> | ||
32 | structures created later. | ||
33 | |||
34 | DSA_get_default_method() returns a pointer to the current default | ||
35 | method. | ||
36 | |||
37 | DSA_set_method() selects B<meth> for all operations using the structure B<DSA>. | ||
38 | |||
39 | DSA_get_method() returns a pointer to the method currently selected | ||
40 | for B<DSA>. | ||
41 | |||
42 | DSA_new_method() allocates and initializes a B<DSA> structure so that | ||
43 | B<method> will be used for the DSA operations. If B<method> is B<NULL>, | ||
44 | the default method is used. | ||
45 | |||
46 | =head1 THE DSA_METHOD STRUCTURE | ||
47 | |||
48 | struct | ||
49 | { | ||
50 | /* name of the implementation */ | ||
51 | const char *name; | ||
52 | |||
53 | /* sign */ | ||
54 | DSA_SIG *(*dsa_do_sign)(const unsigned char *dgst, int dlen, | ||
55 | DSA *dsa); | ||
56 | |||
57 | /* pre-compute k^-1 and r */ | ||
58 | int (*dsa_sign_setup)(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, | ||
59 | BIGNUM **rp); | ||
60 | |||
61 | /* verify */ | ||
62 | int (*dsa_do_verify)(const unsigned char *dgst, int dgst_len, | ||
63 | DSA_SIG *sig, DSA *dsa); | ||
64 | |||
65 | /* compute rr = a1^p1 * a2^p2 mod m. May be NULL */ | ||
66 | int (*dsa_mod_exp)(DSA *dsa, BIGNUM *rr, BIGNUM *a1, BIGNUM *p1, | ||
67 | BIGNUM *a2, BIGNUM *p2, BIGNUM *m, | ||
68 | BN_CTX *ctx, BN_MONT_CTX *in_mont); | ||
69 | |||
70 | /* compute r = a ^ p mod m. May be NULL */ | ||
71 | int (*bn_mod_exp)(DSA *dsa, BIGNUM *r, BIGNUM *a, | ||
72 | const BIGNUM *p, const BIGNUM *m, | ||
73 | BN_CTX *ctx, BN_MONT_CTX *m_ctx); | ||
74 | |||
75 | /* called at DSA_new */ | ||
76 | int (*init)(DSA *DSA); | ||
77 | |||
78 | /* called at DSA_free */ | ||
79 | int (*finish)(DSA *DSA); | ||
80 | |||
81 | int flags; | ||
82 | |||
83 | char *app_data; /* ?? */ | ||
84 | |||
85 | } DSA_METHOD; | ||
86 | |||
87 | =head1 RETURN VALUES | ||
88 | |||
89 | DSA_OpenSSL(), DSA_get_default_method() and DSA_get_method() return | ||
90 | pointers to the respective B<DSA_METHOD>s. | ||
91 | |||
92 | DSA_set_default_method() returns no value. | ||
93 | |||
94 | DSA_set_method() returns a pointer to the B<DSA_METHOD> previously | ||
95 | associated with B<dsa>. | ||
96 | |||
97 | DSA_new_method() returns B<NULL> and sets an error code that can be | ||
98 | obtained by L<ERR_get_error(3)|ERR_get_error(3)> if the allocation | ||
99 | fails. Otherwise it returns a pointer to the newly allocated | ||
100 | structure. | ||
101 | |||
102 | =head1 SEE ALSO | ||
103 | |||
104 | L<dsa(3)|dsa(3)>, L<DSA_new(3)|DSA_new(3)> | ||
105 | |||
106 | =head1 HISTORY | ||
107 | |||
108 | DSA_set_default_method(), DSA_get_default_method(), DSA_set_method(), | ||
109 | DSA_new_method() and DSA_OpenSSL() were added in OpenSSL 0.9.4. | ||
110 | |||
111 | =cut | ||
diff --git a/src/lib/libcrypto/doc/DSA_sign.pod b/src/lib/libcrypto/doc/DSA_sign.pod new file mode 100644 index 0000000000..f6e60a8ca3 --- /dev/null +++ b/src/lib/libcrypto/doc/DSA_sign.pod | |||
@@ -0,0 +1,66 @@ | |||
1 | =pod | ||
2 | |||
3 | =head1 NAME | ||
4 | |||
5 | DSA_sign, DSA_sign_setup, DSA_verify - DSA signatures | ||
6 | |||
7 | =head1 SYNOPSIS | ||
8 | |||
9 | #include <openssl/dsa.h> | ||
10 | |||
11 | int DSA_sign(int type, const unsigned char *dgst, int len, | ||
12 | unsigned char *sigret, unsigned int *siglen, DSA *dsa); | ||
13 | |||
14 | int DSA_sign_setup(DSA *dsa, BN_CTX *ctx, BIGNUM **kinvp, | ||
15 | BIGNUM **rp); | ||
16 | |||
17 | int DSA_verify(int type, const unsigned char *dgst, int len, | ||
18 | unsigned char *sigbuf, int siglen, DSA *dsa); | ||
19 | |||
20 | =head1 DESCRIPTION | ||
21 | |||
22 | DSA_sign() computes a digital signature on the B<len> byte message | ||
23 | digest B<dgst> using the private key B<dsa> and places its ASN.1 DER | ||
24 | encoding at B<sigret>. The length of the signature is places in | ||
25 | *B<siglen>. B<sigret> must point to DSA_size(B<dsa>) bytes of memory. | ||
26 | |||
27 | DSA_sign_setup() may be used to precompute part of the signing | ||
28 | operation in case signature generation is time-critical. It expects | ||
29 | B<dsa> to contain DSA parameters. It places the precomputed values | ||
30 | in newly allocated B<BIGNUM>s at *B<kinvp> and *B<rp>, after freeing | ||
31 | the old ones unless *B<kinvp> and *B<rp> are NULL. These values may | ||
32 | be passed to DSA_sign() in B<dsa-E<gt>kinv> and B<dsa-E<gt>r>. | ||
33 | B<ctx> is a pre-allocated B<BN_CTX> or NULL. | ||
34 | |||
35 | DSA_verify() verifies that the signature B<sigbuf> of size B<siglen> | ||
36 | matches a given message digest B<dgst> of size B<len>. | ||
37 | B<dsa> is the signer's public key. | ||
38 | |||
39 | The B<type> parameter is ignored. | ||
40 | |||
41 | The PRNG must be seeded before DSA_sign() (or DSA_sign_setup()) | ||
42 | is called. | ||
43 | |||
44 | =head1 RETURN VALUES | ||
45 | |||
46 | DSA_sign() and DSA_sign_setup() return 1 on success, 0 on error. | ||
47 | DSA_verify() returns 1 for a valid signature, 0 for an incorrect | ||
48 | signature and -1 on error. The error codes can be obtained by | ||
49 | L<ERR_get_error(3)|ERR_get_error(3)>. | ||
50 | |||
51 | =head1 CONFORMING TO | ||
52 | |||
53 | US Federal Information Processing Standard FIPS 186 (Digital Signature | ||
54 | Standard, DSS), ANSI X9.30 | ||
55 | |||
56 | =head1 SEE ALSO | ||
57 | |||
58 | L<dsa(3)|dsa(3)>, L<err(3)|err(3)>, L<rand(3)|rand(3)>, | ||
59 | L<DSA_do_sign(3)|DSA_do_sign(3)> | ||
60 | |||
61 | =head1 HISTORY | ||
62 | |||
63 | DSA_sign() and DSA_verify() are available in all versions of SSLeay. | ||
64 | DSA_sign_setup() was added in SSLeay 0.8. | ||
65 | |||
66 | =cut | ||
diff --git a/src/lib/libcrypto/doc/DSA_size.pod b/src/lib/libcrypto/doc/DSA_size.pod new file mode 100644 index 0000000000..23b6320a4d --- /dev/null +++ b/src/lib/libcrypto/doc/DSA_size.pod | |||
@@ -0,0 +1,33 @@ | |||
1 | =pod | ||
2 | |||
3 | =head1 NAME | ||
4 | |||
5 | DSA_size - get DSA signature size | ||
6 | |||
7 | =head1 SYNOPSIS | ||
8 | |||
9 | #include <openssl/dsa.h> | ||
10 | |||
11 | int DSA_size(DSA *dsa); | ||
12 | |||
13 | =head1 DESCRIPTION | ||
14 | |||
15 | This function returns the size of an ASN.1 encoded DSA signature in | ||
16 | bytes. It can be used to determine how much memory must be allocated | ||
17 | for a DSA signature. | ||
18 | |||
19 | B<dsa-E<gt>q> must not be B<NULL>. | ||
20 | |||
21 | =head1 RETURN VALUE | ||
22 | |||
23 | The size in bytes. | ||
24 | |||
25 | =head1 SEE ALSO | ||
26 | |||
27 | L<dsa(3)|dsa(3)>, L<DSA_sign(3)|DSA_sign(3)> | ||
28 | |||
29 | =head1 HISTORY | ||
30 | |||
31 | DSA_size() is available in all versions of SSLeay and OpenSSL. | ||
32 | |||
33 | =cut | ||
diff --git a/src/lib/libcrypto/doc/ERR_GET_LIB.pod b/src/lib/libcrypto/doc/ERR_GET_LIB.pod new file mode 100644 index 0000000000..2a129da036 --- /dev/null +++ b/src/lib/libcrypto/doc/ERR_GET_LIB.pod | |||
@@ -0,0 +1,51 @@ | |||
1 | =pod | ||
2 | |||
3 | =head1 NAME | ||
4 | |||
5 | ERR_GET_LIB, ERR_GET_FUNC, ERR_GET_REASON - get library, function and | ||
6 | reason code | ||
7 | |||
8 | =head1 SYNOPSIS | ||
9 | |||
10 | #include <openssl/err.h> | ||
11 | |||
12 | int ERR_GET_LIB(unsigned long e); | ||
13 | |||
14 | int ERR_GET_FUNC(unsigned long e); | ||
15 | |||
16 | int ERR_GET_REASON(unsigned long e); | ||
17 | |||
18 | =head1 DESCRIPTION | ||
19 | |||
20 | The error code returned by ERR_get_error() consists of a library | ||
21 | number, function code and reason code. ERR_GET_LIB(), ERR_GET_FUNC() | ||
22 | and ERR_GET_REASON() can be used to extract these. | ||
23 | |||
24 | The library number and function code describe where the error | ||
25 | occurred, the reason code is the information about what went wrong. | ||
26 | |||
27 | Each sub-library of OpenSSL has a unique library number; function and | ||
28 | reason codes are unique within each sub-library. Note that different | ||
29 | libraries may use the same value to signal different functions and | ||
30 | reasons. | ||
31 | |||
32 | B<ERR_R_...> reason codes such as B<ERR_R_MALLOC_FAILURE> are globally | ||
33 | unique. However, when checking for sub-library specific reason codes, | ||
34 | be sure to also compare the library number. | ||
35 | |||
36 | ERR_GET_LIB(), ERR_GET_FUNC() and ERR_GET_REASON() are macros. | ||
37 | |||
38 | =head1 RETURN VALUES | ||
39 | |||
40 | The library number, function code and reason code respectively. | ||
41 | |||
42 | =head1 SEE ALSO | ||
43 | |||
44 | L<err(3)|err(3)>, L<ERR_get_error(3)|ERR_get_error(3)> | ||
45 | |||
46 | =head1 HISTORY | ||
47 | |||
48 | ERR_GET_LIB(), ERR_GET_FUNC() and ERR_GET_REASON() are available in | ||
49 | all versions of SSLeay and OpenSSL. | ||
50 | |||
51 | =cut | ||
diff --git a/src/lib/libcrypto/doc/ERR_clear_error.pod b/src/lib/libcrypto/doc/ERR_clear_error.pod new file mode 100644 index 0000000000..566e1f4e31 --- /dev/null +++ b/src/lib/libcrypto/doc/ERR_clear_error.pod | |||
@@ -0,0 +1,29 @@ | |||
1 | =pod | ||
2 | |||
3 | =head1 NAME | ||
4 | |||
5 | ERR_clear_error - clear the error queue | ||
6 | |||
7 | =head1 SYNOPSIS | ||
8 | |||
9 | #include <openssl/err.h> | ||
10 | |||
11 | void ERR_clear_error(void); | ||
12 | |||
13 | =head1 DESCRIPTION | ||
14 | |||
15 | ERR_clear_error() empties the current thread's error queue. | ||
16 | |||
17 | =head1 RETURN VALUES | ||
18 | |||
19 | ERR_clear_error() has no return value. | ||
20 | |||
21 | =head1 SEE ALSO | ||
22 | |||
23 | L<err(3)|err(3)>, L<ERR_get_error(3)|ERR_get_error(3)> | ||
24 | |||
25 | =head1 HISTORY | ||
26 | |||
27 | ERR_clear_error() is available in all versions of SSLeay and OpenSSL. | ||
28 | |||
29 | =cut | ||
diff --git a/src/lib/libcrypto/doc/ERR_error_string.pod b/src/lib/libcrypto/doc/ERR_error_string.pod new file mode 100644 index 0000000000..0d2417599c --- /dev/null +++ b/src/lib/libcrypto/doc/ERR_error_string.pod | |||
@@ -0,0 +1,65 @@ | |||
1 | =pod | ||
2 | |||
3 | =head1 NAME | ||
4 | |||
5 | ERR_error_string - obtain human-readable error message | ||
6 | |||
7 | =head1 SYNOPSIS | ||
8 | |||
9 | #include <openssl/err.h> | ||
10 | |||
11 | char *ERR_error_string(unsigned long e, char *buf); | ||
12 | |||
13 | const char *ERR_lib_error_string(unsigned long e); | ||
14 | const char *ERR_func_error_string(unsigned long e); | ||
15 | const char *ERR_reason_error_string(unsigned long e); | ||
16 | |||
17 | =head1 DESCRIPTION | ||
18 | |||
19 | ERR_error_string() generates a human-readable string representing the | ||
20 | error code B<e>, and places it at B<buf>. B<buf> must be at least 120 | ||
21 | bytes long. If B<buf> is B<NULL>, the error string is placed in a | ||
22 | static buffer. | ||
23 | |||
24 | The string will have the following format: | ||
25 | |||
26 | error:[error code]:[library name]:[function name]:[reason string] | ||
27 | |||
28 | I<error code> is an 8 digit hexadecimal number, I<library name>, | ||
29 | I<function name> and I<reason string> are ASCII text. | ||
30 | |||
31 | ERR_lib_error_string(), ERR_func_error_string() and | ||
32 | ERR_reason_error_string() return the library name, function | ||
33 | name and reason string respectively. | ||
34 | |||
35 | The OpenSSL error strings should be loaded by calling | ||
36 | L<ERR_load_crypto_strings(3)|ERR_load_crypto_strings(3)> or, for SSL | ||
37 | applications, L<SSL_load_error_strings(3)|SSL_load_error_strings(3)> | ||
38 | first. | ||
39 | If there is no text string registered for the given error code, | ||
40 | the error string will contain the numeric code. | ||
41 | |||
42 | L<ERR_print_errors(3)|ERR_print_errors(3)> can be used to print | ||
43 | all error codes currently in the queue. | ||
44 | |||
45 | =head1 RETURN VALUES | ||
46 | |||
47 | ERR_error_string() returns a pointer to a static buffer containing the | ||
48 | string if B<buf == NULL>, B<buf> otherwise. | ||
49 | |||
50 | ERR_lib_error_string(), ERR_func_error_string() and | ||
51 | ERR_reason_error_string() return the strings, and B<NULL> if | ||
52 | none is registered for the error code. | ||
53 | |||
54 | =head1 SEE ALSO | ||
55 | |||
56 | L<err(3)|err(3)>, L<ERR_get_error(3)|ERR_get_error(3)>, | ||
57 | L<ERR_load_crypto_strings(3)|ERR_load_crypto_strings(3)>, | ||
58 | L<SSL_load_error_strings(3)|SSL_load_error_strings(3)> | ||
59 | L<ERR_print_errors(3)|ERR_print_errors(3)> | ||
60 | |||
61 | =head1 HISTORY | ||
62 | |||
63 | ERR_error_string() is available in all versions of SSLeay and OpenSSL. | ||
64 | |||
65 | =cut | ||
diff --git a/src/lib/libcrypto/doc/ERR_get_error.pod b/src/lib/libcrypto/doc/ERR_get_error.pod new file mode 100644 index 0000000000..75ece00d97 --- /dev/null +++ b/src/lib/libcrypto/doc/ERR_get_error.pod | |||
@@ -0,0 +1,62 @@ | |||
1 | =pod | ||
2 | |||
3 | =head1 NAME | ||
4 | |||
5 | ERR_get_error, ERR_peek_error - obtain error code | ||
6 | |||
7 | =head1 SYNOPSIS | ||
8 | |||
9 | #include <openssl/err.h> | ||
10 | |||
11 | unsigned long ERR_get_error(void); | ||
12 | unsigned long ERR_peek_error(void); | ||
13 | |||
14 | unsigned long ERR_get_error_line(const char **file, int *line); | ||
15 | unsigned long ERR_peek_error_line(const char **file, int *line); | ||
16 | |||
17 | unsigned long ERR_get_error_line_data(const char **file, int *line, | ||
18 | const char **data, int *flags); | ||
19 | unsigned long ERR_peek_error_line_data(const char **file, int *line, | ||
20 | const char **data, int *flags); | ||
21 | |||
22 | =head1 DESCRIPTION | ||
23 | |||
24 | ERR_get_error() returns the last error code from the thread's error | ||
25 | queue and removes the entry. This function can be called repeatedly | ||
26 | until there are no more error codes to return. | ||
27 | |||
28 | ERR_peek_error() returns the last error code from the thread's | ||
29 | error queue without modifying it. | ||
30 | |||
31 | See L<ERR_GET_LIB(3)|ERR_GET_LIB(3)> for obtaining information about | ||
32 | location and reason of the error, and | ||
33 | L<ERR_error_string(3)|ERR_error_string(3)> for human-readable error | ||
34 | messages. | ||
35 | |||
36 | ERR_get_error_line() and ERR_peek_error_line() are the same as the | ||
37 | above, but they additionally store the file name and line number where | ||
38 | the error occurred in *B<file> and *B<line>, unless these are B<NULL>. | ||
39 | |||
40 | ERR_get_error_line_data() and ERR_peek_error_line_data() store | ||
41 | additional data and flags associated with the error code in *B<data> | ||
42 | and *B<flags>, unless these are B<NULL>. *B<data> contains a string | ||
43 | if *B<flags>&B<ERR_TXT_STRING>. If it has been allocated by Malloc(), | ||
44 | *B<flags>&B<ERR_TXT_MALLOCED> is true. | ||
45 | |||
46 | =head1 RETURN VALUES | ||
47 | |||
48 | The error code, or 0 if there is no error in the queue. | ||
49 | |||
50 | =head1 SEE ALSO | ||
51 | |||
52 | L<err(3)|err(3)>, L<ERR_error_string(3)|ERR_error_string(3)>, | ||
53 | L<ERR_GET_LIB(3)|ERR_GET_LIB(3)> | ||
54 | |||
55 | =head1 HISTORY | ||
56 | |||
57 | ERR_get_error(), ERR_peek_error(), ERR_get_error_line() and | ||
58 | ERR_peek_error_line() are available in all versions of SSLeay and | ||
59 | OpenSSL. ERR_get_error_line_data() and ERR_peek_error_line_data() | ||
60 | were added in SSLeay 0.9.0. | ||
61 | |||
62 | =cut | ||
diff --git a/src/lib/libcrypto/doc/ERR_load_crypto_strings.pod b/src/lib/libcrypto/doc/ERR_load_crypto_strings.pod new file mode 100644 index 0000000000..9bdec75a46 --- /dev/null +++ b/src/lib/libcrypto/doc/ERR_load_crypto_strings.pod | |||
@@ -0,0 +1,46 @@ | |||
1 | =pod | ||
2 | |||
3 | =head1 NAME | ||
4 | |||
5 | ERR_load_crypto_strings, SSL_load_error_strings, ERR_free_strings - | ||
6 | load and free error strings | ||
7 | |||
8 | =head1 SYNOPSIS | ||
9 | |||
10 | #include <openssl/err.h> | ||
11 | |||
12 | void ERR_load_crypto_strings(void); | ||
13 | void ERR_free_strings(void); | ||
14 | |||
15 | #include <openssl/ssl.h> | ||
16 | |||
17 | void SSL_load_error_strings(void); | ||
18 | |||
19 | =head1 DESCRIPTION | ||
20 | |||
21 | ERR_load_crypto_strings() registers the error strings for all | ||
22 | B<libcrypto> functions. SSL_load_error_strings() does the same, | ||
23 | but also registers the B<libssl> error strings. | ||
24 | |||
25 | One of these functions should be called before generating | ||
26 | textual error messages. However, this is not required when memory | ||
27 | usage is an issue. | ||
28 | |||
29 | ERR_free_strings() frees all previously loaded error strings. | ||
30 | |||
31 | =head1 RETURN VALUES | ||
32 | |||
33 | ERR_load_crypto_strings(), SSL_load_error_strings() and | ||
34 | ERR_free_strings() return no values. | ||
35 | |||
36 | =head1 SEE ALSO | ||
37 | |||
38 | L<err(3)|err(3)>, L<ERR_error_string(3)|ERR_error_string(3)> | ||
39 | |||
40 | =head1 HISTORY | ||
41 | |||
42 | ERR_load_error_strings(), SSL_load_error_strings() and | ||
43 | ERR_free_strings() are available in all versions of SSLeay and | ||
44 | OpenSSL. | ||
45 | |||
46 | =cut | ||
diff --git a/src/lib/libcrypto/doc/ERR_load_strings.pod b/src/lib/libcrypto/doc/ERR_load_strings.pod new file mode 100644 index 0000000000..5acdd0edbc --- /dev/null +++ b/src/lib/libcrypto/doc/ERR_load_strings.pod | |||
@@ -0,0 +1,54 @@ | |||
1 | =pod | ||
2 | |||
3 | =head1 NAME | ||
4 | |||
5 | ERR_load_strings, ERR_PACK, ERR_get_next_error_library - load | ||
6 | arbitrary error strings | ||
7 | |||
8 | =head1 SYNOPSIS | ||
9 | |||
10 | #include <openssl/err.h> | ||
11 | |||
12 | void ERR_load_strings(int lib, ERR_STRING_DATA str[]); | ||
13 | |||
14 | int ERR_get_next_error_library(void); | ||
15 | |||
16 | unsigned long ERR_PACK(int lib, int func, int reason); | ||
17 | |||
18 | =head1 DESCRIPTION | ||
19 | |||
20 | ERR_load_strings() registers error strings for library number B<lib>. | ||
21 | |||
22 | B<str> is an array of error string data: | ||
23 | |||
24 | typedef struct ERR_string_data_st | ||
25 | { | ||
26 | unsigned long error; | ||
27 | char *string; | ||
28 | } ERR_STRING_DATA; | ||
29 | |||
30 | The error code is generated from the library number and a function and | ||
31 | reason code: B<error> = ERR_PACK(B<lib>, B<func>, B<reason>). | ||
32 | ERR_PACK() is a macro. | ||
33 | |||
34 | The last entry in the array is {0,0}. | ||
35 | |||
36 | ERR_get_next_error_library() can be used to assign library numbers | ||
37 | to user libraries at runtime. | ||
38 | |||
39 | =head1 RETURN VALUE | ||
40 | |||
41 | ERR_load_strings() returns no value. ERR_PACK() return the error code. | ||
42 | ERR_get_next_error_library() returns a new library number. | ||
43 | |||
44 | =head1 SEE ALSO | ||
45 | |||
46 | L<err(3)|err(3)>, L<ERR_load_strings(3)|ERR_load_strings(3)> | ||
47 | |||
48 | =head1 HISTORY | ||
49 | |||
50 | ERR_load_error_strings() and ERR_PACK() are available in all versions | ||
51 | of SSLeay and OpenSSL. ERR_get_next_error_library() was added in | ||
52 | SSLeay 0.9.0. | ||
53 | |||
54 | =cut | ||
diff --git a/src/lib/libcrypto/doc/ERR_print_errors.pod b/src/lib/libcrypto/doc/ERR_print_errors.pod new file mode 100644 index 0000000000..b100a5fa2b --- /dev/null +++ b/src/lib/libcrypto/doc/ERR_print_errors.pod | |||
@@ -0,0 +1,51 @@ | |||
1 | =pod | ||
2 | |||
3 | =head1 NAME | ||
4 | |||
5 | ERR_print_errors, ERR_print_errors_fp - print error messages | ||
6 | |||
7 | =head1 SYNOPSIS | ||
8 | |||
9 | #include <openssl/err.h> | ||
10 | |||
11 | void ERR_print_errors(BIO *bp); | ||
12 | void ERR_print_errors_fp(FILE *fp); | ||
13 | |||
14 | =head1 DESCRIPTION | ||
15 | |||
16 | ERR_print_errors() is a convenience function that prints the error | ||
17 | strings for all errors that OpenSSL has recorded to B<bp>, thus | ||
18 | emptying the error queue. | ||
19 | |||
20 | ERR_print_errors_fp() is the same, except that the output goes to a | ||
21 | B<FILE>. | ||
22 | |||
23 | |||
24 | The error strings will have the following format: | ||
25 | |||
26 | [pid]:error:[error code]:[library name]:[function name]:[reason string]:[file name]:[line]:[optional text message] | ||
27 | |||
28 | I<error code> is an 8 digit hexadecimal number. I<library name>, | ||
29 | I<function name> and I<reason string> are ASCII text, as is I<optional | ||
30 | text message> if one was set for the respective error code. | ||
31 | |||
32 | If there is no text string registered for the given error code, | ||
33 | the error string will contain the numeric code. | ||
34 | |||
35 | =head1 RETURN VALUES | ||
36 | |||
37 | ERR_print_errors() and ERR_print_errors_fp() return no values. | ||
38 | |||
39 | =head1 SEE ALSO | ||
40 | |||
41 | L<err(3)|err(3)>, L<ERR_error_string(3)|ERR_error_string(3)>, | ||
42 | L<ERR_get_error(3)|ERR_get_error(3)>, | ||
43 | L<ERR_load_crypto_strings(3)|ERR_load_crypto_strings(3)>, | ||
44 | L<SSL_load_error_strings(3)|SSL_load_error_strings(3)> | ||
45 | |||
46 | =head1 HISTORY | ||
47 | |||
48 | ERR_print_errors() and ERR_print_errors_fp() | ||
49 | are available in all versions of SSLeay and OpenSSL. | ||
50 | |||
51 | =cut | ||
diff --git a/src/lib/libcrypto/doc/ERR_put_error.pod b/src/lib/libcrypto/doc/ERR_put_error.pod new file mode 100644 index 0000000000..acd241fbe4 --- /dev/null +++ b/src/lib/libcrypto/doc/ERR_put_error.pod | |||
@@ -0,0 +1,44 @@ | |||
1 | =pod | ||
2 | |||
3 | =head1 NAME | ||
4 | |||
5 | ERR_put_error, ERR_add_error_data - record an error | ||
6 | |||
7 | =head1 SYNOPSIS | ||
8 | |||
9 | #include <openssl/err.h> | ||
10 | |||
11 | void ERR_put_error(int lib, int func, int reason, const char *file, | ||
12 | int line); | ||
13 | |||
14 | void ERR_add_error_data(int num, ...); | ||
15 | |||
16 | =head1 DESCRIPTION | ||
17 | |||
18 | ERR_put_error() adds an error code to the thread's error queue. It | ||
19 | signals that the error of reason code B<reason> occurred in function | ||
20 | B<func> of library B<lib>, in line number B<line> of B<file>. | ||
21 | This function is usually called by a macro. | ||
22 | |||
23 | ERR_add_error_data() associates the concatenation of its B<num> string | ||
24 | arguments with the error code added last. | ||
25 | |||
26 | L<ERR_load_strings(3)|ERR_load_strings(3)> can be used to register | ||
27 | error strings so that the application can a generate human-readable | ||
28 | error messages for the error code. | ||
29 | |||
30 | =head1 RETURN VALUES | ||
31 | |||
32 | ERR_put_error() and ERR_add_error_data() return | ||
33 | no values. | ||
34 | |||
35 | =head1 SEE ALSO | ||
36 | |||
37 | L<err(3)|err(3)>, L<ERR_load_strings(3)|ERR_load_strings(3)> | ||
38 | |||
39 | =head1 HISTORY | ||
40 | |||
41 | ERR_put_error() is available in all versions of SSLeay and OpenSSL. | ||
42 | ERR_add_error_data() was added in SSLeay 0.9.0. | ||
43 | |||
44 | =cut | ||
diff --git a/src/lib/libcrypto/doc/ERR_remove_state.pod b/src/lib/libcrypto/doc/ERR_remove_state.pod new file mode 100644 index 0000000000..ebcdc0f5a5 --- /dev/null +++ b/src/lib/libcrypto/doc/ERR_remove_state.pod | |||
@@ -0,0 +1,34 @@ | |||
1 | =pod | ||
2 | |||
3 | =head1 NAME | ||
4 | |||
5 | ERR_remove_state - free a thread's error queue | ||
6 | |||
7 | =head1 SYNOPSIS | ||
8 | |||
9 | #include <openssl/err.h> | ||
10 | |||
11 | void ERR_remove_state(unsigned long pid); | ||
12 | |||
13 | =head1 DESCRIPTION | ||
14 | |||
15 | ERR_remove_state() frees the error queue associated with thread B<pid>. | ||
16 | If B<pid> == 0, the current thread will have its error queue removed. | ||
17 | |||
18 | Since error queue data structures are allocated automatically for new | ||
19 | threads, they must be freed when threads are terminated in oder to | ||
20 | avoid memory leaks. | ||
21 | |||
22 | =head1 RETURN VALUE | ||
23 | |||
24 | ERR_remove_state() returns no value. | ||
25 | |||
26 | =head1 SEE ALSO | ||
27 | |||
28 | L<err(3)|err(3)> | ||
29 | |||
30 | =head1 HISTORY | ||
31 | |||
32 | ERR_remove_state() is available in all versions of SSLeay and OpenSSL. | ||
33 | |||
34 | =cut | ||
diff --git a/src/lib/libcrypto/doc/EVP_BytesToKey.pod b/src/lib/libcrypto/doc/EVP_BytesToKey.pod new file mode 100644 index 0000000000..5ce4add082 --- /dev/null +++ b/src/lib/libcrypto/doc/EVP_BytesToKey.pod | |||
@@ -0,0 +1,67 @@ | |||
1 | =pod | ||
2 | |||
3 | =head1 NAME | ||
4 | |||
5 | EVP_BytesToKey - password based encryption routine | ||
6 | |||
7 | =head1 SYNOPSIS | ||
8 | |||
9 | #include <openssl/evp.h> | ||
10 | |||
11 | int EVP_BytesToKey(const EVP_CIPHER *type,const EVP_MD *md, | ||
12 | const unsigned char *salt, | ||
13 | const unsigned char *data, int datal, int count, | ||
14 | unsigned char *key,unsigned char *iv); | ||
15 | |||
16 | =head1 DESCRIPTION | ||
17 | |||
18 | EVP_BytesToKey() derives a key and IV from various parameters. B<type> is | ||
19 | the cipher to derive the key and IV for. B<md> is the message digest to use. | ||
20 | The B<salt> paramter is used as a salt in the derivation: it should point to | ||
21 | an 8 byte buffer or NULL if no salt is used. B<data> is a buffer containing | ||
22 | B<datal> bytes which is used to derive the keying data. B<count> is the | ||
23 | iteration count to use. The derived key and IV will be written to B<key> | ||
24 | and B<iv> respectively. | ||
25 | |||
26 | =head1 NOTES | ||
27 | |||
28 | A typical application of this function is to derive keying material for an | ||
29 | encryption algorithm from a password in the B<data> parameter. | ||
30 | |||
31 | Increasing the B<count> parameter slows down the algorithm which makes it | ||
32 | harder for an attacker to peform a brute force attack using a large number | ||
33 | of candidate passwords. | ||
34 | |||
35 | If the total key and IV length is less than the digest length and | ||
36 | B<MD5> is used then the derivation algorithm is compatible with PKCS#5 v1.5 | ||
37 | otherwise a non standard extension is used to derive the extra data. | ||
38 | |||
39 | Newer applications should use more standard algorithms such as PKCS#5 | ||
40 | v2.0 for key derivation. | ||
41 | |||
42 | =head1 KEY DERIVATION ALGORITHM | ||
43 | |||
44 | The key and IV is derived by concatenating D_1, D_2, etc until | ||
45 | enough data is available for the key and IV. D_i is defined as: | ||
46 | |||
47 | D_i = HASH^count(D_(i-1) || data || salt) | ||
48 | |||
49 | where || denotes concatentaion, D_0 is empty, HASH is the digest | ||
50 | algorithm in use, HASH^1(data) is simply HASH(data), HASH^2(data) | ||
51 | is HASH(HASH(data)) and so on. | ||
52 | |||
53 | The initial bytes are used for the key and the subsequent bytes for | ||
54 | the IV. | ||
55 | |||
56 | =head1 RETURN VALUES | ||
57 | |||
58 | EVP_BytesToKey() returns the size of the derived key in bytes. | ||
59 | |||
60 | =head1 SEE ALSO | ||
61 | |||
62 | L<evp(3)|evp(3)>, L<rand(3)|rand(3)>, | ||
63 | L<EVP_EncryptInit(3)|EVP_EncryptInit(3)>, | ||
64 | |||
65 | =head1 HISTORY | ||
66 | |||
67 | =cut | ||
diff --git a/src/lib/libcrypto/doc/EVP_DigestInit.pod b/src/lib/libcrypto/doc/EVP_DigestInit.pod new file mode 100644 index 0000000000..345b1ddfa7 --- /dev/null +++ b/src/lib/libcrypto/doc/EVP_DigestInit.pod | |||
@@ -0,0 +1,197 @@ | |||
1 | =pod | ||
2 | |||
3 | =head1 NAME | ||
4 | |||
5 | EVP_DigestInit, EVP_DigestUpdate, EVP_DigestFinal - EVP digest routines | ||
6 | |||
7 | =head1 SYNOPSIS | ||
8 | |||
9 | #include <openssl/evp.h> | ||
10 | |||
11 | void EVP_DigestInit(EVP_MD_CTX *ctx, const EVP_MD *type); | ||
12 | void EVP_DigestUpdate(EVP_MD_CTX *ctx, const void *d, unsigned int cnt); | ||
13 | void EVP_DigestFinal(EVP_MD_CTX *ctx, unsigned char *md, | ||
14 | unsigned int *s); | ||
15 | |||
16 | #define EVP_MAX_MD_SIZE (16+20) /* The SSLv3 md5+sha1 type */ | ||
17 | |||
18 | int EVP_MD_CTX_copy(EVP_MD_CTX *out,EVP_MD_CTX *in); | ||
19 | |||
20 | #define EVP_MD_type(e) ((e)->type) | ||
21 | #define EVP_MD_pkey_type(e) ((e)->pkey_type) | ||
22 | #define EVP_MD_size(e) ((e)->md_size) | ||
23 | #define EVP_MD_block_size(e) ((e)->block_size) | ||
24 | |||
25 | #define EVP_MD_CTX_md(e) (e)->digest) | ||
26 | #define EVP_MD_CTX_size(e) EVP_MD_size((e)->digest) | ||
27 | #define EVP_MD_CTX_block_size(e) EVP_MD_block_size((e)->digest) | ||
28 | #define EVP_MD_CTX_type(e) EVP_MD_type((e)->digest) | ||
29 | |||
30 | EVP_MD *EVP_md_null(void); | ||
31 | EVP_MD *EVP_md2(void); | ||
32 | EVP_MD *EVP_md5(void); | ||
33 | EVP_MD *EVP_sha(void); | ||
34 | EVP_MD *EVP_sha1(void); | ||
35 | EVP_MD *EVP_dss(void); | ||
36 | EVP_MD *EVP_dss1(void); | ||
37 | EVP_MD *EVP_mdc2(void); | ||
38 | EVP_MD *EVP_ripemd160(void); | ||
39 | |||
40 | const EVP_MD *EVP_get_digestbyname(const char *name); | ||
41 | #define EVP_get_digestbynid(a) EVP_get_digestbyname(OBJ_nid2sn(a)) | ||
42 | #define EVP_get_digestbyobj(a) EVP_get_digestbynid(OBJ_obj2nid(a)) | ||
43 | |||
44 | =head1 DESCRIPTION | ||
45 | |||
46 | The EVP digest routines are a high level interface to message digests. | ||
47 | |||
48 | EVP_DigestInit() initialises a digest context B<ctx> to use a digest | ||
49 | B<type>: this will typically be supplied by a function such as | ||
50 | EVP_sha1(). | ||
51 | |||
52 | EVP_DigestUpdate() hashes B<cnt> bytes of data at B<d> into the | ||
53 | digest context B<ctx>. This funtion can be called several times on the | ||
54 | same B<ctx> to hash additional data. | ||
55 | |||
56 | EVP_DigestFinal() retrieves the digest value from B<ctx> and places | ||
57 | it in B<md>. If the B<s> parameter is not NULL then the number of | ||
58 | bytes of data written (i.e. the length of the digest) will be written | ||
59 | to the integer at B<s>, at most B<EVP_MAX_MD_SIZE> bytes will be written. | ||
60 | After calling EVP_DigestFinal() no additional calls to EVP_DigestUpdate() | ||
61 | can be made, but EVP_DigestInit() can be called to initialiase a new | ||
62 | digest operation. | ||
63 | |||
64 | EVP_MD_CTX_copy() can be used to copy the message digest state from | ||
65 | B<in> to B<out>. This is useful if large amounts of data are to be | ||
66 | hashed which only differ in the last few bytes. | ||
67 | |||
68 | EVP_MD_size() and EVP_MD_CTX_size() return the size of the message digest | ||
69 | when passed an B<EVP_MD> or an B<EVP_MD_CTX> structure, i.e. the size of the | ||
70 | hash. | ||
71 | |||
72 | EVP_MD_block_size() and EVP_MD_CTX_block_size() return the block size of the | ||
73 | message digest when passed an B<EVP_MD> or an B<EVP_MD_CTX> structure. | ||
74 | |||
75 | EVP_MD_type() and EVP_MD_CTX_type() return the NID of the OBJECT IDENTIFIER | ||
76 | representing the given message digest when passed an B<EVP_MD> structure. | ||
77 | For example EVP_MD_type(EVP_sha1()) returns B<NID_sha1>. This function is | ||
78 | normally used when setting ASN1 OIDs. | ||
79 | |||
80 | EVP_MD_CTX_md() returns the B<EVP_MD> structure corresponding to the passed | ||
81 | B<EVP_MD_CTX>. | ||
82 | |||
83 | EVP_MD_pkey_type() returns the NID of the public key signing algorithm associated | ||
84 | with this digest. For example EVP_sha1() is associated with RSA so this will | ||
85 | return B<NID_sha1WithRSAEncryption>. This "link" between digests and signature | ||
86 | algorithms may not be retained in future versions of OpenSSL. | ||
87 | |||
88 | EVP_md2(), EVP_md5(), EVP_sha(), EVP_sha1(), EVP_mdc2() and EVP_ripemd160() | ||
89 | return B<EVP_MD> structures for the MD2, MD5, SHA, SHA1, MDC2 and RIPEMD160 digest | ||
90 | algorithms respectively. The associated signature algorithm is RSA in each case. | ||
91 | |||
92 | EVP_dss() and EVP_dss1() return B<EVP_MD> structures for SHA and SHA1 digest | ||
93 | algorithms but using DSS (DSA) for the signature algorithm. | ||
94 | |||
95 | EVP_md_null() is a "null" message digest that does nothing: i.e. the hash it | ||
96 | returns is of zero length. | ||
97 | |||
98 | EVP_get_digestbyname(), EVP_get_digestbynid() and EVP_get_digestbyobj() | ||
99 | return an B<EVP_MD> structure when passed a digest name, a digest NID or | ||
100 | an ASN1_OBJECT structure respectively. The digest table must be initialised | ||
101 | using, for example, OpenSSL_add_all_digests() for these functions to work. | ||
102 | |||
103 | =head1 RETURN VALUES | ||
104 | |||
105 | EVP_DigestInit(), EVP_DigestUpdate() and EVP_DigestFinal() do not return values. | ||
106 | |||
107 | EVP_MD_CTX_copy() returns 1 if successful or 0 for failure. | ||
108 | |||
109 | EVP_MD_type(), EVP_MD_pkey_type() and EVP_MD_type() return the NID of the | ||
110 | corresponding OBJECT IDENTIFIER or NID_undef if none exists. | ||
111 | |||
112 | EVP_MD_size(), EVP_MD_block_size(), EVP_MD_CTX_size(e), EVP_MD_size(), | ||
113 | EVP_MD_CTX_block_size() and EVP_MD_block_size() return the digest or block | ||
114 | size in bytes. | ||
115 | |||
116 | EVP_md_null(), EVP_md2(), EVP_md5(), EVP_sha(), EVP_sha1(), EVP_dss(), | ||
117 | EVP_dss1(), EVP_mdc2() and EVP_ripemd160() return pointers to the | ||
118 | corresponding EVP_MD structures. | ||
119 | |||
120 | EVP_get_digestbyname(), EVP_get_digestbynid() and EVP_get_digestbyobj() | ||
121 | return either an B<EVP_MD> structure or NULL if an error occurs. | ||
122 | |||
123 | =head1 NOTES | ||
124 | |||
125 | The B<EVP> interface to message digests should almost always be used in | ||
126 | preference to the low level interfaces. This is because the code then becomes | ||
127 | transparent to the digest used and much more flexible. | ||
128 | |||
129 | SHA1 is the digest of choice for new applications. The other digest algorithms | ||
130 | are still in common use. | ||
131 | |||
132 | =head1 EXAMPLE | ||
133 | |||
134 | This example digests the data "Test Message\n" and "Hello World\n", using the | ||
135 | digest name passed on the command line. | ||
136 | |||
137 | #include <stdio.h> | ||
138 | #include <openssl/evp.h> | ||
139 | |||
140 | main(int argc, char *argv[]) | ||
141 | { | ||
142 | EVP_MD_CTX mdctx; | ||
143 | const EVP_MD *md; | ||
144 | char mess1[] = "Test Message\n"; | ||
145 | char mess2[] = "Hello World\n"; | ||
146 | unsigned char md_value[EVP_MAX_MD_SIZE]; | ||
147 | int md_len, i; | ||
148 | |||
149 | OpenSSL_add_all_digests(); | ||
150 | |||
151 | if(!argv[1]) { | ||
152 | printf("Usage: mdtest digestname\n"); | ||
153 | exit(1); | ||
154 | } | ||
155 | |||
156 | md = EVP_get_digestbyname(argv[1]); | ||
157 | |||
158 | if(!md) { | ||
159 | printf("Unknown message digest %s\n", argv[1]); | ||
160 | exit(1); | ||
161 | } | ||
162 | |||
163 | EVP_DigestInit(&mdctx, md); | ||
164 | EVP_DigestUpdate(&mdctx, mess1, strlen(mess1)); | ||
165 | EVP_DigestUpdate(&mdctx, mess2, strlen(mess2)); | ||
166 | EVP_DigestFinal(&mdctx, md_value, &md_len); | ||
167 | |||
168 | printf("Digest is: "); | ||
169 | for(i = 0; i < md_len; i++) printf("%02x", md_value[i]); | ||
170 | printf("\n"); | ||
171 | } | ||
172 | |||
173 | =head1 BUGS | ||
174 | |||
175 | Several of the functions do not return values: maybe they should. Although the | ||
176 | internal digest operations will never fail some future hardware based operations | ||
177 | might. | ||
178 | |||
179 | The link between digests and signing algorithms results in a situation where | ||
180 | EVP_sha1() must be used with RSA and EVP_dss1() must be used with DSS | ||
181 | even though they are identical digests. | ||
182 | |||
183 | The size of an B<EVP_MD_CTX> structure is determined at compile time: this results | ||
184 | in code that must be recompiled if the size of B<EVP_MD_CTX> increases. | ||
185 | |||
186 | =head1 SEE ALSO | ||
187 | |||
188 | L<evp(3)|evp(3)>, L<hmac(3)|hmac(3)>, L<md2(3)|md2(3)>, | ||
189 | L<md5(3)|md5(3)>, L<mdc2(3)|mdc2(3)>, L<ripemd(3)|ripemd(3)>, | ||
190 | L<sha(3)|sha(3)>, L<digest(1)|digest(1)> | ||
191 | |||
192 | =head1 HISTORY | ||
193 | |||
194 | EVP_DigestInit(), EVP_DigestUpdate() and EVP_DigestFinal() are | ||
195 | available in all versions of SSLeay and OpenSSL. | ||
196 | |||
197 | =cut | ||
diff --git a/src/lib/libcrypto/doc/EVP_EncryptInit.pod b/src/lib/libcrypto/doc/EVP_EncryptInit.pod new file mode 100644 index 0000000000..77ed4ccdba --- /dev/null +++ b/src/lib/libcrypto/doc/EVP_EncryptInit.pod | |||
@@ -0,0 +1,224 @@ | |||
1 | =pod | ||
2 | |||
3 | =head1 NAME | ||
4 | |||
5 | EVP_EncryptInit, EVP_EncryptUpdate, EVP_EncryptFinal - EVP cipher routines | ||
6 | |||
7 | =head1 SYNOPSIS | ||
8 | |||
9 | #include <openssl/evp.h> | ||
10 | |||
11 | void EVP_EncryptInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *type, | ||
12 | unsigned char *key, unsigned char *iv); | ||
13 | void EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, | ||
14 | int *outl, unsigned char *in, int inl); | ||
15 | void EVP_EncryptFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, | ||
16 | int *outl); | ||
17 | |||
18 | void EVP_DecryptInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *type, | ||
19 | unsigned char *key, unsigned char *iv); | ||
20 | void EVP_DecryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, | ||
21 | int *outl, unsigned char *in, int inl); | ||
22 | int EVP_DecryptFinal(EVP_CIPHER_CTX *ctx, unsigned char *outm, | ||
23 | int *outl); | ||
24 | |||
25 | void EVP_CipherInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *type, | ||
26 | unsigned char *key, unsigned char *iv, int enc); | ||
27 | void EVP_CipherUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, | ||
28 | int *outl, unsigned char *in, int inl); | ||
29 | int EVP_CipherFinal(EVP_CIPHER_CTX *ctx, unsigned char *outm, | ||
30 | int *outl); | ||
31 | |||
32 | void EVP_CIPHER_CTX_cleanup(EVP_CIPHER_CTX *a); | ||
33 | |||
34 | const EVP_CIPHER *EVP_get_cipherbyname(const char *name); | ||
35 | #define EVP_get_cipherbynid(a) EVP_get_cipherbyname(OBJ_nid2sn(a)) | ||
36 | #define EVP_get_cipherbyobj(a) EVP_get_cipherbynid(OBJ_obj2nid(a)) | ||
37 | |||
38 | #define EVP_CIPHER_nid(e) ((e)->nid) | ||
39 | #define EVP_CIPHER_block_size(e) ((e)->block_size) | ||
40 | #define EVP_CIPHER_key_length(e) ((e)->key_len) | ||
41 | #define EVP_CIPHER_iv_length(e) ((e)->iv_len) | ||
42 | |||
43 | int EVP_CIPHER_type(const EVP_CIPHER *ctx); | ||
44 | #define EVP_CIPHER_CTX_cipher(e) ((e)->cipher) | ||
45 | #define EVP_CIPHER_CTX_nid(e) ((e)->cipher->nid) | ||
46 | #define EVP_CIPHER_CTX_block_size(e) ((e)->cipher->block_size) | ||
47 | #define EVP_CIPHER_CTX_key_length(e) ((e)->cipher->key_len) | ||
48 | #define EVP_CIPHER_CTX_iv_length(e) ((e)->cipher->iv_len) | ||
49 | #define EVP_CIPHER_CTX_type(c) EVP_CIPHER_type(EVP_CIPHER_CTX_cipher(c)) | ||
50 | |||
51 | int EVP_CIPHER_param_to_asn1(EVP_CIPHER_CTX *c, ASN1_TYPE *type); | ||
52 | int EVP_CIPHER_asn1_to_param(EVP_CIPHER_CTX *c, ASN1_TYPE *type); | ||
53 | |||
54 | =head1 DESCRIPTION | ||
55 | |||
56 | The EVP cipher routines are a high level interface to certain | ||
57 | symmetric ciphers. | ||
58 | |||
59 | EVP_EncryptInit() initialises a cipher context B<ctx> for encryption | ||
60 | with cipher B<type>. B<type> is normally supplied by a function such | ||
61 | as EVP_des_cbc() . B<key> is the symmetric key to use and B<iv> is the | ||
62 | IV to use (if necessary), the actual number of bytes used for the | ||
63 | key and IV depends on the cipher. It is possible to set all parameters | ||
64 | to NULL except B<type> in an initial call and supply the remaining | ||
65 | parameters in subsequent calls. This is normally done when the | ||
66 | EVP_CIPHER_asn1_to_param() function is called to set the cipher | ||
67 | parameters from an ASN1 AlgorithmIdentifier and the key from a | ||
68 | different source. | ||
69 | |||
70 | EVP_EncryptUpdate() encrypts B<inl> bytes from the buffer B<in> and | ||
71 | writes the encrypted version to B<out>. This function can be called | ||
72 | multiple times to encrypt successive blocks of data. The amount | ||
73 | of data written depends on the block alignment of the encrypted data: | ||
74 | as a result the amount of data written may be anything from zero bytes | ||
75 | to (inl + cipher_block_size - 1) so B<outl> should contain sufficient | ||
76 | room. The actual number of bytes written is placed in B<outl>. | ||
77 | |||
78 | EVP_EncryptFinal() encrypts the "final" data, that is any data that | ||
79 | remains in a partial block. It uses L<standard block padding|/NOTES> (aka PKCS | ||
80 | padding). The encrypted final data is written to B<out> which should | ||
81 | have sufficient space for one cipher block. The number of bytes written | ||
82 | is placed in B<outl>. After this function is called the encryption operation | ||
83 | is finished and no further calls to EVP_EncryptUpdate() should be made. | ||
84 | |||
85 | EVP_DecryptInit(), EVP_DecryptUpdate() and EVP_DecryptFinal() are the | ||
86 | corresponding decryption operations. EVP_DecryptFinal() will return an | ||
87 | error code if the final block is not correctly formatted. The parameters | ||
88 | and restrictions are identical to the encryption operations except that | ||
89 | the decrypted data buffer B<out> passed to EVP_DecryptUpdate() should | ||
90 | have sufficient room for (B<inl> + cipher_block_size) bytes unless the | ||
91 | cipher block size is 1 in which case B<inl> bytes is sufficient. | ||
92 | |||
93 | EVP_CipherInit(), EVP_CipherUpdate() and EVP_CipherFinal() are functions | ||
94 | that can be used for decryption or encryption. The operation performed | ||
95 | depends on the value of the B<enc> parameter. It should be set to 1 for | ||
96 | encryption and 0 for decryption. | ||
97 | |||
98 | EVP_CIPHER_CTX_cleanup() clears all information from a cipher context. | ||
99 | It should be called after all operations using a cipher are complete | ||
100 | so sensitive information does not remain in memory. | ||
101 | |||
102 | EVP_get_cipherbyname(), EVP_get_cipherbynid() and EVP_get_cipherbyobj() | ||
103 | return an EVP_CIPHER structure when passed a cipher name, a NID or an | ||
104 | ASN1_OBJECT structure. | ||
105 | |||
106 | EVP_CIPHER_nid() and EVP_CIPHER_CTX_nid() return the NID of a cipher when | ||
107 | passed an B<EVP_CIPHER> or B<EVP_CIPHER_CTX> structure. The actual NID | ||
108 | value is an internal value which may not have a corresponding OBJECT | ||
109 | IDENTIFIER. | ||
110 | |||
111 | EVP_CIPHER_key_length() and EVP_CIPHER_CTX_key_length() return the key | ||
112 | length of a cipher when passed an B<EVP_CIPHER> or B<EVP_CIPHER_CTX> | ||
113 | structure. The constant B<EVP_MAX_KEY_LENGTH> is the maximum key length | ||
114 | for all ciphers. | ||
115 | |||
116 | EVP_CIPHER_iv_length() and EVP_CIPHER_CTX_iv_length() return the IV | ||
117 | length of a cipher when passed an B<EVP_CIPHER> or B<EVP_CIPHER_CTX>. | ||
118 | It will return zero if the cipher does not use an IV. The constant | ||
119 | B<EVP_MAX_IV_LENGTH> is the maximum IV length for all ciphers. | ||
120 | |||
121 | EVP_CIPHER_block_size() and EVP_CIPHER_CTX_block_size() return the block | ||
122 | size of a cipher when passed an B<EVP_CIPHER> or B<EVP_CIPHER_CTX> | ||
123 | structure. The constant B<EVP_MAX_IV_LENGTH> is also the maximum block | ||
124 | length for all ciphers. | ||
125 | |||
126 | EVP_CIPHER_type() and EVP_CIPHER_CTX_type() return the type of the passed | ||
127 | cipher or context. This "type" is the actual NID of the cipher OBJECT | ||
128 | IDENTIFIER as such it ignores the cipher parameters and 40 bit RC2 and | ||
129 | 128 bit RC2 have the same NID. If the cipher does not have an object | ||
130 | identifier or does not have ASN1 support this function will return | ||
131 | B<NID_undef>. | ||
132 | |||
133 | EVP_CIPHER_CTX_cipher() returns the B<EVP_CIPHER> structure when passed | ||
134 | an B<EVP_CIPHER_CTX> structure. | ||
135 | |||
136 | EVP_CIPHER_param_to_asn1() sets the AlgorithmIdentifier "parameter" based | ||
137 | on the passed cipher. This will typically include any parameters and an | ||
138 | IV. The cipher IV (if any) must be set when this call is made. This call | ||
139 | should be made before the cipher is actually "used" (before any | ||
140 | EVP_EncryptUpdate(), EVP_DecryptUpdate() calls for example). This function | ||
141 | may fail if the cipher does not have any ASN1 support. | ||
142 | |||
143 | EVP_CIPHER_asn1_to_param() sets the cipher parameters based on an ASN1 | ||
144 | AlgorithmIdentifier "parameter". The precise effect depends on the cipher | ||
145 | In the case of RC2, for example, it will set the IV and effective key length. | ||
146 | This function should be called after the base cipher type is set but before | ||
147 | the key is set. For example EVP_CipherInit() will be called with the IV and | ||
148 | key set to NULL, EVP_CIPHER_asn1_to_param() will be called and finally | ||
149 | EVP_CipherInit() again with all parameters except the key set to NULL. It is | ||
150 | possible for this function to fail if the cipher does not have any ASN1 support | ||
151 | or the parameters cannot be set (for example the RC2 effective key length | ||
152 | does not have an B<EVP_CIPHER> structure). | ||
153 | |||
154 | =head1 RETURN VALUES | ||
155 | |||
156 | EVP_EncryptInit(), EVP_EncryptUpdate() and EVP_EncryptFinal() do not return | ||
157 | values. | ||
158 | |||
159 | EVP_DecryptInit() and EVP_DecryptUpdate() do not return values. | ||
160 | EVP_DecryptFinal() returns 0 if the decrypt failed or 1 for success. | ||
161 | |||
162 | EVP_CipherInit() and EVP_CipherUpdate() do not return values. | ||
163 | EVP_CipherFinal() returns 1 for a decryption failure or 1 for success, if | ||
164 | the operation is encryption then it always returns 1. | ||
165 | |||
166 | EVP_CIPHER_CTX_cleanup() does not return a value. | ||
167 | |||
168 | EVP_get_cipherbyname(), EVP_get_cipherbynid() and EVP_get_cipherbyobj() | ||
169 | return an B<EVP_CIPHER> structure or NULL on error. | ||
170 | |||
171 | EVP_CIPHER_nid() and EVP_CIPHER_CTX_nid() return a NID. | ||
172 | |||
173 | EVP_CIPHER_block_size() and EVP_CIPHER_CTX_block_size() return the block | ||
174 | size. | ||
175 | |||
176 | EVP_CIPHER_key_length() and EVP_CIPHER_CTX_key_length() return the key | ||
177 | length. | ||
178 | |||
179 | EVP_CIPHER_iv_length() and EVP_CIPHER_CTX_iv_length() return the IV | ||
180 | length or zero if the cipher does not use an IV. | ||
181 | |||
182 | EVP_CIPHER_type() and EVP_CIPHER_CTX_type() return the NID of the cipher's | ||
183 | OBJECT IDENTIFIER or NID_undef if it has no defined OBJECT IDENTIFIER. | ||
184 | |||
185 | EVP_CIPHER_CTX_cipher() returns an B<EVP_CIPHER> structure. | ||
186 | |||
187 | EVP_CIPHER_param_to_asn1() and EVP_CIPHER_asn1_to_param() return 1 for | ||
188 | success or zero for failure. | ||
189 | |||
190 | =head1 NOTES | ||
191 | |||
192 | Where possible the B<EVP> interface to symmetric ciphers should be used in | ||
193 | preference to the low level interfaces. This is because the code then becomes | ||
194 | transparent to the cipher used and much more flexible. | ||
195 | |||
196 | PKCS padding works by adding B<n> padding bytes of value B<n> to make the total | ||
197 | length of the encrypted data a multiple of the block size. Padding is always | ||
198 | added so if the data is already a multiple of the block size B<n> will equal | ||
199 | the block size. For example if the block size is 8 and 11 bytes are to be | ||
200 | encrypted then 5 padding bytes of value 5 will be added. | ||
201 | |||
202 | When decrypting the final block is checked to see if it has the correct form. | ||
203 | |||
204 | Although the decryption operation can produce an error, it is not a strong | ||
205 | test that the input data or key is correct. A random block has better than | ||
206 | 1 in 256 chance of being of the correct format and problems with the | ||
207 | input data earlier on will not produce a final decrypt error. | ||
208 | |||
209 | =head1 BUGS | ||
210 | |||
211 | The current B<EVP> cipher interface is not as flexible as it should be. Only | ||
212 | certain "spot" encryption algorithms can be used for ciphers which have various | ||
213 | parameters associated with them (RC2, RC5 for example) this is inadequate. | ||
214 | |||
215 | Several of the functions do not return error codes because the software versions | ||
216 | can never fail. This is not true of hardware versions. | ||
217 | |||
218 | =head1 SEE ALSO | ||
219 | |||
220 | L<evp(3)|evp(3)> | ||
221 | |||
222 | =head1 HISTORY | ||
223 | |||
224 | =cut | ||
diff --git a/src/lib/libcrypto/doc/EVP_OpenInit.pod b/src/lib/libcrypto/doc/EVP_OpenInit.pod new file mode 100644 index 0000000000..9707a4b399 --- /dev/null +++ b/src/lib/libcrypto/doc/EVP_OpenInit.pod | |||
@@ -0,0 +1,51 @@ | |||
1 | =pod | ||
2 | |||
3 | =head1 NAME | ||
4 | |||
5 | EVP_OpenInit, EVP_OpenUpdate, EVP_OpenFinal - EVP envelope decryption | ||
6 | |||
7 | =head1 SYNOPSIS | ||
8 | |||
9 | #include <openssl/evp.h> | ||
10 | |||
11 | int EVP_OpenInit(EVP_CIPHER_CTX *ctx,EVP_CIPHER *type,unsigned char *ek, | ||
12 | int ekl,unsigned char *iv,EVP_PKEY *priv); | ||
13 | void EVP_OpenUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, | ||
14 | int *outl, unsigned char *in, int inl); | ||
15 | void EVP_OpenFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, | ||
16 | int *outl); | ||
17 | |||
18 | =head1 DESCRIPTION | ||
19 | |||
20 | The EVP envelope routines are a high level interface to envelope | ||
21 | decryption. They decrypt a public key encrypted symmetric key and | ||
22 | then decrypt data using it. | ||
23 | |||
24 | EVP_OpenInit() initialises a cipher context B<ctx> for decryption | ||
25 | with cipher B<type>. It decrypts the encrypted symmetric key of length | ||
26 | B<ekl> bytes passed in the B<ek> parameter using the private key B<priv>. | ||
27 | The IV is supplied in the B<iv> parameter. | ||
28 | |||
29 | EVP_OpenUpdate() and EVP_OpenFinal() have exactly the same properties | ||
30 | as the EVP_DecryptUpdate() and EVP_DecryptFinal() routines, as | ||
31 | documented on the L<EVP_EncryptInit(3)|EVP_EncryptInit(3)> manual | ||
32 | page. | ||
33 | |||
34 | =head1 RETURN VALUES | ||
35 | |||
36 | EVP_OpenInit() returns -1 on error or an non zero integer (actually the | ||
37 | recovered secret key size) if successful. | ||
38 | |||
39 | EVP_SealUpdate() does not return a value. | ||
40 | |||
41 | EVP_SealFinal() returns 0 if the decrypt failed or 1 for success. | ||
42 | |||
43 | =head1 SEE ALSO | ||
44 | |||
45 | L<evp(3)|evp(3)>,L<rand(3)|rand(3)> | ||
46 | L<EVP_EncryptInit(3)|EVP_EncryptInit(3)>, | ||
47 | L<EVP_SealInit(3)|EVP_SealInit(3)> | ||
48 | |||
49 | =head1 HISTORY | ||
50 | |||
51 | =cut | ||
diff --git a/src/lib/libcrypto/doc/EVP_SealInit.pod b/src/lib/libcrypto/doc/EVP_SealInit.pod new file mode 100644 index 0000000000..1579d110fa --- /dev/null +++ b/src/lib/libcrypto/doc/EVP_SealInit.pod | |||
@@ -0,0 +1,70 @@ | |||
1 | =pod | ||
2 | |||
3 | =head1 NAME | ||
4 | |||
5 | EVP_SealInit, EVP_SealUpdate, EVP_SealFinal - EVP envelope encryption | ||
6 | |||
7 | =head1 SYNOPSIS | ||
8 | |||
9 | #include <openssl/evp.h> | ||
10 | |||
11 | int EVP_SealInit(EVP_CIPHER_CTX *ctx, EVP_CIPHER *type, unsigned char **ek, | ||
12 | int *ekl, unsigned char *iv,EVP_PKEY **pubk, int npubk); | ||
13 | void EVP_SealUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, | ||
14 | int *outl, unsigned char *in, int inl); | ||
15 | void EVP_SealFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, | ||
16 | int *outl); | ||
17 | |||
18 | =head1 DESCRIPTION | ||
19 | |||
20 | The EVP envelope routines are a high level interface to envelope | ||
21 | encryption. They generate a random key and then "envelope" it by | ||
22 | using public key encryption. Data can then be encrypted using this | ||
23 | key. | ||
24 | |||
25 | EVP_SealInit() initialises a cipher context B<ctx> for encryption | ||
26 | with cipher B<type> using a random secret key and IV supplied in | ||
27 | the B<iv> parameter. B<type> is normally supplied by a function such | ||
28 | as EVP_des_cbc(). The secret key is encrypted using one or more public | ||
29 | keys, this allows the same encrypted data to be decrypted using any | ||
30 | of the corresponding private keys. B<ek> is an array of buffers where | ||
31 | the public key encrypted secret key will be written, each buffer must | ||
32 | contain enough room for the corresponding encrypted key: that is | ||
33 | B<ek[i]> must have room for B<EVP_PKEY_size(pubk[i])> bytes. The actual | ||
34 | size of each encrypted secret key is written to the array B<ekl>. B<pubk> is | ||
35 | an array of B<npubk> public keys. | ||
36 | |||
37 | EVP_SealUpdate() and EVP_SealFinal() have exactly the same properties | ||
38 | as the EVP_EncryptUpdate() and EVP_EncryptFinal() routines, as | ||
39 | documented on the L<EVP_EncryptInit(3)|EVP_EncryptInit(3)> manual | ||
40 | page. | ||
41 | |||
42 | =head1 RETURN VALUES | ||
43 | |||
44 | EVP_SealInit() returns -1 on error or B<npubk> if successful. | ||
45 | |||
46 | EVP_SealUpdate() and EVP_SealFinal() do not return values. | ||
47 | |||
48 | =head1 NOTES | ||
49 | |||
50 | Because a random secret key is generated the random number generator | ||
51 | must be seeded before calling EVP_SealInit(). | ||
52 | |||
53 | The public key must be RSA because it is the only OpenSSL public key | ||
54 | algorithm that supports key transport. | ||
55 | |||
56 | Envelope encryption is the usual method of using public key encryption | ||
57 | on large amounts of data, this is because public key encryption is slow | ||
58 | but symmetric encryption is fast. So symmetric encryption is used for | ||
59 | bulk encryption and the small random symmetric key used is transferred | ||
60 | using public key encryption. | ||
61 | |||
62 | =head1 SEE ALSO | ||
63 | |||
64 | L<evp(3)|evp(3)>,L<rand(3)|rand(3)> | ||
65 | L<EVP_EncryptInit(3)|EVP_EncryptInit(3)>, | ||
66 | L<EVP_OpenInit(3)|EVP_OpenInit(3)> | ||
67 | |||
68 | =head1 HISTORY | ||
69 | |||
70 | =cut | ||
diff --git a/src/lib/libcrypto/doc/EVP_SignInit.pod b/src/lib/libcrypto/doc/EVP_SignInit.pod new file mode 100644 index 0000000000..bbc9203c9c --- /dev/null +++ b/src/lib/libcrypto/doc/EVP_SignInit.pod | |||
@@ -0,0 +1,85 @@ | |||
1 | =pod | ||
2 | |||
3 | =head1 NAME | ||
4 | |||
5 | EVP_SignInit, EVP_SignUpdate, EVP_SignFinal - EVP signing functions | ||
6 | |||
7 | =head1 SYNOPSIS | ||
8 | |||
9 | #include <openssl/evp.h> | ||
10 | |||
11 | void EVP_SignInit(EVP_MD_CTX *ctx, const EVP_MD *type); | ||
12 | void EVP_SignUpdate(EVP_MD_CTX *ctx, const void *d, unsigned int cnt); | ||
13 | int EVP_SignFinal(EVP_MD_CTX *ctx,unsigned char *sig,unsigned int *s, EVP_PKEY *pkey); | ||
14 | |||
15 | int EVP_PKEY_size(EVP_PKEY *pkey); | ||
16 | |||
17 | =head1 DESCRIPTION | ||
18 | |||
19 | The EVP signature routines are a high level interface to digital | ||
20 | signatures. | ||
21 | |||
22 | EVP_SignInit() initialises a signing context B<ctx> to using digest | ||
23 | B<type>: this will typically be supplied by a function such as | ||
24 | EVP_sha1(). | ||
25 | |||
26 | EVP_SignUpdate() hashes B<cnt> bytes of data at B<d> into the | ||
27 | signature context B<ctx>. This funtion can be called several times on the | ||
28 | same B<ctx> to include additional data. | ||
29 | |||
30 | EVP_SignFinal() signs the data in B<ctx> using the private key B<pkey> | ||
31 | and places the signature in B<sig>. If the B<s> parameter is not NULL | ||
32 | then the number of bytes of data written (i.e. the length of the signature) | ||
33 | will be written to the integer at B<s>, at most EVP_PKEY_size(pkey) bytes | ||
34 | will be written. After calling EVP_SignFinal() no additional calls to | ||
35 | EVP_SignUpdate() can be made, but EVP_SignInit() can be called to initialiase | ||
36 | a new signature operation. | ||
37 | |||
38 | EVP_PKEY_size() returns the maximum size of a signature in bytes. The actual | ||
39 | signature returned by EVP_SignFinal() may be smaller. | ||
40 | |||
41 | =head1 RETURN VALUES | ||
42 | |||
43 | EVP_SignInit() and EVP_SignUpdate() do not return values. | ||
44 | |||
45 | EVP_SignFinal() returns 1 for success and 0 for failure. | ||
46 | |||
47 | EVP_PKEY_size() returns the maximum size of a signature in bytes. | ||
48 | |||
49 | The error codes can be obtained by L<ERR_get_error(3)|ERR_get_error(3)>. | ||
50 | |||
51 | =head1 NOTES | ||
52 | |||
53 | The B<EVP> interface to digital signatures should almost always be used in | ||
54 | preference to the low level interfaces. This is because the code then becomes | ||
55 | transparent to the algorithm used and much more flexible. | ||
56 | |||
57 | Due to the link between message digests and public key algorithms the correct | ||
58 | digest algorithm must be used with the correct public key type. A list of | ||
59 | algorithms and associated public key algorithms appears in | ||
60 | L<EVP_DigestInit(3)|EVP_DigestInit(3)>. | ||
61 | |||
62 | When signing with DSA private keys the random number generator must be seeded | ||
63 | or the operation will fail. The random number generator does not need to be | ||
64 | seeded for RSA signatures. | ||
65 | |||
66 | =head1 BUGS | ||
67 | |||
68 | Several of the functions do not return values: maybe they should. Although the | ||
69 | internal digest operations will never fail some future hardware based operations | ||
70 | might. | ||
71 | |||
72 | =head1 SEE ALSO | ||
73 | |||
74 | L<EVP_VerifyInit(3)|EVP_VerifyInit(3)>, | ||
75 | L<EVP_DigestInit(3)|EVP_DigestInit(3)>, L<err(3)|err(3)>, | ||
76 | L<evp(3)|evp(3)>, L<hmac(3)|hmac(3)>, L<md2(3)|md2(3)>, | ||
77 | L<md5(3)|md5(3)>, L<mdc2(3)|mdc2(3)>, L<ripemd(3)|ripemd(3)>, | ||
78 | L<sha(3)|sha(3)>, L<digest(1)|digest(1)> | ||
79 | |||
80 | =head1 HISTORY | ||
81 | |||
82 | EVP_SignInit(), EVP_SignUpdate() and EVP_SignFinal() are | ||
83 | available in all versions of SSLeay and OpenSSL. | ||
84 | |||
85 | =cut | ||
diff --git a/src/lib/libcrypto/doc/EVP_VerifyInit.pod b/src/lib/libcrypto/doc/EVP_VerifyInit.pod new file mode 100644 index 0000000000..3b5e07f4ad --- /dev/null +++ b/src/lib/libcrypto/doc/EVP_VerifyInit.pod | |||
@@ -0,0 +1,71 @@ | |||
1 | =pod | ||
2 | |||
3 | =head1 NAME | ||
4 | |||
5 | EVP_VerifyInit, EVP_VerifyUpdate, EVP_VerifyFinal - EVP signature verification functions | ||
6 | |||
7 | =head1 SYNOPSIS | ||
8 | |||
9 | #include <openssl/evp.h> | ||
10 | |||
11 | void EVP_VerifyInit(EVP_MD_CTX *ctx, const EVP_MD *type); | ||
12 | void EVP_VerifyUpdate(EVP_MD_CTX *ctx, const void *d, unsigned int cnt); | ||
13 | int EVP_VerifyFinal(EVP_MD_CTX *ctx,unsigned char *sigbuf, unsigned int siglen,EVP_PKEY *pkey); | ||
14 | |||
15 | =head1 DESCRIPTION | ||
16 | |||
17 | The EVP signature verification routines are a high level interface to digital | ||
18 | signatures. | ||
19 | |||
20 | EVP_VerifyInit() initialises a verification context B<ctx> to using digest | ||
21 | B<type>: this will typically be supplied by a function such as EVP_sha1(). | ||
22 | |||
23 | EVP_VerifyUpdate() hashes B<cnt> bytes of data at B<d> into the | ||
24 | verification context B<ctx>. This funtion can be called several times on the | ||
25 | same B<ctx> to include additional data. | ||
26 | |||
27 | EVP_VerifyFinal() verifies the data in B<ctx> using the public key B<pkey> | ||
28 | and against the B<siglen> bytes at B<sigbuf>. After calling EVP_VerifyFinal() | ||
29 | no additional calls to EVP_VerifyUpdate() can be made, but EVP_VerifyInit() | ||
30 | can be called to initialiase a new verification operation. | ||
31 | |||
32 | =head1 RETURN VALUES | ||
33 | |||
34 | EVP_VerifyInit() and EVP_VerifyUpdate() do not return values. | ||
35 | |||
36 | EVP_VerifyFinal() returns 1 for a correct signature, 0 for failure and -1 if some | ||
37 | other error occurred. | ||
38 | |||
39 | The error codes can be obtained by L<ERR_get_error(3)|ERR_get_error(3)>. | ||
40 | |||
41 | =head1 NOTES | ||
42 | |||
43 | The B<EVP> interface to digital signatures should almost always be used in | ||
44 | preference to the low level interfaces. This is because the code then becomes | ||
45 | transparent to the algorithm used and much more flexible. | ||
46 | |||
47 | Due to the link between message digests and public key algorithms the correct | ||
48 | digest algorithm must be used with the correct public key type. A list of | ||
49 | algorithms and associated public key algorithms appears in | ||
50 | L<EVP_DigestInit(3)|EVP_DigestInit(3)>. | ||
51 | |||
52 | =head1 BUGS | ||
53 | |||
54 | Several of the functions do not return values: maybe they should. Although the | ||
55 | internal digest operations will never fail some future hardware based operations | ||
56 | might. | ||
57 | |||
58 | =head1 SEE ALSO | ||
59 | |||
60 | L<EVP_SignInit(3)|EVP_SignInit(3)>, | ||
61 | L<EVP_DigestInit(3)|EVP_DigestInit(3)>, L<err(3)|err(3)>, | ||
62 | L<evp(3)|evp(3)>, L<hmac(3)|hmac(3)>, L<md2(3)|md2(3)>, | ||
63 | L<md5(3)|md5(3)>, L<mdc2(3)|mdc2(3)>, L<ripemd(3)|ripemd(3)>, | ||
64 | L<sha(3)|sha(3)>, L<digest(1)|digest(1)> | ||
65 | |||
66 | =head1 HISTORY | ||
67 | |||
68 | EVP_VerifyInit(), EVP_VerifyUpdate() and EVP_VerifyFinal() are | ||
69 | available in all versions of SSLeay and OpenSSL. | ||
70 | |||
71 | =cut | ||
diff --git a/src/lib/libcrypto/doc/OPENSSL_VERSION_NUMBER.pod b/src/lib/libcrypto/doc/OPENSSL_VERSION_NUMBER.pod new file mode 100644 index 0000000000..b0b1058d19 --- /dev/null +++ b/src/lib/libcrypto/doc/OPENSSL_VERSION_NUMBER.pod | |||
@@ -0,0 +1,46 @@ | |||
1 | =pod | ||
2 | |||
3 | =head1 NAME | ||
4 | |||
5 | OPENSSL_VERSION_NUMBER, SSLeay - get OpenSSL version number | ||
6 | |||
7 | =head1 SYNOPSIS | ||
8 | |||
9 | #include <openssl/opensslv.h> | ||
10 | #define OPENSSL_VERSION_NUMBER 0xnnnnnnnnnL | ||
11 | |||
12 | #include <openssl/crypto.h> | ||
13 | long SSLeay(void); | ||
14 | |||
15 | =head1 DESCRIPTION | ||
16 | |||
17 | OPENSSL_VERSION_NUMBER is a numeric release version identifier: | ||
18 | |||
19 | MMNNFFRBB major minor fix final beta/patch | ||
20 | |||
21 | for example | ||
22 | |||
23 | 0x000904100 == 0.9.4 release | ||
24 | 0x000905000 == 0.9.5 dev | ||
25 | |||
26 | Versions prior to 0.9.3 have identifiers E<lt> 0x0930. | ||
27 | For backward compatibility, SSLEAY_VERSION_NUMBER is also defined. | ||
28 | |||
29 | SSLeay() returns this number. The return value can be compared to the | ||
30 | macro to make sure that the correct version of the library has been | ||
31 | loaded, especially when using DLLs on Windows systems. | ||
32 | |||
33 | =head1 RETURN VALUE | ||
34 | |||
35 | The version number. | ||
36 | |||
37 | =head1 SEE ALSO | ||
38 | |||
39 | L<crypto(3)|crypto(3)> | ||
40 | |||
41 | =head1 HISTORY | ||
42 | |||
43 | SSLeay() and SSLEAY_VERSION_NUMBER are available in all versions of SSLeay and OpenSSL. | ||
44 | OPENSSL_VERSION_NUMBER is available in all versions of OpenSSL. | ||
45 | |||
46 | =cut | ||
diff --git a/src/lib/libcrypto/doc/OpenSSL_add_all_algorithms.pod b/src/lib/libcrypto/doc/OpenSSL_add_all_algorithms.pod new file mode 100644 index 0000000000..1300fe190c --- /dev/null +++ b/src/lib/libcrypto/doc/OpenSSL_add_all_algorithms.pod | |||
@@ -0,0 +1,65 @@ | |||
1 | =pod | ||
2 | |||
3 | =head1 NAME | ||
4 | |||
5 | OpenSSL_add_all_algorithms() - add algorithms to internal table | ||
6 | |||
7 | =head1 SYNOPSIS | ||
8 | |||
9 | #include <openssl/evp.h> | ||
10 | |||
11 | void OpenSSL_add_all_algorithms(void); | ||
12 | void OpenSSL_add_all_ciphers(void); | ||
13 | void OpenSSL_add_all_digests(void); | ||
14 | |||
15 | void EVP_cleanup(void); | ||
16 | |||
17 | =head1 DESCRIPTION | ||
18 | |||
19 | OpenSSL keeps an internal table of digest algorithms and ciphers. It uses | ||
20 | this table to lookup ciphers via functions such as EVP_get_cipher_byname(). | ||
21 | |||
22 | OpenSSL_add_all_digests() adds all digest algorithms to the table. | ||
23 | |||
24 | OpenSSL_add_all_algorithms() adds all algorithms to the table (digests and | ||
25 | ciphers). | ||
26 | |||
27 | OpenSSL_add_all_ciphers() adds all encryption algorithms to the table including | ||
28 | password based encryption algorithms. | ||
29 | |||
30 | EVP_cleanup() removes all ciphers and digests from the table. | ||
31 | |||
32 | =head1 RETURN VALUES | ||
33 | |||
34 | None of the functions return a value. | ||
35 | |||
36 | =head1 NOTES | ||
37 | |||
38 | A typical application will will call OpenSSL_add_all_algorithms() initially and | ||
39 | EVP_cleanup() before exiting. | ||
40 | |||
41 | An application does not need to add algorithms to use them explicitly, for example | ||
42 | by EVP_sha1(). It just needs to add them if it (or any of the functions it calls) | ||
43 | needs to lookup algorithms. | ||
44 | |||
45 | The cipher and digest lookup functions are used in many parts of the library. If | ||
46 | the table is not initialised several functions will misbehave and complain they | ||
47 | cannot find algorithms. This includes the PEM, PKCS#12, SSL and S/MIME libraries. | ||
48 | This is a common query in the OpenSSL mailing lists. | ||
49 | |||
50 | Calling OpenSSL_add_all_algorithms() links in all algorithms: as a result a | ||
51 | statically linked executable can be quite large. If this is important it is possible | ||
52 | to just add the required ciphers and digests. | ||
53 | |||
54 | =head1 BUGS | ||
55 | |||
56 | Although the functions do not return error codes it is possible for them to fail. | ||
57 | This will only happen as a result of a memory allocation failure so this is not | ||
58 | too much of a problem in practice. | ||
59 | |||
60 | =head1 SEE ALSO | ||
61 | |||
62 | L<evp(3)|evp(3)>, L<EVP_DigestInit(3)|EVP_DigestInit(3)>, | ||
63 | L<EVP_EncryptInit(3)|EVP_EncryptInit(3)> | ||
64 | |||
65 | =cut | ||
diff --git a/src/lib/libcrypto/doc/RAND_add.pod b/src/lib/libcrypto/doc/RAND_add.pod new file mode 100644 index 0000000000..0a13ec2a92 --- /dev/null +++ b/src/lib/libcrypto/doc/RAND_add.pod | |||
@@ -0,0 +1,68 @@ | |||
1 | =pod | ||
2 | |||
3 | =head1 NAME | ||
4 | |||
5 | RAND_add, RAND_seed, RAND_screen - add entropy to the PRNG | ||
6 | |||
7 | =head1 SYNOPSIS | ||
8 | |||
9 | #include <openssl/rand.h> | ||
10 | |||
11 | void RAND_seed(const void *buf, int num); | ||
12 | |||
13 | void RAND_add(const void *buf, int num, double entropy); | ||
14 | |||
15 | int RAND_status(void); | ||
16 | |||
17 | void RAND_screen(void); | ||
18 | |||
19 | =head1 DESCRIPTION | ||
20 | |||
21 | RAND_add() mixes the B<num> bytes at B<buf> into the PRNG state. Thus, | ||
22 | if the data at B<buf> are unpredictable to an adversary, this | ||
23 | increases the uncertainty about the state and makes the PRNG output | ||
24 | less predictable. Suitable input comes from user interaction (random | ||
25 | key presses, mouse movements) and certain hardware events. The | ||
26 | B<entropy> argument is (the lower bound of) an estimate of how much | ||
27 | randomness is contained in B<buf>, measured in bytes. Details about | ||
28 | sources of randomness and how to estimate their entropy can be found | ||
29 | in the literature, e.g. RFC 1750. | ||
30 | |||
31 | RAND_add() may be called with sensitive data such as user entered | ||
32 | passwords. The seed values cannot be recovered from the PRNG output. | ||
33 | |||
34 | OpenSSL makes sure that the PRNG state is unique for each thread. On | ||
35 | systems that provide C</dev/urandom>, the randomness device is used | ||
36 | to seed the PRNG transparently. However, on all other systems, the | ||
37 | application is responsible for seeding the PRNG by calling RAND_add(), | ||
38 | L<RAND_egd(3)|RAND_egd(3)> | ||
39 | or L<RAND_load_file(3)|RAND_load_file(3)>. | ||
40 | |||
41 | RAND_seed() is equivalent to RAND_add() when B<num == entropy>. | ||
42 | |||
43 | The RAND_screen() function is available for the convenience of Windows | ||
44 | programmers. It adds the current contents of the screen to the PRNG. | ||
45 | For applications that can catch Windows events, seeding the PRNG with | ||
46 | the parameters of B<WM_MOUSEMOVE> events is a significantly better | ||
47 | source of randomness. It should be noted that both methods cannot be | ||
48 | used on servers that run without user interaction. | ||
49 | |||
50 | =head1 RETURN VALUES | ||
51 | |||
52 | RAND_status() returns 1 if the PRNG has been seeded with enough data, | ||
53 | 0 otherwise. | ||
54 | |||
55 | The other functions do not return values. | ||
56 | |||
57 | =head1 SEE ALSO | ||
58 | |||
59 | L<rand(3)|rand(3)>, L<RAND_egd(3)|RAND_egd(3)>, | ||
60 | L<RAND_load_file(3)|RAND_load_file(3)>, L<RAND_cleanup(3)|RAND_cleanup(3)> | ||
61 | |||
62 | =head1 HISTORY | ||
63 | |||
64 | RAND_seed() and RAND_screen() are available in all versions of SSLeay | ||
65 | and OpenSSL. RAND_add() and RAND_status() have been added in OpenSSL | ||
66 | 0.9.5. | ||
67 | |||
68 | =cut | ||
diff --git a/src/lib/libcrypto/doc/RAND_bytes.pod b/src/lib/libcrypto/doc/RAND_bytes.pod new file mode 100644 index 0000000000..b6ebd50527 --- /dev/null +++ b/src/lib/libcrypto/doc/RAND_bytes.pod | |||
@@ -0,0 +1,46 @@ | |||
1 | =pod | ||
2 | |||
3 | =head1 NAME | ||
4 | |||
5 | RAND_bytes, RAND_pseudo_bytes - generate random data | ||
6 | |||
7 | =head1 SYNOPSIS | ||
8 | |||
9 | #include <openssl/rand.h> | ||
10 | |||
11 | int RAND_bytes(unsigned char *buf, int num); | ||
12 | |||
13 | int RAND_pseudo_bytes(unsigned char *buf, int num); | ||
14 | |||
15 | =head1 DESCRIPTION | ||
16 | |||
17 | RAND_bytes() puts B<num> cryptographically strong pseudo-random bytes | ||
18 | into B<buf>. An error occurs if the PRNG has not been seeded with | ||
19 | enough randomness to ensure an unpredictable byte sequence. | ||
20 | |||
21 | RAND_pseudo_bytes() puts B<num> pseudo-random bytes into B<buf>. | ||
22 | Pseudo-random byte sequences generated by RAND_pseudo_bytes() will be | ||
23 | unique if they are of sufficient length, but are not necessarily | ||
24 | unpredictable. They can be used for non-cryptographic purposes and for | ||
25 | certain purposes in cryptographic protocols, but usually not for key | ||
26 | generation etc. | ||
27 | |||
28 | =head1 RETURN VALUES | ||
29 | |||
30 | RAND_bytes() returns 1 on success, 0 otherwise. The error code can be | ||
31 | obtained by L<ERR_get_error(3)|ERR_get_error(3)>. RAND_pseudo_bytes() returns 1 if the | ||
32 | bytes generated are cryptographically strong, 0 otherwise. Both | ||
33 | functions return -1 if they are not supported by the current RAND | ||
34 | method. | ||
35 | |||
36 | =head1 SEE ALSO | ||
37 | |||
38 | L<rand(3)|rand(3)>, L<err(3)|err(3)>, L<RAND_add(3)|RAND_add(3)> | ||
39 | |||
40 | =head1 HISTORY | ||
41 | |||
42 | RAND_bytes() is available in all versions of SSLeay and OpenSSL. It | ||
43 | has a return value since OpenSSL 0.9.5. RAND_pseudo_bytes() was added | ||
44 | in OpenSSL 0.9.5. | ||
45 | |||
46 | =cut | ||
diff --git a/src/lib/libcrypto/doc/RAND_cleanup.pod b/src/lib/libcrypto/doc/RAND_cleanup.pod new file mode 100644 index 0000000000..3a8f0749a8 --- /dev/null +++ b/src/lib/libcrypto/doc/RAND_cleanup.pod | |||
@@ -0,0 +1,29 @@ | |||
1 | =pod | ||
2 | |||
3 | =head1 NAME | ||
4 | |||
5 | RAND_cleanup - erase the PRNG state | ||
6 | |||
7 | =head1 SYNOPSIS | ||
8 | |||
9 | #include <openssl/rand.h> | ||
10 | |||
11 | void RAND_cleanup(void); | ||
12 | |||
13 | =head1 DESCRIPTION | ||
14 | |||
15 | RAND_cleanup() erases the memory used by the PRNG. | ||
16 | |||
17 | =head1 RETURN VALUE | ||
18 | |||
19 | RAND_cleanup() returns no value. | ||
20 | |||
21 | =head1 SEE ALSO | ||
22 | |||
23 | L<rand(3)|rand(3)> | ||
24 | |||
25 | =head1 HISTORY | ||
26 | |||
27 | RAND_cleanup() is available in all versions of SSLeay and OpenSSL. | ||
28 | |||
29 | =cut | ||
diff --git a/src/lib/libcrypto/doc/RAND_load_file.pod b/src/lib/libcrypto/doc/RAND_load_file.pod new file mode 100644 index 0000000000..8dd700ca3d --- /dev/null +++ b/src/lib/libcrypto/doc/RAND_load_file.pod | |||
@@ -0,0 +1,53 @@ | |||
1 | =pod | ||
2 | |||
3 | =head1 NAME | ||
4 | |||
5 | RAND_load_file, RAND_write_file, RAND_file_name - PRNG seed file | ||
6 | |||
7 | =head1 SYNOPSIS | ||
8 | |||
9 | #include <openssl/rand.h> | ||
10 | |||
11 | const char *RAND_file_name(char *buf, int num); | ||
12 | |||
13 | int RAND_load_file(const char *filename, long max_bytes); | ||
14 | |||
15 | int RAND_write_file(const char *filename); | ||
16 | |||
17 | =head1 DESCRIPTION | ||
18 | |||
19 | RAND_file_name() generates a default path for the random seed | ||
20 | file. B<buf> points to a buffer of size B<num> in which to store the | ||
21 | filename. The seed file is $RANDFILE if that environment variable is | ||
22 | set, $HOME/.rnd otherwise. If $HOME is not set either, or B<num> is | ||
23 | too small for the path name, an error occurs. | ||
24 | |||
25 | RAND_load_file() reads a number of bytes from file B<filename> and | ||
26 | adds them to the PRNG. If B<max_bytes> is non-negative, | ||
27 | up to to B<max_bytes> are read; starting with OpenSSL 0.9.5, | ||
28 | if B<max_bytes> is -1, the complete file is read. | ||
29 | |||
30 | RAND_write_file() writes a number of random bytes (currently 1024) to | ||
31 | file B<filename> which can be used to initialize the PRNG by calling | ||
32 | RAND_load_file() in a later session. | ||
33 | |||
34 | =head1 RETURN VALUES | ||
35 | |||
36 | RAND_load_file() returns the number of bytes read. | ||
37 | |||
38 | RAND_write_file() returns the number of bytes written, and -1 if the | ||
39 | bytes written were generated without appropriate seed. | ||
40 | |||
41 | RAND_file_name() returns a pointer to B<buf> on success, and NULL on | ||
42 | error. | ||
43 | |||
44 | =head1 SEE ALSO | ||
45 | |||
46 | L<rand(3)|rand(3)>, L<RAND_add(3)|RAND_add(3)>, L<RAND_cleanup(3)|RAND_cleanup(3)> | ||
47 | |||
48 | =head1 HISTORY | ||
49 | |||
50 | RAND_load_file(), RAND_write_file() and RAND_file_name() are available in | ||
51 | all versions of SSLeay and OpenSSL. | ||
52 | |||
53 | =cut | ||
diff --git a/src/lib/libcrypto/doc/RAND_set_rand_method.pod b/src/lib/libcrypto/doc/RAND_set_rand_method.pod new file mode 100644 index 0000000000..466e9b8767 --- /dev/null +++ b/src/lib/libcrypto/doc/RAND_set_rand_method.pod | |||
@@ -0,0 +1,57 @@ | |||
1 | =pod | ||
2 | |||
3 | =head1 NAME | ||
4 | |||
5 | RAND_set_rand_method, RAND_get_rand_method, RAND_SSLeay - select RAND method | ||
6 | |||
7 | =head1 SYNOPSIS | ||
8 | |||
9 | #include <openssl/rand.h> | ||
10 | |||
11 | void RAND_set_rand_method(RAND_METHOD *meth); | ||
12 | |||
13 | RAND_METHOD *RAND_get_rand_method(void); | ||
14 | |||
15 | RAND_METHOD *RAND_SSLeay(void); | ||
16 | |||
17 | =head1 DESCRIPTION | ||
18 | |||
19 | A B<RAND_METHOD> specifies the functions that OpenSSL uses for random | ||
20 | number generation. By modifying the method, alternative | ||
21 | implementations such as hardware RNGs may be used. Initially, the | ||
22 | default is to use the OpenSSL internal implementation. RAND_SSLeay() | ||
23 | returns a pointer to that method. | ||
24 | |||
25 | RAND_set_rand_method() sets the RAND method to B<meth>. | ||
26 | RAND_get_rand_method() returns a pointer to the current method. | ||
27 | |||
28 | =head1 THE RAND_METHOD STRUCTURE | ||
29 | |||
30 | typedef struct rand_meth_st | ||
31 | { | ||
32 | void (*seed)(const void *buf, int num); | ||
33 | int (*bytes)(unsigned char *buf, int num); | ||
34 | void (*cleanup)(void); | ||
35 | void (*add)(const void *buf, int num, int entropy); | ||
36 | int (*pseudorand)(unsigned char *buf, int num); | ||
37 | } RAND_METHOD; | ||
38 | |||
39 | The components point to the implementation of RAND_seed(), | ||
40 | RAND_bytes(), RAND_cleanup(), RAND_add() and RAND_pseudo_rand(). | ||
41 | Each component may be NULL if the function is not implemented. | ||
42 | |||
43 | =head1 RETURN VALUES | ||
44 | |||
45 | RAND_set_rand_method() returns no value. RAND_get_rand_method() and | ||
46 | RAND_SSLeay() return pointers to the respective methods. | ||
47 | |||
48 | =head1 SEE ALSO | ||
49 | |||
50 | L<rand(3)|rand(3)> | ||
51 | |||
52 | =head1 HISTORY | ||
53 | |||
54 | RAND_set_rand_method(), RAND_get_rand_method() and RAND_SSLeay() are | ||
55 | available in all versions of OpenSSL. | ||
56 | |||
57 | =cut | ||
diff --git a/src/lib/libcrypto/doc/RSA_blinding_on.pod b/src/lib/libcrypto/doc/RSA_blinding_on.pod new file mode 100644 index 0000000000..fd2c69abd8 --- /dev/null +++ b/src/lib/libcrypto/doc/RSA_blinding_on.pod | |||
@@ -0,0 +1,43 @@ | |||
1 | =pod | ||
2 | |||
3 | =head1 NAME | ||
4 | |||
5 | RSA_blinding_on, RSA_blinding_off - protect the RSA operation from timing attacks | ||
6 | |||
7 | =head1 SYNOPSIS | ||
8 | |||
9 | #include <openssl/rsa.h> | ||
10 | |||
11 | int RSA_blinding_on(RSA *rsa, BN_CTX *ctx); | ||
12 | |||
13 | void RSA_blinding_off(RSA *rsa); | ||
14 | |||
15 | =head1 DESCRIPTION | ||
16 | |||
17 | RSA is vulnerable to timing attacks. In a setup where attackers can | ||
18 | measure the time of RSA decryption or signature operations, blinding | ||
19 | must be used to protect the RSA operation from that attack. | ||
20 | |||
21 | RSA_blinding_on() turns blinding on for key B<rsa> and generates a | ||
22 | random blinding factor. B<ctx> is B<NULL> or a pre-allocated and | ||
23 | initialized B<BN_CTX>. The random number generator must be seeded | ||
24 | prior to calling RSA_blinding_on(). | ||
25 | |||
26 | RSA_blinding_off() turns blinding off and frees the memory used for | ||
27 | the blinding factor. | ||
28 | |||
29 | =head1 RETURN VALUES | ||
30 | |||
31 | RSA_blinding_on() returns 1 on success, and 0 if an error occurred. | ||
32 | |||
33 | RSA_blinding_off() returns no value. | ||
34 | |||
35 | =head1 SEE ALSO | ||
36 | |||
37 | L<rsa(3)|rsa(3)>, L<rand(3)|rand(3)> | ||
38 | |||
39 | =head1 HISTORY | ||
40 | |||
41 | RSA_blinding_on() and RSA_blinding_off() appeared in SSLeay 0.9.0. | ||
42 | |||
43 | =cut | ||
diff --git a/src/lib/libcrypto/doc/RSA_check_key.pod b/src/lib/libcrypto/doc/RSA_check_key.pod new file mode 100644 index 0000000000..79fed753ad --- /dev/null +++ b/src/lib/libcrypto/doc/RSA_check_key.pod | |||
@@ -0,0 +1,39 @@ | |||
1 | =pod | ||
2 | |||
3 | =head1 NAME | ||
4 | |||
5 | RSA_check_key - validate private RSA keys | ||
6 | |||
7 | =head1 SYNOPSIS | ||
8 | |||
9 | #include <openssl/rsa.h> | ||
10 | |||
11 | int RSA_check_key(RSA *rsa); | ||
12 | |||
13 | =head1 DESCRIPTION | ||
14 | |||
15 | This function validates RSA keys. It checks that B<p> and B<q> are | ||
16 | in fact prime, and that B<n = p*q>. | ||
17 | |||
18 | It also checks that B<d*e = 1 mod (p-1*q-1)>, | ||
19 | and that B<dmp1>, B<dmq1> and B<iqmp> are set correctly or are B<NULL>. | ||
20 | |||
21 | The key's public components may not be B<NULL>. | ||
22 | |||
23 | =head1 RETURN VALUE | ||
24 | |||
25 | RSA_check_key() returns 1 if B<rsa> is a valid RSA key, and 0 otherwise. | ||
26 | -1 is returned if an error occurs while checking the key. | ||
27 | |||
28 | If the key is invalid or an error occurred, the reason code can be | ||
29 | obtained using L<ERR_get_error(3)|ERR_get_error(3)>. | ||
30 | |||
31 | =head1 SEE ALSO | ||
32 | |||
33 | L<rsa(3)|rsa(3)>, L<err(3)|err(3)> | ||
34 | |||
35 | =head1 HISTORY | ||
36 | |||
37 | RSA_check() appeared in OpenSSL 0.9.4. | ||
38 | |||
39 | =cut | ||
diff --git a/src/lib/libcrypto/doc/RSA_generate_key.pod b/src/lib/libcrypto/doc/RSA_generate_key.pod new file mode 100644 index 0000000000..fdaddbcb13 --- /dev/null +++ b/src/lib/libcrypto/doc/RSA_generate_key.pod | |||
@@ -0,0 +1,68 @@ | |||
1 | =pod | ||
2 | |||
3 | =head1 NAME | ||
4 | |||
5 | RSA_generate_key - generate RSA key pair | ||
6 | |||
7 | =head1 SYNOPSIS | ||
8 | |||
9 | #include <openssl/rsa.h> | ||
10 | |||
11 | RSA *RSA_generate_key(int num, unsigned long e, | ||
12 | void (*callback)(int,int,void *), void *cb_arg); | ||
13 | |||
14 | =head1 DESCRIPTION | ||
15 | |||
16 | RSA_generate_key() generates a key pair and returns it in a newly | ||
17 | allocated B<RSA> structure. The pseudo-random number generator must | ||
18 | be seeded prior to calling RSA_generate_key(). | ||
19 | |||
20 | The modulus size will be B<num> bits, and the public exponent will be | ||
21 | B<e>. Key sizes with B<num> E<lt> 1024 should be considered insecure. | ||
22 | The exponent is an odd number, typically 3 or 65535. | ||
23 | |||
24 | A callback function may be used to provide feedback about the | ||
25 | progress of the key generation. If B<callback> is not B<NULL>, it | ||
26 | will be called as follows: | ||
27 | |||
28 | =over 4 | ||
29 | |||
30 | =item * | ||
31 | |||
32 | While a random prime number is generated, it is called as | ||
33 | described in L<BN_generate_prime(3)|BN_generate_prime(3)>. | ||
34 | |||
35 | =item * | ||
36 | |||
37 | When the n-th randomly generated prime is rejected as not | ||
38 | suitable for the key, B<callback(2, n, cb_arg)> is called. | ||
39 | |||
40 | =item * | ||
41 | |||
42 | When a random p has been found with p-1 relatively prime to B<e>, | ||
43 | it is called as B<callback(3, 0, cb_arg)>. | ||
44 | |||
45 | =back | ||
46 | |||
47 | The process is then repeated for prime q with B<callback(3, 1, cb_arg)>. | ||
48 | |||
49 | =head1 RETURN VALUE | ||
50 | |||
51 | If key generation fails, RSA_generate_key() returns B<NULL>; the | ||
52 | error codes can be obtained by L<ERR_get_error(3)|ERR_get_error(3)>. | ||
53 | |||
54 | =head1 BUGS | ||
55 | |||
56 | B<callback(2, x, cb_arg)> is used with two different meanings. | ||
57 | |||
58 | RSA_generate_key() goes into an infinite loop for illegal input values. | ||
59 | |||
60 | =head1 SEE ALSO | ||
61 | |||
62 | L<err(3)|err(3)>, L<rand(3)|rand(3)>, L<rsa(3)|rsa(3)>, L<RSA_free(3)|RSA_free(3)> | ||
63 | |||
64 | =head1 HISTORY | ||
65 | |||
66 | The B<cb_arg> argument was added in SSLeay 0.9.0. | ||
67 | |||
68 | =cut | ||
diff --git a/src/lib/libcrypto/doc/RSA_get_ex_new_index.pod b/src/lib/libcrypto/doc/RSA_get_ex_new_index.pod new file mode 100644 index 0000000000..920dc76325 --- /dev/null +++ b/src/lib/libcrypto/doc/RSA_get_ex_new_index.pod | |||
@@ -0,0 +1,122 @@ | |||
1 | =pod | ||
2 | |||
3 | =head1 NAME | ||
4 | |||
5 | RSA_get_ex_new_index, RSA_set_ex_data, RSA_get_ex_data - add application specific data to RSA structures | ||
6 | |||
7 | =head1 SYNOPSIS | ||
8 | |||
9 | #include <openssl/rsa.h> | ||
10 | |||
11 | int RSA_get_ex_new_index(long argl, void *argp, | ||
12 | CRYPTO_EX_new *new_func, | ||
13 | CRYPTO_EX_dup *dup_func, | ||
14 | CRYPTO_EX_free *free_func); | ||
15 | |||
16 | int RSA_set_ex_data(RSA *r, int idx, void *arg); | ||
17 | |||
18 | void *RSA_get_ex_data(RSA *r, int idx); | ||
19 | |||
20 | int new_func(void *parent, void *ptr, CRYPTO_EX_DATA *ad, | ||
21 | int idx, long argl, void *argp); | ||
22 | |||
23 | void free_func(void *parent, void *ptr, CRYPTO_EX_DATA *ad, | ||
24 | int idx, long argl, void *argp); | ||
25 | |||
26 | int dup_func(CRYPTO_EX_DATA *to, CRYPTO_EX_DATA *from, void *from_d, | ||
27 | int idx, long argl, void *argp); | ||
28 | |||
29 | =head1 DESCRIPTION | ||
30 | |||
31 | Several OpenSSL structures can have application specific data attached to them. | ||
32 | This has several potential uses, it can be used to cache data associated with | ||
33 | a structure (for example the hash of some part of the structure) or some | ||
34 | additional data (for example a handle to the data in an external library). | ||
35 | |||
36 | Since the application data can be anything at all it is passed and retrieved | ||
37 | as a B<void *> type. | ||
38 | |||
39 | The B<RSA_get_ex_new_index()> function is initially called to "register" some | ||
40 | new application specific data. It takes three optional function pointers which | ||
41 | are called when the parent structure (in this case an RSA structure) is | ||
42 | initially created, when it is copied and when it is freed up. If any or all of | ||
43 | these function pointer arguments are not used they should be set to NULL. The | ||
44 | precise manner in which these function pointers are called is described in more | ||
45 | detail below. B<RSA_get_ex_new_index()> also takes additional long and pointer | ||
46 | parameters which will be passed to the supplied functions but which otherwise | ||
47 | have no special meaning. It returns an B<index> which should be stored | ||
48 | (typically in a static variable) and passed used in the B<idx> parameter in | ||
49 | the remaining functions. Each successful call to B<RSA_get_ex_new_index()> | ||
50 | will return an index greater than any previously returned, this is important | ||
51 | because the optional functions are called in order of increasing index value. | ||
52 | |||
53 | B<RSA_set_ex_data()> is used to set application specific data, the data is | ||
54 | supplied in the B<arg> parameter and its precise meaning is up to the | ||
55 | application. | ||
56 | |||
57 | B<RSA_get_ex_data()> is used to retrieve application specific data. The data | ||
58 | is returned to the application, this will be the same value as supplied to | ||
59 | a previous B<RSA_set_ex_data()> call. | ||
60 | |||
61 | B<new_func()> is called when a structure is initially allocated (for example | ||
62 | with B<RSA_new()>. The parent structure members will not have any meaningful | ||
63 | values at this point. This function will typically be used to allocate any | ||
64 | application specific structure. | ||
65 | |||
66 | B<free_func()> is called when a structure is being freed up. The dynamic parent | ||
67 | structure members should not be accessed because they will be freed up when | ||
68 | this function is called. | ||
69 | |||
70 | B<new_func()> and B<free_func()> take the same parameters. B<parent> is a | ||
71 | pointer to the parent RSA structure. B<ptr> is a the application specific data | ||
72 | (this wont be of much use in B<new_func()>. B<ad> is a pointer to the | ||
73 | B<CRYPTO_EX_DATA> structure from the parent RSA structure: the functions | ||
74 | B<CRYPTO_get_ex_data()> and B<CRYPTO_set_ex_data()> can be called to manipulate | ||
75 | it. The B<idx> parameter is the index: this will be the same value returned by | ||
76 | B<RSA_get_ex_new_index()> when the functions were initially registered. Finally | ||
77 | the B<argl> and B<argp> parameters are the values originally passed to the same | ||
78 | corresponding parameters when B<RSA_get_ex_new_index()> was called. | ||
79 | |||
80 | B<dup_func()> is called when a structure is being copied. Pointers to the | ||
81 | destination and source B<CRYPTO_EX_DATA> structures are passed in the B<to> and | ||
82 | B<from> parameters respectively. The B<from_d> parameter is passed a pointer to | ||
83 | the source application data when the function is called, when the function returns | ||
84 | the value is copied to the destination: the application can thus modify the data | ||
85 | pointed to by B<from_d> and have different values in the source and destination. | ||
86 | The B<idx>, B<argl> and B<argp> parameters are the same as those in B<new_func()> | ||
87 | and B<free_func()>. | ||
88 | |||
89 | =head1 RETURN VALUES | ||
90 | |||
91 | B<RSA_get_ex_new_index()> returns a new index or -1 on failure (note 0 is a valid | ||
92 | index value). | ||
93 | |||
94 | B<RSA_set_ex_data()> returns 1 on success or 0 on failure. | ||
95 | |||
96 | B<RSA_get_ex_data()> returns the application data or 0 on failure. 0 may also | ||
97 | be valid application data but currently it can only fail if given an invalid B<idx> | ||
98 | parameter. | ||
99 | |||
100 | B<new_func()> and B<dup_func()> should return 0 for failure and 1 for success. | ||
101 | |||
102 | On failure an error code can be obtained from L<ERR_get_error(3)|ERR_get_error(3)>. | ||
103 | |||
104 | =head1 BUGS | ||
105 | |||
106 | B<dup_func()> is currently never called. | ||
107 | |||
108 | The return value of B<new_func()> is ignored. | ||
109 | |||
110 | The B<new_func()> function isn't very useful because no meaningful values are | ||
111 | present in the parent RSA structure when it is called. | ||
112 | |||
113 | =head1 SEE ALSO | ||
114 | |||
115 | L<rsa(3)|rsa(3)>, L<CRYPTO_set_ex_data(3)|CRYPTO_set_ex_data(3)> | ||
116 | |||
117 | =head1 HISTORY | ||
118 | |||
119 | RSA_get_ex_new_index(), RSA_set_ex_data() and RSA_get_ex_data() are | ||
120 | available since SSLeay 0.9.0. | ||
121 | |||
122 | =cut | ||
diff --git a/src/lib/libcrypto/doc/RSA_new.pod b/src/lib/libcrypto/doc/RSA_new.pod new file mode 100644 index 0000000000..f16490ea6a --- /dev/null +++ b/src/lib/libcrypto/doc/RSA_new.pod | |||
@@ -0,0 +1,38 @@ | |||
1 | =pod | ||
2 | |||
3 | =head1 NAME | ||
4 | |||
5 | RSA_new, RSA_free - allocate and free RSA objects | ||
6 | |||
7 | =head1 SYNOPSIS | ||
8 | |||
9 | #include <openssl/rsa.h> | ||
10 | |||
11 | RSA * RSA_new(void); | ||
12 | |||
13 | void RSA_free(RSA *rsa); | ||
14 | |||
15 | =head1 DESCRIPTION | ||
16 | |||
17 | RSA_new() allocates and initializes an B<RSA> structure. | ||
18 | |||
19 | RSA_free() frees the B<RSA> structure and its components. The key is | ||
20 | erased before the memory is returned to the system. | ||
21 | |||
22 | =head1 RETURN VALUES | ||
23 | |||
24 | If the allocation fails, RSA_new() returns B<NULL> and sets an error | ||
25 | code that can be obtained by L<ERR_get_error(3)|ERR_get_error(3)>. Otherwise it returns | ||
26 | a pointer to the newly allocated structure. | ||
27 | |||
28 | RSA_free() returns no value. | ||
29 | |||
30 | =head1 SEE ALSO | ||
31 | |||
32 | L<err(3)|err(3)>, L<rsa(3)|rsa(3)>, L<RSA_generate_key(3)|RSA_generate_key(3)> | ||
33 | |||
34 | =head1 HISTORY | ||
35 | |||
36 | RSA_new() and RSA_free() are available in all versions of SSLeay and OpenSSL. | ||
37 | |||
38 | =cut | ||
diff --git a/src/lib/libcrypto/doc/RSA_padding_add_PKCS1_type_1.pod b/src/lib/libcrypto/doc/RSA_padding_add_PKCS1_type_1.pod new file mode 100644 index 0000000000..b8f678fe72 --- /dev/null +++ b/src/lib/libcrypto/doc/RSA_padding_add_PKCS1_type_1.pod | |||
@@ -0,0 +1,124 @@ | |||
1 | =pod | ||
2 | |||
3 | =head1 NAME | ||
4 | |||
5 | RSA_padding_add_PKCS1_type_1, RSA_padding_check_PKCS1_type_1, | ||
6 | RSA_padding_add_PKCS1_type_2, RSA_padding_check_PKCS1_type_2, | ||
7 | RSA_padding_add_PKCS1_OAEP, RSA_padding_check_PKCS1_OAEP, | ||
8 | RSA_padding_add_SSLv23, RSA_padding_check_SSLv23, | ||
9 | RSA_padding_add_none, RSA_padding_check_none - asymmetric encryption | ||
10 | padding | ||
11 | |||
12 | =head1 SYNOPSIS | ||
13 | |||
14 | #include <openssl/rsa.h> | ||
15 | |||
16 | int RSA_padding_add_PKCS1_type_1(unsigned char *to, int tlen, | ||
17 | unsigned char *f, int fl); | ||
18 | |||
19 | int RSA_padding_check_PKCS1_type_1(unsigned char *to, int tlen, | ||
20 | unsigned char *f, int fl, int rsa_len); | ||
21 | |||
22 | int RSA_padding_add_PKCS1_type_2(unsigned char *to, int tlen, | ||
23 | unsigned char *f, int fl); | ||
24 | |||
25 | int RSA_padding_check_PKCS1_type_2(unsigned char *to, int tlen, | ||
26 | unsigned char *f, int fl, int rsa_len); | ||
27 | |||
28 | int RSA_padding_add_PKCS1_OAEP(unsigned char *to, int tlen, | ||
29 | unsigned char *f, int fl, unsigned char *p, int pl); | ||
30 | |||
31 | int RSA_padding_check_PKCS1_OAEP(unsigned char *to, int tlen, | ||
32 | unsigned char *f, int fl, int rsa_len, unsigned char *p, int pl); | ||
33 | |||
34 | int RSA_padding_add_SSLv23(unsigned char *to, int tlen, | ||
35 | unsigned char *f, int fl); | ||
36 | |||
37 | int RSA_padding_check_SSLv23(unsigned char *to, int tlen, | ||
38 | unsigned char *f, int fl, int rsa_len); | ||
39 | |||
40 | int RSA_padding_add_none(unsigned char *to, int tlen, | ||
41 | unsigned char *f, int fl); | ||
42 | |||
43 | int RSA_padding_check_none(unsigned char *to, int tlen, | ||
44 | unsigned char *f, int fl, int rsa_len); | ||
45 | |||
46 | =head1 DESCRIPTION | ||
47 | |||
48 | The RSA_padding_xxx_xxx() functions are called from the RSA encrypt, | ||
49 | decrypt, sign and verify functions. Normally they should not be called | ||
50 | from application programs. | ||
51 | |||
52 | However, they can also be called directly to implement padding for other | ||
53 | asymmetric ciphers. RSA_padding_add_PKCS1_OAEP() and | ||
54 | RSA_padding_check_PKCS1_OAEP() may be used in an application combined | ||
55 | with B<RSA_NO_PADDING> in order to implement OAEP with an encoding | ||
56 | parameter. | ||
57 | |||
58 | RSA_padding_add_xxx() encodes B<fl> bytes from B<f> so as to fit into | ||
59 | B<tlen> bytes and stores the result at B<to>. An error occurs if B<fl> | ||
60 | does not meet the size requirements of the encoding method. | ||
61 | |||
62 | The following encoding methods are implemented: | ||
63 | |||
64 | =over 4 | ||
65 | |||
66 | =item PKCS1_type_1 | ||
67 | |||
68 | PKCS #1 v2.0 EMSA-PKCS1-v1_5 (PKCS #1 v1.5 block type 1); used for signatures | ||
69 | |||
70 | =item PKCS1_type_2 | ||
71 | |||
72 | PKCS #1 v2.0 EME-PKCS1-v1_5 (PKCS #1 v1.5 block type 2) | ||
73 | |||
74 | =item PKCS1_OAEP | ||
75 | |||
76 | PKCS #1 v2.0 EME-OAEP | ||
77 | |||
78 | =item SSLv23 | ||
79 | |||
80 | PKCS #1 EME-PKCS1-v1_5 with SSL-specific modification | ||
81 | |||
82 | =item none | ||
83 | |||
84 | simply copy the data | ||
85 | |||
86 | =back | ||
87 | |||
88 | The random number generator must be seeded prior to calling | ||
89 | RSA_padding_add_xxx(). | ||
90 | |||
91 | RSA_padding_check_xxx() verifies that the B<fl> bytes at B<f> contain | ||
92 | a valid encoding for a B<rsa_len> byte RSA key in the respective | ||
93 | encoding method and stores the recovered data of at most B<tlen> bytes | ||
94 | (for B<RSA_NO_PADDING>: of size B<tlen>) | ||
95 | at B<to>. | ||
96 | |||
97 | For RSA_padding_xxx_OAEP(), B<p> points to the encoding parameter | ||
98 | of length B<pl>. B<p> may be B<NULL> if B<pl> is 0. | ||
99 | |||
100 | =head1 RETURN VALUES | ||
101 | |||
102 | The RSA_padding_add_xxx() functions return 1 on success, 0 on error. | ||
103 | The RSA_padding_check_xxx() functions return the length of the | ||
104 | recovered data, -1 on error. Error codes can be obtained by calling | ||
105 | L<ERR_get_error(3)|ERR_get_error(3)>. | ||
106 | |||
107 | =head1 SEE ALSO | ||
108 | |||
109 | L<RSA_public_encrypt(3)|RSA_public_encrypt(3)>, | ||
110 | L<RSA_private_decrypt(3)|RSA_private_decrypt(3)>, | ||
111 | L<RSA_sign(3)|RSA_sign(3)>, L<RSA_verify(3)|RSA_verify(3)> | ||
112 | |||
113 | =head1 HISTORY | ||
114 | |||
115 | RSA_padding_add_PKCS1_type_1(), RSA_padding_check_PKCS1_type_1(), | ||
116 | RSA_padding_add_PKCS1_type_2(), RSA_padding_check_PKCS1_type_2(), | ||
117 | RSA_padding_add_SSLv23(), RSA_padding_check_SSLv23(), | ||
118 | RSA_padding_add_none() and RSA_padding_check_none() appeared in | ||
119 | SSLeay 0.9.0. | ||
120 | |||
121 | RSA_padding_add_PKCS1_OAEP() and RSA_padding_check_PKCS1_OAEP() were | ||
122 | added in OpenSSL 0.9.2b. | ||
123 | |||
124 | =cut | ||
diff --git a/src/lib/libcrypto/doc/RSA_print.pod b/src/lib/libcrypto/doc/RSA_print.pod new file mode 100644 index 0000000000..dd968a5274 --- /dev/null +++ b/src/lib/libcrypto/doc/RSA_print.pod | |||
@@ -0,0 +1,48 @@ | |||
1 | =pod | ||
2 | |||
3 | =head1 NAME | ||
4 | |||
5 | RSA_print, RSA_print_fp, DHparams_print, DHparams_print_fp - print | ||
6 | cryptographic parameters | ||
7 | |||
8 | =head1 SYNOPSIS | ||
9 | |||
10 | #include <openssl/rsa.h> | ||
11 | |||
12 | int RSA_print(BIO *bp, RSA *x, int offset); | ||
13 | int RSA_print_fp(FILE *fp, RSA *x, int offset); | ||
14 | |||
15 | #include <openssl/dsa.h> | ||
16 | |||
17 | int DSAparams_print(BIO *bp, DSA *x); | ||
18 | int DSAparams_print_fp(FILE *fp, DSA *x); | ||
19 | int DSA_print(BIO *bp, DSA *x, int offset); | ||
20 | int DSA_print_fp(FILE *fp, DSA *x, int offset); | ||
21 | |||
22 | #include <openssl/dh.h> | ||
23 | |||
24 | int DHparams_print(BIO *bp, DH *x); | ||
25 | int DHparams_print_fp(FILE *fp, DH *x); | ||
26 | |||
27 | =head1 DESCRIPTION | ||
28 | |||
29 | A human-readable hexadecimal output of the components of the RSA | ||
30 | key, DSA parameters or key or DH parameters is printed to B<bp> or B<fp>. | ||
31 | |||
32 | The output lines are indented by B<offset> spaces. | ||
33 | |||
34 | =head1 RETURN VALUES | ||
35 | |||
36 | These functions return 1 on success, 0 on error. | ||
37 | |||
38 | =head1 SEE ALSO | ||
39 | |||
40 | L<dh(3)|dh(3)>, L<dsa(3)|dsa(3)>, L<rsa(3)|rsa(3)>, L<BN_bn2bin(3)|BN_bn2bin(3)> | ||
41 | |||
42 | =head1 HISTORY | ||
43 | |||
44 | RSA_print(), RSA_print_fp(), DSA_print(), DSA_print_fp(), DH_print(), | ||
45 | DH_print_fp() are available in all versions of SSLeay and OpenSSL. | ||
46 | DSAparams_print() and DSAparams_print_pf() were added in SSLeay 0.8. | ||
47 | |||
48 | =cut | ||
diff --git a/src/lib/libcrypto/doc/RSA_private_encrypt.pod b/src/lib/libcrypto/doc/RSA_private_encrypt.pod new file mode 100644 index 0000000000..6861a98a10 --- /dev/null +++ b/src/lib/libcrypto/doc/RSA_private_encrypt.pod | |||
@@ -0,0 +1,69 @@ | |||
1 | =pod | ||
2 | |||
3 | =head1 NAME | ||
4 | |||
5 | RSA_private_encrypt, RSA_public_decrypt - low level signature operations | ||
6 | |||
7 | =head1 SYNOPSIS | ||
8 | |||
9 | #include <openssl/rsa.h> | ||
10 | |||
11 | int RSA_private_encrypt(int flen, unsigned char *from, | ||
12 | unsigned char *to, RSA *rsa, int padding); | ||
13 | |||
14 | int RSA_public_decrypt(int flen, unsigned char *from, | ||
15 | unsigned char *to, RSA *rsa, int padding); | ||
16 | |||
17 | =head1 DESCRIPTION | ||
18 | |||
19 | These functions handle RSA signatures at a low level. | ||
20 | |||
21 | RSA_private_encrypt() signs the B<flen> bytes at B<from> (usually a | ||
22 | message digest with an algorithm identifier) using the private key | ||
23 | B<rsa> and stores the signature in B<to>. B<to> must point to | ||
24 | B<RSA_size(rsa)> bytes of memory. | ||
25 | |||
26 | B<padding> denotes one of the following modes: | ||
27 | |||
28 | =over 4 | ||
29 | |||
30 | =item RSA_PKCS1_PADDING | ||
31 | |||
32 | PKCS #1 v1.5 padding. This function does not handle the | ||
33 | B<algorithmIdentifier> specified in PKCS #1. When generating or | ||
34 | verifying PKCS #1 signatures, L<RSA_sign(3)|RSA_sign(3)> and L<RSA_verify(3)|RSA_verify(3)> should be | ||
35 | used. | ||
36 | |||
37 | =item RSA_NO_PADDING | ||
38 | |||
39 | Raw RSA signature. This mode should I<only> be used to implement | ||
40 | cryptographically sound padding modes in the application code. | ||
41 | Signing user data directly with RSA is insecure. | ||
42 | |||
43 | =back | ||
44 | |||
45 | RSA_public_decrypt() recovers the message digest from the B<flen> | ||
46 | bytes long signature at B<from> using the signer's public key | ||
47 | B<rsa>. B<to> must point to a memory section large enough to hold the | ||
48 | message digest (which is smaller than B<RSA_size(rsa) - | ||
49 | 11>). B<padding> is the padding mode that was used to sign the data. | ||
50 | |||
51 | =head1 RETURN VALUES | ||
52 | |||
53 | RSA_private_encrypt() returns the size of the signature (i.e., | ||
54 | RSA_size(rsa)). RSA_public_decrypt() returns the size of the | ||
55 | recovered message digest. | ||
56 | |||
57 | On error, -1 is returned; the error codes can be | ||
58 | obtained by L<ERR_get_error(3)|ERR_get_error(3)>. | ||
59 | |||
60 | =head1 SEE ALSO | ||
61 | |||
62 | L<err(3)|err(3)>, L<rsa(3)|rsa(3)>, L<RSA_sign(3)|RSA_sign(3)>, L<RSA_verify(3)|RSA_verify(3)> | ||
63 | |||
64 | =head1 HISTORY | ||
65 | |||
66 | The B<padding> argument was added in SSLeay 0.8. RSA_NO_PADDING is | ||
67 | available since SSLeay 0.9.0. | ||
68 | |||
69 | =cut | ||
diff --git a/src/lib/libcrypto/doc/RSA_public_encrypt.pod b/src/lib/libcrypto/doc/RSA_public_encrypt.pod new file mode 100644 index 0000000000..910c4752b8 --- /dev/null +++ b/src/lib/libcrypto/doc/RSA_public_encrypt.pod | |||
@@ -0,0 +1,86 @@ | |||
1 | =pod | ||
2 | |||
3 | =head1 NAME | ||
4 | |||
5 | RSA_public_encrypt, RSA_private_decrypt - RSA public key cryptography | ||
6 | |||
7 | =head1 SYNOPSIS | ||
8 | |||
9 | #include <openssl/rsa.h> | ||
10 | |||
11 | int RSA_public_encrypt(int flen, unsigned char *from, | ||
12 | unsigned char *to, RSA *rsa, int padding); | ||
13 | |||
14 | int RSA_private_decrypt(int flen, unsigned char *from, | ||
15 | unsigned char *to, RSA *rsa, int padding); | ||
16 | |||
17 | =head1 DESCRIPTION | ||
18 | |||
19 | RSA_public_encrypt() encrypts the B<flen> bytes at B<from> (usually a | ||
20 | session key) using the public key B<rsa> and stores the ciphertext in | ||
21 | B<to>. B<to> must point to RSA_size(B<rsa>) bytes of memory. | ||
22 | |||
23 | B<padding> denotes one of the following modes: | ||
24 | |||
25 | =over 4 | ||
26 | |||
27 | =item RSA_PKCS1_PADDING | ||
28 | |||
29 | PKCS #1 v1.5 padding. This currently is the most widely used mode. | ||
30 | |||
31 | =item RSA_PKCS1_OAEP_PADDING | ||
32 | |||
33 | EME-OAEP as defined in PKCS #1 v2.0 with SHA-1, MGF1 and an empty | ||
34 | encoding parameter. This mode is recommended for all new applications. | ||
35 | |||
36 | =item RSA_SSLV23_PADDING | ||
37 | |||
38 | PKCS #1 v1.5 padding with an SSL-specific modification that denotes | ||
39 | that the server is SSL3 capable. | ||
40 | |||
41 | =item RSA_NO_PADDING | ||
42 | |||
43 | Raw RSA encryption. This mode should I<only> be used to implement | ||
44 | cryptographically sound padding modes in the application code. | ||
45 | Encrypting user data directly with RSA is insecure. | ||
46 | |||
47 | =back | ||
48 | |||
49 | B<flen> must be less than RSA_size(B<rsa>) - 11 for the PKCS #1 v1.5 | ||
50 | based padding modes, and less than RSA_size(B<rsa>) - 21 for | ||
51 | RSA_PKCS1_OAEP_PADDING. The random number generator must be seeded | ||
52 | prior to calling RSA_public_encrypt(). | ||
53 | |||
54 | RSA_private_decrypt() decrypts the B<flen> bytes at B<from> using the | ||
55 | private key B<rsa> and stores the plaintext in B<to>. B<to> must point | ||
56 | to a memory section large enough to hold the decrypted data (which is | ||
57 | smaller than RSA_size(B<rsa>)). B<padding> is the padding mode that | ||
58 | was used to encrypt the data. | ||
59 | |||
60 | =head1 RETURN VALUES | ||
61 | |||
62 | RSA_public_encrypt() returns the size of the encrypted data (i.e., | ||
63 | RSA_size(B<rsa>)). RSA_private_decrypt() returns the size of the | ||
64 | recovered plaintext. | ||
65 | |||
66 | On error, -1 is returned; the error codes can be | ||
67 | obtained by L<ERR_get_error(3)|ERR_get_error(3)>. | ||
68 | |||
69 | =head1 CONFORMING TO | ||
70 | |||
71 | SSL, PKCS #1 v2.0 | ||
72 | |||
73 | =head1 SEE ALSO | ||
74 | |||
75 | L<err(3)|err(3)>, L<rand(3)|rand(3)>, L<rsa(3)|rsa(3)>, L<RSA_size(3)|RSA_size(3)> | ||
76 | |||
77 | =head1 NOTES | ||
78 | |||
79 | The L<RSA_PKCS1_RSAref(3)|RSA_PKCS1_RSAref(3)> method supports only the RSA_PKCS1_PADDING mode. | ||
80 | |||
81 | =head1 HISTORY | ||
82 | |||
83 | The B<padding> argument was added in SSLeay 0.8. RSA_NO_PADDING is | ||
84 | available since SSLeay 0.9.0, OAEP was added in OpenSSL 0.9.2b. | ||
85 | |||
86 | =cut | ||
diff --git a/src/lib/libcrypto/doc/RSA_set_method.pod b/src/lib/libcrypto/doc/RSA_set_method.pod new file mode 100644 index 0000000000..deb1183a23 --- /dev/null +++ b/src/lib/libcrypto/doc/RSA_set_method.pod | |||
@@ -0,0 +1,153 @@ | |||
1 | =pod | ||
2 | |||
3 | =head1 NAME | ||
4 | |||
5 | RSA_set_default_method, RSA_get_default_method, RSA_set_method, | ||
6 | RSA_get_method, RSA_PKCS1_SSLeay, RSA_PKCS1_RSAref, | ||
7 | RSA_PKCS1_null_method, RSA_flags, RSA_new_method - select RSA method | ||
8 | |||
9 | =head1 SYNOPSIS | ||
10 | |||
11 | #include <openssl/rsa.h> | ||
12 | |||
13 | void RSA_set_default_method(RSA_METHOD *meth); | ||
14 | |||
15 | RSA_METHOD *RSA_get_default_method(void); | ||
16 | |||
17 | RSA_METHOD *RSA_set_method(RSA *rsa, RSA_METHOD *meth); | ||
18 | |||
19 | RSA_METHOD *RSA_get_method(RSA *rsa); | ||
20 | |||
21 | RSA_METHOD *RSA_PKCS1_SSLeay(void); | ||
22 | |||
23 | RSA_METHOD *RSA_PKCS1_RSAref(void); | ||
24 | |||
25 | RSA_METHOD *RSA_null_method(void); | ||
26 | |||
27 | int RSA_flags(RSA *rsa); | ||
28 | |||
29 | RSA *RSA_new_method(RSA_METHOD *method); | ||
30 | |||
31 | =head1 DESCRIPTION | ||
32 | |||
33 | An B<RSA_METHOD> specifies the functions that OpenSSL uses for RSA | ||
34 | operations. By modifying the method, alternative implementations | ||
35 | such as hardware accelerators may be used. | ||
36 | |||
37 | Initially, the default is to use the OpenSSL internal implementation, | ||
38 | unless OpenSSL was configured with the C<rsaref> or C<-DRSA_NULL> | ||
39 | options. RSA_PKCS1_SSLeay() returns a pointer to that method. | ||
40 | |||
41 | RSA_PKCS1_RSAref() returns a pointer to a method that uses the RSAref | ||
42 | library. This is the default method in the C<rsaref> configuration; | ||
43 | the function is not available in other configurations. | ||
44 | RSA_null_method() returns a pointer to a method that does not support | ||
45 | the RSA transformation. It is the default if OpenSSL is compiled with | ||
46 | C<-DRSA_NULL>. These methods may be useful in the USA because of a | ||
47 | patent on the RSA cryptosystem. | ||
48 | |||
49 | RSA_set_default_method() makes B<meth> the default method for all B<RSA> | ||
50 | structures created later. | ||
51 | |||
52 | RSA_get_default_method() returns a pointer to the current default | ||
53 | method. | ||
54 | |||
55 | RSA_set_method() selects B<meth> for all operations using the key | ||
56 | B<rsa>. | ||
57 | |||
58 | RSA_get_method() returns a pointer to the method currently selected | ||
59 | for B<rsa>. | ||
60 | |||
61 | RSA_flags() returns the B<flags> that are set for B<rsa>'s current method. | ||
62 | |||
63 | RSA_new_method() allocates and initializes an B<RSA> structure so that | ||
64 | B<method> will be used for the RSA operations. If B<method> is B<NULL>, | ||
65 | the default method is used. | ||
66 | |||
67 | =head1 THE RSA_METHOD STRUCTURE | ||
68 | |||
69 | typedef struct rsa_meth_st | ||
70 | { | ||
71 | /* name of the implementation */ | ||
72 | const char *name; | ||
73 | |||
74 | /* encrypt */ | ||
75 | int (*rsa_pub_enc)(int flen, unsigned char *from, | ||
76 | unsigned char *to, RSA *rsa, int padding); | ||
77 | |||
78 | /* verify arbitrary data */ | ||
79 | int (*rsa_pub_dec)(int flen, unsigned char *from, | ||
80 | unsigned char *to, RSA *rsa, int padding); | ||
81 | |||
82 | /* sign arbitrary data */ | ||
83 | int (*rsa_priv_enc)(int flen, unsigned char *from, | ||
84 | unsigned char *to, RSA *rsa, int padding); | ||
85 | |||
86 | /* decrypt */ | ||
87 | int (*rsa_priv_dec)(int flen, unsigned char *from, | ||
88 | unsigned char *to, RSA *rsa, int padding); | ||
89 | |||
90 | /* compute r0 = r0 ^ I mod rsa->n. May be NULL */ | ||
91 | int (*rsa_mod_exp)(BIGNUM *r0, BIGNUM *I, RSA *rsa); | ||
92 | |||
93 | /* compute r = a ^ p mod m. May be NULL */ | ||
94 | int (*bn_mod_exp)(BIGNUM *r, BIGNUM *a, const BIGNUM *p, | ||
95 | const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx); | ||
96 | |||
97 | /* called at RSA_new */ | ||
98 | int (*init)(RSA *rsa); | ||
99 | |||
100 | /* called at RSA_free */ | ||
101 | int (*finish)(RSA *rsa); | ||
102 | |||
103 | /* RSA_FLAG_EXT_PKEY - rsa_mod_exp is called for private key | ||
104 | * operations, even if p,q,dmp1,dmq1,iqmp | ||
105 | * are NULL | ||
106 | * RSA_FLAG_SIGN_VER - enable rsa_sign and rsa_verify | ||
107 | * RSA_METHOD_FLAG_NO_CHECK - don't check pub/private match | ||
108 | */ | ||
109 | int flags; | ||
110 | |||
111 | char *app_data; /* ?? */ | ||
112 | |||
113 | /* sign. For backward compatibility, this is used only | ||
114 | * if (flags & RSA_FLAG_SIGN_VER) | ||
115 | */ | ||
116 | int (*rsa_sign)(int type, unsigned char *m, unsigned int m_len, | ||
117 | unsigned char *sigret, unsigned int *siglen, RSA *rsa); | ||
118 | |||
119 | /* verify. For backward compatibility, this is used only | ||
120 | * if (flags & RSA_FLAG_SIGN_VER) | ||
121 | */ | ||
122 | int (*rsa_verify)(int type, unsigned char *m, unsigned int m_len, | ||
123 | unsigned char *sigbuf, unsigned int siglen, RSA *rsa); | ||
124 | |||
125 | } RSA_METHOD; | ||
126 | |||
127 | =head1 RETURN VALUES | ||
128 | |||
129 | RSA_PKCS1_SSLeay(), RSA_PKCS1_RSAref(), RSA_PKCS1_null_method(), | ||
130 | RSA_get_default_method() and RSA_get_method() return pointers to the | ||
131 | respective B<RSA_METHOD>s. | ||
132 | |||
133 | RSA_set_default_method() returns no value. | ||
134 | |||
135 | RSA_set_method() returns a pointer to the B<RSA_METHOD> previously | ||
136 | associated with B<rsa>. | ||
137 | |||
138 | RSA_new_method() returns B<NULL> and sets an error code that can be | ||
139 | obtained by L<ERR_get_error(3)|ERR_get_error(3)> if the allocation fails. Otherwise it | ||
140 | returns a pointer to the newly allocated structure. | ||
141 | |||
142 | =head1 SEE ALSO | ||
143 | |||
144 | L<rsa(3)|rsa(3)>, L<RSA_new(3)|RSA_new(3)> | ||
145 | |||
146 | =head1 HISTORY | ||
147 | |||
148 | RSA_new_method() and RSA_set_default_method() appeared in SSLeay 0.8. | ||
149 | RSA_get_default_method(), RSA_set_method() and RSA_get_method() as | ||
150 | well as the rsa_sign and rsa_verify components of RSA_METHOD were | ||
151 | added in OpenSSL 0.9.4. | ||
152 | |||
153 | =cut | ||
diff --git a/src/lib/libcrypto/doc/RSA_sign.pod b/src/lib/libcrypto/doc/RSA_sign.pod new file mode 100644 index 0000000000..f0bf6eea1b --- /dev/null +++ b/src/lib/libcrypto/doc/RSA_sign.pod | |||
@@ -0,0 +1,62 @@ | |||
1 | =pod | ||
2 | |||
3 | =head1 NAME | ||
4 | |||
5 | RSA_sign, RSA_verify - RSA signatures | ||
6 | |||
7 | =head1 SYNOPSIS | ||
8 | |||
9 | #include <openssl/rsa.h> | ||
10 | |||
11 | int RSA_sign(int type, unsigned char *m, unsigned int m_len, | ||
12 | unsigned char *sigret, unsigned int *siglen, RSA *rsa); | ||
13 | |||
14 | int RSA_verify(int type, unsigned char *m, unsigned int m_len, | ||
15 | unsigned char *sigbuf, unsigned int siglen, RSA *rsa); | ||
16 | |||
17 | =head1 DESCRIPTION | ||
18 | |||
19 | RSA_sign() signs the message digest B<m> of size B<m_len> using the | ||
20 | private key B<rsa> as specified in PKCS #1 v2.0. It stores the | ||
21 | signature in B<sigret> and the signature size in B<siglen>. B<sigret> | ||
22 | must point to RSA_size(B<rsa>) bytes of memory. | ||
23 | |||
24 | B<type> denotes the message digest algorithm that was used to generate | ||
25 | B<m>. It usually is one of B<NID_sha1>, B<NID_ripemd160> and B<NID_md5>; | ||
26 | see L<objects(3)|objects(3)> for details. If B<type> is B<NID_md5_sha1>, | ||
27 | an SSL signature (MD5 and SHA1 message digests with PKCS #1 padding | ||
28 | and no algorithm identifier) is created. | ||
29 | |||
30 | RSA_verify() verifies that the signature B<sigbuf> of size B<siglen> | ||
31 | matches a given message digest B<m> of size B<m_len>. B<type> denotes | ||
32 | the message digest algorithm that was used to generate the signature. | ||
33 | B<rsa> is the signer's public key. | ||
34 | |||
35 | =head1 RETURN VALUES | ||
36 | |||
37 | RSA_sign() returns 1 on success, 0 otherwise. RSA_verify() returns 1 | ||
38 | on successful verification, 0 otherwise. | ||
39 | |||
40 | The error codes can be obtained by L<ERR_get_error(3)|ERR_get_error(3)>. | ||
41 | |||
42 | =head1 BUGS | ||
43 | |||
44 | Certain signatures with an improper algorithm identifier are accepted | ||
45 | for compatibility with SSLeay 0.4.5 :-) | ||
46 | |||
47 | =head1 CONFORMING TO | ||
48 | |||
49 | SSL, PKCS #1 v2.0 | ||
50 | |||
51 | =head1 SEE ALSO | ||
52 | |||
53 | L<err(3)|err(3)>, L<objects(3)|objects(3)>, L<rsa(3)|rsa(3)>, | ||
54 | L<RSA_private_encrypt(3)|RSA_private_encrypt(3)>, | ||
55 | L<RSA_public_decrypt(3)|RSA_public_decrypt(3)> | ||
56 | |||
57 | =head1 HISTORY | ||
58 | |||
59 | RSA_sign() and RSA_verify() are available in all versions of SSLeay | ||
60 | and OpenSSL. | ||
61 | |||
62 | =cut | ||
diff --git a/src/lib/libcrypto/doc/RSA_sign_ASN1_OCTET_STRING.pod b/src/lib/libcrypto/doc/RSA_sign_ASN1_OCTET_STRING.pod new file mode 100644 index 0000000000..df9ceb339a --- /dev/null +++ b/src/lib/libcrypto/doc/RSA_sign_ASN1_OCTET_STRING.pod | |||
@@ -0,0 +1,59 @@ | |||
1 | =pod | ||
2 | |||
3 | =head1 NAME | ||
4 | |||
5 | RSA_sign_ASN1_OCTET_STRING, RSA_verify_ASN1_OCTET_STRING - RSA signatures | ||
6 | |||
7 | =head1 SYNOPSIS | ||
8 | |||
9 | #include <openssl/rsa.h> | ||
10 | |||
11 | int RSA_sign_ASN1_OCTET_STRING(int dummy, unsigned char *m, | ||
12 | unsigned int m_len, unsigned char *sigret, unsigned int *siglen, | ||
13 | RSA *rsa); | ||
14 | |||
15 | int RSA_verify_ASN1_OCTET_STRING(int dummy, unsigned char *m, | ||
16 | unsigned int m_len, unsigned char *sigbuf, unsigned int siglen, | ||
17 | RSA *rsa); | ||
18 | |||
19 | =head1 DESCRIPTION | ||
20 | |||
21 | RSA_sign_ASN1_OCTET_STRING() signs the octet string B<m> of size | ||
22 | B<m_len> using the private key B<rsa> represented in DER using PKCS #1 | ||
23 | padding. It stores the signature in B<sigret> and the signature size | ||
24 | in B<siglen>. B<sigret> must point to B<RSA_size(rsa)> bytes of | ||
25 | memory. | ||
26 | |||
27 | B<dummy> is ignored. | ||
28 | |||
29 | The random number generator must be seeded prior to calling RSA_sign_ASN1_OCTET_STRING(). | ||
30 | |||
31 | RSA_verify_ASN1_OCTET_STRING() verifies that the signature B<sigbuf> | ||
32 | of size B<siglen> is the DER representation of a given octet string | ||
33 | B<m> of size B<m_len>. B<dummy> is ignored. B<rsa> is the signer's | ||
34 | public key. | ||
35 | |||
36 | =head1 RETURN VALUES | ||
37 | |||
38 | RSA_sign_ASN1_OCTET_STRING() returns 1 on success, 0 otherwise. | ||
39 | RSA_verify_ASN1_OCTET_STRING() returns 1 on successful verification, 0 | ||
40 | otherwise. | ||
41 | |||
42 | The error codes can be obtained by L<ERR_get_error(3)|ERR_get_error(3)>. | ||
43 | |||
44 | =head1 BUGS | ||
45 | |||
46 | These functions serve no recognizable purpose. | ||
47 | |||
48 | =head1 SEE ALSO | ||
49 | |||
50 | L<err(3)|err(3)>, L<objects(3)|objects(3)>, L<rand(3)|rand(3)>, | ||
51 | L<rsa(3)|rsa(3)>, L<RSA_sign(3)|RSA_sign(3)>, | ||
52 | L<RSA_verify(3)|RSA_verify(3)> | ||
53 | |||
54 | =head1 HISTORY | ||
55 | |||
56 | RSA_sign_ASN1_OCTET_STRING() and RSA_verify_ASN1_OCTET_STRING() were | ||
57 | added in SSLeay 0.8. | ||
58 | |||
59 | =cut | ||
diff --git a/src/lib/libcrypto/doc/RSA_size.pod b/src/lib/libcrypto/doc/RSA_size.pod new file mode 100644 index 0000000000..b36b4d58d5 --- /dev/null +++ b/src/lib/libcrypto/doc/RSA_size.pod | |||
@@ -0,0 +1,33 @@ | |||
1 | =pod | ||
2 | |||
3 | =head1 NAME | ||
4 | |||
5 | RSA_size - get RSA modulus size | ||
6 | |||
7 | =head1 SYNOPSIS | ||
8 | |||
9 | #include <openssl/rsa.h> | ||
10 | |||
11 | int RSA_size(RSA *rsa); | ||
12 | |||
13 | =head1 DESCRIPTION | ||
14 | |||
15 | This function returns the RSA modulus size in bytes. It can be used to | ||
16 | determine how much memory must be allocated for an RSA encrypted | ||
17 | value. | ||
18 | |||
19 | B<rsa-E<gt>n> must not be B<NULL>. | ||
20 | |||
21 | =head1 RETURN VALUE | ||
22 | |||
23 | The size in bytes. | ||
24 | |||
25 | =head1 SEE ALSO | ||
26 | |||
27 | L<rsa(3)|rsa(3)> | ||
28 | |||
29 | =head1 HISTORY | ||
30 | |||
31 | RSA_size() is available in all versions of SSLeay and OpenSSL. | ||
32 | |||
33 | =cut | ||
diff --git a/src/lib/libcrypto/doc/bn.pod b/src/lib/libcrypto/doc/bn.pod new file mode 100644 index 0000000000..1504a1c92d --- /dev/null +++ b/src/lib/libcrypto/doc/bn.pod | |||
@@ -0,0 +1,148 @@ | |||
1 | =pod | ||
2 | |||
3 | =head1 NAME | ||
4 | |||
5 | bn - multiprecision integer arithmetics | ||
6 | |||
7 | =head1 SYNOPSIS | ||
8 | |||
9 | #include <openssl/bn.h> | ||
10 | |||
11 | BIGNUM *BN_new(void); | ||
12 | void BN_free(BIGNUM *a); | ||
13 | void BN_init(BIGNUM *); | ||
14 | void BN_clear(BIGNUM *a); | ||
15 | void BN_clear_free(BIGNUM *a); | ||
16 | |||
17 | BN_CTX *BN_CTX_new(void); | ||
18 | void BN_CTX_init(BN_CTX *c); | ||
19 | void BN_CTX_free(BN_CTX *c); | ||
20 | |||
21 | BIGNUM *BN_copy(BIGNUM *a, const BIGNUM *b); | ||
22 | BIGNUM *BN_dup(const BIGNUM *a); | ||
23 | |||
24 | int BN_num_bytes(const BIGNUM *a); | ||
25 | int BN_num_bits(const BIGNUM *a); | ||
26 | int BN_num_bits_word(BN_ULONG w); | ||
27 | |||
28 | int BN_add(BIGNUM *r, BIGNUM *a, BIGNUM *b); | ||
29 | int BN_sub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b); | ||
30 | int BN_mul(BIGNUM *r, BIGNUM *a, BIGNUM *b, BN_CTX *ctx); | ||
31 | int BN_div(BIGNUM *dv, BIGNUM *rem, const BIGNUM *a, const BIGNUM *d, | ||
32 | BN_CTX *ctx); | ||
33 | int BN_sqr(BIGNUM *r, BIGNUM *a, BN_CTX *ctx); | ||
34 | int BN_mod(BIGNUM *rem, const BIGNUM *a, const BIGNUM *m, BN_CTX *ctx); | ||
35 | int BN_mod_mul(BIGNUM *ret, BIGNUM *a, BIGNUM *b, const BIGNUM *m, | ||
36 | BN_CTX *ctx); | ||
37 | int BN_exp(BIGNUM *r, BIGNUM *a, BIGNUM *p, BN_CTX *ctx); | ||
38 | int BN_mod_exp(BIGNUM *r, BIGNUM *a, const BIGNUM *p, | ||
39 | const BIGNUM *m, BN_CTX *ctx); | ||
40 | int BN_gcd(BIGNUM *r, BIGNUM *a, BIGNUM *b, BN_CTX *ctx); | ||
41 | |||
42 | int BN_add_word(BIGNUM *a, BN_ULONG w); | ||
43 | int BN_sub_word(BIGNUM *a, BN_ULONG w); | ||
44 | int BN_mul_word(BIGNUM *a, BN_ULONG w); | ||
45 | BN_ULONG BN_div_word(BIGNUM *a, BN_ULONG w); | ||
46 | BN_ULONG BN_mod_word(const BIGNUM *a, BN_ULONG w); | ||
47 | |||
48 | int BN_cmp(BIGNUM *a, BIGNUM *b); | ||
49 | int BN_ucmp(BIGNUM *a, BIGNUM *b); | ||
50 | int BN_is_zero(BIGNUM *a); | ||
51 | int BN_is_one(BIGNUM *a); | ||
52 | int BN_is_word(BIGNUM *a, BN_ULONG w); | ||
53 | int BN_is_odd(BIGNUM *a); | ||
54 | |||
55 | int BN_zero(BIGNUM *a); | ||
56 | int BN_one(BIGNUM *a); | ||
57 | BIGNUM *BN_value_one(void); | ||
58 | int BN_set_word(BIGNUM *a, unsigned long w); | ||
59 | unsigned long BN_get_word(BIGNUM *a); | ||
60 | |||
61 | int BN_rand(BIGNUM *rnd, int bits, int top, int bottom); | ||
62 | int BN_pseudo_rand(BIGNUM *rnd, int bits, int top, int bottom); | ||
63 | |||
64 | BIGNUM *BN_generate_prime(BIGNUM *ret, int bits,int safe, BIGNUM *add, | ||
65 | BIGNUM *rem, void (*callback)(int, int, void *), void *cb_arg); | ||
66 | int BN_is_prime(const BIGNUM *p, int nchecks, | ||
67 | void (*callback)(int, int, void *), BN_CTX *ctx, void *cb_arg); | ||
68 | |||
69 | int BN_set_bit(BIGNUM *a, int n); | ||
70 | int BN_clear_bit(BIGNUM *a, int n); | ||
71 | int BN_is_bit_set(const BIGNUM *a, int n); | ||
72 | int BN_mask_bits(BIGNUM *a, int n); | ||
73 | int BN_lshift(BIGNUM *r, const BIGNUM *a, int n); | ||
74 | int BN_lshift1(BIGNUM *r, BIGNUM *a); | ||
75 | int BN_rshift(BIGNUM *r, BIGNUM *a, int n); | ||
76 | int BN_rshift1(BIGNUM *r, BIGNUM *a); | ||
77 | |||
78 | int BN_bn2bin(const BIGNUM *a, unsigned char *to); | ||
79 | BIGNUM *BN_bin2bn(const unsigned char *s, int len, BIGNUM *ret); | ||
80 | char *BN_bn2hex(const BIGNUM *a); | ||
81 | char *BN_bn2dec(const BIGNUM *a); | ||
82 | int BN_hex2bn(BIGNUM **a, const char *str); | ||
83 | int BN_dec2bn(BIGNUM **a, const char *str); | ||
84 | int BN_print(BIO *fp, const BIGNUM *a); | ||
85 | int BN_print_fp(FILE *fp, const BIGNUM *a); | ||
86 | int BN_bn2mpi(const BIGNUM *a, unsigned char *to); | ||
87 | BIGNUM *BN_mpi2bn(unsigned char *s, int len, BIGNUM *ret); | ||
88 | |||
89 | BIGNUM *BN_mod_inverse(BIGNUM *r, BIGNUM *a, const BIGNUM *n, | ||
90 | BN_CTX *ctx); | ||
91 | |||
92 | BN_RECP_CTX *BN_RECP_CTX_new(void); | ||
93 | void BN_RECP_CTX_init(BN_RECP_CTX *recp); | ||
94 | void BN_RECP_CTX_free(BN_RECP_CTX *recp); | ||
95 | int BN_RECP_CTX_set(BN_RECP_CTX *recp, const BIGNUM *m, BN_CTX *ctx); | ||
96 | int BN_mod_mul_reciprocal(BIGNUM *r, BIGNUM *a, BIGNUM *b, | ||
97 | BN_RECP_CTX *recp, BN_CTX *ctx); | ||
98 | |||
99 | BN_MONT_CTX *BN_MONT_CTX_new(void); | ||
100 | void BN_MONT_CTX_init(BN_MONT_CTX *ctx); | ||
101 | void BN_MONT_CTX_free(BN_MONT_CTX *mont); | ||
102 | int BN_MONT_CTX_set(BN_MONT_CTX *mont, const BIGNUM *m, BN_CTX *ctx); | ||
103 | BN_MONT_CTX *BN_MONT_CTX_copy(BN_MONT_CTX *to, BN_MONT_CTX *from); | ||
104 | int BN_mod_mul_montgomery(BIGNUM *r, BIGNUM *a, BIGNUM *b, | ||
105 | BN_MONT_CTX *mont, BN_CTX *ctx); | ||
106 | int BN_from_montgomery(BIGNUM *r, BIGNUM *a, BN_MONT_CTX *mont, | ||
107 | BN_CTX *ctx); | ||
108 | int BN_to_montgomery(BIGNUM *r, BIGNUM *a, BN_MONT_CTX *mont, | ||
109 | BN_CTX *ctx); | ||
110 | |||
111 | |||
112 | =head1 DESCRIPTION | ||
113 | |||
114 | This library performs arithmetic operations on integers of arbitrary | ||
115 | size. It was written for use in public key cryptography, such as RSA | ||
116 | and Diffie-Hellman. | ||
117 | |||
118 | It uses dynamic memory allocation for storing its data structures. | ||
119 | That means that there is no limit on the size of the numbers | ||
120 | manipulated by these functions, but return values must always be | ||
121 | checked in case a memory allocation error has occurred. | ||
122 | |||
123 | The basic object in this library is a B<BIGNUM>. It is used to hold a | ||
124 | single large integer. This type should be considered opaque and fields | ||
125 | should not be modified or accessed directly. | ||
126 | |||
127 | The creation of B<BIGNUM> objects is described in L<BN_new(3)|BN_new(3)>; | ||
128 | L<BN_add(3)|BN_add(3)> describes most of the arithmetic operations. | ||
129 | Comparison is described in L<BN_cmp(3)|BN_cmp(3)>; L<BN_zero(3)|BN_zero(3)> | ||
130 | describes certain assignments, L<BN_rand(3)|BN_rand(3)> the generation of | ||
131 | random numbers, L<BN_generate_prime(3)|BN_generate_prime(3)> deals with prime | ||
132 | numbers and L<BN_set_bit(3)|BN_set_bit(3)> with bit operations. The conversion | ||
133 | of B<BIGNUM>s to external formats is described in L<BN_bn2bin(3)|BN_bn2bin(3)>. | ||
134 | |||
135 | =head1 SEE ALSO | ||
136 | |||
137 | L<bn_internal(3)|bn_internal(3)>, | ||
138 | L<dh(3)|dh(3)>, L<err(3)|err(3)>, L<rand(3)|rand(3)>, L<rsa(3)|rsa(3)>, | ||
139 | L<BN_new(3)|BN_new(3)>, L<BN_CTX_new(3)|BN_CTX_new(3)>, | ||
140 | L<BN_copy(3)|BN_copy(3)>, L<BN_num_bytes(3)|BN_num_bytes(3)>, | ||
141 | L<BN_add(3)|BN_add(3)>, L<BN_add_word(3)|BN_add_word(3)>, | ||
142 | L<BN_cmp(3)|BN_cmp(3)>, L<BN_zero(3)|BN_zero(3)>, L<BN_rand(3)|BN_rand(3)>, | ||
143 | L<BN_generate_prime(3)|BN_generate_prime(3)>, L<BN_set_bit(3)|BN_set_bit(3)>, | ||
144 | L<BN_bn2bin(3)|BN_bn2bin(3)>, L<BN_mod_inverse(3)|BN_mod_inverse(3)>, | ||
145 | L<BN_mod_mul_reciprocal(3)|BN_mod_mul_reciprocal(3)>, | ||
146 | L<BN_mod_mul_montgomery(3)|BN_mod_mul_montgomery(3)> | ||
147 | |||
148 | =cut | ||
diff --git a/src/lib/libcrypto/doc/d2i_DHparams.pod b/src/lib/libcrypto/doc/d2i_DHparams.pod new file mode 100644 index 0000000000..a6d1743d39 --- /dev/null +++ b/src/lib/libcrypto/doc/d2i_DHparams.pod | |||
@@ -0,0 +1,30 @@ | |||
1 | =pod | ||
2 | |||
3 | =head1 NAME | ||
4 | |||
5 | d2i_DHparams, i2d_DHparams - ... | ||
6 | |||
7 | =head1 SYNOPSIS | ||
8 | |||
9 | #include <openssl/dh.h> | ||
10 | |||
11 | DH *d2i_DHparams(DH **a, unsigned char **pp, long length); | ||
12 | int i2d_DHparams(DH *a, unsigned char **pp); | ||
13 | |||
14 | =head1 DESCRIPTION | ||
15 | |||
16 | ... | ||
17 | |||
18 | =head1 RETURN VALUES | ||
19 | |||
20 | ... | ||
21 | |||
22 | =head1 SEE ALSO | ||
23 | |||
24 | ... | ||
25 | |||
26 | =head1 HISTORY | ||
27 | |||
28 | ... | ||
29 | |||
30 | =cut | ||
diff --git a/src/lib/libcrypto/doc/d2i_RSAPublicKey.pod b/src/lib/libcrypto/doc/d2i_RSAPublicKey.pod new file mode 100644 index 0000000000..ff4d0d57db --- /dev/null +++ b/src/lib/libcrypto/doc/d2i_RSAPublicKey.pod | |||
@@ -0,0 +1,39 @@ | |||
1 | =pod | ||
2 | |||
3 | =head1 NAME | ||
4 | |||
5 | d2i_RSAPublicKey, i2d_RSAPublicKey, d2i_RSAPrivateKey, i2d_RSAPrivateKey, i2d_Netscape_RSA, d2i_Netscape_RSA - ... | ||
6 | |||
7 | =head1 SYNOPSIS | ||
8 | |||
9 | #include <openssl/rsa.h> | ||
10 | |||
11 | RSA * d2i_RSAPublicKey(RSA **a, unsigned char **pp, long length); | ||
12 | |||
13 | int i2d_RSAPublicKey(RSA *a, unsigned char **pp); | ||
14 | |||
15 | RSA * d2i_RSAPrivateKey(RSA **a, unsigned char **pp, long length); | ||
16 | |||
17 | int i2d_RSAPrivateKey(RSA *a, unsigned char **pp); | ||
18 | |||
19 | int i2d_Netscape_RSA(RSA *a, unsigned char **pp, int (*cb)()); | ||
20 | |||
21 | RSA * d2i_Netscape_RSA(RSA **a, unsigned char **pp, long length, int (*cb)()); | ||
22 | |||
23 | =head1 DESCRIPTION | ||
24 | |||
25 | ... | ||
26 | |||
27 | =head1 RETURN VALUES | ||
28 | |||
29 | ... | ||
30 | |||
31 | =head1 SEE ALSO | ||
32 | |||
33 | ... | ||
34 | |||
35 | =head1 HISTORY | ||
36 | |||
37 | ... | ||
38 | |||
39 | =cut | ||
diff --git a/src/lib/libcrypto/doc/dh.pod b/src/lib/libcrypto/doc/dh.pod new file mode 100644 index 0000000000..0a9b7c03a2 --- /dev/null +++ b/src/lib/libcrypto/doc/dh.pod | |||
@@ -0,0 +1,68 @@ | |||
1 | =pod | ||
2 | |||
3 | =head1 NAME | ||
4 | |||
5 | dh - Diffie-Hellman key agreement | ||
6 | |||
7 | =head1 SYNOPSIS | ||
8 | |||
9 | #include <openssl/dh.h> | ||
10 | |||
11 | DH * DH_new(void); | ||
12 | void DH_free(DH *dh); | ||
13 | |||
14 | int DH_size(DH *dh); | ||
15 | |||
16 | DH * DH_generate_parameters(int prime_len, int generator, | ||
17 | void (*callback)(int, int, void *), void *cb_arg); | ||
18 | int DH_check(DH *dh, int *codes); | ||
19 | |||
20 | int DH_generate_key(DH *dh); | ||
21 | int DH_compute_key(unsigned char *key, BIGNUM *pub_key, DH *dh); | ||
22 | |||
23 | void DH_set_default_method(DH_METHOD *meth); | ||
24 | DH_METHOD *DH_get_default_method(void); | ||
25 | DH_METHOD *DH_set_method(DH *dh, DH_METHOD *meth); | ||
26 | DH *DH_new_method(DH_METHOD *meth); | ||
27 | DH_METHOD *DH_OpenSSL(void); | ||
28 | |||
29 | int DH_get_ex_new_index(long argl, char *argp, int (*new_func)(), | ||
30 | int (*dup_func)(), void (*free_func)()); | ||
31 | int DH_set_ex_data(DH *d, int idx, char *arg); | ||
32 | char *DH_get_ex_data(DH *d, int idx); | ||
33 | |||
34 | DH * d2i_DHparams(DH **a, unsigned char **pp, long length); | ||
35 | int i2d_DHparams(DH *a, unsigned char **pp); | ||
36 | |||
37 | int DHparams_print_fp(FILE *fp, DH *x); | ||
38 | int DHparams_print(BIO *bp, DH *x); | ||
39 | |||
40 | =head1 DESCRIPTION | ||
41 | |||
42 | These functions implement the Diffie-Hellman key agreement protocol. | ||
43 | The generation of shared DH parameters is described in | ||
44 | L<DH_generate_parameters(3)|DH_generate_parameters(3)>; L<DH_generate_key(3)|DH_generate_key(3)> describes how | ||
45 | to perform a key agreement. | ||
46 | |||
47 | The B<DH> structure consists of several BIGNUM components. | ||
48 | |||
49 | struct | ||
50 | { | ||
51 | BIGNUM *p; // prime number (shared) | ||
52 | BIGNUM *g; // generator of Z_p (shared) | ||
53 | BIGNUM *priv_key; // private DH value x | ||
54 | BIGNUM *pub_key; // public DH value g^x | ||
55 | // ... | ||
56 | }; | ||
57 | DH | ||
58 | |||
59 | =head1 SEE ALSO | ||
60 | |||
61 | L<dhparam(1)|dhparam(1)>, L<bn(3)|bn(3)>, L<dsa(3)|dsa(3)>, L<err(3)|err(3)>, | ||
62 | L<rand(3)|rand(3)>, L<rsa(3)|rsa(3)>, L<DH_set_method(3)|DH_set_method(3)>, | ||
63 | L<DH_new(3)|DH_new(3)>, L<DH_get_ex_new_index(3)|DH_get_ex_new_index(3)>, | ||
64 | L<DH_generate_parameters(3)|DH_generate_parameters(3)>, | ||
65 | L<DH_compute_key(3)|DH_compute_key(3)>, L<d2i_DHparams(3)|d2i_DHparams(3)>, | ||
66 | L<RSA_print(3)|RSA_print(3)> | ||
67 | |||
68 | =cut | ||
diff --git a/src/lib/libcrypto/doc/dsa.pod b/src/lib/libcrypto/doc/dsa.pod new file mode 100644 index 0000000000..2c09244899 --- /dev/null +++ b/src/lib/libcrypto/doc/dsa.pod | |||
@@ -0,0 +1,104 @@ | |||
1 | =pod | ||
2 | |||
3 | =head1 NAME | ||
4 | |||
5 | dsa - Digital Signature Algorithm | ||
6 | |||
7 | =head1 SYNOPSIS | ||
8 | |||
9 | #include <openssl/dsa.h> | ||
10 | |||
11 | DSA * DSA_new(void); | ||
12 | void DSA_free(DSA *dsa); | ||
13 | |||
14 | int DSA_size(DSA *dsa); | ||
15 | |||
16 | DSA * DSA_generate_parameters(int bits, unsigned char *seed, | ||
17 | int seed_len, int *counter_ret, unsigned long *h_ret, | ||
18 | void (*callback)(int, int, void *), void *cb_arg); | ||
19 | |||
20 | DH * DSA_dup_DH(DSA *r); | ||
21 | |||
22 | int DSA_generate_key(DSA *dsa); | ||
23 | |||
24 | int DSA_sign(int dummy, const unsigned char *dgst, int len, | ||
25 | unsigned char *sigret, unsigned int *siglen, DSA *dsa); | ||
26 | int DSA_sign_setup(DSA *dsa, BN_CTX *ctx, BIGNUM **kinvp, | ||
27 | BIGNUM **rp); | ||
28 | int DSA_verify(int dummy, const unsigned char *dgst, int len, | ||
29 | unsigned char *sigbuf, int siglen, DSA *dsa); | ||
30 | |||
31 | void DSA_set_default_method(DSA_METHOD *meth); | ||
32 | DSA_METHOD *DSA_get_default_method(void); | ||
33 | DSA_METHOD *DSA_set_method(DSA *dsa, DSA_METHOD *meth); | ||
34 | DSA *DSA_new_method(DSA_METHOD *meth); | ||
35 | DSA_METHOD *DSA_OpenSSL(void); | ||
36 | |||
37 | int DSA_get_ex_new_index(long argl, char *argp, int (*new_func)(), | ||
38 | int (*dup_func)(), void (*free_func)()); | ||
39 | int DSA_set_ex_data(DSA *d, int idx, char *arg); | ||
40 | char *DSA_get_ex_data(DSA *d, int idx); | ||
41 | |||
42 | DSA_SIG *DSA_SIG_new(void); | ||
43 | void DSA_SIG_free(DSA_SIG *a); | ||
44 | int i2d_DSA_SIG(DSA_SIG *a, unsigned char **pp); | ||
45 | DSA_SIG *d2i_DSA_SIG(DSA_SIG **v, unsigned char **pp, long length); | ||
46 | |||
47 | DSA_SIG *DSA_do_sign(const unsigned char *dgst, int dlen, DSA *dsa); | ||
48 | int DSA_do_verify(const unsigned char *dgst, int dgst_len, | ||
49 | DSA_SIG *sig, DSA *dsa); | ||
50 | |||
51 | DSA * d2i_DSAPublicKey(DSA **a, unsigned char **pp, long length); | ||
52 | DSA * d2i_DSAPrivateKey(DSA **a, unsigned char **pp, long length); | ||
53 | DSA * d2i_DSAparams(DSA **a, unsigned char **pp, long length); | ||
54 | int i2d_DSAPublicKey(DSA *a, unsigned char **pp); | ||
55 | int i2d_DSAPrivateKey(DSA *a, unsigned char **pp); | ||
56 | int i2d_DSAparams(DSA *a,unsigned char **pp); | ||
57 | |||
58 | int DSAparams_print(BIO *bp, DSA *x); | ||
59 | int DSAparams_print_fp(FILE *fp, DSA *x); | ||
60 | int DSA_print(BIO *bp, DSA *x, int off); | ||
61 | int DSA_print_fp(FILE *bp, DSA *x, int off); | ||
62 | |||
63 | =head1 DESCRIPTION | ||
64 | |||
65 | These functions implement the Digital Signature Algorithm (DSA). The | ||
66 | generation of shared DSA parameters is described in | ||
67 | L<DSA_generate_parameters(3)|DSA_generate_parameters(3)>; | ||
68 | L<DSA_generate_key(3)|DSA_generate_key(3)> describes how to | ||
69 | generate a signature key. Signature generation and verification are | ||
70 | described in L<DSA_sign(3)|DSA_sign(3)>. | ||
71 | |||
72 | The B<DSA> structure consists of several BIGNUM components. | ||
73 | |||
74 | struct | ||
75 | { | ||
76 | BIGNUM *p; // prime number (public) | ||
77 | BIGNUM *q; // 160-bit subprime, q | p-1 (public) | ||
78 | BIGNUM *g; // generator of subgroup (public) | ||
79 | BIGNUM *priv_key; // private key x | ||
80 | BIGNUM *pub_key; // public key y = g^x | ||
81 | // ... | ||
82 | } | ||
83 | DSA; | ||
84 | |||
85 | In public keys, B<priv_key> is NULL. | ||
86 | |||
87 | =head1 CONFORMING TO | ||
88 | |||
89 | US Federal Information Processing Standard FIPS 186 (Digital Signature | ||
90 | Standard, DSS), ANSI X9.30 | ||
91 | |||
92 | =head1 SEE ALSO | ||
93 | |||
94 | L<bn(3)|bn(3)>, L<dh(3)|dh(3)>, L<err(3)|err(3)>, L<rand(3)|rand(3)>, | ||
95 | L<rsa(3)|rsa(3)>, L<sha(3)|sha(3)>, L<DSA_new(3)|DSA_new(3)>, | ||
96 | L<DSA_size(3)|DSA_size(3)>, | ||
97 | L<DSA_generate_parameters(3)|DSA_generate_parameters(3)>, | ||
98 | L<DSA_dup_DH(3)|DSA_dup_DH(3)>, | ||
99 | L<DSA_generate_key(3)|DSA_generate_key(3)>, | ||
100 | L<DSA_sign(3)|DSA_sign(3)>, L<DSA_set_method(3)|DSA_set_method(3)>, | ||
101 | L<DSA_get_ex_new_index(3)|DSA_get_ex_new_index(3)>, | ||
102 | L<RSA_print(3)|RSA_print(3)> | ||
103 | |||
104 | =cut | ||
diff --git a/src/lib/libcrypto/doc/evp.pod b/src/lib/libcrypto/doc/evp.pod new file mode 100644 index 0000000000..f089dd49a2 --- /dev/null +++ b/src/lib/libcrypto/doc/evp.pod | |||
@@ -0,0 +1,37 @@ | |||
1 | =pod | ||
2 | |||
3 | =head1 NAME | ||
4 | |||
5 | evp - high-level cryptographic functions | ||
6 | |||
7 | =head1 SYNOPSIS | ||
8 | |||
9 | #include <openssl/evp.h> | ||
10 | |||
11 | =head1 DESCRIPTION | ||
12 | |||
13 | The EVP library provided a high-level interface to cryptographic | ||
14 | functions. | ||
15 | |||
16 | B<EVP_Seal>I<...> and B<EVP_Open>I<...> provide public key encryption | ||
17 | and decryption to implement digital "envelopes". | ||
18 | |||
19 | The B<EVP_Sign>I<...> and B<EVP_Verify>I<...> functions implement | ||
20 | digital signatures. | ||
21 | |||
22 | Symmetric encryption is available with the B<EVP_Encrypt>I<...> | ||
23 | functions. The B<EVP_Digest>I<...> functions provide message digests. | ||
24 | |||
25 | Algorithms are loaded with OpenSSL_add_all_algorithms(3). | ||
26 | |||
27 | =head1 SEE ALSO | ||
28 | |||
29 | L<EVP_DigestInit(3)|EVP_DigestInit(3)>, | ||
30 | L<EVP_EncryptInit(3)|EVP_EncryptInit(3)>, | ||
31 | L<EVP_OpenInit(3)|EVP_OpenInit(3)>, | ||
32 | L<EVP_SealInit(3)|EVP_SealInit(3)>, | ||
33 | L<EVP_SignInit(3)|EVP_SignInit(3)>, | ||
34 | L<EVP_VerifyInit(3)|EVP_VerifyInit(3)>, | ||
35 | L<OpenSSL_add_all_algorithms(3)|OpenSSL_add_all_algorithms(3)> | ||
36 | |||
37 | =cut | ||
diff --git a/src/lib/libcrypto/doc/lh_stats.pod b/src/lib/libcrypto/doc/lh_stats.pod new file mode 100644 index 0000000000..3eeaa72e52 --- /dev/null +++ b/src/lib/libcrypto/doc/lh_stats.pod | |||
@@ -0,0 +1,60 @@ | |||
1 | =pod | ||
2 | |||
3 | =head1 NAME | ||
4 | |||
5 | lh_stats, lh_node_stats, lh_node_usage_stats, lh_stats_bio, | ||
6 | lh_node_stats_bio, lh_node_usage_stats_bio - LHASH statistics | ||
7 | |||
8 | =head1 SYNOPSIS | ||
9 | |||
10 | #include <openssl/lhash.h> | ||
11 | |||
12 | void lh_stats(LHASH *table, FILE *out); | ||
13 | void lh_node_stats(LHASH *table, FILE *out); | ||
14 | void lh_node_usage_stats(LHASH *table, FILE *out); | ||
15 | |||
16 | void lh_stats_bio(LHASH *table, BIO *out); | ||
17 | void lh_node_stats_bio(LHASH *table, BIO *out); | ||
18 | void lh_node_usage_stats_bio(LHASH *table, BIO *out); | ||
19 | |||
20 | =head1 DESCRIPTION | ||
21 | |||
22 | The B<LHASH> structure records statistics about most aspects of | ||
23 | accessing the hash table. This is mostly a legacy of Eric Young | ||
24 | writing this library for the reasons of implementing what looked like | ||
25 | a nice algorithm rather than for a particular software product. | ||
26 | |||
27 | lh_stats() prints out statistics on the size of the hash table, how | ||
28 | many entries are in it, and the number and result of calls to the | ||
29 | routines in this library. | ||
30 | |||
31 | lh_node_stats() prints the number of entries for each 'bucket' in the | ||
32 | hash table. | ||
33 | |||
34 | lh_node_usage_stats() prints out a short summary of the state of the | ||
35 | hash table. It prints the 'load' and the 'actual load'. The load is | ||
36 | the average number of data items per 'bucket' in the hash table. The | ||
37 | 'actual load' is the average number of items per 'bucket', but only | ||
38 | for buckets which contain entries. So the 'actual load' is the | ||
39 | average number of searches that will need to find an item in the hash | ||
40 | table, while the 'load' is the average number that will be done to | ||
41 | record a miss. | ||
42 | |||
43 | lh_stats_bio(), lh_node_stats_bio() and lh_node_usage_stats_bio() | ||
44 | are the same as the above, except that the output goes to a B<BIO>. | ||
45 | |||
46 | =head1 RETURN VALUES | ||
47 | |||
48 | These functions do not return values. | ||
49 | |||
50 | =head1 SEE ALSO | ||
51 | |||
52 | L<bio(3)|bio(3)>, L<lhash(3)|lhash(3)> | ||
53 | |||
54 | =head1 HISTORY | ||
55 | |||
56 | These functions are available in all versions of SSLeay and OpenSSL. | ||
57 | |||
58 | This manpage is derived from the SSLeay documentation. | ||
59 | |||
60 | =cut | ||
diff --git a/src/lib/libcrypto/doc/rsa.pod b/src/lib/libcrypto/doc/rsa.pod new file mode 100644 index 0000000000..0486c044a6 --- /dev/null +++ b/src/lib/libcrypto/doc/rsa.pod | |||
@@ -0,0 +1,115 @@ | |||
1 | =pod | ||
2 | |||
3 | =head1 NAME | ||
4 | |||
5 | rsa - RSA public key cryptosystem | ||
6 | |||
7 | =head1 SYNOPSIS | ||
8 | |||
9 | #include <openssl/rsa.h> | ||
10 | |||
11 | RSA * RSA_new(void); | ||
12 | void RSA_free(RSA *rsa); | ||
13 | |||
14 | int RSA_public_encrypt(int flen, unsigned char *from, | ||
15 | unsigned char *to, RSA *rsa, int padding); | ||
16 | int RSA_private_decrypt(int flen, unsigned char *from, | ||
17 | unsigned char *to, RSA *rsa, int padding); | ||
18 | |||
19 | int RSA_sign(int type, unsigned char *m, unsigned int m_len, | ||
20 | unsigned char *sigret, unsigned int *siglen, RSA *rsa); | ||
21 | int RSA_verify(int type, unsigned char *m, unsigned int m_len, | ||
22 | unsigned char *sigbuf, unsigned int siglen, RSA *rsa); | ||
23 | |||
24 | int RSA_size(RSA *rsa); | ||
25 | |||
26 | RSA *RSA_generate_key(int num, unsigned long e, | ||
27 | void (*callback)(int,int,void *), void *cb_arg); | ||
28 | |||
29 | int RSA_check_key(RSA *rsa); | ||
30 | |||
31 | int RSA_blinding_on(RSA *rsa, BN_CTX *ctx); | ||
32 | void RSA_blinding_off(RSA *rsa); | ||
33 | |||
34 | void RSA_set_default_method(RSA_METHOD *meth); | ||
35 | RSA_METHOD *RSA_get_default_method(void); | ||
36 | RSA_METHOD *RSA_set_method(RSA *rsa, RSA_METHOD *meth); | ||
37 | RSA_METHOD *RSA_get_method(RSA *rsa); | ||
38 | RSA_METHOD *RSA_PKCS1_SSLeay(void); | ||
39 | RSA_METHOD *RSA_PKCS1_RSAref(void); | ||
40 | RSA_METHOD *RSA_null_method(void); | ||
41 | int RSA_flags(RSA *rsa); | ||
42 | RSA *RSA_new_method(RSA_METHOD *method); | ||
43 | |||
44 | int RSA_print(BIO *bp, RSA *x, int offset); | ||
45 | int RSA_print_fp(FILE *fp, RSA *x, int offset); | ||
46 | |||
47 | int RSA_get_ex_new_index(long argl, char *argp, int (*new_func)(), | ||
48 | int (*dup_func)(), void (*free_func)()); | ||
49 | int RSA_set_ex_data(RSA *r,int idx,char *arg); | ||
50 | char *RSA_get_ex_data(RSA *r, int idx); | ||
51 | |||
52 | int RSA_private_encrypt(int flen, unsigned char *from, | ||
53 | unsigned char *to, RSA *rsa,int padding); | ||
54 | int RSA_public_decrypt(int flen, unsigned char *from, | ||
55 | unsigned char *to, RSA *rsa,int padding); | ||
56 | |||
57 | int RSA_sign_ASN1_OCTET_STRING(int dummy, unsigned char *m, | ||
58 | unsigned int m_len, unsigned char *sigret, unsigned int *siglen, | ||
59 | RSA *rsa); | ||
60 | int RSA_verify_ASN1_OCTET_STRING(int dummy, unsigned char *m, | ||
61 | unsigned int m_len, unsigned char *sigbuf, unsigned int siglen, | ||
62 | RSA *rsa); | ||
63 | |||
64 | =head1 DESCRIPTION | ||
65 | |||
66 | These functions implement RSA public key encryption and signatures | ||
67 | as defined in PKCS #1 v2.0 [RFC 2437]. | ||
68 | |||
69 | The B<RSA> structure consists of several BIGNUM components. It can | ||
70 | contain public as well as private RSA keys: | ||
71 | |||
72 | struct | ||
73 | { | ||
74 | BIGNUM *n; // public modulus | ||
75 | BIGNUM *e; // public exponent | ||
76 | BIGNUM *d; // private exponent | ||
77 | BIGNUM *p; // secret prime factor | ||
78 | BIGNUM *q; // secret prime factor | ||
79 | BIGNUM *dmp1; // d mod (p-1) | ||
80 | BIGNUM *dmq1; // d mod (q-1) | ||
81 | BIGNUM *iqmp; // q^-1 mod p | ||
82 | // ... | ||
83 | }; | ||
84 | RSA | ||
85 | |||
86 | In public keys, the private exponent and the related secret values are | ||
87 | B<NULL>. | ||
88 | |||
89 | B<dmp1>, B<dmq1> and B<iqmp> may be B<NULL> in private keys, but the | ||
90 | RSA operations are much faster when these values are available. | ||
91 | |||
92 | =head1 CONFORMING TO | ||
93 | |||
94 | SSL, PKCS #1 v2.0 | ||
95 | |||
96 | =head1 PATENTS | ||
97 | |||
98 | RSA is covered by a US patent which expires in September 2000. | ||
99 | |||
100 | =head1 SEE ALSO | ||
101 | |||
102 | L<rsa(1)|rsa(1)>, L<bn(3)|bn(3)>, L<dsa(3)|dsa(3)>, L<dh(3)|dh(3)>, | ||
103 | L<rand(3)|rand(3)>, L<RSA_new(3)|RSA_new(3)>, | ||
104 | L<RSA_public_encrypt(3)|RSA_public_encrypt(3)>, | ||
105 | L<RSA_sign(3)|RSA_sign(3)>, L<RSA_size(3)|RSA_size(3)>, | ||
106 | L<RSA_generate_key(3)|RSA_generate_key(3)>, | ||
107 | L<RSA_check_key(3)|RSA_check_key(3)>, | ||
108 | L<RSA_blinding_on(3)|RSA_blinding_on(3)>, | ||
109 | L<RSA_set_method(3)|RSA_set_method(3)>, L<RSA_print(3)|RSA_print(3)>, | ||
110 | L<RSA_get_ex_new_index(3)|RSA_get_ex_new_index(3)>, | ||
111 | L<RSA_private_encrypt(3)|RSA_private_encrypt(3)>, | ||
112 | L<RSA_sign_ASN_OCTET_STRING(3)|RSA_sign_ASN_OCTET_STRING(3)>, | ||
113 | L<RSA_padding_add_PKCS1_type_1(3)|RSA_padding_add_PKCS1_type_1(3)> | ||
114 | |||
115 | =cut | ||
diff --git a/src/lib/libcrypto/dsa/dsa_asn1.c b/src/lib/libcrypto/dsa/dsa_asn1.c new file mode 100644 index 0000000000..7523b21654 --- /dev/null +++ b/src/lib/libcrypto/dsa/dsa_asn1.c | |||
@@ -0,0 +1,96 @@ | |||
1 | /* crypto/dsa/dsa_asn1.c */ | ||
2 | |||
3 | #include <stdio.h> | ||
4 | #include "cryptlib.h" | ||
5 | #include <openssl/dsa.h> | ||
6 | #include <openssl/asn1.h> | ||
7 | #include <openssl/asn1_mac.h> | ||
8 | |||
9 | DSA_SIG *DSA_SIG_new(void) | ||
10 | { | ||
11 | DSA_SIG *ret; | ||
12 | |||
13 | ret = Malloc(sizeof(DSA_SIG)); | ||
14 | if (ret == NULL) | ||
15 | { | ||
16 | DSAerr(DSA_F_DSA_SIG_NEW,ERR_R_MALLOC_FAILURE); | ||
17 | return(NULL); | ||
18 | } | ||
19 | ret->r = NULL; | ||
20 | ret->s = NULL; | ||
21 | return(ret); | ||
22 | } | ||
23 | |||
24 | void DSA_SIG_free(DSA_SIG *r) | ||
25 | { | ||
26 | if (r == NULL) return; | ||
27 | if (r->r) BN_clear_free(r->r); | ||
28 | if (r->s) BN_clear_free(r->s); | ||
29 | Free(r); | ||
30 | } | ||
31 | |||
32 | int i2d_DSA_SIG(DSA_SIG *v, unsigned char **pp) | ||
33 | { | ||
34 | int t=0,len; | ||
35 | ASN1_INTEGER rbs,sbs; | ||
36 | unsigned char *p; | ||
37 | |||
38 | rbs.data=Malloc(BN_num_bits(v->r)/8+1); | ||
39 | if (rbs.data == NULL) | ||
40 | { | ||
41 | DSAerr(DSA_F_I2D_DSA_SIG, ERR_R_MALLOC_FAILURE); | ||
42 | return(0); | ||
43 | } | ||
44 | rbs.type=V_ASN1_INTEGER; | ||
45 | rbs.length=BN_bn2bin(v->r,rbs.data); | ||
46 | sbs.data=Malloc(BN_num_bits(v->s)/8+1); | ||
47 | if (sbs.data == NULL) | ||
48 | { | ||
49 | Free(rbs.data); | ||
50 | DSAerr(DSA_F_I2D_DSA_SIG, ERR_R_MALLOC_FAILURE); | ||
51 | return(0); | ||
52 | } | ||
53 | sbs.type=V_ASN1_INTEGER; | ||
54 | sbs.length=BN_bn2bin(v->s,sbs.data); | ||
55 | |||
56 | len=i2d_ASN1_INTEGER(&rbs,NULL); | ||
57 | len+=i2d_ASN1_INTEGER(&sbs,NULL); | ||
58 | |||
59 | if (pp) | ||
60 | { | ||
61 | p=*pp; | ||
62 | ASN1_put_object(&p,1,len,V_ASN1_SEQUENCE,V_ASN1_UNIVERSAL); | ||
63 | i2d_ASN1_INTEGER(&rbs,&p); | ||
64 | i2d_ASN1_INTEGER(&sbs,&p); | ||
65 | } | ||
66 | t=ASN1_object_size(1,len,V_ASN1_SEQUENCE); | ||
67 | Free(rbs.data); | ||
68 | Free(sbs.data); | ||
69 | return(t); | ||
70 | } | ||
71 | |||
72 | DSA_SIG *d2i_DSA_SIG(DSA_SIG **a, unsigned char **pp, long length) | ||
73 | { | ||
74 | int i=ERR_R_NESTED_ASN1_ERROR; | ||
75 | ASN1_INTEGER *bs=NULL; | ||
76 | M_ASN1_D2I_vars(a,DSA_SIG *,DSA_SIG_new); | ||
77 | |||
78 | M_ASN1_D2I_Init(); | ||
79 | M_ASN1_D2I_start_sequence(); | ||
80 | M_ASN1_D2I_get(bs,d2i_ASN1_INTEGER); | ||
81 | if ((ret->r=BN_bin2bn(bs->data,bs->length,ret->r)) == NULL) | ||
82 | goto err_bn; | ||
83 | M_ASN1_D2I_get(bs,d2i_ASN1_INTEGER); | ||
84 | if ((ret->s=BN_bin2bn(bs->data,bs->length,ret->s)) == NULL) | ||
85 | goto err_bn; | ||
86 | ASN1_BIT_STRING_free(bs); | ||
87 | M_ASN1_D2I_Finish_2(a); | ||
88 | |||
89 | err_bn: | ||
90 | i=ERR_R_BN_LIB; | ||
91 | err: | ||
92 | DSAerr(DSA_F_D2I_DSA_SIG,i); | ||
93 | if ((ret != NULL) && ((a == NULL) || (*a != ret))) DSA_SIG_free(ret); | ||
94 | if (bs != NULL) ASN1_BIT_STRING_free(bs); | ||
95 | return(NULL); | ||
96 | } | ||
diff --git a/src/lib/libcrypto/dsa/dsa_ossl.c b/src/lib/libcrypto/dsa/dsa_ossl.c new file mode 100644 index 0000000000..b51cf6ad8d --- /dev/null +++ b/src/lib/libcrypto/dsa/dsa_ossl.c | |||
@@ -0,0 +1,321 @@ | |||
1 | /* crypto/dsa/dsa_ossl.c */ | ||
2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) | ||
3 | * All rights reserved. | ||
4 | * | ||
5 | * This package is an SSL implementation written | ||
6 | * by Eric Young (eay@cryptsoft.com). | ||
7 | * The implementation was written so as to conform with Netscapes SSL. | ||
8 | * | ||
9 | * This library is free for commercial and non-commercial use as long as | ||
10 | * the following conditions are aheared to. The following conditions | ||
11 | * apply to all code found in this distribution, be it the RC4, RSA, | ||
12 | * lhash, DES, etc., code; not just the SSL code. The SSL documentation | ||
13 | * included with this distribution is covered by the same copyright terms | ||
14 | * except that the holder is Tim Hudson (tjh@cryptsoft.com). | ||
15 | * | ||
16 | * Copyright remains Eric Young's, and as such any Copyright notices in | ||
17 | * the code are not to be removed. | ||
18 | * If this package is used in a product, Eric Young should be given attribution | ||
19 | * as the author of the parts of the library used. | ||
20 | * This can be in the form of a textual message at program startup or | ||
21 | * in documentation (online or textual) provided with the package. | ||
22 | * | ||
23 | * Redistribution and use in source and binary forms, with or without | ||
24 | * modification, are permitted provided that the following conditions | ||
25 | * are met: | ||
26 | * 1. Redistributions of source code must retain the copyright | ||
27 | * notice, this list of conditions and the following disclaimer. | ||
28 | * 2. Redistributions in binary form must reproduce the above copyright | ||
29 | * notice, this list of conditions and the following disclaimer in the | ||
30 | * documentation and/or other materials provided with the distribution. | ||
31 | * 3. All advertising materials mentioning features or use of this software | ||
32 | * must display the following acknowledgement: | ||
33 | * "This product includes cryptographic software written by | ||
34 | * Eric Young (eay@cryptsoft.com)" | ||
35 | * The word 'cryptographic' can be left out if the rouines from the library | ||
36 | * being used are not cryptographic related :-). | ||
37 | * 4. If you include any Windows specific code (or a derivative thereof) from | ||
38 | * the apps directory (application code) you must include an acknowledgement: | ||
39 | * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" | ||
40 | * | ||
41 | * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND | ||
42 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
43 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
44 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | ||
45 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
46 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
47 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
48 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
49 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
50 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
51 | * SUCH DAMAGE. | ||
52 | * | ||
53 | * The licence and distribution terms for any publically available version or | ||
54 | * derivative of this code cannot be changed. i.e. this code cannot simply be | ||
55 | * copied and put under another distribution licence | ||
56 | * [including the GNU Public Licence.] | ||
57 | */ | ||
58 | |||
59 | /* Original version from Steven Schoch <schoch@sheba.arc.nasa.gov> */ | ||
60 | |||
61 | #include <stdio.h> | ||
62 | #include "cryptlib.h" | ||
63 | #include <openssl/bn.h> | ||
64 | #include <openssl/dsa.h> | ||
65 | #include <openssl/rand.h> | ||
66 | #include <openssl/asn1.h> | ||
67 | |||
68 | static DSA_SIG *dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa); | ||
69 | static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp); | ||
70 | static int dsa_do_verify(const unsigned char *dgst, int dgst_len, DSA_SIG *sig, | ||
71 | DSA *dsa); | ||
72 | static int dsa_init(DSA *dsa); | ||
73 | static int dsa_finish(DSA *dsa); | ||
74 | static int dsa_mod_exp(DSA *dsa, BIGNUM *rr, BIGNUM *a1, BIGNUM *p1, | ||
75 | BIGNUM *a2, BIGNUM *p2, BIGNUM *m, BN_CTX *ctx, | ||
76 | BN_MONT_CTX *in_mont); | ||
77 | static int dsa_bn_mod_exp(DSA *dsa, BIGNUM *r, BIGNUM *a, const BIGNUM *p, | ||
78 | const BIGNUM *m, BN_CTX *ctx, | ||
79 | BN_MONT_CTX *m_ctx); | ||
80 | |||
81 | static DSA_METHOD openssl_dsa_meth = { | ||
82 | "OpenSSL DSA method", | ||
83 | dsa_do_sign, | ||
84 | dsa_sign_setup, | ||
85 | dsa_do_verify, | ||
86 | dsa_mod_exp, | ||
87 | dsa_bn_mod_exp, | ||
88 | dsa_init, | ||
89 | dsa_finish, | ||
90 | 0, | ||
91 | NULL | ||
92 | }; | ||
93 | |||
94 | DSA_METHOD *DSA_OpenSSL(void) | ||
95 | { | ||
96 | return &openssl_dsa_meth; | ||
97 | } | ||
98 | |||
99 | static DSA_SIG *dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa) | ||
100 | { | ||
101 | BIGNUM *kinv=NULL,*r=NULL,*s=NULL; | ||
102 | BIGNUM m; | ||
103 | BIGNUM xr; | ||
104 | BN_CTX *ctx=NULL; | ||
105 | int i,reason=ERR_R_BN_LIB; | ||
106 | DSA_SIG *ret=NULL; | ||
107 | |||
108 | BN_init(&m); | ||
109 | BN_init(&xr); | ||
110 | s=BN_new(); | ||
111 | if (s == NULL) goto err; | ||
112 | |||
113 | i=BN_num_bytes(dsa->q); /* should be 20 */ | ||
114 | if ((dlen > i) || (dlen > 50)) | ||
115 | { | ||
116 | reason=DSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE; | ||
117 | goto err; | ||
118 | } | ||
119 | |||
120 | ctx=BN_CTX_new(); | ||
121 | if (ctx == NULL) goto err; | ||
122 | |||
123 | if ((dsa->kinv == NULL) || (dsa->r == NULL)) | ||
124 | { | ||
125 | if (!DSA_sign_setup(dsa,ctx,&kinv,&r)) goto err; | ||
126 | } | ||
127 | else | ||
128 | { | ||
129 | kinv=dsa->kinv; | ||
130 | dsa->kinv=NULL; | ||
131 | r=dsa->r; | ||
132 | dsa->r=NULL; | ||
133 | } | ||
134 | |||
135 | if (BN_bin2bn(dgst,dlen,&m) == NULL) goto err; | ||
136 | |||
137 | /* Compute s = inv(k) (m + xr) mod q */ | ||
138 | if (!BN_mod_mul(&xr,dsa->priv_key,r,dsa->q,ctx)) goto err;/* s = xr */ | ||
139 | if (!BN_add(s, &xr, &m)) goto err; /* s = m + xr */ | ||
140 | if (BN_cmp(s,dsa->q) > 0) | ||
141 | BN_sub(s,s,dsa->q); | ||
142 | if (!BN_mod_mul(s,s,kinv,dsa->q,ctx)) goto err; | ||
143 | |||
144 | ret=DSA_SIG_new(); | ||
145 | if (ret == NULL) goto err; | ||
146 | ret->r = r; | ||
147 | ret->s = s; | ||
148 | |||
149 | err: | ||
150 | if (!ret) | ||
151 | { | ||
152 | DSAerr(DSA_F_DSA_DO_SIGN,reason); | ||
153 | BN_free(r); | ||
154 | BN_free(s); | ||
155 | } | ||
156 | if (ctx != NULL) BN_CTX_free(ctx); | ||
157 | BN_clear_free(&m); | ||
158 | BN_clear_free(&xr); | ||
159 | if (kinv != NULL) /* dsa->kinv is NULL now if we used it */ | ||
160 | BN_clear_free(kinv); | ||
161 | return(ret); | ||
162 | } | ||
163 | |||
164 | static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp) | ||
165 | { | ||
166 | BN_CTX *ctx; | ||
167 | BIGNUM k,*kinv=NULL,*r=NULL; | ||
168 | int ret=0; | ||
169 | |||
170 | if (ctx_in == NULL) | ||
171 | { | ||
172 | if ((ctx=BN_CTX_new()) == NULL) goto err; | ||
173 | } | ||
174 | else | ||
175 | ctx=ctx_in; | ||
176 | |||
177 | BN_init(&k); | ||
178 | if ((r=BN_new()) == NULL) goto err; | ||
179 | kinv=NULL; | ||
180 | |||
181 | /* Get random k */ | ||
182 | for (;;) | ||
183 | { | ||
184 | if (!BN_rand(&k, BN_num_bits(dsa->q), 1, 0)) goto err; | ||
185 | if (BN_cmp(&k,dsa->q) >= 0) | ||
186 | BN_sub(&k,&k,dsa->q); | ||
187 | if (!BN_is_zero(&k)) break; | ||
188 | } | ||
189 | |||
190 | if ((dsa->method_mont_p == NULL) && (dsa->flags & DSA_FLAG_CACHE_MONT_P)) | ||
191 | { | ||
192 | if ((dsa->method_mont_p=(char *)BN_MONT_CTX_new()) != NULL) | ||
193 | if (!BN_MONT_CTX_set((BN_MONT_CTX *)dsa->method_mont_p, | ||
194 | dsa->p,ctx)) goto err; | ||
195 | } | ||
196 | |||
197 | /* Compute r = (g^k mod p) mod q */ | ||
198 | if (!dsa->meth->bn_mod_exp(dsa, r,dsa->g,&k,dsa->p,ctx, | ||
199 | (BN_MONT_CTX *)dsa->method_mont_p)) goto err; | ||
200 | if (!BN_mod(r,r,dsa->q,ctx)) goto err; | ||
201 | |||
202 | /* Compute part of 's = inv(k) (m + xr) mod q' */ | ||
203 | if ((kinv=BN_mod_inverse(NULL,&k,dsa->q,ctx)) == NULL) goto err; | ||
204 | |||
205 | if (*kinvp != NULL) BN_clear_free(*kinvp); | ||
206 | *kinvp=kinv; | ||
207 | kinv=NULL; | ||
208 | if (*rp != NULL) BN_clear_free(*rp); | ||
209 | *rp=r; | ||
210 | ret=1; | ||
211 | err: | ||
212 | if (!ret) | ||
213 | { | ||
214 | DSAerr(DSA_F_DSA_SIGN_SETUP,ERR_R_BN_LIB); | ||
215 | if (kinv != NULL) BN_clear_free(kinv); | ||
216 | if (r != NULL) BN_clear_free(r); | ||
217 | } | ||
218 | if (ctx_in == NULL) BN_CTX_free(ctx); | ||
219 | if (kinv != NULL) BN_clear_free(kinv); | ||
220 | BN_clear_free(&k); | ||
221 | return(ret); | ||
222 | } | ||
223 | |||
224 | static int dsa_do_verify(const unsigned char *dgst, int dgst_len, DSA_SIG *sig, | ||
225 | DSA *dsa) | ||
226 | { | ||
227 | BN_CTX *ctx; | ||
228 | BIGNUM u1,u2,t1; | ||
229 | BN_MONT_CTX *mont=NULL; | ||
230 | int ret = -1; | ||
231 | |||
232 | if ((ctx=BN_CTX_new()) == NULL) goto err; | ||
233 | BN_init(&u1); | ||
234 | BN_init(&u2); | ||
235 | BN_init(&t1); | ||
236 | |||
237 | /* Calculate W = inv(S) mod Q | ||
238 | * save W in u2 */ | ||
239 | if ((BN_mod_inverse(&u2,sig->s,dsa->q,ctx)) == NULL) goto err; | ||
240 | |||
241 | /* save M in u1 */ | ||
242 | if (BN_bin2bn(dgst,dgst_len,&u1) == NULL) goto err; | ||
243 | |||
244 | /* u1 = M * w mod q */ | ||
245 | if (!BN_mod_mul(&u1,&u1,&u2,dsa->q,ctx)) goto err; | ||
246 | |||
247 | /* u2 = r * w mod q */ | ||
248 | if (!BN_mod_mul(&u2,sig->r,&u2,dsa->q,ctx)) goto err; | ||
249 | |||
250 | if ((dsa->method_mont_p == NULL) && (dsa->flags & DSA_FLAG_CACHE_MONT_P)) | ||
251 | { | ||
252 | if ((dsa->method_mont_p=(char *)BN_MONT_CTX_new()) != NULL) | ||
253 | if (!BN_MONT_CTX_set((BN_MONT_CTX *)dsa->method_mont_p, | ||
254 | dsa->p,ctx)) goto err; | ||
255 | } | ||
256 | mont=(BN_MONT_CTX *)dsa->method_mont_p; | ||
257 | |||
258 | #if 0 | ||
259 | { | ||
260 | BIGNUM t2; | ||
261 | |||
262 | BN_init(&t2); | ||
263 | /* v = ( g^u1 * y^u2 mod p ) mod q */ | ||
264 | /* let t1 = g ^ u1 mod p */ | ||
265 | if (!BN_mod_exp_mont(&t1,dsa->g,&u1,dsa->p,ctx,mont)) goto err; | ||
266 | /* let t2 = y ^ u2 mod p */ | ||
267 | if (!BN_mod_exp_mont(&t2,dsa->pub_key,&u2,dsa->p,ctx,mont)) goto err; | ||
268 | /* let u1 = t1 * t2 mod p */ | ||
269 | if (!BN_mod_mul(&u1,&t1,&t2,dsa->p,ctx)) goto err_bn; | ||
270 | BN_free(&t2); | ||
271 | } | ||
272 | /* let u1 = u1 mod q */ | ||
273 | if (!BN_mod(&u1,&u1,dsa->q,ctx)) goto err; | ||
274 | #else | ||
275 | { | ||
276 | if (!dsa->meth->dsa_mod_exp(dsa, &t1,dsa->g,&u1,dsa->pub_key,&u2, | ||
277 | dsa->p,ctx,mont)) goto err; | ||
278 | /* BN_copy(&u1,&t1); */ | ||
279 | /* let u1 = u1 mod q */ | ||
280 | if (!BN_mod(&u1,&t1,dsa->q,ctx)) goto err; | ||
281 | } | ||
282 | #endif | ||
283 | /* V is now in u1. If the signature is correct, it will be | ||
284 | * equal to R. */ | ||
285 | ret=(BN_ucmp(&u1, sig->r) == 0); | ||
286 | |||
287 | err: | ||
288 | if (ret != 1) DSAerr(DSA_F_DSA_DO_VERIFY,ERR_R_BN_LIB); | ||
289 | if (ctx != NULL) BN_CTX_free(ctx); | ||
290 | BN_free(&u1); | ||
291 | BN_free(&u2); | ||
292 | BN_free(&t1); | ||
293 | return(ret); | ||
294 | } | ||
295 | |||
296 | static int dsa_init(DSA *dsa) | ||
297 | { | ||
298 | dsa->flags|=DSA_FLAG_CACHE_MONT_P; | ||
299 | return(1); | ||
300 | } | ||
301 | |||
302 | static int dsa_finish(DSA *dsa) | ||
303 | { | ||
304 | if(dsa->method_mont_p) | ||
305 | BN_MONT_CTX_free((BN_MONT_CTX *)dsa->method_mont_p); | ||
306 | return(1); | ||
307 | } | ||
308 | |||
309 | static int dsa_mod_exp(DSA *dsa, BIGNUM *rr, BIGNUM *a1, BIGNUM *p1, | ||
310 | BIGNUM *a2, BIGNUM *p2, BIGNUM *m, BN_CTX *ctx, | ||
311 | BN_MONT_CTX *in_mont) | ||
312 | { | ||
313 | return BN_mod_exp2_mont(rr, a1, p1, a2, p2, m, ctx, in_mont); | ||
314 | } | ||
315 | |||
316 | static int dsa_bn_mod_exp(DSA *dsa, BIGNUM *r, BIGNUM *a, const BIGNUM *p, | ||
317 | const BIGNUM *m, BN_CTX *ctx, | ||
318 | BN_MONT_CTX *m_ctx) | ||
319 | { | ||
320 | return BN_mod_exp_mont(r, a, p, m, ctx, m_ctx); | ||
321 | } | ||
diff --git a/src/lib/libcrypto/dso/dso.h b/src/lib/libcrypto/dso/dso.h new file mode 100644 index 0000000000..bed7c464a6 --- /dev/null +++ b/src/lib/libcrypto/dso/dso.h | |||
@@ -0,0 +1,250 @@ | |||
1 | /* dso.h */ | ||
2 | /* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL | ||
3 | * project 2000. | ||
4 | */ | ||
5 | /* ==================================================================== | ||
6 | * Copyright (c) 2000 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_DSO_H | ||
60 | #define HEADER_DSO_H | ||
61 | |||
62 | #include <openssl/crypto.h> | ||
63 | |||
64 | #ifdef __cplusplus | ||
65 | extern "C" { | ||
66 | #endif | ||
67 | |||
68 | /* These values are used as commands to DSO_ctrl() */ | ||
69 | #define DSO_CTRL_GET_FLAGS 1 | ||
70 | #define DSO_CTRL_SET_FLAGS 2 | ||
71 | #define DSO_CTRL_OR_FLAGS 3 | ||
72 | |||
73 | /* These flags control the translation of file-names from canonical to | ||
74 | * native. Eg. in the CryptoSwift support, the "dl" and "dlfcn" | ||
75 | * methods will translate "swift" -> "libswift.so" whereas the "win32" | ||
76 | * method will translate "swift" -> "swift.dll". NB: Until I can figure | ||
77 | * out how to be more "conventional" with this, the methods will only | ||
78 | * honour this flag if it looks like it was passed a file without any | ||
79 | * path and if the filename is small enough. | ||
80 | */ | ||
81 | #define DSO_FLAG_NAME_TRANSLATION 0x01 | ||
82 | |||
83 | /* The following flag controls the translation of symbol names to upper | ||
84 | * case. This is currently only being implemented for OpenVMS. | ||
85 | */ | ||
86 | #define DSO_FLAG_UPCASE_SYMBOL 0x02 | ||
87 | |||
88 | |||
89 | typedef void (*DSO_FUNC_TYPE)(void); | ||
90 | |||
91 | typedef struct dso_st DSO; | ||
92 | |||
93 | typedef struct dso_meth_st | ||
94 | { | ||
95 | const char *name; | ||
96 | /* Loads a shared library */ | ||
97 | int (*dso_load)(DSO *dso, const char *filename); | ||
98 | /* Unloads a shared library */ | ||
99 | int (*dso_unload)(DSO *dso); | ||
100 | /* Binds a variable */ | ||
101 | void *(*dso_bind_var)(DSO *dso, const char *symname); | ||
102 | /* Binds a function - assumes a return type of DSO_FUNC_TYPE. | ||
103 | * This should be cast to the real function prototype by the | ||
104 | * caller. Platforms that don't have compatible representations | ||
105 | * for different prototypes (this is possible within ANSI C) | ||
106 | * are highly unlikely to have shared libraries at all, let | ||
107 | * alone a DSO_METHOD implemented for them. */ | ||
108 | DSO_FUNC_TYPE (*dso_bind_func)(DSO *dso, const char *symname); | ||
109 | |||
110 | /* I don't think this would actually be used in any circumstances. */ | ||
111 | #if 0 | ||
112 | /* Unbinds a variable */ | ||
113 | int (*dso_unbind_var)(DSO *dso, char *symname, void *symptr); | ||
114 | /* Unbinds a function */ | ||
115 | int (*dso_unbind_func)(DSO *dso, char *symname, DSO_FUNC_TYPE symptr); | ||
116 | #endif | ||
117 | /* The generic (yuck) "ctrl()" function. NB: Negative return | ||
118 | * values (rather than zero) indicate errors. */ | ||
119 | long (*dso_ctrl)(DSO *dso, int cmd, long larg, void *parg); | ||
120 | |||
121 | /* [De]Initialisation handlers. */ | ||
122 | int (*init)(DSO *dso); | ||
123 | int (*finish)(DSO *dso); | ||
124 | } DSO_METHOD; | ||
125 | |||
126 | /**********************************************************************/ | ||
127 | /* The low-level handle type used to refer to a loaded shared library */ | ||
128 | |||
129 | struct dso_st | ||
130 | { | ||
131 | DSO_METHOD *meth; | ||
132 | /* Standard dlopen uses a (void *). Win32 uses a HANDLE. VMS | ||
133 | * doesn't use anything but will need to cache the filename | ||
134 | * for use in the dso_bind handler. All in all, let each | ||
135 | * method control its own destiny. "Handles" and such go in | ||
136 | * a STACK. */ | ||
137 | STACK *meth_data; | ||
138 | int references; | ||
139 | int flags; | ||
140 | /* For use by applications etc ... use this for your bits'n'pieces, | ||
141 | * don't touch meth_data! */ | ||
142 | CRYPTO_EX_DATA ex_data; | ||
143 | }; | ||
144 | |||
145 | |||
146 | DSO * DSO_new(void); | ||
147 | DSO * DSO_new_method(DSO_METHOD *method); | ||
148 | int DSO_free(DSO *dso); | ||
149 | int DSO_flags(DSO *dso); | ||
150 | int DSO_up(DSO *dso); | ||
151 | long DSO_ctrl(DSO *dso, int cmd, long larg, void *parg); | ||
152 | |||
153 | void DSO_set_default_method(DSO_METHOD *meth); | ||
154 | DSO_METHOD *DSO_get_default_method(void); | ||
155 | DSO_METHOD *DSO_get_method(DSO *dso); | ||
156 | DSO_METHOD *DSO_set_method(DSO *dso, DSO_METHOD *meth); | ||
157 | |||
158 | /* The all-singing all-dancing load function, you normally pass NULL | ||
159 | * for the first and third parameters. Use DSO_up and DSO_free for | ||
160 | * subsequent reference count handling. Any flags passed in will be set | ||
161 | * in the constructed DSO after its init() function but before the | ||
162 | * load operation. This will be done with; | ||
163 | * DSO_ctrl(dso, DSO_CTRL_SET_FLAGS, flags, NULL); */ | ||
164 | DSO *DSO_load(DSO *dso, const char *filename, DSO_METHOD *meth, int flags); | ||
165 | |||
166 | /* This function binds to a variable inside a shared library. */ | ||
167 | void *DSO_bind_var(DSO *dso, const char *symname); | ||
168 | |||
169 | /* This function binds to a function inside a shared library. */ | ||
170 | DSO_FUNC_TYPE DSO_bind_func(DSO *dso, const char *symname); | ||
171 | |||
172 | /* This method is the default, but will beg, borrow, or steal whatever | ||
173 | * method should be the default on any particular platform (including | ||
174 | * DSO_METH_null() if necessary). */ | ||
175 | DSO_METHOD *DSO_METHOD_openssl(void); | ||
176 | |||
177 | /* This method is defined for all platforms - if a platform has no | ||
178 | * DSO support then this will be the only method! */ | ||
179 | DSO_METHOD *DSO_METHOD_null(void); | ||
180 | |||
181 | /* If DSO_DLFCN is defined, the standard dlfcn.h-style functions | ||
182 | * (dlopen, dlclose, dlsym, etc) will be used and incorporated into | ||
183 | * this method. If not, this method will return NULL. */ | ||
184 | DSO_METHOD *DSO_METHOD_dlfcn(void); | ||
185 | |||
186 | /* If DSO_DL is defined, the standard dl.h-style functions (shl_load, | ||
187 | * shl_unload, shl_findsym, etc) will be used and incorporated into | ||
188 | * this method. If not, this method will return NULL. */ | ||
189 | DSO_METHOD *DSO_METHOD_dl(void); | ||
190 | |||
191 | /* If WIN32 is defined, use DLLs. If not, return NULL. */ | ||
192 | DSO_METHOD *DSO_METHOD_win32(void); | ||
193 | |||
194 | /* If VMS is defined, use shared images. If not, return NULL. */ | ||
195 | DSO_METHOD *DSO_METHOD_vms(void); | ||
196 | |||
197 | void ERR_load_DSO_strings(void); | ||
198 | |||
199 | /* BEGIN ERROR CODES */ | ||
200 | /* The following lines are auto generated by the script mkerr.pl. Any changes | ||
201 | * made after this point may be overwritten when the script is next run. | ||
202 | */ | ||
203 | |||
204 | /* Error codes for the DSO functions. */ | ||
205 | |||
206 | /* Function codes. */ | ||
207 | #define DSO_F_DLFCN_BIND_FUNC 100 | ||
208 | #define DSO_F_DLFCN_BIND_VAR 101 | ||
209 | #define DSO_F_DLFCN_CTRL 102 | ||
210 | #define DSO_F_DLFCN_LOAD 103 | ||
211 | #define DSO_F_DLFCN_UNLOAD 104 | ||
212 | #define DSO_F_DL_BIND_FUNC 105 | ||
213 | #define DSO_F_DL_BIND_VAR 106 | ||
214 | #define DSO_F_DL_CTRL 107 | ||
215 | #define DSO_F_DL_LOAD 108 | ||
216 | #define DSO_F_DL_UNLOAD 109 | ||
217 | #define DSO_F_DSO_BIND_FUNC 110 | ||
218 | #define DSO_F_DSO_BIND_VAR 111 | ||
219 | #define DSO_F_DSO_CTRL 112 | ||
220 | #define DSO_F_DSO_FREE 113 | ||
221 | #define DSO_F_DSO_LOAD 114 | ||
222 | #define DSO_F_DSO_NEW_METHOD 115 | ||
223 | #define DSO_F_DSO_UP 116 | ||
224 | #define DSO_F_VMS_BIND_VAR 122 | ||
225 | #define DSO_F_VMS_CTRL 123 | ||
226 | #define DSO_F_VMS_LOAD 124 | ||
227 | #define DSO_F_VMS_UNLOAD 125 | ||
228 | #define DSO_F_WIN32_BIND_FUNC 117 | ||
229 | #define DSO_F_WIN32_BIND_VAR 118 | ||
230 | #define DSO_F_WIN32_CTRL 119 | ||
231 | #define DSO_F_WIN32_LOAD 120 | ||
232 | #define DSO_F_WIN32_UNLOAD 121 | ||
233 | |||
234 | /* Reason codes. */ | ||
235 | #define DSO_R_CTRL_FAILED 100 | ||
236 | #define DSO_R_FILENAME_TOO_BIG 109 | ||
237 | #define DSO_R_FINISH_FAILED 101 | ||
238 | #define DSO_R_LOAD_FAILED 102 | ||
239 | #define DSO_R_NULL_HANDLE 103 | ||
240 | #define DSO_R_STACK_ERROR 104 | ||
241 | #define DSO_R_SYM_FAILURE 105 | ||
242 | #define DSO_R_UNKNOWN_COMMAND 106 | ||
243 | #define DSO_R_UNLOAD_FAILED 107 | ||
244 | #define DSO_R_UNSUPPORTED 108 | ||
245 | |||
246 | #ifdef __cplusplus | ||
247 | } | ||
248 | #endif | ||
249 | #endif | ||
250 | |||
diff --git a/src/lib/libcrypto/dso/dso_dlfcn.c b/src/lib/libcrypto/dso/dso_dlfcn.c new file mode 100644 index 0000000000..e709c721cc --- /dev/null +++ b/src/lib/libcrypto/dso/dso_dlfcn.c | |||
@@ -0,0 +1,276 @@ | |||
1 | /* dso_dlfcn.c */ | ||
2 | /* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL | ||
3 | * project 2000. | ||
4 | */ | ||
5 | /* ==================================================================== | ||
6 | * Copyright (c) 2000 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 | #include "cryptlib.h" | ||
61 | #include <openssl/dso.h> | ||
62 | |||
63 | #ifndef DSO_DLFCN | ||
64 | DSO_METHOD *DSO_METHOD_dlfcn(void) | ||
65 | { | ||
66 | return NULL; | ||
67 | } | ||
68 | #else | ||
69 | |||
70 | #ifdef HAVE_DLFCN_H | ||
71 | #include <dlfcn.h> | ||
72 | #endif | ||
73 | |||
74 | /* Part of the hack in "dlfcn_load" ... */ | ||
75 | #define DSO_MAX_TRANSLATED_SIZE 256 | ||
76 | |||
77 | static int dlfcn_load(DSO *dso, const char *filename); | ||
78 | static int dlfcn_unload(DSO *dso); | ||
79 | static void *dlfcn_bind_var(DSO *dso, const char *symname); | ||
80 | static DSO_FUNC_TYPE dlfcn_bind_func(DSO *dso, const char *symname); | ||
81 | #if 0 | ||
82 | static int dlfcn_unbind(DSO *dso, char *symname, void *symptr); | ||
83 | static int dlfcn_init(DSO *dso); | ||
84 | static int dlfcn_finish(DSO *dso); | ||
85 | #endif | ||
86 | static long dlfcn_ctrl(DSO *dso, int cmd, long larg, void *parg); | ||
87 | |||
88 | static DSO_METHOD dso_meth_dlfcn = { | ||
89 | "OpenSSL 'dlfcn' shared library method", | ||
90 | dlfcn_load, | ||
91 | dlfcn_unload, | ||
92 | dlfcn_bind_var, | ||
93 | dlfcn_bind_func, | ||
94 | /* For now, "unbind" doesn't exist */ | ||
95 | #if 0 | ||
96 | NULL, /* unbind_var */ | ||
97 | NULL, /* unbind_func */ | ||
98 | #endif | ||
99 | dlfcn_ctrl, | ||
100 | NULL, /* init */ | ||
101 | NULL /* finish */ | ||
102 | }; | ||
103 | |||
104 | DSO_METHOD *DSO_METHOD_dlfcn(void) | ||
105 | { | ||
106 | return(&dso_meth_dlfcn); | ||
107 | } | ||
108 | |||
109 | /* Prior to using the dlopen() function, we should decide on the flag | ||
110 | * we send. There's a few different ways of doing this and it's a | ||
111 | * messy venn-diagram to match up which platforms support what. So | ||
112 | * as we don't have autoconf yet, I'm implementing a hack that could | ||
113 | * be hacked further relatively easily to deal with cases as we find | ||
114 | * them. Initially this is to cope with OpenBSD. */ | ||
115 | #ifdef __OpenBSD__ | ||
116 | # ifdef DL_LAZY | ||
117 | # define DLOPEN_FLAG DL_LAZY | ||
118 | # else | ||
119 | # ifdef RTLD_NOW | ||
120 | # define DLOPEN_FLAG RTLD_NOW | ||
121 | # else | ||
122 | # define DLOPEN_FLAG 0 | ||
123 | # endif | ||
124 | # endif | ||
125 | #else | ||
126 | # define DLOPEN_FLAG RTLD_NOW /* Hope this works everywhere else */ | ||
127 | #endif | ||
128 | |||
129 | /* For this DSO_METHOD, our meth_data STACK will contain; | ||
130 | * (i) the handle (void*) returned from dlopen(). | ||
131 | */ | ||
132 | |||
133 | static int dlfcn_load(DSO *dso, const char *filename) | ||
134 | { | ||
135 | void *ptr; | ||
136 | char translated[DSO_MAX_TRANSLATED_SIZE]; | ||
137 | int len; | ||
138 | |||
139 | /* NB: This is a hideous hack, but I'm not yet sure what | ||
140 | * to replace it with. This attempts to convert any filename, | ||
141 | * that looks like it has no path information, into a | ||
142 | * translated form, e. "blah" -> "libblah.so" */ | ||
143 | len = strlen(filename); | ||
144 | if((dso->flags & DSO_FLAG_NAME_TRANSLATION) && | ||
145 | (len + 6 < DSO_MAX_TRANSLATED_SIZE) && | ||
146 | (strstr(filename, "/") == NULL)) | ||
147 | { | ||
148 | sprintf(translated, "lib%s.so", filename); | ||
149 | ptr = dlopen(translated, DLOPEN_FLAG); | ||
150 | } | ||
151 | else | ||
152 | { | ||
153 | ptr = dlopen(filename, DLOPEN_FLAG); | ||
154 | } | ||
155 | if(ptr == NULL) | ||
156 | { | ||
157 | DSOerr(DSO_F_DLFCN_LOAD,DSO_R_LOAD_FAILED); | ||
158 | return(0); | ||
159 | } | ||
160 | if(!sk_push(dso->meth_data, (char *)ptr)) | ||
161 | { | ||
162 | DSOerr(DSO_F_DLFCN_LOAD,DSO_R_STACK_ERROR); | ||
163 | dlclose(ptr); | ||
164 | return(0); | ||
165 | } | ||
166 | return(1); | ||
167 | } | ||
168 | |||
169 | static int dlfcn_unload(DSO *dso) | ||
170 | { | ||
171 | void *ptr; | ||
172 | if(dso == NULL) | ||
173 | { | ||
174 | DSOerr(DSO_F_DLFCN_UNLOAD,ERR_R_PASSED_NULL_PARAMETER); | ||
175 | return(0); | ||
176 | } | ||
177 | if(sk_num(dso->meth_data) < 1) | ||
178 | return(1); | ||
179 | ptr = (void *)sk_pop(dso->meth_data); | ||
180 | if(ptr == NULL) | ||
181 | { | ||
182 | DSOerr(DSO_F_DLFCN_UNLOAD,DSO_R_NULL_HANDLE); | ||
183 | /* Should push the value back onto the stack in | ||
184 | * case of a retry. */ | ||
185 | sk_push(dso->meth_data, (char *)ptr); | ||
186 | return(0); | ||
187 | } | ||
188 | /* For now I'm not aware of any errors associated with dlclose() */ | ||
189 | dlclose(ptr); | ||
190 | return(1); | ||
191 | } | ||
192 | |||
193 | static void *dlfcn_bind_var(DSO *dso, const char *symname) | ||
194 | { | ||
195 | void *ptr, *sym; | ||
196 | |||
197 | if((dso == NULL) || (symname == NULL)) | ||
198 | { | ||
199 | DSOerr(DSO_F_DLFCN_BIND_VAR,ERR_R_PASSED_NULL_PARAMETER); | ||
200 | return(NULL); | ||
201 | } | ||
202 | if(sk_num(dso->meth_data) < 1) | ||
203 | { | ||
204 | DSOerr(DSO_F_DLFCN_BIND_VAR,DSO_R_STACK_ERROR); | ||
205 | return(NULL); | ||
206 | } | ||
207 | ptr = (void *)sk_value(dso->meth_data, sk_num(dso->meth_data) - 1); | ||
208 | if(ptr == NULL) | ||
209 | { | ||
210 | DSOerr(DSO_F_DLFCN_BIND_VAR,DSO_R_NULL_HANDLE); | ||
211 | return(NULL); | ||
212 | } | ||
213 | sym = dlsym(ptr, symname); | ||
214 | if(sym == NULL) | ||
215 | { | ||
216 | DSOerr(DSO_F_DLFCN_BIND_VAR,DSO_R_SYM_FAILURE); | ||
217 | return(NULL); | ||
218 | } | ||
219 | return(sym); | ||
220 | } | ||
221 | |||
222 | static DSO_FUNC_TYPE dlfcn_bind_func(DSO *dso, const char *symname) | ||
223 | { | ||
224 | void *ptr; | ||
225 | DSO_FUNC_TYPE sym; | ||
226 | |||
227 | if((dso == NULL) || (symname == NULL)) | ||
228 | { | ||
229 | DSOerr(DSO_F_DLFCN_BIND_FUNC,ERR_R_PASSED_NULL_PARAMETER); | ||
230 | return(NULL); | ||
231 | } | ||
232 | if(sk_num(dso->meth_data) < 1) | ||
233 | { | ||
234 | DSOerr(DSO_F_DLFCN_BIND_FUNC,DSO_R_STACK_ERROR); | ||
235 | return(NULL); | ||
236 | } | ||
237 | ptr = (void *)sk_value(dso->meth_data, sk_num(dso->meth_data) - 1); | ||
238 | if(ptr == NULL) | ||
239 | { | ||
240 | DSOerr(DSO_F_DLFCN_BIND_FUNC,DSO_R_NULL_HANDLE); | ||
241 | return(NULL); | ||
242 | } | ||
243 | sym = (DSO_FUNC_TYPE)dlsym(ptr, symname); | ||
244 | if(sym == NULL) | ||
245 | { | ||
246 | DSOerr(DSO_F_DLFCN_BIND_FUNC,DSO_R_SYM_FAILURE); | ||
247 | return(NULL); | ||
248 | } | ||
249 | return(sym); | ||
250 | } | ||
251 | |||
252 | static long dlfcn_ctrl(DSO *dso, int cmd, long larg, void *parg) | ||
253 | { | ||
254 | if(dso == NULL) | ||
255 | { | ||
256 | DSOerr(DSO_F_DLFCN_CTRL,ERR_R_PASSED_NULL_PARAMETER); | ||
257 | return(-1); | ||
258 | } | ||
259 | switch(cmd) | ||
260 | { | ||
261 | case DSO_CTRL_GET_FLAGS: | ||
262 | return dso->flags; | ||
263 | case DSO_CTRL_SET_FLAGS: | ||
264 | dso->flags = (int)larg; | ||
265 | return(0); | ||
266 | case DSO_CTRL_OR_FLAGS: | ||
267 | dso->flags |= (int)larg; | ||
268 | return(0); | ||
269 | default: | ||
270 | break; | ||
271 | } | ||
272 | DSOerr(DSO_F_DLFCN_CTRL,DSO_R_UNKNOWN_COMMAND); | ||
273 | return(-1); | ||
274 | } | ||
275 | |||
276 | #endif /* DSO_DLFCN */ | ||
diff --git a/src/lib/libcrypto/dso/dso_err.c b/src/lib/libcrypto/dso/dso_err.c new file mode 100644 index 0000000000..a3d7321c9b --- /dev/null +++ b/src/lib/libcrypto/dso/dso_err.c | |||
@@ -0,0 +1,128 @@ | |||
1 | /* crypto/dso/dso_err.c */ | ||
2 | /* ==================================================================== | ||
3 | * Copyright (c) 1999 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/dso.h> | ||
64 | |||
65 | /* BEGIN ERROR CODES */ | ||
66 | #ifndef NO_ERR | ||
67 | static ERR_STRING_DATA DSO_str_functs[]= | ||
68 | { | ||
69 | {ERR_PACK(0,DSO_F_DLFCN_BIND_FUNC,0), "DLFCN_BIND_FUNC"}, | ||
70 | {ERR_PACK(0,DSO_F_DLFCN_BIND_VAR,0), "DLFCN_BIND_VAR"}, | ||
71 | {ERR_PACK(0,DSO_F_DLFCN_CTRL,0), "DLFCN_CTRL"}, | ||
72 | {ERR_PACK(0,DSO_F_DLFCN_LOAD,0), "DLFCN_LOAD"}, | ||
73 | {ERR_PACK(0,DSO_F_DLFCN_UNLOAD,0), "DLFCN_UNLOAD"}, | ||
74 | {ERR_PACK(0,DSO_F_DL_BIND_FUNC,0), "DL_BIND_FUNC"}, | ||
75 | {ERR_PACK(0,DSO_F_DL_BIND_VAR,0), "DL_BIND_VAR"}, | ||
76 | {ERR_PACK(0,DSO_F_DL_CTRL,0), "DL_CTRL"}, | ||
77 | {ERR_PACK(0,DSO_F_DL_LOAD,0), "DL_LOAD"}, | ||
78 | {ERR_PACK(0,DSO_F_DL_UNLOAD,0), "DL_UNLOAD"}, | ||
79 | {ERR_PACK(0,DSO_F_DSO_BIND_FUNC,0), "DSO_bind_func"}, | ||
80 | {ERR_PACK(0,DSO_F_DSO_BIND_VAR,0), "DSO_bind_var"}, | ||
81 | {ERR_PACK(0,DSO_F_DSO_CTRL,0), "DSO_ctrl"}, | ||
82 | {ERR_PACK(0,DSO_F_DSO_FREE,0), "DSO_free"}, | ||
83 | {ERR_PACK(0,DSO_F_DSO_LOAD,0), "DSO_load"}, | ||
84 | {ERR_PACK(0,DSO_F_DSO_NEW_METHOD,0), "DSO_new_method"}, | ||
85 | {ERR_PACK(0,DSO_F_DSO_UP,0), "DSO_up"}, | ||
86 | {ERR_PACK(0,DSO_F_VMS_BIND_VAR,0), "VMS_BIND_VAR"}, | ||
87 | {ERR_PACK(0,DSO_F_VMS_CTRL,0), "VMS_CTRL"}, | ||
88 | {ERR_PACK(0,DSO_F_VMS_LOAD,0), "VMS_LOAD"}, | ||
89 | {ERR_PACK(0,DSO_F_VMS_UNLOAD,0), "VMS_UNLOAD"}, | ||
90 | {ERR_PACK(0,DSO_F_WIN32_BIND_FUNC,0), "WIN32_BIND_FUNC"}, | ||
91 | {ERR_PACK(0,DSO_F_WIN32_BIND_VAR,0), "WIN32_BIND_VAR"}, | ||
92 | {ERR_PACK(0,DSO_F_WIN32_CTRL,0), "WIN32_CTRL"}, | ||
93 | {ERR_PACK(0,DSO_F_WIN32_LOAD,0), "WIN32_LOAD"}, | ||
94 | {ERR_PACK(0,DSO_F_WIN32_UNLOAD,0), "WIN32_UNLOAD"}, | ||
95 | {0,NULL} | ||
96 | }; | ||
97 | |||
98 | static ERR_STRING_DATA DSO_str_reasons[]= | ||
99 | { | ||
100 | {DSO_R_CTRL_FAILED ,"control command failed"}, | ||
101 | {DSO_R_FILENAME_TOO_BIG ,"filename too big"}, | ||
102 | {DSO_R_FINISH_FAILED ,"cleanup method function failed"}, | ||
103 | {DSO_R_LOAD_FAILED ,"could not load the shared library"}, | ||
104 | {DSO_R_NULL_HANDLE ,"a null shared library handle was used"}, | ||
105 | {DSO_R_STACK_ERROR ,"the meth_data stack is corrupt"}, | ||
106 | {DSO_R_SYM_FAILURE ,"could not bind to the requested symbol name"}, | ||
107 | {DSO_R_UNKNOWN_COMMAND ,"unknown control command"}, | ||
108 | {DSO_R_UNLOAD_FAILED ,"could not unload the shared library"}, | ||
109 | {DSO_R_UNSUPPORTED ,"functionality not supported"}, | ||
110 | {0,NULL} | ||
111 | }; | ||
112 | |||
113 | #endif | ||
114 | |||
115 | void ERR_load_DSO_strings(void) | ||
116 | { | ||
117 | static int init=1; | ||
118 | |||
119 | if (init) | ||
120 | { | ||
121 | init=0; | ||
122 | #ifndef NO_ERR | ||
123 | ERR_load_strings(ERR_LIB_DSO,DSO_str_functs); | ||
124 | ERR_load_strings(ERR_LIB_DSO,DSO_str_reasons); | ||
125 | #endif | ||
126 | |||
127 | } | ||
128 | } | ||
diff --git a/src/lib/libcrypto/dso/dso_lib.c b/src/lib/libcrypto/dso/dso_lib.c new file mode 100644 index 0000000000..acd166697e --- /dev/null +++ b/src/lib/libcrypto/dso/dso_lib.c | |||
@@ -0,0 +1,306 @@ | |||
1 | /* dso_lib.c */ | ||
2 | /* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL | ||
3 | * project 2000. | ||
4 | */ | ||
5 | /* ==================================================================== | ||
6 | * Copyright (c) 2000 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 | #include <openssl/crypto.h> | ||
61 | #include "cryptlib.h" | ||
62 | #include <openssl/dso.h> | ||
63 | |||
64 | static DSO_METHOD *default_DSO_meth = NULL; | ||
65 | |||
66 | DSO *DSO_new(void) | ||
67 | { | ||
68 | return(DSO_new_method(NULL)); | ||
69 | } | ||
70 | |||
71 | void DSO_set_default_method(DSO_METHOD *meth) | ||
72 | { | ||
73 | default_DSO_meth = meth; | ||
74 | } | ||
75 | |||
76 | DSO_METHOD *DSO_get_default_method(void) | ||
77 | { | ||
78 | return(default_DSO_meth); | ||
79 | } | ||
80 | |||
81 | DSO_METHOD *DSO_get_method(DSO *dso) | ||
82 | { | ||
83 | return(dso->meth); | ||
84 | } | ||
85 | |||
86 | DSO_METHOD *DSO_set_method(DSO *dso, DSO_METHOD *meth) | ||
87 | { | ||
88 | DSO_METHOD *mtmp; | ||
89 | mtmp = dso->meth; | ||
90 | dso->meth = meth; | ||
91 | return(mtmp); | ||
92 | } | ||
93 | |||
94 | DSO *DSO_new_method(DSO_METHOD *meth) | ||
95 | { | ||
96 | DSO *ret; | ||
97 | |||
98 | if(default_DSO_meth == NULL) | ||
99 | /* We default to DSO_METH_openssl() which in turn defaults | ||
100 | * to stealing the "best available" method. Will fallback | ||
101 | * to DSO_METH_null() in the worst case. */ | ||
102 | default_DSO_meth = DSO_METHOD_openssl(); | ||
103 | ret = (DSO *)OPENSSL_malloc(sizeof(DSO)); | ||
104 | if(ret == NULL) | ||
105 | { | ||
106 | DSOerr(DSO_F_DSO_NEW_METHOD,ERR_R_MALLOC_FAILURE); | ||
107 | return(NULL); | ||
108 | } | ||
109 | memset(ret, 0, sizeof(DSO)); | ||
110 | ret->meth_data = sk_new_null(); | ||
111 | if((ret->meth_data = sk_new_null()) == NULL) | ||
112 | { | ||
113 | /* sk_new doesn't generate any errors so we do */ | ||
114 | DSOerr(DSO_F_DSO_NEW_METHOD,ERR_R_MALLOC_FAILURE); | ||
115 | OPENSSL_free(ret); | ||
116 | return(NULL); | ||
117 | } | ||
118 | if(meth == NULL) | ||
119 | ret->meth = default_DSO_meth; | ||
120 | else | ||
121 | ret->meth = meth; | ||
122 | ret->references = 1; | ||
123 | if((ret->meth->init != NULL) && !ret->meth->init(ret)) | ||
124 | { | ||
125 | OPENSSL_free(ret); | ||
126 | ret=NULL; | ||
127 | } | ||
128 | return(ret); | ||
129 | } | ||
130 | |||
131 | int DSO_free(DSO *dso) | ||
132 | { | ||
133 | int i; | ||
134 | |||
135 | if(dso == NULL) | ||
136 | { | ||
137 | DSOerr(DSO_F_DSO_FREE,ERR_R_PASSED_NULL_PARAMETER); | ||
138 | return(0); | ||
139 | } | ||
140 | |||
141 | i=CRYPTO_add(&dso->references,-1,CRYPTO_LOCK_DSO); | ||
142 | #ifdef REF_PRINT | ||
143 | REF_PRINT("DSO",dso); | ||
144 | #endif | ||
145 | if(i > 0) return(1); | ||
146 | #ifdef REF_CHECK | ||
147 | if(i < 0) | ||
148 | { | ||
149 | fprintf(stderr,"DSO_free, bad reference count\n"); | ||
150 | abort(); | ||
151 | } | ||
152 | #endif | ||
153 | |||
154 | if((dso->meth->dso_unload != NULL) && !dso->meth->dso_unload(dso)) | ||
155 | { | ||
156 | DSOerr(DSO_F_DSO_FREE,DSO_R_UNLOAD_FAILED); | ||
157 | return(0); | ||
158 | } | ||
159 | |||
160 | if((dso->meth->finish != NULL) && !dso->meth->finish(dso)) | ||
161 | { | ||
162 | DSOerr(DSO_F_DSO_FREE,DSO_R_FINISH_FAILED); | ||
163 | return(0); | ||
164 | } | ||
165 | |||
166 | sk_free(dso->meth_data); | ||
167 | |||
168 | OPENSSL_free(dso); | ||
169 | return(1); | ||
170 | } | ||
171 | |||
172 | int DSO_flags(DSO *dso) | ||
173 | { | ||
174 | return((dso == NULL) ? 0 : dso->flags); | ||
175 | } | ||
176 | |||
177 | |||
178 | int DSO_up(DSO *dso) | ||
179 | { | ||
180 | if (dso == NULL) | ||
181 | { | ||
182 | DSOerr(DSO_F_DSO_UP,ERR_R_PASSED_NULL_PARAMETER); | ||
183 | return(0); | ||
184 | } | ||
185 | |||
186 | CRYPTO_add(&dso->references,1,CRYPTO_LOCK_DSO); | ||
187 | return(1); | ||
188 | } | ||
189 | |||
190 | DSO *DSO_load(DSO *dso, const char *filename, DSO_METHOD *meth, int flags) | ||
191 | { | ||
192 | DSO *ret; | ||
193 | int allocated = 0; | ||
194 | |||
195 | if(filename == NULL) | ||
196 | { | ||
197 | DSOerr(DSO_F_DSO_LOAD,ERR_R_PASSED_NULL_PARAMETER); | ||
198 | return(NULL); | ||
199 | } | ||
200 | if(dso == NULL) | ||
201 | { | ||
202 | ret = DSO_new_method(meth); | ||
203 | if(ret == NULL) | ||
204 | { | ||
205 | DSOerr(DSO_F_DSO_LOAD,ERR_R_MALLOC_FAILURE); | ||
206 | return(NULL); | ||
207 | } | ||
208 | allocated = 1; | ||
209 | } | ||
210 | else | ||
211 | ret = dso; | ||
212 | /* Bleurgh ... have to check for negative return values for | ||
213 | * errors. <grimace> */ | ||
214 | if(DSO_ctrl(ret, DSO_CTRL_SET_FLAGS, flags, NULL) < 0) | ||
215 | { | ||
216 | DSOerr(DSO_F_DSO_LOAD,DSO_R_CTRL_FAILED); | ||
217 | if(allocated) | ||
218 | DSO_free(ret); | ||
219 | return(NULL); | ||
220 | } | ||
221 | if(ret->meth->dso_load == NULL) | ||
222 | { | ||
223 | DSOerr(DSO_F_DSO_LOAD,DSO_R_UNSUPPORTED); | ||
224 | if(allocated) | ||
225 | DSO_free(ret); | ||
226 | return(NULL); | ||
227 | } | ||
228 | if(!ret->meth->dso_load(ret, filename)) | ||
229 | { | ||
230 | DSOerr(DSO_F_DSO_LOAD,DSO_R_LOAD_FAILED); | ||
231 | if(allocated) | ||
232 | DSO_free(ret); | ||
233 | return(NULL); | ||
234 | } | ||
235 | /* Load succeeded */ | ||
236 | return(ret); | ||
237 | } | ||
238 | |||
239 | void *DSO_bind_var(DSO *dso, const char *symname) | ||
240 | { | ||
241 | void *ret = NULL; | ||
242 | |||
243 | if((dso == NULL) || (symname == NULL)) | ||
244 | { | ||
245 | DSOerr(DSO_F_DSO_BIND_VAR,ERR_R_PASSED_NULL_PARAMETER); | ||
246 | return(NULL); | ||
247 | } | ||
248 | if(dso->meth->dso_bind_var == NULL) | ||
249 | { | ||
250 | DSOerr(DSO_F_DSO_BIND_VAR,DSO_R_UNSUPPORTED); | ||
251 | return(NULL); | ||
252 | } | ||
253 | if((ret = dso->meth->dso_bind_var(dso, symname)) == NULL) | ||
254 | { | ||
255 | DSOerr(DSO_F_DSO_BIND_VAR,DSO_R_SYM_FAILURE); | ||
256 | return(NULL); | ||
257 | } | ||
258 | /* Success */ | ||
259 | return(ret); | ||
260 | } | ||
261 | |||
262 | DSO_FUNC_TYPE DSO_bind_func(DSO *dso, const char *symname) | ||
263 | { | ||
264 | DSO_FUNC_TYPE ret = NULL; | ||
265 | |||
266 | if((dso == NULL) || (symname == NULL)) | ||
267 | { | ||
268 | DSOerr(DSO_F_DSO_BIND_FUNC,ERR_R_PASSED_NULL_PARAMETER); | ||
269 | return(NULL); | ||
270 | } | ||
271 | if(dso->meth->dso_bind_func == NULL) | ||
272 | { | ||
273 | DSOerr(DSO_F_DSO_BIND_FUNC,DSO_R_UNSUPPORTED); | ||
274 | return(NULL); | ||
275 | } | ||
276 | if((ret = dso->meth->dso_bind_func(dso, symname)) == NULL) | ||
277 | { | ||
278 | DSOerr(DSO_F_DSO_BIND_FUNC,DSO_R_SYM_FAILURE); | ||
279 | return(NULL); | ||
280 | } | ||
281 | /* Success */ | ||
282 | return(ret); | ||
283 | } | ||
284 | |||
285 | /* I don't really like these *_ctrl functions very much to be perfectly | ||
286 | * honest. For one thing, I think I have to return a negative value for | ||
287 | * any error because possible DSO_ctrl() commands may return values | ||
288 | * such as "size"s that can legitimately be zero (making the standard | ||
289 | * "if(DSO_cmd(...))" form that works almost everywhere else fail at | ||
290 | * odd times. I'd prefer "output" values to be passed by reference and | ||
291 | * the return value as success/failure like usual ... but we conform | ||
292 | * when we must... :-) */ | ||
293 | long DSO_ctrl(DSO *dso, int cmd, long larg, void *parg) | ||
294 | { | ||
295 | if(dso == NULL) | ||
296 | { | ||
297 | DSOerr(DSO_F_DSO_CTRL,ERR_R_PASSED_NULL_PARAMETER); | ||
298 | return(-1); | ||
299 | } | ||
300 | if((dso->meth == NULL) || (dso->meth->dso_ctrl == NULL)) | ||
301 | { | ||
302 | DSOerr(DSO_F_DSO_CTRL,DSO_R_UNSUPPORTED); | ||
303 | return(-1); | ||
304 | } | ||
305 | return(dso->meth->dso_ctrl(dso,cmd,larg,parg)); | ||
306 | } | ||
diff --git a/src/lib/libcrypto/dso/dso_null.c b/src/lib/libcrypto/dso/dso_null.c new file mode 100644 index 0000000000..fa13a7cb0f --- /dev/null +++ b/src/lib/libcrypto/dso/dso_null.c | |||
@@ -0,0 +1,86 @@ | |||
1 | /* dso_null.c */ | ||
2 | /* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL | ||
3 | * project 2000. | ||
4 | */ | ||
5 | /* ==================================================================== | ||
6 | * Copyright (c) 2000 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 | /* This "NULL" method is provided as the fallback for systems that have | ||
60 | * no appropriate support for "shared-libraries". */ | ||
61 | |||
62 | #include <stdio.h> | ||
63 | #include "cryptlib.h" | ||
64 | #include <openssl/dso.h> | ||
65 | |||
66 | static DSO_METHOD dso_meth_null = { | ||
67 | "NULL shared library method", | ||
68 | NULL, /* load */ | ||
69 | NULL, /* unload */ | ||
70 | NULL, /* bind_var */ | ||
71 | NULL, /* bind_func */ | ||
72 | /* For now, "unbind" doesn't exist */ | ||
73 | #if 0 | ||
74 | NULL, /* unbind_var */ | ||
75 | NULL, /* unbind_func */ | ||
76 | #endif | ||
77 | NULL, /* ctrl */ | ||
78 | NULL, /* init */ | ||
79 | NULL /* finish */ | ||
80 | }; | ||
81 | |||
82 | DSO_METHOD *DSO_METHOD_null(void) | ||
83 | { | ||
84 | return(&dso_meth_null); | ||
85 | } | ||
86 | |||
diff --git a/src/lib/libcrypto/dso/dso_openssl.c b/src/lib/libcrypto/dso/dso_openssl.c new file mode 100644 index 0000000000..a4395ebffe --- /dev/null +++ b/src/lib/libcrypto/dso/dso_openssl.c | |||
@@ -0,0 +1,81 @@ | |||
1 | /* dso_openssl.c */ | ||
2 | /* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL | ||
3 | * project 2000. | ||
4 | */ | ||
5 | /* ==================================================================== | ||
6 | * Copyright (c) 2000 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 | #include "cryptlib.h" | ||
61 | #include <openssl/dso.h> | ||
62 | |||
63 | /* We just pinch the method from an appropriate "default" method. */ | ||
64 | |||
65 | DSO_METHOD *DSO_METHOD_openssl(void) | ||
66 | { | ||
67 | #ifdef DEF_DSO_METHOD | ||
68 | return(DEF_DSO_METHOD()); | ||
69 | #elif defined(DSO_DLFCN) | ||
70 | return(DSO_METHOD_dlfcn()); | ||
71 | #elif defined(DSO_DL) | ||
72 | return(DSO_METHOD_dl()); | ||
73 | #elif defined(DSO_WIN32) | ||
74 | return(DSO_METHOD_win32()); | ||
75 | #elif defined(DSO_VMS) | ||
76 | return(DSO_METHOD_vms()); | ||
77 | #else | ||
78 | return(DSO_METHOD_null()); | ||
79 | #endif | ||
80 | } | ||
81 | |||
diff --git a/src/lib/libcrypto/ec/ec.h b/src/lib/libcrypto/ec/ec.h new file mode 100644 index 0000000000..a52d4edf14 --- /dev/null +++ b/src/lib/libcrypto/ec/ec.h | |||
@@ -0,0 +1,245 @@ | |||
1 | /* crypto/ec/ec.h */ | ||
2 | /* ==================================================================== | ||
3 | * Copyright (c) 1998-2001 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 | #ifndef HEADER_EC_H | ||
57 | #define HEADER_EC_H | ||
58 | |||
59 | #ifdef OPENSSL_NO_EC | ||
60 | #error EC is disabled. | ||
61 | #endif | ||
62 | |||
63 | #include <openssl/bn.h> | ||
64 | #include <openssl/symhacks.h> | ||
65 | |||
66 | #ifdef __cplusplus | ||
67 | extern "C" { | ||
68 | #endif | ||
69 | |||
70 | |||
71 | typedef enum { | ||
72 | /* values as defined in X9.62 (ECDSA) and elsewhere */ | ||
73 | POINT_CONVERSION_COMPRESSED = 2, | ||
74 | POINT_CONVERSION_UNCOMPRESSED = 4, | ||
75 | POINT_CONVERSION_HYBRID = 6 | ||
76 | } point_conversion_form_t; | ||
77 | |||
78 | |||
79 | typedef struct ec_method_st EC_METHOD; | ||
80 | |||
81 | typedef struct ec_group_st | ||
82 | /* | ||
83 | EC_METHOD *meth; | ||
84 | -- field definition | ||
85 | -- curve coefficients | ||
86 | -- optional generator with associated information (order, cofactor) | ||
87 | -- optional extra data (TODO: precomputed table for fast computation of multiples of generator) | ||
88 | */ | ||
89 | EC_GROUP; | ||
90 | |||
91 | typedef struct ec_point_st EC_POINT; | ||
92 | |||
93 | |||
94 | /* EC_METHODs for curves over GF(p). | ||
95 | * EC_GFp_simple_method provides the basis for the optimized methods. | ||
96 | */ | ||
97 | const EC_METHOD *EC_GFp_simple_method(void); | ||
98 | const EC_METHOD *EC_GFp_mont_method(void); | ||
99 | #if 0 | ||
100 | const EC_METHOD *EC_GFp_recp_method(void); /* TODO */ | ||
101 | const EC_METHOD *EC_GFp_nist_method(void); /* TODO */ | ||
102 | #endif | ||
103 | |||
104 | |||
105 | EC_GROUP *EC_GROUP_new(const EC_METHOD *); | ||
106 | void EC_GROUP_free(EC_GROUP *); | ||
107 | void EC_GROUP_clear_free(EC_GROUP *); | ||
108 | int EC_GROUP_copy(EC_GROUP *, const EC_GROUP *); | ||
109 | |||
110 | const EC_METHOD *EC_GROUP_method_of(const EC_GROUP *); | ||
111 | |||
112 | |||
113 | /* We don't have types for field specifications and field elements in general. | ||
114 | * Otherwise we could declare | ||
115 | * int EC_GROUP_set_curve(EC_GROUP *, .....); | ||
116 | */ | ||
117 | int EC_GROUP_set_curve_GFp(EC_GROUP *, const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *); | ||
118 | int EC_GROUP_get_curve_GFp(const EC_GROUP *, BIGNUM *p, BIGNUM *a, BIGNUM *b, BN_CTX *); | ||
119 | |||
120 | /* EC_GROUP_new_GFp() calls EC_GROUP_new() and EC_GROUP_set_GFp() | ||
121 | * after choosing an appropriate EC_METHOD */ | ||
122 | EC_GROUP *EC_GROUP_new_curve_GFp(const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *); | ||
123 | |||
124 | int EC_GROUP_set_generator(EC_GROUP *, const EC_POINT *generator, const BIGNUM *order, const BIGNUM *cofactor); | ||
125 | EC_POINT *EC_GROUP_get0_generator(const EC_GROUP *); | ||
126 | int EC_GROUP_get_order(const EC_GROUP *, BIGNUM *order, BN_CTX *); | ||
127 | int EC_GROUP_get_cofactor(const EC_GROUP *, BIGNUM *cofactor, BN_CTX *); | ||
128 | |||
129 | EC_POINT *EC_POINT_new(const EC_GROUP *); | ||
130 | void EC_POINT_free(EC_POINT *); | ||
131 | void EC_POINT_clear_free(EC_POINT *); | ||
132 | int EC_POINT_copy(EC_POINT *, const EC_POINT *); | ||
133 | |||
134 | const EC_METHOD *EC_POINT_method_of(const EC_POINT *); | ||
135 | |||
136 | int EC_POINT_set_to_infinity(const EC_GROUP *, EC_POINT *); | ||
137 | int EC_POINT_set_Jprojective_coordinates_GFp(const EC_GROUP *, EC_POINT *, | ||
138 | const BIGNUM *x, const BIGNUM *y, const BIGNUM *z, BN_CTX *); | ||
139 | int EC_POINT_get_Jprojective_coordinates_GFp(const EC_GROUP *, const EC_POINT *, | ||
140 | BIGNUM *x, BIGNUM *y, BIGNUM *z, BN_CTX *); | ||
141 | int EC_POINT_set_affine_coordinates_GFp(const EC_GROUP *, EC_POINT *, | ||
142 | const BIGNUM *x, const BIGNUM *y, BN_CTX *); | ||
143 | int EC_POINT_get_affine_coordinates_GFp(const EC_GROUP *, const EC_POINT *, | ||
144 | BIGNUM *x, BIGNUM *y, BN_CTX *); | ||
145 | int EC_POINT_set_compressed_coordinates_GFp(const EC_GROUP *, EC_POINT *, | ||
146 | const BIGNUM *x, int y_bit, BN_CTX *); | ||
147 | |||
148 | size_t EC_POINT_point2oct(const EC_GROUP *, const EC_POINT *, point_conversion_form_t form, | ||
149 | unsigned char *buf, size_t len, BN_CTX *); | ||
150 | int EC_POINT_oct2point(const EC_GROUP *, EC_POINT *, | ||
151 | const unsigned char *buf, size_t len, BN_CTX *); | ||
152 | |||
153 | int EC_POINT_add(const EC_GROUP *, EC_POINT *r, const EC_POINT *a, const EC_POINT *b, BN_CTX *); | ||
154 | int EC_POINT_dbl(const EC_GROUP *, EC_POINT *r, const EC_POINT *a, BN_CTX *); | ||
155 | int EC_POINT_invert(const EC_GROUP *, EC_POINT *, BN_CTX *); | ||
156 | |||
157 | int EC_POINT_is_at_infinity(const EC_GROUP *, const EC_POINT *); | ||
158 | int EC_POINT_is_on_curve(const EC_GROUP *, const EC_POINT *, BN_CTX *); | ||
159 | int EC_POINT_cmp(const EC_GROUP *, const EC_POINT *a, const EC_POINT *b, BN_CTX *); | ||
160 | |||
161 | int EC_POINT_make_affine(const EC_GROUP *, EC_POINT *, BN_CTX *); | ||
162 | int EC_POINTs_make_affine(const EC_GROUP *, size_t num, EC_POINT *[], BN_CTX *); | ||
163 | |||
164 | |||
165 | int EC_POINTs_mul(const EC_GROUP *, EC_POINT *r, const BIGNUM *, size_t num, const EC_POINT *[], const BIGNUM *[], BN_CTX *); | ||
166 | int EC_POINT_mul(const EC_GROUP *, EC_POINT *r, const BIGNUM *, const EC_POINT *, const BIGNUM *, BN_CTX *); | ||
167 | int EC_GROUP_precompute_mult(EC_GROUP *, BN_CTX *); | ||
168 | |||
169 | |||
170 | |||
171 | /* BEGIN ERROR CODES */ | ||
172 | /* The following lines are auto generated by the script mkerr.pl. Any changes | ||
173 | * made after this point may be overwritten when the script is next run. | ||
174 | */ | ||
175 | void ERR_load_EC_strings(void); | ||
176 | |||
177 | /* Error codes for the EC functions. */ | ||
178 | |||
179 | /* Function codes. */ | ||
180 | #define EC_F_COMPUTE_WNAF 143 | ||
181 | #define EC_F_EC_GFP_MONT_FIELD_DECODE 133 | ||
182 | #define EC_F_EC_GFP_MONT_FIELD_ENCODE 134 | ||
183 | #define EC_F_EC_GFP_MONT_FIELD_MUL 131 | ||
184 | #define EC_F_EC_GFP_MONT_FIELD_SQR 132 | ||
185 | #define EC_F_EC_GFP_SIMPLE_GROUP_SET_CURVE_GFP 100 | ||
186 | #define EC_F_EC_GFP_SIMPLE_GROUP_SET_GENERATOR 101 | ||
187 | #define EC_F_EC_GFP_SIMPLE_MAKE_AFFINE 102 | ||
188 | #define EC_F_EC_GFP_SIMPLE_OCT2POINT 103 | ||
189 | #define EC_F_EC_GFP_SIMPLE_POINT2OCT 104 | ||
190 | #define EC_F_EC_GFP_SIMPLE_POINTS_MAKE_AFFINE 137 | ||
191 | #define EC_F_EC_GFP_SIMPLE_POINT_GET_AFFINE_COORDINATES_GFP 105 | ||
192 | #define EC_F_EC_GFP_SIMPLE_POINT_SET_AFFINE_COORDINATES_GFP 128 | ||
193 | #define EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES_GFP 129 | ||
194 | #define EC_F_EC_GROUP_COPY 106 | ||
195 | #define EC_F_EC_GROUP_GET0_GENERATOR 139 | ||
196 | #define EC_F_EC_GROUP_GET_COFACTOR 140 | ||
197 | #define EC_F_EC_GROUP_GET_CURVE_GFP 130 | ||
198 | #define EC_F_EC_GROUP_GET_EXTRA_DATA 107 | ||
199 | #define EC_F_EC_GROUP_GET_ORDER 141 | ||
200 | #define EC_F_EC_GROUP_NEW 108 | ||
201 | #define EC_F_EC_GROUP_PRECOMPUTE_MULT 142 | ||
202 | #define EC_F_EC_GROUP_SET_CURVE_GFP 109 | ||
203 | #define EC_F_EC_GROUP_SET_EXTRA_DATA 110 | ||
204 | #define EC_F_EC_GROUP_SET_GENERATOR 111 | ||
205 | #define EC_F_EC_POINTS_MAKE_AFFINE 136 | ||
206 | #define EC_F_EC_POINTS_MUL 138 | ||
207 | #define EC_F_EC_POINT_ADD 112 | ||
208 | #define EC_F_EC_POINT_CMP 113 | ||
209 | #define EC_F_EC_POINT_COPY 114 | ||
210 | #define EC_F_EC_POINT_DBL 115 | ||
211 | #define EC_F_EC_POINT_GET_AFFINE_COORDINATES_GFP 116 | ||
212 | #define EC_F_EC_POINT_GET_JPROJECTIVE_COORDINATES_GFP 117 | ||
213 | #define EC_F_EC_POINT_IS_AT_INFINITY 118 | ||
214 | #define EC_F_EC_POINT_IS_ON_CURVE 119 | ||
215 | #define EC_F_EC_POINT_MAKE_AFFINE 120 | ||
216 | #define EC_F_EC_POINT_NEW 121 | ||
217 | #define EC_F_EC_POINT_OCT2POINT 122 | ||
218 | #define EC_F_EC_POINT_POINT2OCT 123 | ||
219 | #define EC_F_EC_POINT_SET_AFFINE_COORDINATES_GFP 124 | ||
220 | #define EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GFP 125 | ||
221 | #define EC_F_EC_POINT_SET_JPROJECTIVE_COORDINATES_GFP 126 | ||
222 | #define EC_F_EC_POINT_SET_TO_INFINITY 127 | ||
223 | #define EC_F_GFP_MONT_GROUP_SET_CURVE_GFP 135 | ||
224 | |||
225 | /* Reason codes. */ | ||
226 | #define EC_R_BUFFER_TOO_SMALL 100 | ||
227 | #define EC_R_INCOMPATIBLE_OBJECTS 101 | ||
228 | #define EC_R_INVALID_ARGUMENT 112 | ||
229 | #define EC_R_INVALID_COMPRESSED_POINT 110 | ||
230 | #define EC_R_INVALID_COMPRESSION_BIT 109 | ||
231 | #define EC_R_INVALID_ENCODING 102 | ||
232 | #define EC_R_INVALID_FIELD 103 | ||
233 | #define EC_R_INVALID_FORM 104 | ||
234 | #define EC_R_NOT_INITIALIZED 111 | ||
235 | #define EC_R_NO_SUCH_EXTRA_DATA 105 | ||
236 | #define EC_R_POINT_AT_INFINITY 106 | ||
237 | #define EC_R_POINT_IS_NOT_ON_CURVE 107 | ||
238 | #define EC_R_SLOT_FULL 108 | ||
239 | #define EC_R_UNDEFINED_GENERATOR 113 | ||
240 | #define EC_R_UNKNOWN_ORDER 114 | ||
241 | |||
242 | #ifdef __cplusplus | ||
243 | } | ||
244 | #endif | ||
245 | #endif | ||
diff --git a/src/lib/libcrypto/ec/ec_cvt.c b/src/lib/libcrypto/ec/ec_cvt.c new file mode 100644 index 0000000000..45b0ec33a0 --- /dev/null +++ b/src/lib/libcrypto/ec/ec_cvt.c | |||
@@ -0,0 +1,80 @@ | |||
1 | /* crypto/ec/ec_cvt.c */ | ||
2 | /* ==================================================================== | ||
3 | * Copyright (c) 1998-2001 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 | |||
58 | |||
59 | EC_GROUP *EC_GROUP_new_curve_GFp(const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx) | ||
60 | { | ||
61 | const EC_METHOD *meth; | ||
62 | EC_GROUP *ret; | ||
63 | |||
64 | /* Finally, this will use EC_GFp_nist_method if 'p' is a special | ||
65 | * prime with optimized modular arithmetics (for NIST curves) | ||
66 | */ | ||
67 | meth = EC_GFp_mont_method(); | ||
68 | |||
69 | ret = EC_GROUP_new(meth); | ||
70 | if (ret == NULL) | ||
71 | return NULL; | ||
72 | |||
73 | if (!EC_GROUP_set_curve_GFp(ret, p, a, b, ctx)) | ||
74 | { | ||
75 | EC_GROUP_clear_free(ret); | ||
76 | return NULL; | ||
77 | } | ||
78 | |||
79 | return ret; | ||
80 | } | ||
diff --git a/src/lib/libcrypto/ec/ec_err.c b/src/lib/libcrypto/ec/ec_err.c new file mode 100644 index 0000000000..394cdc021f --- /dev/null +++ b/src/lib/libcrypto/ec/ec_err.c | |||
@@ -0,0 +1,151 @@ | |||
1 | /* crypto/ec/ec_err.c */ | ||
2 | /* ==================================================================== | ||
3 | * Copyright (c) 1999 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/ec.h> | ||
64 | |||
65 | /* BEGIN ERROR CODES */ | ||
66 | #ifndef OPENSSL_NO_ERR | ||
67 | static ERR_STRING_DATA EC_str_functs[]= | ||
68 | { | ||
69 | {ERR_PACK(0,EC_F_COMPUTE_WNAF,0), "COMPUTE_WNAF"}, | ||
70 | {ERR_PACK(0,EC_F_EC_GFP_MONT_FIELD_DECODE,0), "ec_GFp_mont_field_decode"}, | ||
71 | {ERR_PACK(0,EC_F_EC_GFP_MONT_FIELD_ENCODE,0), "ec_GFp_mont_field_encode"}, | ||
72 | {ERR_PACK(0,EC_F_EC_GFP_MONT_FIELD_MUL,0), "ec_GFp_mont_field_mul"}, | ||
73 | {ERR_PACK(0,EC_F_EC_GFP_MONT_FIELD_SQR,0), "ec_GFp_mont_field_sqr"}, | ||
74 | {ERR_PACK(0,EC_F_EC_GFP_SIMPLE_GROUP_SET_CURVE_GFP,0), "ec_GFp_simple_group_set_curve_GFp"}, | ||
75 | {ERR_PACK(0,EC_F_EC_GFP_SIMPLE_GROUP_SET_GENERATOR,0), "ec_GFp_simple_group_set_generator"}, | ||
76 | {ERR_PACK(0,EC_F_EC_GFP_SIMPLE_MAKE_AFFINE,0), "ec_GFp_simple_make_affine"}, | ||
77 | {ERR_PACK(0,EC_F_EC_GFP_SIMPLE_OCT2POINT,0), "ec_GFp_simple_oct2point"}, | ||
78 | {ERR_PACK(0,EC_F_EC_GFP_SIMPLE_POINT2OCT,0), "ec_GFp_simple_point2oct"}, | ||
79 | {ERR_PACK(0,EC_F_EC_GFP_SIMPLE_POINTS_MAKE_AFFINE,0), "ec_GFp_simple_points_make_affine"}, | ||
80 | {ERR_PACK(0,EC_F_EC_GFP_SIMPLE_POINT_GET_AFFINE_COORDINATES_GFP,0), "ec_GFp_simple_point_get_affine_coordinates_GFp"}, | ||
81 | {ERR_PACK(0,EC_F_EC_GFP_SIMPLE_POINT_SET_AFFINE_COORDINATES_GFP,0), "ec_GFp_simple_point_set_affine_coordinates_GFp"}, | ||
82 | {ERR_PACK(0,EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES_GFP,0), "ec_GFp_simple_set_compressed_coordinates_GFp"}, | ||
83 | {ERR_PACK(0,EC_F_EC_GROUP_COPY,0), "EC_GROUP_copy"}, | ||
84 | {ERR_PACK(0,EC_F_EC_GROUP_GET0_GENERATOR,0), "EC_GROUP_get0_generator"}, | ||
85 | {ERR_PACK(0,EC_F_EC_GROUP_GET_COFACTOR,0), "EC_GROUP_get_cofactor"}, | ||
86 | {ERR_PACK(0,EC_F_EC_GROUP_GET_CURVE_GFP,0), "EC_GROUP_get_curve_GFp"}, | ||
87 | {ERR_PACK(0,EC_F_EC_GROUP_GET_EXTRA_DATA,0), "EC_GROUP_get_extra_data"}, | ||
88 | {ERR_PACK(0,EC_F_EC_GROUP_GET_ORDER,0), "EC_GROUP_get_order"}, | ||
89 | {ERR_PACK(0,EC_F_EC_GROUP_NEW,0), "EC_GROUP_new"}, | ||
90 | {ERR_PACK(0,EC_F_EC_GROUP_PRECOMPUTE_MULT,0), "EC_GROUP_precompute_mult"}, | ||
91 | {ERR_PACK(0,EC_F_EC_GROUP_SET_CURVE_GFP,0), "EC_GROUP_set_curve_GFp"}, | ||
92 | {ERR_PACK(0,EC_F_EC_GROUP_SET_EXTRA_DATA,0), "EC_GROUP_set_extra_data"}, | ||
93 | {ERR_PACK(0,EC_F_EC_GROUP_SET_GENERATOR,0), "EC_GROUP_set_generator"}, | ||
94 | {ERR_PACK(0,EC_F_EC_POINTS_MAKE_AFFINE,0), "EC_POINTs_make_affine"}, | ||
95 | {ERR_PACK(0,EC_F_EC_POINTS_MUL,0), "EC_POINTs_mul"}, | ||
96 | {ERR_PACK(0,EC_F_EC_POINT_ADD,0), "EC_POINT_add"}, | ||
97 | {ERR_PACK(0,EC_F_EC_POINT_CMP,0), "EC_POINT_cmp"}, | ||
98 | {ERR_PACK(0,EC_F_EC_POINT_COPY,0), "EC_POINT_copy"}, | ||
99 | {ERR_PACK(0,EC_F_EC_POINT_DBL,0), "EC_POINT_dbl"}, | ||
100 | {ERR_PACK(0,EC_F_EC_POINT_GET_AFFINE_COORDINATES_GFP,0), "EC_POINT_get_affine_coordinates_GFp"}, | ||
101 | {ERR_PACK(0,EC_F_EC_POINT_GET_JPROJECTIVE_COORDINATES_GFP,0), "EC_POINT_get_Jprojective_coordinates_GFp"}, | ||
102 | {ERR_PACK(0,EC_F_EC_POINT_IS_AT_INFINITY,0), "EC_POINT_is_at_infinity"}, | ||
103 | {ERR_PACK(0,EC_F_EC_POINT_IS_ON_CURVE,0), "EC_POINT_is_on_curve"}, | ||
104 | {ERR_PACK(0,EC_F_EC_POINT_MAKE_AFFINE,0), "EC_POINT_make_affine"}, | ||
105 | {ERR_PACK(0,EC_F_EC_POINT_NEW,0), "EC_POINT_new"}, | ||
106 | {ERR_PACK(0,EC_F_EC_POINT_OCT2POINT,0), "EC_POINT_oct2point"}, | ||
107 | {ERR_PACK(0,EC_F_EC_POINT_POINT2OCT,0), "EC_POINT_point2oct"}, | ||
108 | {ERR_PACK(0,EC_F_EC_POINT_SET_AFFINE_COORDINATES_GFP,0), "EC_POINT_set_affine_coordinates_GFp"}, | ||
109 | {ERR_PACK(0,EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GFP,0), "EC_POINT_set_compressed_coordinates_GFp"}, | ||
110 | {ERR_PACK(0,EC_F_EC_POINT_SET_JPROJECTIVE_COORDINATES_GFP,0), "EC_POINT_set_Jprojective_coordinates_GFp"}, | ||
111 | {ERR_PACK(0,EC_F_EC_POINT_SET_TO_INFINITY,0), "EC_POINT_set_to_infinity"}, | ||
112 | {ERR_PACK(0,EC_F_GFP_MONT_GROUP_SET_CURVE_GFP,0), "GFP_MONT_GROUP_SET_CURVE_GFP"}, | ||
113 | {0,NULL} | ||
114 | }; | ||
115 | |||
116 | static ERR_STRING_DATA EC_str_reasons[]= | ||
117 | { | ||
118 | {EC_R_BUFFER_TOO_SMALL ,"buffer too small"}, | ||
119 | {EC_R_INCOMPATIBLE_OBJECTS ,"incompatible objects"}, | ||
120 | {EC_R_INVALID_ARGUMENT ,"invalid argument"}, | ||
121 | {EC_R_INVALID_COMPRESSED_POINT ,"invalid compressed point"}, | ||
122 | {EC_R_INVALID_COMPRESSION_BIT ,"invalid compression bit"}, | ||
123 | {EC_R_INVALID_ENCODING ,"invalid encoding"}, | ||
124 | {EC_R_INVALID_FIELD ,"invalid field"}, | ||
125 | {EC_R_INVALID_FORM ,"invalid form"}, | ||
126 | {EC_R_NOT_INITIALIZED ,"not initialized"}, | ||
127 | {EC_R_NO_SUCH_EXTRA_DATA ,"no such extra data"}, | ||
128 | {EC_R_POINT_AT_INFINITY ,"point at infinity"}, | ||
129 | {EC_R_POINT_IS_NOT_ON_CURVE ,"point is not on curve"}, | ||
130 | {EC_R_SLOT_FULL ,"slot full"}, | ||
131 | {EC_R_UNDEFINED_GENERATOR ,"undefined generator"}, | ||
132 | {EC_R_UNKNOWN_ORDER ,"unknown order"}, | ||
133 | {0,NULL} | ||
134 | }; | ||
135 | |||
136 | #endif | ||
137 | |||
138 | void ERR_load_EC_strings(void) | ||
139 | { | ||
140 | static int init=1; | ||
141 | |||
142 | if (init) | ||
143 | { | ||
144 | init=0; | ||
145 | #ifndef OPENSSL_NO_ERR | ||
146 | ERR_load_strings(ERR_LIB_EC,EC_str_functs); | ||
147 | ERR_load_strings(ERR_LIB_EC,EC_str_reasons); | ||
148 | #endif | ||
149 | |||
150 | } | ||
151 | } | ||
diff --git a/src/lib/libcrypto/ec/ec_lcl.h b/src/lib/libcrypto/ec/ec_lcl.h new file mode 100644 index 0000000000..cc4cf27755 --- /dev/null +++ b/src/lib/libcrypto/ec/ec_lcl.h | |||
@@ -0,0 +1,277 @@ | |||
1 | /* crypto/ec/ec_lcl.h */ | ||
2 | /* ==================================================================== | ||
3 | * Copyright (c) 1998-2001 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 | #include <stdlib.h> | ||
58 | |||
59 | #include <openssl/ec.h> | ||
60 | |||
61 | |||
62 | /* Structure details are not part of the exported interface, | ||
63 | * so all this may change in future versions. */ | ||
64 | |||
65 | struct ec_method_st { | ||
66 | /* used by EC_GROUP_new, EC_GROUP_free, EC_GROUP_clear_free, EC_GROUP_copy: */ | ||
67 | int (*group_init)(EC_GROUP *); | ||
68 | void (*group_finish)(EC_GROUP *); | ||
69 | void (*group_clear_finish)(EC_GROUP *); | ||
70 | int (*group_copy)(EC_GROUP *, const EC_GROUP *); | ||
71 | |||
72 | /* used by EC_GROUP_set_curve_GFp and EC_GROUP_get_curve_GFp: */ | ||
73 | int (*group_set_curve_GFp)(EC_GROUP *, const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *); | ||
74 | int (*group_get_curve_GFp)(const EC_GROUP *, BIGNUM *p, BIGNUM *a, BIGNUM *b, BN_CTX *); | ||
75 | |||
76 | /* used by EC_GROUP_set_generator, EC_GROUP_get0_generator, | ||
77 | * EC_GROUP_get_order, EC_GROUP_get_cofactor: | ||
78 | */ | ||
79 | int (*group_set_generator)(EC_GROUP *, const EC_POINT *generator, | ||
80 | const BIGNUM *order, const BIGNUM *cofactor); | ||
81 | EC_POINT *(*group_get0_generator)(const EC_GROUP *); | ||
82 | int (*group_get_order)(const EC_GROUP *, BIGNUM *order, BN_CTX *); | ||
83 | int (*group_get_cofactor)(const EC_GROUP *, BIGNUM *cofactor, BN_CTX *); | ||
84 | |||
85 | /* used by EC_POINT_new, EC_POINT_free, EC_POINT_clear_free, EC_POINT_copy: */ | ||
86 | int (*point_init)(EC_POINT *); | ||
87 | void (*point_finish)(EC_POINT *); | ||
88 | void (*point_clear_finish)(EC_POINT *); | ||
89 | int (*point_copy)(EC_POINT *, const EC_POINT *); | ||
90 | |||
91 | /* used by EC_POINT_set_to_infinity, | ||
92 | * EC_POINT_set_Jprojective_coordinates_GFp, EC_POINT_get_Jprojective_coordinates_GFp, | ||
93 | * EC_POINT_set_affine_coordinates_GFp, EC_POINT_get_affine_coordinates_GFp, | ||
94 | * EC_POINT_set_compressed_coordinates_GFp: | ||
95 | */ | ||
96 | int (*point_set_to_infinity)(const EC_GROUP *, EC_POINT *); | ||
97 | int (*point_set_Jprojective_coordinates_GFp)(const EC_GROUP *, EC_POINT *, | ||
98 | const BIGNUM *x, const BIGNUM *y, const BIGNUM *z, BN_CTX *); | ||
99 | int (*point_get_Jprojective_coordinates_GFp)(const EC_GROUP *, const EC_POINT *, | ||
100 | BIGNUM *x, BIGNUM *y, BIGNUM *z, BN_CTX *); | ||
101 | int (*point_set_affine_coordinates_GFp)(const EC_GROUP *, EC_POINT *, | ||
102 | const BIGNUM *x, const BIGNUM *y, BN_CTX *); | ||
103 | int (*point_get_affine_coordinates_GFp)(const EC_GROUP *, const EC_POINT *, | ||
104 | BIGNUM *x, BIGNUM *y, BN_CTX *); | ||
105 | int (*point_set_compressed_coordinates_GFp)(const EC_GROUP *, EC_POINT *, | ||
106 | const BIGNUM *x, int y_bit, BN_CTX *); | ||
107 | |||
108 | /* used by EC_POINT_point2oct, EC_POINT_oct2point: */ | ||
109 | size_t (*point2oct)(const EC_GROUP *, const EC_POINT *, point_conversion_form_t form, | ||
110 | unsigned char *buf, size_t len, BN_CTX *); | ||
111 | int (*oct2point)(const EC_GROUP *, EC_POINT *, | ||
112 | const unsigned char *buf, size_t len, BN_CTX *); | ||
113 | |||
114 | /* used by EC_POINT_add, EC_POINT_dbl, ECP_POINT_invert: */ | ||
115 | int (*add)(const EC_GROUP *, EC_POINT *r, const EC_POINT *a, const EC_POINT *b, BN_CTX *); | ||
116 | int (*dbl)(const EC_GROUP *, EC_POINT *r, const EC_POINT *a, BN_CTX *); | ||
117 | int (*invert)(const EC_GROUP *, EC_POINT *, BN_CTX *); | ||
118 | |||
119 | /* used by EC_POINT_is_at_infinity, EC_POINT_is_on_curve, EC_POINT_cmp: */ | ||
120 | int (*is_at_infinity)(const EC_GROUP *, const EC_POINT *); | ||
121 | int (*is_on_curve)(const EC_GROUP *, const EC_POINT *, BN_CTX *); | ||
122 | int (*point_cmp)(const EC_GROUP *, const EC_POINT *a, const EC_POINT *b, BN_CTX *); | ||
123 | |||
124 | /* used by EC_POINT_make_affine, EC_POINTs_make_affine: */ | ||
125 | int (*make_affine)(const EC_GROUP *, EC_POINT *, BN_CTX *); | ||
126 | int (*points_make_affine)(const EC_GROUP *, size_t num, EC_POINT *[], BN_CTX *); | ||
127 | |||
128 | |||
129 | /* internal functions */ | ||
130 | |||
131 | /* 'field_mul' and 'field_sqr' can be used by 'add' and 'dbl' so that | ||
132 | * the same implementations of point operations can be used with different | ||
133 | * optimized implementations of expensive field operations: */ | ||
134 | int (*field_mul)(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *); | ||
135 | int (*field_sqr)(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, BN_CTX *); | ||
136 | |||
137 | int (*field_encode)(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, BN_CTX *); /* e.g. to Montgomery */ | ||
138 | int (*field_decode)(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, BN_CTX *); /* e.g. from Montgomery */ | ||
139 | int (*field_set_to_one)(const EC_GROUP *, BIGNUM *r, BN_CTX *); | ||
140 | } /* EC_METHOD */; | ||
141 | |||
142 | |||
143 | struct ec_group_st { | ||
144 | const EC_METHOD *meth; | ||
145 | |||
146 | void *extra_data; | ||
147 | void *(*extra_data_dup_func)(void *); | ||
148 | void (*extra_data_free_func)(void *); | ||
149 | void (*extra_data_clear_free_func)(void *); | ||
150 | |||
151 | /* All members except 'meth' and 'extra_data...' are handled by | ||
152 | * the method functions, even if they appear generic */ | ||
153 | |||
154 | BIGNUM field; /* Field specification. | ||
155 | * For curves over GF(p), this is the modulus. */ | ||
156 | |||
157 | BIGNUM a, b; /* Curve coefficients. | ||
158 | * (Here the assumption is that BIGNUMs can be used | ||
159 | * or abused for all kinds of fields, not just GF(p).) | ||
160 | * For characteristic > 3, the curve is defined | ||
161 | * by a Weierstrass equation of the form | ||
162 | * y^2 = x^3 + a*x + b. | ||
163 | */ | ||
164 | int a_is_minus3; /* enable optimized point arithmetics for special case */ | ||
165 | |||
166 | EC_POINT *generator; /* optional */ | ||
167 | BIGNUM order, cofactor; | ||
168 | |||
169 | void *field_data1; /* method-specific (e.g., Montgomery structure) */ | ||
170 | void *field_data2; /* method-specific */ | ||
171 | } /* EC_GROUP */; | ||
172 | |||
173 | |||
174 | /* Basically a 'mixin' for extra data, but available for EC_GROUPs only | ||
175 | * (with visibility limited to 'package' level for now). | ||
176 | * We use the function pointers as index for retrieval; this obviates | ||
177 | * global ex_data-style index tables. | ||
178 | * (Currently, we have one slot only, but is is possible to extend this | ||
179 | * if necessary.) */ | ||
180 | int EC_GROUP_set_extra_data(EC_GROUP *, void *extra_data, void *(*extra_data_dup_func)(void *), | ||
181 | void (*extra_data_free_func)(void *), void (*extra_data_clear_free_func)(void *)); | ||
182 | void *EC_GROUP_get_extra_data(const EC_GROUP *, void *(*extra_data_dup_func)(void *), | ||
183 | void (*extra_data_free_func)(void *), void (*extra_data_clear_free_func)(void *)); | ||
184 | void EC_GROUP_free_extra_data(EC_GROUP *); | ||
185 | void EC_GROUP_clear_free_extra_data(EC_GROUP *); | ||
186 | |||
187 | |||
188 | |||
189 | struct ec_point_st { | ||
190 | const EC_METHOD *meth; | ||
191 | |||
192 | /* All members except 'meth' are handled by the method functions, | ||
193 | * even if they appear generic */ | ||
194 | |||
195 | BIGNUM X; | ||
196 | BIGNUM Y; | ||
197 | BIGNUM Z; /* Jacobian projective coordinates: | ||
198 | * (X, Y, Z) represents (X/Z^2, Y/Z^3) if Z != 0 */ | ||
199 | int Z_is_one; /* enable optimized point arithmetics for special case */ | ||
200 | } /* EC_POINT */; | ||
201 | |||
202 | |||
203 | |||
204 | /* method functions in ecp_smpl.c */ | ||
205 | int ec_GFp_simple_group_init(EC_GROUP *); | ||
206 | void ec_GFp_simple_group_finish(EC_GROUP *); | ||
207 | void ec_GFp_simple_group_clear_finish(EC_GROUP *); | ||
208 | int ec_GFp_simple_group_copy(EC_GROUP *, const EC_GROUP *); | ||
209 | int ec_GFp_simple_group_set_curve_GFp(EC_GROUP *, const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *); | ||
210 | int ec_GFp_simple_group_get_curve_GFp(const EC_GROUP *, BIGNUM *p, BIGNUM *a, BIGNUM *b, BN_CTX *); | ||
211 | int ec_GFp_simple_group_set_generator(EC_GROUP *, const EC_POINT *generator, | ||
212 | const BIGNUM *order, const BIGNUM *cofactor); | ||
213 | EC_POINT *ec_GFp_simple_group_get0_generator(const EC_GROUP *); | ||
214 | int ec_GFp_simple_group_get_order(const EC_GROUP *, BIGNUM *order, BN_CTX *); | ||
215 | int ec_GFp_simple_group_get_cofactor(const EC_GROUP *, BIGNUM *cofactor, BN_CTX *); | ||
216 | int ec_GFp_simple_point_init(EC_POINT *); | ||
217 | void ec_GFp_simple_point_finish(EC_POINT *); | ||
218 | void ec_GFp_simple_point_clear_finish(EC_POINT *); | ||
219 | int ec_GFp_simple_point_copy(EC_POINT *, const EC_POINT *); | ||
220 | int ec_GFp_simple_point_set_to_infinity(const EC_GROUP *, EC_POINT *); | ||
221 | int ec_GFp_simple_set_Jprojective_coordinates_GFp(const EC_GROUP *, EC_POINT *, | ||
222 | const BIGNUM *x, const BIGNUM *y, const BIGNUM *z, BN_CTX *); | ||
223 | int ec_GFp_simple_get_Jprojective_coordinates_GFp(const EC_GROUP *, const EC_POINT *, | ||
224 | BIGNUM *x, BIGNUM *y, BIGNUM *z, BN_CTX *); | ||
225 | int ec_GFp_simple_point_set_affine_coordinates_GFp(const EC_GROUP *, EC_POINT *, | ||
226 | const BIGNUM *x, const BIGNUM *y, BN_CTX *); | ||
227 | int ec_GFp_simple_point_get_affine_coordinates_GFp(const EC_GROUP *, const EC_POINT *, | ||
228 | BIGNUM *x, BIGNUM *y, BN_CTX *); | ||
229 | int ec_GFp_simple_set_compressed_coordinates_GFp(const EC_GROUP *, EC_POINT *, | ||
230 | const BIGNUM *x, int y_bit, BN_CTX *); | ||
231 | size_t ec_GFp_simple_point2oct(const EC_GROUP *, const EC_POINT *, point_conversion_form_t form, | ||
232 | unsigned char *buf, size_t len, BN_CTX *); | ||
233 | int ec_GFp_simple_oct2point(const EC_GROUP *, EC_POINT *, | ||
234 | const unsigned char *buf, size_t len, BN_CTX *); | ||
235 | int ec_GFp_simple_add(const EC_GROUP *, EC_POINT *r, const EC_POINT *a, const EC_POINT *b, BN_CTX *); | ||
236 | int ec_GFp_simple_dbl(const EC_GROUP *, EC_POINT *r, const EC_POINT *a, BN_CTX *); | ||
237 | int ec_GFp_simple_invert(const EC_GROUP *, EC_POINT *, BN_CTX *); | ||
238 | int ec_GFp_simple_is_at_infinity(const EC_GROUP *, const EC_POINT *); | ||
239 | int ec_GFp_simple_is_on_curve(const EC_GROUP *, const EC_POINT *, BN_CTX *); | ||
240 | int ec_GFp_simple_cmp(const EC_GROUP *, const EC_POINT *a, const EC_POINT *b, BN_CTX *); | ||
241 | int ec_GFp_simple_make_affine(const EC_GROUP *, EC_POINT *, BN_CTX *); | ||
242 | int ec_GFp_simple_points_make_affine(const EC_GROUP *, size_t num, EC_POINT *[], BN_CTX *); | ||
243 | int ec_GFp_simple_field_mul(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *); | ||
244 | int ec_GFp_simple_field_sqr(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, BN_CTX *); | ||
245 | |||
246 | |||
247 | /* method functions in ecp_mont.c */ | ||
248 | int ec_GFp_mont_group_init(EC_GROUP *); | ||
249 | int ec_GFp_mont_group_set_curve_GFp(EC_GROUP *, const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *); | ||
250 | void ec_GFp_mont_group_finish(EC_GROUP *); | ||
251 | void ec_GFp_mont_group_clear_finish(EC_GROUP *); | ||
252 | int ec_GFp_mont_group_copy(EC_GROUP *, const EC_GROUP *); | ||
253 | int ec_GFp_mont_field_mul(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *); | ||
254 | int ec_GFp_mont_field_sqr(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, BN_CTX *); | ||
255 | int ec_GFp_mont_field_encode(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, BN_CTX *); | ||
256 | int ec_GFp_mont_field_decode(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, BN_CTX *); | ||
257 | int ec_GFp_mont_field_set_to_one(const EC_GROUP *, BIGNUM *r, BN_CTX *); | ||
258 | |||
259 | |||
260 | /* method functions in ecp_recp.c */ | ||
261 | int ec_GFp_recp_group_init(EC_GROUP *); | ||
262 | int ec_GFp_recp_group_set_curve_GFp(EC_GROUP *, const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *); | ||
263 | void ec_GFp_recp_group_finish(EC_GROUP *); | ||
264 | void ec_GFp_recp_group_clear_finish(EC_GROUP *); | ||
265 | int ec_GFp_recp_group_copy(EC_GROUP *, const EC_GROUP *); | ||
266 | int ec_GFp_recp_field_mul(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *); | ||
267 | int ec_GFp_recp_field_sqr(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, BN_CTX *); | ||
268 | |||
269 | |||
270 | /* method functions in ecp_nist.c */ | ||
271 | int ec_GFp_nist_group_init(EC_GROUP *); | ||
272 | int ec_GFp_nist_group_set_curve_GFp(EC_GROUP *, const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *); | ||
273 | void ec_GFp_nist_group_finish(EC_GROUP *); | ||
274 | void ec_GFp_nist_group_clear_finish(EC_GROUP *); | ||
275 | int ec_GFp_nist_group_copy(EC_GROUP *, const EC_GROUP *); | ||
276 | int ec_GFp_nist_field_mul(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *); | ||
277 | int ec_GFp_nist_field_sqr(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, BN_CTX *); | ||
diff --git a/src/lib/libcrypto/ec/ec_lib.c b/src/lib/libcrypto/ec/ec_lib.c new file mode 100644 index 0000000000..e0d78d67fb --- /dev/null +++ b/src/lib/libcrypto/ec/ec_lib.c | |||
@@ -0,0 +1,646 @@ | |||
1 | /* crypto/ec/ec_lib.c */ | ||
2 | /* ==================================================================== | ||
3 | * Copyright (c) 1998-2001 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 | |||
58 | #include <openssl/err.h> | ||
59 | #include <openssl/opensslv.h> | ||
60 | |||
61 | #include "ec_lcl.h" | ||
62 | |||
63 | static const char EC_version[] = "EC" OPENSSL_VERSION_PTEXT; | ||
64 | |||
65 | |||
66 | /* functions for EC_GROUP objects */ | ||
67 | |||
68 | EC_GROUP *EC_GROUP_new(const EC_METHOD *meth) | ||
69 | { | ||
70 | EC_GROUP *ret; | ||
71 | |||
72 | if (meth == NULL) | ||
73 | { | ||
74 | ECerr(EC_F_EC_GROUP_NEW, ERR_R_PASSED_NULL_PARAMETER); | ||
75 | return NULL; | ||
76 | } | ||
77 | if (meth->group_init == 0) | ||
78 | { | ||
79 | ECerr(EC_F_EC_GROUP_NEW, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); | ||
80 | return NULL; | ||
81 | } | ||
82 | |||
83 | ret = OPENSSL_malloc(sizeof *ret); | ||
84 | if (ret == NULL) | ||
85 | { | ||
86 | ECerr(EC_F_EC_GROUP_NEW, ERR_R_MALLOC_FAILURE); | ||
87 | return NULL; | ||
88 | } | ||
89 | |||
90 | ret->meth = meth; | ||
91 | |||
92 | ret->extra_data = NULL; | ||
93 | ret->extra_data_dup_func = 0; | ||
94 | ret->extra_data_free_func = 0; | ||
95 | ret->extra_data_clear_free_func = 0; | ||
96 | |||
97 | if (!meth->group_init(ret)) | ||
98 | { | ||
99 | OPENSSL_free(ret); | ||
100 | return NULL; | ||
101 | } | ||
102 | |||
103 | return ret; | ||
104 | } | ||
105 | |||
106 | |||
107 | void EC_GROUP_free(EC_GROUP *group) | ||
108 | { | ||
109 | if (group->meth->group_finish != 0) | ||
110 | group->meth->group_finish(group); | ||
111 | |||
112 | EC_GROUP_free_extra_data(group); | ||
113 | |||
114 | OPENSSL_free(group); | ||
115 | } | ||
116 | |||
117 | |||
118 | void EC_GROUP_clear_free(EC_GROUP *group) | ||
119 | { | ||
120 | if (group->meth->group_clear_finish != 0) | ||
121 | group->meth->group_clear_finish(group); | ||
122 | else if (group->meth != NULL && group->meth->group_finish != 0) | ||
123 | group->meth->group_finish(group); | ||
124 | |||
125 | EC_GROUP_clear_free_extra_data(group); | ||
126 | |||
127 | memset(group, 0, sizeof *group); | ||
128 | OPENSSL_free(group); | ||
129 | } | ||
130 | |||
131 | |||
132 | int EC_GROUP_copy(EC_GROUP *dest, const EC_GROUP *src) | ||
133 | { | ||
134 | if (dest->meth->group_copy == 0) | ||
135 | { | ||
136 | ECerr(EC_F_EC_GROUP_COPY, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); | ||
137 | return 0; | ||
138 | } | ||
139 | if (dest->meth != src->meth) | ||
140 | { | ||
141 | ECerr(EC_F_EC_GROUP_COPY, EC_R_INCOMPATIBLE_OBJECTS); | ||
142 | return 0; | ||
143 | } | ||
144 | if (dest == src) | ||
145 | return 1; | ||
146 | |||
147 | EC_GROUP_clear_free_extra_data(dest); | ||
148 | if (src->extra_data_dup_func) | ||
149 | { | ||
150 | if (src->extra_data != NULL) | ||
151 | { | ||
152 | dest->extra_data = src->extra_data_dup_func(src->extra_data); | ||
153 | if (dest->extra_data == NULL) | ||
154 | return 0; | ||
155 | } | ||
156 | |||
157 | dest->extra_data_dup_func = src->extra_data_dup_func; | ||
158 | dest->extra_data_free_func = src->extra_data_free_func; | ||
159 | dest->extra_data_clear_free_func = src->extra_data_clear_free_func; | ||
160 | } | ||
161 | |||
162 | return dest->meth->group_copy(dest, src); | ||
163 | } | ||
164 | |||
165 | |||
166 | const EC_METHOD *EC_GROUP_method_of(const EC_GROUP *group) | ||
167 | { | ||
168 | return group->meth; | ||
169 | } | ||
170 | |||
171 | |||
172 | int EC_GROUP_set_curve_GFp(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx) | ||
173 | { | ||
174 | if (group->meth->group_set_curve_GFp == 0) | ||
175 | { | ||
176 | ECerr(EC_F_EC_GROUP_SET_CURVE_GFP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); | ||
177 | return 0; | ||
178 | } | ||
179 | return group->meth->group_set_curve_GFp(group, p, a, b, ctx); | ||
180 | } | ||
181 | |||
182 | |||
183 | int EC_GROUP_get_curve_GFp(const EC_GROUP *group, BIGNUM *p, BIGNUM *a, BIGNUM *b, BN_CTX *ctx) | ||
184 | { | ||
185 | if (group->meth->group_get_curve_GFp == 0) | ||
186 | { | ||
187 | ECerr(EC_F_EC_GROUP_GET_CURVE_GFP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); | ||
188 | return 0; | ||
189 | } | ||
190 | return group->meth->group_get_curve_GFp(group, p, a, b, ctx); | ||
191 | } | ||
192 | |||
193 | |||
194 | int EC_GROUP_set_generator(EC_GROUP *group, const EC_POINT *generator, const BIGNUM *order, const BIGNUM *cofactor) | ||
195 | { | ||
196 | if (group->meth->group_set_generator == 0) | ||
197 | { | ||
198 | ECerr(EC_F_EC_GROUP_SET_GENERATOR, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); | ||
199 | return 0; | ||
200 | } | ||
201 | return group->meth->group_set_generator(group, generator, order, cofactor); | ||
202 | } | ||
203 | |||
204 | |||
205 | EC_POINT *EC_GROUP_get0_generator(const EC_GROUP *group) | ||
206 | { | ||
207 | if (group->meth->group_get0_generator == 0) | ||
208 | { | ||
209 | ECerr(EC_F_EC_GROUP_GET0_GENERATOR, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); | ||
210 | return 0; | ||
211 | } | ||
212 | return group->meth->group_get0_generator(group); | ||
213 | } | ||
214 | |||
215 | |||
216 | int EC_GROUP_get_order(const EC_GROUP *group, BIGNUM *order, BN_CTX *ctx) | ||
217 | { | ||
218 | if (group->meth->group_get_order == 0) | ||
219 | { | ||
220 | ECerr(EC_F_EC_GROUP_GET_ORDER, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); | ||
221 | return 0; | ||
222 | } | ||
223 | return group->meth->group_get_order(group, order, ctx); | ||
224 | } | ||
225 | |||
226 | |||
227 | int EC_GROUP_get_cofactor(const EC_GROUP *group, BIGNUM *cofactor, BN_CTX *ctx) | ||
228 | { | ||
229 | if (group->meth->group_get_cofactor == 0) | ||
230 | { | ||
231 | ECerr(EC_F_EC_GROUP_GET_COFACTOR, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); | ||
232 | return 0; | ||
233 | } | ||
234 | return group->meth->group_get_cofactor(group, cofactor, ctx); | ||
235 | } | ||
236 | |||
237 | |||
238 | /* this has 'package' visibility */ | ||
239 | int EC_GROUP_set_extra_data(EC_GROUP *group, void *extra_data, void *(*extra_data_dup_func)(void *), | ||
240 | void (*extra_data_free_func)(void *), void (*extra_data_clear_free_func)(void *)) | ||
241 | { | ||
242 | if ((group->extra_data != NULL) | ||
243 | || (group->extra_data_dup_func != 0) | ||
244 | || (group->extra_data_free_func != 0) | ||
245 | || (group->extra_data_clear_free_func != 0)) | ||
246 | { | ||
247 | ECerr(EC_F_EC_GROUP_SET_EXTRA_DATA, EC_R_SLOT_FULL); | ||
248 | return 0; | ||
249 | } | ||
250 | |||
251 | group->extra_data = extra_data; | ||
252 | group->extra_data_dup_func = extra_data_dup_func; | ||
253 | group->extra_data_free_func = extra_data_free_func; | ||
254 | group->extra_data_clear_free_func = extra_data_clear_free_func; | ||
255 | return 1; | ||
256 | } | ||
257 | |||
258 | |||
259 | /* this has 'package' visibility */ | ||
260 | void *EC_GROUP_get_extra_data(const EC_GROUP *group, void *(*extra_data_dup_func)(void *), | ||
261 | void (*extra_data_free_func)(void *), void (*extra_data_clear_free_func)(void *)) | ||
262 | { | ||
263 | if ((group->extra_data_dup_func != extra_data_dup_func) | ||
264 | || (group->extra_data_free_func != extra_data_free_func) | ||
265 | || (group->extra_data_clear_free_func != extra_data_clear_free_func)) | ||
266 | { | ||
267 | ECerr(EC_F_EC_GROUP_GET_EXTRA_DATA, EC_R_NO_SUCH_EXTRA_DATA); | ||
268 | return NULL; | ||
269 | } | ||
270 | |||
271 | return group->extra_data; | ||
272 | } | ||
273 | |||
274 | |||
275 | /* this has 'package' visibility */ | ||
276 | void EC_GROUP_free_extra_data(EC_GROUP *group) | ||
277 | { | ||
278 | if (group->extra_data_free_func) | ||
279 | group->extra_data_free_func(group->extra_data); | ||
280 | group->extra_data = NULL; | ||
281 | group->extra_data_dup_func = 0; | ||
282 | group->extra_data_free_func = 0; | ||
283 | group->extra_data_clear_free_func = 0; | ||
284 | } | ||
285 | |||
286 | |||
287 | /* this has 'package' visibility */ | ||
288 | void EC_GROUP_clear_free_extra_data(EC_GROUP *group) | ||
289 | { | ||
290 | if (group->extra_data_clear_free_func) | ||
291 | group->extra_data_clear_free_func(group->extra_data); | ||
292 | else if (group->extra_data_free_func) | ||
293 | group->extra_data_free_func(group->extra_data); | ||
294 | group->extra_data = NULL; | ||
295 | group->extra_data_dup_func = 0; | ||
296 | group->extra_data_free_func = 0; | ||
297 | group->extra_data_clear_free_func = 0; | ||
298 | } | ||
299 | |||
300 | |||
301 | |||
302 | /* functions for EC_POINT objects */ | ||
303 | |||
304 | EC_POINT *EC_POINT_new(const EC_GROUP *group) | ||
305 | { | ||
306 | EC_POINT *ret; | ||
307 | |||
308 | if (group == NULL) | ||
309 | { | ||
310 | ECerr(EC_F_EC_POINT_NEW, ERR_R_PASSED_NULL_PARAMETER); | ||
311 | return NULL; | ||
312 | } | ||
313 | if (group->meth->point_init == 0) | ||
314 | { | ||
315 | ECerr(EC_F_EC_POINT_NEW, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); | ||
316 | return NULL; | ||
317 | } | ||
318 | |||
319 | ret = OPENSSL_malloc(sizeof *ret); | ||
320 | if (ret == NULL) | ||
321 | { | ||
322 | ECerr(EC_F_EC_POINT_NEW, ERR_R_MALLOC_FAILURE); | ||
323 | return NULL; | ||
324 | } | ||
325 | |||
326 | ret->meth = group->meth; | ||
327 | |||
328 | if (!ret->meth->point_init(ret)) | ||
329 | { | ||
330 | OPENSSL_free(ret); | ||
331 | return NULL; | ||
332 | } | ||
333 | |||
334 | return ret; | ||
335 | } | ||
336 | |||
337 | |||
338 | void EC_POINT_free(EC_POINT *point) | ||
339 | { | ||
340 | if (point->meth->point_finish != 0) | ||
341 | point->meth->point_finish(point); | ||
342 | OPENSSL_free(point); | ||
343 | } | ||
344 | |||
345 | |||
346 | void EC_POINT_clear_free(EC_POINT *point) | ||
347 | { | ||
348 | if (point->meth->point_clear_finish != 0) | ||
349 | point->meth->point_clear_finish(point); | ||
350 | else if (point->meth != NULL && point->meth->point_finish != 0) | ||
351 | point->meth->point_finish(point); | ||
352 | memset(point, 0, sizeof *point); | ||
353 | OPENSSL_free(point); | ||
354 | } | ||
355 | |||
356 | |||
357 | int EC_POINT_copy(EC_POINT *dest, const EC_POINT *src) | ||
358 | { | ||
359 | if (dest->meth->point_copy == 0) | ||
360 | { | ||
361 | ECerr(EC_F_EC_POINT_COPY, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); | ||
362 | return 0; | ||
363 | } | ||
364 | if (dest->meth != src->meth) | ||
365 | { | ||
366 | ECerr(EC_F_EC_POINT_COPY, EC_R_INCOMPATIBLE_OBJECTS); | ||
367 | return 0; | ||
368 | } | ||
369 | if (dest == src) | ||
370 | return 1; | ||
371 | return dest->meth->point_copy(dest, src); | ||
372 | } | ||
373 | |||
374 | |||
375 | const EC_METHOD *EC_POINT_method_of(const EC_POINT *point) | ||
376 | { | ||
377 | return point->meth; | ||
378 | } | ||
379 | |||
380 | |||
381 | int EC_POINT_set_to_infinity(const EC_GROUP *group, EC_POINT *point) | ||
382 | { | ||
383 | if (group->meth->point_set_to_infinity == 0) | ||
384 | { | ||
385 | ECerr(EC_F_EC_POINT_SET_TO_INFINITY, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); | ||
386 | return 0; | ||
387 | } | ||
388 | if (group->meth != point->meth) | ||
389 | { | ||
390 | ECerr(EC_F_EC_POINT_SET_TO_INFINITY, EC_R_INCOMPATIBLE_OBJECTS); | ||
391 | return 0; | ||
392 | } | ||
393 | return group->meth->point_set_to_infinity(group, point); | ||
394 | } | ||
395 | |||
396 | |||
397 | int EC_POINT_set_Jprojective_coordinates_GFp(const EC_GROUP *group, EC_POINT *point, | ||
398 | const BIGNUM *x, const BIGNUM *y, const BIGNUM *z, BN_CTX *ctx) | ||
399 | { | ||
400 | if (group->meth->point_set_Jprojective_coordinates_GFp == 0) | ||
401 | { | ||
402 | ECerr(EC_F_EC_POINT_SET_JPROJECTIVE_COORDINATES_GFP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); | ||
403 | return 0; | ||
404 | } | ||
405 | if (group->meth != point->meth) | ||
406 | { | ||
407 | ECerr(EC_F_EC_POINT_SET_JPROJECTIVE_COORDINATES_GFP, EC_R_INCOMPATIBLE_OBJECTS); | ||
408 | return 0; | ||
409 | } | ||
410 | return group->meth->point_set_Jprojective_coordinates_GFp(group, point, x, y, z, ctx); | ||
411 | } | ||
412 | |||
413 | |||
414 | int EC_POINT_get_Jprojective_coordinates_GFp(const EC_GROUP *group, const EC_POINT *point, | ||
415 | BIGNUM *x, BIGNUM *y, BIGNUM *z, BN_CTX *ctx) | ||
416 | { | ||
417 | if (group->meth->point_get_Jprojective_coordinates_GFp == 0) | ||
418 | { | ||
419 | ECerr(EC_F_EC_POINT_GET_JPROJECTIVE_COORDINATES_GFP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); | ||
420 | return 0; | ||
421 | } | ||
422 | if (group->meth != point->meth) | ||
423 | { | ||
424 | ECerr(EC_F_EC_POINT_GET_JPROJECTIVE_COORDINATES_GFP, EC_R_INCOMPATIBLE_OBJECTS); | ||
425 | return 0; | ||
426 | } | ||
427 | return group->meth->point_get_Jprojective_coordinates_GFp(group, point, x, y, z, ctx); | ||
428 | } | ||
429 | |||
430 | |||
431 | int EC_POINT_set_affine_coordinates_GFp(const EC_GROUP *group, EC_POINT *point, | ||
432 | const BIGNUM *x, const BIGNUM *y, BN_CTX *ctx) | ||
433 | { | ||
434 | if (group->meth->point_set_affine_coordinates_GFp == 0) | ||
435 | { | ||
436 | ECerr(EC_F_EC_POINT_SET_AFFINE_COORDINATES_GFP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); | ||
437 | return 0; | ||
438 | } | ||
439 | if (group->meth != point->meth) | ||
440 | { | ||
441 | ECerr(EC_F_EC_POINT_SET_AFFINE_COORDINATES_GFP, EC_R_INCOMPATIBLE_OBJECTS); | ||
442 | return 0; | ||
443 | } | ||
444 | return group->meth->point_set_affine_coordinates_GFp(group, point, x, y, ctx); | ||
445 | } | ||
446 | |||
447 | |||
448 | int EC_POINT_get_affine_coordinates_GFp(const EC_GROUP *group, const EC_POINT *point, | ||
449 | BIGNUM *x, BIGNUM *y, BN_CTX *ctx) | ||
450 | { | ||
451 | if (group->meth->point_get_affine_coordinates_GFp == 0) | ||
452 | { | ||
453 | ECerr(EC_F_EC_POINT_GET_AFFINE_COORDINATES_GFP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); | ||
454 | return 0; | ||
455 | } | ||
456 | if (group->meth != point->meth) | ||
457 | { | ||
458 | ECerr(EC_F_EC_POINT_GET_AFFINE_COORDINATES_GFP, EC_R_INCOMPATIBLE_OBJECTS); | ||
459 | return 0; | ||
460 | } | ||
461 | return group->meth->point_get_affine_coordinates_GFp(group, point, x, y, ctx); | ||
462 | } | ||
463 | |||
464 | |||
465 | int EC_POINT_set_compressed_coordinates_GFp(const EC_GROUP *group, EC_POINT *point, | ||
466 | const BIGNUM *x, int y_bit, BN_CTX *ctx) | ||
467 | { | ||
468 | if (group->meth->point_set_compressed_coordinates_GFp == 0) | ||
469 | { | ||
470 | ECerr(EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GFP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); | ||
471 | return 0; | ||
472 | } | ||
473 | if (group->meth != point->meth) | ||
474 | { | ||
475 | ECerr(EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GFP, EC_R_INCOMPATIBLE_OBJECTS); | ||
476 | return 0; | ||
477 | } | ||
478 | return group->meth->point_set_compressed_coordinates_GFp(group, point, x, y_bit, ctx); | ||
479 | } | ||
480 | |||
481 | |||
482 | size_t EC_POINT_point2oct(const EC_GROUP *group, const EC_POINT *point, point_conversion_form_t form, | ||
483 | unsigned char *buf, size_t len, BN_CTX *ctx) | ||
484 | { | ||
485 | if (group->meth->point2oct == 0) | ||
486 | { | ||
487 | ECerr(EC_F_EC_POINT_POINT2OCT, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); | ||
488 | return 0; | ||
489 | } | ||
490 | if (group->meth != point->meth) | ||
491 | { | ||
492 | ECerr(EC_F_EC_POINT_POINT2OCT, EC_R_INCOMPATIBLE_OBJECTS); | ||
493 | return 0; | ||
494 | } | ||
495 | return group->meth->point2oct(group, point, form, buf, len, ctx); | ||
496 | } | ||
497 | |||
498 | |||
499 | int EC_POINT_oct2point(const EC_GROUP *group, EC_POINT *point, | ||
500 | const unsigned char *buf, size_t len, BN_CTX *ctx) | ||
501 | { | ||
502 | if (group->meth->oct2point == 0) | ||
503 | { | ||
504 | ECerr(EC_F_EC_POINT_OCT2POINT, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); | ||
505 | return 0; | ||
506 | } | ||
507 | if (group->meth != point->meth) | ||
508 | { | ||
509 | ECerr(EC_F_EC_POINT_OCT2POINT, EC_R_INCOMPATIBLE_OBJECTS); | ||
510 | return 0; | ||
511 | } | ||
512 | return group->meth->oct2point(group, point, buf, len, ctx); | ||
513 | } | ||
514 | |||
515 | |||
516 | int EC_POINT_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, const EC_POINT *b, BN_CTX *ctx) | ||
517 | { | ||
518 | if (group->meth->add == 0) | ||
519 | { | ||
520 | ECerr(EC_F_EC_POINT_ADD, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); | ||
521 | return 0; | ||
522 | } | ||
523 | if ((group->meth != r->meth) || (r->meth != a->meth) || (a->meth != b->meth)) | ||
524 | { | ||
525 | ECerr(EC_F_EC_POINT_ADD, EC_R_INCOMPATIBLE_OBJECTS); | ||
526 | return 0; | ||
527 | } | ||
528 | return group->meth->add(group, r, a, b, ctx); | ||
529 | } | ||
530 | |||
531 | |||
532 | int EC_POINT_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, BN_CTX *ctx) | ||
533 | { | ||
534 | if (group->meth->dbl == 0) | ||
535 | { | ||
536 | ECerr(EC_F_EC_POINT_DBL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); | ||
537 | return 0; | ||
538 | } | ||
539 | if ((group->meth != r->meth) || (r->meth != a->meth)) | ||
540 | { | ||
541 | ECerr(EC_F_EC_POINT_DBL, EC_R_INCOMPATIBLE_OBJECTS); | ||
542 | return 0; | ||
543 | } | ||
544 | return group->meth->dbl(group, r, a, ctx); | ||
545 | } | ||
546 | |||
547 | |||
548 | int EC_POINT_invert(const EC_GROUP *group, EC_POINT *a, BN_CTX *ctx) | ||
549 | { | ||
550 | if (group->meth->dbl == 0) | ||
551 | { | ||
552 | ECerr(EC_F_EC_POINT_DBL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); | ||
553 | return 0; | ||
554 | } | ||
555 | if (group->meth != a->meth) | ||
556 | { | ||
557 | ECerr(EC_F_EC_POINT_DBL, EC_R_INCOMPATIBLE_OBJECTS); | ||
558 | return 0; | ||
559 | } | ||
560 | return group->meth->invert(group, a, ctx); | ||
561 | } | ||
562 | |||
563 | |||
564 | int EC_POINT_is_at_infinity(const EC_GROUP *group, const EC_POINT *point) | ||
565 | { | ||
566 | if (group->meth->is_at_infinity == 0) | ||
567 | { | ||
568 | ECerr(EC_F_EC_POINT_IS_AT_INFINITY, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); | ||
569 | return 0; | ||
570 | } | ||
571 | if (group->meth != point->meth) | ||
572 | { | ||
573 | ECerr(EC_F_EC_POINT_IS_AT_INFINITY, EC_R_INCOMPATIBLE_OBJECTS); | ||
574 | return 0; | ||
575 | } | ||
576 | return group->meth->is_at_infinity(group, point); | ||
577 | } | ||
578 | |||
579 | |||
580 | int EC_POINT_is_on_curve(const EC_GROUP *group, const EC_POINT *point, BN_CTX *ctx) | ||
581 | { | ||
582 | if (group->meth->is_on_curve == 0) | ||
583 | { | ||
584 | ECerr(EC_F_EC_POINT_IS_ON_CURVE, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); | ||
585 | return 0; | ||
586 | } | ||
587 | if (group->meth != point->meth) | ||
588 | { | ||
589 | ECerr(EC_F_EC_POINT_IS_ON_CURVE, EC_R_INCOMPATIBLE_OBJECTS); | ||
590 | return 0; | ||
591 | } | ||
592 | return group->meth->is_on_curve(group, point, ctx); | ||
593 | } | ||
594 | |||
595 | |||
596 | int EC_POINT_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b, BN_CTX *ctx) | ||
597 | { | ||
598 | if (group->meth->point_cmp == 0) | ||
599 | { | ||
600 | ECerr(EC_F_EC_POINT_CMP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); | ||
601 | return 0; | ||
602 | } | ||
603 | if ((group->meth != a->meth) || (a->meth != b->meth)) | ||
604 | { | ||
605 | ECerr(EC_F_EC_POINT_CMP, EC_R_INCOMPATIBLE_OBJECTS); | ||
606 | return 0; | ||
607 | } | ||
608 | return group->meth->point_cmp(group, a, b, ctx); | ||
609 | } | ||
610 | |||
611 | |||
612 | int EC_POINT_make_affine(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx) | ||
613 | { | ||
614 | if (group->meth->make_affine == 0) | ||
615 | { | ||
616 | ECerr(EC_F_EC_POINT_MAKE_AFFINE, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); | ||
617 | return 0; | ||
618 | } | ||
619 | if (group->meth != point->meth) | ||
620 | { | ||
621 | ECerr(EC_F_EC_POINT_MAKE_AFFINE, EC_R_INCOMPATIBLE_OBJECTS); | ||
622 | return 0; | ||
623 | } | ||
624 | return group->meth->make_affine(group, point, ctx); | ||
625 | } | ||
626 | |||
627 | |||
628 | int EC_POINTs_make_affine(const EC_GROUP *group, size_t num, EC_POINT *points[], BN_CTX *ctx) | ||
629 | { | ||
630 | size_t i; | ||
631 | |||
632 | if (group->meth->points_make_affine == 0) | ||
633 | { | ||
634 | ECerr(EC_F_EC_POINTS_MAKE_AFFINE, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); | ||
635 | return 0; | ||
636 | } | ||
637 | for (i = 0; i < num; i++) | ||
638 | { | ||
639 | if (group->meth != points[i]->meth) | ||
640 | { | ||
641 | ECerr(EC_F_EC_POINTS_MAKE_AFFINE, EC_R_INCOMPATIBLE_OBJECTS); | ||
642 | return 0; | ||
643 | } | ||
644 | } | ||
645 | return group->meth->points_make_affine(group, num, points, ctx); | ||
646 | } | ||
diff --git a/src/lib/libcrypto/ec/ec_mult.c b/src/lib/libcrypto/ec/ec_mult.c new file mode 100644 index 0000000000..603ba31b81 --- /dev/null +++ b/src/lib/libcrypto/ec/ec_mult.c | |||
@@ -0,0 +1,473 @@ | |||
1 | /* crypto/ec/ec_mult.c */ | ||
2 | /* ==================================================================== | ||
3 | * Copyright (c) 1998-2001 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/err.h> | ||
57 | |||
58 | #include "ec_lcl.h" | ||
59 | |||
60 | |||
61 | /* TODO: optional precomputation of multiples of the generator */ | ||
62 | |||
63 | |||
64 | |||
65 | /* | ||
66 | * wNAF-based interleaving multi-exponentation method | ||
67 | * (<URL:http://www.informatik.tu-darmstadt.de/TI/Mitarbeiter/moeller.html#multiexp>) | ||
68 | */ | ||
69 | |||
70 | |||
71 | /* Determine the width-(w+1) Non-Adjacent Form (wNAF) of 'scalar'. | ||
72 | * This is an array r[] of values that are either zero or odd with an | ||
73 | * absolute value less than 2^w satisfying | ||
74 | * scalar = \sum_j r[j]*2^j | ||
75 | * where at most one of any w+1 consecutive digits is non-zero. | ||
76 | */ | ||
77 | static signed char *compute_wNAF(const BIGNUM *scalar, int w, size_t *ret_len, BN_CTX *ctx) | ||
78 | { | ||
79 | BIGNUM *c; | ||
80 | int ok = 0; | ||
81 | signed char *r = NULL; | ||
82 | int sign = 1; | ||
83 | int bit, next_bit, mask; | ||
84 | size_t len = 0, j; | ||
85 | |||
86 | BN_CTX_start(ctx); | ||
87 | c = BN_CTX_get(ctx); | ||
88 | if (c == NULL) goto err; | ||
89 | |||
90 | if (w <= 0 || w > 7) /* 'signed char' can represent integers with absolute values less than 2^7 */ | ||
91 | { | ||
92 | ECerr(EC_F_COMPUTE_WNAF, ERR_R_INTERNAL_ERROR); | ||
93 | goto err; | ||
94 | } | ||
95 | bit = 1 << w; /* at most 128 */ | ||
96 | next_bit = bit << 1; /* at most 256 */ | ||
97 | mask = next_bit - 1; /* at most 255 */ | ||
98 | |||
99 | if (!BN_copy(c, scalar)) goto err; | ||
100 | if (c->neg) | ||
101 | { | ||
102 | sign = -1; | ||
103 | c->neg = 0; | ||
104 | } | ||
105 | |||
106 | len = BN_num_bits(c) + 1; /* wNAF may be one digit longer than binary representation */ | ||
107 | r = OPENSSL_malloc(len); | ||
108 | if (r == NULL) goto err; | ||
109 | |||
110 | j = 0; | ||
111 | while (!BN_is_zero(c)) | ||
112 | { | ||
113 | int u = 0; | ||
114 | |||
115 | if (BN_is_odd(c)) | ||
116 | { | ||
117 | if (c->d == NULL || c->top == 0) | ||
118 | { | ||
119 | ECerr(EC_F_COMPUTE_WNAF, ERR_R_INTERNAL_ERROR); | ||
120 | goto err; | ||
121 | } | ||
122 | u = c->d[0] & mask; | ||
123 | if (u & bit) | ||
124 | { | ||
125 | u -= next_bit; | ||
126 | /* u < 0 */ | ||
127 | if (!BN_add_word(c, -u)) goto err; | ||
128 | } | ||
129 | else | ||
130 | { | ||
131 | /* u > 0 */ | ||
132 | if (!BN_sub_word(c, u)) goto err; | ||
133 | } | ||
134 | |||
135 | if (u <= -bit || u >= bit || !(u & 1) || c->neg) | ||
136 | { | ||
137 | ECerr(EC_F_COMPUTE_WNAF, ERR_R_INTERNAL_ERROR); | ||
138 | goto err; | ||
139 | } | ||
140 | } | ||
141 | |||
142 | r[j++] = sign * u; | ||
143 | |||
144 | if (BN_is_odd(c)) | ||
145 | { | ||
146 | ECerr(EC_F_COMPUTE_WNAF, ERR_R_INTERNAL_ERROR); | ||
147 | goto err; | ||
148 | } | ||
149 | if (!BN_rshift1(c, c)) goto err; | ||
150 | } | ||
151 | |||
152 | if (j > len) | ||
153 | { | ||
154 | ECerr(EC_F_COMPUTE_WNAF, ERR_R_INTERNAL_ERROR); | ||
155 | goto err; | ||
156 | } | ||
157 | len = j; | ||
158 | ok = 1; | ||
159 | |||
160 | err: | ||
161 | BN_CTX_end(ctx); | ||
162 | if (!ok) | ||
163 | { | ||
164 | OPENSSL_free(r); | ||
165 | r = NULL; | ||
166 | } | ||
167 | if (ok) | ||
168 | *ret_len = len; | ||
169 | return r; | ||
170 | } | ||
171 | |||
172 | |||
173 | /* TODO: table should be optimised for the wNAF-based implementation, | ||
174 | * sometimes smaller windows will give better performance | ||
175 | * (thus the boundaries should be increased) | ||
176 | */ | ||
177 | #define EC_window_bits_for_scalar_size(b) \ | ||
178 | ((b) >= 2000 ? 6 : \ | ||
179 | (b) >= 800 ? 5 : \ | ||
180 | (b) >= 300 ? 4 : \ | ||
181 | (b) >= 70 ? 3 : \ | ||
182 | (b) >= 20 ? 2 : \ | ||
183 | 1) | ||
184 | |||
185 | /* Compute | ||
186 | * \sum scalars[i]*points[i], | ||
187 | * also including | ||
188 | * scalar*generator | ||
189 | * in the addition if scalar != NULL | ||
190 | */ | ||
191 | int EC_POINTs_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, | ||
192 | size_t num, const EC_POINT *points[], const BIGNUM *scalars[], BN_CTX *ctx) | ||
193 | { | ||
194 | BN_CTX *new_ctx = NULL; | ||
195 | EC_POINT *generator = NULL; | ||
196 | EC_POINT *tmp = NULL; | ||
197 | size_t totalnum; | ||
198 | size_t i, j; | ||
199 | int k; | ||
200 | int r_is_inverted = 0; | ||
201 | int r_is_at_infinity = 1; | ||
202 | size_t *wsize = NULL; /* individual window sizes */ | ||
203 | signed char **wNAF = NULL; /* individual wNAFs */ | ||
204 | size_t *wNAF_len = NULL; | ||
205 | size_t max_len = 0; | ||
206 | size_t num_val; | ||
207 | EC_POINT **val = NULL; /* precomputation */ | ||
208 | EC_POINT **v; | ||
209 | EC_POINT ***val_sub = NULL; /* pointers to sub-arrays of 'val' */ | ||
210 | int ret = 0; | ||
211 | |||
212 | if (scalar != NULL) | ||
213 | { | ||
214 | generator = EC_GROUP_get0_generator(group); | ||
215 | if (generator == NULL) | ||
216 | { | ||
217 | ECerr(EC_F_EC_POINTS_MUL, EC_R_UNDEFINED_GENERATOR); | ||
218 | return 0; | ||
219 | } | ||
220 | } | ||
221 | |||
222 | for (i = 0; i < num; i++) | ||
223 | { | ||
224 | if (group->meth != points[i]->meth) | ||
225 | { | ||
226 | ECerr(EC_F_EC_POINTS_MUL, EC_R_INCOMPATIBLE_OBJECTS); | ||
227 | return 0; | ||
228 | } | ||
229 | } | ||
230 | |||
231 | totalnum = num + (scalar != NULL); | ||
232 | |||
233 | wsize = OPENSSL_malloc(totalnum * sizeof wsize[0]); | ||
234 | wNAF_len = OPENSSL_malloc(totalnum * sizeof wNAF_len[0]); | ||
235 | wNAF = OPENSSL_malloc((totalnum + 1) * sizeof wNAF[0]); | ||
236 | if (wNAF != NULL) | ||
237 | { | ||
238 | wNAF[0] = NULL; /* preliminary pivot */ | ||
239 | } | ||
240 | if (wsize == NULL || wNAF_len == NULL || wNAF == NULL) goto err; | ||
241 | |||
242 | /* num_val := total number of points to precompute */ | ||
243 | num_val = 0; | ||
244 | for (i = 0; i < totalnum; i++) | ||
245 | { | ||
246 | size_t bits; | ||
247 | |||
248 | bits = i < num ? BN_num_bits(scalars[i]) : BN_num_bits(scalar); | ||
249 | wsize[i] = EC_window_bits_for_scalar_size(bits); | ||
250 | num_val += 1u << (wsize[i] - 1); | ||
251 | } | ||
252 | |||
253 | /* all precomputed points go into a single array 'val', | ||
254 | * 'val_sub[i]' is a pointer to the subarray for the i-th point */ | ||
255 | val = OPENSSL_malloc((num_val + 1) * sizeof val[0]); | ||
256 | if (val == NULL) goto err; | ||
257 | val[num_val] = NULL; /* pivot element */ | ||
258 | |||
259 | val_sub = OPENSSL_malloc(totalnum * sizeof val_sub[0]); | ||
260 | if (val_sub == NULL) goto err; | ||
261 | |||
262 | /* allocate points for precomputation */ | ||
263 | v = val; | ||
264 | for (i = 0; i < totalnum; i++) | ||
265 | { | ||
266 | val_sub[i] = v; | ||
267 | for (j = 0; j < (1u << (wsize[i] - 1)); j++) | ||
268 | { | ||
269 | *v = EC_POINT_new(group); | ||
270 | if (*v == NULL) goto err; | ||
271 | v++; | ||
272 | } | ||
273 | } | ||
274 | if (!(v == val + num_val)) | ||
275 | { | ||
276 | ECerr(EC_F_EC_POINTS_MUL, ERR_R_INTERNAL_ERROR); | ||
277 | goto err; | ||
278 | } | ||
279 | |||
280 | if (ctx == NULL) | ||
281 | { | ||
282 | ctx = new_ctx = BN_CTX_new(); | ||
283 | if (ctx == NULL) | ||
284 | goto err; | ||
285 | } | ||
286 | |||
287 | tmp = EC_POINT_new(group); | ||
288 | if (tmp == NULL) goto err; | ||
289 | |||
290 | /* prepare precomputed values: | ||
291 | * val_sub[i][0] := points[i] | ||
292 | * val_sub[i][1] := 3 * points[i] | ||
293 | * val_sub[i][2] := 5 * points[i] | ||
294 | * ... | ||
295 | */ | ||
296 | for (i = 0; i < totalnum; i++) | ||
297 | { | ||
298 | if (i < num) | ||
299 | { | ||
300 | if (!EC_POINT_copy(val_sub[i][0], points[i])) goto err; | ||
301 | } | ||
302 | else | ||
303 | { | ||
304 | if (!EC_POINT_copy(val_sub[i][0], generator)) goto err; | ||
305 | } | ||
306 | |||
307 | if (wsize[i] > 1) | ||
308 | { | ||
309 | if (!EC_POINT_dbl(group, tmp, val_sub[i][0], ctx)) goto err; | ||
310 | for (j = 1; j < (1u << (wsize[i] - 1)); j++) | ||
311 | { | ||
312 | if (!EC_POINT_add(group, val_sub[i][j], val_sub[i][j - 1], tmp, ctx)) goto err; | ||
313 | } | ||
314 | } | ||
315 | |||
316 | wNAF[i + 1] = NULL; /* make sure we always have a pivot */ | ||
317 | wNAF[i] = compute_wNAF((i < num ? scalars[i] : scalar), wsize[i], &wNAF_len[i], ctx); | ||
318 | if (wNAF[i] == NULL) goto err; | ||
319 | if (wNAF_len[i] > max_len) | ||
320 | max_len = wNAF_len[i]; | ||
321 | } | ||
322 | |||
323 | #if 1 /* optional; EC_window_bits_for_scalar_size assumes we do this step */ | ||
324 | if (!EC_POINTs_make_affine(group, num_val, val, ctx)) goto err; | ||
325 | #endif | ||
326 | |||
327 | r_is_at_infinity = 1; | ||
328 | |||
329 | for (k = max_len - 1; k >= 0; k--) | ||
330 | { | ||
331 | if (!r_is_at_infinity) | ||
332 | { | ||
333 | if (!EC_POINT_dbl(group, r, r, ctx)) goto err; | ||
334 | } | ||
335 | |||
336 | for (i = 0; i < totalnum; i++) | ||
337 | { | ||
338 | if (wNAF_len[i] > (size_t)k) | ||
339 | { | ||
340 | int digit = wNAF[i][k]; | ||
341 | int is_neg; | ||
342 | |||
343 | if (digit) | ||
344 | { | ||
345 | is_neg = digit < 0; | ||
346 | |||
347 | if (is_neg) | ||
348 | digit = -digit; | ||
349 | |||
350 | if (is_neg != r_is_inverted) | ||
351 | { | ||
352 | if (!r_is_at_infinity) | ||
353 | { | ||
354 | if (!EC_POINT_invert(group, r, ctx)) goto err; | ||
355 | } | ||
356 | r_is_inverted = !r_is_inverted; | ||
357 | } | ||
358 | |||
359 | /* digit > 0 */ | ||
360 | |||
361 | if (r_is_at_infinity) | ||
362 | { | ||
363 | if (!EC_POINT_copy(r, val_sub[i][digit >> 1])) goto err; | ||
364 | r_is_at_infinity = 0; | ||
365 | } | ||
366 | else | ||
367 | { | ||
368 | if (!EC_POINT_add(group, r, r, val_sub[i][digit >> 1], ctx)) goto err; | ||
369 | } | ||
370 | } | ||
371 | } | ||
372 | } | ||
373 | } | ||
374 | |||
375 | if (r_is_at_infinity) | ||
376 | { | ||
377 | if (!EC_POINT_set_to_infinity(group, r)) goto err; | ||
378 | } | ||
379 | else | ||
380 | { | ||
381 | if (r_is_inverted) | ||
382 | if (!EC_POINT_invert(group, r, ctx)) goto err; | ||
383 | } | ||
384 | |||
385 | ret = 1; | ||
386 | |||
387 | err: | ||
388 | if (new_ctx != NULL) | ||
389 | BN_CTX_free(new_ctx); | ||
390 | if (tmp != NULL) | ||
391 | EC_POINT_free(tmp); | ||
392 | if (wsize != NULL) | ||
393 | OPENSSL_free(wsize); | ||
394 | if (wNAF_len != NULL) | ||
395 | OPENSSL_free(wNAF_len); | ||
396 | if (wNAF != NULL) | ||
397 | { | ||
398 | signed char **w; | ||
399 | |||
400 | for (w = wNAF; *w != NULL; w++) | ||
401 | OPENSSL_free(*w); | ||
402 | |||
403 | OPENSSL_free(wNAF); | ||
404 | } | ||
405 | if (val != NULL) | ||
406 | { | ||
407 | for (v = val; *v != NULL; v++) | ||
408 | EC_POINT_clear_free(*v); | ||
409 | |||
410 | OPENSSL_free(val); | ||
411 | } | ||
412 | if (val_sub != NULL) | ||
413 | { | ||
414 | OPENSSL_free(val_sub); | ||
415 | } | ||
416 | return ret; | ||
417 | } | ||
418 | |||
419 | |||
420 | int EC_POINT_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *g_scalar, const EC_POINT *point, const BIGNUM *p_scalar, BN_CTX *ctx) | ||
421 | { | ||
422 | const EC_POINT *points[1]; | ||
423 | const BIGNUM *scalars[1]; | ||
424 | |||
425 | points[0] = point; | ||
426 | scalars[0] = p_scalar; | ||
427 | |||
428 | return EC_POINTs_mul(group, r, g_scalar, (point != NULL && p_scalar != NULL), points, scalars, ctx); | ||
429 | } | ||
430 | |||
431 | |||
432 | int EC_GROUP_precompute_mult(EC_GROUP *group, BN_CTX *ctx) | ||
433 | { | ||
434 | const EC_POINT *generator; | ||
435 | BN_CTX *new_ctx = NULL; | ||
436 | BIGNUM *order; | ||
437 | int ret = 0; | ||
438 | |||
439 | generator = EC_GROUP_get0_generator(group); | ||
440 | if (generator == NULL) | ||
441 | { | ||
442 | ECerr(EC_F_EC_GROUP_PRECOMPUTE_MULT, EC_R_UNDEFINED_GENERATOR); | ||
443 | return 0; | ||
444 | } | ||
445 | |||
446 | if (ctx == NULL) | ||
447 | { | ||
448 | ctx = new_ctx = BN_CTX_new(); | ||
449 | if (ctx == NULL) | ||
450 | return 0; | ||
451 | } | ||
452 | |||
453 | BN_CTX_start(ctx); | ||
454 | order = BN_CTX_get(ctx); | ||
455 | if (order == NULL) goto err; | ||
456 | |||
457 | if (!EC_GROUP_get_order(group, order, ctx)) return 0; | ||
458 | if (BN_is_zero(order)) | ||
459 | { | ||
460 | ECerr(EC_F_EC_GROUP_PRECOMPUTE_MULT, EC_R_UNKNOWN_ORDER); | ||
461 | goto err; | ||
462 | } | ||
463 | |||
464 | /* TODO */ | ||
465 | |||
466 | ret = 1; | ||
467 | |||
468 | err: | ||
469 | BN_CTX_end(ctx); | ||
470 | if (new_ctx != NULL) | ||
471 | BN_CTX_free(new_ctx); | ||
472 | return ret; | ||
473 | } | ||
diff --git a/src/lib/libcrypto/ec/ecp_mont.c b/src/lib/libcrypto/ec/ecp_mont.c new file mode 100644 index 0000000000..7b30d4c38a --- /dev/null +++ b/src/lib/libcrypto/ec/ecp_mont.c | |||
@@ -0,0 +1,304 @@ | |||
1 | /* crypto/ec/ecp_mont.c */ | ||
2 | /* ==================================================================== | ||
3 | * Copyright (c) 1998-2001 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/err.h> | ||
57 | |||
58 | #include "ec_lcl.h" | ||
59 | |||
60 | |||
61 | const EC_METHOD *EC_GFp_mont_method(void) | ||
62 | { | ||
63 | static const EC_METHOD ret = { | ||
64 | ec_GFp_mont_group_init, | ||
65 | ec_GFp_mont_group_finish, | ||
66 | ec_GFp_mont_group_clear_finish, | ||
67 | ec_GFp_mont_group_copy, | ||
68 | ec_GFp_mont_group_set_curve_GFp, | ||
69 | ec_GFp_simple_group_get_curve_GFp, | ||
70 | ec_GFp_simple_group_set_generator, | ||
71 | ec_GFp_simple_group_get0_generator, | ||
72 | ec_GFp_simple_group_get_order, | ||
73 | ec_GFp_simple_group_get_cofactor, | ||
74 | ec_GFp_simple_point_init, | ||
75 | ec_GFp_simple_point_finish, | ||
76 | ec_GFp_simple_point_clear_finish, | ||
77 | ec_GFp_simple_point_copy, | ||
78 | ec_GFp_simple_point_set_to_infinity, | ||
79 | ec_GFp_simple_set_Jprojective_coordinates_GFp, | ||
80 | ec_GFp_simple_get_Jprojective_coordinates_GFp, | ||
81 | ec_GFp_simple_point_set_affine_coordinates_GFp, | ||
82 | ec_GFp_simple_point_get_affine_coordinates_GFp, | ||
83 | ec_GFp_simple_set_compressed_coordinates_GFp, | ||
84 | ec_GFp_simple_point2oct, | ||
85 | ec_GFp_simple_oct2point, | ||
86 | ec_GFp_simple_add, | ||
87 | ec_GFp_simple_dbl, | ||
88 | ec_GFp_simple_invert, | ||
89 | ec_GFp_simple_is_at_infinity, | ||
90 | ec_GFp_simple_is_on_curve, | ||
91 | ec_GFp_simple_cmp, | ||
92 | ec_GFp_simple_make_affine, | ||
93 | ec_GFp_simple_points_make_affine, | ||
94 | ec_GFp_mont_field_mul, | ||
95 | ec_GFp_mont_field_sqr, | ||
96 | ec_GFp_mont_field_encode, | ||
97 | ec_GFp_mont_field_decode, | ||
98 | ec_GFp_mont_field_set_to_one }; | ||
99 | |||
100 | return &ret; | ||
101 | } | ||
102 | |||
103 | |||
104 | int ec_GFp_mont_group_init(EC_GROUP *group) | ||
105 | { | ||
106 | int ok; | ||
107 | |||
108 | ok = ec_GFp_simple_group_init(group); | ||
109 | group->field_data1 = NULL; | ||
110 | group->field_data2 = NULL; | ||
111 | return ok; | ||
112 | } | ||
113 | |||
114 | |||
115 | int ec_GFp_mont_group_set_curve_GFp(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx) | ||
116 | { | ||
117 | BN_CTX *new_ctx = NULL; | ||
118 | BN_MONT_CTX *mont = NULL; | ||
119 | BIGNUM *one = NULL; | ||
120 | int ret = 0; | ||
121 | |||
122 | if (group->field_data1 != NULL) | ||
123 | { | ||
124 | BN_MONT_CTX_free(group->field_data1); | ||
125 | group->field_data1 = NULL; | ||
126 | } | ||
127 | if (group->field_data2 != NULL) | ||
128 | { | ||
129 | BN_free(group->field_data2); | ||
130 | group->field_data2 = NULL; | ||
131 | } | ||
132 | |||
133 | if (ctx == NULL) | ||
134 | { | ||
135 | ctx = new_ctx = BN_CTX_new(); | ||
136 | if (ctx == NULL) | ||
137 | return 0; | ||
138 | } | ||
139 | |||
140 | mont = BN_MONT_CTX_new(); | ||
141 | if (mont == NULL) goto err; | ||
142 | if (!BN_MONT_CTX_set(mont, p, ctx)) | ||
143 | { | ||
144 | ECerr(EC_F_GFP_MONT_GROUP_SET_CURVE_GFP, ERR_R_BN_LIB); | ||
145 | goto err; | ||
146 | } | ||
147 | one = BN_new(); | ||
148 | if (one == NULL) goto err; | ||
149 | if (!BN_to_montgomery(one, BN_value_one(), mont, ctx)) goto err; | ||
150 | |||
151 | group->field_data1 = mont; | ||
152 | mont = NULL; | ||
153 | group->field_data2 = one; | ||
154 | one = NULL; | ||
155 | |||
156 | ret = ec_GFp_simple_group_set_curve_GFp(group, p, a, b, ctx); | ||
157 | |||
158 | if (!ret) | ||
159 | { | ||
160 | BN_MONT_CTX_free(group->field_data1); | ||
161 | group->field_data1 = NULL; | ||
162 | BN_free(group->field_data2); | ||
163 | group->field_data2 = NULL; | ||
164 | } | ||
165 | |||
166 | err: | ||
167 | if (new_ctx != NULL) | ||
168 | BN_CTX_free(new_ctx); | ||
169 | if (mont != NULL) | ||
170 | BN_MONT_CTX_free(mont); | ||
171 | return ret; | ||
172 | } | ||
173 | |||
174 | |||
175 | void ec_GFp_mont_group_finish(EC_GROUP *group) | ||
176 | { | ||
177 | if (group->field_data1 != NULL) | ||
178 | { | ||
179 | BN_MONT_CTX_free(group->field_data1); | ||
180 | group->field_data1 = NULL; | ||
181 | } | ||
182 | if (group->field_data2 != NULL) | ||
183 | { | ||
184 | BN_free(group->field_data2); | ||
185 | group->field_data2 = NULL; | ||
186 | } | ||
187 | ec_GFp_simple_group_finish(group); | ||
188 | } | ||
189 | |||
190 | |||
191 | void ec_GFp_mont_group_clear_finish(EC_GROUP *group) | ||
192 | { | ||
193 | if (group->field_data1 != NULL) | ||
194 | { | ||
195 | BN_MONT_CTX_free(group->field_data1); | ||
196 | group->field_data1 = NULL; | ||
197 | } | ||
198 | if (group->field_data2 != NULL) | ||
199 | { | ||
200 | BN_clear_free(group->field_data2); | ||
201 | group->field_data2 = NULL; | ||
202 | } | ||
203 | ec_GFp_simple_group_clear_finish(group); | ||
204 | } | ||
205 | |||
206 | |||
207 | int ec_GFp_mont_group_copy(EC_GROUP *dest, const EC_GROUP *src) | ||
208 | { | ||
209 | if (dest->field_data1 != NULL) | ||
210 | { | ||
211 | BN_MONT_CTX_free(dest->field_data1); | ||
212 | dest->field_data1 = NULL; | ||
213 | } | ||
214 | if (dest->field_data2 != NULL) | ||
215 | { | ||
216 | BN_clear_free(dest->field_data2); | ||
217 | dest->field_data2 = NULL; | ||
218 | } | ||
219 | |||
220 | if (!ec_GFp_simple_group_copy(dest, src)) return 0; | ||
221 | |||
222 | if (src->field_data1 != NULL) | ||
223 | { | ||
224 | dest->field_data1 = BN_MONT_CTX_new(); | ||
225 | if (dest->field_data1 == NULL) return 0; | ||
226 | if (!BN_MONT_CTX_copy(dest->field_data1, src->field_data1)) goto err; | ||
227 | } | ||
228 | if (src->field_data2 != NULL) | ||
229 | { | ||
230 | dest->field_data2 = BN_dup(src->field_data2); | ||
231 | if (dest->field_data2 == NULL) goto err; | ||
232 | } | ||
233 | |||
234 | return 1; | ||
235 | |||
236 | err: | ||
237 | if (dest->field_data1 != NULL) | ||
238 | { | ||
239 | BN_MONT_CTX_free(dest->field_data1); | ||
240 | dest->field_data1 = NULL; | ||
241 | } | ||
242 | return 0; | ||
243 | } | ||
244 | |||
245 | |||
246 | int ec_GFp_mont_field_mul(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx) | ||
247 | { | ||
248 | if (group->field_data1 == NULL) | ||
249 | { | ||
250 | ECerr(EC_F_EC_GFP_MONT_FIELD_MUL, EC_R_NOT_INITIALIZED); | ||
251 | return 0; | ||
252 | } | ||
253 | |||
254 | return BN_mod_mul_montgomery(r, a, b, group->field_data1, ctx); | ||
255 | } | ||
256 | |||
257 | |||
258 | int ec_GFp_mont_field_sqr(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, BN_CTX *ctx) | ||
259 | { | ||
260 | if (group->field_data1 == NULL) | ||
261 | { | ||
262 | ECerr(EC_F_EC_GFP_MONT_FIELD_SQR, EC_R_NOT_INITIALIZED); | ||
263 | return 0; | ||
264 | } | ||
265 | |||
266 | return BN_mod_mul_montgomery(r, a, a, group->field_data1, ctx); | ||
267 | } | ||
268 | |||
269 | |||
270 | int ec_GFp_mont_field_encode(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, BN_CTX *ctx) | ||
271 | { | ||
272 | if (group->field_data1 == NULL) | ||
273 | { | ||
274 | ECerr(EC_F_EC_GFP_MONT_FIELD_ENCODE, EC_R_NOT_INITIALIZED); | ||
275 | return 0; | ||
276 | } | ||
277 | |||
278 | return BN_to_montgomery(r, a, (BN_MONT_CTX *)group->field_data1, ctx); | ||
279 | } | ||
280 | |||
281 | |||
282 | int ec_GFp_mont_field_decode(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, BN_CTX *ctx) | ||
283 | { | ||
284 | if (group->field_data1 == NULL) | ||
285 | { | ||
286 | ECerr(EC_F_EC_GFP_MONT_FIELD_DECODE, EC_R_NOT_INITIALIZED); | ||
287 | return 0; | ||
288 | } | ||
289 | |||
290 | return BN_from_montgomery(r, a, group->field_data1, ctx); | ||
291 | } | ||
292 | |||
293 | |||
294 | int ec_GFp_mont_field_set_to_one(const EC_GROUP *group, BIGNUM *r, BN_CTX *ctx) | ||
295 | { | ||
296 | if (group->field_data2 == NULL) | ||
297 | { | ||
298 | ECerr(EC_F_EC_GFP_MONT_FIELD_DECODE, EC_R_NOT_INITIALIZED); | ||
299 | return 0; | ||
300 | } | ||
301 | |||
302 | if (!BN_copy(r, group->field_data2)) return 0; | ||
303 | return 1; | ||
304 | } | ||
diff --git a/src/lib/libcrypto/ec/ecp_nist.c b/src/lib/libcrypto/ec/ecp_nist.c new file mode 100644 index 0000000000..ed07748675 --- /dev/null +++ b/src/lib/libcrypto/ec/ecp_nist.c | |||
@@ -0,0 +1,134 @@ | |||
1 | /* crypto/ec/ecp_nist.c */ | ||
2 | /* ==================================================================== | ||
3 | * Copyright (c) 1998-2001 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 | |||
58 | #if 0 | ||
59 | const EC_METHOD *EC_GFp_nist_method(void) | ||
60 | { | ||
61 | static const EC_METHOD ret = { | ||
62 | ec_GFp_nist_group_init, | ||
63 | ec_GFp_nist_group_finish, | ||
64 | ec_GFp_nist_group_clear_finish, | ||
65 | ec_GFp_nist_group_copy, | ||
66 | ec_GFp_nist_group_set_curve_GFp, | ||
67 | ec_GFp_simple_group_get_curve_GFp, | ||
68 | ec_GFp_simple_group_set_generator, | ||
69 | ec_GFp_simple_group_get0_generator, | ||
70 | ec_GFp_simple_group_get_order, | ||
71 | ec_GFp_simple_group_get_cofactor, | ||
72 | ec_GFp_simple_point_init, | ||
73 | ec_GFp_simple_point_finish, | ||
74 | ec_GFp_simple_point_clear_finish, | ||
75 | ec_GFp_simple_point_copy, | ||
76 | ec_GFp_simple_point_set_to_infinity, | ||
77 | ec_GFp_simple_set_Jprojective_coordinates_GFp, | ||
78 | ec_GFp_simple_get_Jprojective_coordinates_GFp, | ||
79 | ec_GFp_simple_point_set_affine_coordinates_GFp, | ||
80 | ec_GFp_simple_point_get_affine_coordinates_GFp, | ||
81 | ec_GFp_simple_set_compressed_coordinates_GFp, | ||
82 | ec_GFp_simple_point2oct, | ||
83 | ec_GFp_simple_oct2point, | ||
84 | ec_GFp_simple_add, | ||
85 | ec_GFp_simple_dbl, | ||
86 | ec_GFp_simple_invert, | ||
87 | ec_GFp_simple_is_at_infinity, | ||
88 | ec_GFp_simple_is_on_curve, | ||
89 | ec_GFp_simple_cmp, | ||
90 | ec_GFp_simple_make_affine, | ||
91 | ec_GFp_simple_points_make_affine, | ||
92 | ec_GFp_nist_field_mul, | ||
93 | ec_GFp_nist_field_sqr, | ||
94 | 0 /* field_encode */, | ||
95 | 0 /* field_decode */, | ||
96 | 0 /* field_set_to_one */ }; | ||
97 | |||
98 | return &ret; | ||
99 | } | ||
100 | #endif | ||
101 | |||
102 | |||
103 | int ec_GFp_nist_group_init(EC_GROUP *group) | ||
104 | { | ||
105 | int ok; | ||
106 | |||
107 | ok = ec_GFp_simple_group_init(group); | ||
108 | group->field_data1 = NULL; | ||
109 | return ok; | ||
110 | } | ||
111 | |||
112 | |||
113 | int ec_GFp_nist_group_set_curve_GFp(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx); | ||
114 | /* TODO */ | ||
115 | |||
116 | |||
117 | void ec_GFp_nist_group_finish(EC_GROUP *group); | ||
118 | /* TODO */ | ||
119 | |||
120 | |||
121 | void ec_GFp_nist_group_clear_finish(EC_GROUP *group); | ||
122 | /* TODO */ | ||
123 | |||
124 | |||
125 | int ec_GFp_nist_group_copy(EC_GROUP *dest, const EC_GROUP *src); | ||
126 | /* TODO */ | ||
127 | |||
128 | |||
129 | int ec_GFp_nist_field_mul(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx); | ||
130 | /* TODO */ | ||
131 | |||
132 | |||
133 | int ec_GFp_nist_field_sqr(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, BN_CTX *ctx); | ||
134 | /* TODO */ | ||
diff --git a/src/lib/libcrypto/ec/ecp_smpl.c b/src/lib/libcrypto/ec/ecp_smpl.c new file mode 100644 index 0000000000..4666a052bf --- /dev/null +++ b/src/lib/libcrypto/ec/ecp_smpl.c | |||
@@ -0,0 +1,1717 @@ | |||
1 | /* crypto/ec/ecp_smpl.c */ | ||
2 | /* Includes code written by Lenka Fibikova <fibikova@exp-math.uni-essen.de> | ||
3 | * for the OpenSSL project. */ | ||
4 | /* ==================================================================== | ||
5 | * Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved. | ||
6 | * | ||
7 | * Redistribution and use in source and binary forms, with or without | ||
8 | * modification, are permitted provided that the following conditions | ||
9 | * are met: | ||
10 | * | ||
11 | * 1. Redistributions of source code must retain the above copyright | ||
12 | * notice, this list of conditions and the following disclaimer. | ||
13 | * | ||
14 | * 2. Redistributions in binary form must reproduce the above copyright | ||
15 | * notice, this list of conditions and the following disclaimer in | ||
16 | * the documentation and/or other materials provided with the | ||
17 | * distribution. | ||
18 | * | ||
19 | * 3. All advertising materials mentioning features or use of this | ||
20 | * software must display the following acknowledgment: | ||
21 | * "This product includes software developed by the OpenSSL Project | ||
22 | * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" | ||
23 | * | ||
24 | * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to | ||
25 | * endorse or promote products derived from this software without | ||
26 | * prior written permission. For written permission, please contact | ||
27 | * openssl-core@openssl.org. | ||
28 | * | ||
29 | * 5. Products derived from this software may not be called "OpenSSL" | ||
30 | * nor may "OpenSSL" appear in their names without prior written | ||
31 | * permission of the OpenSSL Project. | ||
32 | * | ||
33 | * 6. Redistributions of any form whatsoever must retain the following | ||
34 | * acknowledgment: | ||
35 | * "This product includes software developed by the OpenSSL Project | ||
36 | * for use in the OpenSSL Toolkit (http://www.openssl.org/)" | ||
37 | * | ||
38 | * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY | ||
39 | * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
40 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | ||
41 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR | ||
42 | * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
43 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
44 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
45 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
46 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
47 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
48 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED | ||
49 | * OF THE POSSIBILITY OF SUCH DAMAGE. | ||
50 | * ==================================================================== | ||
51 | * | ||
52 | * This product includes cryptographic software written by Eric Young | ||
53 | * (eay@cryptsoft.com). This product includes software written by Tim | ||
54 | * Hudson (tjh@cryptsoft.com). | ||
55 | * | ||
56 | */ | ||
57 | |||
58 | #include <openssl/err.h> | ||
59 | |||
60 | #include "ec_lcl.h" | ||
61 | |||
62 | |||
63 | const EC_METHOD *EC_GFp_simple_method(void) | ||
64 | { | ||
65 | static const EC_METHOD ret = { | ||
66 | ec_GFp_simple_group_init, | ||
67 | ec_GFp_simple_group_finish, | ||
68 | ec_GFp_simple_group_clear_finish, | ||
69 | ec_GFp_simple_group_copy, | ||
70 | ec_GFp_simple_group_set_curve_GFp, | ||
71 | ec_GFp_simple_group_get_curve_GFp, | ||
72 | ec_GFp_simple_group_set_generator, | ||
73 | ec_GFp_simple_group_get0_generator, | ||
74 | ec_GFp_simple_group_get_order, | ||
75 | ec_GFp_simple_group_get_cofactor, | ||
76 | ec_GFp_simple_point_init, | ||
77 | ec_GFp_simple_point_finish, | ||
78 | ec_GFp_simple_point_clear_finish, | ||
79 | ec_GFp_simple_point_copy, | ||
80 | ec_GFp_simple_point_set_to_infinity, | ||
81 | ec_GFp_simple_set_Jprojective_coordinates_GFp, | ||
82 | ec_GFp_simple_get_Jprojective_coordinates_GFp, | ||
83 | ec_GFp_simple_point_set_affine_coordinates_GFp, | ||
84 | ec_GFp_simple_point_get_affine_coordinates_GFp, | ||
85 | ec_GFp_simple_set_compressed_coordinates_GFp, | ||
86 | ec_GFp_simple_point2oct, | ||
87 | ec_GFp_simple_oct2point, | ||
88 | ec_GFp_simple_add, | ||
89 | ec_GFp_simple_dbl, | ||
90 | ec_GFp_simple_invert, | ||
91 | ec_GFp_simple_is_at_infinity, | ||
92 | ec_GFp_simple_is_on_curve, | ||
93 | ec_GFp_simple_cmp, | ||
94 | ec_GFp_simple_make_affine, | ||
95 | ec_GFp_simple_points_make_affine, | ||
96 | ec_GFp_simple_field_mul, | ||
97 | ec_GFp_simple_field_sqr, | ||
98 | 0 /* field_encode */, | ||
99 | 0 /* field_decode */, | ||
100 | 0 /* field_set_to_one */ }; | ||
101 | |||
102 | return &ret; | ||
103 | } | ||
104 | |||
105 | |||
106 | int ec_GFp_simple_group_init(EC_GROUP *group) | ||
107 | { | ||
108 | BN_init(&group->field); | ||
109 | BN_init(&group->a); | ||
110 | BN_init(&group->b); | ||
111 | group->a_is_minus3 = 0; | ||
112 | group->generator = NULL; | ||
113 | BN_init(&group->order); | ||
114 | BN_init(&group->cofactor); | ||
115 | return 1; | ||
116 | } | ||
117 | |||
118 | |||
119 | void ec_GFp_simple_group_finish(EC_GROUP *group) | ||
120 | { | ||
121 | BN_free(&group->field); | ||
122 | BN_free(&group->a); | ||
123 | BN_free(&group->b); | ||
124 | if (group->generator != NULL) | ||
125 | EC_POINT_free(group->generator); | ||
126 | BN_free(&group->order); | ||
127 | BN_free(&group->cofactor); | ||
128 | } | ||
129 | |||
130 | |||
131 | void ec_GFp_simple_group_clear_finish(EC_GROUP *group) | ||
132 | { | ||
133 | BN_clear_free(&group->field); | ||
134 | BN_clear_free(&group->a); | ||
135 | BN_clear_free(&group->b); | ||
136 | if (group->generator != NULL) | ||
137 | { | ||
138 | EC_POINT_clear_free(group->generator); | ||
139 | group->generator = NULL; | ||
140 | } | ||
141 | BN_clear_free(&group->order); | ||
142 | BN_clear_free(&group->cofactor); | ||
143 | } | ||
144 | |||
145 | |||
146 | int ec_GFp_simple_group_copy(EC_GROUP *dest, const EC_GROUP *src) | ||
147 | { | ||
148 | if (!BN_copy(&dest->field, &src->field)) return 0; | ||
149 | if (!BN_copy(&dest->a, &src->a)) return 0; | ||
150 | if (!BN_copy(&dest->b, &src->b)) return 0; | ||
151 | |||
152 | dest->a_is_minus3 = src->a_is_minus3; | ||
153 | |||
154 | if (src->generator != NULL) | ||
155 | { | ||
156 | if (dest->generator == NULL) | ||
157 | { | ||
158 | dest->generator = EC_POINT_new(dest); | ||
159 | if (dest->generator == NULL) return 0; | ||
160 | } | ||
161 | if (!EC_POINT_copy(dest->generator, src->generator)) return 0; | ||
162 | } | ||
163 | else | ||
164 | { | ||
165 | /* src->generator == NULL */ | ||
166 | if (dest->generator != NULL) | ||
167 | { | ||
168 | EC_POINT_clear_free(dest->generator); | ||
169 | dest->generator = NULL; | ||
170 | } | ||
171 | } | ||
172 | |||
173 | if (!BN_copy(&dest->order, &src->order)) return 0; | ||
174 | if (!BN_copy(&dest->cofactor, &src->cofactor)) return 0; | ||
175 | |||
176 | return 1; | ||
177 | } | ||
178 | |||
179 | |||
180 | int ec_GFp_simple_group_set_curve_GFp(EC_GROUP *group, | ||
181 | const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx) | ||
182 | { | ||
183 | int ret = 0; | ||
184 | BN_CTX *new_ctx = NULL; | ||
185 | BIGNUM *tmp_a; | ||
186 | |||
187 | /* p must be a prime > 3 */ | ||
188 | if (BN_num_bits(p) <= 2 || !BN_is_odd(p)) | ||
189 | { | ||
190 | ECerr(EC_F_EC_GFP_SIMPLE_GROUP_SET_CURVE_GFP, EC_R_INVALID_FIELD); | ||
191 | return 0; | ||
192 | } | ||
193 | |||
194 | if (ctx == NULL) | ||
195 | { | ||
196 | ctx = new_ctx = BN_CTX_new(); | ||
197 | if (ctx == NULL) | ||
198 | return 0; | ||
199 | } | ||
200 | |||
201 | BN_CTX_start(ctx); | ||
202 | tmp_a = BN_CTX_get(ctx); | ||
203 | if (tmp_a == NULL) goto err; | ||
204 | |||
205 | /* group->field */ | ||
206 | if (!BN_copy(&group->field, p)) goto err; | ||
207 | group->field.neg = 0; | ||
208 | |||
209 | /* group->a */ | ||
210 | if (!BN_nnmod(tmp_a, a, p, ctx)) goto err; | ||
211 | if (group->meth->field_encode) | ||
212 | { if (!group->meth->field_encode(group, &group->a, tmp_a, ctx)) goto err; } | ||
213 | else | ||
214 | if (!BN_copy(&group->a, tmp_a)) goto err; | ||
215 | |||
216 | /* group->b */ | ||
217 | if (!BN_nnmod(&group->b, b, p, ctx)) goto err; | ||
218 | if (group->meth->field_encode) | ||
219 | if (!group->meth->field_encode(group, &group->b, &group->b, ctx)) goto err; | ||
220 | |||
221 | /* group->a_is_minus3 */ | ||
222 | if (!BN_add_word(tmp_a, 3)) goto err; | ||
223 | group->a_is_minus3 = (0 == BN_cmp(tmp_a, &group->field)); | ||
224 | |||
225 | ret = 1; | ||
226 | |||
227 | err: | ||
228 | BN_CTX_end(ctx); | ||
229 | if (new_ctx != NULL) | ||
230 | BN_CTX_free(new_ctx); | ||
231 | return ret; | ||
232 | } | ||
233 | |||
234 | |||
235 | int ec_GFp_simple_group_get_curve_GFp(const EC_GROUP *group, BIGNUM *p, BIGNUM *a, BIGNUM *b, BN_CTX *ctx) | ||
236 | { | ||
237 | int ret = 0; | ||
238 | BN_CTX *new_ctx = NULL; | ||
239 | |||
240 | if (p != NULL) | ||
241 | { | ||
242 | if (!BN_copy(p, &group->field)) return 0; | ||
243 | } | ||
244 | |||
245 | if (a != NULL || b != NULL) | ||
246 | { | ||
247 | if (group->meth->field_decode) | ||
248 | { | ||
249 | if (ctx == NULL) | ||
250 | { | ||
251 | ctx = new_ctx = BN_CTX_new(); | ||
252 | if (ctx == NULL) | ||
253 | return 0; | ||
254 | } | ||
255 | if (a != NULL) | ||
256 | { | ||
257 | if (!group->meth->field_decode(group, a, &group->a, ctx)) goto err; | ||
258 | } | ||
259 | if (b != NULL) | ||
260 | { | ||
261 | if (!group->meth->field_decode(group, b, &group->b, ctx)) goto err; | ||
262 | } | ||
263 | } | ||
264 | else | ||
265 | { | ||
266 | if (a != NULL) | ||
267 | { | ||
268 | if (!BN_copy(a, &group->a)) goto err; | ||
269 | } | ||
270 | if (b != NULL) | ||
271 | { | ||
272 | if (!BN_copy(b, &group->b)) goto err; | ||
273 | } | ||
274 | } | ||
275 | } | ||
276 | |||
277 | ret = 1; | ||
278 | |||
279 | err: | ||
280 | if (new_ctx) | ||
281 | BN_CTX_free(new_ctx); | ||
282 | return ret; | ||
283 | } | ||
284 | |||
285 | |||
286 | |||
287 | int ec_GFp_simple_group_set_generator(EC_GROUP *group, const EC_POINT *generator, | ||
288 | const BIGNUM *order, const BIGNUM *cofactor) | ||
289 | { | ||
290 | if (generator == NULL) | ||
291 | { | ||
292 | ECerr(EC_F_EC_GFP_SIMPLE_GROUP_SET_GENERATOR, ERR_R_PASSED_NULL_PARAMETER); | ||
293 | return 0 ; | ||
294 | } | ||
295 | |||
296 | if (group->generator == NULL) | ||
297 | { | ||
298 | group->generator = EC_POINT_new(group); | ||
299 | if (group->generator == NULL) return 0; | ||
300 | } | ||
301 | if (!EC_POINT_copy(group->generator, generator)) return 0; | ||
302 | |||
303 | if (order != NULL) | ||
304 | { if (!BN_copy(&group->order, order)) return 0; } | ||
305 | else | ||
306 | { if (!BN_zero(&group->order)) return 0; } | ||
307 | |||
308 | if (cofactor != NULL) | ||
309 | { if (!BN_copy(&group->cofactor, cofactor)) return 0; } | ||
310 | else | ||
311 | { if (!BN_zero(&group->cofactor)) return 0; } | ||
312 | |||
313 | return 1; | ||
314 | } | ||
315 | |||
316 | |||
317 | EC_POINT *ec_GFp_simple_group_get0_generator(const EC_GROUP *group) | ||
318 | { | ||
319 | return group->generator; | ||
320 | } | ||
321 | |||
322 | |||
323 | int ec_GFp_simple_group_get_order(const EC_GROUP *group, BIGNUM *order, BN_CTX *ctx) | ||
324 | { | ||
325 | if (!BN_copy(order, &group->order)) | ||
326 | return 0; | ||
327 | |||
328 | return !BN_is_zero(&group->order); | ||
329 | } | ||
330 | |||
331 | |||
332 | int ec_GFp_simple_group_get_cofactor(const EC_GROUP *group, BIGNUM *cofactor, BN_CTX *ctx) | ||
333 | { | ||
334 | if (!BN_copy(cofactor, &group->cofactor)) | ||
335 | return 0; | ||
336 | |||
337 | return !BN_is_zero(&group->cofactor); | ||
338 | } | ||
339 | |||
340 | |||
341 | int ec_GFp_simple_point_init(EC_POINT *point) | ||
342 | { | ||
343 | BN_init(&point->X); | ||
344 | BN_init(&point->Y); | ||
345 | BN_init(&point->Z); | ||
346 | point->Z_is_one = 0; | ||
347 | |||
348 | return 1; | ||
349 | } | ||
350 | |||
351 | |||
352 | void ec_GFp_simple_point_finish(EC_POINT *point) | ||
353 | { | ||
354 | BN_free(&point->X); | ||
355 | BN_free(&point->Y); | ||
356 | BN_free(&point->Z); | ||
357 | } | ||
358 | |||
359 | |||
360 | void ec_GFp_simple_point_clear_finish(EC_POINT *point) | ||
361 | { | ||
362 | BN_clear_free(&point->X); | ||
363 | BN_clear_free(&point->Y); | ||
364 | BN_clear_free(&point->Z); | ||
365 | point->Z_is_one = 0; | ||
366 | } | ||
367 | |||
368 | |||
369 | int ec_GFp_simple_point_copy(EC_POINT *dest, const EC_POINT *src) | ||
370 | { | ||
371 | if (!BN_copy(&dest->X, &src->X)) return 0; | ||
372 | if (!BN_copy(&dest->Y, &src->Y)) return 0; | ||
373 | if (!BN_copy(&dest->Z, &src->Z)) return 0; | ||
374 | dest->Z_is_one = src->Z_is_one; | ||
375 | |||
376 | return 1; | ||
377 | } | ||
378 | |||
379 | |||
380 | int ec_GFp_simple_point_set_to_infinity(const EC_GROUP *group, EC_POINT *point) | ||
381 | { | ||
382 | point->Z_is_one = 0; | ||
383 | return (BN_zero(&point->Z)); | ||
384 | } | ||
385 | |||
386 | |||
387 | int ec_GFp_simple_set_Jprojective_coordinates_GFp(const EC_GROUP *group, EC_POINT *point, | ||
388 | const BIGNUM *x, const BIGNUM *y, const BIGNUM *z, BN_CTX *ctx) | ||
389 | { | ||
390 | BN_CTX *new_ctx = NULL; | ||
391 | int ret = 0; | ||
392 | |||
393 | if (ctx == NULL) | ||
394 | { | ||
395 | ctx = new_ctx = BN_CTX_new(); | ||
396 | if (ctx == NULL) | ||
397 | return 0; | ||
398 | } | ||
399 | |||
400 | if (x != NULL) | ||
401 | { | ||
402 | if (!BN_nnmod(&point->X, x, &group->field, ctx)) goto err; | ||
403 | if (group->meth->field_encode) | ||
404 | { | ||
405 | if (!group->meth->field_encode(group, &point->X, &point->X, ctx)) goto err; | ||
406 | } | ||
407 | } | ||
408 | |||
409 | if (y != NULL) | ||
410 | { | ||
411 | if (!BN_nnmod(&point->Y, y, &group->field, ctx)) goto err; | ||
412 | if (group->meth->field_encode) | ||
413 | { | ||
414 | if (!group->meth->field_encode(group, &point->Y, &point->Y, ctx)) goto err; | ||
415 | } | ||
416 | } | ||
417 | |||
418 | if (z != NULL) | ||
419 | { | ||
420 | int Z_is_one; | ||
421 | |||
422 | if (!BN_nnmod(&point->Z, z, &group->field, ctx)) goto err; | ||
423 | Z_is_one = BN_is_one(&point->Z); | ||
424 | if (group->meth->field_encode) | ||
425 | { | ||
426 | if (Z_is_one && (group->meth->field_set_to_one != 0)) | ||
427 | { | ||
428 | if (!group->meth->field_set_to_one(group, &point->Z, ctx)) goto err; | ||
429 | } | ||
430 | else | ||
431 | { | ||
432 | if (!group->meth->field_encode(group, &point->Z, &point->Z, ctx)) goto err; | ||
433 | } | ||
434 | } | ||
435 | point->Z_is_one = Z_is_one; | ||
436 | } | ||
437 | |||
438 | ret = 1; | ||
439 | |||
440 | err: | ||
441 | if (new_ctx != NULL) | ||
442 | BN_CTX_free(new_ctx); | ||
443 | return ret; | ||
444 | } | ||
445 | |||
446 | |||
447 | int ec_GFp_simple_get_Jprojective_coordinates_GFp(const EC_GROUP *group, const EC_POINT *point, | ||
448 | BIGNUM *x, BIGNUM *y, BIGNUM *z, BN_CTX *ctx) | ||
449 | { | ||
450 | BN_CTX *new_ctx = NULL; | ||
451 | int ret = 0; | ||
452 | |||
453 | if (group->meth->field_decode != 0) | ||
454 | { | ||
455 | if (ctx == NULL) | ||
456 | { | ||
457 | ctx = new_ctx = BN_CTX_new(); | ||
458 | if (ctx == NULL) | ||
459 | return 0; | ||
460 | } | ||
461 | |||
462 | if (x != NULL) | ||
463 | { | ||
464 | if (!group->meth->field_decode(group, x, &point->X, ctx)) goto err; | ||
465 | } | ||
466 | if (y != NULL) | ||
467 | { | ||
468 | if (!group->meth->field_decode(group, y, &point->Y, ctx)) goto err; | ||
469 | } | ||
470 | if (z != NULL) | ||
471 | { | ||
472 | if (!group->meth->field_decode(group, z, &point->Z, ctx)) goto err; | ||
473 | } | ||
474 | } | ||
475 | else | ||
476 | { | ||
477 | if (x != NULL) | ||
478 | { | ||
479 | if (!BN_copy(x, &point->X)) goto err; | ||
480 | } | ||
481 | if (y != NULL) | ||
482 | { | ||
483 | if (!BN_copy(y, &point->Y)) goto err; | ||
484 | } | ||
485 | if (z != NULL) | ||
486 | { | ||
487 | if (!BN_copy(z, &point->Z)) goto err; | ||
488 | } | ||
489 | } | ||
490 | |||
491 | ret = 1; | ||
492 | |||
493 | err: | ||
494 | if (new_ctx != NULL) | ||
495 | BN_CTX_free(new_ctx); | ||
496 | return ret; | ||
497 | } | ||
498 | |||
499 | |||
500 | int ec_GFp_simple_point_set_affine_coordinates_GFp(const EC_GROUP *group, EC_POINT *point, | ||
501 | const BIGNUM *x, const BIGNUM *y, BN_CTX *ctx) | ||
502 | { | ||
503 | if (x == NULL || y == NULL) | ||
504 | { | ||
505 | /* unlike for projective coordinates, we do not tolerate this */ | ||
506 | ECerr(EC_F_EC_GFP_SIMPLE_POINT_SET_AFFINE_COORDINATES_GFP, ERR_R_PASSED_NULL_PARAMETER); | ||
507 | return 0; | ||
508 | } | ||
509 | |||
510 | return EC_POINT_set_Jprojective_coordinates_GFp(group, point, x, y, BN_value_one(), ctx); | ||
511 | } | ||
512 | |||
513 | |||
514 | int ec_GFp_simple_point_get_affine_coordinates_GFp(const EC_GROUP *group, const EC_POINT *point, | ||
515 | BIGNUM *x, BIGNUM *y, BN_CTX *ctx) | ||
516 | { | ||
517 | BN_CTX *new_ctx = NULL; | ||
518 | BIGNUM *X, *Y, *Z, *Z_1, *Z_2, *Z_3; | ||
519 | const BIGNUM *X_, *Y_, *Z_; | ||
520 | int ret = 0; | ||
521 | |||
522 | if (EC_POINT_is_at_infinity(group, point)) | ||
523 | { | ||
524 | ECerr(EC_F_EC_GFP_SIMPLE_POINT_GET_AFFINE_COORDINATES_GFP, EC_R_POINT_AT_INFINITY); | ||
525 | return 0; | ||
526 | } | ||
527 | |||
528 | if (ctx == NULL) | ||
529 | { | ||
530 | ctx = new_ctx = BN_CTX_new(); | ||
531 | if (ctx == NULL) | ||
532 | return 0; | ||
533 | } | ||
534 | |||
535 | BN_CTX_start(ctx); | ||
536 | X = BN_CTX_get(ctx); | ||
537 | Y = BN_CTX_get(ctx); | ||
538 | Z = BN_CTX_get(ctx); | ||
539 | Z_1 = BN_CTX_get(ctx); | ||
540 | Z_2 = BN_CTX_get(ctx); | ||
541 | Z_3 = BN_CTX_get(ctx); | ||
542 | if (Z_3 == NULL) goto err; | ||
543 | |||
544 | /* transform (X, Y, Z) into (x, y) := (X/Z^2, Y/Z^3) */ | ||
545 | |||
546 | if (group->meth->field_decode) | ||
547 | { | ||
548 | if (!group->meth->field_decode(group, X, &point->X, ctx)) goto err; | ||
549 | if (!group->meth->field_decode(group, Y, &point->Y, ctx)) goto err; | ||
550 | if (!group->meth->field_decode(group, Z, &point->Z, ctx)) goto err; | ||
551 | X_ = X; Y_ = Y; Z_ = Z; | ||
552 | } | ||
553 | else | ||
554 | { | ||
555 | X_ = &point->X; | ||
556 | Y_ = &point->Y; | ||
557 | Z_ = &point->Z; | ||
558 | } | ||
559 | |||
560 | if (BN_is_one(Z_)) | ||
561 | { | ||
562 | if (x != NULL) | ||
563 | { | ||
564 | if (!BN_copy(x, X_)) goto err; | ||
565 | } | ||
566 | if (y != NULL) | ||
567 | { | ||
568 | if (!BN_copy(y, Y_)) goto err; | ||
569 | } | ||
570 | } | ||
571 | else | ||
572 | { | ||
573 | if (!BN_mod_inverse(Z_1, Z_, &group->field, ctx)) | ||
574 | { | ||
575 | ECerr(EC_F_EC_GFP_SIMPLE_POINT_GET_AFFINE_COORDINATES_GFP, ERR_R_BN_LIB); | ||
576 | goto err; | ||
577 | } | ||
578 | |||
579 | if (group->meth->field_encode == 0) | ||
580 | { | ||
581 | /* field_sqr works on standard representation */ | ||
582 | if (!group->meth->field_sqr(group, Z_2, Z_1, ctx)) goto err; | ||
583 | } | ||
584 | else | ||
585 | { | ||
586 | if (!BN_mod_sqr(Z_2, Z_1, &group->field, ctx)) goto err; | ||
587 | } | ||
588 | |||
589 | if (x != NULL) | ||
590 | { | ||
591 | if (group->meth->field_encode == 0) | ||
592 | { | ||
593 | /* field_mul works on standard representation */ | ||
594 | if (!group->meth->field_mul(group, x, X_, Z_2, ctx)) goto err; | ||
595 | } | ||
596 | else | ||
597 | { | ||
598 | if (!BN_mod_mul(x, X_, Z_2, &group->field, ctx)) goto err; | ||
599 | } | ||
600 | } | ||
601 | |||
602 | if (y != NULL) | ||
603 | { | ||
604 | if (group->meth->field_encode == 0) | ||
605 | { | ||
606 | /* field_mul works on standard representation */ | ||
607 | if (!group->meth->field_mul(group, Z_3, Z_2, Z_1, ctx)) goto err; | ||
608 | if (!group->meth->field_mul(group, y, Y_, Z_3, ctx)) goto err; | ||
609 | |||
610 | } | ||
611 | else | ||
612 | { | ||
613 | if (!BN_mod_mul(Z_3, Z_2, Z_1, &group->field, ctx)) goto err; | ||
614 | if (!BN_mod_mul(y, Y_, Z_3, &group->field, ctx)) goto err; | ||
615 | } | ||
616 | } | ||
617 | } | ||
618 | |||
619 | ret = 1; | ||
620 | |||
621 | err: | ||
622 | BN_CTX_end(ctx); | ||
623 | if (new_ctx != NULL) | ||
624 | BN_CTX_free(new_ctx); | ||
625 | return ret; | ||
626 | } | ||
627 | |||
628 | |||
629 | int ec_GFp_simple_set_compressed_coordinates_GFp(const EC_GROUP *group, EC_POINT *point, | ||
630 | const BIGNUM *x_, int y_bit, BN_CTX *ctx) | ||
631 | { | ||
632 | BN_CTX *new_ctx = NULL; | ||
633 | BIGNUM *tmp1, *tmp2, *x, *y; | ||
634 | int ret = 0; | ||
635 | |||
636 | if (ctx == NULL) | ||
637 | { | ||
638 | ctx = new_ctx = BN_CTX_new(); | ||
639 | if (ctx == NULL) | ||
640 | return 0; | ||
641 | } | ||
642 | |||
643 | y_bit = (y_bit != 0); | ||
644 | |||
645 | BN_CTX_start(ctx); | ||
646 | tmp1 = BN_CTX_get(ctx); | ||
647 | tmp2 = BN_CTX_get(ctx); | ||
648 | x = BN_CTX_get(ctx); | ||
649 | y = BN_CTX_get(ctx); | ||
650 | if (y == NULL) goto err; | ||
651 | |||
652 | /* Recover y. We have a Weierstrass equation | ||
653 | * y^2 = x^3 + a*x + b, | ||
654 | * so y is one of the square roots of x^3 + a*x + b. | ||
655 | */ | ||
656 | |||
657 | /* tmp1 := x^3 */ | ||
658 | if (!BN_nnmod(x, x_, &group->field,ctx)) goto err; | ||
659 | if (group->meth->field_decode == 0) | ||
660 | { | ||
661 | /* field_{sqr,mul} work on standard representation */ | ||
662 | if (!group->meth->field_sqr(group, tmp2, x_, ctx)) goto err; | ||
663 | if (!group->meth->field_mul(group, tmp1, tmp2, x_, ctx)) goto err; | ||
664 | } | ||
665 | else | ||
666 | { | ||
667 | if (!BN_mod_sqr(tmp2, x_, &group->field, ctx)) goto err; | ||
668 | if (!BN_mod_mul(tmp1, tmp2, x_, &group->field, ctx)) goto err; | ||
669 | } | ||
670 | |||
671 | /* tmp1 := tmp1 + a*x */ | ||
672 | if (group->a_is_minus3) | ||
673 | { | ||
674 | if (!BN_mod_lshift1_quick(tmp2, x, &group->field)) goto err; | ||
675 | if (!BN_mod_add_quick(tmp2, tmp2, x, &group->field)) goto err; | ||
676 | if (!BN_mod_sub_quick(tmp1, tmp1, tmp2, &group->field)) goto err; | ||
677 | } | ||
678 | else | ||
679 | { | ||
680 | if (group->meth->field_decode) | ||
681 | { | ||
682 | if (!group->meth->field_decode(group, tmp2, &group->a, ctx)) goto err; | ||
683 | if (!BN_mod_mul(tmp2, tmp2, x, &group->field, ctx)) goto err; | ||
684 | } | ||
685 | else | ||
686 | { | ||
687 | /* field_mul works on standard representation */ | ||
688 | if (!group->meth->field_mul(group, tmp2, &group->a, x, ctx)) goto err; | ||
689 | } | ||
690 | |||
691 | if (!BN_mod_add_quick(tmp1, tmp1, tmp2, &group->field)) goto err; | ||
692 | } | ||
693 | |||
694 | /* tmp1 := tmp1 + b */ | ||
695 | if (group->meth->field_decode) | ||
696 | { | ||
697 | if (!group->meth->field_decode(group, tmp2, &group->b, ctx)) goto err; | ||
698 | if (!BN_mod_add_quick(tmp1, tmp1, tmp2, &group->field)) goto err; | ||
699 | } | ||
700 | else | ||
701 | { | ||
702 | if (!BN_mod_add_quick(tmp1, tmp1, &group->b, &group->field)) goto err; | ||
703 | } | ||
704 | |||
705 | if (!BN_mod_sqrt(y, tmp1, &group->field, ctx)) | ||
706 | { | ||
707 | unsigned long err = ERR_peek_error(); | ||
708 | |||
709 | if (ERR_GET_LIB(err) == ERR_LIB_BN && ERR_GET_REASON(err) == BN_R_NOT_A_SQUARE) | ||
710 | { | ||
711 | (void)ERR_get_error(); | ||
712 | ECerr(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES_GFP, EC_R_INVALID_COMPRESSED_POINT); | ||
713 | } | ||
714 | else | ||
715 | ECerr(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES_GFP, ERR_R_BN_LIB); | ||
716 | goto err; | ||
717 | } | ||
718 | /* If tmp1 is not a square (i.e. there is no point on the curve with | ||
719 | * our x), then y now is a nonsense value too */ | ||
720 | |||
721 | if (y_bit != BN_is_odd(y)) | ||
722 | { | ||
723 | if (BN_is_zero(y)) | ||
724 | { | ||
725 | int kron; | ||
726 | |||
727 | kron = BN_kronecker(x, &group->field, ctx); | ||
728 | if (kron == -2) goto err; | ||
729 | |||
730 | if (kron == 1) | ||
731 | ECerr(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES_GFP, EC_R_INVALID_COMPRESSION_BIT); | ||
732 | else | ||
733 | ECerr(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES_GFP, EC_R_INVALID_COMPRESSED_POINT); | ||
734 | goto err; | ||
735 | } | ||
736 | if (!BN_usub(y, &group->field, y)) goto err; | ||
737 | } | ||
738 | if (y_bit != BN_is_odd(y)) | ||
739 | { | ||
740 | ECerr(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES_GFP, ERR_R_INTERNAL_ERROR); | ||
741 | goto err; | ||
742 | } | ||
743 | |||
744 | if (!EC_POINT_set_affine_coordinates_GFp(group, point, x, y, ctx)) goto err; | ||
745 | |||
746 | ret = 1; | ||
747 | |||
748 | err: | ||
749 | BN_CTX_end(ctx); | ||
750 | if (new_ctx != NULL) | ||
751 | BN_CTX_free(new_ctx); | ||
752 | return ret; | ||
753 | } | ||
754 | |||
755 | |||
756 | size_t ec_GFp_simple_point2oct(const EC_GROUP *group, const EC_POINT *point, point_conversion_form_t form, | ||
757 | unsigned char *buf, size_t len, BN_CTX *ctx) | ||
758 | { | ||
759 | size_t ret; | ||
760 | BN_CTX *new_ctx = NULL; | ||
761 | int used_ctx = 0; | ||
762 | BIGNUM *x, *y; | ||
763 | size_t field_len, i, skip; | ||
764 | |||
765 | if ((form != POINT_CONVERSION_COMPRESSED) | ||
766 | && (form != POINT_CONVERSION_UNCOMPRESSED) | ||
767 | && (form != POINT_CONVERSION_HYBRID)) | ||
768 | { | ||
769 | ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, EC_R_INVALID_FORM); | ||
770 | goto err; | ||
771 | } | ||
772 | |||
773 | if (EC_POINT_is_at_infinity(group, point)) | ||
774 | { | ||
775 | /* encodes to a single 0 octet */ | ||
776 | if (buf != NULL) | ||
777 | { | ||
778 | if (len < 1) | ||
779 | { | ||
780 | ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, EC_R_BUFFER_TOO_SMALL); | ||
781 | return 0; | ||
782 | } | ||
783 | buf[0] = 0; | ||
784 | } | ||
785 | return 1; | ||
786 | } | ||
787 | |||
788 | |||
789 | /* ret := required output buffer length */ | ||
790 | field_len = BN_num_bytes(&group->field); | ||
791 | ret = (form == POINT_CONVERSION_COMPRESSED) ? 1 + field_len : 1 + 2*field_len; | ||
792 | |||
793 | /* if 'buf' is NULL, just return required length */ | ||
794 | if (buf != NULL) | ||
795 | { | ||
796 | if (len < ret) | ||
797 | { | ||
798 | ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, EC_R_BUFFER_TOO_SMALL); | ||
799 | goto err; | ||
800 | } | ||
801 | |||
802 | if (ctx == NULL) | ||
803 | { | ||
804 | ctx = new_ctx = BN_CTX_new(); | ||
805 | if (ctx == NULL) | ||
806 | return 0; | ||
807 | } | ||
808 | |||
809 | BN_CTX_start(ctx); | ||
810 | used_ctx = 1; | ||
811 | x = BN_CTX_get(ctx); | ||
812 | y = BN_CTX_get(ctx); | ||
813 | if (y == NULL) goto err; | ||
814 | |||
815 | if (!EC_POINT_get_affine_coordinates_GFp(group, point, x, y, ctx)) goto err; | ||
816 | |||
817 | if ((form == POINT_CONVERSION_COMPRESSED || form == POINT_CONVERSION_HYBRID) && BN_is_odd(y)) | ||
818 | buf[0] = form + 1; | ||
819 | else | ||
820 | buf[0] = form; | ||
821 | |||
822 | i = 1; | ||
823 | |||
824 | skip = field_len - BN_num_bytes(x); | ||
825 | if (skip > field_len) | ||
826 | { | ||
827 | ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR); | ||
828 | goto err; | ||
829 | } | ||
830 | while (skip > 0) | ||
831 | { | ||
832 | buf[i++] = 0; | ||
833 | skip--; | ||
834 | } | ||
835 | skip = BN_bn2bin(x, buf + i); | ||
836 | i += skip; | ||
837 | if (i != 1 + field_len) | ||
838 | { | ||
839 | ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR); | ||
840 | goto err; | ||
841 | } | ||
842 | |||
843 | if (form == POINT_CONVERSION_UNCOMPRESSED || form == POINT_CONVERSION_HYBRID) | ||
844 | { | ||
845 | skip = field_len - BN_num_bytes(y); | ||
846 | if (skip > field_len) | ||
847 | { | ||
848 | ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR); | ||
849 | goto err; | ||
850 | } | ||
851 | while (skip > 0) | ||
852 | { | ||
853 | buf[i++] = 0; | ||
854 | skip--; | ||
855 | } | ||
856 | skip = BN_bn2bin(y, buf + i); | ||
857 | i += skip; | ||
858 | } | ||
859 | |||
860 | if (i != ret) | ||
861 | { | ||
862 | ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR); | ||
863 | goto err; | ||
864 | } | ||
865 | } | ||
866 | |||
867 | if (used_ctx) | ||
868 | BN_CTX_end(ctx); | ||
869 | if (new_ctx != NULL) | ||
870 | BN_CTX_free(new_ctx); | ||
871 | return ret; | ||
872 | |||
873 | err: | ||
874 | if (used_ctx) | ||
875 | BN_CTX_end(ctx); | ||
876 | if (new_ctx != NULL) | ||
877 | BN_CTX_free(new_ctx); | ||
878 | return 0; | ||
879 | } | ||
880 | |||
881 | |||
882 | int ec_GFp_simple_oct2point(const EC_GROUP *group, EC_POINT *point, | ||
883 | const unsigned char *buf, size_t len, BN_CTX *ctx) | ||
884 | { | ||
885 | point_conversion_form_t form; | ||
886 | int y_bit; | ||
887 | BN_CTX *new_ctx = NULL; | ||
888 | BIGNUM *x, *y; | ||
889 | size_t field_len, enc_len; | ||
890 | int ret = 0; | ||
891 | |||
892 | if (len == 0) | ||
893 | { | ||
894 | ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_BUFFER_TOO_SMALL); | ||
895 | return 0; | ||
896 | } | ||
897 | form = buf[0]; | ||
898 | y_bit = form & 1; | ||
899 | form = form & ~1; | ||
900 | if ((form != 0) && (form != POINT_CONVERSION_COMPRESSED) | ||
901 | && (form != POINT_CONVERSION_UNCOMPRESSED) | ||
902 | && (form != POINT_CONVERSION_HYBRID)) | ||
903 | { | ||
904 | ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING); | ||
905 | return 0; | ||
906 | } | ||
907 | if ((form == 0 || form == POINT_CONVERSION_UNCOMPRESSED) && y_bit) | ||
908 | { | ||
909 | ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING); | ||
910 | return 0; | ||
911 | } | ||
912 | |||
913 | if (form == 0) | ||
914 | { | ||
915 | if (len != 1) | ||
916 | { | ||
917 | ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING); | ||
918 | return 0; | ||
919 | } | ||
920 | |||
921 | return EC_POINT_set_to_infinity(group, point); | ||
922 | } | ||
923 | |||
924 | field_len = BN_num_bytes(&group->field); | ||
925 | enc_len = (form == POINT_CONVERSION_COMPRESSED) ? 1 + field_len : 1 + 2*field_len; | ||
926 | |||
927 | if (len != enc_len) | ||
928 | { | ||
929 | ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING); | ||
930 | return 0; | ||
931 | } | ||
932 | |||
933 | if (ctx == NULL) | ||
934 | { | ||
935 | ctx = new_ctx = BN_CTX_new(); | ||
936 | if (ctx == NULL) | ||
937 | return 0; | ||
938 | } | ||
939 | |||
940 | BN_CTX_start(ctx); | ||
941 | x = BN_CTX_get(ctx); | ||
942 | y = BN_CTX_get(ctx); | ||
943 | if (y == NULL) goto err; | ||
944 | |||
945 | if (!BN_bin2bn(buf + 1, field_len, x)) goto err; | ||
946 | if (BN_ucmp(x, &group->field) >= 0) | ||
947 | { | ||
948 | ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING); | ||
949 | goto err; | ||
950 | } | ||
951 | |||
952 | if (form == POINT_CONVERSION_COMPRESSED) | ||
953 | { | ||
954 | if (!EC_POINT_set_compressed_coordinates_GFp(group, point, x, y_bit, ctx)) goto err; | ||
955 | } | ||
956 | else | ||
957 | { | ||
958 | if (!BN_bin2bn(buf + 1 + field_len, field_len, y)) goto err; | ||
959 | if (BN_ucmp(y, &group->field) >= 0) | ||
960 | { | ||
961 | ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING); | ||
962 | goto err; | ||
963 | } | ||
964 | if (form == POINT_CONVERSION_HYBRID) | ||
965 | { | ||
966 | if (y_bit != BN_is_odd(y)) | ||
967 | { | ||
968 | ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING); | ||
969 | goto err; | ||
970 | } | ||
971 | } | ||
972 | |||
973 | if (!EC_POINT_set_affine_coordinates_GFp(group, point, x, y, ctx)) goto err; | ||
974 | } | ||
975 | |||
976 | if (!EC_POINT_is_on_curve(group, point, ctx)) /* test required by X9.62 */ | ||
977 | { | ||
978 | ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_POINT_IS_NOT_ON_CURVE); | ||
979 | goto err; | ||
980 | } | ||
981 | |||
982 | ret = 1; | ||
983 | |||
984 | err: | ||
985 | BN_CTX_end(ctx); | ||
986 | if (new_ctx != NULL) | ||
987 | BN_CTX_free(new_ctx); | ||
988 | return ret; | ||
989 | } | ||
990 | |||
991 | |||
992 | int ec_GFp_simple_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, const EC_POINT *b, BN_CTX *ctx) | ||
993 | { | ||
994 | int (*field_mul)(const EC_GROUP *, BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *); | ||
995 | int (*field_sqr)(const EC_GROUP *, BIGNUM *, const BIGNUM *, BN_CTX *); | ||
996 | const BIGNUM *p; | ||
997 | BN_CTX *new_ctx = NULL; | ||
998 | BIGNUM *n0, *n1, *n2, *n3, *n4, *n5, *n6; | ||
999 | int ret = 0; | ||
1000 | |||
1001 | if (a == b) | ||
1002 | return EC_POINT_dbl(group, r, a, ctx); | ||
1003 | if (EC_POINT_is_at_infinity(group, a)) | ||
1004 | return EC_POINT_copy(r, b); | ||
1005 | if (EC_POINT_is_at_infinity(group, b)) | ||
1006 | return EC_POINT_copy(r, a); | ||
1007 | |||
1008 | field_mul = group->meth->field_mul; | ||
1009 | field_sqr = group->meth->field_sqr; | ||
1010 | p = &group->field; | ||
1011 | |||
1012 | if (ctx == NULL) | ||
1013 | { | ||
1014 | ctx = new_ctx = BN_CTX_new(); | ||
1015 | if (ctx == NULL) | ||
1016 | return 0; | ||
1017 | } | ||
1018 | |||
1019 | BN_CTX_start(ctx); | ||
1020 | n0 = BN_CTX_get(ctx); | ||
1021 | n1 = BN_CTX_get(ctx); | ||
1022 | n2 = BN_CTX_get(ctx); | ||
1023 | n3 = BN_CTX_get(ctx); | ||
1024 | n4 = BN_CTX_get(ctx); | ||
1025 | n5 = BN_CTX_get(ctx); | ||
1026 | n6 = BN_CTX_get(ctx); | ||
1027 | if (n6 == NULL) goto end; | ||
1028 | |||
1029 | /* Note that in this function we must not read components of 'a' or 'b' | ||
1030 | * once we have written the corresponding components of 'r'. | ||
1031 | * ('r' might be one of 'a' or 'b'.) | ||
1032 | */ | ||
1033 | |||
1034 | /* n1, n2 */ | ||
1035 | if (b->Z_is_one) | ||
1036 | { | ||
1037 | if (!BN_copy(n1, &a->X)) goto end; | ||
1038 | if (!BN_copy(n2, &a->Y)) goto end; | ||
1039 | /* n1 = X_a */ | ||
1040 | /* n2 = Y_a */ | ||
1041 | } | ||
1042 | else | ||
1043 | { | ||
1044 | if (!field_sqr(group, n0, &b->Z, ctx)) goto end; | ||
1045 | if (!field_mul(group, n1, &a->X, n0, ctx)) goto end; | ||
1046 | /* n1 = X_a * Z_b^2 */ | ||
1047 | |||
1048 | if (!field_mul(group, n0, n0, &b->Z, ctx)) goto end; | ||
1049 | if (!field_mul(group, n2, &a->Y, n0, ctx)) goto end; | ||
1050 | /* n2 = Y_a * Z_b^3 */ | ||
1051 | } | ||
1052 | |||
1053 | /* n3, n4 */ | ||
1054 | if (a->Z_is_one) | ||
1055 | { | ||
1056 | if (!BN_copy(n3, &b->X)) goto end; | ||
1057 | if (!BN_copy(n4, &b->Y)) goto end; | ||
1058 | /* n3 = X_b */ | ||
1059 | /* n4 = Y_b */ | ||
1060 | } | ||
1061 | else | ||
1062 | { | ||
1063 | if (!field_sqr(group, n0, &a->Z, ctx)) goto end; | ||
1064 | if (!field_mul(group, n3, &b->X, n0, ctx)) goto end; | ||
1065 | /* n3 = X_b * Z_a^2 */ | ||
1066 | |||
1067 | if (!field_mul(group, n0, n0, &a->Z, ctx)) goto end; | ||
1068 | if (!field_mul(group, n4, &b->Y, n0, ctx)) goto end; | ||
1069 | /* n4 = Y_b * Z_a^3 */ | ||
1070 | } | ||
1071 | |||
1072 | /* n5, n6 */ | ||
1073 | if (!BN_mod_sub_quick(n5, n1, n3, p)) goto end; | ||
1074 | if (!BN_mod_sub_quick(n6, n2, n4, p)) goto end; | ||
1075 | /* n5 = n1 - n3 */ | ||
1076 | /* n6 = n2 - n4 */ | ||
1077 | |||
1078 | if (BN_is_zero(n5)) | ||
1079 | { | ||
1080 | if (BN_is_zero(n6)) | ||
1081 | { | ||
1082 | /* a is the same point as b */ | ||
1083 | BN_CTX_end(ctx); | ||
1084 | ret = EC_POINT_dbl(group, r, a, ctx); | ||
1085 | ctx = NULL; | ||
1086 | goto end; | ||
1087 | } | ||
1088 | else | ||
1089 | { | ||
1090 | /* a is the inverse of b */ | ||
1091 | if (!BN_zero(&r->Z)) goto end; | ||
1092 | r->Z_is_one = 0; | ||
1093 | ret = 1; | ||
1094 | goto end; | ||
1095 | } | ||
1096 | } | ||
1097 | |||
1098 | /* 'n7', 'n8' */ | ||
1099 | if (!BN_mod_add_quick(n1, n1, n3, p)) goto end; | ||
1100 | if (!BN_mod_add_quick(n2, n2, n4, p)) goto end; | ||
1101 | /* 'n7' = n1 + n3 */ | ||
1102 | /* 'n8' = n2 + n4 */ | ||
1103 | |||
1104 | /* Z_r */ | ||
1105 | if (a->Z_is_one && b->Z_is_one) | ||
1106 | { | ||
1107 | if (!BN_copy(&r->Z, n5)) goto end; | ||
1108 | } | ||
1109 | else | ||
1110 | { | ||
1111 | if (a->Z_is_one) | ||
1112 | { if (!BN_copy(n0, &b->Z)) goto end; } | ||
1113 | else if (b->Z_is_one) | ||
1114 | { if (!BN_copy(n0, &a->Z)) goto end; } | ||
1115 | else | ||
1116 | { if (!field_mul(group, n0, &a->Z, &b->Z, ctx)) goto end; } | ||
1117 | if (!field_mul(group, &r->Z, n0, n5, ctx)) goto end; | ||
1118 | } | ||
1119 | r->Z_is_one = 0; | ||
1120 | /* Z_r = Z_a * Z_b * n5 */ | ||
1121 | |||
1122 | /* X_r */ | ||
1123 | if (!field_sqr(group, n0, n6, ctx)) goto end; | ||
1124 | if (!field_sqr(group, n4, n5, ctx)) goto end; | ||
1125 | if (!field_mul(group, n3, n1, n4, ctx)) goto end; | ||
1126 | if (!BN_mod_sub_quick(&r->X, n0, n3, p)) goto end; | ||
1127 | /* X_r = n6^2 - n5^2 * 'n7' */ | ||
1128 | |||
1129 | /* 'n9' */ | ||
1130 | if (!BN_mod_lshift1_quick(n0, &r->X, p)) goto end; | ||
1131 | if (!BN_mod_sub_quick(n0, n3, n0, p)) goto end; | ||
1132 | /* n9 = n5^2 * 'n7' - 2 * X_r */ | ||
1133 | |||
1134 | /* Y_r */ | ||
1135 | if (!field_mul(group, n0, n0, n6, ctx)) goto end; | ||
1136 | if (!field_mul(group, n5, n4, n5, ctx)) goto end; /* now n5 is n5^3 */ | ||
1137 | if (!field_mul(group, n1, n2, n5, ctx)) goto end; | ||
1138 | if (!BN_mod_sub_quick(n0, n0, n1, p)) goto end; | ||
1139 | if (BN_is_odd(n0)) | ||
1140 | if (!BN_add(n0, n0, p)) goto end; | ||
1141 | /* now 0 <= n0 < 2*p, and n0 is even */ | ||
1142 | if (!BN_rshift1(&r->Y, n0)) goto end; | ||
1143 | /* Y_r = (n6 * 'n9' - 'n8' * 'n5^3') / 2 */ | ||
1144 | |||
1145 | ret = 1; | ||
1146 | |||
1147 | end: | ||
1148 | if (ctx) /* otherwise we already called BN_CTX_end */ | ||
1149 | BN_CTX_end(ctx); | ||
1150 | if (new_ctx != NULL) | ||
1151 | BN_CTX_free(new_ctx); | ||
1152 | return ret; | ||
1153 | } | ||
1154 | |||
1155 | |||
1156 | int ec_GFp_simple_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, BN_CTX *ctx) | ||
1157 | { | ||
1158 | int (*field_mul)(const EC_GROUP *, BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *); | ||
1159 | int (*field_sqr)(const EC_GROUP *, BIGNUM *, const BIGNUM *, BN_CTX *); | ||
1160 | const BIGNUM *p; | ||
1161 | BN_CTX *new_ctx = NULL; | ||
1162 | BIGNUM *n0, *n1, *n2, *n3; | ||
1163 | int ret = 0; | ||
1164 | |||
1165 | if (EC_POINT_is_at_infinity(group, a)) | ||
1166 | { | ||
1167 | if (!BN_zero(&r->Z)) return 0; | ||
1168 | r->Z_is_one = 0; | ||
1169 | return 1; | ||
1170 | } | ||
1171 | |||
1172 | field_mul = group->meth->field_mul; | ||
1173 | field_sqr = group->meth->field_sqr; | ||
1174 | p = &group->field; | ||
1175 | |||
1176 | if (ctx == NULL) | ||
1177 | { | ||
1178 | ctx = new_ctx = BN_CTX_new(); | ||
1179 | if (ctx == NULL) | ||
1180 | return 0; | ||
1181 | } | ||
1182 | |||
1183 | BN_CTX_start(ctx); | ||
1184 | n0 = BN_CTX_get(ctx); | ||
1185 | n1 = BN_CTX_get(ctx); | ||
1186 | n2 = BN_CTX_get(ctx); | ||
1187 | n3 = BN_CTX_get(ctx); | ||
1188 | if (n3 == NULL) goto err; | ||
1189 | |||
1190 | /* Note that in this function we must not read components of 'a' | ||
1191 | * once we have written the corresponding components of 'r'. | ||
1192 | * ('r' might the same as 'a'.) | ||
1193 | */ | ||
1194 | |||
1195 | /* n1 */ | ||
1196 | if (a->Z_is_one) | ||
1197 | { | ||
1198 | if (!field_sqr(group, n0, &a->X, ctx)) goto err; | ||
1199 | if (!BN_mod_lshift1_quick(n1, n0, p)) goto err; | ||
1200 | if (!BN_mod_add_quick(n0, n0, n1, p)) goto err; | ||
1201 | if (!BN_mod_add_quick(n1, n0, &group->a, p)) goto err; | ||
1202 | /* n1 = 3 * X_a^2 + a_curve */ | ||
1203 | } | ||
1204 | else if (group->a_is_minus3) | ||
1205 | { | ||
1206 | if (!field_sqr(group, n1, &a->Z, ctx)) goto err; | ||
1207 | if (!BN_mod_add_quick(n0, &a->X, n1, p)) goto err; | ||
1208 | if (!BN_mod_sub_quick(n2, &a->X, n1, p)) goto err; | ||
1209 | if (!field_mul(group, n1, n0, n2, ctx)) goto err; | ||
1210 | if (!BN_mod_lshift1_quick(n0, n1, p)) goto err; | ||
1211 | if (!BN_mod_add_quick(n1, n0, n1, p)) goto err; | ||
1212 | /* n1 = 3 * (X_a + Z_a^2) * (X_a - Z_a^2) | ||
1213 | * = 3 * X_a^2 - 3 * Z_a^4 */ | ||
1214 | } | ||
1215 | else | ||
1216 | { | ||
1217 | if (!field_sqr(group, n0, &a->X, ctx)) goto err; | ||
1218 | if (!BN_mod_lshift1_quick(n1, n0, p)) goto err; | ||
1219 | if (!BN_mod_add_quick(n0, n0, n1, p)) goto err; | ||
1220 | if (!field_sqr(group, n1, &a->Z, ctx)) goto err; | ||
1221 | if (!field_sqr(group, n1, n1, ctx)) goto err; | ||
1222 | if (!field_mul(group, n1, n1, &group->a, ctx)) goto err; | ||
1223 | if (!BN_mod_add_quick(n1, n1, n0, p)) goto err; | ||
1224 | /* n1 = 3 * X_a^2 + a_curve * Z_a^4 */ | ||
1225 | } | ||
1226 | |||
1227 | /* Z_r */ | ||
1228 | if (a->Z_is_one) | ||
1229 | { | ||
1230 | if (!BN_copy(n0, &a->Y)) goto err; | ||
1231 | } | ||
1232 | else | ||
1233 | { | ||
1234 | if (!field_mul(group, n0, &a->Y, &a->Z, ctx)) goto err; | ||
1235 | } | ||
1236 | if (!BN_mod_lshift1_quick(&r->Z, n0, p)) goto err; | ||
1237 | r->Z_is_one = 0; | ||
1238 | /* Z_r = 2 * Y_a * Z_a */ | ||
1239 | |||
1240 | /* n2 */ | ||
1241 | if (!field_sqr(group, n3, &a->Y, ctx)) goto err; | ||
1242 | if (!field_mul(group, n2, &a->X, n3, ctx)) goto err; | ||
1243 | if (!BN_mod_lshift_quick(n2, n2, 2, p)) goto err; | ||
1244 | /* n2 = 4 * X_a * Y_a^2 */ | ||
1245 | |||
1246 | /* X_r */ | ||
1247 | if (!BN_mod_lshift1_quick(n0, n2, p)) goto err; | ||
1248 | if (!field_sqr(group, &r->X, n1, ctx)) goto err; | ||
1249 | if (!BN_mod_sub_quick(&r->X, &r->X, n0, p)) goto err; | ||
1250 | /* X_r = n1^2 - 2 * n2 */ | ||
1251 | |||
1252 | /* n3 */ | ||
1253 | if (!field_sqr(group, n0, n3, ctx)) goto err; | ||
1254 | if (!BN_mod_lshift_quick(n3, n0, 3, p)) goto err; | ||
1255 | /* n3 = 8 * Y_a^4 */ | ||
1256 | |||
1257 | /* Y_r */ | ||
1258 | if (!BN_mod_sub_quick(n0, n2, &r->X, p)) goto err; | ||
1259 | if (!field_mul(group, n0, n1, n0, ctx)) goto err; | ||
1260 | if (!BN_mod_sub_quick(&r->Y, n0, n3, p)) goto err; | ||
1261 | /* Y_r = n1 * (n2 - X_r) - n3 */ | ||
1262 | |||
1263 | ret = 1; | ||
1264 | |||
1265 | err: | ||
1266 | BN_CTX_end(ctx); | ||
1267 | if (new_ctx != NULL) | ||
1268 | BN_CTX_free(new_ctx); | ||
1269 | return ret; | ||
1270 | } | ||
1271 | |||
1272 | |||
1273 | int ec_GFp_simple_invert(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx) | ||
1274 | { | ||
1275 | if (EC_POINT_is_at_infinity(group, point) || BN_is_zero(&point->Y)) | ||
1276 | /* point is its own inverse */ | ||
1277 | return 1; | ||
1278 | |||
1279 | return BN_usub(&point->Y, &group->field, &point->Y); | ||
1280 | } | ||
1281 | |||
1282 | |||
1283 | int ec_GFp_simple_is_at_infinity(const EC_GROUP *group, const EC_POINT *point) | ||
1284 | { | ||
1285 | return BN_is_zero(&point->Z); | ||
1286 | } | ||
1287 | |||
1288 | |||
1289 | int ec_GFp_simple_is_on_curve(const EC_GROUP *group, const EC_POINT *point, BN_CTX *ctx) | ||
1290 | { | ||
1291 | int (*field_mul)(const EC_GROUP *, BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *); | ||
1292 | int (*field_sqr)(const EC_GROUP *, BIGNUM *, const BIGNUM *, BN_CTX *); | ||
1293 | const BIGNUM *p; | ||
1294 | BN_CTX *new_ctx = NULL; | ||
1295 | BIGNUM *rh, *tmp1, *tmp2, *Z4, *Z6; | ||
1296 | int ret = -1; | ||
1297 | |||
1298 | if (EC_POINT_is_at_infinity(group, point)) | ||
1299 | return 1; | ||
1300 | |||
1301 | field_mul = group->meth->field_mul; | ||
1302 | field_sqr = group->meth->field_sqr; | ||
1303 | p = &group->field; | ||
1304 | |||
1305 | if (ctx == NULL) | ||
1306 | { | ||
1307 | ctx = new_ctx = BN_CTX_new(); | ||
1308 | if (ctx == NULL) | ||
1309 | return -1; | ||
1310 | } | ||
1311 | |||
1312 | BN_CTX_start(ctx); | ||
1313 | rh = BN_CTX_get(ctx); | ||
1314 | tmp1 = BN_CTX_get(ctx); | ||
1315 | tmp2 = BN_CTX_get(ctx); | ||
1316 | Z4 = BN_CTX_get(ctx); | ||
1317 | Z6 = BN_CTX_get(ctx); | ||
1318 | if (Z6 == NULL) goto err; | ||
1319 | |||
1320 | /* We have a curve defined by a Weierstrass equation | ||
1321 | * y^2 = x^3 + a*x + b. | ||
1322 | * The point to consider is given in Jacobian projective coordinates | ||
1323 | * where (X, Y, Z) represents (x, y) = (X/Z^2, Y/Z^3). | ||
1324 | * Substituting this and multiplying by Z^6 transforms the above equation into | ||
1325 | * Y^2 = X^3 + a*X*Z^4 + b*Z^6. | ||
1326 | * To test this, we add up the right-hand side in 'rh'. | ||
1327 | */ | ||
1328 | |||
1329 | /* rh := X^3 */ | ||
1330 | if (!field_sqr(group, rh, &point->X, ctx)) goto err; | ||
1331 | if (!field_mul(group, rh, rh, &point->X, ctx)) goto err; | ||
1332 | |||
1333 | if (!point->Z_is_one) | ||
1334 | { | ||
1335 | if (!field_sqr(group, tmp1, &point->Z, ctx)) goto err; | ||
1336 | if (!field_sqr(group, Z4, tmp1, ctx)) goto err; | ||
1337 | if (!field_mul(group, Z6, Z4, tmp1, ctx)) goto err; | ||
1338 | |||
1339 | /* rh := rh + a*X*Z^4 */ | ||
1340 | if (!field_mul(group, tmp1, &point->X, Z4, ctx)) goto err; | ||
1341 | if (group->a_is_minus3) | ||
1342 | { | ||
1343 | if (!BN_mod_lshift1_quick(tmp2, tmp1, p)) goto err; | ||
1344 | if (!BN_mod_add_quick(tmp2, tmp2, tmp1, p)) goto err; | ||
1345 | if (!BN_mod_sub_quick(rh, rh, tmp2, p)) goto err; | ||
1346 | } | ||
1347 | else | ||
1348 | { | ||
1349 | if (!field_mul(group, tmp2, tmp1, &group->a, ctx)) goto err; | ||
1350 | if (!BN_mod_add_quick(rh, rh, tmp2, p)) goto err; | ||
1351 | } | ||
1352 | |||
1353 | /* rh := rh + b*Z^6 */ | ||
1354 | if (!field_mul(group, tmp1, &group->b, Z6, ctx)) goto err; | ||
1355 | if (!BN_mod_add_quick(rh, rh, tmp1, p)) goto err; | ||
1356 | } | ||
1357 | else | ||
1358 | { | ||
1359 | /* point->Z_is_one */ | ||
1360 | |||
1361 | /* rh := rh + a*X */ | ||
1362 | if (group->a_is_minus3) | ||
1363 | { | ||
1364 | if (!BN_mod_lshift1_quick(tmp2, &point->X, p)) goto err; | ||
1365 | if (!BN_mod_add_quick(tmp2, tmp2, &point->X, p)) goto err; | ||
1366 | if (!BN_mod_sub_quick(rh, rh, tmp2, p)) goto err; | ||
1367 | } | ||
1368 | else | ||
1369 | { | ||
1370 | if (!field_mul(group, tmp2, &point->X, &group->a, ctx)) goto err; | ||
1371 | if (!BN_mod_add_quick(rh, rh, tmp2, p)) goto err; | ||
1372 | } | ||
1373 | |||
1374 | /* rh := rh + b */ | ||
1375 | if (!BN_mod_add_quick(rh, rh, &group->b, p)) goto err; | ||
1376 | } | ||
1377 | |||
1378 | /* 'lh' := Y^2 */ | ||
1379 | if (!field_sqr(group, tmp1, &point->Y, ctx)) goto err; | ||
1380 | |||
1381 | ret = (0 == BN_cmp(tmp1, rh)); | ||
1382 | |||
1383 | err: | ||
1384 | BN_CTX_end(ctx); | ||
1385 | if (new_ctx != NULL) | ||
1386 | BN_CTX_free(new_ctx); | ||
1387 | return ret; | ||
1388 | } | ||
1389 | |||
1390 | |||
1391 | int ec_GFp_simple_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b, BN_CTX *ctx) | ||
1392 | { | ||
1393 | /* return values: | ||
1394 | * -1 error | ||
1395 | * 0 equal (in affine coordinates) | ||
1396 | * 1 not equal | ||
1397 | */ | ||
1398 | |||
1399 | int (*field_mul)(const EC_GROUP *, BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *); | ||
1400 | int (*field_sqr)(const EC_GROUP *, BIGNUM *, const BIGNUM *, BN_CTX *); | ||
1401 | BN_CTX *new_ctx = NULL; | ||
1402 | BIGNUM *tmp1, *tmp2, *Za23, *Zb23; | ||
1403 | const BIGNUM *tmp1_, *tmp2_; | ||
1404 | int ret = -1; | ||
1405 | |||
1406 | if (EC_POINT_is_at_infinity(group, a)) | ||
1407 | { | ||
1408 | return EC_POINT_is_at_infinity(group, b) ? 0 : 1; | ||
1409 | } | ||
1410 | |||
1411 | if (a->Z_is_one && b->Z_is_one) | ||
1412 | { | ||
1413 | return ((BN_cmp(&a->X, &b->X) == 0) && BN_cmp(&a->Y, &b->Y) == 0) ? 0 : 1; | ||
1414 | } | ||
1415 | |||
1416 | field_mul = group->meth->field_mul; | ||
1417 | field_sqr = group->meth->field_sqr; | ||
1418 | |||
1419 | if (ctx == NULL) | ||
1420 | { | ||
1421 | ctx = new_ctx = BN_CTX_new(); | ||
1422 | if (ctx == NULL) | ||
1423 | return -1; | ||
1424 | } | ||
1425 | |||
1426 | BN_CTX_start(ctx); | ||
1427 | tmp1 = BN_CTX_get(ctx); | ||
1428 | tmp2 = BN_CTX_get(ctx); | ||
1429 | Za23 = BN_CTX_get(ctx); | ||
1430 | Zb23 = BN_CTX_get(ctx); | ||
1431 | if (Zb23 == NULL) goto end; | ||
1432 | |||
1433 | /* We have to decide whether | ||
1434 | * (X_a/Z_a^2, Y_a/Z_a^3) = (X_b/Z_b^2, Y_b/Z_b^3), | ||
1435 | * or equivalently, whether | ||
1436 | * (X_a*Z_b^2, Y_a*Z_b^3) = (X_b*Z_a^2, Y_b*Z_a^3). | ||
1437 | */ | ||
1438 | |||
1439 | if (!b->Z_is_one) | ||
1440 | { | ||
1441 | if (!field_sqr(group, Zb23, &b->Z, ctx)) goto end; | ||
1442 | if (!field_mul(group, tmp1, &a->X, Zb23, ctx)) goto end; | ||
1443 | tmp1_ = tmp1; | ||
1444 | } | ||
1445 | else | ||
1446 | tmp1_ = &a->X; | ||
1447 | if (!a->Z_is_one) | ||
1448 | { | ||
1449 | if (!field_sqr(group, Za23, &a->Z, ctx)) goto end; | ||
1450 | if (!field_mul(group, tmp2, &b->X, Za23, ctx)) goto end; | ||
1451 | tmp2_ = tmp2; | ||
1452 | } | ||
1453 | else | ||
1454 | tmp2_ = &b->X; | ||
1455 | |||
1456 | /* compare X_a*Z_b^2 with X_b*Z_a^2 */ | ||
1457 | if (BN_cmp(tmp1_, tmp2_) != 0) | ||
1458 | { | ||
1459 | ret = 1; /* points differ */ | ||
1460 | goto end; | ||
1461 | } | ||
1462 | |||
1463 | |||
1464 | if (!b->Z_is_one) | ||
1465 | { | ||
1466 | if (!field_mul(group, Zb23, Zb23, &b->Z, ctx)) goto end; | ||
1467 | if (!field_mul(group, tmp1, &a->Y, Zb23, ctx)) goto end; | ||
1468 | /* tmp1_ = tmp1 */ | ||
1469 | } | ||
1470 | else | ||
1471 | tmp1_ = &a->Y; | ||
1472 | if (!a->Z_is_one) | ||
1473 | { | ||
1474 | if (!field_mul(group, Za23, Za23, &a->Z, ctx)) goto end; | ||
1475 | if (!field_mul(group, tmp2, &b->Y, Za23, ctx)) goto end; | ||
1476 | /* tmp2_ = tmp2 */ | ||
1477 | } | ||
1478 | else | ||
1479 | tmp2_ = &b->Y; | ||
1480 | |||
1481 | /* compare Y_a*Z_b^3 with Y_b*Z_a^3 */ | ||
1482 | if (BN_cmp(tmp1_, tmp2_) != 0) | ||
1483 | { | ||
1484 | ret = 1; /* points differ */ | ||
1485 | goto end; | ||
1486 | } | ||
1487 | |||
1488 | /* points are equal */ | ||
1489 | ret = 0; | ||
1490 | |||
1491 | end: | ||
1492 | BN_CTX_end(ctx); | ||
1493 | if (new_ctx != NULL) | ||
1494 | BN_CTX_free(new_ctx); | ||
1495 | return ret; | ||
1496 | } | ||
1497 | |||
1498 | |||
1499 | int ec_GFp_simple_make_affine(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx) | ||
1500 | { | ||
1501 | BN_CTX *new_ctx = NULL; | ||
1502 | BIGNUM *x, *y; | ||
1503 | int ret = 0; | ||
1504 | |||
1505 | if (point->Z_is_one || EC_POINT_is_at_infinity(group, point)) | ||
1506 | return 1; | ||
1507 | |||
1508 | if (ctx == NULL) | ||
1509 | { | ||
1510 | ctx = new_ctx = BN_CTX_new(); | ||
1511 | if (ctx == NULL) | ||
1512 | return 0; | ||
1513 | } | ||
1514 | |||
1515 | BN_CTX_start(ctx); | ||
1516 | x = BN_CTX_get(ctx); | ||
1517 | y = BN_CTX_get(ctx); | ||
1518 | if (y == NULL) goto err; | ||
1519 | |||
1520 | if (!EC_POINT_get_affine_coordinates_GFp(group, point, x, y, ctx)) goto err; | ||
1521 | if (!EC_POINT_set_affine_coordinates_GFp(group, point, x, y, ctx)) goto err; | ||
1522 | if (!point->Z_is_one) | ||
1523 | { | ||
1524 | ECerr(EC_F_EC_GFP_SIMPLE_MAKE_AFFINE, ERR_R_INTERNAL_ERROR); | ||
1525 | goto err; | ||
1526 | } | ||
1527 | |||
1528 | ret = 1; | ||
1529 | |||
1530 | err: | ||
1531 | BN_CTX_end(ctx); | ||
1532 | if (new_ctx != NULL) | ||
1533 | BN_CTX_free(new_ctx); | ||
1534 | return ret; | ||
1535 | } | ||
1536 | |||
1537 | |||
1538 | int ec_GFp_simple_points_make_affine(const EC_GROUP *group, size_t num, EC_POINT *points[], BN_CTX *ctx) | ||
1539 | { | ||
1540 | BN_CTX *new_ctx = NULL; | ||
1541 | BIGNUM *tmp0, *tmp1; | ||
1542 | size_t pow2 = 0; | ||
1543 | BIGNUM **heap = NULL; | ||
1544 | size_t i; | ||
1545 | int ret = 0; | ||
1546 | |||
1547 | if (num == 0) | ||
1548 | return 1; | ||
1549 | |||
1550 | if (ctx == NULL) | ||
1551 | { | ||
1552 | ctx = new_ctx = BN_CTX_new(); | ||
1553 | if (ctx == NULL) | ||
1554 | return 0; | ||
1555 | } | ||
1556 | |||
1557 | BN_CTX_start(ctx); | ||
1558 | tmp0 = BN_CTX_get(ctx); | ||
1559 | tmp1 = BN_CTX_get(ctx); | ||
1560 | if (tmp0 == NULL || tmp1 == NULL) goto err; | ||
1561 | |||
1562 | /* Before converting the individual points, compute inverses of all Z values. | ||
1563 | * Modular inversion is rather slow, but luckily we can do with a single | ||
1564 | * explicit inversion, plus about 3 multiplications per input value. | ||
1565 | */ | ||
1566 | |||
1567 | pow2 = 1; | ||
1568 | while (num > pow2) | ||
1569 | pow2 <<= 1; | ||
1570 | /* Now pow2 is the smallest power of 2 satifsying pow2 >= num. | ||
1571 | * We need twice that. */ | ||
1572 | pow2 <<= 1; | ||
1573 | |||
1574 | heap = OPENSSL_malloc(pow2 * sizeof heap[0]); | ||
1575 | if (heap == NULL) goto err; | ||
1576 | |||
1577 | /* The array is used as a binary tree, exactly as in heapsort: | ||
1578 | * | ||
1579 | * heap[1] | ||
1580 | * heap[2] heap[3] | ||
1581 | * heap[4] heap[5] heap[6] heap[7] | ||
1582 | * heap[8]heap[9] heap[10]heap[11] heap[12]heap[13] heap[14] heap[15] | ||
1583 | * | ||
1584 | * We put the Z's in the last line; | ||
1585 | * then we set each other node to the product of its two child-nodes (where | ||
1586 | * empty or 0 entries are treated as ones); | ||
1587 | * then we invert heap[1]; | ||
1588 | * then we invert each other node by replacing it by the product of its | ||
1589 | * parent (after inversion) and its sibling (before inversion). | ||
1590 | */ | ||
1591 | heap[0] = NULL; | ||
1592 | for (i = pow2/2 - 1; i > 0; i--) | ||
1593 | heap[i] = NULL; | ||
1594 | for (i = 0; i < num; i++) | ||
1595 | heap[pow2/2 + i] = &points[i]->Z; | ||
1596 | for (i = pow2/2 + num; i < pow2; i++) | ||
1597 | heap[i] = NULL; | ||
1598 | |||
1599 | /* set each node to the product of its children */ | ||
1600 | for (i = pow2/2 - 1; i > 0; i--) | ||
1601 | { | ||
1602 | heap[i] = BN_new(); | ||
1603 | if (heap[i] == NULL) goto err; | ||
1604 | |||
1605 | if (heap[2*i] != NULL) | ||
1606 | { | ||
1607 | if ((heap[2*i + 1] == NULL) || BN_is_zero(heap[2*i + 1])) | ||
1608 | { | ||
1609 | if (!BN_copy(heap[i], heap[2*i])) goto err; | ||
1610 | } | ||
1611 | else | ||
1612 | { | ||
1613 | if (BN_is_zero(heap[2*i])) | ||
1614 | { | ||
1615 | if (!BN_copy(heap[i], heap[2*i + 1])) goto err; | ||
1616 | } | ||
1617 | else | ||
1618 | { | ||
1619 | if (!group->meth->field_mul(group, heap[i], | ||
1620 | heap[2*i], heap[2*i + 1], ctx)) goto err; | ||
1621 | } | ||
1622 | } | ||
1623 | } | ||
1624 | } | ||
1625 | |||
1626 | /* invert heap[1] */ | ||
1627 | if (!BN_is_zero(heap[1])) | ||
1628 | { | ||
1629 | if (!BN_mod_inverse(heap[1], heap[1], &group->field, ctx)) | ||
1630 | { | ||
1631 | ECerr(EC_F_EC_GFP_SIMPLE_POINTS_MAKE_AFFINE, ERR_R_BN_LIB); | ||
1632 | goto err; | ||
1633 | } | ||
1634 | } | ||
1635 | if (group->meth->field_encode != 0) | ||
1636 | { | ||
1637 | /* in the Montgomery case, we just turned R*H (representing H) | ||
1638 | * into 1/(R*H), but we need R*(1/H) (representing 1/H); | ||
1639 | * i.e. we have need to multiply by the Montgomery factor twice */ | ||
1640 | if (!group->meth->field_encode(group, heap[1], heap[1], ctx)) goto err; | ||
1641 | if (!group->meth->field_encode(group, heap[1], heap[1], ctx)) goto err; | ||
1642 | } | ||
1643 | |||
1644 | /* set other heap[i]'s to their inverses */ | ||
1645 | for (i = 2; i < pow2/2 + num; i += 2) | ||
1646 | { | ||
1647 | /* i is even */ | ||
1648 | if ((heap[i + 1] != NULL) && !BN_is_zero(heap[i + 1])) | ||
1649 | { | ||
1650 | if (!group->meth->field_mul(group, tmp0, heap[i/2], heap[i + 1], ctx)) goto err; | ||
1651 | if (!group->meth->field_mul(group, tmp1, heap[i/2], heap[i], ctx)) goto err; | ||
1652 | if (!BN_copy(heap[i], tmp0)) goto err; | ||
1653 | if (!BN_copy(heap[i + 1], tmp1)) goto err; | ||
1654 | } | ||
1655 | else | ||
1656 | { | ||
1657 | if (!BN_copy(heap[i], heap[i/2])) goto err; | ||
1658 | } | ||
1659 | } | ||
1660 | |||
1661 | /* we have replaced all non-zero Z's by their inverses, now fix up all the points */ | ||
1662 | for (i = 0; i < num; i++) | ||
1663 | { | ||
1664 | EC_POINT *p = points[i]; | ||
1665 | |||
1666 | if (!BN_is_zero(&p->Z)) | ||
1667 | { | ||
1668 | /* turn (X, Y, 1/Z) into (X/Z^2, Y/Z^3, 1) */ | ||
1669 | |||
1670 | if (!group->meth->field_sqr(group, tmp1, &p->Z, ctx)) goto err; | ||
1671 | if (!group->meth->field_mul(group, &p->X, &p->X, tmp1, ctx)) goto err; | ||
1672 | |||
1673 | if (!group->meth->field_mul(group, tmp1, tmp1, &p->Z, ctx)) goto err; | ||
1674 | if (!group->meth->field_mul(group, &p->Y, &p->Y, tmp1, ctx)) goto err; | ||
1675 | |||
1676 | if (group->meth->field_set_to_one != 0) | ||
1677 | { | ||
1678 | if (!group->meth->field_set_to_one(group, &p->Z, ctx)) goto err; | ||
1679 | } | ||
1680 | else | ||
1681 | { | ||
1682 | if (!BN_one(&p->Z)) goto err; | ||
1683 | } | ||
1684 | p->Z_is_one = 1; | ||
1685 | } | ||
1686 | } | ||
1687 | |||
1688 | ret = 1; | ||
1689 | |||
1690 | err: | ||
1691 | BN_CTX_end(ctx); | ||
1692 | if (new_ctx != NULL) | ||
1693 | BN_CTX_free(new_ctx); | ||
1694 | if (heap != NULL) | ||
1695 | { | ||
1696 | /* heap[pow2/2] .. heap[pow2-1] have not been allocated locally! */ | ||
1697 | for (i = pow2/2 - 1; i > 0; i--) | ||
1698 | { | ||
1699 | if (heap[i] != NULL) | ||
1700 | BN_clear_free(heap[i]); | ||
1701 | } | ||
1702 | OPENSSL_free(heap); | ||
1703 | } | ||
1704 | return ret; | ||
1705 | } | ||
1706 | |||
1707 | |||
1708 | int ec_GFp_simple_field_mul(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx) | ||
1709 | { | ||
1710 | return BN_mod_mul(r, a, b, &group->field, ctx); | ||
1711 | } | ||
1712 | |||
1713 | |||
1714 | int ec_GFp_simple_field_sqr(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, BN_CTX *ctx) | ||
1715 | { | ||
1716 | return BN_mod_sqr(r, a, &group->field, ctx); | ||
1717 | } | ||
diff --git a/src/lib/libcrypto/engine/README b/src/lib/libcrypto/engine/README new file mode 100644 index 0000000000..96595e6f35 --- /dev/null +++ b/src/lib/libcrypto/engine/README | |||
@@ -0,0 +1,278 @@ | |||
1 | NOTES, THOUGHTS, and EVERYTHING | ||
2 | ------------------------------- | ||
3 | |||
4 | (1) Concurrency and locking ... I made a change to the ENGINE_free code | ||
5 | because I spotted a potential hold-up in proceedings (doing too | ||
6 | much inside a lock including calling a callback), there may be | ||
7 | other bits like this. What do the speed/optimisation freaks think | ||
8 | of this aspect of the code and design? There's lots of locking for | ||
9 | manipulation functions and I need that to keep things nice and | ||
10 | solid, but this manipulation is mostly (de)initialisation, I would | ||
11 | think that most run-time locking is purely in the ENGINE_init and | ||
12 | ENGINE_finish calls that might be made when getting handles for | ||
13 | RSA (and friends') structures. These would be mostly reference | ||
14 | count operations as the functional references should always be 1 | ||
15 | or greater at run-time to prevent init/deinit thrashing. | ||
16 | |||
17 | (2) nCipher support, via the HWCryptoHook API, is now in the code. | ||
18 | Apparently this hasn't been tested too much yet, but it looks | ||
19 | good. :-) Atalla support has been added too, but shares a lot in | ||
20 | common with Ben's original hooks in bn_exp.c (although it has been | ||
21 | ENGINE-ified, and error handling wrapped around it) and it's also | ||
22 | had some low-volume testing, so it should be usable. | ||
23 | |||
24 | (3) Of more concern, we need to work out (a) how to put together usable | ||
25 | RAND_METHODs for units that just have one "get n or less random | ||
26 | bytes" function, (b) we also need to determine how to hook the code | ||
27 | in crypto/rand/ to use the ENGINE defaults in a way similar to what | ||
28 | has been done in crypto/rsa/, crypto/dsa/, etc. | ||
29 | |||
30 | (4) ENGINE should really grow to encompass more than 3 public key | ||
31 | algorithms and randomness gathering. The structure/data level of | ||
32 | the engine code is hidden from code outside the crypto/engine/ | ||
33 | directory so change shouldn't be too viral. More important though | ||
34 | is how things should evolve ... this needs thought and discussion. | ||
35 | |||
36 | |||
37 | -----------------------------------==*==----------------------------------- | ||
38 | |||
39 | More notes 2000-08-01 | ||
40 | --------------------- | ||
41 | |||
42 | Geoff Thorpe, who designed the engine part, wrote a pretty good description | ||
43 | of the thoughts he had when he built it, good enough to include verbatim here | ||
44 | (with his permission) -- Richard Levitte | ||
45 | |||
46 | |||
47 | Date: Tue, 1 Aug 2000 16:54:08 +0100 (BST) | ||
48 | From: Geoff Thorpe | ||
49 | Subject: Re: The thoughts to merge BRANCH_engine into the main trunk are | ||
50 | emerging | ||
51 | |||
52 | Hi there, | ||
53 | |||
54 | I'm going to try and do some justice to this, but I'm a little short on | ||
55 | time and the there is an endless amount that could be discussed on this | ||
56 | subject. sigh ... please bear with me :-) | ||
57 | |||
58 | > The changes in BRANCH_engine dig deep into the core of OpenSSL, for example | ||
59 | > into the RSA and RAND routines, adding a level of indirection which is needed | ||
60 | > to keep the abstraction, as far as I understand. It would be a good thing if | ||
61 | > those who do play with those things took a look at the changes that have been | ||
62 | > done in the branch and say out loud how much (or hopefully little) we've made | ||
63 | > fools of ourselves. | ||
64 | |||
65 | The point here is that the code that has emerged in the BRANCH_engine | ||
66 | branch was based on some initial requirements of mine that I went in and | ||
67 | addressed, and Richard has picked up the ball and run with it too. It | ||
68 | would be really useful to get some review of the approach we've taken, but | ||
69 | first I think I need to describe as best I can the reasons behind what has | ||
70 | been done so far, in particular what issues we have tried to address when | ||
71 | doing this, and what issues we have intentionally (or necessarily) tried | ||
72 | to avoid. | ||
73 | |||
74 | methods, engines, and evps | ||
75 | -------------------------- | ||
76 | |||
77 | There has been some dicussion, particularly with Steve, about where this | ||
78 | ENGINE stuff might fit into the conceptual picture as/when we start to | ||
79 | abstract algorithms a little bit to make the library more extensible. In | ||
80 | particular, it would desirable to have algorithms (symmetric, hash, pkc, | ||
81 | etc) abstracted in some way that allows them to be just objects sitting in | ||
82 | a list (or database) ... it'll just happen that the "DSA" object doesn't | ||
83 | support encryption whereas the "RSA" object does. This requires a lot of | ||
84 | consideration to begin to know how to tackle it; in particular how | ||
85 | encapsulated should these things be? If the objects also understand their | ||
86 | own ASN1 encodings and what-not, then it would for example be possible to | ||
87 | add support for elliptic-curve DSA in as a new algorithm and automatically | ||
88 | have ECC-DSA certificates supported in SSL applications. Possible, but not | ||
89 | easy. :-) | ||
90 | |||
91 | Whatever, it seems that the way to go (if I've grok'd Steve's comments on | ||
92 | this in the past) is to amalgamate these things in EVP as is already done | ||
93 | (I think) for ciphers or hashes (Steve, please correct/elaborate). I | ||
94 | certainly think something should be done in this direction because right | ||
95 | now we have different source directories, types, functions, and methods | ||
96 | for each algorithm - even when conceptually they are very much different | ||
97 | feathers of the same bird. (This is certainly all true for the public-key | ||
98 | stuff, and may be partially true for the other parts.) | ||
99 | |||
100 | ENGINE was *not* conceived as a way of solving this, far from it. Nor was | ||
101 | it conceived as a way of replacing the various "***_METHOD"s. It was | ||
102 | conceived as an abstraction of a sort of "virtual crypto device". If we | ||
103 | lived in a world where "EVP_ALGO"s (or something like them) encapsulated | ||
104 | particular algorithms like RSA,DSA,MD5,RC4,etc, and "***_METHOD"s | ||
105 | encapsulated interfaces to algorithms (eg. some algo's might support a | ||
106 | PKC_METHOD, a HASH_METHOD, or a CIPHER_METHOD, who knows?), then I would | ||
107 | think that ENGINE would encapsulate an implementation of arbitrarily many | ||
108 | of those algorithms - perhaps as alternatives to existing algorithms | ||
109 | and/or perhaps as new previously unimplemented algorithms. An ENGINE could | ||
110 | be used to contain an alternative software implementation, a wrapper for a | ||
111 | hardware acceleration and/or key-management unit, a comms-wrapper for | ||
112 | distributing cryptographic operations to remote machines, or any other | ||
113 | "devices" your imagination can dream up. | ||
114 | |||
115 | However, what has been done in the ENGINE branch so far is nothing more | ||
116 | than starting to get our toes wet. I had a couple of self-imposed | ||
117 | requirements when putting the initial abstraction together, and I may have | ||
118 | already posed these in one form or another on the list, but briefly; | ||
119 | |||
120 | (i) only bother with public key algorithms for now, and maybe RAND too | ||
121 | (motivated by the need to get hardware support going and the fact | ||
122 | this was a comparitively easy subset to address to begin with). | ||
123 | |||
124 | (ii) don't change (if at all possible) the existing crypto code, ie. the | ||
125 | implementations, the way the ***_METHODs work, etc. | ||
126 | |||
127 | (iii) ensure that if no function from the ENGINE code is ever called then | ||
128 | things work the way they always did, and there is no memory | ||
129 | allocation (otherwise the failure to cleanup would be a problem - | ||
130 | this is part of the reason no STACKs were used, the other part of | ||
131 | the reason being I found them inappropriate). | ||
132 | |||
133 | (iv) ensure that all the built-in crypto was encapsulated by one of | ||
134 | these "ENGINE"s and that this engine was automatically selected as | ||
135 | the default. | ||
136 | |||
137 | (v) provide the minimum hooking possible in the existing crypto code | ||
138 | so that global functions (eg. RSA_public_encrypt) do not need any | ||
139 | extra parameter, yet will use whatever the current default ENGINE | ||
140 | for that RSA key is, and that the default can be set "per-key" | ||
141 | and globally (new keys will assume the global default, and keys | ||
142 | without their own default will be operated on using the global | ||
143 | default). NB: Try and make (v) conflict as little as possible with | ||
144 | (ii). :-) | ||
145 | |||
146 | (vi) wrap the ENGINE code up in duct tape so you can't even see the | ||
147 | corners. Ie. expose no structures at all, just black-box pointers. | ||
148 | |||
149 | (v) maintain internally a list of ENGINEs on which a calling | ||
150 | application can iterate, interrogate, etc. Allow a calling | ||
151 | application to hook in new ENGINEs, remove ENGINEs from the list, | ||
152 | and enforce uniqueness within the global list of each ENGINE's | ||
153 | "unique id". | ||
154 | |||
155 | (vi) keep reference counts for everything - eg. this includes storing a | ||
156 | reference inside each RSA structure to the ENGINE that it uses. | ||
157 | This is freed when the RSA structure is destroyed, or has its | ||
158 | ENGINE explicitly changed. The net effect needs to be that at any | ||
159 | time, it is deterministic to know whether an ENGINE is in use or | ||
160 | can be safely removed (or unloaded in the case of the other type | ||
161 | of reference) without invalidating function pointers that may or | ||
162 | may not be used indavertently in the future. This was actually | ||
163 | one of the biggest problems to overcome in the existing OpenSSL | ||
164 | code - implementations had always been assumed to be ever-present, | ||
165 | so there was no trivial way to get round this. | ||
166 | |||
167 | (vii) distinguish between structural references and functional | ||
168 | references. | ||
169 | |||
170 | A *little* detail | ||
171 | ----------------- | ||
172 | |||
173 | While my mind is on it; I'll illustrate the bit in item (vii). This idea | ||
174 | turned out to be very handy - the ENGINEs themselves need to be operated | ||
175 | on and manipulated simply as objects without necessarily trying to | ||
176 | "enable" them for use. Eg. most host machines will not have the necessary | ||
177 | hardware or software to support all the engines one might compile into | ||
178 | OpenSSL, yet it needs to be possible to iterate across the ENGINEs, | ||
179 | querying their names, properties, etc - all happening in a thread-safe | ||
180 | manner that uses reference counts (if you imagine two threads iterating | ||
181 | through a list and one thread removing the ENGINE the other is currently | ||
182 | looking at - you can see the gotcha waiting to happen). For all of this, | ||
183 | *structural references* are used and operate much like the other reference | ||
184 | counts in OpenSSL. | ||
185 | |||
186 | The other kind of reference count is for *functional* references - these | ||
187 | indicate a reference on which the caller can actually assume the | ||
188 | particular ENGINE to be initialised and usable to perform the operations | ||
189 | it implements. Any increment or decrement of the functional reference | ||
190 | count automatically invokes a corresponding change in the structural | ||
191 | reference count, as it is fairly obvious that a functional reference is a | ||
192 | restricted case of a structural reference. So struct_ref >= funct_ref at | ||
193 | all times. NB: functional references are usually obtained by a call to | ||
194 | ENGINE_init(), but can also be created implicitly by calls that require a | ||
195 | new functional reference to be created, eg. ENGINE_set_default(). Either | ||
196 | way the only time the underlying ENGINE's "init" function is really called | ||
197 | is when the (functional) reference count increases to 1, similarly the | ||
198 | underlying "finish" handler is only called as the count goes down to 0. | ||
199 | The effect of this, for example, is that if you set the default ENGINE for | ||
200 | RSA operations to be "cswift", then its functional reference count will | ||
201 | already be at least 1 so the CryptoSwift shared-library and the card will | ||
202 | stay loaded and initialised until such time as all RSA keys using the | ||
203 | cswift ENGINE are changed or destroyed and the default ENGINE for RSA | ||
204 | operations has been changed. This prevents repeated thrashing of init and | ||
205 | finish handling if the count keeps getting down as far as zero. | ||
206 | |||
207 | Otherwise, the way the ENGINE code has been put together I think pretty | ||
208 | much reflects the above points. The reason for the ENGINE structure having | ||
209 | individual RSA_METHOD, DSA_METHOD, etc pointers is simply that it was the | ||
210 | easiest way to go about things for now, to hook it all into the raw | ||
211 | RSA,DSA,etc code, and I was trying to the keep the structure invisible | ||
212 | anyway so that the way this is internally managed could be easily changed | ||
213 | later on when we start to work out what's to be done about these other | ||
214 | abstractions. | ||
215 | |||
216 | Down the line, if some EVP-based technique emerges for adequately | ||
217 | encapsulating algorithms and all their various bits and pieces, then I can | ||
218 | imagine that "ENGINE" would turn into a reference-counting database of | ||
219 | these EVP things, of which the default "openssl" ENGINE would be the | ||
220 | library's own object database of pre-built software implemented algorithms | ||
221 | (and such). It would also be cool to see the idea of "METHOD"s detached | ||
222 | from the algorithms themselves ... so RSA, DSA, ElGamal, etc can all | ||
223 | expose essentially the same METHOD (aka interface), which would include | ||
224 | any querying/flagging stuff to identify what the algorithm can/can't do, | ||
225 | its name, and other stuff like max/min block sizes, key sizes, etc. This | ||
226 | would result in ENGINE similarly detaching its internal database of | ||
227 | algorithm implementations from the function definitions that return | ||
228 | interfaces to them. I think ... | ||
229 | |||
230 | As for DSOs etc. Well the DSO code is pretty handy (but could be made much | ||
231 | more so) for loading vendor's driver-libraries and talking to them in some | ||
232 | generic way, but right now there's still big problems associated with | ||
233 | actually putting OpenSSL code (ie. new ENGINEs, or anything else for that | ||
234 | matter) in dynamically loadable libraries. These problems won't go away in | ||
235 | a hurry so I don't think we should expect to have any kind of | ||
236 | shared-library extensions any time soon - but solving the problems is a | ||
237 | good thing to aim for, and would as a side-effect probably help make | ||
238 | OpenSSL more usable as a shared-library itself (looking at the things | ||
239 | needed to do this will show you why). | ||
240 | |||
241 | One of the problems is that if you look at any of the ENGINE | ||
242 | implementations, eg. hw_cswift.c or hw_ncipher.c, you'll see how it needs | ||
243 | a variety of functionality and definitions from various areas of OpenSSL, | ||
244 | including crypto/bn/, crypto/err/, crypto/ itself (locking for example), | ||
245 | crypto/dso/, crypto/engine/, crypto/rsa, etc etc etc. So if similar code | ||
246 | were to be suctioned off into shared libraries, the shared libraries would | ||
247 | either have to duplicate all the definitions and code and avoid loader | ||
248 | conflicts, or OpenSSL would have to somehow expose all that functionality | ||
249 | to the shared-library. If this isn't a big enough problem, the issue of | ||
250 | binary compatibility will be - anyone writing Apache modules can tell you | ||
251 | that (Ralf? Ben? :-). However, I don't think OpenSSL would need to be | ||
252 | quite so forgiving as Apache should be, so OpenSSL could simply tell its | ||
253 | version to the DSO and leave the DSO with the problem of deciding whether | ||
254 | to proceed or bail out for fear of binary incompatibilities. | ||
255 | |||
256 | Certainly one thing that would go a long way to addressing this is to | ||
257 | embark on a bit of an opaqueness mission. I've set the ENGINE code up with | ||
258 | this in mind - it's so draconian that even to declare your own ENGINE, you | ||
259 | have to get the engine code to create the underlying ENGINE structure, and | ||
260 | then feed in the new ENGINE's function/method pointers through various | ||
261 | "set" functions. The more of the code that takes on such a black-box | ||
262 | approach, the more of the code that will be (a) easy to expose to shared | ||
263 | libraries that need it, and (b) easy to expose to applications wanting to | ||
264 | use OpenSSL itself as a shared-library. From my own explorations in | ||
265 | OpenSSL, the biggest leviathan I've seen that is a problem in this respect | ||
266 | is the BIGNUM code. Trying to "expose" the bignum code through any kind of | ||
267 | organised "METHODs", let alone do all the necessary bignum operations | ||
268 | solely through functions rather than direct access to the structures and | ||
269 | macros, will be a massive pain in the "r"s. | ||
270 | |||
271 | Anyway, I'm done for now - hope it was readable. Thoughts? | ||
272 | |||
273 | Cheers, | ||
274 | Geoff | ||
275 | |||
276 | |||
277 | -----------------------------------==*==----------------------------------- | ||
278 | |||
diff --git a/src/lib/libcrypto/engine/eng_all.c b/src/lib/libcrypto/engine/eng_all.c new file mode 100644 index 0000000000..a35b3db9e8 --- /dev/null +++ b/src/lib/libcrypto/engine/eng_all.c | |||
@@ -0,0 +1,118 @@ | |||
1 | /* crypto/engine/eng_all.c -*- mode: C; c-file-style: "eay" -*- */ | ||
2 | /* Written by Richard Levitte <richard@levitte.org> for the OpenSSL | ||
3 | * project 2000. | ||
4 | */ | ||
5 | /* ==================================================================== | ||
6 | * Copyright (c) 2000-2001 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/err.h> | ||
60 | #include <openssl/engine.h> | ||
61 | #include "eng_int.h" | ||
62 | |||
63 | #ifdef __OpenBSD__ | ||
64 | static int openbsd_default_loaded = 0; | ||
65 | #endif | ||
66 | |||
67 | void ENGINE_load_builtin_engines(void) | ||
68 | { | ||
69 | /* There's no longer any need for an "openssl" ENGINE unless, one day, | ||
70 | * it is the *only* way for standard builtin implementations to be be | ||
71 | * accessed (ie. it would be possible to statically link binaries with | ||
72 | * *no* builtin implementations). */ | ||
73 | #if 0 | ||
74 | ENGINE_load_openssl(); | ||
75 | #endif | ||
76 | ENGINE_load_dynamic(); | ||
77 | #ifndef OPENSSL_NO_HW | ||
78 | #ifndef OPENSSL_NO_HW_CSWIFT | ||
79 | ENGINE_load_cswift(); | ||
80 | #endif | ||
81 | #ifndef OPENSSL_NO_HW_NCIPHER | ||
82 | ENGINE_load_chil(); | ||
83 | #endif | ||
84 | #ifndef OPENSSL_NO_HW_ATALLA | ||
85 | ENGINE_load_atalla(); | ||
86 | #endif | ||
87 | #ifndef OPENSSL_NO_HW_NURON | ||
88 | ENGINE_load_nuron(); | ||
89 | #endif | ||
90 | #ifndef OPENSSL_NO_HW_UBSEC | ||
91 | ENGINE_load_ubsec(); | ||
92 | #endif | ||
93 | #ifndef OPENSSL_NO_HW_AEP | ||
94 | ENGINE_load_aep(); | ||
95 | #endif | ||
96 | #ifndef OPENSSL_NO_HW_SUREWARE | ||
97 | ENGINE_load_sureware(); | ||
98 | #endif | ||
99 | #ifdef OPENSSL_OPENBSD_DEV_CRYPTO | ||
100 | ENGINE_load_openbsd_dev_crypto(); | ||
101 | #endif | ||
102 | #ifdef __OpenBSD__ | ||
103 | ENGINE_load_cryptodev(); | ||
104 | #endif | ||
105 | #endif | ||
106 | } | ||
107 | |||
108 | #ifdef __OpenBSD__ | ||
109 | void ENGINE_setup_openbsd(void) { | ||
110 | if (!openbsd_default_loaded) { | ||
111 | ENGINE_load_cryptodev(); | ||
112 | ENGINE_register_all_complete(); | ||
113 | } | ||
114 | openbsd_default_loaded=1; | ||
115 | } | ||
116 | #endif | ||
117 | |||
118 | |||
diff --git a/src/lib/libcrypto/engine/eng_cnf.c b/src/lib/libcrypto/engine/eng_cnf.c new file mode 100644 index 0000000000..8c0ae8a1ad --- /dev/null +++ b/src/lib/libcrypto/engine/eng_cnf.c | |||
@@ -0,0 +1,242 @@ | |||
1 | /* eng_cnf.c */ | ||
2 | /* Written by Stephen Henson (shenson@bigfoot.com) for the OpenSSL | ||
3 | * project 2001. | ||
4 | */ | ||
5 | /* ==================================================================== | ||
6 | * Copyright (c) 2001 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 | #include <openssl/crypto.h> | ||
61 | #include "cryptlib.h" | ||
62 | #include <openssl/conf.h> | ||
63 | #include <openssl/engine.h> | ||
64 | |||
65 | /* #define ENGINE_CONF_DEBUG */ | ||
66 | |||
67 | /* ENGINE config module */ | ||
68 | |||
69 | static char *skip_dot(char *name) | ||
70 | { | ||
71 | char *p; | ||
72 | p = strchr(name, '.'); | ||
73 | if (p) | ||
74 | return p + 1; | ||
75 | return name; | ||
76 | } | ||
77 | |||
78 | static STACK_OF(ENGINE) *initialized_engines = NULL; | ||
79 | |||
80 | static int int_engine_init(ENGINE *e) | ||
81 | { | ||
82 | if (!ENGINE_init(e)) | ||
83 | return 0; | ||
84 | if (!initialized_engines) | ||
85 | initialized_engines = sk_ENGINE_new_null(); | ||
86 | if (!initialized_engines || !sk_ENGINE_push(initialized_engines, e)) | ||
87 | { | ||
88 | ENGINE_finish(e); | ||
89 | return 0; | ||
90 | } | ||
91 | return 1; | ||
92 | } | ||
93 | |||
94 | |||
95 | int int_engine_configure(char *name, char *value, const CONF *cnf) | ||
96 | { | ||
97 | int i; | ||
98 | int ret = 0; | ||
99 | long do_init = -1; | ||
100 | STACK_OF(CONF_VALUE) *ecmds; | ||
101 | CONF_VALUE *ecmd; | ||
102 | char *ctrlname, *ctrlvalue; | ||
103 | ENGINE *e = NULL; | ||
104 | name = skip_dot(name); | ||
105 | #ifdef ENGINE_CONF_DEBUG | ||
106 | fprintf(stderr, "Configuring engine %s\n", name); | ||
107 | #endif | ||
108 | /* Value is a section containing ENGINE commands */ | ||
109 | ecmds = NCONF_get_section(cnf, value); | ||
110 | |||
111 | if (!ecmds) | ||
112 | { | ||
113 | ENGINEerr(ENGINE_F_INT_ENGINE_CONFIGURE, ENGINE_R_ENGINE_SECTION_ERROR); | ||
114 | return 0; | ||
115 | } | ||
116 | |||
117 | for (i = 0; i < sk_CONF_VALUE_num(ecmds); i++) | ||
118 | { | ||
119 | ecmd = sk_CONF_VALUE_value(ecmds, i); | ||
120 | ctrlname = skip_dot(ecmd->name); | ||
121 | ctrlvalue = ecmd->value; | ||
122 | #ifdef ENGINE_CONF_DEBUG | ||
123 | fprintf(stderr, "ENGINE conf: doing ctrl(%s,%s)\n", ctrlname, ctrlvalue); | ||
124 | #endif | ||
125 | |||
126 | /* First handle some special pseudo ctrls */ | ||
127 | |||
128 | /* Override engine name to use */ | ||
129 | if (!strcmp(ctrlname, "engine_id")) | ||
130 | name = ctrlvalue; | ||
131 | /* Load a dynamic ENGINE */ | ||
132 | else if (!strcmp(ctrlname, "dynamic_path")) | ||
133 | { | ||
134 | e = ENGINE_by_id("dynamic"); | ||
135 | if (!e) | ||
136 | goto err; | ||
137 | if (!ENGINE_ctrl_cmd_string(e, "SO_PATH", ctrlvalue, 0)) | ||
138 | goto err; | ||
139 | if (!ENGINE_ctrl_cmd_string(e, "LIST_ADD", "2", 0)) | ||
140 | goto err; | ||
141 | if (!ENGINE_ctrl_cmd_string(e, "LOAD", NULL, 0)) | ||
142 | goto err; | ||
143 | } | ||
144 | /* ... add other pseudos here ... */ | ||
145 | else | ||
146 | { | ||
147 | /* At this point we need an ENGINE structural reference | ||
148 | * if we don't already have one. | ||
149 | */ | ||
150 | if (!e) | ||
151 | { | ||
152 | e = ENGINE_by_id(name); | ||
153 | if (!e) | ||
154 | return 0; | ||
155 | } | ||
156 | /* Allow "EMPTY" to mean no value: this allows a valid | ||
157 | * "value" to be passed to ctrls of type NO_INPUT | ||
158 | */ | ||
159 | if (!strcmp(ctrlvalue, "EMPTY")) | ||
160 | ctrlvalue = NULL; | ||
161 | else if (!strcmp(ctrlname, "init")) | ||
162 | { | ||
163 | if (!NCONF_get_number_e(cnf, value, "init", &do_init)) | ||
164 | goto err; | ||
165 | if (do_init == 1) | ||
166 | { | ||
167 | if (!int_engine_init(e)) | ||
168 | goto err; | ||
169 | } | ||
170 | else if (do_init != 0) | ||
171 | { | ||
172 | ENGINEerr(ENGINE_F_INT_ENGINE_CONFIGURE, ENGINE_R_INVALID_INIT_VALUE); | ||
173 | goto err; | ||
174 | } | ||
175 | } | ||
176 | else if (!strcmp(ctrlname, "default_algorithms")) | ||
177 | { | ||
178 | if (!ENGINE_set_default_string(e, ctrlvalue)) | ||
179 | goto err; | ||
180 | } | ||
181 | else if (!ENGINE_ctrl_cmd_string(e, | ||
182 | ctrlname, ctrlvalue, 0)) | ||
183 | return 0; | ||
184 | } | ||
185 | |||
186 | |||
187 | |||
188 | } | ||
189 | if (e && (do_init == -1) && !int_engine_init(e)) | ||
190 | goto err; | ||
191 | ret = 1; | ||
192 | err: | ||
193 | if (e) | ||
194 | ENGINE_free(e); | ||
195 | return ret; | ||
196 | } | ||
197 | |||
198 | |||
199 | static int int_engine_module_init(CONF_IMODULE *md, const CONF *cnf) | ||
200 | { | ||
201 | STACK_OF(CONF_VALUE) *elist; | ||
202 | CONF_VALUE *cval; | ||
203 | int i; | ||
204 | #ifdef ENGINE_CONF_DEBUG | ||
205 | fprintf(stderr, "Called engine module: name %s, value %s\n", | ||
206 | CONF_imodule_get_name(md), CONF_imodule_get_value(md)); | ||
207 | #endif | ||
208 | /* Value is a section containing ENGINEs to configure */ | ||
209 | elist = NCONF_get_section(cnf, CONF_imodule_get_value(md)); | ||
210 | |||
211 | if (!elist) | ||
212 | { | ||
213 | ENGINEerr(ENGINE_F_ENGINE_MODULE_INIT, ENGINE_R_ENGINES_SECTION_ERROR); | ||
214 | return 0; | ||
215 | } | ||
216 | |||
217 | for (i = 0; i < sk_CONF_VALUE_num(elist); i++) | ||
218 | { | ||
219 | cval = sk_CONF_VALUE_value(elist, i); | ||
220 | if (!int_engine_configure(cval->name, cval->value, cnf)) | ||
221 | return 0; | ||
222 | } | ||
223 | |||
224 | return 1; | ||
225 | } | ||
226 | |||
227 | static void int_engine_module_finish(CONF_IMODULE *md) | ||
228 | { | ||
229 | ENGINE *e; | ||
230 | while ((e = sk_ENGINE_pop(initialized_engines))) | ||
231 | ENGINE_finish(e); | ||
232 | sk_ENGINE_free(initialized_engines); | ||
233 | initialized_engines = NULL; | ||
234 | } | ||
235 | |||
236 | |||
237 | void ENGINE_add_conf_module(void) | ||
238 | { | ||
239 | CONF_module_add("engines", | ||
240 | int_engine_module_init, | ||
241 | int_engine_module_finish); | ||
242 | } | ||
diff --git a/src/lib/libcrypto/engine/eng_ctrl.c b/src/lib/libcrypto/engine/eng_ctrl.c new file mode 100644 index 0000000000..ad3858395b --- /dev/null +++ b/src/lib/libcrypto/engine/eng_ctrl.c | |||
@@ -0,0 +1,387 @@ | |||
1 | /* crypto/engine/eng_ctrl.c */ | ||
2 | /* ==================================================================== | ||
3 | * Copyright (c) 1999-2001 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 <openssl/crypto.h> | ||
57 | #include "cryptlib.h" | ||
58 | #include "eng_int.h" | ||
59 | #include <openssl/engine.h> | ||
60 | |||
61 | /* When querying a ENGINE-specific control command's 'description', this string | ||
62 | * is used if the ENGINE_CMD_DEFN has cmd_desc set to NULL. */ | ||
63 | static const char *int_no_description = ""; | ||
64 | |||
65 | /* These internal functions handle 'CMD'-related control commands when the | ||
66 | * ENGINE in question has asked us to take care of it (ie. the ENGINE did not | ||
67 | * set the ENGINE_FLAGS_MANUAL_CMD_CTRL flag. */ | ||
68 | |||
69 | static int int_ctrl_cmd_is_null(const ENGINE_CMD_DEFN *defn) | ||
70 | { | ||
71 | if((defn->cmd_num == 0) || (defn->cmd_name == NULL)) | ||
72 | return 1; | ||
73 | return 0; | ||
74 | } | ||
75 | |||
76 | static int int_ctrl_cmd_by_name(const ENGINE_CMD_DEFN *defn, const char *s) | ||
77 | { | ||
78 | int idx = 0; | ||
79 | while(!int_ctrl_cmd_is_null(defn) && (strcmp(defn->cmd_name, s) != 0)) | ||
80 | { | ||
81 | idx++; | ||
82 | defn++; | ||
83 | } | ||
84 | if(int_ctrl_cmd_is_null(defn)) | ||
85 | /* The given name wasn't found */ | ||
86 | return -1; | ||
87 | return idx; | ||
88 | } | ||
89 | |||
90 | static int int_ctrl_cmd_by_num(const ENGINE_CMD_DEFN *defn, unsigned int num) | ||
91 | { | ||
92 | int idx = 0; | ||
93 | /* NB: It is stipulated that 'cmd_defn' lists are ordered by cmd_num. So | ||
94 | * our searches don't need to take any longer than necessary. */ | ||
95 | while(!int_ctrl_cmd_is_null(defn) && (defn->cmd_num < num)) | ||
96 | { | ||
97 | idx++; | ||
98 | defn++; | ||
99 | } | ||
100 | if(defn->cmd_num == num) | ||
101 | return idx; | ||
102 | /* The given cmd_num wasn't found */ | ||
103 | return -1; | ||
104 | } | ||
105 | |||
106 | static int int_ctrl_helper(ENGINE *e, int cmd, long i, void *p, void (*f)()) | ||
107 | { | ||
108 | int idx; | ||
109 | char *s = (char *)p; | ||
110 | /* Take care of the easy one first (eg. it requires no searches) */ | ||
111 | if(cmd == ENGINE_CTRL_GET_FIRST_CMD_TYPE) | ||
112 | { | ||
113 | if((e->cmd_defns == NULL) || int_ctrl_cmd_is_null(e->cmd_defns)) | ||
114 | return 0; | ||
115 | return e->cmd_defns->cmd_num; | ||
116 | } | ||
117 | /* One or two commands require that "p" be a valid string buffer */ | ||
118 | if((cmd == ENGINE_CTRL_GET_CMD_FROM_NAME) || | ||
119 | (cmd == ENGINE_CTRL_GET_NAME_FROM_CMD) || | ||
120 | (cmd == ENGINE_CTRL_GET_DESC_FROM_CMD)) | ||
121 | { | ||
122 | if(s == NULL) | ||
123 | { | ||
124 | ENGINEerr(ENGINE_F_INT_CTRL_HELPER, | ||
125 | ERR_R_PASSED_NULL_PARAMETER); | ||
126 | return -1; | ||
127 | } | ||
128 | } | ||
129 | /* Now handle cmd_name -> cmd_num conversion */ | ||
130 | if(cmd == ENGINE_CTRL_GET_CMD_FROM_NAME) | ||
131 | { | ||
132 | if((e->cmd_defns == NULL) || ((idx = int_ctrl_cmd_by_name( | ||
133 | e->cmd_defns, s)) < 0)) | ||
134 | { | ||
135 | ENGINEerr(ENGINE_F_INT_CTRL_HELPER, | ||
136 | ENGINE_R_INVALID_CMD_NAME); | ||
137 | return -1; | ||
138 | } | ||
139 | return e->cmd_defns[idx].cmd_num; | ||
140 | } | ||
141 | /* For the rest of the commands, the 'long' argument must specify a | ||
142 | * valie command number - so we need to conduct a search. */ | ||
143 | if((e->cmd_defns == NULL) || ((idx = int_ctrl_cmd_by_num(e->cmd_defns, | ||
144 | (unsigned int)i)) < 0)) | ||
145 | { | ||
146 | ENGINEerr(ENGINE_F_INT_CTRL_HELPER, | ||
147 | ENGINE_R_INVALID_CMD_NUMBER); | ||
148 | return -1; | ||
149 | } | ||
150 | /* Now the logic splits depending on command type */ | ||
151 | switch(cmd) | ||
152 | { | ||
153 | case ENGINE_CTRL_GET_NEXT_CMD_TYPE: | ||
154 | idx++; | ||
155 | if(int_ctrl_cmd_is_null(e->cmd_defns + idx)) | ||
156 | /* end-of-list */ | ||
157 | return 0; | ||
158 | else | ||
159 | return e->cmd_defns[idx].cmd_num; | ||
160 | case ENGINE_CTRL_GET_NAME_LEN_FROM_CMD: | ||
161 | return strlen(e->cmd_defns[idx].cmd_name); | ||
162 | case ENGINE_CTRL_GET_NAME_FROM_CMD: | ||
163 | return sprintf(s, "%s", e->cmd_defns[idx].cmd_name); | ||
164 | case ENGINE_CTRL_GET_DESC_LEN_FROM_CMD: | ||
165 | if(e->cmd_defns[idx].cmd_desc) | ||
166 | return strlen(e->cmd_defns[idx].cmd_desc); | ||
167 | return strlen(int_no_description); | ||
168 | case ENGINE_CTRL_GET_DESC_FROM_CMD: | ||
169 | if(e->cmd_defns[idx].cmd_desc) | ||
170 | return sprintf(s, "%s", e->cmd_defns[idx].cmd_desc); | ||
171 | return sprintf(s, "%s", int_no_description); | ||
172 | case ENGINE_CTRL_GET_CMD_FLAGS: | ||
173 | return e->cmd_defns[idx].cmd_flags; | ||
174 | } | ||
175 | /* Shouldn't really be here ... */ | ||
176 | ENGINEerr(ENGINE_F_INT_CTRL_HELPER,ENGINE_R_INTERNAL_LIST_ERROR); | ||
177 | return -1; | ||
178 | } | ||
179 | |||
180 | int ENGINE_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)()) | ||
181 | { | ||
182 | int ctrl_exists, ref_exists; | ||
183 | if(e == NULL) | ||
184 | { | ||
185 | ENGINEerr(ENGINE_F_ENGINE_CTRL,ERR_R_PASSED_NULL_PARAMETER); | ||
186 | return 0; | ||
187 | } | ||
188 | CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); | ||
189 | ref_exists = ((e->struct_ref > 0) ? 1 : 0); | ||
190 | CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); | ||
191 | ctrl_exists = ((e->ctrl == NULL) ? 0 : 1); | ||
192 | if(!ref_exists) | ||
193 | { | ||
194 | ENGINEerr(ENGINE_F_ENGINE_CTRL,ENGINE_R_NO_REFERENCE); | ||
195 | return 0; | ||
196 | } | ||
197 | /* Intercept any "root-level" commands before trying to hand them on to | ||
198 | * ctrl() handlers. */ | ||
199 | switch(cmd) | ||
200 | { | ||
201 | case ENGINE_CTRL_HAS_CTRL_FUNCTION: | ||
202 | return ctrl_exists; | ||
203 | case ENGINE_CTRL_GET_FIRST_CMD_TYPE: | ||
204 | case ENGINE_CTRL_GET_NEXT_CMD_TYPE: | ||
205 | case ENGINE_CTRL_GET_CMD_FROM_NAME: | ||
206 | case ENGINE_CTRL_GET_NAME_LEN_FROM_CMD: | ||
207 | case ENGINE_CTRL_GET_NAME_FROM_CMD: | ||
208 | case ENGINE_CTRL_GET_DESC_LEN_FROM_CMD: | ||
209 | case ENGINE_CTRL_GET_DESC_FROM_CMD: | ||
210 | case ENGINE_CTRL_GET_CMD_FLAGS: | ||
211 | if(ctrl_exists && !(e->flags & ENGINE_FLAGS_MANUAL_CMD_CTRL)) | ||
212 | return int_ctrl_helper(e,cmd,i,p,f); | ||
213 | if(!ctrl_exists) | ||
214 | { | ||
215 | ENGINEerr(ENGINE_F_ENGINE_CTRL,ENGINE_R_NO_CONTROL_FUNCTION); | ||
216 | /* For these cmd-related functions, failure is indicated | ||
217 | * by a -1 return value (because 0 is used as a valid | ||
218 | * return in some places). */ | ||
219 | return -1; | ||
220 | } | ||
221 | default: | ||
222 | break; | ||
223 | } | ||
224 | /* Anything else requires a ctrl() handler to exist. */ | ||
225 | if(!ctrl_exists) | ||
226 | { | ||
227 | ENGINEerr(ENGINE_F_ENGINE_CTRL,ENGINE_R_NO_CONTROL_FUNCTION); | ||
228 | return 0; | ||
229 | } | ||
230 | return e->ctrl(e, cmd, i, p, f); | ||
231 | } | ||
232 | |||
233 | int ENGINE_cmd_is_executable(ENGINE *e, int cmd) | ||
234 | { | ||
235 | int flags; | ||
236 | if((flags = ENGINE_ctrl(e, ENGINE_CTRL_GET_CMD_FLAGS, cmd, NULL, NULL)) < 0) | ||
237 | { | ||
238 | ENGINEerr(ENGINE_F_ENGINE_CMD_IS_EXECUTABLE, | ||
239 | ENGINE_R_INVALID_CMD_NUMBER); | ||
240 | return 0; | ||
241 | } | ||
242 | if(!(flags & ENGINE_CMD_FLAG_NO_INPUT) && | ||
243 | !(flags & ENGINE_CMD_FLAG_NUMERIC) && | ||
244 | !(flags & ENGINE_CMD_FLAG_STRING)) | ||
245 | return 0; | ||
246 | return 1; | ||
247 | } | ||
248 | |||
249 | int ENGINE_ctrl_cmd(ENGINE *e, const char *cmd_name, | ||
250 | long i, void *p, void (*f)(), int cmd_optional) | ||
251 | { | ||
252 | int num; | ||
253 | |||
254 | if((e == NULL) || (cmd_name == NULL)) | ||
255 | { | ||
256 | ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD_STRING, | ||
257 | ERR_R_PASSED_NULL_PARAMETER); | ||
258 | return 0; | ||
259 | } | ||
260 | if((e->ctrl == NULL) || ((num = ENGINE_ctrl(e, | ||
261 | ENGINE_CTRL_GET_CMD_FROM_NAME, | ||
262 | 0, (void *)cmd_name, NULL)) <= 0)) | ||
263 | { | ||
264 | /* If the command didn't *have* to be supported, we fake | ||
265 | * success. This allows certain settings to be specified for | ||
266 | * multiple ENGINEs and only require a change of ENGINE id | ||
267 | * (without having to selectively apply settings). Eg. changing | ||
268 | * from a hardware device back to the regular software ENGINE | ||
269 | * without editing the config file, etc. */ | ||
270 | if(cmd_optional) | ||
271 | { | ||
272 | ERR_clear_error(); | ||
273 | return 1; | ||
274 | } | ||
275 | ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD, | ||
276 | ENGINE_R_INVALID_CMD_NAME); | ||
277 | return 0; | ||
278 | } | ||
279 | /* Force the result of the control command to 0 or 1, for the reasons | ||
280 | * mentioned before. */ | ||
281 | if (ENGINE_ctrl(e, num, i, p, f)) | ||
282 | return 1; | ||
283 | return 0; | ||
284 | } | ||
285 | |||
286 | int ENGINE_ctrl_cmd_string(ENGINE *e, const char *cmd_name, const char *arg, | ||
287 | int cmd_optional) | ||
288 | { | ||
289 | int num, flags; | ||
290 | long l; | ||
291 | char *ptr; | ||
292 | if((e == NULL) || (cmd_name == NULL)) | ||
293 | { | ||
294 | ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD_STRING, | ||
295 | ERR_R_PASSED_NULL_PARAMETER); | ||
296 | return 0; | ||
297 | } | ||
298 | if((e->ctrl == NULL) || ((num = ENGINE_ctrl(e, | ||
299 | ENGINE_CTRL_GET_CMD_FROM_NAME, | ||
300 | 0, (void *)cmd_name, NULL)) <= 0)) | ||
301 | { | ||
302 | /* If the command didn't *have* to be supported, we fake | ||
303 | * success. This allows certain settings to be specified for | ||
304 | * multiple ENGINEs and only require a change of ENGINE id | ||
305 | * (without having to selectively apply settings). Eg. changing | ||
306 | * from a hardware device back to the regular software ENGINE | ||
307 | * without editing the config file, etc. */ | ||
308 | if(cmd_optional) | ||
309 | { | ||
310 | ERR_clear_error(); | ||
311 | return 1; | ||
312 | } | ||
313 | ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD_STRING, | ||
314 | ENGINE_R_INVALID_CMD_NAME); | ||
315 | return 0; | ||
316 | } | ||
317 | if(!ENGINE_cmd_is_executable(e, num)) | ||
318 | { | ||
319 | ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD_STRING, | ||
320 | ENGINE_R_CMD_NOT_EXECUTABLE); | ||
321 | return 0; | ||
322 | } | ||
323 | if((flags = ENGINE_ctrl(e, ENGINE_CTRL_GET_CMD_FLAGS, num, NULL, NULL)) < 0) | ||
324 | { | ||
325 | /* Shouldn't happen, given that ENGINE_cmd_is_executable() | ||
326 | * returned success. */ | ||
327 | ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD_STRING, | ||
328 | ENGINE_R_INTERNAL_LIST_ERROR); | ||
329 | return 0; | ||
330 | } | ||
331 | /* If the command takes no input, there must be no input. And vice | ||
332 | * versa. */ | ||
333 | if(flags & ENGINE_CMD_FLAG_NO_INPUT) | ||
334 | { | ||
335 | if(arg != NULL) | ||
336 | { | ||
337 | ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD_STRING, | ||
338 | ENGINE_R_COMMAND_TAKES_NO_INPUT); | ||
339 | return 0; | ||
340 | } | ||
341 | /* We deliberately force the result of ENGINE_ctrl() to 0 or 1 | ||
342 | * rather than returning it as "return data". This is to ensure | ||
343 | * usage of these commands is consistent across applications and | ||
344 | * that certain applications don't understand it one way, and | ||
345 | * others another. */ | ||
346 | if(ENGINE_ctrl(e, num, 0, (void *)arg, NULL)) | ||
347 | return 1; | ||
348 | return 0; | ||
349 | } | ||
350 | /* So, we require input */ | ||
351 | if(arg == NULL) | ||
352 | { | ||
353 | ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD_STRING, | ||
354 | ENGINE_R_COMMAND_TAKES_INPUT); | ||
355 | return 0; | ||
356 | } | ||
357 | /* If it takes string input, that's easy */ | ||
358 | if(flags & ENGINE_CMD_FLAG_STRING) | ||
359 | { | ||
360 | /* Same explanation as above */ | ||
361 | if(ENGINE_ctrl(e, num, 0, (void *)arg, NULL)) | ||
362 | return 1; | ||
363 | return 0; | ||
364 | } | ||
365 | /* If it doesn't take numeric either, then it is unsupported for use in | ||
366 | * a config-setting situation, which is what this function is for. This | ||
367 | * should never happen though, because ENGINE_cmd_is_executable() was | ||
368 | * used. */ | ||
369 | if(!(flags & ENGINE_CMD_FLAG_NUMERIC)) | ||
370 | { | ||
371 | ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD_STRING, | ||
372 | ENGINE_R_INTERNAL_LIST_ERROR); | ||
373 | return 0; | ||
374 | } | ||
375 | l = strtol(arg, &ptr, 10); | ||
376 | if((arg == ptr) || (*ptr != '\0')) | ||
377 | { | ||
378 | ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD_STRING, | ||
379 | ENGINE_R_ARGUMENT_IS_NOT_A_NUMBER); | ||
380 | return 0; | ||
381 | } | ||
382 | /* Force the result of the control command to 0 or 1, for the reasons | ||
383 | * mentioned before. */ | ||
384 | if(ENGINE_ctrl(e, num, l, NULL, NULL)) | ||
385 | return 1; | ||
386 | return 0; | ||
387 | } | ||
diff --git a/src/lib/libcrypto/engine/eng_dyn.c b/src/lib/libcrypto/engine/eng_dyn.c new file mode 100644 index 0000000000..4fefcc0cae --- /dev/null +++ b/src/lib/libcrypto/engine/eng_dyn.c | |||
@@ -0,0 +1,446 @@ | |||
1 | /* crypto/engine/eng_dyn.c */ | ||
2 | /* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL | ||
3 | * project 2001. | ||
4 | */ | ||
5 | /* ==================================================================== | ||
6 | * Copyright (c) 1999-2001 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 <openssl/crypto.h> | ||
62 | #include "cryptlib.h" | ||
63 | #include "eng_int.h" | ||
64 | #include <openssl/engine.h> | ||
65 | #include <openssl/dso.h> | ||
66 | |||
67 | /* Shared libraries implementing ENGINEs for use by the "dynamic" ENGINE loader | ||
68 | * should implement the hook-up functions with the following prototypes. */ | ||
69 | |||
70 | /* Our ENGINE handlers */ | ||
71 | static int dynamic_init(ENGINE *e); | ||
72 | static int dynamic_finish(ENGINE *e); | ||
73 | static int dynamic_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)()); | ||
74 | /* Predeclare our context type */ | ||
75 | typedef struct st_dynamic_data_ctx dynamic_data_ctx; | ||
76 | /* The implementation for the important control command */ | ||
77 | static int dynamic_load(ENGINE *e, dynamic_data_ctx *ctx); | ||
78 | |||
79 | #define DYNAMIC_CMD_SO_PATH ENGINE_CMD_BASE | ||
80 | #define DYNAMIC_CMD_NO_VCHECK (ENGINE_CMD_BASE + 1) | ||
81 | #define DYNAMIC_CMD_ID (ENGINE_CMD_BASE + 2) | ||
82 | #define DYNAMIC_CMD_LIST_ADD (ENGINE_CMD_BASE + 3) | ||
83 | #define DYNAMIC_CMD_LOAD (ENGINE_CMD_BASE + 4) | ||
84 | |||
85 | /* The constants used when creating the ENGINE */ | ||
86 | static const char *engine_dynamic_id = "dynamic"; | ||
87 | static const char *engine_dynamic_name = "Dynamic engine loading support"; | ||
88 | static const ENGINE_CMD_DEFN dynamic_cmd_defns[] = { | ||
89 | {DYNAMIC_CMD_SO_PATH, | ||
90 | "SO_PATH", | ||
91 | "Specifies the path to the new ENGINE shared library", | ||
92 | ENGINE_CMD_FLAG_STRING}, | ||
93 | {DYNAMIC_CMD_NO_VCHECK, | ||
94 | "NO_VCHECK", | ||
95 | "Specifies to continue even if version checking fails (boolean)", | ||
96 | ENGINE_CMD_FLAG_NUMERIC}, | ||
97 | {DYNAMIC_CMD_ID, | ||
98 | "ID", | ||
99 | "Specifies an ENGINE id name for loading", | ||
100 | ENGINE_CMD_FLAG_STRING}, | ||
101 | {DYNAMIC_CMD_LIST_ADD, | ||
102 | "LIST_ADD", | ||
103 | "Whether to add a loaded ENGINE to the internal list (0=no,1=yes,2=mandatory)", | ||
104 | ENGINE_CMD_FLAG_NUMERIC}, | ||
105 | {DYNAMIC_CMD_LOAD, | ||
106 | "LOAD", | ||
107 | "Load up the ENGINE specified by other settings", | ||
108 | ENGINE_CMD_FLAG_NO_INPUT}, | ||
109 | {0, NULL, NULL, 0} | ||
110 | }; | ||
111 | static const ENGINE_CMD_DEFN dynamic_cmd_defns_empty[] = { | ||
112 | {0, NULL, NULL, 0} | ||
113 | }; | ||
114 | |||
115 | /* Loading code stores state inside the ENGINE structure via the "ex_data" | ||
116 | * element. We load all our state into a single structure and use that as a | ||
117 | * single context in the "ex_data" stack. */ | ||
118 | struct st_dynamic_data_ctx | ||
119 | { | ||
120 | /* The DSO object we load that supplies the ENGINE code */ | ||
121 | DSO *dynamic_dso; | ||
122 | /* The function pointer to the version checking shared library function */ | ||
123 | dynamic_v_check_fn v_check; | ||
124 | /* The function pointer to the engine-binding shared library function */ | ||
125 | dynamic_bind_engine bind_engine; | ||
126 | /* The default name/path for loading the shared library */ | ||
127 | const char *DYNAMIC_LIBNAME; | ||
128 | /* Whether to continue loading on a version check failure */ | ||
129 | int no_vcheck; | ||
130 | /* If non-NULL, stipulates the 'id' of the ENGINE to be loaded */ | ||
131 | const char *engine_id; | ||
132 | /* If non-zero, a successfully loaded ENGINE should be added to the internal | ||
133 | * ENGINE list. If 2, the add must succeed or the entire load should fail. */ | ||
134 | int list_add_value; | ||
135 | /* The symbol name for the version checking function */ | ||
136 | const char *DYNAMIC_F1; | ||
137 | /* The symbol name for the "initialise ENGINE structure" function */ | ||
138 | const char *DYNAMIC_F2; | ||
139 | }; | ||
140 | |||
141 | /* This is the "ex_data" index we obtain and reserve for use with our context | ||
142 | * structure. */ | ||
143 | static int dynamic_ex_data_idx = -1; | ||
144 | |||
145 | /* Because our ex_data element may or may not get allocated depending on whether | ||
146 | * a "first-use" occurs before the ENGINE is freed, we have a memory leak | ||
147 | * problem to solve. We can't declare a "new" handler for the ex_data as we | ||
148 | * don't want a dynamic_data_ctx in *all* ENGINE structures of all types (this | ||
149 | * is a bug in the design of CRYPTO_EX_DATA). As such, we just declare a "free" | ||
150 | * handler and that will get called if an ENGINE is being destroyed and there | ||
151 | * was an ex_data element corresponding to our context type. */ | ||
152 | static void dynamic_data_ctx_free_func(void *parent, void *ptr, | ||
153 | CRYPTO_EX_DATA *ad, int idx, long argl, void *argp) | ||
154 | { | ||
155 | if(ptr) | ||
156 | { | ||
157 | dynamic_data_ctx *ctx = (dynamic_data_ctx *)ptr; | ||
158 | if(ctx->dynamic_dso) | ||
159 | DSO_free(ctx->dynamic_dso); | ||
160 | OPENSSL_free(ctx); | ||
161 | } | ||
162 | } | ||
163 | |||
164 | /* Construct the per-ENGINE context. We create it blindly and then use a lock to | ||
165 | * check for a race - if so, all but one of the threads "racing" will have | ||
166 | * wasted their time. The alternative involves creating everything inside the | ||
167 | * lock which is far worse. */ | ||
168 | static int dynamic_set_data_ctx(ENGINE *e, dynamic_data_ctx **ctx) | ||
169 | { | ||
170 | dynamic_data_ctx *c; | ||
171 | c = OPENSSL_malloc(sizeof(dynamic_data_ctx)); | ||
172 | if(!ctx) | ||
173 | { | ||
174 | ENGINEerr(ENGINE_F_SET_DATA_CTX,ERR_R_MALLOC_FAILURE); | ||
175 | return 0; | ||
176 | } | ||
177 | memset(c, 0, sizeof(dynamic_data_ctx)); | ||
178 | c->dynamic_dso = NULL; | ||
179 | c->v_check = NULL; | ||
180 | c->bind_engine = NULL; | ||
181 | c->DYNAMIC_LIBNAME = NULL; | ||
182 | c->no_vcheck = 0; | ||
183 | c->engine_id = NULL; | ||
184 | c->list_add_value = 0; | ||
185 | c->DYNAMIC_F1 = "v_check"; | ||
186 | c->DYNAMIC_F2 = "bind_engine"; | ||
187 | CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); | ||
188 | if((*ctx = (dynamic_data_ctx *)ENGINE_get_ex_data(e, | ||
189 | dynamic_ex_data_idx)) == NULL) | ||
190 | { | ||
191 | /* Good, we're the first */ | ||
192 | ENGINE_set_ex_data(e, dynamic_ex_data_idx, c); | ||
193 | *ctx = c; | ||
194 | c = NULL; | ||
195 | } | ||
196 | CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); | ||
197 | /* If we lost the race to set the context, c is non-NULL and *ctx is the | ||
198 | * context of the thread that won. */ | ||
199 | if(c) | ||
200 | OPENSSL_free(c); | ||
201 | return 1; | ||
202 | } | ||
203 | |||
204 | /* This function retrieves the context structure from an ENGINE's "ex_data", or | ||
205 | * if it doesn't exist yet, sets it up. */ | ||
206 | static dynamic_data_ctx *dynamic_get_data_ctx(ENGINE *e) | ||
207 | { | ||
208 | dynamic_data_ctx *ctx; | ||
209 | if(dynamic_ex_data_idx < 0) | ||
210 | { | ||
211 | /* Create and register the ENGINE ex_data, and associate our | ||
212 | * "free" function with it to ensure any allocated contexts get | ||
213 | * freed when an ENGINE goes underground. */ | ||
214 | int new_idx = ENGINE_get_ex_new_index(0, NULL, NULL, NULL, | ||
215 | dynamic_data_ctx_free_func); | ||
216 | if(new_idx == -1) | ||
217 | { | ||
218 | ENGINEerr(ENGINE_F_DYNAMIC_GET_DATA_CTX,ENGINE_R_NO_INDEX); | ||
219 | return NULL; | ||
220 | } | ||
221 | CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); | ||
222 | /* Avoid a race by checking again inside this lock */ | ||
223 | if(dynamic_ex_data_idx < 0) | ||
224 | { | ||
225 | /* Good, someone didn't beat us to it */ | ||
226 | dynamic_ex_data_idx = new_idx; | ||
227 | new_idx = -1; | ||
228 | } | ||
229 | CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); | ||
230 | /* In theory we could "give back" the index here if | ||
231 | * (new_idx>-1), but it's not possible and wouldn't gain us much | ||
232 | * if it were. */ | ||
233 | } | ||
234 | ctx = (dynamic_data_ctx *)ENGINE_get_ex_data(e, dynamic_ex_data_idx); | ||
235 | /* Check if the context needs to be created */ | ||
236 | if((ctx == NULL) && !dynamic_set_data_ctx(e, &ctx)) | ||
237 | /* "set_data" will set errors if necessary */ | ||
238 | return NULL; | ||
239 | return ctx; | ||
240 | } | ||
241 | |||
242 | static ENGINE *engine_dynamic(void) | ||
243 | { | ||
244 | ENGINE *ret = ENGINE_new(); | ||
245 | if(!ret) | ||
246 | return NULL; | ||
247 | if(!ENGINE_set_id(ret, engine_dynamic_id) || | ||
248 | !ENGINE_set_name(ret, engine_dynamic_name) || | ||
249 | !ENGINE_set_init_function(ret, dynamic_init) || | ||
250 | !ENGINE_set_finish_function(ret, dynamic_finish) || | ||
251 | !ENGINE_set_ctrl_function(ret, dynamic_ctrl) || | ||
252 | !ENGINE_set_flags(ret, ENGINE_FLAGS_BY_ID_COPY) || | ||
253 | !ENGINE_set_cmd_defns(ret, dynamic_cmd_defns)) | ||
254 | { | ||
255 | ENGINE_free(ret); | ||
256 | return NULL; | ||
257 | } | ||
258 | return ret; | ||
259 | } | ||
260 | |||
261 | void ENGINE_load_dynamic(void) | ||
262 | { | ||
263 | ENGINE *toadd = engine_dynamic(); | ||
264 | if(!toadd) return; | ||
265 | ENGINE_add(toadd); | ||
266 | /* If the "add" worked, it gets a structural reference. So either way, | ||
267 | * we release our just-created reference. */ | ||
268 | ENGINE_free(toadd); | ||
269 | /* If the "add" didn't work, it was probably a conflict because it was | ||
270 | * already added (eg. someone calling ENGINE_load_blah then calling | ||
271 | * ENGINE_load_builtin_engines() perhaps). */ | ||
272 | ERR_clear_error(); | ||
273 | } | ||
274 | |||
275 | static int dynamic_init(ENGINE *e) | ||
276 | { | ||
277 | /* We always return failure - the "dyanamic" engine itself can't be used | ||
278 | * for anything. */ | ||
279 | return 0; | ||
280 | } | ||
281 | |||
282 | static int dynamic_finish(ENGINE *e) | ||
283 | { | ||
284 | /* This should never be called on account of "dynamic_init" always | ||
285 | * failing. */ | ||
286 | return 0; | ||
287 | } | ||
288 | |||
289 | static int dynamic_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)()) | ||
290 | { | ||
291 | dynamic_data_ctx *ctx = dynamic_get_data_ctx(e); | ||
292 | int initialised; | ||
293 | |||
294 | if(!ctx) | ||
295 | { | ||
296 | ENGINEerr(ENGINE_F_DYNAMIC_CTRL,ENGINE_R_NOT_LOADED); | ||
297 | return 0; | ||
298 | } | ||
299 | initialised = ((ctx->dynamic_dso == NULL) ? 0 : 1); | ||
300 | /* All our control commands require the ENGINE to be uninitialised */ | ||
301 | if(initialised) | ||
302 | { | ||
303 | ENGINEerr(ENGINE_F_DYNAMIC_CTRL, | ||
304 | ENGINE_R_ALREADY_LOADED); | ||
305 | return 0; | ||
306 | } | ||
307 | switch(cmd) | ||
308 | { | ||
309 | case DYNAMIC_CMD_SO_PATH: | ||
310 | /* a NULL 'p' or a string of zero-length is the same thing */ | ||
311 | if(p && (strlen((const char *)p) < 1)) | ||
312 | p = NULL; | ||
313 | ctx->DYNAMIC_LIBNAME = (const char *)p; | ||
314 | return 1; | ||
315 | case DYNAMIC_CMD_NO_VCHECK: | ||
316 | ctx->no_vcheck = ((i == 0) ? 0 : 1); | ||
317 | return 1; | ||
318 | case DYNAMIC_CMD_ID: | ||
319 | /* a NULL 'p' or a string of zero-length is the same thing */ | ||
320 | if(p && (strlen((const char *)p) < 1)) | ||
321 | p = NULL; | ||
322 | ctx->engine_id = (const char *)p; | ||
323 | return 1; | ||
324 | case DYNAMIC_CMD_LIST_ADD: | ||
325 | if((i < 0) || (i > 2)) | ||
326 | { | ||
327 | ENGINEerr(ENGINE_F_DYNAMIC_CTRL, | ||
328 | ENGINE_R_INVALID_ARGUMENT); | ||
329 | return 0; | ||
330 | } | ||
331 | ctx->list_add_value = (int)i; | ||
332 | return 1; | ||
333 | case DYNAMIC_CMD_LOAD: | ||
334 | return dynamic_load(e, ctx); | ||
335 | default: | ||
336 | break; | ||
337 | } | ||
338 | ENGINEerr(ENGINE_F_DYNAMIC_CTRL,ENGINE_R_CTRL_COMMAND_NOT_IMPLEMENTED); | ||
339 | return 0; | ||
340 | } | ||
341 | |||
342 | static int dynamic_load(ENGINE *e, dynamic_data_ctx *ctx) | ||
343 | { | ||
344 | ENGINE cpy; | ||
345 | dynamic_fns fns; | ||
346 | |||
347 | if(!ctx->DYNAMIC_LIBNAME || ((ctx->dynamic_dso = DSO_load(NULL, | ||
348 | ctx->DYNAMIC_LIBNAME, NULL, 0)) == NULL)) | ||
349 | { | ||
350 | ENGINEerr(ENGINE_F_DYNAMIC_LOAD, | ||
351 | ENGINE_R_DSO_NOT_FOUND); | ||
352 | return 0; | ||
353 | } | ||
354 | /* We have to find a bind function otherwise it'll always end badly */ | ||
355 | if(!(ctx->bind_engine = (dynamic_bind_engine)DSO_bind_func( | ||
356 | ctx->dynamic_dso, ctx->DYNAMIC_F2))) | ||
357 | { | ||
358 | ctx->bind_engine = NULL; | ||
359 | DSO_free(ctx->dynamic_dso); | ||
360 | ctx->dynamic_dso = NULL; | ||
361 | ENGINEerr(ENGINE_F_DYNAMIC_LOAD, | ||
362 | ENGINE_R_DSO_FAILURE); | ||
363 | return 0; | ||
364 | } | ||
365 | /* Do we perform version checking? */ | ||
366 | if(!ctx->no_vcheck) | ||
367 | { | ||
368 | unsigned long vcheck_res = 0; | ||
369 | /* Now we try to find a version checking function and decide how | ||
370 | * to cope with failure if/when it fails. */ | ||
371 | ctx->v_check = (dynamic_v_check_fn)DSO_bind_func( | ||
372 | ctx->dynamic_dso, ctx->DYNAMIC_F1); | ||
373 | if(ctx->v_check) | ||
374 | vcheck_res = ctx->v_check(OSSL_DYNAMIC_VERSION); | ||
375 | /* We fail if the version checker veto'd the load *or* if it is | ||
376 | * deferring to us (by returning its version) and we think it is | ||
377 | * too old. */ | ||
378 | if(vcheck_res < OSSL_DYNAMIC_OLDEST) | ||
379 | { | ||
380 | /* Fail */ | ||
381 | ctx->bind_engine = NULL; | ||
382 | ctx->v_check = NULL; | ||
383 | DSO_free(ctx->dynamic_dso); | ||
384 | ctx->dynamic_dso = NULL; | ||
385 | ENGINEerr(ENGINE_F_DYNAMIC_LOAD, | ||
386 | ENGINE_R_VERSION_INCOMPATIBILITY); | ||
387 | return 0; | ||
388 | } | ||
389 | } | ||
390 | /* First binary copy the ENGINE structure so that we can roll back if | ||
391 | * the hand-over fails */ | ||
392 | memcpy(&cpy, e, sizeof(ENGINE)); | ||
393 | /* Provide the ERR, "ex_data", memory, and locking callbacks so the | ||
394 | * loaded library uses our state rather than its own. FIXME: As noted in | ||
395 | * engine.h, much of this would be simplified if each area of code | ||
396 | * provided its own "summary" structure of all related callbacks. It | ||
397 | * would also increase opaqueness. */ | ||
398 | fns.err_fns = ERR_get_implementation(); | ||
399 | fns.ex_data_fns = CRYPTO_get_ex_data_implementation(); | ||
400 | CRYPTO_get_mem_functions(&fns.mem_fns.malloc_cb, | ||
401 | &fns.mem_fns.realloc_cb, | ||
402 | &fns.mem_fns.free_cb); | ||
403 | fns.lock_fns.lock_locking_cb = CRYPTO_get_locking_callback(); | ||
404 | fns.lock_fns.lock_add_lock_cb = CRYPTO_get_add_lock_callback(); | ||
405 | fns.lock_fns.dynlock_create_cb = CRYPTO_get_dynlock_create_callback(); | ||
406 | fns.lock_fns.dynlock_lock_cb = CRYPTO_get_dynlock_lock_callback(); | ||
407 | fns.lock_fns.dynlock_destroy_cb = CRYPTO_get_dynlock_destroy_callback(); | ||
408 | /* Now that we've loaded the dynamic engine, make sure no "dynamic" | ||
409 | * ENGINE elements will show through. */ | ||
410 | engine_set_all_null(e); | ||
411 | |||
412 | /* Try to bind the ENGINE onto our own ENGINE structure */ | ||
413 | if(!ctx->bind_engine(e, ctx->engine_id, &fns)) | ||
414 | { | ||
415 | ctx->bind_engine = NULL; | ||
416 | ctx->v_check = NULL; | ||
417 | DSO_free(ctx->dynamic_dso); | ||
418 | ctx->dynamic_dso = NULL; | ||
419 | ENGINEerr(ENGINE_F_DYNAMIC_LOAD,ENGINE_R_INIT_FAILED); | ||
420 | /* Copy the original ENGINE structure back */ | ||
421 | memcpy(e, &cpy, sizeof(ENGINE)); | ||
422 | return 0; | ||
423 | } | ||
424 | /* Do we try to add this ENGINE to the internal list too? */ | ||
425 | if(ctx->list_add_value > 0) | ||
426 | { | ||
427 | if(!ENGINE_add(e)) | ||
428 | { | ||
429 | /* Do we tolerate this or fail? */ | ||
430 | if(ctx->list_add_value > 1) | ||
431 | { | ||
432 | /* Fail - NB: By this time, it's too late to | ||
433 | * rollback, and trying to do so allows the | ||
434 | * bind_engine() code to have created leaks. We | ||
435 | * just have to fail where we are, after the | ||
436 | * ENGINE has changed. */ | ||
437 | ENGINEerr(ENGINE_F_DYNAMIC_LOAD, | ||
438 | ENGINE_R_CONFLICTING_ENGINE_ID); | ||
439 | return 0; | ||
440 | } | ||
441 | /* Tolerate */ | ||
442 | ERR_clear_error(); | ||
443 | } | ||
444 | } | ||
445 | return 1; | ||
446 | } | ||
diff --git a/src/lib/libcrypto/engine/eng_err.c b/src/lib/libcrypto/engine/eng_err.c new file mode 100644 index 0000000000..f6c5630395 --- /dev/null +++ b/src/lib/libcrypto/engine/eng_err.c | |||
@@ -0,0 +1,165 @@ | |||
1 | /* crypto/engine/eng_err.c */ | ||
2 | /* ==================================================================== | ||
3 | * Copyright (c) 1999 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/engine.h> | ||
64 | |||
65 | /* BEGIN ERROR CODES */ | ||
66 | #ifndef OPENSSL_NO_ERR | ||
67 | static ERR_STRING_DATA ENGINE_str_functs[]= | ||
68 | { | ||
69 | {ERR_PACK(0,ENGINE_F_DYNAMIC_CTRL,0), "DYNAMIC_CTRL"}, | ||
70 | {ERR_PACK(0,ENGINE_F_DYNAMIC_GET_DATA_CTX,0), "DYNAMIC_GET_DATA_CTX"}, | ||
71 | {ERR_PACK(0,ENGINE_F_DYNAMIC_LOAD,0), "DYNAMIC_LOAD"}, | ||
72 | {ERR_PACK(0,ENGINE_F_ENGINE_ADD,0), "ENGINE_add"}, | ||
73 | {ERR_PACK(0,ENGINE_F_ENGINE_BY_ID,0), "ENGINE_by_id"}, | ||
74 | {ERR_PACK(0,ENGINE_F_ENGINE_CMD_IS_EXECUTABLE,0), "ENGINE_cmd_is_executable"}, | ||
75 | {ERR_PACK(0,ENGINE_F_ENGINE_CTRL,0), "ENGINE_ctrl"}, | ||
76 | {ERR_PACK(0,ENGINE_F_ENGINE_CTRL_CMD,0), "ENGINE_ctrl_cmd"}, | ||
77 | {ERR_PACK(0,ENGINE_F_ENGINE_CTRL_CMD_STRING,0), "ENGINE_ctrl_cmd_string"}, | ||
78 | {ERR_PACK(0,ENGINE_F_ENGINE_FINISH,0), "ENGINE_finish"}, | ||
79 | {ERR_PACK(0,ENGINE_F_ENGINE_FREE,0), "ENGINE_free"}, | ||
80 | {ERR_PACK(0,ENGINE_F_ENGINE_GET_CIPHER,0), "ENGINE_get_cipher"}, | ||
81 | {ERR_PACK(0,ENGINE_F_ENGINE_GET_DEFAULT_TYPE,0), "ENGINE_GET_DEFAULT_TYPE"}, | ||
82 | {ERR_PACK(0,ENGINE_F_ENGINE_GET_DIGEST,0), "ENGINE_get_digest"}, | ||
83 | {ERR_PACK(0,ENGINE_F_ENGINE_GET_NEXT,0), "ENGINE_get_next"}, | ||
84 | {ERR_PACK(0,ENGINE_F_ENGINE_GET_PREV,0), "ENGINE_get_prev"}, | ||
85 | {ERR_PACK(0,ENGINE_F_ENGINE_INIT,0), "ENGINE_init"}, | ||
86 | {ERR_PACK(0,ENGINE_F_ENGINE_LIST_ADD,0), "ENGINE_LIST_ADD"}, | ||
87 | {ERR_PACK(0,ENGINE_F_ENGINE_LIST_REMOVE,0), "ENGINE_LIST_REMOVE"}, | ||
88 | {ERR_PACK(0,ENGINE_F_ENGINE_LOAD_PRIVATE_KEY,0), "ENGINE_load_private_key"}, | ||
89 | {ERR_PACK(0,ENGINE_F_ENGINE_LOAD_PUBLIC_KEY,0), "ENGINE_load_public_key"}, | ||
90 | {ERR_PACK(0,ENGINE_F_ENGINE_MODULE_INIT,0), "ENGINE_MODULE_INIT"}, | ||
91 | {ERR_PACK(0,ENGINE_F_ENGINE_NEW,0), "ENGINE_new"}, | ||
92 | {ERR_PACK(0,ENGINE_F_ENGINE_REMOVE,0), "ENGINE_remove"}, | ||
93 | {ERR_PACK(0,ENGINE_F_ENGINE_SET_DEFAULT_STRING,0), "ENGINE_set_default_string"}, | ||
94 | {ERR_PACK(0,ENGINE_F_ENGINE_SET_DEFAULT_TYPE,0), "ENGINE_SET_DEFAULT_TYPE"}, | ||
95 | {ERR_PACK(0,ENGINE_F_ENGINE_SET_ID,0), "ENGINE_set_id"}, | ||
96 | {ERR_PACK(0,ENGINE_F_ENGINE_SET_NAME,0), "ENGINE_set_name"}, | ||
97 | {ERR_PACK(0,ENGINE_F_ENGINE_TABLE_REGISTER,0), "ENGINE_TABLE_REGISTER"}, | ||
98 | {ERR_PACK(0,ENGINE_F_ENGINE_UNLOAD_KEY,0), "ENGINE_UNLOAD_KEY"}, | ||
99 | {ERR_PACK(0,ENGINE_F_INT_CTRL_HELPER,0), "INT_CTRL_HELPER"}, | ||
100 | {ERR_PACK(0,ENGINE_F_INT_ENGINE_CONFIGURE,0), "INT_ENGINE_CONFIGURE"}, | ||
101 | {ERR_PACK(0,ENGINE_F_LOG_MESSAGE,0), "LOG_MESSAGE"}, | ||
102 | {ERR_PACK(0,ENGINE_F_SET_DATA_CTX,0), "SET_DATA_CTX"}, | ||
103 | {0,NULL} | ||
104 | }; | ||
105 | |||
106 | static ERR_STRING_DATA ENGINE_str_reasons[]= | ||
107 | { | ||
108 | {ENGINE_R_ALREADY_LOADED ,"already loaded"}, | ||
109 | {ENGINE_R_ARGUMENT_IS_NOT_A_NUMBER ,"argument is not a number"}, | ||
110 | {ENGINE_R_CMD_NOT_EXECUTABLE ,"cmd not executable"}, | ||
111 | {ENGINE_R_COMMAND_TAKES_INPUT ,"command takes input"}, | ||
112 | {ENGINE_R_COMMAND_TAKES_NO_INPUT ,"command takes no input"}, | ||
113 | {ENGINE_R_CONFLICTING_ENGINE_ID ,"conflicting engine id"}, | ||
114 | {ENGINE_R_CTRL_COMMAND_NOT_IMPLEMENTED ,"ctrl command not implemented"}, | ||
115 | {ENGINE_R_DH_NOT_IMPLEMENTED ,"dh not implemented"}, | ||
116 | {ENGINE_R_DSA_NOT_IMPLEMENTED ,"dsa not implemented"}, | ||
117 | {ENGINE_R_DSO_FAILURE ,"DSO failure"}, | ||
118 | {ENGINE_R_DSO_NOT_FOUND ,"dso not found"}, | ||
119 | {ENGINE_R_ENGINES_SECTION_ERROR ,"engines section error"}, | ||
120 | {ENGINE_R_ENGINE_IS_NOT_IN_LIST ,"engine is not in the list"}, | ||
121 | {ENGINE_R_ENGINE_SECTION_ERROR ,"engine section error"}, | ||
122 | {ENGINE_R_FAILED_LOADING_PRIVATE_KEY ,"failed loading private key"}, | ||
123 | {ENGINE_R_FAILED_LOADING_PUBLIC_KEY ,"failed loading public key"}, | ||
124 | {ENGINE_R_FINISH_FAILED ,"finish failed"}, | ||
125 | {ENGINE_R_GET_HANDLE_FAILED ,"could not obtain hardware handle"}, | ||
126 | {ENGINE_R_ID_OR_NAME_MISSING ,"'id' or 'name' missing"}, | ||
127 | {ENGINE_R_INIT_FAILED ,"init failed"}, | ||
128 | {ENGINE_R_INTERNAL_LIST_ERROR ,"internal list error"}, | ||
129 | {ENGINE_R_INVALID_ARGUMENT ,"invalid argument"}, | ||
130 | {ENGINE_R_INVALID_CMD_NAME ,"invalid cmd name"}, | ||
131 | {ENGINE_R_INVALID_CMD_NUMBER ,"invalid cmd number"}, | ||
132 | {ENGINE_R_INVALID_INIT_VALUE ,"invalid init value"}, | ||
133 | {ENGINE_R_INVALID_STRING ,"invalid string"}, | ||
134 | {ENGINE_R_NOT_INITIALISED ,"not initialised"}, | ||
135 | {ENGINE_R_NOT_LOADED ,"not loaded"}, | ||
136 | {ENGINE_R_NO_CONTROL_FUNCTION ,"no control function"}, | ||
137 | {ENGINE_R_NO_INDEX ,"no index"}, | ||
138 | {ENGINE_R_NO_LOAD_FUNCTION ,"no load function"}, | ||
139 | {ENGINE_R_NO_REFERENCE ,"no reference"}, | ||
140 | {ENGINE_R_NO_SUCH_ENGINE ,"no such engine"}, | ||
141 | {ENGINE_R_NO_UNLOAD_FUNCTION ,"no unload function"}, | ||
142 | {ENGINE_R_PROVIDE_PARAMETERS ,"provide parameters"}, | ||
143 | {ENGINE_R_RSA_NOT_IMPLEMENTED ,"rsa not implemented"}, | ||
144 | {ENGINE_R_UNIMPLEMENTED_CIPHER ,"unimplemented cipher"}, | ||
145 | {ENGINE_R_UNIMPLEMENTED_DIGEST ,"unimplemented digest"}, | ||
146 | {ENGINE_R_VERSION_INCOMPATIBILITY ,"version incompatibility"}, | ||
147 | {0,NULL} | ||
148 | }; | ||
149 | |||
150 | #endif | ||
151 | |||
152 | void ERR_load_ENGINE_strings(void) | ||
153 | { | ||
154 | static int init=1; | ||
155 | |||
156 | if (init) | ||
157 | { | ||
158 | init=0; | ||
159 | #ifndef OPENSSL_NO_ERR | ||
160 | ERR_load_strings(ERR_LIB_ENGINE,ENGINE_str_functs); | ||
161 | ERR_load_strings(ERR_LIB_ENGINE,ENGINE_str_reasons); | ||
162 | #endif | ||
163 | |||
164 | } | ||
165 | } | ||
diff --git a/src/lib/libcrypto/engine/eng_fat.c b/src/lib/libcrypto/engine/eng_fat.c new file mode 100644 index 0000000000..af918b1499 --- /dev/null +++ b/src/lib/libcrypto/engine/eng_fat.c | |||
@@ -0,0 +1,148 @@ | |||
1 | /* crypto/engine/eng_fat.c */ | ||
2 | /* ==================================================================== | ||
3 | * Copyright (c) 1999-2001 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 <openssl/crypto.h> | ||
57 | #include "cryptlib.h" | ||
58 | #include "eng_int.h" | ||
59 | #include <openssl/engine.h> | ||
60 | #include <openssl/conf.h> | ||
61 | |||
62 | int ENGINE_set_default(ENGINE *e, unsigned int flags) | ||
63 | { | ||
64 | if((flags & ENGINE_METHOD_CIPHERS) && !ENGINE_set_default_ciphers(e)) | ||
65 | return 0; | ||
66 | if((flags & ENGINE_METHOD_DIGESTS) && !ENGINE_set_default_digests(e)) | ||
67 | return 0; | ||
68 | #ifndef OPENSSL_NO_RSA | ||
69 | if((flags & ENGINE_METHOD_RSA) & !ENGINE_set_default_RSA(e)) | ||
70 | return 0; | ||
71 | #endif | ||
72 | #ifndef OPENSSL_NO_DSA | ||
73 | if((flags & ENGINE_METHOD_DSA) & !ENGINE_set_default_DSA(e)) | ||
74 | return 0; | ||
75 | #endif | ||
76 | #ifndef OPENSSL_NO_DH | ||
77 | if((flags & ENGINE_METHOD_DH) & !ENGINE_set_default_DH(e)) | ||
78 | return 0; | ||
79 | #endif | ||
80 | if((flags & ENGINE_METHOD_RAND) & !ENGINE_set_default_RAND(e)) | ||
81 | return 0; | ||
82 | return 1; | ||
83 | } | ||
84 | |||
85 | /* Set default algorithms using a string */ | ||
86 | |||
87 | int int_def_cb(const char *alg, int len, void *arg) | ||
88 | { | ||
89 | unsigned int *pflags = arg; | ||
90 | if (!strncmp(alg, "ALL", len)) | ||
91 | *pflags |= ENGINE_METHOD_ALL; | ||
92 | else if (!strncmp(alg, "RSA", len)) | ||
93 | *pflags |= ENGINE_METHOD_RSA; | ||
94 | else if (!strncmp(alg, "DSA", len)) | ||
95 | *pflags |= ENGINE_METHOD_DSA; | ||
96 | else if (!strncmp(alg, "DH", len)) | ||
97 | *pflags |= ENGINE_METHOD_DH; | ||
98 | else if (!strncmp(alg, "RAND", len)) | ||
99 | *pflags |= ENGINE_METHOD_RAND; | ||
100 | else if (!strncmp(alg, "CIPHERS", len)) | ||
101 | *pflags |= ENGINE_METHOD_CIPHERS; | ||
102 | else if (!strncmp(alg, "DIGESTS", len)) | ||
103 | *pflags |= ENGINE_METHOD_DIGESTS; | ||
104 | else | ||
105 | return 0; | ||
106 | return 1; | ||
107 | } | ||
108 | |||
109 | |||
110 | int ENGINE_set_default_string(ENGINE *e, const char *list) | ||
111 | { | ||
112 | unsigned int flags = 0; | ||
113 | if (!CONF_parse_list(list, ',', 1, int_def_cb, &flags)) | ||
114 | { | ||
115 | ENGINEerr(ENGINE_F_ENGINE_SET_DEFAULT_STRING, | ||
116 | ENGINE_R_INVALID_STRING); | ||
117 | ERR_add_error_data(2, "str=",list); | ||
118 | return 0; | ||
119 | } | ||
120 | return ENGINE_set_default(e, flags); | ||
121 | } | ||
122 | |||
123 | int ENGINE_register_complete(ENGINE *e) | ||
124 | { | ||
125 | ENGINE_register_ciphers(e); | ||
126 | ENGINE_register_digests(e); | ||
127 | #ifndef OPENSSL_NO_RSA | ||
128 | ENGINE_register_RSA(e); | ||
129 | #endif | ||
130 | #ifndef OPENSSL_NO_DSA | ||
131 | ENGINE_register_DSA(e); | ||
132 | #endif | ||
133 | #ifndef OPENSSL_NO_DH | ||
134 | ENGINE_register_DH(e); | ||
135 | #endif | ||
136 | ENGINE_register_RAND(e); | ||
137 | return 1; | ||
138 | } | ||
139 | |||
140 | int ENGINE_register_all_complete(void) | ||
141 | { | ||
142 | ENGINE *e; | ||
143 | |||
144 | for(e=ENGINE_get_first() ; e ; e=ENGINE_get_next(e)) { | ||
145 | ENGINE_register_complete(e); | ||
146 | } | ||
147 | return 1; | ||
148 | } | ||
diff --git a/src/lib/libcrypto/engine/eng_init.c b/src/lib/libcrypto/engine/eng_init.c new file mode 100644 index 0000000000..cc9396e863 --- /dev/null +++ b/src/lib/libcrypto/engine/eng_init.c | |||
@@ -0,0 +1,158 @@ | |||
1 | /* crypto/engine/eng_init.c */ | ||
2 | /* ==================================================================== | ||
3 | * Copyright (c) 1999-2001 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 <openssl/crypto.h> | ||
57 | #include "cryptlib.h" | ||
58 | #include "eng_int.h" | ||
59 | #include <openssl/engine.h> | ||
60 | |||
61 | /* Initialise a engine type for use (or up its functional reference count | ||
62 | * if it's already in use). This version is only used internally. */ | ||
63 | int engine_unlocked_init(ENGINE *e) | ||
64 | { | ||
65 | int to_return = 1; | ||
66 | |||
67 | if((e->funct_ref == 0) && e->init) | ||
68 | /* This is the first functional reference and the engine | ||
69 | * requires initialisation so we do it now. */ | ||
70 | to_return = e->init(e); | ||
71 | if(to_return) | ||
72 | { | ||
73 | /* OK, we return a functional reference which is also a | ||
74 | * structural reference. */ | ||
75 | e->struct_ref++; | ||
76 | e->funct_ref++; | ||
77 | engine_ref_debug(e, 0, 1) | ||
78 | engine_ref_debug(e, 1, 1) | ||
79 | } | ||
80 | return to_return; | ||
81 | } | ||
82 | |||
83 | /* Free a functional reference to a engine type. This version is only used | ||
84 | * internally. */ | ||
85 | int engine_unlocked_finish(ENGINE *e, int unlock_for_handlers) | ||
86 | { | ||
87 | int to_return = 1; | ||
88 | |||
89 | /* Reduce the functional reference count here so if it's the terminating | ||
90 | * case, we can release the lock safely and call the finish() handler | ||
91 | * without risk of a race. We get a race if we leave the count until | ||
92 | * after and something else is calling "finish" at the same time - | ||
93 | * there's a chance that both threads will together take the count from | ||
94 | * 2 to 0 without either calling finish(). */ | ||
95 | e->funct_ref--; | ||
96 | engine_ref_debug(e, 1, -1); | ||
97 | if((e->funct_ref == 0) && e->finish) | ||
98 | { | ||
99 | if(unlock_for_handlers) | ||
100 | CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); | ||
101 | to_return = e->finish(e); | ||
102 | if(unlock_for_handlers) | ||
103 | CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); | ||
104 | if(!to_return) | ||
105 | return 0; | ||
106 | } | ||
107 | #ifdef REF_CHECK | ||
108 | if(e->funct_ref < 0) | ||
109 | { | ||
110 | fprintf(stderr,"ENGINE_finish, bad functional reference count\n"); | ||
111 | abort(); | ||
112 | } | ||
113 | #endif | ||
114 | /* Release the structural reference too */ | ||
115 | if(!engine_free_util(e, 0)) | ||
116 | { | ||
117 | ENGINEerr(ENGINE_F_ENGINE_FINISH,ENGINE_R_FINISH_FAILED); | ||
118 | return 0; | ||
119 | } | ||
120 | return to_return; | ||
121 | } | ||
122 | |||
123 | /* The API (locked) version of "init" */ | ||
124 | int ENGINE_init(ENGINE *e) | ||
125 | { | ||
126 | int ret; | ||
127 | if(e == NULL) | ||
128 | { | ||
129 | ENGINEerr(ENGINE_F_ENGINE_INIT,ERR_R_PASSED_NULL_PARAMETER); | ||
130 | return 0; | ||
131 | } | ||
132 | CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); | ||
133 | ret = engine_unlocked_init(e); | ||
134 | CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); | ||
135 | return ret; | ||
136 | } | ||
137 | |||
138 | /* The API (locked) version of "finish" */ | ||
139 | int ENGINE_finish(ENGINE *e) | ||
140 | { | ||
141 | int to_return = 1; | ||
142 | |||
143 | if(e == NULL) | ||
144 | { | ||
145 | ENGINEerr(ENGINE_F_ENGINE_FINISH,ERR_R_PASSED_NULL_PARAMETER); | ||
146 | return 0; | ||
147 | } | ||
148 | CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); | ||
149 | to_return = engine_unlocked_finish(e, 1); | ||
150 | CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); | ||
151 | if(!to_return) | ||
152 | { | ||
153 | ENGINEerr(ENGINE_F_ENGINE_FINISH,ENGINE_R_FINISH_FAILED); | ||
154 | return 0; | ||
155 | } | ||
156 | return to_return; | ||
157 | } | ||
158 | |||
diff --git a/src/lib/libcrypto/engine/eng_int.h b/src/lib/libcrypto/engine/eng_int.h new file mode 100644 index 0000000000..38335f99cd --- /dev/null +++ b/src/lib/libcrypto/engine/eng_int.h | |||
@@ -0,0 +1,185 @@ | |||
1 | /* crypto/engine/eng_int.h */ | ||
2 | /* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL | ||
3 | * project 2000. | ||
4 | */ | ||
5 | /* ==================================================================== | ||
6 | * Copyright (c) 1999-2001 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_ENGINE_INT_H | ||
60 | #define HEADER_ENGINE_INT_H | ||
61 | |||
62 | /* Take public definitions from engine.h */ | ||
63 | #include <openssl/engine.h> | ||
64 | |||
65 | #ifdef __cplusplus | ||
66 | extern "C" { | ||
67 | #endif | ||
68 | |||
69 | /* If we compile with this symbol defined, then both reference counts in the | ||
70 | * ENGINE structure will be monitored with a line of output on stderr for each | ||
71 | * change. This prints the engine's pointer address (truncated to unsigned int), | ||
72 | * "struct" or "funct" to indicate the reference type, the before and after | ||
73 | * reference count, and the file:line-number pair. The "engine_ref_debug" | ||
74 | * statements must come *after* the change. */ | ||
75 | #ifdef ENGINE_REF_COUNT_DEBUG | ||
76 | |||
77 | #define engine_ref_debug(e, isfunct, diff) \ | ||
78 | fprintf(stderr, "engine: %08x %s from %d to %d (%s:%d)\n", \ | ||
79 | (unsigned int)(e), (isfunct ? "funct" : "struct"), \ | ||
80 | ((isfunct) ? ((e)->funct_ref - (diff)) : ((e)->struct_ref - (diff))), \ | ||
81 | ((isfunct) ? (e)->funct_ref : (e)->struct_ref), \ | ||
82 | (__FILE__), (__LINE__)); | ||
83 | |||
84 | #else | ||
85 | |||
86 | #define engine_ref_debug(e, isfunct, diff) | ||
87 | |||
88 | #endif | ||
89 | |||
90 | /* Any code that will need cleanup operations should use these functions to | ||
91 | * register callbacks. ENGINE_cleanup() will call all registered callbacks in | ||
92 | * order. NB: both the "add" functions assume CRYPTO_LOCK_ENGINE to already be | ||
93 | * held (in "write" mode). */ | ||
94 | typedef void (ENGINE_CLEANUP_CB)(void); | ||
95 | typedef struct st_engine_cleanup_item | ||
96 | { | ||
97 | ENGINE_CLEANUP_CB *cb; | ||
98 | } ENGINE_CLEANUP_ITEM; | ||
99 | DECLARE_STACK_OF(ENGINE_CLEANUP_ITEM) | ||
100 | void engine_cleanup_add_first(ENGINE_CLEANUP_CB *cb); | ||
101 | void engine_cleanup_add_last(ENGINE_CLEANUP_CB *cb); | ||
102 | |||
103 | /* We need stacks of ENGINEs for use in eng_table.c */ | ||
104 | DECLARE_STACK_OF(ENGINE) | ||
105 | |||
106 | /* If this symbol is defined then engine_table_select(), the function that is | ||
107 | * used by RSA, DSA (etc) code to select registered ENGINEs, cache defaults and | ||
108 | * functional references (etc), will display debugging summaries to stderr. */ | ||
109 | /* #define ENGINE_TABLE_DEBUG */ | ||
110 | |||
111 | /* This represents an implementation table. Dependent code should instantiate it | ||
112 | * as a (ENGINE_TABLE *) pointer value set initially to NULL. */ | ||
113 | typedef struct st_engine_table ENGINE_TABLE; | ||
114 | int engine_table_register(ENGINE_TABLE **table, ENGINE_CLEANUP_CB *cleanup, | ||
115 | ENGINE *e, const int *nids, int num_nids, int setdefault); | ||
116 | void engine_table_unregister(ENGINE_TABLE **table, ENGINE *e); | ||
117 | void engine_table_cleanup(ENGINE_TABLE **table); | ||
118 | #ifndef ENGINE_TABLE_DEBUG | ||
119 | ENGINE *engine_table_select(ENGINE_TABLE **table, int nid); | ||
120 | #else | ||
121 | ENGINE *engine_table_select_tmp(ENGINE_TABLE **table, int nid, const char *f, int l); | ||
122 | #define engine_table_select(t,n) engine_table_select_tmp(t,n,__FILE__,__LINE__) | ||
123 | #endif | ||
124 | |||
125 | /* Internal versions of API functions that have control over locking. These are | ||
126 | * used between C files when functionality needs to be shared but the caller may | ||
127 | * already be controlling of the CRYPTO_LOCK_ENGINE lock. */ | ||
128 | int engine_unlocked_init(ENGINE *e); | ||
129 | int engine_unlocked_finish(ENGINE *e, int unlock_for_handlers); | ||
130 | int engine_free_util(ENGINE *e, int locked); | ||
131 | |||
132 | /* This function will reset all "set"able values in an ENGINE to NULL. This | ||
133 | * won't touch reference counts or ex_data, but is equivalent to calling all the | ||
134 | * ENGINE_set_***() functions with a NULL value. */ | ||
135 | void engine_set_all_null(ENGINE *e); | ||
136 | |||
137 | /* NB: Bitwise OR-able values for the "flags" variable in ENGINE are now exposed | ||
138 | * in engine.h. */ | ||
139 | |||
140 | /* This is a structure for storing implementations of various crypto | ||
141 | * algorithms and functions. */ | ||
142 | struct engine_st | ||
143 | { | ||
144 | const char *id; | ||
145 | const char *name; | ||
146 | const RSA_METHOD *rsa_meth; | ||
147 | const DSA_METHOD *dsa_meth; | ||
148 | const DH_METHOD *dh_meth; | ||
149 | const RAND_METHOD *rand_meth; | ||
150 | /* Cipher handling is via this callback */ | ||
151 | ENGINE_CIPHERS_PTR ciphers; | ||
152 | /* Digest handling is via this callback */ | ||
153 | ENGINE_DIGESTS_PTR digests; | ||
154 | |||
155 | |||
156 | ENGINE_GEN_INT_FUNC_PTR destroy; | ||
157 | |||
158 | ENGINE_GEN_INT_FUNC_PTR init; | ||
159 | ENGINE_GEN_INT_FUNC_PTR finish; | ||
160 | ENGINE_CTRL_FUNC_PTR ctrl; | ||
161 | ENGINE_LOAD_KEY_PTR load_privkey; | ||
162 | ENGINE_LOAD_KEY_PTR load_pubkey; | ||
163 | |||
164 | const ENGINE_CMD_DEFN *cmd_defns; | ||
165 | int flags; | ||
166 | /* reference count on the structure itself */ | ||
167 | int struct_ref; | ||
168 | /* reference count on usability of the engine type. NB: This | ||
169 | * controls the loading and initialisation of any functionlity | ||
170 | * required by this engine, whereas the previous count is | ||
171 | * simply to cope with (de)allocation of this structure. Hence, | ||
172 | * running_ref <= struct_ref at all times. */ | ||
173 | int funct_ref; | ||
174 | /* A place to store per-ENGINE data */ | ||
175 | CRYPTO_EX_DATA ex_data; | ||
176 | /* Used to maintain the linked-list of engines. */ | ||
177 | struct engine_st *prev; | ||
178 | struct engine_st *next; | ||
179 | }; | ||
180 | |||
181 | #ifdef __cplusplus | ||
182 | } | ||
183 | #endif | ||
184 | |||
185 | #endif /* HEADER_ENGINE_INT_H */ | ||
diff --git a/src/lib/libcrypto/engine/eng_lib.c b/src/lib/libcrypto/engine/eng_lib.c new file mode 100644 index 0000000000..a66d0f08af --- /dev/null +++ b/src/lib/libcrypto/engine/eng_lib.c | |||
@@ -0,0 +1,321 @@ | |||
1 | /* crypto/engine/eng_lib.c */ | ||
2 | /* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL | ||
3 | * project 2000. | ||
4 | */ | ||
5 | /* ==================================================================== | ||
6 | * Copyright (c) 1999-2001 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/crypto.h> | ||
60 | #include "cryptlib.h" | ||
61 | #include "eng_int.h" | ||
62 | #include <openssl/rand.h> /* FIXME: This shouldn't be needed */ | ||
63 | #include <openssl/engine.h> | ||
64 | |||
65 | /* The "new"/"free" stuff first */ | ||
66 | |||
67 | ENGINE *ENGINE_new(void) | ||
68 | { | ||
69 | ENGINE *ret; | ||
70 | |||
71 | ret = (ENGINE *)OPENSSL_malloc(sizeof(ENGINE)); | ||
72 | if(ret == NULL) | ||
73 | { | ||
74 | ENGINEerr(ENGINE_F_ENGINE_NEW, ERR_R_MALLOC_FAILURE); | ||
75 | return NULL; | ||
76 | } | ||
77 | memset(ret, 0, sizeof(ENGINE)); | ||
78 | ret->struct_ref = 1; | ||
79 | engine_ref_debug(ret, 0, 1) | ||
80 | CRYPTO_new_ex_data(CRYPTO_EX_INDEX_ENGINE, ret, &ret->ex_data); | ||
81 | return ret; | ||
82 | } | ||
83 | |||
84 | /* Placed here (close proximity to ENGINE_new) so that modifications to the | ||
85 | * elements of the ENGINE structure are more likely to be caught and changed | ||
86 | * here. */ | ||
87 | void engine_set_all_null(ENGINE *e) | ||
88 | { | ||
89 | e->id = NULL; | ||
90 | e->name = NULL; | ||
91 | e->rsa_meth = NULL; | ||
92 | e->dsa_meth = NULL; | ||
93 | e->dh_meth = NULL; | ||
94 | e->rand_meth = NULL; | ||
95 | e->ciphers = NULL; | ||
96 | e->digests = NULL; | ||
97 | e->destroy = NULL; | ||
98 | e->init = NULL; | ||
99 | e->finish = NULL; | ||
100 | e->ctrl = NULL; | ||
101 | e->load_privkey = NULL; | ||
102 | e->load_pubkey = NULL; | ||
103 | e->cmd_defns = NULL; | ||
104 | e->flags = 0; | ||
105 | } | ||
106 | |||
107 | int engine_free_util(ENGINE *e, int locked) | ||
108 | { | ||
109 | int i; | ||
110 | |||
111 | if(e == NULL) | ||
112 | { | ||
113 | ENGINEerr(ENGINE_F_ENGINE_FREE, | ||
114 | ERR_R_PASSED_NULL_PARAMETER); | ||
115 | return 0; | ||
116 | } | ||
117 | if(locked) | ||
118 | i = CRYPTO_add(&e->struct_ref,-1,CRYPTO_LOCK_ENGINE); | ||
119 | else | ||
120 | i = --e->struct_ref; | ||
121 | engine_ref_debug(e, 0, -1) | ||
122 | if (i > 0) return 1; | ||
123 | #ifdef REF_CHECK | ||
124 | if (i < 0) | ||
125 | { | ||
126 | fprintf(stderr,"ENGINE_free, bad structural reference count\n"); | ||
127 | abort(); | ||
128 | } | ||
129 | #endif | ||
130 | /* Give the ENGINE a chance to do any structural cleanup corresponding | ||
131 | * to allocation it did in its constructor (eg. unload error strings) */ | ||
132 | if(e->destroy) | ||
133 | e->destroy(e); | ||
134 | CRYPTO_free_ex_data(CRYPTO_EX_INDEX_ENGINE, e, &e->ex_data); | ||
135 | OPENSSL_free(e); | ||
136 | return 1; | ||
137 | } | ||
138 | |||
139 | int ENGINE_free(ENGINE *e) | ||
140 | { | ||
141 | return engine_free_util(e, 1); | ||
142 | } | ||
143 | |||
144 | /* Cleanup stuff */ | ||
145 | |||
146 | /* ENGINE_cleanup() is coded such that anything that does work that will need | ||
147 | * cleanup can register a "cleanup" callback here. That way we don't get linker | ||
148 | * bloat by referring to all *possible* cleanups, but any linker bloat into code | ||
149 | * "X" will cause X's cleanup function to end up here. */ | ||
150 | static STACK_OF(ENGINE_CLEANUP_ITEM) *cleanup_stack = NULL; | ||
151 | static int int_cleanup_check(int create) | ||
152 | { | ||
153 | if(cleanup_stack) return 1; | ||
154 | if(!create) return 0; | ||
155 | cleanup_stack = sk_ENGINE_CLEANUP_ITEM_new_null(); | ||
156 | return (cleanup_stack ? 1 : 0); | ||
157 | } | ||
158 | static ENGINE_CLEANUP_ITEM *int_cleanup_item(ENGINE_CLEANUP_CB *cb) | ||
159 | { | ||
160 | ENGINE_CLEANUP_ITEM *item = OPENSSL_malloc(sizeof( | ||
161 | ENGINE_CLEANUP_ITEM)); | ||
162 | if(!item) return NULL; | ||
163 | item->cb = cb; | ||
164 | return item; | ||
165 | } | ||
166 | void engine_cleanup_add_first(ENGINE_CLEANUP_CB *cb) | ||
167 | { | ||
168 | ENGINE_CLEANUP_ITEM *item; | ||
169 | if(!int_cleanup_check(1)) return; | ||
170 | item = int_cleanup_item(cb); | ||
171 | if(item) | ||
172 | sk_ENGINE_CLEANUP_ITEM_insert(cleanup_stack, item, 0); | ||
173 | } | ||
174 | void engine_cleanup_add_last(ENGINE_CLEANUP_CB *cb) | ||
175 | { | ||
176 | ENGINE_CLEANUP_ITEM *item; | ||
177 | if(!int_cleanup_check(1)) return; | ||
178 | item = int_cleanup_item(cb); | ||
179 | if(item) | ||
180 | sk_ENGINE_CLEANUP_ITEM_push(cleanup_stack, item); | ||
181 | } | ||
182 | /* The API function that performs all cleanup */ | ||
183 | static void engine_cleanup_cb_free(ENGINE_CLEANUP_ITEM *item) | ||
184 | { | ||
185 | (*(item->cb))(); | ||
186 | OPENSSL_free(item); | ||
187 | } | ||
188 | void ENGINE_cleanup(void) | ||
189 | { | ||
190 | if(int_cleanup_check(0)) | ||
191 | { | ||
192 | sk_ENGINE_CLEANUP_ITEM_pop_free(cleanup_stack, | ||
193 | engine_cleanup_cb_free); | ||
194 | cleanup_stack = NULL; | ||
195 | } | ||
196 | /* FIXME: This should be handled (somehow) through RAND, eg. by it | ||
197 | * registering a cleanup callback. */ | ||
198 | RAND_set_rand_method(NULL); | ||
199 | } | ||
200 | |||
201 | /* Now the "ex_data" support */ | ||
202 | |||
203 | int ENGINE_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, | ||
204 | CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func) | ||
205 | { | ||
206 | return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_ENGINE, argl, argp, | ||
207 | new_func, dup_func, free_func); | ||
208 | } | ||
209 | |||
210 | int ENGINE_set_ex_data(ENGINE *e, int idx, void *arg) | ||
211 | { | ||
212 | return(CRYPTO_set_ex_data(&e->ex_data, idx, arg)); | ||
213 | } | ||
214 | |||
215 | void *ENGINE_get_ex_data(const ENGINE *e, int idx) | ||
216 | { | ||
217 | return(CRYPTO_get_ex_data(&e->ex_data, idx)); | ||
218 | } | ||
219 | |||
220 | /* Functions to get/set an ENGINE's elements - mainly to avoid exposing the | ||
221 | * ENGINE structure itself. */ | ||
222 | |||
223 | int ENGINE_set_id(ENGINE *e, const char *id) | ||
224 | { | ||
225 | if(id == NULL) | ||
226 | { | ||
227 | ENGINEerr(ENGINE_F_ENGINE_SET_ID, | ||
228 | ERR_R_PASSED_NULL_PARAMETER); | ||
229 | return 0; | ||
230 | } | ||
231 | e->id = id; | ||
232 | return 1; | ||
233 | } | ||
234 | |||
235 | int ENGINE_set_name(ENGINE *e, const char *name) | ||
236 | { | ||
237 | if(name == NULL) | ||
238 | { | ||
239 | ENGINEerr(ENGINE_F_ENGINE_SET_NAME, | ||
240 | ERR_R_PASSED_NULL_PARAMETER); | ||
241 | return 0; | ||
242 | } | ||
243 | e->name = name; | ||
244 | return 1; | ||
245 | } | ||
246 | |||
247 | int ENGINE_set_destroy_function(ENGINE *e, ENGINE_GEN_INT_FUNC_PTR destroy_f) | ||
248 | { | ||
249 | e->destroy = destroy_f; | ||
250 | return 1; | ||
251 | } | ||
252 | |||
253 | int ENGINE_set_init_function(ENGINE *e, ENGINE_GEN_INT_FUNC_PTR init_f) | ||
254 | { | ||
255 | e->init = init_f; | ||
256 | return 1; | ||
257 | } | ||
258 | |||
259 | int ENGINE_set_finish_function(ENGINE *e, ENGINE_GEN_INT_FUNC_PTR finish_f) | ||
260 | { | ||
261 | e->finish = finish_f; | ||
262 | return 1; | ||
263 | } | ||
264 | |||
265 | int ENGINE_set_ctrl_function(ENGINE *e, ENGINE_CTRL_FUNC_PTR ctrl_f) | ||
266 | { | ||
267 | e->ctrl = ctrl_f; | ||
268 | return 1; | ||
269 | } | ||
270 | |||
271 | int ENGINE_set_flags(ENGINE *e, int flags) | ||
272 | { | ||
273 | e->flags = flags; | ||
274 | return 1; | ||
275 | } | ||
276 | |||
277 | int ENGINE_set_cmd_defns(ENGINE *e, const ENGINE_CMD_DEFN *defns) | ||
278 | { | ||
279 | e->cmd_defns = defns; | ||
280 | return 1; | ||
281 | } | ||
282 | |||
283 | const char *ENGINE_get_id(const ENGINE *e) | ||
284 | { | ||
285 | return e->id; | ||
286 | } | ||
287 | |||
288 | const char *ENGINE_get_name(const ENGINE *e) | ||
289 | { | ||
290 | return e->name; | ||
291 | } | ||
292 | |||
293 | ENGINE_GEN_INT_FUNC_PTR ENGINE_get_destroy_function(const ENGINE *e) | ||
294 | { | ||
295 | return e->destroy; | ||
296 | } | ||
297 | |||
298 | ENGINE_GEN_INT_FUNC_PTR ENGINE_get_init_function(const ENGINE *e) | ||
299 | { | ||
300 | return e->init; | ||
301 | } | ||
302 | |||
303 | ENGINE_GEN_INT_FUNC_PTR ENGINE_get_finish_function(const ENGINE *e) | ||
304 | { | ||
305 | return e->finish; | ||
306 | } | ||
307 | |||
308 | ENGINE_CTRL_FUNC_PTR ENGINE_get_ctrl_function(const ENGINE *e) | ||
309 | { | ||
310 | return e->ctrl; | ||
311 | } | ||
312 | |||
313 | int ENGINE_get_flags(const ENGINE *e) | ||
314 | { | ||
315 | return e->flags; | ||
316 | } | ||
317 | |||
318 | const ENGINE_CMD_DEFN *ENGINE_get_cmd_defns(const ENGINE *e) | ||
319 | { | ||
320 | return e->cmd_defns; | ||
321 | } | ||
diff --git a/src/lib/libcrypto/engine/eng_list.c b/src/lib/libcrypto/engine/eng_list.c new file mode 100644 index 0000000000..ce48d2255a --- /dev/null +++ b/src/lib/libcrypto/engine/eng_list.c | |||
@@ -0,0 +1,383 @@ | |||
1 | /* crypto/engine/eng_list.c */ | ||
2 | /* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL | ||
3 | * project 2000. | ||
4 | */ | ||
5 | /* ==================================================================== | ||
6 | * Copyright (c) 1999-2001 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/crypto.h> | ||
60 | #include "cryptlib.h" | ||
61 | #include "eng_int.h" | ||
62 | #include <openssl/engine.h> | ||
63 | |||
64 | /* The linked-list of pointers to engine types. engine_list_head | ||
65 | * incorporates an implicit structural reference but engine_list_tail | ||
66 | * does not - the latter is a computational niceity and only points | ||
67 | * to something that is already pointed to by its predecessor in the | ||
68 | * list (or engine_list_head itself). In the same way, the use of the | ||
69 | * "prev" pointer in each ENGINE is to save excessive list iteration, | ||
70 | * it doesn't correspond to an extra structural reference. Hence, | ||
71 | * engine_list_head, and each non-null "next" pointer account for | ||
72 | * the list itself assuming exactly 1 structural reference on each | ||
73 | * list member. */ | ||
74 | static ENGINE *engine_list_head = NULL; | ||
75 | static ENGINE *engine_list_tail = NULL; | ||
76 | |||
77 | /* This cleanup function is only needed internally. If it should be called, we | ||
78 | * register it with the "ENGINE_cleanup()" stack to be called during cleanup. */ | ||
79 | |||
80 | static void engine_list_cleanup(void) | ||
81 | { | ||
82 | ENGINE *iterator = engine_list_head; | ||
83 | |||
84 | while(iterator != NULL) | ||
85 | { | ||
86 | ENGINE_remove(iterator); | ||
87 | iterator = engine_list_head; | ||
88 | } | ||
89 | return; | ||
90 | } | ||
91 | |||
92 | /* These static functions starting with a lower case "engine_" always | ||
93 | * take place when CRYPTO_LOCK_ENGINE has been locked up. */ | ||
94 | static int engine_list_add(ENGINE *e) | ||
95 | { | ||
96 | int conflict = 0; | ||
97 | ENGINE *iterator = NULL; | ||
98 | |||
99 | if(e == NULL) | ||
100 | { | ||
101 | ENGINEerr(ENGINE_F_ENGINE_LIST_ADD, | ||
102 | ERR_R_PASSED_NULL_PARAMETER); | ||
103 | return 0; | ||
104 | } | ||
105 | iterator = engine_list_head; | ||
106 | while(iterator && !conflict) | ||
107 | { | ||
108 | conflict = (strcmp(iterator->id, e->id) == 0); | ||
109 | iterator = iterator->next; | ||
110 | } | ||
111 | if(conflict) | ||
112 | { | ||
113 | ENGINEerr(ENGINE_F_ENGINE_LIST_ADD, | ||
114 | ENGINE_R_CONFLICTING_ENGINE_ID); | ||
115 | return 0; | ||
116 | } | ||
117 | if(engine_list_head == NULL) | ||
118 | { | ||
119 | /* We are adding to an empty list. */ | ||
120 | if(engine_list_tail) | ||
121 | { | ||
122 | ENGINEerr(ENGINE_F_ENGINE_LIST_ADD, | ||
123 | ENGINE_R_INTERNAL_LIST_ERROR); | ||
124 | return 0; | ||
125 | } | ||
126 | engine_list_head = e; | ||
127 | e->prev = NULL; | ||
128 | /* The first time the list allocates, we should register the | ||
129 | * cleanup. */ | ||
130 | engine_cleanup_add_last(engine_list_cleanup); | ||
131 | } | ||
132 | else | ||
133 | { | ||
134 | /* We are adding to the tail of an existing list. */ | ||
135 | if((engine_list_tail == NULL) || | ||
136 | (engine_list_tail->next != NULL)) | ||
137 | { | ||
138 | ENGINEerr(ENGINE_F_ENGINE_LIST_ADD, | ||
139 | ENGINE_R_INTERNAL_LIST_ERROR); | ||
140 | return 0; | ||
141 | } | ||
142 | engine_list_tail->next = e; | ||
143 | e->prev = engine_list_tail; | ||
144 | } | ||
145 | /* Having the engine in the list assumes a structural | ||
146 | * reference. */ | ||
147 | e->struct_ref++; | ||
148 | engine_ref_debug(e, 0, 1) | ||
149 | /* However it came to be, e is the last item in the list. */ | ||
150 | engine_list_tail = e; | ||
151 | e->next = NULL; | ||
152 | return 1; | ||
153 | } | ||
154 | |||
155 | static int engine_list_remove(ENGINE *e) | ||
156 | { | ||
157 | ENGINE *iterator; | ||
158 | |||
159 | if(e == NULL) | ||
160 | { | ||
161 | ENGINEerr(ENGINE_F_ENGINE_LIST_REMOVE, | ||
162 | ERR_R_PASSED_NULL_PARAMETER); | ||
163 | return 0; | ||
164 | } | ||
165 | /* We need to check that e is in our linked list! */ | ||
166 | iterator = engine_list_head; | ||
167 | while(iterator && (iterator != e)) | ||
168 | iterator = iterator->next; | ||
169 | if(iterator == NULL) | ||
170 | { | ||
171 | ENGINEerr(ENGINE_F_ENGINE_LIST_REMOVE, | ||
172 | ENGINE_R_ENGINE_IS_NOT_IN_LIST); | ||
173 | return 0; | ||
174 | } | ||
175 | /* un-link e from the chain. */ | ||
176 | if(e->next) | ||
177 | e->next->prev = e->prev; | ||
178 | if(e->prev) | ||
179 | e->prev->next = e->next; | ||
180 | /* Correct our head/tail if necessary. */ | ||
181 | if(engine_list_head == e) | ||
182 | engine_list_head = e->next; | ||
183 | if(engine_list_tail == e) | ||
184 | engine_list_tail = e->prev; | ||
185 | engine_free_util(e, 0); | ||
186 | return 1; | ||
187 | } | ||
188 | |||
189 | /* Get the first/last "ENGINE" type available. */ | ||
190 | ENGINE *ENGINE_get_first(void) | ||
191 | { | ||
192 | ENGINE *ret; | ||
193 | |||
194 | CRYPTO_r_lock(CRYPTO_LOCK_ENGINE); | ||
195 | ret = engine_list_head; | ||
196 | if(ret) | ||
197 | { | ||
198 | ret->struct_ref++; | ||
199 | engine_ref_debug(ret, 0, 1) | ||
200 | } | ||
201 | CRYPTO_r_unlock(CRYPTO_LOCK_ENGINE); | ||
202 | return ret; | ||
203 | } | ||
204 | |||
205 | ENGINE *ENGINE_get_last(void) | ||
206 | { | ||
207 | ENGINE *ret; | ||
208 | |||
209 | CRYPTO_r_lock(CRYPTO_LOCK_ENGINE); | ||
210 | ret = engine_list_tail; | ||
211 | if(ret) | ||
212 | { | ||
213 | ret->struct_ref++; | ||
214 | engine_ref_debug(ret, 0, 1) | ||
215 | } | ||
216 | CRYPTO_r_unlock(CRYPTO_LOCK_ENGINE); | ||
217 | return ret; | ||
218 | } | ||
219 | |||
220 | /* Iterate to the next/previous "ENGINE" type (NULL = end of the list). */ | ||
221 | ENGINE *ENGINE_get_next(ENGINE *e) | ||
222 | { | ||
223 | ENGINE *ret = NULL; | ||
224 | if(e == NULL) | ||
225 | { | ||
226 | ENGINEerr(ENGINE_F_ENGINE_GET_NEXT, | ||
227 | ERR_R_PASSED_NULL_PARAMETER); | ||
228 | return 0; | ||
229 | } | ||
230 | CRYPTO_r_lock(CRYPTO_LOCK_ENGINE); | ||
231 | ret = e->next; | ||
232 | if(ret) | ||
233 | { | ||
234 | /* Return a valid structural refernce to the next ENGINE */ | ||
235 | ret->struct_ref++; | ||
236 | engine_ref_debug(ret, 0, 1) | ||
237 | } | ||
238 | CRYPTO_r_unlock(CRYPTO_LOCK_ENGINE); | ||
239 | /* Release the structural reference to the previous ENGINE */ | ||
240 | ENGINE_free(e); | ||
241 | return ret; | ||
242 | } | ||
243 | |||
244 | ENGINE *ENGINE_get_prev(ENGINE *e) | ||
245 | { | ||
246 | ENGINE *ret = NULL; | ||
247 | if(e == NULL) | ||
248 | { | ||
249 | ENGINEerr(ENGINE_F_ENGINE_GET_PREV, | ||
250 | ERR_R_PASSED_NULL_PARAMETER); | ||
251 | return 0; | ||
252 | } | ||
253 | CRYPTO_r_lock(CRYPTO_LOCK_ENGINE); | ||
254 | ret = e->prev; | ||
255 | if(ret) | ||
256 | { | ||
257 | /* Return a valid structural reference to the next ENGINE */ | ||
258 | ret->struct_ref++; | ||
259 | engine_ref_debug(ret, 0, 1) | ||
260 | } | ||
261 | CRYPTO_r_unlock(CRYPTO_LOCK_ENGINE); | ||
262 | /* Release the structural reference to the previous ENGINE */ | ||
263 | ENGINE_free(e); | ||
264 | return ret; | ||
265 | } | ||
266 | |||
267 | /* Add another "ENGINE" type into the list. */ | ||
268 | int ENGINE_add(ENGINE *e) | ||
269 | { | ||
270 | int to_return = 1; | ||
271 | if(e == NULL) | ||
272 | { | ||
273 | ENGINEerr(ENGINE_F_ENGINE_ADD, | ||
274 | ERR_R_PASSED_NULL_PARAMETER); | ||
275 | return 0; | ||
276 | } | ||
277 | if((e->id == NULL) || (e->name == NULL)) | ||
278 | { | ||
279 | ENGINEerr(ENGINE_F_ENGINE_ADD, | ||
280 | ENGINE_R_ID_OR_NAME_MISSING); | ||
281 | } | ||
282 | CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); | ||
283 | if(!engine_list_add(e)) | ||
284 | { | ||
285 | ENGINEerr(ENGINE_F_ENGINE_ADD, | ||
286 | ENGINE_R_INTERNAL_LIST_ERROR); | ||
287 | to_return = 0; | ||
288 | } | ||
289 | CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); | ||
290 | return to_return; | ||
291 | } | ||
292 | |||
293 | /* Remove an existing "ENGINE" type from the array. */ | ||
294 | int ENGINE_remove(ENGINE *e) | ||
295 | { | ||
296 | int to_return = 1; | ||
297 | if(e == NULL) | ||
298 | { | ||
299 | ENGINEerr(ENGINE_F_ENGINE_REMOVE, | ||
300 | ERR_R_PASSED_NULL_PARAMETER); | ||
301 | return 0; | ||
302 | } | ||
303 | CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); | ||
304 | if(!engine_list_remove(e)) | ||
305 | { | ||
306 | ENGINEerr(ENGINE_F_ENGINE_REMOVE, | ||
307 | ENGINE_R_INTERNAL_LIST_ERROR); | ||
308 | to_return = 0; | ||
309 | } | ||
310 | CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); | ||
311 | return to_return; | ||
312 | } | ||
313 | |||
314 | static void engine_cpy(ENGINE *dest, const ENGINE *src) | ||
315 | { | ||
316 | dest->id = src->id; | ||
317 | dest->name = src->name; | ||
318 | #ifndef OPENSSL_NO_RSA | ||
319 | dest->rsa_meth = src->rsa_meth; | ||
320 | #endif | ||
321 | #ifndef OPENSSL_NO_DSA | ||
322 | dest->dsa_meth = src->dsa_meth; | ||
323 | #endif | ||
324 | #ifndef OPENSSL_NO_DH | ||
325 | dest->dh_meth = src->dh_meth; | ||
326 | #endif | ||
327 | dest->rand_meth = src->rand_meth; | ||
328 | dest->ciphers = src->ciphers; | ||
329 | dest->digests = src->digests; | ||
330 | dest->destroy = src->destroy; | ||
331 | dest->init = src->init; | ||
332 | dest->finish = src->finish; | ||
333 | dest->ctrl = src->ctrl; | ||
334 | dest->load_privkey = src->load_privkey; | ||
335 | dest->load_pubkey = src->load_pubkey; | ||
336 | dest->cmd_defns = src->cmd_defns; | ||
337 | dest->flags = src->flags; | ||
338 | } | ||
339 | |||
340 | ENGINE *ENGINE_by_id(const char *id) | ||
341 | { | ||
342 | ENGINE *iterator; | ||
343 | if(id == NULL) | ||
344 | { | ||
345 | ENGINEerr(ENGINE_F_ENGINE_BY_ID, | ||
346 | ERR_R_PASSED_NULL_PARAMETER); | ||
347 | return NULL; | ||
348 | } | ||
349 | CRYPTO_r_lock(CRYPTO_LOCK_ENGINE); | ||
350 | iterator = engine_list_head; | ||
351 | while(iterator && (strcmp(id, iterator->id) != 0)) | ||
352 | iterator = iterator->next; | ||
353 | if(iterator) | ||
354 | { | ||
355 | /* We need to return a structural reference. If this is an | ||
356 | * ENGINE type that returns copies, make a duplicate - otherwise | ||
357 | * increment the existing ENGINE's reference count. */ | ||
358 | if(iterator->flags & ENGINE_FLAGS_BY_ID_COPY) | ||
359 | { | ||
360 | ENGINE *cp = ENGINE_new(); | ||
361 | if(!cp) | ||
362 | iterator = NULL; | ||
363 | else | ||
364 | { | ||
365 | engine_cpy(cp, iterator); | ||
366 | iterator = cp; | ||
367 | } | ||
368 | } | ||
369 | else | ||
370 | { | ||
371 | iterator->struct_ref++; | ||
372 | engine_ref_debug(iterator, 0, 1) | ||
373 | } | ||
374 | } | ||
375 | CRYPTO_r_unlock(CRYPTO_LOCK_ENGINE); | ||
376 | if(iterator == NULL) | ||
377 | { | ||
378 | ENGINEerr(ENGINE_F_ENGINE_BY_ID, | ||
379 | ENGINE_R_NO_SUCH_ENGINE); | ||
380 | ERR_add_error_data(2, "id=", id); | ||
381 | } | ||
382 | return iterator; | ||
383 | } | ||
diff --git a/src/lib/libcrypto/engine/eng_openssl.c b/src/lib/libcrypto/engine/eng_openssl.c new file mode 100644 index 0000000000..e9d976f46b --- /dev/null +++ b/src/lib/libcrypto/engine/eng_openssl.c | |||
@@ -0,0 +1,347 @@ | |||
1 | /* crypto/engine/eng_openssl.c */ | ||
2 | /* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL | ||
3 | * project 2000. | ||
4 | */ | ||
5 | /* ==================================================================== | ||
6 | * Copyright (c) 1999-2001 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 <openssl/crypto.h> | ||
62 | #include "cryptlib.h" | ||
63 | #include <openssl/engine.h> | ||
64 | #include <openssl/dso.h> | ||
65 | #include <openssl/pem.h> | ||
66 | |||
67 | /* This testing gunk is implemented (and explained) lower down. It also assumes | ||
68 | * the application explicitly calls "ENGINE_load_openssl()" because this is no | ||
69 | * longer automatic in ENGINE_load_builtin_engines(). */ | ||
70 | #define TEST_ENG_OPENSSL_RC4 | ||
71 | #define TEST_ENG_OPENSSL_PKEY | ||
72 | /* #define TEST_ENG_OPENSSL_RC4_OTHERS */ | ||
73 | #define TEST_ENG_OPENSSL_RC4_P_INIT | ||
74 | /* #define TEST_ENG_OPENSSL_RC4_P_CIPHER */ | ||
75 | #define TEST_ENG_OPENSSL_SHA | ||
76 | /* #define TEST_ENG_OPENSSL_SHA_OTHERS */ | ||
77 | /* #define TEST_ENG_OPENSSL_SHA_P_INIT */ | ||
78 | /* #define TEST_ENG_OPENSSL_SHA_P_UPDATE */ | ||
79 | /* #define TEST_ENG_OPENSSL_SHA_P_FINAL */ | ||
80 | |||
81 | #ifdef TEST_ENG_OPENSSL_RC4 | ||
82 | static int openssl_ciphers(ENGINE *e, const EVP_CIPHER **cipher, | ||
83 | const int **nids, int nid); | ||
84 | #endif | ||
85 | #ifdef TEST_ENG_OPENSSL_SHA | ||
86 | static int openssl_digests(ENGINE *e, const EVP_MD **digest, | ||
87 | const int **nids, int nid); | ||
88 | #endif | ||
89 | |||
90 | #ifdef TEST_ENG_OPENSSL_PKEY | ||
91 | static EVP_PKEY *openssl_load_privkey(ENGINE *eng, const char *key_id, | ||
92 | UI_METHOD *ui_method, void *callback_data); | ||
93 | #endif | ||
94 | |||
95 | /* The constants used when creating the ENGINE */ | ||
96 | static const char *engine_openssl_id = "openssl"; | ||
97 | static const char *engine_openssl_name = "Software engine support"; | ||
98 | |||
99 | /* This internal function is used by ENGINE_openssl() and possibly by the | ||
100 | * "dynamic" ENGINE support too */ | ||
101 | static int bind_helper(ENGINE *e) | ||
102 | { | ||
103 | if(!ENGINE_set_id(e, engine_openssl_id) | ||
104 | || !ENGINE_set_name(e, engine_openssl_name) | ||
105 | #ifndef TEST_ENG_OPENSSL_NO_ALGORITHMS | ||
106 | #ifndef OPENSSL_NO_RSA | ||
107 | || !ENGINE_set_RSA(e, RSA_get_default_method()) | ||
108 | #endif | ||
109 | #ifndef OPENSSL_NO_DSA | ||
110 | || !ENGINE_set_DSA(e, DSA_get_default_method()) | ||
111 | #endif | ||
112 | #ifndef OPENSSL_NO_DH | ||
113 | || !ENGINE_set_DH(e, DH_get_default_method()) | ||
114 | #endif | ||
115 | || !ENGINE_set_RAND(e, RAND_SSLeay()) | ||
116 | #ifdef TEST_ENG_OPENSSL_RC4 | ||
117 | || !ENGINE_set_ciphers(e, openssl_ciphers) | ||
118 | #endif | ||
119 | #ifdef TEST_ENG_OPENSSL_SHA | ||
120 | || !ENGINE_set_digests(e, openssl_digests) | ||
121 | #endif | ||
122 | #endif | ||
123 | #ifdef TEST_ENG_OPENSSL_PKEY | ||
124 | || !ENGINE_set_load_privkey_function(e, openssl_load_privkey) | ||
125 | #endif | ||
126 | ) | ||
127 | return 0; | ||
128 | /* If we add errors to this ENGINE, ensure the error handling is setup here */ | ||
129 | /* openssl_load_error_strings(); */ | ||
130 | return 1; | ||
131 | } | ||
132 | |||
133 | static ENGINE *engine_openssl(void) | ||
134 | { | ||
135 | ENGINE *ret = ENGINE_new(); | ||
136 | if(!ret) | ||
137 | return NULL; | ||
138 | if(!bind_helper(ret)) | ||
139 | { | ||
140 | ENGINE_free(ret); | ||
141 | return NULL; | ||
142 | } | ||
143 | return ret; | ||
144 | } | ||
145 | |||
146 | void ENGINE_load_openssl(void) | ||
147 | { | ||
148 | ENGINE *toadd = engine_openssl(); | ||
149 | if(!toadd) return; | ||
150 | ENGINE_add(toadd); | ||
151 | /* If the "add" worked, it gets a structural reference. So either way, | ||
152 | * we release our just-created reference. */ | ||
153 | ENGINE_free(toadd); | ||
154 | ERR_clear_error(); | ||
155 | } | ||
156 | |||
157 | /* This stuff is needed if this ENGINE is being compiled into a self-contained | ||
158 | * shared-library. */ | ||
159 | #ifdef ENGINE_DYNAMIC_SUPPORT | ||
160 | static int bind_fn(ENGINE *e, const char *id) | ||
161 | { | ||
162 | if(id && (strcmp(id, engine_openssl_id) != 0)) | ||
163 | return 0; | ||
164 | if(!bind_helper(e)) | ||
165 | return 0; | ||
166 | return 1; | ||
167 | } | ||
168 | IMPLEMENT_DYNAMIC_CHECK_FN() | ||
169 | IMPLEMENT_DYNAMIC_BIND_FN(bind_fn) | ||
170 | #endif /* ENGINE_DYNAMIC_SUPPORT */ | ||
171 | |||
172 | #ifdef TEST_ENG_OPENSSL_RC4 | ||
173 | /* This section of code compiles an "alternative implementation" of two modes of | ||
174 | * RC4 into this ENGINE. The result is that EVP_CIPHER operation for "rc4" | ||
175 | * should under normal circumstances go via this support rather than the default | ||
176 | * EVP support. There are other symbols to tweak the testing; | ||
177 | * TEST_ENC_OPENSSL_RC4_OTHERS - print a one line message to stderr each time | ||
178 | * we're asked for a cipher we don't support (should not happen). | ||
179 | * TEST_ENG_OPENSSL_RC4_P_INIT - print a one line message to stderr each time | ||
180 | * the "init_key" handler is called. | ||
181 | * TEST_ENG_OPENSSL_RC4_P_CIPHER - ditto for the "cipher" handler. | ||
182 | */ | ||
183 | #include <openssl/evp.h> | ||
184 | #include <openssl/rc4.h> | ||
185 | #define TEST_RC4_KEY_SIZE 16 | ||
186 | static int test_cipher_nids[] = {NID_rc4,NID_rc4_40}; | ||
187 | static int test_cipher_nids_number = 2; | ||
188 | typedef struct { | ||
189 | unsigned char key[TEST_RC4_KEY_SIZE]; | ||
190 | RC4_KEY ks; | ||
191 | } TEST_RC4_KEY; | ||
192 | #define test(ctx) ((TEST_RC4_KEY *)(ctx)->cipher_data) | ||
193 | static int test_rc4_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, | ||
194 | const unsigned char *iv, int enc) | ||
195 | { | ||
196 | #ifdef TEST_ENG_OPENSSL_RC4_P_INIT | ||
197 | fprintf(stderr, "(TEST_ENG_OPENSSL_RC4) test_init_key() called\n"); | ||
198 | #endif | ||
199 | memcpy(&test(ctx)->key[0],key,EVP_CIPHER_CTX_key_length(ctx)); | ||
200 | RC4_set_key(&test(ctx)->ks,EVP_CIPHER_CTX_key_length(ctx), | ||
201 | test(ctx)->key); | ||
202 | return 1; | ||
203 | } | ||
204 | static int test_rc4_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, | ||
205 | const unsigned char *in, unsigned int inl) | ||
206 | { | ||
207 | #ifdef TEST_ENG_OPENSSL_RC4_P_CIPHER | ||
208 | fprintf(stderr, "(TEST_ENG_OPENSSL_RC4) test_cipher() called\n"); | ||
209 | #endif | ||
210 | RC4(&test(ctx)->ks,inl,in,out); | ||
211 | return 1; | ||
212 | } | ||
213 | static const EVP_CIPHER test_r4_cipher= | ||
214 | { | ||
215 | NID_rc4, | ||
216 | 1,TEST_RC4_KEY_SIZE,0, | ||
217 | EVP_CIPH_VARIABLE_LENGTH, | ||
218 | test_rc4_init_key, | ||
219 | test_rc4_cipher, | ||
220 | NULL, | ||
221 | sizeof(TEST_RC4_KEY), | ||
222 | NULL, | ||
223 | NULL, | ||
224 | NULL | ||
225 | }; | ||
226 | static const EVP_CIPHER test_r4_40_cipher= | ||
227 | { | ||
228 | NID_rc4_40, | ||
229 | 1,5 /* 40 bit */,0, | ||
230 | EVP_CIPH_VARIABLE_LENGTH, | ||
231 | test_rc4_init_key, | ||
232 | test_rc4_cipher, | ||
233 | NULL, | ||
234 | sizeof(TEST_RC4_KEY), | ||
235 | NULL, | ||
236 | NULL, | ||
237 | NULL | ||
238 | }; | ||
239 | static int openssl_ciphers(ENGINE *e, const EVP_CIPHER **cipher, | ||
240 | const int **nids, int nid) | ||
241 | { | ||
242 | if(!cipher) | ||
243 | { | ||
244 | /* We are returning a list of supported nids */ | ||
245 | *nids = test_cipher_nids; | ||
246 | return test_cipher_nids_number; | ||
247 | } | ||
248 | /* We are being asked for a specific cipher */ | ||
249 | if(nid == NID_rc4) | ||
250 | *cipher = &test_r4_cipher; | ||
251 | else if(nid == NID_rc4_40) | ||
252 | *cipher = &test_r4_40_cipher; | ||
253 | else | ||
254 | { | ||
255 | #ifdef TEST_ENG_OPENSSL_RC4_OTHERS | ||
256 | fprintf(stderr, "(TEST_ENG_OPENSSL_RC4) returning NULL for " | ||
257 | "nid %d\n", nid); | ||
258 | #endif | ||
259 | *cipher = NULL; | ||
260 | return 0; | ||
261 | } | ||
262 | return 1; | ||
263 | } | ||
264 | #endif | ||
265 | |||
266 | #ifdef TEST_ENG_OPENSSL_SHA | ||
267 | /* Much the same sort of comment as for TEST_ENG_OPENSSL_RC4 */ | ||
268 | #include <openssl/evp.h> | ||
269 | #include <openssl/sha.h> | ||
270 | static int test_digest_nids[] = {NID_sha1}; | ||
271 | static int test_digest_nids_number = 1; | ||
272 | static int test_sha1_init(EVP_MD_CTX *ctx) | ||
273 | { | ||
274 | #ifdef TEST_ENG_OPENSSL_SHA_P_INIT | ||
275 | fprintf(stderr, "(TEST_ENG_OPENSSL_SHA) test_sha1_init() called\n"); | ||
276 | #endif | ||
277 | return SHA1_Init(ctx->md_data); | ||
278 | } | ||
279 | static int test_sha1_update(EVP_MD_CTX *ctx,const void *data,unsigned long count) | ||
280 | { | ||
281 | #ifdef TEST_ENG_OPENSSL_SHA_P_UPDATE | ||
282 | fprintf(stderr, "(TEST_ENG_OPENSSL_SHA) test_sha1_update() called\n"); | ||
283 | #endif | ||
284 | return SHA1_Update(ctx->md_data,data,count); | ||
285 | } | ||
286 | static int test_sha1_final(EVP_MD_CTX *ctx,unsigned char *md) | ||
287 | { | ||
288 | #ifdef TEST_ENG_OPENSSL_SHA_P_FINAL | ||
289 | fprintf(stderr, "(TEST_ENG_OPENSSL_SHA) test_sha1_final() called\n"); | ||
290 | #endif | ||
291 | return SHA1_Final(md,ctx->md_data); | ||
292 | } | ||
293 | static const EVP_MD test_sha_md= | ||
294 | { | ||
295 | NID_sha1, | ||
296 | NID_sha1WithRSAEncryption, | ||
297 | SHA_DIGEST_LENGTH, | ||
298 | 0, | ||
299 | test_sha1_init, | ||
300 | test_sha1_update, | ||
301 | test_sha1_final, | ||
302 | NULL, | ||
303 | NULL, | ||
304 | EVP_PKEY_RSA_method, | ||
305 | SHA_CBLOCK, | ||
306 | sizeof(EVP_MD *)+sizeof(SHA_CTX), | ||
307 | }; | ||
308 | static int openssl_digests(ENGINE *e, const EVP_MD **digest, | ||
309 | const int **nids, int nid) | ||
310 | { | ||
311 | if(!digest) | ||
312 | { | ||
313 | /* We are returning a list of supported nids */ | ||
314 | *nids = test_digest_nids; | ||
315 | return test_digest_nids_number; | ||
316 | } | ||
317 | /* We are being asked for a specific digest */ | ||
318 | if(nid == NID_sha1) | ||
319 | *digest = &test_sha_md; | ||
320 | else | ||
321 | { | ||
322 | #ifdef TEST_ENG_OPENSSL_SHA_OTHERS | ||
323 | fprintf(stderr, "(TEST_ENG_OPENSSL_SHA) returning NULL for " | ||
324 | "nid %d\n", nid); | ||
325 | #endif | ||
326 | *digest = NULL; | ||
327 | return 0; | ||
328 | } | ||
329 | return 1; | ||
330 | } | ||
331 | #endif | ||
332 | |||
333 | #ifdef TEST_ENG_OPENSSL_PKEY | ||
334 | static EVP_PKEY *openssl_load_privkey(ENGINE *eng, const char *key_id, | ||
335 | UI_METHOD *ui_method, void *callback_data) | ||
336 | { | ||
337 | BIO *in; | ||
338 | EVP_PKEY *key; | ||
339 | fprintf(stderr, "(TEST_ENG_OPENSSL_PKEY)Loading Private key %s\n", key_id); | ||
340 | in = BIO_new_file(key_id, "r"); | ||
341 | if (!in) | ||
342 | return NULL; | ||
343 | key = PEM_read_bio_PrivateKey(in, NULL, 0, NULL); | ||
344 | BIO_free(in); | ||
345 | return key; | ||
346 | } | ||
347 | #endif | ||
diff --git a/src/lib/libcrypto/engine/eng_pkey.c b/src/lib/libcrypto/engine/eng_pkey.c new file mode 100644 index 0000000000..8c69171511 --- /dev/null +++ b/src/lib/libcrypto/engine/eng_pkey.c | |||
@@ -0,0 +1,157 @@ | |||
1 | /* crypto/engine/eng_pkey.c */ | ||
2 | /* ==================================================================== | ||
3 | * Copyright (c) 1999-2001 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 <openssl/crypto.h> | ||
57 | #include "cryptlib.h" | ||
58 | #include "eng_int.h" | ||
59 | #include <openssl/engine.h> | ||
60 | |||
61 | /* Basic get/set stuff */ | ||
62 | |||
63 | int ENGINE_set_load_privkey_function(ENGINE *e, ENGINE_LOAD_KEY_PTR loadpriv_f) | ||
64 | { | ||
65 | e->load_privkey = loadpriv_f; | ||
66 | return 1; | ||
67 | } | ||
68 | |||
69 | int ENGINE_set_load_pubkey_function(ENGINE *e, ENGINE_LOAD_KEY_PTR loadpub_f) | ||
70 | { | ||
71 | e->load_pubkey = loadpub_f; | ||
72 | return 1; | ||
73 | } | ||
74 | |||
75 | ENGINE_LOAD_KEY_PTR ENGINE_get_load_privkey_function(const ENGINE *e) | ||
76 | { | ||
77 | return e->load_privkey; | ||
78 | } | ||
79 | |||
80 | ENGINE_LOAD_KEY_PTR ENGINE_get_load_pubkey_function(const ENGINE *e) | ||
81 | { | ||
82 | return e->load_pubkey; | ||
83 | } | ||
84 | |||
85 | /* API functions to load public/private keys */ | ||
86 | |||
87 | EVP_PKEY *ENGINE_load_private_key(ENGINE *e, const char *key_id, | ||
88 | UI_METHOD *ui_method, void *callback_data) | ||
89 | { | ||
90 | EVP_PKEY *pkey; | ||
91 | |||
92 | if(e == NULL) | ||
93 | { | ||
94 | ENGINEerr(ENGINE_F_ENGINE_LOAD_PRIVATE_KEY, | ||
95 | ERR_R_PASSED_NULL_PARAMETER); | ||
96 | return 0; | ||
97 | } | ||
98 | CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); | ||
99 | if(e->funct_ref == 0) | ||
100 | { | ||
101 | CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); | ||
102 | ENGINEerr(ENGINE_F_ENGINE_LOAD_PRIVATE_KEY, | ||
103 | ENGINE_R_NOT_INITIALISED); | ||
104 | return 0; | ||
105 | } | ||
106 | CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); | ||
107 | if (!e->load_privkey) | ||
108 | { | ||
109 | ENGINEerr(ENGINE_F_ENGINE_LOAD_PRIVATE_KEY, | ||
110 | ENGINE_R_NO_LOAD_FUNCTION); | ||
111 | return 0; | ||
112 | } | ||
113 | pkey = e->load_privkey(e, key_id, ui_method, callback_data); | ||
114 | if (!pkey) | ||
115 | { | ||
116 | ENGINEerr(ENGINE_F_ENGINE_LOAD_PRIVATE_KEY, | ||
117 | ENGINE_R_FAILED_LOADING_PRIVATE_KEY); | ||
118 | return 0; | ||
119 | } | ||
120 | return pkey; | ||
121 | } | ||
122 | |||
123 | EVP_PKEY *ENGINE_load_public_key(ENGINE *e, const char *key_id, | ||
124 | UI_METHOD *ui_method, void *callback_data) | ||
125 | { | ||
126 | EVP_PKEY *pkey; | ||
127 | |||
128 | if(e == NULL) | ||
129 | { | ||
130 | ENGINEerr(ENGINE_F_ENGINE_LOAD_PUBLIC_KEY, | ||
131 | ERR_R_PASSED_NULL_PARAMETER); | ||
132 | return 0; | ||
133 | } | ||
134 | CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); | ||
135 | if(e->funct_ref == 0) | ||
136 | { | ||
137 | CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); | ||
138 | ENGINEerr(ENGINE_F_ENGINE_LOAD_PUBLIC_KEY, | ||
139 | ENGINE_R_NOT_INITIALISED); | ||
140 | return 0; | ||
141 | } | ||
142 | CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); | ||
143 | if (!e->load_pubkey) | ||
144 | { | ||
145 | ENGINEerr(ENGINE_F_ENGINE_LOAD_PUBLIC_KEY, | ||
146 | ENGINE_R_NO_LOAD_FUNCTION); | ||
147 | return 0; | ||
148 | } | ||
149 | pkey = e->load_pubkey(e, key_id, ui_method, callback_data); | ||
150 | if (!pkey) | ||
151 | { | ||
152 | ENGINEerr(ENGINE_F_ENGINE_LOAD_PUBLIC_KEY, | ||
153 | ENGINE_R_FAILED_LOADING_PUBLIC_KEY); | ||
154 | return 0; | ||
155 | } | ||
156 | return pkey; | ||
157 | } | ||
diff --git a/src/lib/libcrypto/engine/eng_table.c b/src/lib/libcrypto/engine/eng_table.c new file mode 100644 index 0000000000..c69a84a8bf --- /dev/null +++ b/src/lib/libcrypto/engine/eng_table.c | |||
@@ -0,0 +1,361 @@ | |||
1 | /* ==================================================================== | ||
2 | * Copyright (c) 2001 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 <openssl/evp.h> | ||
56 | #include <openssl/engine.h> | ||
57 | #include "eng_int.h" | ||
58 | |||
59 | /* This is the type of item in the 'implementation' table. Each 'nid' hashes to | ||
60 | * a (potentially NULL) ENGINE_PILE structure which contains a stack of ENGINE* | ||
61 | * pointers. These pointers aren't references, because they're inserted and | ||
62 | * removed during ENGINE creation and ENGINE destruction. They point to ENGINEs | ||
63 | * that *exist* (ie. have a structural reference count greater than zero) rather | ||
64 | * than ENGINEs that are *functional*. Each pointer in those stacks are to | ||
65 | * ENGINEs that implements the algorithm corresponding to each 'nid'. */ | ||
66 | |||
67 | /* The type of the items in the table */ | ||
68 | typedef struct st_engine_pile | ||
69 | { | ||
70 | /* The 'nid' of the algorithm/mode this ENGINE_PILE structure represents | ||
71 | * */ | ||
72 | int nid; | ||
73 | /* A stack of ENGINE pointers for ENGINEs that support this | ||
74 | * algorithm/mode. In the event that 'funct' is NULL, the first entry in | ||
75 | * this stack that initialises will be set as 'funct' and assumed as the | ||
76 | * default for operations of this type. */ | ||
77 | STACK_OF(ENGINE) *sk; | ||
78 | /* The default ENGINE to perform this algorithm/mode. */ | ||
79 | ENGINE *funct; | ||
80 | /* This value optimises engine_table_select(). If it is called it sets | ||
81 | * this value to 1. Any changes to this ENGINE_PILE resets it to zero. | ||
82 | * As such, no ENGINE_init() thrashing is done unless ENGINEs | ||
83 | * continually register (and/or unregister). */ | ||
84 | int uptodate; | ||
85 | } ENGINE_PILE; | ||
86 | |||
87 | /* The type of the hash table of ENGINE_PILE structures such that each are | ||
88 | * unique and keyed by the 'nid' value. */ | ||
89 | struct st_engine_table | ||
90 | { | ||
91 | LHASH piles; | ||
92 | }; /* ENGINE_TABLE */ | ||
93 | |||
94 | /* This value stores global options controlling behaviour of (mostly) the | ||
95 | * engine_table_select() function. It's a bitmask of flag values of the form | ||
96 | * ENGINE_TABLE_FLAG_*** (as defined in engine.h) and is controlled by the | ||
97 | * ENGINE_[get|set]_table_flags() function. */ | ||
98 | static unsigned int table_flags = 0; | ||
99 | |||
100 | /* API function manipulating 'table_flags' */ | ||
101 | unsigned int ENGINE_get_table_flags(void) | ||
102 | { | ||
103 | return table_flags; | ||
104 | } | ||
105 | void ENGINE_set_table_flags(unsigned int flags) | ||
106 | { | ||
107 | table_flags = flags; | ||
108 | } | ||
109 | |||
110 | /* Internal functions for the "piles" hash table */ | ||
111 | static unsigned long engine_pile_hash(const ENGINE_PILE *c) | ||
112 | { | ||
113 | return c->nid; | ||
114 | } | ||
115 | static int engine_pile_cmp(const ENGINE_PILE *a, const ENGINE_PILE *b) | ||
116 | { | ||
117 | return a->nid - b->nid; | ||
118 | } | ||
119 | static IMPLEMENT_LHASH_HASH_FN(engine_pile_hash, const ENGINE_PILE *) | ||
120 | static IMPLEMENT_LHASH_COMP_FN(engine_pile_cmp, const ENGINE_PILE *) | ||
121 | static int int_table_check(ENGINE_TABLE **t, int create) | ||
122 | { | ||
123 | LHASH *lh; | ||
124 | if(*t) | ||
125 | return 1; | ||
126 | if(!create) | ||
127 | return 0; | ||
128 | if((lh = lh_new(LHASH_HASH_FN(engine_pile_hash), | ||
129 | LHASH_COMP_FN(engine_pile_cmp))) == NULL) | ||
130 | return 0; | ||
131 | *t = (ENGINE_TABLE *)lh; | ||
132 | return 1; | ||
133 | } | ||
134 | |||
135 | /* Privately exposed (via eng_int.h) functions for adding and/or removing | ||
136 | * ENGINEs from the implementation table */ | ||
137 | int engine_table_register(ENGINE_TABLE **table, ENGINE_CLEANUP_CB *cleanup, | ||
138 | ENGINE *e, const int *nids, int num_nids, int setdefault) | ||
139 | { | ||
140 | int ret = 0, added = 0; | ||
141 | ENGINE_PILE tmplate, *fnd; | ||
142 | CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); | ||
143 | if(!(*table)) | ||
144 | added = 1; | ||
145 | if(!int_table_check(table, 1)) | ||
146 | goto end; | ||
147 | if(added) | ||
148 | /* The cleanup callback needs to be added */ | ||
149 | engine_cleanup_add_first(cleanup); | ||
150 | while(num_nids--) | ||
151 | { | ||
152 | tmplate.nid = *nids; | ||
153 | fnd = lh_retrieve(&(*table)->piles, &tmplate); | ||
154 | if(!fnd) | ||
155 | { | ||
156 | fnd = OPENSSL_malloc(sizeof(ENGINE_PILE)); | ||
157 | if(!fnd) | ||
158 | goto end; | ||
159 | fnd->uptodate = 1; | ||
160 | fnd->nid = *nids; | ||
161 | fnd->sk = sk_ENGINE_new_null(); | ||
162 | if(!fnd->sk) | ||
163 | { | ||
164 | OPENSSL_free(fnd); | ||
165 | goto end; | ||
166 | } | ||
167 | fnd->funct= NULL; | ||
168 | lh_insert(&(*table)->piles, fnd); | ||
169 | } | ||
170 | /* A registration shouldn't add duplciate entries */ | ||
171 | sk_ENGINE_delete_ptr(fnd->sk, e); | ||
172 | /* if 'setdefault', this ENGINE goes to the head of the list */ | ||
173 | if(!sk_ENGINE_push(fnd->sk, e)) | ||
174 | goto end; | ||
175 | /* "touch" this ENGINE_PILE */ | ||
176 | fnd->uptodate = 0; | ||
177 | if(setdefault) | ||
178 | { | ||
179 | if(!engine_unlocked_init(e)) | ||
180 | { | ||
181 | ENGINEerr(ENGINE_F_ENGINE_TABLE_REGISTER, | ||
182 | ENGINE_R_INIT_FAILED); | ||
183 | goto end; | ||
184 | } | ||
185 | if(fnd->funct) | ||
186 | engine_unlocked_finish(fnd->funct, 0); | ||
187 | fnd->funct = e; | ||
188 | } | ||
189 | nids++; | ||
190 | } | ||
191 | ret = 1; | ||
192 | end: | ||
193 | CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); | ||
194 | return ret; | ||
195 | } | ||
196 | static void int_unregister_cb(ENGINE_PILE *pile, ENGINE *e) | ||
197 | { | ||
198 | int n; | ||
199 | /* Iterate the 'c->sk' stack removing any occurance of 'e' */ | ||
200 | while((n = sk_ENGINE_find(pile->sk, e)) >= 0) | ||
201 | { | ||
202 | sk_ENGINE_delete(pile->sk, n); | ||
203 | /* "touch" this ENGINE_CIPHER */ | ||
204 | pile->uptodate = 0; | ||
205 | } | ||
206 | if(pile->funct == e) | ||
207 | { | ||
208 | engine_unlocked_finish(e, 0); | ||
209 | pile->funct = NULL; | ||
210 | } | ||
211 | } | ||
212 | static IMPLEMENT_LHASH_DOALL_ARG_FN(int_unregister_cb,ENGINE_PILE *,ENGINE *) | ||
213 | void engine_table_unregister(ENGINE_TABLE **table, ENGINE *e) | ||
214 | { | ||
215 | CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); | ||
216 | if(int_table_check(table, 0)) | ||
217 | lh_doall_arg(&(*table)->piles, | ||
218 | LHASH_DOALL_ARG_FN(int_unregister_cb), e); | ||
219 | CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); | ||
220 | } | ||
221 | |||
222 | static void int_cleanup_cb(ENGINE_PILE *p) | ||
223 | { | ||
224 | sk_ENGINE_free(p->sk); | ||
225 | if(p->funct) | ||
226 | engine_unlocked_finish(p->funct, 0); | ||
227 | OPENSSL_free(p); | ||
228 | } | ||
229 | static IMPLEMENT_LHASH_DOALL_FN(int_cleanup_cb,ENGINE_PILE *) | ||
230 | void engine_table_cleanup(ENGINE_TABLE **table) | ||
231 | { | ||
232 | CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); | ||
233 | if(*table) | ||
234 | { | ||
235 | lh_doall(&(*table)->piles, LHASH_DOALL_FN(int_cleanup_cb)); | ||
236 | lh_free(&(*table)->piles); | ||
237 | *table = NULL; | ||
238 | } | ||
239 | CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); | ||
240 | } | ||
241 | |||
242 | /* Exposed API function to get a functional reference from the implementation | ||
243 | * table (ie. try to get a functional reference from the tabled structural | ||
244 | * references) for a given cipher 'nid' */ | ||
245 | #ifndef ENGINE_TABLE_DEBUG | ||
246 | ENGINE *engine_table_select(ENGINE_TABLE **table, int nid) | ||
247 | #else | ||
248 | ENGINE *engine_table_select_tmp(ENGINE_TABLE **table, int nid, const char *f, int l) | ||
249 | #endif | ||
250 | { | ||
251 | ENGINE *ret = NULL; | ||
252 | ENGINE_PILE tmplate, *fnd=NULL; | ||
253 | int initres, loop = 0; | ||
254 | |||
255 | /* If 'engine_ciphers' is NULL, then it's absolutely *sure* that no | ||
256 | * ENGINEs have registered any implementations! */ | ||
257 | if(!(*table)) | ||
258 | { | ||
259 | #ifdef ENGINE_TABLE_DEBUG | ||
260 | fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, no " | ||
261 | "registered for anything!\n", f, l, nid); | ||
262 | #endif | ||
263 | return NULL; | ||
264 | } | ||
265 | CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); | ||
266 | /* Check again inside the lock otherwise we could race against cleanup | ||
267 | * operations. But don't worry about a fprintf(stderr). */ | ||
268 | if(!int_table_check(table, 0)) | ||
269 | goto end; | ||
270 | tmplate.nid = nid; | ||
271 | fnd = lh_retrieve(&(*table)->piles, &tmplate); | ||
272 | if(!fnd) | ||
273 | goto end; | ||
274 | if(fnd->funct && engine_unlocked_init(fnd->funct)) | ||
275 | { | ||
276 | #ifdef ENGINE_TABLE_DEBUG | ||
277 | fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, using " | ||
278 | "ENGINE '%s' cached\n", f, l, nid, fnd->funct->id); | ||
279 | #endif | ||
280 | ret = fnd->funct; | ||
281 | goto end; | ||
282 | } | ||
283 | if(fnd->uptodate) | ||
284 | { | ||
285 | ret = fnd->funct; | ||
286 | goto end; | ||
287 | } | ||
288 | trynext: | ||
289 | ret = sk_ENGINE_value(fnd->sk, loop++); | ||
290 | if(!ret) | ||
291 | { | ||
292 | #ifdef ENGINE_TABLE_DEBUG | ||
293 | fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, no " | ||
294 | "registered implementations would initialise\n", | ||
295 | f, l, nid); | ||
296 | #endif | ||
297 | goto end; | ||
298 | } | ||
299 | #if 0 | ||
300 | /* Don't need to get a reference if we hold the lock. If the locking has | ||
301 | * to change in future, that would be different ... */ | ||
302 | ret->struct_ref++; engine_ref_debug(ret, 0, 1) | ||
303 | #endif | ||
304 | /* Try and initialise the ENGINE if it's already functional *or* if the | ||
305 | * ENGINE_TABLE_FLAG_NOINIT flag is not set. */ | ||
306 | if((ret->funct_ref > 0) || !(table_flags & ENGINE_TABLE_FLAG_NOINIT)) | ||
307 | initres = engine_unlocked_init(ret); | ||
308 | else | ||
309 | initres = 0; | ||
310 | #if 0 | ||
311 | /* Release the structural reference */ | ||
312 | ret->struct_ref--; engine_ref_debug(ret, 0, -1); | ||
313 | #endif | ||
314 | if(initres) | ||
315 | { | ||
316 | /* If we didn't have a default (functional reference) for this | ||
317 | * 'nid' (or we had one but for whatever reason we're now | ||
318 | * initialising a different one), use this opportunity to set | ||
319 | * 'funct'. */ | ||
320 | if((fnd->funct != ret) && engine_unlocked_init(ret)) | ||
321 | { | ||
322 | /* If there was a previous default we release it. */ | ||
323 | if(fnd->funct) | ||
324 | engine_unlocked_finish(fnd->funct, 0); | ||
325 | /* We got an extra functional reference for the | ||
326 | * per-'nid' default */ | ||
327 | fnd->funct = ret; | ||
328 | #ifdef ENGINE_TABLE_DEBUG | ||
329 | fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, " | ||
330 | "setting default to '%s'\n", f, l, nid, ret->id); | ||
331 | #endif | ||
332 | } | ||
333 | #ifdef ENGINE_TABLE_DEBUG | ||
334 | fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, using " | ||
335 | "newly initialised '%s'\n", f, l, nid, ret->id); | ||
336 | #endif | ||
337 | goto end; | ||
338 | } | ||
339 | goto trynext; | ||
340 | end: | ||
341 | /* Whatever happened - we should "untouch" our uptodate file seeing as | ||
342 | * we have tried our best to find a functional reference for 'nid'. If | ||
343 | * it failed, it is unlikely to succeed again until some future | ||
344 | * registrations (or unregistrations) have taken place that affect that | ||
345 | * 'nid'. */ | ||
346 | if(fnd) | ||
347 | fnd->uptodate = 1; | ||
348 | #ifdef ENGINE_TABLE_DEBUG | ||
349 | if(ret) | ||
350 | fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, caching " | ||
351 | "ENGINE '%s'\n", f, l, nid, ret->id); | ||
352 | else | ||
353 | fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, caching " | ||
354 | "'no matching ENGINE'\n", f, l, nid); | ||
355 | #endif | ||
356 | CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); | ||
357 | /* Whatever happened, any failed init()s are not failures in this | ||
358 | * context, so clear our error state. */ | ||
359 | ERR_clear_error(); | ||
360 | return ret; | ||
361 | } | ||
diff --git a/src/lib/libcrypto/engine/engine.h b/src/lib/libcrypto/engine/engine.h new file mode 100644 index 0000000000..2983f47034 --- /dev/null +++ b/src/lib/libcrypto/engine/engine.h | |||
@@ -0,0 +1,398 @@ | |||
1 | /* openssl/engine.h */ | ||
2 | /* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL | ||
3 | * project 2000. | ||
4 | */ | ||
5 | /* ==================================================================== | ||
6 | * Copyright (c) 1999 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_ENGINE_H | ||
60 | #define HEADER_ENGINE_H | ||
61 | |||
62 | #include <openssl/bn.h> | ||
63 | #include <openssl/rsa.h> | ||
64 | #include <openssl/dsa.h> | ||
65 | #include <openssl/dh.h> | ||
66 | #include <openssl/rand.h> | ||
67 | #include <openssl/evp.h> | ||
68 | #include <openssl/symhacks.h> | ||
69 | |||
70 | #ifdef __cplusplus | ||
71 | extern "C" { | ||
72 | #endif | ||
73 | |||
74 | /* These flags are used to control combinations of algorithm (methods) | ||
75 | * by bitwise "OR"ing. */ | ||
76 | #define ENGINE_METHOD_RSA (unsigned int)0x0001 | ||
77 | #define ENGINE_METHOD_DSA (unsigned int)0x0002 | ||
78 | #define ENGINE_METHOD_DH (unsigned int)0x0004 | ||
79 | #define ENGINE_METHOD_RAND (unsigned int)0x0008 | ||
80 | #define ENGINE_METHOD_BN_MOD_EXP (unsigned int)0x0010 | ||
81 | #define ENGINE_METHOD_BN_MOD_EXP_CRT (unsigned int)0x0020 | ||
82 | /* Obvious all-or-nothing cases. */ | ||
83 | #define ENGINE_METHOD_ALL (unsigned int)0xFFFF | ||
84 | #define ENGINE_METHOD_NONE (unsigned int)0x0000 | ||
85 | |||
86 | /* These flags are used to tell the ctrl function what should be done. | ||
87 | * All command numbers are shared between all engines, even if some don't | ||
88 | * make sense to some engines. In such a case, they do nothing but return | ||
89 | * the error ENGINE_R_CTRL_COMMAND_NOT_IMPLEMENTED. */ | ||
90 | #define ENGINE_CTRL_SET_LOGSTREAM 1 | ||
91 | #define ENGINE_CTRL_SET_PASSWORD_CALLBACK 2 | ||
92 | /* Flags specific to the nCipher "chil" engine */ | ||
93 | #define ENGINE_CTRL_CHIL_SET_FORKCHECK 100 | ||
94 | /* Depending on the value of the (long)i argument, this sets or | ||
95 | * unsets the SimpleForkCheck flag in the CHIL API to enable or | ||
96 | * disable checking and workarounds for applications that fork(). | ||
97 | */ | ||
98 | #define ENGINE_CTRL_CHIL_NO_LOCKING 101 | ||
99 | /* This prevents the initialisation function from providing mutex | ||
100 | * callbacks to the nCipher library. */ | ||
101 | |||
102 | /* As we're missing a BIGNUM_METHOD, we need a couple of locally | ||
103 | * defined function types that engines can implement. */ | ||
104 | |||
105 | #ifndef HEADER_ENGINE_INT_H | ||
106 | /* mod_exp operation, calculates; r = a ^ p mod m | ||
107 | * NB: ctx can be NULL, but if supplied, the implementation may use | ||
108 | * it if it wishes. */ | ||
109 | typedef int (*BN_MOD_EXP)(BIGNUM *r, BIGNUM *a, const BIGNUM *p, | ||
110 | const BIGNUM *m, BN_CTX *ctx); | ||
111 | |||
112 | /* private key operation for RSA, provided seperately in case other | ||
113 | * RSA implementations wish to use it. */ | ||
114 | typedef int (*BN_MOD_EXP_CRT)(BIGNUM *r, BIGNUM *a, const BIGNUM *p, | ||
115 | const BIGNUM *q, const BIGNUM *dmp1, const BIGNUM *dmq1, | ||
116 | const BIGNUM *iqmp, BN_CTX *ctx); | ||
117 | |||
118 | /* Generic function pointer */ | ||
119 | typedef void (*ENGINE_GEN_FUNC_PTR)(); | ||
120 | /* Generic function pointer taking no arguments */ | ||
121 | typedef void (*ENGINE_GEN_INT_FUNC_PTR)(void); | ||
122 | /* Specific control function pointer */ | ||
123 | typedef int (*ENGINE_CTRL_FUNC_PTR)(int cmd, long i, void *p, void (*f)()); | ||
124 | |||
125 | /* The list of "engine" types is a static array of (const ENGINE*) | ||
126 | * pointers (not dynamic because static is fine for now and we otherwise | ||
127 | * have to hook an appropriate load/unload function in to initialise and | ||
128 | * cleanup). */ | ||
129 | typedef struct engine_st ENGINE; | ||
130 | #endif | ||
131 | |||
132 | /* STRUCTURE functions ... all of these functions deal with pointers to | ||
133 | * ENGINE structures where the pointers have a "structural reference". | ||
134 | * This means that their reference is to allow access to the structure | ||
135 | * but it does not imply that the structure is functional. To simply | ||
136 | * increment or decrement the structural reference count, use ENGINE_new | ||
137 | * and ENGINE_free. NB: This is not required when iterating using | ||
138 | * ENGINE_get_next as it will automatically decrement the structural | ||
139 | * reference count of the "current" ENGINE and increment the structural | ||
140 | * reference count of the ENGINE it returns (unless it is NULL). */ | ||
141 | |||
142 | /* Get the first/last "ENGINE" type available. */ | ||
143 | ENGINE *ENGINE_get_first(void); | ||
144 | ENGINE *ENGINE_get_last(void); | ||
145 | /* Iterate to the next/previous "ENGINE" type (NULL = end of the list). */ | ||
146 | ENGINE *ENGINE_get_next(ENGINE *e); | ||
147 | ENGINE *ENGINE_get_prev(ENGINE *e); | ||
148 | /* Add another "ENGINE" type into the array. */ | ||
149 | int ENGINE_add(ENGINE *e); | ||
150 | /* Remove an existing "ENGINE" type from the array. */ | ||
151 | int ENGINE_remove(ENGINE *e); | ||
152 | /* Retrieve an engine from the list by its unique "id" value. */ | ||
153 | ENGINE *ENGINE_by_id(const char *id); | ||
154 | |||
155 | /* These functions are useful for manufacturing new ENGINE | ||
156 | * structures. They don't address reference counting at all - | ||
157 | * one uses them to populate an ENGINE structure with personalised | ||
158 | * implementations of things prior to using it directly or adding | ||
159 | * it to the builtin ENGINE list in OpenSSL. These are also here | ||
160 | * so that the ENGINE structure doesn't have to be exposed and | ||
161 | * break binary compatibility! | ||
162 | * | ||
163 | * NB: I'm changing ENGINE_new to force the ENGINE structure to | ||
164 | * be allocated from within OpenSSL. See the comment for | ||
165 | * ENGINE_get_struct_size(). | ||
166 | */ | ||
167 | #if 0 | ||
168 | ENGINE *ENGINE_new(ENGINE *e); | ||
169 | #else | ||
170 | ENGINE *ENGINE_new(void); | ||
171 | #endif | ||
172 | int ENGINE_free(ENGINE *e); | ||
173 | int ENGINE_set_id(ENGINE *e, const char *id); | ||
174 | int ENGINE_set_name(ENGINE *e, const char *name); | ||
175 | int ENGINE_set_RSA(ENGINE *e, RSA_METHOD *rsa_meth); | ||
176 | int ENGINE_set_DSA(ENGINE *e, DSA_METHOD *dsa_meth); | ||
177 | int ENGINE_set_DH(ENGINE *e, DH_METHOD *dh_meth); | ||
178 | int ENGINE_set_RAND(ENGINE *e, RAND_METHOD *rand_meth); | ||
179 | int ENGINE_set_BN_mod_exp(ENGINE *e, BN_MOD_EXP bn_mod_exp); | ||
180 | int ENGINE_set_BN_mod_exp_crt(ENGINE *e, BN_MOD_EXP_CRT bn_mod_exp_crt); | ||
181 | int ENGINE_set_init_function(ENGINE *e, ENGINE_GEN_INT_FUNC_PTR init_f); | ||
182 | int ENGINE_set_finish_function(ENGINE *e, ENGINE_GEN_INT_FUNC_PTR finish_f); | ||
183 | int ENGINE_set_ctrl_function(ENGINE *e, ENGINE_CTRL_FUNC_PTR ctrl_f); | ||
184 | |||
185 | /* These return values from within the ENGINE structure. These can | ||
186 | * be useful with functional references as well as structural | ||
187 | * references - it depends which you obtained. Using the result | ||
188 | * for functional purposes if you only obtained a structural | ||
189 | * reference may be problematic! */ | ||
190 | const char *ENGINE_get_id(ENGINE *e); | ||
191 | const char *ENGINE_get_name(ENGINE *e); | ||
192 | RSA_METHOD *ENGINE_get_RSA(ENGINE *e); | ||
193 | DSA_METHOD *ENGINE_get_DSA(ENGINE *e); | ||
194 | DH_METHOD *ENGINE_get_DH(ENGINE *e); | ||
195 | RAND_METHOD *ENGINE_get_RAND(ENGINE *e); | ||
196 | BN_MOD_EXP ENGINE_get_BN_mod_exp(ENGINE *e); | ||
197 | BN_MOD_EXP_CRT ENGINE_get_BN_mod_exp_crt(ENGINE *e); | ||
198 | ENGINE_GEN_INT_FUNC_PTR ENGINE_get_init_function(ENGINE *e); | ||
199 | ENGINE_GEN_INT_FUNC_PTR ENGINE_get_finish_function(ENGINE *e); | ||
200 | ENGINE_CTRL_FUNC_PTR ENGINE_get_ctrl_function(ENGINE *e); | ||
201 | |||
202 | /* ENGINE_new is normally passed a NULL in the first parameter because | ||
203 | * the calling code doesn't have access to the definition of the ENGINE | ||
204 | * structure (for good reason). However, if the caller wishes to use | ||
205 | * its own memory allocation or use a static array, the following call | ||
206 | * should be used to check the amount of memory the ENGINE structure | ||
207 | * will occupy. This will make the code more future-proof. | ||
208 | * | ||
209 | * NB: I'm "#if 0"-ing this out because it's better to force the use of | ||
210 | * internally allocated memory. See similar change in ENGINE_new(). | ||
211 | */ | ||
212 | #if 0 | ||
213 | int ENGINE_get_struct_size(void); | ||
214 | #endif | ||
215 | |||
216 | /* FUNCTIONAL functions. These functions deal with ENGINE structures | ||
217 | * that have (or will) be initialised for use. Broadly speaking, the | ||
218 | * structural functions are useful for iterating the list of available | ||
219 | * engine types, creating new engine types, and other "list" operations. | ||
220 | * These functions actually deal with ENGINEs that are to be used. As | ||
221 | * such these functions can fail (if applicable) when particular | ||
222 | * engines are unavailable - eg. if a hardware accelerator is not | ||
223 | * attached or not functioning correctly. Each ENGINE has 2 reference | ||
224 | * counts; structural and functional. Every time a functional reference | ||
225 | * is obtained or released, a corresponding structural reference is | ||
226 | * automatically obtained or released too. */ | ||
227 | |||
228 | /* Initialise a engine type for use (or up its reference count if it's | ||
229 | * already in use). This will fail if the engine is not currently | ||
230 | * operational and cannot initialise. */ | ||
231 | int ENGINE_init(ENGINE *e); | ||
232 | /* Free a functional reference to a engine type. This does not require | ||
233 | * a corresponding call to ENGINE_free as it also releases a structural | ||
234 | * reference. */ | ||
235 | int ENGINE_finish(ENGINE *e); | ||
236 | /* Send control parametrised commands to the engine. The possibilities | ||
237 | * to send down an integer, a pointer to data or a function pointer are | ||
238 | * provided. Any of the parameters may or may not be NULL, depending | ||
239 | * on the command number */ | ||
240 | /* WARNING: This is currently experimental and may change radically! */ | ||
241 | int ENGINE_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)()); | ||
242 | |||
243 | /* The following functions handle keys that are stored in some secondary | ||
244 | * location, handled by the engine. The storage may be on a card or | ||
245 | * whatever. */ | ||
246 | EVP_PKEY *ENGINE_load_private_key(ENGINE *e, const char *key_id, | ||
247 | const char *passphrase); | ||
248 | EVP_PKEY *ENGINE_load_public_key(ENGINE *e, const char *key_id, | ||
249 | const char *passphrase); | ||
250 | |||
251 | /* This returns a pointer for the current ENGINE structure that | ||
252 | * is (by default) performing any RSA operations. The value returned | ||
253 | * is an incremented reference, so it should be free'd (ENGINE_finish) | ||
254 | * before it is discarded. */ | ||
255 | ENGINE *ENGINE_get_default_RSA(void); | ||
256 | /* Same for the other "methods" */ | ||
257 | ENGINE *ENGINE_get_default_DSA(void); | ||
258 | ENGINE *ENGINE_get_default_DH(void); | ||
259 | ENGINE *ENGINE_get_default_RAND(void); | ||
260 | ENGINE *ENGINE_get_default_BN_mod_exp(void); | ||
261 | ENGINE *ENGINE_get_default_BN_mod_exp_crt(void); | ||
262 | |||
263 | /* This sets a new default ENGINE structure for performing RSA | ||
264 | * operations. If the result is non-zero (success) then the ENGINE | ||
265 | * structure will have had its reference count up'd so the caller | ||
266 | * should still free their own reference 'e'. */ | ||
267 | int ENGINE_set_default_RSA(ENGINE *e); | ||
268 | /* Same for the other "methods" */ | ||
269 | int ENGINE_set_default_DSA(ENGINE *e); | ||
270 | int ENGINE_set_default_DH(ENGINE *e); | ||
271 | int ENGINE_set_default_RAND(ENGINE *e); | ||
272 | int ENGINE_set_default_BN_mod_exp(ENGINE *e); | ||
273 | int ENGINE_set_default_BN_mod_exp_crt(ENGINE *e); | ||
274 | |||
275 | /* The combination "set" - the flags are bitwise "OR"d from the | ||
276 | * ENGINE_METHOD_*** defines above. */ | ||
277 | int ENGINE_set_default(ENGINE *e, unsigned int flags); | ||
278 | |||
279 | /* Obligatory error function. */ | ||
280 | void ERR_load_ENGINE_strings(void); | ||
281 | |||
282 | /* | ||
283 | * Error codes for all engine functions. NB: We use "generic" | ||
284 | * function names instead of per-implementation ones because this | ||
285 | * levels the playing field for externally implemented bootstrapped | ||
286 | * support code. As the filename and line number is included, it's | ||
287 | * more important to indicate the type of function, so that | ||
288 | * bootstrapped code (that can't easily add its own errors in) can | ||
289 | * use the same error codes too. | ||
290 | */ | ||
291 | |||
292 | /* BEGIN ERROR CODES */ | ||
293 | /* The following lines are auto generated by the script mkerr.pl. Any changes | ||
294 | * made after this point may be overwritten when the script is next run. | ||
295 | */ | ||
296 | |||
297 | /* Error codes for the ENGINE functions. */ | ||
298 | |||
299 | /* Function codes. */ | ||
300 | #define ENGINE_F_ATALLA_FINISH 135 | ||
301 | #define ENGINE_F_ATALLA_INIT 136 | ||
302 | #define ENGINE_F_ATALLA_MOD_EXP 137 | ||
303 | #define ENGINE_F_ATALLA_RSA_MOD_EXP 138 | ||
304 | #define ENGINE_F_CSWIFT_DSA_SIGN 133 | ||
305 | #define ENGINE_F_CSWIFT_DSA_VERIFY 134 | ||
306 | #define ENGINE_F_CSWIFT_FINISH 100 | ||
307 | #define ENGINE_F_CSWIFT_INIT 101 | ||
308 | #define ENGINE_F_CSWIFT_MOD_EXP 102 | ||
309 | #define ENGINE_F_CSWIFT_MOD_EXP_CRT 103 | ||
310 | #define ENGINE_F_CSWIFT_RSA_MOD_EXP 104 | ||
311 | #define ENGINE_F_ENGINE_ADD 105 | ||
312 | #define ENGINE_F_ENGINE_BY_ID 106 | ||
313 | #define ENGINE_F_ENGINE_CTRL 142 | ||
314 | #define ENGINE_F_ENGINE_FINISH 107 | ||
315 | #define ENGINE_F_ENGINE_FREE 108 | ||
316 | #define ENGINE_F_ENGINE_GET_BN_MOD_EXP 109 | ||
317 | #define ENGINE_F_ENGINE_GET_BN_MOD_EXP_CRT 110 | ||
318 | #define ENGINE_F_ENGINE_GET_CTRL_FUNCTION 144 | ||
319 | #define ENGINE_F_ENGINE_GET_DH 111 | ||
320 | #define ENGINE_F_ENGINE_GET_DSA 112 | ||
321 | #define ENGINE_F_ENGINE_GET_FINISH_FUNCTION 145 | ||
322 | #define ENGINE_F_ENGINE_GET_ID 113 | ||
323 | #define ENGINE_F_ENGINE_GET_INIT_FUNCTION 146 | ||
324 | #define ENGINE_F_ENGINE_GET_NAME 114 | ||
325 | #define ENGINE_F_ENGINE_GET_NEXT 115 | ||
326 | #define ENGINE_F_ENGINE_GET_PREV 116 | ||
327 | #define ENGINE_F_ENGINE_GET_RAND 117 | ||
328 | #define ENGINE_F_ENGINE_GET_RSA 118 | ||
329 | #define ENGINE_F_ENGINE_INIT 119 | ||
330 | #define ENGINE_F_ENGINE_LIST_ADD 120 | ||
331 | #define ENGINE_F_ENGINE_LIST_REMOVE 121 | ||
332 | #define ENGINE_F_ENGINE_LOAD_PRIVATE_KEY 150 | ||
333 | #define ENGINE_F_ENGINE_LOAD_PUBLIC_KEY 151 | ||
334 | #define ENGINE_F_ENGINE_NEW 122 | ||
335 | #define ENGINE_F_ENGINE_REMOVE 123 | ||
336 | #define ENGINE_F_ENGINE_SET_BN_MOD_EXP 124 | ||
337 | #define ENGINE_F_ENGINE_SET_BN_MOD_EXP_CRT 125 | ||
338 | #define ENGINE_F_ENGINE_SET_CTRL_FUNCTION 147 | ||
339 | #define ENGINE_F_ENGINE_SET_DEFAULT_TYPE 126 | ||
340 | #define ENGINE_F_ENGINE_SET_DH 127 | ||
341 | #define ENGINE_F_ENGINE_SET_DSA 128 | ||
342 | #define ENGINE_F_ENGINE_SET_FINISH_FUNCTION 148 | ||
343 | #define ENGINE_F_ENGINE_SET_ID 129 | ||
344 | #define ENGINE_F_ENGINE_SET_INIT_FUNCTION 149 | ||
345 | #define ENGINE_F_ENGINE_SET_NAME 130 | ||
346 | #define ENGINE_F_ENGINE_SET_RAND 131 | ||
347 | #define ENGINE_F_ENGINE_SET_RSA 132 | ||
348 | #define ENGINE_F_ENGINE_UNLOAD_KEY 152 | ||
349 | #define ENGINE_F_HWCRHK_CTRL 143 | ||
350 | #define ENGINE_F_HWCRHK_FINISH 135 | ||
351 | #define ENGINE_F_HWCRHK_GET_PASS 155 | ||
352 | #define ENGINE_F_HWCRHK_INIT 136 | ||
353 | #define ENGINE_F_HWCRHK_LOAD_PRIVKEY 153 | ||
354 | #define ENGINE_F_HWCRHK_LOAD_PUBKEY 154 | ||
355 | #define ENGINE_F_HWCRHK_MOD_EXP 137 | ||
356 | #define ENGINE_F_HWCRHK_MOD_EXP_CRT 138 | ||
357 | #define ENGINE_F_HWCRHK_RAND_BYTES 139 | ||
358 | #define ENGINE_F_HWCRHK_RSA_MOD_EXP 140 | ||
359 | #define ENGINE_F_LOG_MESSAGE 141 | ||
360 | |||
361 | /* Reason codes. */ | ||
362 | #define ENGINE_R_ALREADY_LOADED 100 | ||
363 | #define ENGINE_R_BIO_WAS_FREED 121 | ||
364 | #define ENGINE_R_BN_CTX_FULL 101 | ||
365 | #define ENGINE_R_BN_EXPAND_FAIL 102 | ||
366 | #define ENGINE_R_CHIL_ERROR 123 | ||
367 | #define ENGINE_R_CONFLICTING_ENGINE_ID 103 | ||
368 | #define ENGINE_R_CTRL_COMMAND_NOT_IMPLEMENTED 119 | ||
369 | #define ENGINE_R_DSO_FAILURE 104 | ||
370 | #define ENGINE_R_ENGINE_IS_NOT_IN_LIST 105 | ||
371 | #define ENGINE_R_FAILED_LOADING_PRIVATE_KEY 128 | ||
372 | #define ENGINE_R_FAILED_LOADING_PUBLIC_KEY 129 | ||
373 | #define ENGINE_R_FINISH_FAILED 106 | ||
374 | #define ENGINE_R_GET_HANDLE_FAILED 107 | ||
375 | #define ENGINE_R_ID_OR_NAME_MISSING 108 | ||
376 | #define ENGINE_R_INIT_FAILED 109 | ||
377 | #define ENGINE_R_INTERNAL_LIST_ERROR 110 | ||
378 | #define ENGINE_R_MISSING_KEY_COMPONENTS 111 | ||
379 | #define ENGINE_R_NOT_INITIALISED 117 | ||
380 | #define ENGINE_R_NOT_LOADED 112 | ||
381 | #define ENGINE_R_NO_CALLBACK 127 | ||
382 | #define ENGINE_R_NO_CONTROL_FUNCTION 120 | ||
383 | #define ENGINE_R_NO_KEY 124 | ||
384 | #define ENGINE_R_NO_LOAD_FUNCTION 125 | ||
385 | #define ENGINE_R_NO_REFERENCE 130 | ||
386 | #define ENGINE_R_NO_SUCH_ENGINE 116 | ||
387 | #define ENGINE_R_NO_UNLOAD_FUNCTION 126 | ||
388 | #define ENGINE_R_PROVIDE_PARAMETERS 113 | ||
389 | #define ENGINE_R_REQUEST_FAILED 114 | ||
390 | #define ENGINE_R_REQUEST_FALLBACK 118 | ||
391 | #define ENGINE_R_SIZE_TOO_LARGE_OR_TOO_SMALL 122 | ||
392 | #define ENGINE_R_UNIT_FAILURE 115 | ||
393 | |||
394 | #ifdef __cplusplus | ||
395 | } | ||
396 | #endif | ||
397 | #endif | ||
398 | |||
diff --git a/src/lib/libcrypto/engine/tb_cipher.c b/src/lib/libcrypto/engine/tb_cipher.c new file mode 100644 index 0000000000..c5a50fc910 --- /dev/null +++ b/src/lib/libcrypto/engine/tb_cipher.c | |||
@@ -0,0 +1,145 @@ | |||
1 | /* ==================================================================== | ||
2 | * Copyright (c) 2000 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 <openssl/evp.h> | ||
56 | #include <openssl/engine.h> | ||
57 | #include "eng_int.h" | ||
58 | |||
59 | /* If this symbol is defined then ENGINE_get_cipher_engine(), the function that | ||
60 | * is used by EVP to hook in cipher code and cache defaults (etc), will display | ||
61 | * brief debugging summaries to stderr with the 'nid'. */ | ||
62 | /* #define ENGINE_CIPHER_DEBUG */ | ||
63 | |||
64 | static ENGINE_TABLE *cipher_table = NULL; | ||
65 | |||
66 | void ENGINE_unregister_ciphers(ENGINE *e) | ||
67 | { | ||
68 | engine_table_unregister(&cipher_table, e); | ||
69 | } | ||
70 | |||
71 | static void engine_unregister_all_ciphers(void) | ||
72 | { | ||
73 | engine_table_cleanup(&cipher_table); | ||
74 | } | ||
75 | |||
76 | int ENGINE_register_ciphers(ENGINE *e) | ||
77 | { | ||
78 | if(e->ciphers) | ||
79 | { | ||
80 | const int *nids; | ||
81 | int num_nids = e->ciphers(e, NULL, &nids, 0); | ||
82 | if(num_nids > 0) | ||
83 | return engine_table_register(&cipher_table, | ||
84 | &engine_unregister_all_ciphers, e, nids, | ||
85 | num_nids, 0); | ||
86 | } | ||
87 | return 1; | ||
88 | } | ||
89 | |||
90 | void ENGINE_register_all_ciphers() | ||
91 | { | ||
92 | ENGINE *e; | ||
93 | |||
94 | for(e=ENGINE_get_first() ; e ; e=ENGINE_get_next(e)) | ||
95 | ENGINE_register_ciphers(e); | ||
96 | } | ||
97 | |||
98 | int ENGINE_set_default_ciphers(ENGINE *e) | ||
99 | { | ||
100 | if(e->ciphers) | ||
101 | { | ||
102 | const int *nids; | ||
103 | int num_nids = e->ciphers(e, NULL, &nids, 0); | ||
104 | if(num_nids > 0) | ||
105 | return engine_table_register(&cipher_table, | ||
106 | &engine_unregister_all_ciphers, e, nids, | ||
107 | num_nids, 1); | ||
108 | } | ||
109 | return 1; | ||
110 | } | ||
111 | |||
112 | /* Exposed API function to get a functional reference from the implementation | ||
113 | * table (ie. try to get a functional reference from the tabled structural | ||
114 | * references) for a given cipher 'nid' */ | ||
115 | ENGINE *ENGINE_get_cipher_engine(int nid) | ||
116 | { | ||
117 | return engine_table_select(&cipher_table, nid); | ||
118 | } | ||
119 | |||
120 | /* Obtains a cipher implementation from an ENGINE functional reference */ | ||
121 | const EVP_CIPHER *ENGINE_get_cipher(ENGINE *e, int nid) | ||
122 | { | ||
123 | const EVP_CIPHER *ret; | ||
124 | ENGINE_CIPHERS_PTR fn = ENGINE_get_ciphers(e); | ||
125 | if(!fn || !fn(e, &ret, NULL, nid)) | ||
126 | { | ||
127 | ENGINEerr(ENGINE_F_ENGINE_GET_CIPHER, | ||
128 | ENGINE_R_UNIMPLEMENTED_CIPHER); | ||
129 | return NULL; | ||
130 | } | ||
131 | return ret; | ||
132 | } | ||
133 | |||
134 | /* Gets the cipher callback from an ENGINE structure */ | ||
135 | ENGINE_CIPHERS_PTR ENGINE_get_ciphers(const ENGINE *e) | ||
136 | { | ||
137 | return e->ciphers; | ||
138 | } | ||
139 | |||
140 | /* Sets the cipher callback in an ENGINE structure */ | ||
141 | int ENGINE_set_ciphers(ENGINE *e, ENGINE_CIPHERS_PTR f) | ||
142 | { | ||
143 | e->ciphers = f; | ||
144 | return 1; | ||
145 | } | ||
diff --git a/src/lib/libcrypto/engine/tb_dh.c b/src/lib/libcrypto/engine/tb_dh.c new file mode 100644 index 0000000000..c9347235ea --- /dev/null +++ b/src/lib/libcrypto/engine/tb_dh.c | |||
@@ -0,0 +1,120 @@ | |||
1 | /* ==================================================================== | ||
2 | * Copyright (c) 2000 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 <openssl/evp.h> | ||
56 | #include <openssl/engine.h> | ||
57 | #include "eng_int.h" | ||
58 | |||
59 | /* If this symbol is defined then ENGINE_get_default_DH(), the function that is | ||
60 | * used by DH to hook in implementation code and cache defaults (etc), will | ||
61 | * display brief debugging summaries to stderr with the 'nid'. */ | ||
62 | /* #define ENGINE_DH_DEBUG */ | ||
63 | |||
64 | static ENGINE_TABLE *dh_table = NULL; | ||
65 | static const int dummy_nid = 1; | ||
66 | |||
67 | void ENGINE_unregister_DH(ENGINE *e) | ||
68 | { | ||
69 | engine_table_unregister(&dh_table, e); | ||
70 | } | ||
71 | |||
72 | static void engine_unregister_all_DH(void) | ||
73 | { | ||
74 | engine_table_cleanup(&dh_table); | ||
75 | } | ||
76 | |||
77 | int ENGINE_register_DH(ENGINE *e) | ||
78 | { | ||
79 | if(e->dh_meth) | ||
80 | return engine_table_register(&dh_table, | ||
81 | &engine_unregister_all_DH, e, &dummy_nid, 1, 0); | ||
82 | return 1; | ||
83 | } | ||
84 | |||
85 | void ENGINE_register_all_DH() | ||
86 | { | ||
87 | ENGINE *e; | ||
88 | |||
89 | for(e=ENGINE_get_first() ; e ; e=ENGINE_get_next(e)) | ||
90 | ENGINE_register_DH(e); | ||
91 | } | ||
92 | |||
93 | int ENGINE_set_default_DH(ENGINE *e) | ||
94 | { | ||
95 | if(e->dh_meth) | ||
96 | return engine_table_register(&dh_table, | ||
97 | &engine_unregister_all_DH, e, &dummy_nid, 1, 1); | ||
98 | return 1; | ||
99 | } | ||
100 | |||
101 | /* Exposed API function to get a functional reference from the implementation | ||
102 | * table (ie. try to get a functional reference from the tabled structural | ||
103 | * references). */ | ||
104 | ENGINE *ENGINE_get_default_DH(void) | ||
105 | { | ||
106 | return engine_table_select(&dh_table, dummy_nid); | ||
107 | } | ||
108 | |||
109 | /* Obtains an DH implementation from an ENGINE functional reference */ | ||
110 | const DH_METHOD *ENGINE_get_DH(const ENGINE *e) | ||
111 | { | ||
112 | return e->dh_meth; | ||
113 | } | ||
114 | |||
115 | /* Sets an DH implementation in an ENGINE structure */ | ||
116 | int ENGINE_set_DH(ENGINE *e, const DH_METHOD *dh_meth) | ||
117 | { | ||
118 | e->dh_meth = dh_meth; | ||
119 | return 1; | ||
120 | } | ||
diff --git a/src/lib/libcrypto/engine/tb_digest.c b/src/lib/libcrypto/engine/tb_digest.c new file mode 100644 index 0000000000..2c4dd6f796 --- /dev/null +++ b/src/lib/libcrypto/engine/tb_digest.c | |||
@@ -0,0 +1,145 @@ | |||
1 | /* ==================================================================== | ||
2 | * Copyright (c) 2000 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 <openssl/evp.h> | ||
56 | #include <openssl/engine.h> | ||
57 | #include "eng_int.h" | ||
58 | |||
59 | /* If this symbol is defined then ENGINE_get_digest_engine(), the function that | ||
60 | * is used by EVP to hook in digest code and cache defaults (etc), will display | ||
61 | * brief debugging summaries to stderr with the 'nid'. */ | ||
62 | /* #define ENGINE_DIGEST_DEBUG */ | ||
63 | |||
64 | static ENGINE_TABLE *digest_table = NULL; | ||
65 | |||
66 | void ENGINE_unregister_digests(ENGINE *e) | ||
67 | { | ||
68 | engine_table_unregister(&digest_table, e); | ||
69 | } | ||
70 | |||
71 | static void engine_unregister_all_digests(void) | ||
72 | { | ||
73 | engine_table_cleanup(&digest_table); | ||
74 | } | ||
75 | |||
76 | int ENGINE_register_digests(ENGINE *e) | ||
77 | { | ||
78 | if(e->digests) | ||
79 | { | ||
80 | const int *nids; | ||
81 | int num_nids = e->digests(e, NULL, &nids, 0); | ||
82 | if(num_nids > 0) | ||
83 | return engine_table_register(&digest_table, | ||
84 | &engine_unregister_all_digests, e, nids, | ||
85 | num_nids, 0); | ||
86 | } | ||
87 | return 1; | ||
88 | } | ||
89 | |||
90 | void ENGINE_register_all_digests() | ||
91 | { | ||
92 | ENGINE *e; | ||
93 | |||
94 | for(e=ENGINE_get_first() ; e ; e=ENGINE_get_next(e)) | ||
95 | ENGINE_register_digests(e); | ||
96 | } | ||
97 | |||
98 | int ENGINE_set_default_digests(ENGINE *e) | ||
99 | { | ||
100 | if(e->digests) | ||
101 | { | ||
102 | const int *nids; | ||
103 | int num_nids = e->digests(e, NULL, &nids, 0); | ||
104 | if(num_nids > 0) | ||
105 | return engine_table_register(&digest_table, | ||
106 | &engine_unregister_all_digests, e, nids, | ||
107 | num_nids, 1); | ||
108 | } | ||
109 | return 1; | ||
110 | } | ||
111 | |||
112 | /* Exposed API function to get a functional reference from the implementation | ||
113 | * table (ie. try to get a functional reference from the tabled structural | ||
114 | * references) for a given digest 'nid' */ | ||
115 | ENGINE *ENGINE_get_digest_engine(int nid) | ||
116 | { | ||
117 | return engine_table_select(&digest_table, nid); | ||
118 | } | ||
119 | |||
120 | /* Obtains a digest implementation from an ENGINE functional reference */ | ||
121 | const EVP_MD *ENGINE_get_digest(ENGINE *e, int nid) | ||
122 | { | ||
123 | const EVP_MD *ret; | ||
124 | ENGINE_DIGESTS_PTR fn = ENGINE_get_digests(e); | ||
125 | if(!fn || !fn(e, &ret, NULL, nid)) | ||
126 | { | ||
127 | ENGINEerr(ENGINE_F_ENGINE_GET_DIGEST, | ||
128 | ENGINE_R_UNIMPLEMENTED_DIGEST); | ||
129 | return NULL; | ||
130 | } | ||
131 | return ret; | ||
132 | } | ||
133 | |||
134 | /* Gets the digest callback from an ENGINE structure */ | ||
135 | ENGINE_DIGESTS_PTR ENGINE_get_digests(const ENGINE *e) | ||
136 | { | ||
137 | return e->digests; | ||
138 | } | ||
139 | |||
140 | /* Sets the digest callback in an ENGINE structure */ | ||
141 | int ENGINE_set_digests(ENGINE *e, ENGINE_DIGESTS_PTR f) | ||
142 | { | ||
143 | e->digests = f; | ||
144 | return 1; | ||
145 | } | ||
diff --git a/src/lib/libcrypto/engine/tb_dsa.c b/src/lib/libcrypto/engine/tb_dsa.c new file mode 100644 index 0000000000..e9209476b8 --- /dev/null +++ b/src/lib/libcrypto/engine/tb_dsa.c | |||
@@ -0,0 +1,120 @@ | |||
1 | /* ==================================================================== | ||
2 | * Copyright (c) 2000 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 <openssl/evp.h> | ||
56 | #include <openssl/engine.h> | ||
57 | #include "eng_int.h" | ||
58 | |||
59 | /* If this symbol is defined then ENGINE_get_default_DSA(), the function that is | ||
60 | * used by DSA to hook in implementation code and cache defaults (etc), will | ||
61 | * display brief debugging summaries to stderr with the 'nid'. */ | ||
62 | /* #define ENGINE_DSA_DEBUG */ | ||
63 | |||
64 | static ENGINE_TABLE *dsa_table = NULL; | ||
65 | static const int dummy_nid = 1; | ||
66 | |||
67 | void ENGINE_unregister_DSA(ENGINE *e) | ||
68 | { | ||
69 | engine_table_unregister(&dsa_table, e); | ||
70 | } | ||
71 | |||
72 | static void engine_unregister_all_DSA(void) | ||
73 | { | ||
74 | engine_table_cleanup(&dsa_table); | ||
75 | } | ||
76 | |||
77 | int ENGINE_register_DSA(ENGINE *e) | ||
78 | { | ||
79 | if(e->dsa_meth) | ||
80 | return engine_table_register(&dsa_table, | ||
81 | &engine_unregister_all_DSA, e, &dummy_nid, 1, 0); | ||
82 | return 1; | ||
83 | } | ||
84 | |||
85 | void ENGINE_register_all_DSA() | ||
86 | { | ||
87 | ENGINE *e; | ||
88 | |||
89 | for(e=ENGINE_get_first() ; e ; e=ENGINE_get_next(e)) | ||
90 | ENGINE_register_DSA(e); | ||
91 | } | ||
92 | |||
93 | int ENGINE_set_default_DSA(ENGINE *e) | ||
94 | { | ||
95 | if(e->dsa_meth) | ||
96 | return engine_table_register(&dsa_table, | ||
97 | &engine_unregister_all_DSA, e, &dummy_nid, 1, 0); | ||
98 | return 1; | ||
99 | } | ||
100 | |||
101 | /* Exposed API function to get a functional reference from the implementation | ||
102 | * table (ie. try to get a functional reference from the tabled structural | ||
103 | * references). */ | ||
104 | ENGINE *ENGINE_get_default_DSA(void) | ||
105 | { | ||
106 | return engine_table_select(&dsa_table, dummy_nid); | ||
107 | } | ||
108 | |||
109 | /* Obtains an DSA implementation from an ENGINE functional reference */ | ||
110 | const DSA_METHOD *ENGINE_get_DSA(const ENGINE *e) | ||
111 | { | ||
112 | return e->dsa_meth; | ||
113 | } | ||
114 | |||
115 | /* Sets an DSA implementation in an ENGINE structure */ | ||
116 | int ENGINE_set_DSA(ENGINE *e, const DSA_METHOD *dsa_meth) | ||
117 | { | ||
118 | e->dsa_meth = dsa_meth; | ||
119 | return 1; | ||
120 | } | ||
diff --git a/src/lib/libcrypto/engine/tb_rand.c b/src/lib/libcrypto/engine/tb_rand.c new file mode 100644 index 0000000000..0b1d031f1e --- /dev/null +++ b/src/lib/libcrypto/engine/tb_rand.c | |||
@@ -0,0 +1,120 @@ | |||
1 | /* ==================================================================== | ||
2 | * Copyright (c) 2000 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 <openssl/evp.h> | ||
56 | #include <openssl/engine.h> | ||
57 | #include "eng_int.h" | ||
58 | |||
59 | /* If this symbol is defined then ENGINE_get_default_RAND(), the function that is | ||
60 | * used by RAND to hook in implementation code and cache defaults (etc), will | ||
61 | * display brief debugging summaries to stderr with the 'nid'. */ | ||
62 | /* #define ENGINE_RAND_DEBUG */ | ||
63 | |||
64 | static ENGINE_TABLE *rand_table = NULL; | ||
65 | static const int dummy_nid = 1; | ||
66 | |||
67 | void ENGINE_unregister_RAND(ENGINE *e) | ||
68 | { | ||
69 | engine_table_unregister(&rand_table, e); | ||
70 | } | ||
71 | |||
72 | static void engine_unregister_all_RAND(void) | ||
73 | { | ||
74 | engine_table_cleanup(&rand_table); | ||
75 | } | ||
76 | |||
77 | int ENGINE_register_RAND(ENGINE *e) | ||
78 | { | ||
79 | if(e->rand_meth) | ||
80 | return engine_table_register(&rand_table, | ||
81 | &engine_unregister_all_RAND, e, &dummy_nid, 1, 0); | ||
82 | return 1; | ||
83 | } | ||
84 | |||
85 | void ENGINE_register_all_RAND() | ||
86 | { | ||
87 | ENGINE *e; | ||
88 | |||
89 | for(e=ENGINE_get_first() ; e ; e=ENGINE_get_next(e)) | ||
90 | ENGINE_register_RAND(e); | ||
91 | } | ||
92 | |||
93 | int ENGINE_set_default_RAND(ENGINE *e) | ||
94 | { | ||
95 | if(e->rand_meth) | ||
96 | return engine_table_register(&rand_table, | ||
97 | &engine_unregister_all_RAND, e, &dummy_nid, 1, 1); | ||
98 | return 1; | ||
99 | } | ||
100 | |||
101 | /* Exposed API function to get a functional reference from the implementation | ||
102 | * table (ie. try to get a functional reference from the tabled structural | ||
103 | * references). */ | ||
104 | ENGINE *ENGINE_get_default_RAND(void) | ||
105 | { | ||
106 | return engine_table_select(&rand_table, dummy_nid); | ||
107 | } | ||
108 | |||
109 | /* Obtains an RAND implementation from an ENGINE functional reference */ | ||
110 | const RAND_METHOD *ENGINE_get_RAND(const ENGINE *e) | ||
111 | { | ||
112 | return e->rand_meth; | ||
113 | } | ||
114 | |||
115 | /* Sets an RAND implementation in an ENGINE structure */ | ||
116 | int ENGINE_set_RAND(ENGINE *e, const RAND_METHOD *rand_meth) | ||
117 | { | ||
118 | e->rand_meth = rand_meth; | ||
119 | return 1; | ||
120 | } | ||
diff --git a/src/lib/libcrypto/engine/tb_rsa.c b/src/lib/libcrypto/engine/tb_rsa.c new file mode 100644 index 0000000000..f84fea3968 --- /dev/null +++ b/src/lib/libcrypto/engine/tb_rsa.c | |||
@@ -0,0 +1,120 @@ | |||
1 | /* ==================================================================== | ||
2 | * Copyright (c) 2000 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 <openssl/evp.h> | ||
56 | #include <openssl/engine.h> | ||
57 | #include "eng_int.h" | ||
58 | |||
59 | /* If this symbol is defined then ENGINE_get_default_RSA(), the function that is | ||
60 | * used by RSA to hook in implementation code and cache defaults (etc), will | ||
61 | * display brief debugging summaries to stderr with the 'nid'. */ | ||
62 | /* #define ENGINE_RSA_DEBUG */ | ||
63 | |||
64 | static ENGINE_TABLE *rsa_table = NULL; | ||
65 | static const int dummy_nid = 1; | ||
66 | |||
67 | void ENGINE_unregister_RSA(ENGINE *e) | ||
68 | { | ||
69 | engine_table_unregister(&rsa_table, e); | ||
70 | } | ||
71 | |||
72 | static void engine_unregister_all_RSA(void) | ||
73 | { | ||
74 | engine_table_cleanup(&rsa_table); | ||
75 | } | ||
76 | |||
77 | int ENGINE_register_RSA(ENGINE *e) | ||
78 | { | ||
79 | if(e->rsa_meth) | ||
80 | return engine_table_register(&rsa_table, | ||
81 | &engine_unregister_all_RSA, e, &dummy_nid, 1, 0); | ||
82 | return 1; | ||
83 | } | ||
84 | |||
85 | void ENGINE_register_all_RSA() | ||
86 | { | ||
87 | ENGINE *e; | ||
88 | |||
89 | for(e=ENGINE_get_first() ; e ; e=ENGINE_get_next(e)) | ||
90 | ENGINE_register_RSA(e); | ||
91 | } | ||
92 | |||
93 | int ENGINE_set_default_RSA(ENGINE *e) | ||
94 | { | ||
95 | if(e->rsa_meth) | ||
96 | return engine_table_register(&rsa_table, | ||
97 | &engine_unregister_all_RSA, e, &dummy_nid, 1, 1); | ||
98 | return 1; | ||
99 | } | ||
100 | |||
101 | /* Exposed API function to get a functional reference from the implementation | ||
102 | * table (ie. try to get a functional reference from the tabled structural | ||
103 | * references). */ | ||
104 | ENGINE *ENGINE_get_default_RSA(void) | ||
105 | { | ||
106 | return engine_table_select(&rsa_table, dummy_nid); | ||
107 | } | ||
108 | |||
109 | /* Obtains an RSA implementation from an ENGINE functional reference */ | ||
110 | const RSA_METHOD *ENGINE_get_RSA(const ENGINE *e) | ||
111 | { | ||
112 | return e->rsa_meth; | ||
113 | } | ||
114 | |||
115 | /* Sets an RSA implementation in an ENGINE structure */ | ||
116 | int ENGINE_set_RSA(ENGINE *e, const RSA_METHOD *rsa_meth) | ||
117 | { | ||
118 | e->rsa_meth = rsa_meth; | ||
119 | return 1; | ||
120 | } | ||
diff --git a/src/lib/libcrypto/err/openssl.ec b/src/lib/libcrypto/err/openssl.ec new file mode 100644 index 0000000000..c2a8acff0c --- /dev/null +++ b/src/lib/libcrypto/err/openssl.ec | |||
@@ -0,0 +1,71 @@ | |||
1 | L ERR NONE NONE | ||
2 | L CRYPTO crypto/crypto.h crypto/cpt_err.c | ||
3 | L BN crypto/bn/bn.h crypto/bn/bn_err.c | ||
4 | L RSA crypto/rsa/rsa.h crypto/rsa/rsa_err.c | ||
5 | L DSA crypto/dsa/dsa.h crypto/dsa/dsa_err.c | ||
6 | L DH crypto/dh/dh.h crypto/dh/dh_err.c | ||
7 | L EVP crypto/evp/evp.h crypto/evp/evp_err.c | ||
8 | L BUF crypto/buffer/buffer.h crypto/buffer/buf_err.c | ||
9 | L BIO crypto/bio/bio.h crypto/bio/bio_err.c | ||
10 | L OBJ crypto/objects/objects.h crypto/objects/obj_err.c | ||
11 | L PEM crypto/pem/pem.h crypto/pem/pem_err.c | ||
12 | L X509 crypto/x509/x509.h crypto/x509/x509_err.c | ||
13 | L NONE crypto/x509/x509_vfy.h NONE | ||
14 | L X509V3 crypto/x509v3/x509v3.h crypto/x509v3/v3err.c | ||
15 | #L METH crypto/meth/meth.h crypto/meth/meth_err.c | ||
16 | L ASN1 crypto/asn1/asn1.h crypto/asn1/asn1_err.c | ||
17 | L CONF crypto/conf/conf.h crypto/conf/conf_err.c | ||
18 | #L PROXY crypto/proxy/proxy.h crypto/proxy/proxy_err.c | ||
19 | L PKCS7 crypto/pkcs7/pkcs7.h crypto/pkcs7/pkcs7err.c | ||
20 | L PKCS12 crypto/pkcs12/pkcs12.h crypto/pkcs12/pk12err.c | ||
21 | L RSAREF rsaref/rsaref.h rsaref/rsar_err.c | ||
22 | L SSL ssl/ssl.h ssl/ssl_err.c | ||
23 | L COMP crypto/comp/comp.h crypto/comp/comp_err.c | ||
24 | |||
25 | |||
26 | F RSAREF_F_RSA_BN2BIN | ||
27 | F RSAREF_F_RSA_PRIVATE_DECRYPT | ||
28 | F RSAREF_F_RSA_PRIVATE_ENCRYPT | ||
29 | F RSAREF_F_RSA_PUBLIC_DECRYPT | ||
30 | F RSAREF_F_RSA_PUBLIC_ENCRYPT | ||
31 | #F SSL_F_CLIENT_CERTIFICATE | ||
32 | |||
33 | R SSL_R_SSLV3_ALERT_UNEXPECTED_MESSAGE 1010 | ||
34 | R SSL_R_SSLV3_ALERT_BAD_RECORD_MAC 1020 | ||
35 | R SSL_R_TLSV1_ALERT_DECRYPTION_FAILED 1021 | ||
36 | R SSL_R_TLSV1_ALERT_RECORD_OVERFLOW 1022 | ||
37 | R SSL_R_SSLV3_ALERT_DECOMPRESSION_FAILURE 1030 | ||
38 | R SSL_R_SSLV3_ALERT_HANDSHAKE_FAILURE 1040 | ||
39 | R SSL_R_SSLV3_ALERT_NO_CERTIFICATE 1041 | ||
40 | R SSL_R_SSLV3_ALERT_BAD_CERTIFICATE 1042 | ||
41 | R SSL_R_SSLV3_ALERT_UNSUPPORTED_CERTIFICATE 1043 | ||
42 | R SSL_R_SSLV3_ALERT_CERTIFICATE_REVOKED 1044 | ||
43 | R SSL_R_SSLV3_ALERT_CERTIFICATE_EXPIRED 1045 | ||
44 | R SSL_R_SSLV3_ALERT_CERTIFICATE_UNKNOWN 1046 | ||
45 | R SSL_R_SSLV3_ALERT_ILLEGAL_PARAMETER 1047 | ||
46 | R SSL_R_TLSV1_ALERT_UNKNOWN_CA 1048 | ||
47 | R SSL_R_TLSV1_ALERT_ACCESS_DENIED 1049 | ||
48 | R SSL_R_TLSV1_ALERT_DECODE_ERROR 1050 | ||
49 | R SSL_R_TLSV1_ALERT_DECRYPT_ERROR 1051 | ||
50 | R SSL_R_TLSV1_ALERT_EXPORT_RESTRICION 1060 | ||
51 | R SSL_R_TLSV1_ALERT_PROTOCOL_VERSION 1070 | ||
52 | R SSL_R_TLSV1_ALERT_INSUFFICIENT_SECURITY 1071 | ||
53 | R SSL_R_TLSV1_ALERT_INTERNAL_ERROR 1080 | ||
54 | R SSL_R_TLSV1_ALERT_USER_CANCLED 1090 | ||
55 | R SSL_R_TLSV1_ALERT_NO_RENEGOTIATION 1100 | ||
56 | |||
57 | R RSAREF_R_CONTENT_ENCODING 0x0400 | ||
58 | R RSAREF_R_DATA 0x0401 | ||
59 | R RSAREF_R_DIGEST_ALGORITHM 0x0402 | ||
60 | R RSAREF_R_ENCODING 0x0403 | ||
61 | R RSAREF_R_KEY 0x0404 | ||
62 | R RSAREF_R_KEY_ENCODING 0x0405 | ||
63 | R RSAREF_R_LEN 0x0406 | ||
64 | R RSAREF_R_MODULUS_LEN 0x0407 | ||
65 | R RSAREF_R_NEED_RANDOM 0x0408 | ||
66 | R RSAREF_R_PRIVATE_KEY 0x0409 | ||
67 | R RSAREF_R_PUBLIC_KEY 0x040a | ||
68 | R RSAREF_R_SIGNATURE 0x040b | ||
69 | R RSAREF_R_SIGNATURE_ENCODING 0x040c | ||
70 | R RSAREF_R_ENCRYPTION_ALGORITHM 0x040d | ||
71 | |||
diff --git a/src/lib/libcrypto/evp/e_aes.c b/src/lib/libcrypto/evp/e_aes.c new file mode 100644 index 0000000000..9d03a9602f --- /dev/null +++ b/src/lib/libcrypto/evp/e_aes.c | |||
@@ -0,0 +1,99 @@ | |||
1 | /* ==================================================================== | ||
2 | * Copyright (c) 2001 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 | * openssl-core@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 | */ | ||
50 | |||
51 | #ifndef OPENSSL_NO_AES | ||
52 | #include <openssl/evp.h> | ||
53 | #include <openssl/err.h> | ||
54 | #include <string.h> | ||
55 | #include <assert.h> | ||
56 | #include <openssl/aes.h> | ||
57 | #include "evp_locl.h" | ||
58 | |||
59 | static int aes_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, | ||
60 | const unsigned char *iv, int enc); | ||
61 | |||
62 | typedef struct | ||
63 | { | ||
64 | AES_KEY ks; | ||
65 | } EVP_AES_KEY; | ||
66 | |||
67 | #define data(ctx) EVP_C_DATA(EVP_AES_KEY,ctx) | ||
68 | |||
69 | IMPLEMENT_BLOCK_CIPHER(aes_128, ks, AES, EVP_AES_KEY, | ||
70 | NID_aes_128, 16, 16, 16, 128, | ||
71 | 0, aes_init_key, NULL, | ||
72 | EVP_CIPHER_set_asn1_iv, | ||
73 | EVP_CIPHER_get_asn1_iv, | ||
74 | NULL) | ||
75 | IMPLEMENT_BLOCK_CIPHER(aes_192, ks, AES, EVP_AES_KEY, | ||
76 | NID_aes_192, 16, 24, 16, 128, | ||
77 | 0, aes_init_key, NULL, | ||
78 | EVP_CIPHER_set_asn1_iv, | ||
79 | EVP_CIPHER_get_asn1_iv, | ||
80 | NULL) | ||
81 | IMPLEMENT_BLOCK_CIPHER(aes_256, ks, AES, EVP_AES_KEY, | ||
82 | NID_aes_256, 16, 32, 16, 128, | ||
83 | 0, aes_init_key, NULL, | ||
84 | EVP_CIPHER_set_asn1_iv, | ||
85 | EVP_CIPHER_get_asn1_iv, | ||
86 | NULL) | ||
87 | |||
88 | static int aes_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, | ||
89 | const unsigned char *iv, int enc) { | ||
90 | |||
91 | if (enc) | ||
92 | AES_set_encrypt_key(key, ctx->key_len * 8, ctx->cipher_data); | ||
93 | else | ||
94 | AES_set_decrypt_key(key, ctx->key_len * 8, ctx->cipher_data); | ||
95 | |||
96 | return 1; | ||
97 | } | ||
98 | |||
99 | #endif | ||
diff --git a/src/lib/libcrypto/evp/e_bf.c b/src/lib/libcrypto/evp/e_bf.c new file mode 100644 index 0000000000..72047f64da --- /dev/null +++ b/src/lib/libcrypto/evp/e_bf.c | |||
@@ -0,0 +1,80 @@ | |||
1 | /* crypto/evp/e_bf.c */ | ||
2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) | ||
3 | * All rights reserved. | ||
4 | * | ||
5 | * This package is an SSL implementation written | ||
6 | * by Eric Young (eay@cryptsoft.com). | ||
7 | * The implementation was written so as to conform with Netscapes SSL. | ||
8 | * | ||
9 | * This library is free for commercial and non-commercial use as long as | ||
10 | * the following conditions are aheared to. The following conditions | ||
11 | * apply to all code found in this distribution, be it the RC4, RSA, | ||
12 | * lhash, DES, etc., code; not just the SSL code. The SSL documentation | ||
13 | * included with this distribution is covered by the same copyright terms | ||
14 | * except that the holder is Tim Hudson (tjh@cryptsoft.com). | ||
15 | * | ||
16 | * Copyright remains Eric Young's, and as such any Copyright notices in | ||
17 | * the code are not to be removed. | ||
18 | * If this package is used in a product, Eric Young should be given attribution | ||
19 | * as the author of the parts of the library used. | ||
20 | * This can be in the form of a textual message at program startup or | ||
21 | * in documentation (online or textual) provided with the package. | ||
22 | * | ||
23 | * Redistribution and use in source and binary forms, with or without | ||
24 | * modification, are permitted provided that the following conditions | ||
25 | * are met: | ||
26 | * 1. Redistributions of source code must retain the copyright | ||
27 | * notice, this list of conditions and the following disclaimer. | ||
28 | * 2. Redistributions in binary form must reproduce the above copyright | ||
29 | * notice, this list of conditions and the following disclaimer in the | ||
30 | * documentation and/or other materials provided with the distribution. | ||
31 | * 3. All advertising materials mentioning features or use of this software | ||
32 | * must display the following acknowledgement: | ||
33 | * "This product includes cryptographic software written by | ||
34 | * Eric Young (eay@cryptsoft.com)" | ||
35 | * The word 'cryptographic' can be left out if the rouines from the library | ||
36 | * being used are not cryptographic related :-). | ||
37 | * 4. If you include any Windows specific code (or a derivative thereof) from | ||
38 | * the apps directory (application code) you must include an acknowledgement: | ||
39 | * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" | ||
40 | * | ||
41 | * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND | ||
42 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
43 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
44 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | ||
45 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
46 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
47 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
48 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
49 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
50 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
51 | * SUCH DAMAGE. | ||
52 | * | ||
53 | * The licence and distribution terms for any publically available version or | ||
54 | * derivative of this code cannot be changed. i.e. this code cannot simply be | ||
55 | * copied and put under another distribution licence | ||
56 | * [including the GNU Public Licence.] | ||
57 | */ | ||
58 | |||
59 | #ifndef NO_BF | ||
60 | #include <stdio.h> | ||
61 | #include "cryptlib.h" | ||
62 | #include <openssl/evp.h> | ||
63 | #include "evp_locl.h" | ||
64 | #include <openssl/objects.h> | ||
65 | |||
66 | static int bf_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, | ||
67 | const unsigned char *iv, int enc); | ||
68 | |||
69 | IMPLEMENT_BLOCK_CIPHER(bf, bf_ks, BF, bf_ks, NID_bf, 8, 16, 8, | ||
70 | 0, bf_init_key, NULL, | ||
71 | EVP_CIPHER_set_asn1_iv, EVP_CIPHER_get_asn1_iv, NULL) | ||
72 | |||
73 | static int bf_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, | ||
74 | const unsigned char *iv, int enc) | ||
75 | { | ||
76 | BF_set_key(&(ctx->c.bf_ks),EVP_CIPHER_CTX_key_length(ctx),key); | ||
77 | return 1; | ||
78 | } | ||
79 | |||
80 | #endif | ||
diff --git a/src/lib/libcrypto/evp/e_cast.c b/src/lib/libcrypto/evp/e_cast.c new file mode 100644 index 0000000000..e5af7fb4ed --- /dev/null +++ b/src/lib/libcrypto/evp/e_cast.c | |||
@@ -0,0 +1,82 @@ | |||
1 | /* crypto/evp/e_cast.c */ | ||
2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) | ||
3 | * All rights reserved. | ||
4 | * | ||
5 | * This package is an SSL implementation written | ||
6 | * by Eric Young (eay@cryptsoft.com). | ||
7 | * The implementation was written so as to conform with Netscapes SSL. | ||
8 | * | ||
9 | * This library is free for commercial and non-commercial use as long as | ||
10 | * the following conditions are aheared to. The following conditions | ||
11 | * apply to all code found in this distribution, be it the RC4, RSA, | ||
12 | * lhash, DES, etc., code; not just the SSL code. The SSL documentation | ||
13 | * included with this distribution is covered by the same copyright terms | ||
14 | * except that the holder is Tim Hudson (tjh@cryptsoft.com). | ||
15 | * | ||
16 | * Copyright remains Eric Young's, and as such any Copyright notices in | ||
17 | * the code are not to be removed. | ||
18 | * If this package is used in a product, Eric Young should be given attribution | ||
19 | * as the author of the parts of the library used. | ||
20 | * This can be in the form of a textual message at program startup or | ||
21 | * in documentation (online or textual) provided with the package. | ||
22 | * | ||
23 | * Redistribution and use in source and binary forms, with or without | ||
24 | * modification, are permitted provided that the following conditions | ||
25 | * are met: | ||
26 | * 1. Redistributions of source code must retain the copyright | ||
27 | * notice, this list of conditions and the following disclaimer. | ||
28 | * 2. Redistributions in binary form must reproduce the above copyright | ||
29 | * notice, this list of conditions and the following disclaimer in the | ||
30 | * documentation and/or other materials provided with the distribution. | ||
31 | * 3. All advertising materials mentioning features or use of this software | ||
32 | * must display the following acknowledgement: | ||
33 | * "This product includes cryptographic software written by | ||
34 | * Eric Young (eay@cryptsoft.com)" | ||
35 | * The word 'cryptographic' can be left out if the rouines from the library | ||
36 | * being used are not cryptographic related :-). | ||
37 | * 4. If you include any Windows specific code (or a derivative thereof) from | ||
38 | * the apps directory (application code) you must include an acknowledgement: | ||
39 | * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" | ||
40 | * | ||
41 | * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND | ||
42 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
43 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
44 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | ||
45 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
46 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
47 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
48 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
49 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
50 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
51 | * SUCH DAMAGE. | ||
52 | * | ||
53 | * The licence and distribution terms for any publically available version or | ||
54 | * derivative of this code cannot be changed. i.e. this code cannot simply be | ||
55 | * copied and put under another distribution licence | ||
56 | * [including the GNU Public Licence.] | ||
57 | */ | ||
58 | |||
59 | #ifndef NO_CAST | ||
60 | |||
61 | #include <stdio.h> | ||
62 | #include "cryptlib.h" | ||
63 | #include <openssl/evp.h> | ||
64 | #include <openssl/objects.h> | ||
65 | #include "evp_locl.h" | ||
66 | |||
67 | static int cast_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, | ||
68 | const unsigned char *iv,int enc); | ||
69 | |||
70 | IMPLEMENT_BLOCK_CIPHER(cast5, cast_ks, CAST, cast_ks, | ||
71 | NID_cast5, 8, EVP_CAST5_KEY_SIZE, 8, | ||
72 | EVP_CIPH_VARIABLE_LENGTH, cast_init_key, NULL, | ||
73 | EVP_CIPHER_set_asn1_iv, EVP_CIPHER_get_asn1_iv, NULL) | ||
74 | |||
75 | static int cast_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, | ||
76 | const unsigned char *iv, int enc) | ||
77 | { | ||
78 | CAST_set_key(&(ctx->c.cast_ks),EVP_CIPHER_CTX_key_length(ctx),key); | ||
79 | return 1; | ||
80 | } | ||
81 | |||
82 | #endif | ||
diff --git a/src/lib/libcrypto/evp/e_des.c b/src/lib/libcrypto/evp/e_des.c new file mode 100644 index 0000000000..f4e998b81c --- /dev/null +++ b/src/lib/libcrypto/evp/e_des.c | |||
@@ -0,0 +1,118 @@ | |||
1 | /* crypto/evp/e_des.c */ | ||
2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) | ||
3 | * All rights reserved. | ||
4 | * | ||
5 | * This package is an SSL implementation written | ||
6 | * by Eric Young (eay@cryptsoft.com). | ||
7 | * The implementation was written so as to conform with Netscapes SSL. | ||
8 | * | ||
9 | * This library is free for commercial and non-commercial use as long as | ||
10 | * the following conditions are aheared to. The following conditions | ||
11 | * apply to all code found in this distribution, be it the RC4, RSA, | ||
12 | * lhash, DES, etc., code; not just the SSL code. The SSL documentation | ||
13 | * included with this distribution is covered by the same copyright terms | ||
14 | * except that the holder is Tim Hudson (tjh@cryptsoft.com). | ||
15 | * | ||
16 | * Copyright remains Eric Young's, and as such any Copyright notices in | ||
17 | * the code are not to be removed. | ||
18 | * If this package is used in a product, Eric Young should be given attribution | ||
19 | * as the author of the parts of the library used. | ||
20 | * This can be in the form of a textual message at program startup or | ||
21 | * in documentation (online or textual) provided with the package. | ||
22 | * | ||
23 | * Redistribution and use in source and binary forms, with or without | ||
24 | * modification, are permitted provided that the following conditions | ||
25 | * are met: | ||
26 | * 1. Redistributions of source code must retain the copyright | ||
27 | * notice, this list of conditions and the following disclaimer. | ||
28 | * 2. Redistributions in binary form must reproduce the above copyright | ||
29 | * notice, this list of conditions and the following disclaimer in the | ||
30 | * documentation and/or other materials provided with the distribution. | ||
31 | * 3. All advertising materials mentioning features or use of this software | ||
32 | * must display the following acknowledgement: | ||
33 | * "This product includes cryptographic software written by | ||
34 | * Eric Young (eay@cryptsoft.com)" | ||
35 | * The word 'cryptographic' can be left out if the rouines from the library | ||
36 | * being used are not cryptographic related :-). | ||
37 | * 4. If you include any Windows specific code (or a derivative thereof) from | ||
38 | * the apps directory (application code) you must include an acknowledgement: | ||
39 | * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" | ||
40 | * | ||
41 | * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND | ||
42 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
43 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
44 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | ||
45 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
46 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
47 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
48 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
49 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
50 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
51 | * SUCH DAMAGE. | ||
52 | * | ||
53 | * The licence and distribution terms for any publically available version or | ||
54 | * derivative of this code cannot be changed. i.e. this code cannot simply be | ||
55 | * copied and put under another distribution licence | ||
56 | * [including the GNU Public Licence.] | ||
57 | */ | ||
58 | |||
59 | #ifndef NO_DES | ||
60 | #include <stdio.h> | ||
61 | #include "cryptlib.h" | ||
62 | #include <openssl/evp.h> | ||
63 | #include <openssl/objects.h> | ||
64 | #include "evp_locl.h" | ||
65 | |||
66 | static int des_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, | ||
67 | const unsigned char *iv, int enc); | ||
68 | |||
69 | /* Because of various casts and different names can't use IMPLEMENT_BLOCK_CIPHER */ | ||
70 | |||
71 | static int des_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, | ||
72 | const unsigned char *in, unsigned int inl) | ||
73 | { | ||
74 | BLOCK_CIPHER_ecb_loop() | ||
75 | des_ecb_encrypt((des_cblock *)(in + i), (des_cblock *)(out + i), ctx->c.des_ks, ctx->encrypt); | ||
76 | return 1; | ||
77 | } | ||
78 | |||
79 | static int des_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, | ||
80 | const unsigned char *in, unsigned int inl) | ||
81 | { | ||
82 | des_ofb64_encrypt(in, out, (long)inl, ctx->c.des_ks, (des_cblock *)ctx->iv, &ctx->num); | ||
83 | return 1; | ||
84 | } | ||
85 | |||
86 | static int des_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, | ||
87 | const unsigned char *in, unsigned int inl) | ||
88 | { | ||
89 | des_ncbc_encrypt(in, out, (long)inl, ctx->c.des_ks, | ||
90 | (des_cblock *)ctx->iv, ctx->encrypt); | ||
91 | return 1; | ||
92 | } | ||
93 | |||
94 | static int des_cfb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, | ||
95 | const unsigned char *in, unsigned int inl) | ||
96 | { | ||
97 | des_cfb64_encrypt(in, out, (long)inl, ctx->c.des_ks, | ||
98 | (des_cblock *)ctx->iv, &ctx->num, ctx->encrypt); | ||
99 | return 1; | ||
100 | } | ||
101 | |||
102 | BLOCK_CIPHER_defs(des, des_ks, NID_des, 8, 8, 8, | ||
103 | 0, des_init_key, NULL, | ||
104 | EVP_CIPHER_set_asn1_iv, | ||
105 | EVP_CIPHER_get_asn1_iv, | ||
106 | NULL) | ||
107 | |||
108 | |||
109 | static int des_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, | ||
110 | const unsigned char *iv, int enc) | ||
111 | { | ||
112 | des_cblock *deskey = (des_cblock *)key; | ||
113 | |||
114 | des_set_key_unchecked(deskey,ctx->c.des_ks); | ||
115 | return 1; | ||
116 | } | ||
117 | |||
118 | #endif | ||
diff --git a/src/lib/libcrypto/evp/e_des3.c b/src/lib/libcrypto/evp/e_des3.c new file mode 100644 index 0000000000..a9aba4ae70 --- /dev/null +++ b/src/lib/libcrypto/evp/e_des3.c | |||
@@ -0,0 +1,165 @@ | |||
1 | /* crypto/evp/e_des3.c */ | ||
2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) | ||
3 | * All rights reserved. | ||
4 | * | ||
5 | * This package is an SSL implementation written | ||
6 | * by Eric Young (eay@cryptsoft.com). | ||
7 | * The implementation was written so as to conform with Netscapes SSL. | ||
8 | * | ||
9 | * This library is free for commercial and non-commercial use as long as | ||
10 | * the following conditions are aheared to. The following conditions | ||
11 | * apply to all code found in this distribution, be it the RC4, RSA, | ||
12 | * lhash, DES, etc., code; not just the SSL code. The SSL documentation | ||
13 | * included with this distribution is covered by the same copyright terms | ||
14 | * except that the holder is Tim Hudson (tjh@cryptsoft.com). | ||
15 | * | ||
16 | * Copyright remains Eric Young's, and as such any Copyright notices in | ||
17 | * the code are not to be removed. | ||
18 | * If this package is used in a product, Eric Young should be given attribution | ||
19 | * as the author of the parts of the library used. | ||
20 | * This can be in the form of a textual message at program startup or | ||
21 | * in documentation (online or textual) provided with the package. | ||
22 | * | ||
23 | * Redistribution and use in source and binary forms, with or without | ||
24 | * modification, are permitted provided that the following conditions | ||
25 | * are met: | ||
26 | * 1. Redistributions of source code must retain the copyright | ||
27 | * notice, this list of conditions and the following disclaimer. | ||
28 | * 2. Redistributions in binary form must reproduce the above copyright | ||
29 | * notice, this list of conditions and the following disclaimer in the | ||
30 | * documentation and/or other materials provided with the distribution. | ||
31 | * 3. All advertising materials mentioning features or use of this software | ||
32 | * must display the following acknowledgement: | ||
33 | * "This product includes cryptographic software written by | ||
34 | * Eric Young (eay@cryptsoft.com)" | ||
35 | * The word 'cryptographic' can be left out if the rouines from the library | ||
36 | * being used are not cryptographic related :-). | ||
37 | * 4. If you include any Windows specific code (or a derivative thereof) from | ||
38 | * the apps directory (application code) you must include an acknowledgement: | ||
39 | * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" | ||
40 | * | ||
41 | * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND | ||
42 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
43 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
44 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | ||
45 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
46 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
47 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
48 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
49 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
50 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
51 | * SUCH DAMAGE. | ||
52 | * | ||
53 | * The licence and distribution terms for any publically available version or | ||
54 | * derivative of this code cannot be changed. i.e. this code cannot simply be | ||
55 | * copied and put under another distribution licence | ||
56 | * [including the GNU Public Licence.] | ||
57 | */ | ||
58 | |||
59 | #ifndef NO_DES | ||
60 | #include <stdio.h> | ||
61 | #include "cryptlib.h" | ||
62 | #include <openssl/evp.h> | ||
63 | #include <openssl/objects.h> | ||
64 | #include "evp_locl.h" | ||
65 | |||
66 | static int des_ede_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, | ||
67 | const unsigned char *iv,int enc); | ||
68 | |||
69 | static int des_ede3_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, | ||
70 | const unsigned char *iv,int enc); | ||
71 | |||
72 | /* Because of various casts and different args can't use IMPLEMENT_BLOCK_CIPHER */ | ||
73 | |||
74 | static int des_ede_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, | ||
75 | const unsigned char *in, unsigned int inl) | ||
76 | { | ||
77 | BLOCK_CIPHER_ecb_loop() | ||
78 | des_ecb3_encrypt((des_cblock *)(in + i), (des_cblock *)(out + i), | ||
79 | ctx->c.des_ede.ks1, ctx->c.des_ede.ks2, ctx->c.des_ede.ks3, | ||
80 | ctx->encrypt); | ||
81 | return 1; | ||
82 | } | ||
83 | |||
84 | static int des_ede_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, | ||
85 | const unsigned char *in, unsigned int inl) | ||
86 | { | ||
87 | des_ede3_ofb64_encrypt(in, out, (long)inl, | ||
88 | ctx->c.des_ede.ks1, ctx->c.des_ede.ks2, ctx->c.des_ede.ks3, | ||
89 | (des_cblock *)ctx->iv, &ctx->num); | ||
90 | return 1; | ||
91 | } | ||
92 | |||
93 | static int des_ede_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, | ||
94 | const unsigned char *in, unsigned int inl) | ||
95 | { | ||
96 | des_ede3_cbc_encrypt(in, out, (long)inl, | ||
97 | ctx->c.des_ede.ks1, ctx->c.des_ede.ks2, ctx->c.des_ede.ks3, | ||
98 | (des_cblock *)ctx->iv, ctx->encrypt); | ||
99 | return 1; | ||
100 | } | ||
101 | |||
102 | static int des_ede_cfb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, | ||
103 | const unsigned char *in, unsigned int inl) | ||
104 | { | ||
105 | des_ede3_cfb64_encrypt(in, out, (long)inl, | ||
106 | ctx->c.des_ede.ks1, ctx->c.des_ede.ks2, ctx->c.des_ede.ks3, | ||
107 | (des_cblock *)ctx->iv, &ctx->num, ctx->encrypt); | ||
108 | return 1; | ||
109 | } | ||
110 | |||
111 | #define NID_des_ede_ecb NID_des_ede | ||
112 | |||
113 | BLOCK_CIPHER_defs(des_ede, des_ede, NID_des_ede, 8, 16, 8, | ||
114 | 0, des_ede_init_key, NULL, | ||
115 | EVP_CIPHER_set_asn1_iv, | ||
116 | EVP_CIPHER_get_asn1_iv, | ||
117 | NULL) | ||
118 | |||
119 | #define NID_des_ede3_ecb NID_des_ede3 | ||
120 | #define des_ede3_cfb_cipher des_ede_cfb_cipher | ||
121 | #define des_ede3_ofb_cipher des_ede_ofb_cipher | ||
122 | #define des_ede3_cbc_cipher des_ede_cbc_cipher | ||
123 | #define des_ede3_ecb_cipher des_ede_ecb_cipher | ||
124 | |||
125 | BLOCK_CIPHER_defs(des_ede3, des_ede, NID_des_ede3, 8, 24, 8, | ||
126 | 0, des_ede3_init_key, NULL, | ||
127 | EVP_CIPHER_set_asn1_iv, | ||
128 | EVP_CIPHER_get_asn1_iv, | ||
129 | NULL) | ||
130 | |||
131 | static int des_ede_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, | ||
132 | const unsigned char *iv, int enc) | ||
133 | { | ||
134 | des_cblock *deskey = (des_cblock *)key; | ||
135 | |||
136 | des_set_key_unchecked(&deskey[0],ctx->c.des_ede.ks1); | ||
137 | des_set_key_unchecked(&deskey[1],ctx->c.des_ede.ks2); | ||
138 | memcpy( (char *)ctx->c.des_ede.ks3, | ||
139 | (char *)ctx->c.des_ede.ks1, | ||
140 | sizeof(ctx->c.des_ede.ks1)); | ||
141 | return 1; | ||
142 | } | ||
143 | |||
144 | static int des_ede3_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, | ||
145 | const unsigned char *iv, int enc) | ||
146 | { | ||
147 | des_cblock *deskey = (des_cblock *)key; | ||
148 | |||
149 | des_set_key_unchecked(&deskey[0],ctx->c.des_ede.ks1); | ||
150 | des_set_key_unchecked(&deskey[1],ctx->c.des_ede.ks2); | ||
151 | des_set_key_unchecked(&deskey[2],ctx->c.des_ede.ks3); | ||
152 | |||
153 | return 1; | ||
154 | } | ||
155 | |||
156 | EVP_CIPHER *EVP_des_ede(void) | ||
157 | { | ||
158 | return &des_ede_ecb; | ||
159 | } | ||
160 | |||
161 | EVP_CIPHER *EVP_des_ede3(void) | ||
162 | { | ||
163 | return &des_ede3_ecb; | ||
164 | } | ||
165 | #endif | ||
diff --git a/src/lib/libcrypto/evp/e_idea.c b/src/lib/libcrypto/evp/e_idea.c new file mode 100644 index 0000000000..8d3c88deb7 --- /dev/null +++ b/src/lib/libcrypto/evp/e_idea.c | |||
@@ -0,0 +1,112 @@ | |||
1 | /* crypto/evp/e_idea.c */ | ||
2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) | ||
3 | * All rights reserved. | ||
4 | * | ||
5 | * This package is an SSL implementation written | ||
6 | * by Eric Young (eay@cryptsoft.com). | ||
7 | * The implementation was written so as to conform with Netscapes SSL. | ||
8 | * | ||
9 | * This library is free for commercial and non-commercial use as long as | ||
10 | * the following conditions are aheared to. The following conditions | ||
11 | * apply to all code found in this distribution, be it the RC4, RSA, | ||
12 | * lhash, DES, etc., code; not just the SSL code. The SSL documentation | ||
13 | * included with this distribution is covered by the same copyright terms | ||
14 | * except that the holder is Tim Hudson (tjh@cryptsoft.com). | ||
15 | * | ||
16 | * Copyright remains Eric Young's, and as such any Copyright notices in | ||
17 | * the code are not to be removed. | ||
18 | * If this package is used in a product, Eric Young should be given attribution | ||
19 | * as the author of the parts of the library used. | ||
20 | * This can be in the form of a textual message at program startup or | ||
21 | * in documentation (online or textual) provided with the package. | ||
22 | * | ||
23 | * Redistribution and use in source and binary forms, with or without | ||
24 | * modification, are permitted provided that the following conditions | ||
25 | * are met: | ||
26 | * 1. Redistributions of source code must retain the copyright | ||
27 | * notice, this list of conditions and the following disclaimer. | ||
28 | * 2. Redistributions in binary form must reproduce the above copyright | ||
29 | * notice, this list of conditions and the following disclaimer in the | ||
30 | * documentation and/or other materials provided with the distribution. | ||
31 | * 3. All advertising materials mentioning features or use of this software | ||
32 | * must display the following acknowledgement: | ||
33 | * "This product includes cryptographic software written by | ||
34 | * Eric Young (eay@cryptsoft.com)" | ||
35 | * The word 'cryptographic' can be left out if the rouines from the library | ||
36 | * being used are not cryptographic related :-). | ||
37 | * 4. If you include any Windows specific code (or a derivative thereof) from | ||
38 | * the apps directory (application code) you must include an acknowledgement: | ||
39 | * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" | ||
40 | * | ||
41 | * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND | ||
42 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
43 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
44 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | ||
45 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
46 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
47 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
48 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
49 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
50 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
51 | * SUCH DAMAGE. | ||
52 | * | ||
53 | * The licence and distribution terms for any publically available version or | ||
54 | * derivative of this code cannot be changed. i.e. this code cannot simply be | ||
55 | * copied and put under another distribution licence | ||
56 | * [including the GNU Public Licence.] | ||
57 | */ | ||
58 | |||
59 | #ifndef NO_IDEA | ||
60 | |||
61 | #include <stdio.h> | ||
62 | #include "cryptlib.h" | ||
63 | #include <openssl/evp.h> | ||
64 | #include <openssl/objects.h> | ||
65 | #include "evp_locl.h" | ||
66 | |||
67 | static int idea_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, | ||
68 | const unsigned char *iv,int enc); | ||
69 | |||
70 | /* NB idea_ecb_encrypt doesn't take an 'encrypt' argument so we treat it as a special | ||
71 | * case | ||
72 | */ | ||
73 | |||
74 | static int idea_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, | ||
75 | const unsigned char *in, unsigned int inl) | ||
76 | { | ||
77 | BLOCK_CIPHER_ecb_loop() | ||
78 | idea_ecb_encrypt(in + i, out + i, &ctx->c.idea_ks); | ||
79 | return 1; | ||
80 | } | ||
81 | |||
82 | /* Can't use IMPLEMENT_BLOCK_CIPHER because idea_ecb_encrypt is different */ | ||
83 | |||
84 | BLOCK_CIPHER_func_cbc(idea, idea, idea_ks) | ||
85 | BLOCK_CIPHER_func_ofb(idea, idea, idea_ks) | ||
86 | BLOCK_CIPHER_func_cfb(idea, idea, idea_ks) | ||
87 | |||
88 | BLOCK_CIPHER_defs(idea, idea_ks, NID_idea, 8, 16, 8, | ||
89 | 0, idea_init_key, NULL, | ||
90 | EVP_CIPHER_set_asn1_iv, EVP_CIPHER_get_asn1_iv, NULL) | ||
91 | |||
92 | static int idea_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, | ||
93 | const unsigned char *iv, int enc) | ||
94 | { | ||
95 | if(!enc) { | ||
96 | if (EVP_CIPHER_CTX_mode(ctx) == EVP_CIPH_OFB_MODE) enc = 1; | ||
97 | else if (EVP_CIPHER_CTX_mode(ctx) == EVP_CIPH_CFB_MODE) enc = 1; | ||
98 | } | ||
99 | if (enc) idea_set_encrypt_key(key,&(ctx->c.idea_ks)); | ||
100 | else | ||
101 | { | ||
102 | IDEA_KEY_SCHEDULE tmp; | ||
103 | |||
104 | idea_set_encrypt_key(key,&tmp); | ||
105 | idea_set_decrypt_key(&tmp,&(ctx->c.idea_ks)); | ||
106 | memset((unsigned char *)&tmp,0, | ||
107 | sizeof(IDEA_KEY_SCHEDULE)); | ||
108 | } | ||
109 | return 1; | ||
110 | } | ||
111 | |||
112 | #endif | ||
diff --git a/src/lib/libcrypto/evp/e_rc2.c b/src/lib/libcrypto/evp/e_rc2.c new file mode 100644 index 0000000000..3955c3ef84 --- /dev/null +++ b/src/lib/libcrypto/evp/e_rc2.c | |||
@@ -0,0 +1,222 @@ | |||
1 | /* crypto/evp/e_rc2.c */ | ||
2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) | ||
3 | * All rights reserved. | ||
4 | * | ||
5 | * This package is an SSL implementation written | ||
6 | * by Eric Young (eay@cryptsoft.com). | ||
7 | * The implementation was written so as to conform with Netscapes SSL. | ||
8 | * | ||
9 | * This library is free for commercial and non-commercial use as long as | ||
10 | * the following conditions are aheared to. The following conditions | ||
11 | * apply to all code found in this distribution, be it the RC4, RSA, | ||
12 | * lhash, DES, etc., code; not just the SSL code. The SSL documentation | ||
13 | * included with this distribution is covered by the same copyright terms | ||
14 | * except that the holder is Tim Hudson (tjh@cryptsoft.com). | ||
15 | * | ||
16 | * Copyright remains Eric Young's, and as such any Copyright notices in | ||
17 | * the code are not to be removed. | ||
18 | * If this package is used in a product, Eric Young should be given attribution | ||
19 | * as the author of the parts of the library used. | ||
20 | * This can be in the form of a textual message at program startup or | ||
21 | * in documentation (online or textual) provided with the package. | ||
22 | * | ||
23 | * Redistribution and use in source and binary forms, with or without | ||
24 | * modification, are permitted provided that the following conditions | ||
25 | * are met: | ||
26 | * 1. Redistributions of source code must retain the copyright | ||
27 | * notice, this list of conditions and the following disclaimer. | ||
28 | * 2. Redistributions in binary form must reproduce the above copyright | ||
29 | * notice, this list of conditions and the following disclaimer in the | ||
30 | * documentation and/or other materials provided with the distribution. | ||
31 | * 3. All advertising materials mentioning features or use of this software | ||
32 | * must display the following acknowledgement: | ||
33 | * "This product includes cryptographic software written by | ||
34 | * Eric Young (eay@cryptsoft.com)" | ||
35 | * The word 'cryptographic' can be left out if the rouines from the library | ||
36 | * being used are not cryptographic related :-). | ||
37 | * 4. If you include any Windows specific code (or a derivative thereof) from | ||
38 | * the apps directory (application code) you must include an acknowledgement: | ||
39 | * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" | ||
40 | * | ||
41 | * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND | ||
42 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
43 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
44 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | ||
45 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
46 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
47 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
48 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
49 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
50 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
51 | * SUCH DAMAGE. | ||
52 | * | ||
53 | * The licence and distribution terms for any publically available version or | ||
54 | * derivative of this code cannot be changed. i.e. this code cannot simply be | ||
55 | * copied and put under another distribution licence | ||
56 | * [including the GNU Public Licence.] | ||
57 | */ | ||
58 | |||
59 | #ifndef NO_RC2 | ||
60 | |||
61 | #include <stdio.h> | ||
62 | #include "cryptlib.h" | ||
63 | #include <openssl/evp.h> | ||
64 | #include <openssl/objects.h> | ||
65 | #include "evp_locl.h" | ||
66 | |||
67 | static int rc2_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, | ||
68 | const unsigned char *iv,int enc); | ||
69 | static int rc2_meth_to_magic(EVP_CIPHER_CTX *ctx); | ||
70 | static int rc2_magic_to_meth(int i); | ||
71 | static int rc2_set_asn1_type_and_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type); | ||
72 | static int rc2_get_asn1_type_and_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type); | ||
73 | static int rc2_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr); | ||
74 | |||
75 | IMPLEMENT_BLOCK_CIPHER(rc2, rc2.ks, RC2, rc2, NID_rc2, | ||
76 | 8, | ||
77 | EVP_RC2_KEY_SIZE, 8, | ||
78 | EVP_CIPH_VARIABLE_LENGTH | EVP_CIPH_CTRL_INIT, | ||
79 | rc2_init_key, NULL, | ||
80 | rc2_set_asn1_type_and_iv, rc2_get_asn1_type_and_iv, | ||
81 | rc2_ctrl) | ||
82 | |||
83 | #define RC2_40_MAGIC 0xa0 | ||
84 | #define RC2_64_MAGIC 0x78 | ||
85 | #define RC2_128_MAGIC 0x3a | ||
86 | |||
87 | static EVP_CIPHER r2_64_cbc_cipher= | ||
88 | { | ||
89 | NID_rc2_64_cbc, | ||
90 | 8,8 /* 64 bit */,8, | ||
91 | EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH | EVP_CIPH_CTRL_INIT, | ||
92 | rc2_init_key, | ||
93 | rc2_cbc_cipher, | ||
94 | NULL, | ||
95 | sizeof(EVP_CIPHER_CTX)-sizeof((((EVP_CIPHER_CTX *)NULL)->c))+ | ||
96 | sizeof((((EVP_CIPHER_CTX *)NULL)->c.rc2)), | ||
97 | rc2_set_asn1_type_and_iv, | ||
98 | rc2_get_asn1_type_and_iv, | ||
99 | rc2_ctrl, | ||
100 | NULL | ||
101 | }; | ||
102 | |||
103 | static EVP_CIPHER r2_40_cbc_cipher= | ||
104 | { | ||
105 | NID_rc2_40_cbc, | ||
106 | 8,5 /* 40 bit */,8, | ||
107 | EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH | EVP_CIPH_CTRL_INIT, | ||
108 | rc2_init_key, | ||
109 | rc2_cbc_cipher, | ||
110 | NULL, | ||
111 | sizeof(EVP_CIPHER_CTX)-sizeof((((EVP_CIPHER_CTX *)NULL)->c))+ | ||
112 | sizeof((((EVP_CIPHER_CTX *)NULL)->c.rc2)), | ||
113 | rc2_set_asn1_type_and_iv, | ||
114 | rc2_get_asn1_type_and_iv, | ||
115 | rc2_ctrl, | ||
116 | NULL | ||
117 | }; | ||
118 | |||
119 | EVP_CIPHER *EVP_rc2_64_cbc(void) | ||
120 | { | ||
121 | return(&r2_64_cbc_cipher); | ||
122 | } | ||
123 | |||
124 | EVP_CIPHER *EVP_rc2_40_cbc(void) | ||
125 | { | ||
126 | return(&r2_40_cbc_cipher); | ||
127 | } | ||
128 | |||
129 | static int rc2_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, | ||
130 | const unsigned char *iv, int enc) | ||
131 | { | ||
132 | RC2_set_key(&(ctx->c.rc2.ks),EVP_CIPHER_CTX_key_length(ctx), | ||
133 | key,ctx->c.rc2.key_bits); | ||
134 | return 1; | ||
135 | } | ||
136 | |||
137 | static int rc2_meth_to_magic(EVP_CIPHER_CTX *e) | ||
138 | { | ||
139 | int i; | ||
140 | |||
141 | EVP_CIPHER_CTX_ctrl(e, EVP_CTRL_GET_RC2_KEY_BITS, 0, &i); | ||
142 | if (i == 128) return(RC2_128_MAGIC); | ||
143 | else if (i == 64) return(RC2_64_MAGIC); | ||
144 | else if (i == 40) return(RC2_40_MAGIC); | ||
145 | else return(0); | ||
146 | } | ||
147 | |||
148 | static int rc2_magic_to_meth(int i) | ||
149 | { | ||
150 | if (i == RC2_128_MAGIC) return 128; | ||
151 | else if (i == RC2_64_MAGIC) return 64; | ||
152 | else if (i == RC2_40_MAGIC) return 40; | ||
153 | else | ||
154 | { | ||
155 | EVPerr(EVP_F_RC2_MAGIC_TO_METH,EVP_R_UNSUPPORTED_KEY_SIZE); | ||
156 | return(0); | ||
157 | } | ||
158 | } | ||
159 | |||
160 | static int rc2_get_asn1_type_and_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type) | ||
161 | { | ||
162 | long num=0; | ||
163 | int i=0,l; | ||
164 | int key_bits; | ||
165 | unsigned char iv[EVP_MAX_IV_LENGTH]; | ||
166 | |||
167 | if (type != NULL) | ||
168 | { | ||
169 | l=EVP_CIPHER_CTX_iv_length(c); | ||
170 | i=ASN1_TYPE_get_int_octetstring(type,&num,iv,l); | ||
171 | if (i != l) | ||
172 | return(-1); | ||
173 | key_bits =rc2_magic_to_meth((int)num); | ||
174 | if (!key_bits) | ||
175 | return(-1); | ||
176 | if(i > 0) EVP_CipherInit(c, NULL, NULL, iv, -1); | ||
177 | EVP_CIPHER_CTX_ctrl(c, EVP_CTRL_SET_RC2_KEY_BITS, key_bits, NULL); | ||
178 | EVP_CIPHER_CTX_set_key_length(c, key_bits / 8); | ||
179 | } | ||
180 | return(i); | ||
181 | } | ||
182 | |||
183 | static int rc2_set_asn1_type_and_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type) | ||
184 | { | ||
185 | long num; | ||
186 | int i=0,j; | ||
187 | |||
188 | if (type != NULL) | ||
189 | { | ||
190 | num=rc2_meth_to_magic(c); | ||
191 | j=EVP_CIPHER_CTX_iv_length(c); | ||
192 | i=ASN1_TYPE_set_int_octetstring(type,num,c->oiv,j); | ||
193 | } | ||
194 | return(i); | ||
195 | } | ||
196 | |||
197 | static int rc2_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) | ||
198 | { | ||
199 | switch(type) { | ||
200 | |||
201 | case EVP_CTRL_INIT: | ||
202 | c->c.rc2.key_bits = EVP_CIPHER_CTX_key_length(c) * 8; | ||
203 | return 1; | ||
204 | |||
205 | case EVP_CTRL_GET_RC2_KEY_BITS: | ||
206 | *(int *)ptr = c->c.rc2.key_bits; | ||
207 | return 1; | ||
208 | |||
209 | |||
210 | case EVP_CTRL_SET_RC2_KEY_BITS: | ||
211 | if(arg > 0) { | ||
212 | c->c.rc2.key_bits = arg; | ||
213 | return 1; | ||
214 | } | ||
215 | return 0; | ||
216 | |||
217 | default: | ||
218 | return -1; | ||
219 | } | ||
220 | } | ||
221 | |||
222 | #endif | ||
diff --git a/src/lib/libcrypto/evp/evp_locl.h b/src/lib/libcrypto/evp/evp_locl.h new file mode 100644 index 0000000000..ce49d5b7d8 --- /dev/null +++ b/src/lib/libcrypto/evp/evp_locl.h | |||
@@ -0,0 +1,168 @@ | |||
1 | /* evp_locl.h */ | ||
2 | /* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL | ||
3 | * project 2000. | ||
4 | */ | ||
5 | /* ==================================================================== | ||
6 | * Copyright (c) 1999 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 | /* Macros to code block cipher wrappers */ | ||
60 | |||
61 | /* Wrapper functions for each cipher mode */ | ||
62 | |||
63 | #define BLOCK_CIPHER_ecb_loop() \ | ||
64 | unsigned int i; \ | ||
65 | if(inl < 8) return 1;\ | ||
66 | inl -= 8; \ | ||
67 | for(i=0; i <= inl; i+=8) \ | ||
68 | |||
69 | #define BLOCK_CIPHER_func_ecb(cname, cprefix, kname) \ | ||
70 | static int cname##_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, unsigned int inl) \ | ||
71 | {\ | ||
72 | BLOCK_CIPHER_ecb_loop() \ | ||
73 | cprefix##_ecb_encrypt(in + i, out + i, &ctx->c.kname, ctx->encrypt);\ | ||
74 | return 1;\ | ||
75 | } | ||
76 | |||
77 | #define BLOCK_CIPHER_func_ofb(cname, cprefix, kname) \ | ||
78 | static int cname##_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, unsigned int inl) \ | ||
79 | {\ | ||
80 | cprefix##_ofb64_encrypt(in, out, (long)inl, &ctx->c.kname, ctx->iv, &ctx->num);\ | ||
81 | return 1;\ | ||
82 | } | ||
83 | |||
84 | #define BLOCK_CIPHER_func_cbc(cname, cprefix, kname) \ | ||
85 | static int cname##_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, unsigned int inl) \ | ||
86 | {\ | ||
87 | cprefix##_cbc_encrypt(in, out, (long)inl, &ctx->c.kname, ctx->iv, ctx->encrypt);\ | ||
88 | return 1;\ | ||
89 | } | ||
90 | |||
91 | #define BLOCK_CIPHER_func_cfb(cname, cprefix, kname) \ | ||
92 | static int cname##_cfb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, unsigned int inl) \ | ||
93 | {\ | ||
94 | cprefix##_cfb64_encrypt(in, out, (long)inl, &ctx->c.kname, ctx->iv, &ctx->num, ctx->encrypt);\ | ||
95 | return 1;\ | ||
96 | } | ||
97 | |||
98 | #define BLOCK_CIPHER_all_funcs(cname, cprefix, kname) \ | ||
99 | BLOCK_CIPHER_func_cbc(cname, cprefix, kname) \ | ||
100 | BLOCK_CIPHER_func_cfb(cname, cprefix, kname) \ | ||
101 | BLOCK_CIPHER_func_ecb(cname, cprefix, kname) \ | ||
102 | BLOCK_CIPHER_func_ofb(cname, cprefix, kname) | ||
103 | |||
104 | #define BLOCK_CIPHER_defs(cname, kstruct, \ | ||
105 | nid, block_size, key_len, iv_len, flags,\ | ||
106 | init_key, cleanup, set_asn1, get_asn1, ctrl)\ | ||
107 | static EVP_CIPHER cname##_cbc = {\ | ||
108 | nid##_cbc, block_size, key_len, iv_len, \ | ||
109 | flags | EVP_CIPH_CBC_MODE,\ | ||
110 | init_key,\ | ||
111 | cname##_cbc_cipher,\ | ||
112 | cleanup,\ | ||
113 | sizeof(EVP_CIPHER_CTX)-sizeof((((EVP_CIPHER_CTX *)NULL)->c))+\ | ||
114 | sizeof((((EVP_CIPHER_CTX *)NULL)->c.kstruct)),\ | ||
115 | set_asn1, get_asn1,\ | ||
116 | ctrl, \ | ||
117 | NULL \ | ||
118 | };\ | ||
119 | EVP_CIPHER *EVP_##cname##_cbc(void) { return &cname##_cbc; }\ | ||
120 | static EVP_CIPHER cname##_cfb = {\ | ||
121 | nid##_cfb64, 1, key_len, iv_len, \ | ||
122 | flags | EVP_CIPH_CFB_MODE,\ | ||
123 | init_key,\ | ||
124 | cname##_cfb_cipher,\ | ||
125 | cleanup,\ | ||
126 | sizeof(EVP_CIPHER_CTX)-sizeof((((EVP_CIPHER_CTX *)NULL)->c))+\ | ||
127 | sizeof((((EVP_CIPHER_CTX *)NULL)->c.kstruct)),\ | ||
128 | set_asn1, get_asn1,\ | ||
129 | ctrl,\ | ||
130 | NULL \ | ||
131 | };\ | ||
132 | EVP_CIPHER *EVP_##cname##_cfb(void) { return &cname##_cfb; }\ | ||
133 | static EVP_CIPHER cname##_ofb = {\ | ||
134 | nid##_ofb64, 1, key_len, iv_len, \ | ||
135 | flags | EVP_CIPH_OFB_MODE,\ | ||
136 | init_key,\ | ||
137 | cname##_ofb_cipher,\ | ||
138 | cleanup,\ | ||
139 | sizeof(EVP_CIPHER_CTX)-sizeof((((EVP_CIPHER_CTX *)NULL)->c))+\ | ||
140 | sizeof((((EVP_CIPHER_CTX *)NULL)->c.kstruct)),\ | ||
141 | set_asn1, get_asn1,\ | ||
142 | ctrl,\ | ||
143 | NULL \ | ||
144 | };\ | ||
145 | EVP_CIPHER *EVP_##cname##_ofb(void) { return &cname##_ofb; }\ | ||
146 | static EVP_CIPHER cname##_ecb = {\ | ||
147 | nid##_ecb, block_size, key_len, iv_len, \ | ||
148 | flags | EVP_CIPH_ECB_MODE,\ | ||
149 | init_key,\ | ||
150 | cname##_ecb_cipher,\ | ||
151 | cleanup,\ | ||
152 | sizeof(EVP_CIPHER_CTX)-sizeof((((EVP_CIPHER_CTX *)NULL)->c))+\ | ||
153 | sizeof((((EVP_CIPHER_CTX *)NULL)->c.kstruct)),\ | ||
154 | set_asn1, get_asn1,\ | ||
155 | ctrl,\ | ||
156 | NULL \ | ||
157 | };\ | ||
158 | EVP_CIPHER *EVP_##cname##_ecb(void) { return &cname##_ecb; } | ||
159 | |||
160 | |||
161 | |||
162 | #define IMPLEMENT_BLOCK_CIPHER(cname, kname, cprefix, kstruct, \ | ||
163 | nid, block_size, key_len, iv_len, flags, \ | ||
164 | init_key, cleanup, set_asn1, get_asn1, ctrl) \ | ||
165 | BLOCK_CIPHER_all_funcs(cname, cprefix, kname) \ | ||
166 | BLOCK_CIPHER_defs(cname, kstruct, nid, block_size, key_len, iv_len, flags,\ | ||
167 | init_key, cleanup, set_asn1, get_asn1, ctrl) | ||
168 | |||
diff --git a/src/lib/libcrypto/evp/evp_pbe.c b/src/lib/libcrypto/evp/evp_pbe.c new file mode 100644 index 0000000000..353c3ad667 --- /dev/null +++ b/src/lib/libcrypto/evp/evp_pbe.c | |||
@@ -0,0 +1,134 @@ | |||
1 | /* evp_pbe.c */ | ||
2 | /* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL | ||
3 | * project 1999. | ||
4 | */ | ||
5 | /* ==================================================================== | ||
6 | * Copyright (c) 1999 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 | #include <openssl/evp.h> | ||
61 | #include <openssl/x509.h> | ||
62 | #include "cryptlib.h" | ||
63 | |||
64 | /* Password based encryption (PBE) functions */ | ||
65 | |||
66 | static STACK *pbe_algs; | ||
67 | |||
68 | /* Setup a cipher context from a PBE algorithm */ | ||
69 | |||
70 | typedef struct { | ||
71 | int pbe_nid; | ||
72 | EVP_CIPHER *cipher; | ||
73 | EVP_MD *md; | ||
74 | EVP_PBE_KEYGEN *keygen; | ||
75 | } EVP_PBE_CTL; | ||
76 | |||
77 | int EVP_PBE_CipherInit (ASN1_OBJECT *pbe_obj, const char *pass, int passlen, | ||
78 | ASN1_TYPE *param, EVP_CIPHER_CTX *ctx, int en_de) | ||
79 | { | ||
80 | |||
81 | EVP_PBE_CTL *pbetmp, pbelu; | ||
82 | int i; | ||
83 | pbelu.pbe_nid = OBJ_obj2nid(pbe_obj); | ||
84 | if (pbelu.pbe_nid != NID_undef) i = sk_find(pbe_algs, (char *)&pbelu); | ||
85 | else i = -1; | ||
86 | |||
87 | if (i == -1) { | ||
88 | char obj_tmp[80]; | ||
89 | EVPerr(EVP_F_EVP_PBE_CIPHERINIT,EVP_R_UNKNOWN_PBE_ALGORITHM); | ||
90 | if (!pbe_obj) strcpy (obj_tmp, "NULL"); | ||
91 | else i2t_ASN1_OBJECT(obj_tmp, 80, pbe_obj); | ||
92 | ERR_add_error_data(2, "TYPE=", obj_tmp); | ||
93 | return 0; | ||
94 | } | ||
95 | if (passlen == -1) passlen = strlen(pass); | ||
96 | pbetmp = (EVP_PBE_CTL *)sk_value (pbe_algs, i); | ||
97 | i = (*pbetmp->keygen)(ctx, pass, passlen, param, pbetmp->cipher, | ||
98 | pbetmp->md, en_de); | ||
99 | if (!i) { | ||
100 | EVPerr(EVP_F_EVP_PBE_CIPHERINIT,EVP_R_KEYGEN_FAILURE); | ||
101 | return 0; | ||
102 | } | ||
103 | return 1; | ||
104 | } | ||
105 | |||
106 | static int pbe_cmp (EVP_PBE_CTL **pbe1, EVP_PBE_CTL **pbe2) | ||
107 | { | ||
108 | return ((*pbe1)->pbe_nid - (*pbe2)->pbe_nid); | ||
109 | } | ||
110 | |||
111 | /* Add a PBE algorithm */ | ||
112 | |||
113 | int EVP_PBE_alg_add (int nid, EVP_CIPHER *cipher, EVP_MD *md, | ||
114 | EVP_PBE_KEYGEN *keygen) | ||
115 | { | ||
116 | EVP_PBE_CTL *pbe_tmp; | ||
117 | if (!pbe_algs) pbe_algs = sk_new (pbe_cmp); | ||
118 | if (!(pbe_tmp = (EVP_PBE_CTL*) Malloc (sizeof(EVP_PBE_CTL)))) { | ||
119 | EVPerr(EVP_F_EVP_PBE_ALG_ADD,ERR_R_MALLOC_FAILURE); | ||
120 | return 0; | ||
121 | } | ||
122 | pbe_tmp->pbe_nid = nid; | ||
123 | pbe_tmp->cipher = cipher; | ||
124 | pbe_tmp->md = md; | ||
125 | pbe_tmp->keygen = keygen; | ||
126 | sk_push (pbe_algs, (char *)pbe_tmp); | ||
127 | return 1; | ||
128 | } | ||
129 | |||
130 | void EVP_PBE_cleanup(void) | ||
131 | { | ||
132 | sk_pop_free(pbe_algs, FreeFunc); | ||
133 | pbe_algs = NULL; | ||
134 | } | ||
diff --git a/src/lib/libcrypto/evp/evp_pkey.c b/src/lib/libcrypto/evp/evp_pkey.c new file mode 100644 index 0000000000..421e452db1 --- /dev/null +++ b/src/lib/libcrypto/evp/evp_pkey.c | |||
@@ -0,0 +1,298 @@ | |||
1 | /* evp_pkey.c */ | ||
2 | /* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL | ||
3 | * project 1999. | ||
4 | */ | ||
5 | /* ==================================================================== | ||
6 | * Copyright (c) 1999 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 | #include <stdlib.h> | ||
61 | #include "cryptlib.h" | ||
62 | #include <openssl/x509.h> | ||
63 | #include <openssl/rand.h> | ||
64 | |||
65 | /* Extract a private key from a PKCS8 structure */ | ||
66 | |||
67 | EVP_PKEY *EVP_PKCS82PKEY (PKCS8_PRIV_KEY_INFO *p8) | ||
68 | { | ||
69 | EVP_PKEY *pkey; | ||
70 | #ifndef NO_RSA | ||
71 | RSA *rsa; | ||
72 | #endif | ||
73 | #ifndef NO_DSA | ||
74 | DSA *dsa; | ||
75 | ASN1_INTEGER *dsapriv; | ||
76 | STACK *ndsa; | ||
77 | BN_CTX *ctx; | ||
78 | int plen; | ||
79 | #endif | ||
80 | X509_ALGOR *a; | ||
81 | unsigned char *p; | ||
82 | int pkeylen; | ||
83 | char obj_tmp[80]; | ||
84 | |||
85 | switch (p8->broken) { | ||
86 | case PKCS8_OK: | ||
87 | p = p8->pkey->value.octet_string->data; | ||
88 | pkeylen = p8->pkey->value.octet_string->length; | ||
89 | break; | ||
90 | |||
91 | case PKCS8_NO_OCTET: | ||
92 | p = p8->pkey->value.sequence->data; | ||
93 | pkeylen = p8->pkey->value.sequence->length; | ||
94 | break; | ||
95 | |||
96 | default: | ||
97 | EVPerr(EVP_F_EVP_PKCS82PKEY,EVP_R_PKCS8_UNKNOWN_BROKEN_TYPE); | ||
98 | return NULL; | ||
99 | break; | ||
100 | } | ||
101 | if (!(pkey = EVP_PKEY_new())) { | ||
102 | EVPerr(EVP_F_EVP_PKCS82PKEY,ERR_R_MALLOC_FAILURE); | ||
103 | return NULL; | ||
104 | } | ||
105 | a = p8->pkeyalg; | ||
106 | switch (OBJ_obj2nid(a->algorithm)) | ||
107 | { | ||
108 | #ifndef NO_RSA | ||
109 | case NID_rsaEncryption: | ||
110 | if (!(rsa = d2i_RSAPrivateKey (NULL, &p, pkeylen))) { | ||
111 | EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR); | ||
112 | return NULL; | ||
113 | } | ||
114 | EVP_PKEY_assign_RSA (pkey, rsa); | ||
115 | break; | ||
116 | #endif | ||
117 | #ifndef NO_DSA | ||
118 | case NID_dsa: | ||
119 | /* PKCS#8 DSA is weird: you just get a private key integer | ||
120 | * and parameters in the AlgorithmIdentifier the pubkey must | ||
121 | * be recalculated. | ||
122 | */ | ||
123 | |||
124 | /* Check for broken Netscape Database DSA PKCS#8, UGH! */ | ||
125 | if(*p == (V_ASN1_SEQUENCE|V_ASN1_CONSTRUCTED)) { | ||
126 | if(!(ndsa = ASN1_seq_unpack(p, pkeylen, | ||
127 | (char *(*)())d2i_ASN1_INTEGER, | ||
128 | ASN1_STRING_free))) { | ||
129 | EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR); | ||
130 | return NULL; | ||
131 | } | ||
132 | if(sk_num(ndsa) != 2 ) { | ||
133 | EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR); | ||
134 | sk_pop_free(ndsa, ASN1_STRING_free); | ||
135 | return NULL; | ||
136 | } | ||
137 | dsapriv = (ASN1_INTEGER *) sk_pop(ndsa); | ||
138 | sk_pop_free(ndsa, ASN1_STRING_free); | ||
139 | } else if (!(dsapriv=d2i_ASN1_INTEGER (NULL, &p, pkeylen))) { | ||
140 | EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR); | ||
141 | return NULL; | ||
142 | } | ||
143 | /* Retrieve parameters */ | ||
144 | if (a->parameter->type != V_ASN1_SEQUENCE) { | ||
145 | EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_NO_DSA_PARAMETERS); | ||
146 | return NULL; | ||
147 | } | ||
148 | p = a->parameter->value.sequence->data; | ||
149 | plen = a->parameter->value.sequence->length; | ||
150 | if (!(dsa = d2i_DSAparams (NULL, &p, plen))) { | ||
151 | EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR); | ||
152 | return NULL; | ||
153 | } | ||
154 | /* We have parameters now set private key */ | ||
155 | if (!(dsa->priv_key = ASN1_INTEGER_to_BN(dsapriv, NULL))) { | ||
156 | EVPerr(EVP_F_EVP_PKCS82PKEY,EVP_R_BN_DECODE_ERROR); | ||
157 | DSA_free (dsa); | ||
158 | return NULL; | ||
159 | } | ||
160 | /* Calculate public key (ouch!) */ | ||
161 | if (!(dsa->pub_key = BN_new())) { | ||
162 | EVPerr(EVP_F_EVP_PKCS82PKEY,ERR_R_MALLOC_FAILURE); | ||
163 | DSA_free (dsa); | ||
164 | return NULL; | ||
165 | } | ||
166 | if (!(ctx = BN_CTX_new())) { | ||
167 | EVPerr(EVP_F_EVP_PKCS82PKEY,ERR_R_MALLOC_FAILURE); | ||
168 | DSA_free (dsa); | ||
169 | return NULL; | ||
170 | } | ||
171 | |||
172 | if (!BN_mod_exp(dsa->pub_key, dsa->g, | ||
173 | dsa->priv_key, dsa->p, ctx)) { | ||
174 | |||
175 | EVPerr(EVP_F_EVP_PKCS82PKEY,EVP_R_BN_PUBKEY_ERROR); | ||
176 | BN_CTX_free (ctx); | ||
177 | DSA_free (dsa); | ||
178 | return NULL; | ||
179 | } | ||
180 | |||
181 | EVP_PKEY_assign_DSA (pkey, dsa); | ||
182 | BN_CTX_free (ctx); | ||
183 | break; | ||
184 | #endif | ||
185 | default: | ||
186 | EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM); | ||
187 | if (!a->algorithm) strcpy (obj_tmp, "NULL"); | ||
188 | else i2t_ASN1_OBJECT(obj_tmp, 80, a->algorithm); | ||
189 | ERR_add_error_data(2, "TYPE=", obj_tmp); | ||
190 | EVP_PKEY_free (pkey); | ||
191 | return NULL; | ||
192 | } | ||
193 | return pkey; | ||
194 | } | ||
195 | |||
196 | /* Turn a private key into a PKCS8 structure */ | ||
197 | |||
198 | PKCS8_PRIV_KEY_INFO *EVP_PKEY2PKCS8(EVP_PKEY *pkey) | ||
199 | { | ||
200 | PKCS8_PRIV_KEY_INFO *p8; | ||
201 | #ifndef NO_DSA | ||
202 | ASN1_INTEGER *dpkey; | ||
203 | unsigned char *p, *q; | ||
204 | int len; | ||
205 | #endif | ||
206 | if (!(p8 = PKCS8_PRIV_KEY_INFO_new())) { | ||
207 | EVPerr(EVP_F_EVP_PKEY2PKCS8,ERR_R_MALLOC_FAILURE); | ||
208 | return NULL; | ||
209 | } | ||
210 | ASN1_INTEGER_set (p8->version, 0); | ||
211 | if (!(p8->pkeyalg->parameter = ASN1_TYPE_new ())) { | ||
212 | EVPerr(EVP_F_EVP_PKEY2PKCS8,ERR_R_MALLOC_FAILURE); | ||
213 | PKCS8_PRIV_KEY_INFO_free (p8); | ||
214 | return NULL; | ||
215 | } | ||
216 | switch (EVP_PKEY_type(pkey->type)) { | ||
217 | #ifndef NO_RSA | ||
218 | case EVP_PKEY_RSA: | ||
219 | |||
220 | p8->pkeyalg->algorithm = OBJ_nid2obj(NID_rsaEncryption); | ||
221 | p8->pkeyalg->parameter->type = V_ASN1_NULL; | ||
222 | if (!ASN1_pack_string ((char *)pkey, i2d_PrivateKey, | ||
223 | &p8->pkey->value.octet_string)) { | ||
224 | EVPerr(EVP_F_EVP_PKEY2PKCS8,ERR_R_MALLOC_FAILURE); | ||
225 | PKCS8_PRIV_KEY_INFO_free (p8); | ||
226 | return NULL; | ||
227 | } | ||
228 | break; | ||
229 | #endif | ||
230 | #ifndef NO_DSA | ||
231 | case EVP_PKEY_DSA: | ||
232 | p8->pkeyalg->algorithm = OBJ_nid2obj(NID_dsa); | ||
233 | |||
234 | /* get paramaters and place in AlgorithmIdentifier */ | ||
235 | len = i2d_DSAparams (pkey->pkey.dsa, NULL); | ||
236 | if (!(p = Malloc(len))) { | ||
237 | EVPerr(EVP_F_EVP_PKEY2PKCS8,ERR_R_MALLOC_FAILURE); | ||
238 | PKCS8_PRIV_KEY_INFO_free (p8); | ||
239 | return NULL; | ||
240 | } | ||
241 | q = p; | ||
242 | i2d_DSAparams (pkey->pkey.dsa, &q); | ||
243 | p8->pkeyalg->parameter->type = V_ASN1_SEQUENCE; | ||
244 | p8->pkeyalg->parameter->value.sequence = ASN1_STRING_new(); | ||
245 | ASN1_STRING_set(p8->pkeyalg->parameter->value.sequence, p, len); | ||
246 | Free(p); | ||
247 | /* Get private key into an integer and pack */ | ||
248 | if (!(dpkey = BN_to_ASN1_INTEGER (pkey->pkey.dsa->priv_key, NULL))) { | ||
249 | EVPerr(EVP_F_EVP_PKEY2PKCS8,EVP_R_ENCODE_ERROR); | ||
250 | PKCS8_PRIV_KEY_INFO_free (p8); | ||
251 | return NULL; | ||
252 | } | ||
253 | |||
254 | if (!ASN1_pack_string((char *)dpkey, i2d_ASN1_INTEGER, | ||
255 | &p8->pkey->value.octet_string)) { | ||
256 | EVPerr(EVP_F_EVP_PKEY2PKCS8,ERR_R_MALLOC_FAILURE); | ||
257 | ASN1_INTEGER_free (dpkey); | ||
258 | PKCS8_PRIV_KEY_INFO_free (p8); | ||
259 | return NULL; | ||
260 | } | ||
261 | ASN1_INTEGER_free (dpkey); | ||
262 | break; | ||
263 | #endif | ||
264 | default: | ||
265 | EVPerr(EVP_F_EVP_PKEY2PKCS8, EVP_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM); | ||
266 | PKCS8_PRIV_KEY_INFO_free (p8); | ||
267 | return NULL; | ||
268 | } | ||
269 | p8->pkey->type = V_ASN1_OCTET_STRING; | ||
270 | RAND_seed (p8->pkey->value.octet_string->data, | ||
271 | p8->pkey->value.octet_string->length); | ||
272 | return p8; | ||
273 | } | ||
274 | |||
275 | PKCS8_PRIV_KEY_INFO *PKCS8_set_broken(PKCS8_PRIV_KEY_INFO *p8, int broken) | ||
276 | { | ||
277 | switch (broken) { | ||
278 | |||
279 | case PKCS8_OK: | ||
280 | p8->broken = PKCS8_OK; | ||
281 | return p8; | ||
282 | break; | ||
283 | |||
284 | case PKCS8_NO_OCTET: | ||
285 | p8->broken = PKCS8_NO_OCTET; | ||
286 | p8->pkey->type = V_ASN1_SEQUENCE; | ||
287 | return p8; | ||
288 | break; | ||
289 | |||
290 | default: | ||
291 | EVPerr(EVP_F_EVP_PKCS8_SET_BROKEN,EVP_R_PKCS8_UNKNOWN_BROKEN_TYPE); | ||
292 | return NULL; | ||
293 | break; | ||
294 | |||
295 | } | ||
296 | } | ||
297 | |||
298 | |||
diff --git a/src/lib/libcrypto/evp/m_md4.c b/src/lib/libcrypto/evp/m_md4.c new file mode 100644 index 0000000000..6a24ceb86d --- /dev/null +++ b/src/lib/libcrypto/evp/m_md4.c | |||
@@ -0,0 +1,83 @@ | |||
1 | /* crypto/evp/m_md4.c */ | ||
2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) | ||
3 | * All rights reserved. | ||
4 | * | ||
5 | * This package is an SSL implementation written | ||
6 | * by Eric Young (eay@cryptsoft.com). | ||
7 | * The implementation was written so as to conform with Netscapes SSL. | ||
8 | * | ||
9 | * This library is free for commercial and non-commercial use as long as | ||
10 | * the following conditions are aheared to. The following conditions | ||
11 | * apply to all code found in this distribution, be it the RC4, RSA, | ||
12 | * lhash, DES, etc., code; not just the SSL code. The SSL documentation | ||
13 | * included with this distribution is covered by the same copyright terms | ||
14 | * except that the holder is Tim Hudson (tjh@cryptsoft.com). | ||
15 | * | ||
16 | * Copyright remains Eric Young's, and as such any Copyright notices in | ||
17 | * the code are not to be removed. | ||
18 | * If this package is used in a product, Eric Young should be given attribution | ||
19 | * as the author of the parts of the library used. | ||
20 | * This can be in the form of a textual message at program startup or | ||
21 | * in documentation (online or textual) provided with the package. | ||
22 | * | ||
23 | * Redistribution and use in source and binary forms, with or without | ||
24 | * modification, are permitted provided that the following conditions | ||
25 | * are met: | ||
26 | * 1. Redistributions of source code must retain the copyright | ||
27 | * notice, this list of conditions and the following disclaimer. | ||
28 | * 2. Redistributions in binary form must reproduce the above copyright | ||
29 | * notice, this list of conditions and the following disclaimer in the | ||
30 | * documentation and/or other materials provided with the distribution. | ||
31 | * 3. All advertising materials mentioning features or use of this software | ||
32 | * must display the following acknowledgement: | ||
33 | * "This product includes cryptographic software written by | ||
34 | * Eric Young (eay@cryptsoft.com)" | ||
35 | * The word 'cryptographic' can be left out if the rouines from the library | ||
36 | * being used are not cryptographic related :-). | ||
37 | * 4. If you include any Windows specific code (or a derivative thereof) from | ||
38 | * the apps directory (application code) you must include an acknowledgement: | ||
39 | * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" | ||
40 | * | ||
41 | * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND | ||
42 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
43 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
44 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | ||
45 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
46 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
47 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
48 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
49 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
50 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
51 | * SUCH DAMAGE. | ||
52 | * | ||
53 | * The licence and distribution terms for any publically available version or | ||
54 | * derivative of this code cannot be changed. i.e. this code cannot simply be | ||
55 | * copied and put under another distribution licence | ||
56 | * [including the GNU Public Licence.] | ||
57 | */ | ||
58 | |||
59 | #ifndef NO_MD4 | ||
60 | #include <stdio.h> | ||
61 | #include "cryptlib.h" | ||
62 | #include <openssl/evp.h> | ||
63 | #include <openssl/objects.h> | ||
64 | #include <openssl/x509.h> | ||
65 | |||
66 | static EVP_MD md4_md= | ||
67 | { | ||
68 | NID_md4, | ||
69 | 0, | ||
70 | MD4_DIGEST_LENGTH, | ||
71 | MD4_Init, | ||
72 | MD4_Update, | ||
73 | MD4_Final, | ||
74 | EVP_PKEY_RSA_method, | ||
75 | MD4_CBLOCK, | ||
76 | sizeof(EVP_MD *)+sizeof(MD4_CTX), | ||
77 | }; | ||
78 | |||
79 | EVP_MD *EVP_md4(void) | ||
80 | { | ||
81 | return(&md4_md); | ||
82 | } | ||
83 | #endif | ||
diff --git a/src/lib/libcrypto/evp/p5_crpt.c b/src/lib/libcrypto/evp/p5_crpt.c new file mode 100644 index 0000000000..e3dae52d4d --- /dev/null +++ b/src/lib/libcrypto/evp/p5_crpt.c | |||
@@ -0,0 +1,146 @@ | |||
1 | /* p5_crpt.c */ | ||
2 | /* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL | ||
3 | * project 1999. | ||
4 | */ | ||
5 | /* ==================================================================== | ||
6 | * Copyright (c) 1999 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 | #include <stdlib.h> | ||
61 | #include <openssl/x509.h> | ||
62 | #include <openssl/evp.h> | ||
63 | #include "cryptlib.h" | ||
64 | |||
65 | /* PKCS#5 v1.5 compatible PBE functions: see PKCS#5 v2.0 for more info. | ||
66 | */ | ||
67 | |||
68 | void PKCS5_PBE_add(void) | ||
69 | { | ||
70 | #ifndef NO_DES | ||
71 | # ifndef NO_MD5 | ||
72 | EVP_PBE_alg_add(NID_pbeWithMD5AndDES_CBC, EVP_des_cbc(), EVP_md5(), | ||
73 | PKCS5_PBE_keyivgen); | ||
74 | # endif | ||
75 | # ifndef NO_MD2 | ||
76 | EVP_PBE_alg_add(NID_pbeWithMD2AndDES_CBC, EVP_des_cbc(), EVP_md2(), | ||
77 | PKCS5_PBE_keyivgen); | ||
78 | # endif | ||
79 | # ifndef NO_SHA | ||
80 | EVP_PBE_alg_add(NID_pbeWithSHA1AndDES_CBC, EVP_des_cbc(), EVP_sha1(), | ||
81 | PKCS5_PBE_keyivgen); | ||
82 | # endif | ||
83 | #endif | ||
84 | #ifndef NO_RC2 | ||
85 | # ifndef NO_MD5 | ||
86 | EVP_PBE_alg_add(NID_pbeWithMD5AndRC2_CBC, EVP_rc2_64_cbc(), EVP_md5(), | ||
87 | PKCS5_PBE_keyivgen); | ||
88 | # endif | ||
89 | # ifndef NO_MD2 | ||
90 | EVP_PBE_alg_add(NID_pbeWithMD2AndRC2_CBC, EVP_rc2_64_cbc(), EVP_md2(), | ||
91 | PKCS5_PBE_keyivgen); | ||
92 | # endif | ||
93 | # ifndef NO_SHA | ||
94 | EVP_PBE_alg_add(NID_pbeWithSHA1AndRC2_CBC, EVP_rc2_64_cbc(), EVP_sha1(), | ||
95 | PKCS5_PBE_keyivgen); | ||
96 | # endif | ||
97 | #endif | ||
98 | #ifndef NO_HMAC | ||
99 | EVP_PBE_alg_add(NID_pbes2, NULL, NULL, PKCS5_v2_PBE_keyivgen); | ||
100 | #endif | ||
101 | } | ||
102 | |||
103 | int PKCS5_PBE_keyivgen(EVP_CIPHER_CTX *cctx, const char *pass, int passlen, | ||
104 | ASN1_TYPE *param, EVP_CIPHER *cipher, EVP_MD *md, | ||
105 | int en_de) | ||
106 | { | ||
107 | EVP_MD_CTX ctx; | ||
108 | unsigned char md_tmp[EVP_MAX_MD_SIZE]; | ||
109 | unsigned char key[EVP_MAX_KEY_LENGTH], iv[EVP_MAX_IV_LENGTH]; | ||
110 | int i; | ||
111 | PBEPARAM *pbe; | ||
112 | int saltlen, iter; | ||
113 | unsigned char *salt, *pbuf; | ||
114 | |||
115 | /* Extract useful info from parameter */ | ||
116 | pbuf = param->value.sequence->data; | ||
117 | if (!param || (param->type != V_ASN1_SEQUENCE) || | ||
118 | !(pbe = d2i_PBEPARAM (NULL, &pbuf, param->value.sequence->length))) { | ||
119 | EVPerr(EVP_F_PKCS5_PBE_KEYIVGEN,EVP_R_DECODE_ERROR); | ||
120 | return 0; | ||
121 | } | ||
122 | |||
123 | if (!pbe->iter) iter = 1; | ||
124 | else iter = ASN1_INTEGER_get (pbe->iter); | ||
125 | salt = pbe->salt->data; | ||
126 | saltlen = pbe->salt->length; | ||
127 | |||
128 | EVP_DigestInit (&ctx, md); | ||
129 | EVP_DigestUpdate (&ctx, pass, passlen); | ||
130 | EVP_DigestUpdate (&ctx, salt, saltlen); | ||
131 | PBEPARAM_free(pbe); | ||
132 | EVP_DigestFinal (&ctx, md_tmp, NULL); | ||
133 | for (i = 1; i < iter; i++) { | ||
134 | EVP_DigestInit(&ctx, md); | ||
135 | EVP_DigestUpdate(&ctx, md_tmp, EVP_MD_size(md)); | ||
136 | EVP_DigestFinal (&ctx, md_tmp, NULL); | ||
137 | } | ||
138 | memcpy (key, md_tmp, EVP_CIPHER_key_length(cipher)); | ||
139 | memcpy (iv, md_tmp + (16 - EVP_CIPHER_iv_length(cipher)), | ||
140 | EVP_CIPHER_iv_length(cipher)); | ||
141 | EVP_CipherInit(cctx, cipher, key, iv, en_de); | ||
142 | memset(md_tmp, 0, EVP_MAX_MD_SIZE); | ||
143 | memset(key, 0, EVP_MAX_KEY_LENGTH); | ||
144 | memset(iv, 0, EVP_MAX_IV_LENGTH); | ||
145 | return 1; | ||
146 | } | ||
diff --git a/src/lib/libcrypto/evp/p5_crpt2.c b/src/lib/libcrypto/evp/p5_crpt2.c new file mode 100644 index 0000000000..27a2c518be --- /dev/null +++ b/src/lib/libcrypto/evp/p5_crpt2.c | |||
@@ -0,0 +1,247 @@ | |||
1 | /* p5_crpt2.c */ | ||
2 | /* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL | ||
3 | * project 1999. | ||
4 | */ | ||
5 | /* ==================================================================== | ||
6 | * Copyright (c) 1999 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 | #if !defined(NO_HMAC) && !defined(NO_SHA) | ||
59 | #include <stdio.h> | ||
60 | #include <stdlib.h> | ||
61 | #include <openssl/x509.h> | ||
62 | #include <openssl/evp.h> | ||
63 | #include <openssl/hmac.h> | ||
64 | #include "cryptlib.h" | ||
65 | |||
66 | /* set this to print out info about the keygen algorithm */ | ||
67 | /* #define DEBUG_PKCS5V2 */ | ||
68 | |||
69 | #ifdef DEBUG_PKCS5V2 | ||
70 | static void h__dump (const unsigned char *p, int len); | ||
71 | #endif | ||
72 | |||
73 | /* This is an implementation of PKCS#5 v2.0 password based encryption key | ||
74 | * derivation function PBKDF2 using the only currently defined function HMAC | ||
75 | * with SHA1. Verified against test vectors posted by Peter Gutmann | ||
76 | * <pgut001@cs.auckland.ac.nz> to the PKCS-TNG <pkcs-tng@rsa.com> mailing list. | ||
77 | */ | ||
78 | |||
79 | int PKCS5_PBKDF2_HMAC_SHA1(const char *pass, int passlen, | ||
80 | unsigned char *salt, int saltlen, int iter, | ||
81 | int keylen, unsigned char *out) | ||
82 | { | ||
83 | unsigned char digtmp[SHA_DIGEST_LENGTH], *p, itmp[4]; | ||
84 | int cplen, j, k, tkeylen; | ||
85 | unsigned long i = 1; | ||
86 | HMAC_CTX hctx; | ||
87 | p = out; | ||
88 | tkeylen = keylen; | ||
89 | if(passlen == -1) passlen = strlen(pass); | ||
90 | while(tkeylen) { | ||
91 | if(tkeylen > SHA_DIGEST_LENGTH) cplen = SHA_DIGEST_LENGTH; | ||
92 | else cplen = tkeylen; | ||
93 | /* We are unlikely to ever use more than 256 blocks (5120 bits!) | ||
94 | * but just in case... | ||
95 | */ | ||
96 | itmp[0] = (unsigned char)((i >> 24) & 0xff); | ||
97 | itmp[1] = (unsigned char)((i >> 16) & 0xff); | ||
98 | itmp[2] = (unsigned char)((i >> 8) & 0xff); | ||
99 | itmp[3] = (unsigned char)(i & 0xff); | ||
100 | HMAC_Init(&hctx, pass, passlen, EVP_sha1()); | ||
101 | HMAC_Update(&hctx, salt, saltlen); | ||
102 | HMAC_Update(&hctx, itmp, 4); | ||
103 | HMAC_Final(&hctx, digtmp, NULL); | ||
104 | memcpy(p, digtmp, cplen); | ||
105 | for(j = 1; j < iter; j++) { | ||
106 | HMAC(EVP_sha1(), pass, passlen, | ||
107 | digtmp, SHA_DIGEST_LENGTH, digtmp, NULL); | ||
108 | for(k = 0; k < cplen; k++) p[k] ^= digtmp[k]; | ||
109 | } | ||
110 | tkeylen-= cplen; | ||
111 | i++; | ||
112 | p+= cplen; | ||
113 | } | ||
114 | HMAC_cleanup(&hctx); | ||
115 | #ifdef DEBUG_PKCS5V2 | ||
116 | fprintf(stderr, "Password:\n"); | ||
117 | h__dump (pass, passlen); | ||
118 | fprintf(stderr, "Salt:\n"); | ||
119 | h__dump (salt, saltlen); | ||
120 | fprintf(stderr, "Iteration count %d\n", iter); | ||
121 | fprintf(stderr, "Key:\n"); | ||
122 | h__dump (out, keylen); | ||
123 | #endif | ||
124 | return 1; | ||
125 | } | ||
126 | |||
127 | #ifdef DO_TEST | ||
128 | main() | ||
129 | { | ||
130 | unsigned char out[4]; | ||
131 | unsigned char salt[] = {0x12, 0x34, 0x56, 0x78}; | ||
132 | PKCS5_PBKDF2_HMAC_SHA1("password", -1, salt, 4, 5, 4, out); | ||
133 | fprintf(stderr, "Out %02X %02X %02X %02X\n", | ||
134 | out[0], out[1], out[2], out[3]); | ||
135 | } | ||
136 | |||
137 | #endif | ||
138 | |||
139 | /* Now the key derivation function itself. This is a bit evil because | ||
140 | * it has to check the ASN1 parameters are valid: and there are quite a | ||
141 | * few of them... | ||
142 | */ | ||
143 | |||
144 | int PKCS5_v2_PBE_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen, | ||
145 | ASN1_TYPE *param, EVP_CIPHER *c, EVP_MD *md, | ||
146 | int en_de) | ||
147 | { | ||
148 | unsigned char *pbuf, *salt, key[EVP_MAX_KEY_LENGTH]; | ||
149 | int saltlen, keylen, iter, plen; | ||
150 | PBE2PARAM *pbe2 = NULL; | ||
151 | const EVP_CIPHER *cipher; | ||
152 | PBKDF2PARAM *kdf = NULL; | ||
153 | |||
154 | pbuf = param->value.sequence->data; | ||
155 | plen = param->value.sequence->length; | ||
156 | if(!param || (param->type != V_ASN1_SEQUENCE) || | ||
157 | !(pbe2 = d2i_PBE2PARAM(NULL, &pbuf, plen))) { | ||
158 | EVPerr(EVP_F_PKCS5_V2_PBE_KEYIVGEN,EVP_R_DECODE_ERROR); | ||
159 | return 0; | ||
160 | } | ||
161 | |||
162 | /* See if we recognise the key derivation function */ | ||
163 | |||
164 | if(OBJ_obj2nid(pbe2->keyfunc->algorithm) != NID_id_pbkdf2) { | ||
165 | EVPerr(EVP_F_PKCS5_V2_PBE_KEYIVGEN, | ||
166 | EVP_R_UNSUPPORTED_KEY_DERIVATION_FUNCTION); | ||
167 | goto err; | ||
168 | } | ||
169 | |||
170 | /* lets see if we recognise the encryption algorithm. | ||
171 | */ | ||
172 | |||
173 | cipher = EVP_get_cipherbyname( | ||
174 | OBJ_nid2sn(OBJ_obj2nid(pbe2->encryption->algorithm))); | ||
175 | |||
176 | if(!cipher) { | ||
177 | EVPerr(EVP_F_PKCS5_V2_PBE_KEYIVGEN, | ||
178 | EVP_R_UNSUPPORTED_CIPHER); | ||
179 | goto err; | ||
180 | } | ||
181 | |||
182 | /* Fixup cipher based on AlgorithmIdentifier */ | ||
183 | EVP_CipherInit(ctx, cipher, NULL, NULL, en_de); | ||
184 | if(EVP_CIPHER_asn1_to_param(ctx, pbe2->encryption->parameter) < 0) { | ||
185 | EVPerr(EVP_F_PKCS5_V2_PBE_KEYIVGEN, | ||
186 | EVP_R_CIPHER_PARAMETER_ERROR); | ||
187 | goto err; | ||
188 | } | ||
189 | keylen = EVP_CIPHER_CTX_key_length(ctx); | ||
190 | |||
191 | /* Now decode key derivation function */ | ||
192 | |||
193 | pbuf = pbe2->keyfunc->parameter->value.sequence->data; | ||
194 | plen = pbe2->keyfunc->parameter->value.sequence->length; | ||
195 | if(!pbe2->keyfunc->parameter || | ||
196 | (pbe2->keyfunc->parameter->type != V_ASN1_SEQUENCE) || | ||
197 | !(kdf = d2i_PBKDF2PARAM(NULL, &pbuf, plen)) ) { | ||
198 | EVPerr(EVP_F_PKCS5_V2_PBE_KEYIVGEN,EVP_R_DECODE_ERROR); | ||
199 | goto err; | ||
200 | } | ||
201 | |||
202 | PBE2PARAM_free(pbe2); | ||
203 | pbe2 = NULL; | ||
204 | |||
205 | /* Now check the parameters of the kdf */ | ||
206 | |||
207 | if(kdf->keylength && (ASN1_INTEGER_get(kdf->keylength) != keylen)){ | ||
208 | EVPerr(EVP_F_PKCS5_V2_PBE_KEYIVGEN, | ||
209 | EVP_R_UNSUPPORTED_KEYLENGTH); | ||
210 | goto err; | ||
211 | } | ||
212 | |||
213 | if(kdf->prf && (OBJ_obj2nid(kdf->prf->algorithm) != NID_hmacWithSHA1)) { | ||
214 | EVPerr(EVP_F_PKCS5_V2_PBE_KEYIVGEN, EVP_R_UNSUPPORTED_PRF); | ||
215 | goto err; | ||
216 | } | ||
217 | |||
218 | if(kdf->salt->type != V_ASN1_OCTET_STRING) { | ||
219 | EVPerr(EVP_F_PKCS5_V2_PBE_KEYIVGEN, | ||
220 | EVP_R_UNSUPPORTED_SALT_TYPE); | ||
221 | goto err; | ||
222 | } | ||
223 | |||
224 | /* it seems that its all OK */ | ||
225 | salt = kdf->salt->value.octet_string->data; | ||
226 | saltlen = kdf->salt->value.octet_string->length; | ||
227 | iter = ASN1_INTEGER_get(kdf->iter); | ||
228 | PKCS5_PBKDF2_HMAC_SHA1(pass, passlen, salt, saltlen, iter, keylen, key); | ||
229 | EVP_CipherInit(ctx, NULL, key, NULL, en_de); | ||
230 | memset(key, 0, keylen); | ||
231 | PBKDF2PARAM_free(kdf); | ||
232 | return 1; | ||
233 | |||
234 | err: | ||
235 | PBE2PARAM_free(pbe2); | ||
236 | PBKDF2PARAM_free(kdf); | ||
237 | return 0; | ||
238 | } | ||
239 | |||
240 | #ifdef DEBUG_PKCS5V2 | ||
241 | static void h__dump (const unsigned char *p, int len) | ||
242 | { | ||
243 | for (; len --; p++) fprintf(stderr, "%02X ", *p); | ||
244 | fprintf(stderr, "\n"); | ||
245 | } | ||
246 | #endif | ||
247 | #endif | ||
diff --git a/src/lib/libcrypto/idea/idea.h b/src/lib/libcrypto/idea/idea.h new file mode 100644 index 0000000000..ae32f5692e --- /dev/null +++ b/src/lib/libcrypto/idea/idea.h | |||
@@ -0,0 +1,99 @@ | |||
1 | /* crypto/idea/idea.h */ | ||
2 | /* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) | ||
3 | * All rights reserved. | ||
4 | * | ||
5 | * This package is an SSL implementation written | ||
6 | * by Eric Young (eay@cryptsoft.com). | ||
7 | * The implementation was written so as to conform with Netscapes SSL. | ||
8 | * | ||
9 | * This library is free for commercial and non-commercial use as long as | ||
10 | * the following conditions are aheared to. The following conditions | ||
11 | * apply to all code found in this distribution, be it the RC4, RSA, | ||
12 | * lhash, DES, etc., code; not just the SSL code. The SSL documentation | ||
13 | * included with this distribution is covered by the same copyright terms | ||
14 | * except that the holder is Tim Hudson (tjh@cryptsoft.com). | ||
15 | * | ||
16 | * Copyright remains Eric Young's, and as such any Copyright notices in | ||
17 | * the code are not to be removed. | ||
18 | * If this package is used in a product, Eric Young should be given attribution | ||
19 | * as the author of the parts of the library used. | ||
20 | * This can be in the form of a textual message at program startup or | ||
21 | * in documentation (online or textual) provided with the package. | ||
22 | * | ||
23 | * Redistribution and use in source and binary forms, with or without | ||
24 | * modification, are permitted provided that the following conditions | ||
25 | * are met: | ||
26 | * 1. Redistributions of source code must retain the copyright | ||
27 | * notice, this list of conditions and the following disclaimer. | ||
28 | * 2. Redistributions in binary form must reproduce the above copyright | ||
29 | * notice, this list of conditions and the following disclaimer in the | ||
30 | * documentation and/or other materials provided with the distribution. | ||
31 | * 3. All advertising materials mentioning features or use of this software | ||
32 | * must display the following acknowledgement: | ||
33 | * "This product includes cryptographic software written by | ||
34 | * Eric Young (eay@cryptsoft.com)" | ||
35 | * The word 'cryptographic' can be left out if the rouines from the library | ||
36 | * being used are not cryptographic related :-). | ||
37 | * 4. If you include any Windows specific code (or a derivative thereof) from | ||
38 | * the apps directory (application code) you must include an acknowledgement: | ||
39 | * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" | ||
40 | * | ||
41 | * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND | ||
42 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
43 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
44 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | ||
45 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
46 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
47 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
48 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
49 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
50 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
51 | * SUCH DAMAGE. | ||
52 | * | ||
53 | * The licence and distribution terms for any publically available version or | ||
54 | * derivative of this code cannot be changed. i.e. this code cannot simply be | ||
55 | * copied and put under another distribution licence | ||
56 | * [including the GNU Public Licence.] | ||
57 | */ | ||
58 | |||
59 | #ifndef HEADER_IDEA_H | ||
60 | #define HEADER_IDEA_H | ||
61 | |||
62 | #ifdef __cplusplus | ||
63 | extern "C" { | ||
64 | #endif | ||
65 | |||
66 | #ifdef NO_IDEA | ||
67 | #error IDEA is disabled. | ||
68 | #endif | ||
69 | |||
70 | #define IDEA_ENCRYPT 1 | ||
71 | #define IDEA_DECRYPT 0 | ||
72 | |||
73 | #include <openssl/opensslconf.h> /* IDEA_INT */ | ||
74 | #define IDEA_BLOCK 8 | ||
75 | #define IDEA_KEY_LENGTH 16 | ||
76 | |||
77 | typedef struct idea_key_st | ||
78 | { | ||
79 | IDEA_INT data[9][6]; | ||
80 | } IDEA_KEY_SCHEDULE; | ||
81 | |||
82 | const char *idea_options(void); | ||
83 | void idea_ecb_encrypt(unsigned char *in, unsigned char *out, | ||
84 | IDEA_KEY_SCHEDULE *ks); | ||
85 | void idea_set_encrypt_key(unsigned char *key, IDEA_KEY_SCHEDULE *ks); | ||
86 | void idea_set_decrypt_key(IDEA_KEY_SCHEDULE *ek, IDEA_KEY_SCHEDULE *dk); | ||
87 | void idea_cbc_encrypt(unsigned char *in, unsigned char *out, | ||
88 | long length, IDEA_KEY_SCHEDULE *ks, unsigned char *iv,int enc); | ||
89 | void idea_cfb64_encrypt(unsigned char *in, unsigned char *out, | ||
90 | long length, IDEA_KEY_SCHEDULE *ks, unsigned char *iv, | ||
91 | int *num,int enc); | ||
92 | void idea_ofb64_encrypt(unsigned char *in, unsigned char *out, | ||
93 | long length, IDEA_KEY_SCHEDULE *ks, unsigned char *iv, int *num); | ||
94 | void idea_encrypt(unsigned long *in, IDEA_KEY_SCHEDULE *ks); | ||
95 | #ifdef __cplusplus | ||
96 | } | ||
97 | #endif | ||
98 | |||
99 | #endif | ||
diff --git a/src/lib/libcrypto/krb5/krb5_asn.c b/src/lib/libcrypto/krb5/krb5_asn.c new file mode 100644 index 0000000000..1fb741d2a0 --- /dev/null +++ b/src/lib/libcrypto/krb5/krb5_asn.c | |||
@@ -0,0 +1,167 @@ | |||
1 | /* krb5_asn.c */ | ||
2 | /* Written by Vern Staats <staatsvr@asc.hpc.mil> for the OpenSSL project, | ||
3 | ** using ocsp/{*.h,*asn*.c} as a starting point | ||
4 | */ | ||
5 | /* ==================================================================== | ||
6 | * Copyright (c) 2000 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 | #include <openssl/asn1.h> | ||
59 | #include <openssl/asn1t.h> | ||
60 | #include <openssl/krb5_asn.h> | ||
61 | |||
62 | |||
63 | ASN1_SEQUENCE(KRB5_ENCDATA) = { | ||
64 | ASN1_EXP(KRB5_ENCDATA, etype, ASN1_INTEGER, 0), | ||
65 | ASN1_EXP_OPT(KRB5_ENCDATA, kvno, ASN1_INTEGER, 1), | ||
66 | ASN1_EXP(KRB5_ENCDATA, cipher, ASN1_OCTET_STRING,2) | ||
67 | } ASN1_SEQUENCE_END(KRB5_ENCDATA) | ||
68 | |||
69 | IMPLEMENT_ASN1_FUNCTIONS(KRB5_ENCDATA) | ||
70 | |||
71 | |||
72 | ASN1_SEQUENCE(KRB5_PRINCNAME) = { | ||
73 | ASN1_EXP(KRB5_PRINCNAME, nametype, ASN1_INTEGER, 0), | ||
74 | ASN1_EXP_SEQUENCE_OF(KRB5_PRINCNAME, namestring, ASN1_GENERALSTRING, 1) | ||
75 | } ASN1_SEQUENCE_END(KRB5_PRINCNAME) | ||
76 | |||
77 | IMPLEMENT_ASN1_FUNCTIONS(KRB5_PRINCNAME) | ||
78 | |||
79 | |||
80 | /* [APPLICATION 1] = 0x61 */ | ||
81 | ASN1_SEQUENCE(KRB5_TKTBODY) = { | ||
82 | ASN1_EXP(KRB5_TKTBODY, tktvno, ASN1_INTEGER, 0), | ||
83 | ASN1_EXP(KRB5_TKTBODY, realm, ASN1_GENERALSTRING, 1), | ||
84 | ASN1_EXP(KRB5_TKTBODY, sname, KRB5_PRINCNAME, 2), | ||
85 | ASN1_EXP(KRB5_TKTBODY, encdata, KRB5_ENCDATA, 3) | ||
86 | } ASN1_SEQUENCE_END(KRB5_TKTBODY) | ||
87 | |||
88 | IMPLEMENT_ASN1_FUNCTIONS(KRB5_TKTBODY) | ||
89 | |||
90 | |||
91 | ASN1_ITEM_TEMPLATE(KRB5_TICKET) = | ||
92 | ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_EXPTAG|ASN1_TFLG_APPLICATION, 1, | ||
93 | KRB5_TICKET, KRB5_TKTBODY) | ||
94 | ASN1_ITEM_TEMPLATE_END(KRB5_TICKET) | ||
95 | |||
96 | IMPLEMENT_ASN1_FUNCTIONS(KRB5_TICKET) | ||
97 | |||
98 | |||
99 | /* [APPLICATION 14] = 0x6e */ | ||
100 | ASN1_SEQUENCE(KRB5_APREQBODY) = { | ||
101 | ASN1_EXP(KRB5_APREQBODY, pvno, ASN1_INTEGER, 0), | ||
102 | ASN1_EXP(KRB5_APREQBODY, msgtype, ASN1_INTEGER, 1), | ||
103 | ASN1_EXP(KRB5_APREQBODY, apoptions, ASN1_BIT_STRING, 2), | ||
104 | ASN1_EXP(KRB5_APREQBODY, ticket, KRB5_TICKET, 3), | ||
105 | ASN1_EXP(KRB5_APREQBODY, authenticator, KRB5_ENCDATA, 4), | ||
106 | } ASN1_SEQUENCE_END(KRB5_APREQBODY) | ||
107 | |||
108 | IMPLEMENT_ASN1_FUNCTIONS(KRB5_APREQBODY) | ||
109 | |||
110 | ASN1_ITEM_TEMPLATE(KRB5_APREQ) = | ||
111 | ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_EXPTAG|ASN1_TFLG_APPLICATION, 14, | ||
112 | KRB5_APREQ, KRB5_APREQBODY) | ||
113 | ASN1_ITEM_TEMPLATE_END(KRB5_APREQ) | ||
114 | |||
115 | IMPLEMENT_ASN1_FUNCTIONS(KRB5_APREQ) | ||
116 | |||
117 | |||
118 | /* Authenticator stuff */ | ||
119 | |||
120 | ASN1_SEQUENCE(KRB5_CHECKSUM) = { | ||
121 | ASN1_EXP(KRB5_CHECKSUM, ctype, ASN1_INTEGER, 0), | ||
122 | ASN1_EXP(KRB5_CHECKSUM, checksum, ASN1_OCTET_STRING,1) | ||
123 | } ASN1_SEQUENCE_END(KRB5_CHECKSUM) | ||
124 | |||
125 | IMPLEMENT_ASN1_FUNCTIONS(KRB5_CHECKSUM) | ||
126 | |||
127 | |||
128 | ASN1_SEQUENCE(KRB5_ENCKEY) = { | ||
129 | ASN1_EXP(KRB5_ENCKEY, ktype, ASN1_INTEGER, 0), | ||
130 | ASN1_EXP(KRB5_ENCKEY, keyvalue, ASN1_OCTET_STRING,1) | ||
131 | } ASN1_SEQUENCE_END(KRB5_ENCKEY) | ||
132 | |||
133 | IMPLEMENT_ASN1_FUNCTIONS(KRB5_ENCKEY) | ||
134 | |||
135 | |||
136 | /* SEQ OF SEQ; see ASN1_EXP_SEQUENCE_OF_OPT() below */ | ||
137 | ASN1_SEQUENCE(KRB5_AUTHDATA) = { | ||
138 | ASN1_EXP(KRB5_AUTHDATA, adtype, ASN1_INTEGER, 0), | ||
139 | ASN1_EXP(KRB5_AUTHDATA, addata, ASN1_OCTET_STRING,1) | ||
140 | } ASN1_SEQUENCE_END(KRB5_AUTHDATA) | ||
141 | |||
142 | IMPLEMENT_ASN1_FUNCTIONS(KRB5_AUTHDATA) | ||
143 | |||
144 | |||
145 | /* [APPLICATION 2] = 0x62 */ | ||
146 | ASN1_SEQUENCE(KRB5_AUTHENTBODY) = { | ||
147 | ASN1_EXP(KRB5_AUTHENTBODY, avno, ASN1_INTEGER, 0), | ||
148 | ASN1_EXP(KRB5_AUTHENTBODY, crealm, ASN1_GENERALSTRING, 1), | ||
149 | ASN1_EXP(KRB5_AUTHENTBODY, cname, KRB5_PRINCNAME, 2), | ||
150 | ASN1_EXP_OPT(KRB5_AUTHENTBODY, cksum, KRB5_CHECKSUM, 3), | ||
151 | ASN1_EXP(KRB5_AUTHENTBODY, cusec, ASN1_INTEGER, 4), | ||
152 | ASN1_EXP(KRB5_AUTHENTBODY, ctime, ASN1_GENERALIZEDTIME, 5), | ||
153 | ASN1_EXP_OPT(KRB5_AUTHENTBODY, subkey, KRB5_ENCKEY, 6), | ||
154 | ASN1_EXP_OPT(KRB5_AUTHENTBODY, seqnum, ASN1_INTEGER, 7), | ||
155 | ASN1_EXP_SEQUENCE_OF_OPT | ||
156 | (KRB5_AUTHENTBODY, authorization, KRB5_AUTHDATA, 8), | ||
157 | } ASN1_SEQUENCE_END(KRB5_AUTHENTBODY) | ||
158 | |||
159 | IMPLEMENT_ASN1_FUNCTIONS(KRB5_AUTHENTBODY) | ||
160 | |||
161 | ASN1_ITEM_TEMPLATE(KRB5_AUTHENT) = | ||
162 | ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_EXPTAG|ASN1_TFLG_APPLICATION, 2, | ||
163 | KRB5_AUTHENT, KRB5_AUTHENTBODY) | ||
164 | ASN1_ITEM_TEMPLATE_END(KRB5_AUTHENT) | ||
165 | |||
166 | IMPLEMENT_ASN1_FUNCTIONS(KRB5_AUTHENT) | ||
167 | |||
diff --git a/src/lib/libcrypto/krb5/krb5_asn.h b/src/lib/libcrypto/krb5/krb5_asn.h new file mode 100644 index 0000000000..3329477b07 --- /dev/null +++ b/src/lib/libcrypto/krb5/krb5_asn.h | |||
@@ -0,0 +1,256 @@ | |||
1 | /* krb5_asn.h */ | ||
2 | /* Written by Vern Staats <staatsvr@asc.hpc.mil> for the OpenSSL project, | ||
3 | ** using ocsp/{*.h,*asn*.c} as a starting point | ||
4 | */ | ||
5 | |||
6 | /* ==================================================================== | ||
7 | * Copyright (c) 1998-2000 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_KRB5_ASN_H | ||
61 | #define HEADER_KRB5_ASN_H | ||
62 | |||
63 | /* | ||
64 | #include <krb5.h> | ||
65 | */ | ||
66 | #include <openssl/safestack.h> | ||
67 | |||
68 | #ifdef __cplusplus | ||
69 | extern "C" { | ||
70 | #endif | ||
71 | |||
72 | |||
73 | /* ASN.1 from Kerberos RFC 1510 | ||
74 | */ | ||
75 | |||
76 | /* EncryptedData ::= SEQUENCE { | ||
77 | ** etype[0] INTEGER, -- EncryptionType | ||
78 | ** kvno[1] INTEGER OPTIONAL, | ||
79 | ** cipher[2] OCTET STRING -- ciphertext | ||
80 | ** } | ||
81 | */ | ||
82 | typedef struct krb5_encdata_st | ||
83 | { | ||
84 | ASN1_INTEGER *etype; | ||
85 | ASN1_INTEGER *kvno; | ||
86 | ASN1_OCTET_STRING *cipher; | ||
87 | } KRB5_ENCDATA; | ||
88 | |||
89 | DECLARE_STACK_OF(KRB5_ENCDATA) | ||
90 | |||
91 | /* PrincipalName ::= SEQUENCE { | ||
92 | ** name-type[0] INTEGER, | ||
93 | ** name-string[1] SEQUENCE OF GeneralString | ||
94 | ** } | ||
95 | */ | ||
96 | typedef struct krb5_princname_st | ||
97 | { | ||
98 | ASN1_INTEGER *nametype; | ||
99 | STACK_OF(ASN1_GENERALSTRING) *namestring; | ||
100 | } KRB5_PRINCNAME; | ||
101 | |||
102 | DECLARE_STACK_OF(KRB5_PRINCNAME) | ||
103 | |||
104 | |||
105 | /* Ticket ::= [APPLICATION 1] SEQUENCE { | ||
106 | ** tkt-vno[0] INTEGER, | ||
107 | ** realm[1] Realm, | ||
108 | ** sname[2] PrincipalName, | ||
109 | ** enc-part[3] EncryptedData | ||
110 | ** } | ||
111 | */ | ||
112 | typedef struct krb5_tktbody_st | ||
113 | { | ||
114 | ASN1_INTEGER *tktvno; | ||
115 | ASN1_GENERALSTRING *realm; | ||
116 | KRB5_PRINCNAME *sname; | ||
117 | KRB5_ENCDATA *encdata; | ||
118 | } KRB5_TKTBODY; | ||
119 | |||
120 | typedef STACK_OF(KRB5_TKTBODY) KRB5_TICKET; | ||
121 | DECLARE_STACK_OF(KRB5_TKTBODY) | ||
122 | |||
123 | |||
124 | /* AP-REQ ::= [APPLICATION 14] SEQUENCE { | ||
125 | ** pvno[0] INTEGER, | ||
126 | ** msg-type[1] INTEGER, | ||
127 | ** ap-options[2] APOptions, | ||
128 | ** ticket[3] Ticket, | ||
129 | ** authenticator[4] EncryptedData | ||
130 | ** } | ||
131 | ** | ||
132 | ** APOptions ::= BIT STRING { | ||
133 | ** reserved(0), use-session-key(1), mutual-required(2) } | ||
134 | */ | ||
135 | typedef struct krb5_ap_req_st | ||
136 | { | ||
137 | ASN1_INTEGER *pvno; | ||
138 | ASN1_INTEGER *msgtype; | ||
139 | ASN1_BIT_STRING *apoptions; | ||
140 | KRB5_TICKET *ticket; | ||
141 | KRB5_ENCDATA *authenticator; | ||
142 | } KRB5_APREQBODY; | ||
143 | |||
144 | typedef STACK_OF(KRB5_APREQBODY) KRB5_APREQ; | ||
145 | DECLARE_STACK_OF(KRB5_APREQBODY) | ||
146 | |||
147 | |||
148 | /* Authenticator Stuff */ | ||
149 | |||
150 | |||
151 | /* Checksum ::= SEQUENCE { | ||
152 | ** cksumtype[0] INTEGER, | ||
153 | ** checksum[1] OCTET STRING | ||
154 | ** } | ||
155 | */ | ||
156 | typedef struct krb5_checksum_st | ||
157 | { | ||
158 | ASN1_INTEGER *ctype; | ||
159 | ASN1_OCTET_STRING *checksum; | ||
160 | } KRB5_CHECKSUM; | ||
161 | |||
162 | DECLARE_STACK_OF(KRB5_CHECKSUM) | ||
163 | |||
164 | |||
165 | /* EncryptionKey ::= SEQUENCE { | ||
166 | ** keytype[0] INTEGER, | ||
167 | ** keyvalue[1] OCTET STRING | ||
168 | ** } | ||
169 | */ | ||
170 | typedef struct krb5_encryptionkey_st | ||
171 | { | ||
172 | ASN1_INTEGER *ktype; | ||
173 | ASN1_OCTET_STRING *keyvalue; | ||
174 | } KRB5_ENCKEY; | ||
175 | |||
176 | DECLARE_STACK_OF(KRB5_ENCKEY) | ||
177 | |||
178 | |||
179 | /* AuthorizationData ::= SEQUENCE OF SEQUENCE { | ||
180 | ** ad-type[0] INTEGER, | ||
181 | ** ad-data[1] OCTET STRING | ||
182 | ** } | ||
183 | */ | ||
184 | typedef struct krb5_authorization_st | ||
185 | { | ||
186 | ASN1_INTEGER *adtype; | ||
187 | ASN1_OCTET_STRING *addata; | ||
188 | } KRB5_AUTHDATA; | ||
189 | |||
190 | DECLARE_STACK_OF(KRB5_AUTHDATA) | ||
191 | |||
192 | |||
193 | /* -- Unencrypted authenticator | ||
194 | ** Authenticator ::= [APPLICATION 2] SEQUENCE { | ||
195 | ** authenticator-vno[0] INTEGER, | ||
196 | ** crealm[1] Realm, | ||
197 | ** cname[2] PrincipalName, | ||
198 | ** cksum[3] Checksum OPTIONAL, | ||
199 | ** cusec[4] INTEGER, | ||
200 | ** ctime[5] KerberosTime, | ||
201 | ** subkey[6] EncryptionKey OPTIONAL, | ||
202 | ** seq-number[7] INTEGER OPTIONAL, | ||
203 | ** authorization-data[8] AuthorizationData OPTIONAL | ||
204 | ** } | ||
205 | */ | ||
206 | typedef struct krb5_authenticator_st | ||
207 | { | ||
208 | ASN1_INTEGER *avno; | ||
209 | ASN1_GENERALSTRING *crealm; | ||
210 | KRB5_PRINCNAME *cname; | ||
211 | KRB5_CHECKSUM *cksum; | ||
212 | ASN1_INTEGER *cusec; | ||
213 | ASN1_GENERALIZEDTIME *ctime; | ||
214 | KRB5_ENCKEY *subkey; | ||
215 | ASN1_INTEGER *seqnum; | ||
216 | KRB5_AUTHDATA *authorization; | ||
217 | } KRB5_AUTHENTBODY; | ||
218 | |||
219 | typedef STACK_OF(KRB5_AUTHENTBODY) KRB5_AUTHENT; | ||
220 | DECLARE_STACK_OF(KRB5_AUTHENTBODY) | ||
221 | |||
222 | |||
223 | /* DECLARE_ASN1_FUNCTIONS(type) = DECLARE_ASN1_FUNCTIONS_name(type, type) = | ||
224 | ** type *name##_new(void); | ||
225 | ** void name##_free(type *a); | ||
226 | ** DECLARE_ASN1_ENCODE_FUNCTIONS(type, name, name) = | ||
227 | ** DECLARE_ASN1_ENCODE_FUNCTIONS(type, itname, name) = | ||
228 | ** type *d2i_##name(type **a, unsigned char **in, long len); | ||
229 | ** int i2d_##name(type *a, unsigned char **out); | ||
230 | ** DECLARE_ASN1_ITEM(itname) = OPENSSL_EXTERN const ASN1_ITEM itname##_it | ||
231 | */ | ||
232 | |||
233 | DECLARE_ASN1_FUNCTIONS(KRB5_ENCDATA) | ||
234 | DECLARE_ASN1_FUNCTIONS(KRB5_PRINCNAME) | ||
235 | DECLARE_ASN1_FUNCTIONS(KRB5_TKTBODY) | ||
236 | DECLARE_ASN1_FUNCTIONS(KRB5_APREQBODY) | ||
237 | DECLARE_ASN1_FUNCTIONS(KRB5_TICKET) | ||
238 | DECLARE_ASN1_FUNCTIONS(KRB5_APREQ) | ||
239 | |||
240 | DECLARE_ASN1_FUNCTIONS(KRB5_CHECKSUM) | ||
241 | DECLARE_ASN1_FUNCTIONS(KRB5_ENCKEY) | ||
242 | DECLARE_ASN1_FUNCTIONS(KRB5_AUTHDATA) | ||
243 | DECLARE_ASN1_FUNCTIONS(KRB5_AUTHENTBODY) | ||
244 | DECLARE_ASN1_FUNCTIONS(KRB5_AUTHENT) | ||
245 | |||
246 | |||
247 | /* BEGIN ERROR CODES */ | ||
248 | /* The following lines are auto generated by the script mkerr.pl. Any changes | ||
249 | * made after this point may be overwritten when the script is next run. | ||
250 | */ | ||
251 | |||
252 | #ifdef __cplusplus | ||
253 | } | ||
254 | #endif | ||
255 | #endif | ||
256 | |||
diff --git a/src/lib/libcrypto/md32_common.h b/src/lib/libcrypto/md32_common.h new file mode 100644 index 0000000000..2b91f9eef2 --- /dev/null +++ b/src/lib/libcrypto/md32_common.h | |||
@@ -0,0 +1,594 @@ | |||
1 | /* crypto/md32_common.h */ | ||
2 | /* ==================================================================== | ||
3 | * Copyright (c) 1999 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 | /* | ||
57 | * This is a generic 32 bit "collector" for message digest algorithms. | ||
58 | * Whenever needed it collects input character stream into chunks of | ||
59 | * 32 bit values and invokes a block function that performs actual hash | ||
60 | * calculations. | ||
61 | * | ||
62 | * Porting guide. | ||
63 | * | ||
64 | * Obligatory macros: | ||
65 | * | ||
66 | * DATA_ORDER_IS_BIG_ENDIAN or DATA_ORDER_IS_LITTLE_ENDIAN | ||
67 | * this macro defines byte order of input stream. | ||
68 | * HASH_CBLOCK | ||
69 | * size of a unit chunk HASH_BLOCK operates on. | ||
70 | * HASH_LONG | ||
71 | * has to be at lest 32 bit wide, if it's wider, then | ||
72 | * HASH_LONG_LOG2 *has to* be defined along | ||
73 | * HASH_CTX | ||
74 | * context structure that at least contains following | ||
75 | * members: | ||
76 | * typedef struct { | ||
77 | * ... | ||
78 | * HASH_LONG Nl,Nh; | ||
79 | * HASH_LONG data[HASH_LBLOCK]; | ||
80 | * int num; | ||
81 | * ... | ||
82 | * } HASH_CTX; | ||
83 | * HASH_UPDATE | ||
84 | * name of "Update" function, implemented here. | ||
85 | * HASH_TRANSFORM | ||
86 | * name of "Transform" function, implemented here. | ||
87 | * HASH_FINAL | ||
88 | * name of "Final" function, implemented here. | ||
89 | * HASH_BLOCK_HOST_ORDER | ||
90 | * name of "block" function treating *aligned* input message | ||
91 | * in host byte order, implemented externally. | ||
92 | * HASH_BLOCK_DATA_ORDER | ||
93 | * name of "block" function treating *unaligned* input message | ||
94 | * in original (data) byte order, implemented externally (it | ||
95 | * actually is optional if data and host are of the same | ||
96 | * "endianess"). | ||
97 | * | ||
98 | * Optional macros: | ||
99 | * | ||
100 | * B_ENDIAN or L_ENDIAN | ||
101 | * defines host byte-order. | ||
102 | * HASH_LONG_LOG2 | ||
103 | * defaults to 2 if not states otherwise. | ||
104 | * HASH_LBLOCK | ||
105 | * assumed to be HASH_CBLOCK/4 if not stated otherwise. | ||
106 | * HASH_BLOCK_DATA_ORDER_ALIGNED | ||
107 | * alternative "block" function capable of treating | ||
108 | * aligned input message in original (data) order, | ||
109 | * implemented externally. | ||
110 | * | ||
111 | * MD5 example: | ||
112 | * | ||
113 | * #define DATA_ORDER_IS_LITTLE_ENDIAN | ||
114 | * | ||
115 | * #define HASH_LONG MD5_LONG | ||
116 | * #define HASH_LONG_LOG2 MD5_LONG_LOG2 | ||
117 | * #define HASH_CTX MD5_CTX | ||
118 | * #define HASH_CBLOCK MD5_CBLOCK | ||
119 | * #define HASH_LBLOCK MD5_LBLOCK | ||
120 | * #define HASH_UPDATE MD5_Update | ||
121 | * #define HASH_TRANSFORM MD5_Transform | ||
122 | * #define HASH_FINAL MD5_Final | ||
123 | * #define HASH_BLOCK_HOST_ORDER md5_block_host_order | ||
124 | * #define HASH_BLOCK_DATA_ORDER md5_block_data_order | ||
125 | * | ||
126 | * <appro@fy.chalmers.se> | ||
127 | */ | ||
128 | |||
129 | #if !defined(DATA_ORDER_IS_BIG_ENDIAN) && !defined(DATA_ORDER_IS_LITTLE_ENDIAN) | ||
130 | #error "DATA_ORDER must be defined!" | ||
131 | #endif | ||
132 | |||
133 | #ifndef HASH_CBLOCK | ||
134 | #error "HASH_CBLOCK must be defined!" | ||
135 | #endif | ||
136 | #ifndef HASH_LONG | ||
137 | #error "HASH_LONG must be defined!" | ||
138 | #endif | ||
139 | #ifndef HASH_CTX | ||
140 | #error "HASH_CTX must be defined!" | ||
141 | #endif | ||
142 | |||
143 | #ifndef HASH_UPDATE | ||
144 | #error "HASH_UPDATE must be defined!" | ||
145 | #endif | ||
146 | #ifndef HASH_TRANSFORM | ||
147 | #error "HASH_TRANSFORM must be defined!" | ||
148 | #endif | ||
149 | #ifndef HASH_FINAL | ||
150 | #error "HASH_FINAL must be defined!" | ||
151 | #endif | ||
152 | |||
153 | #ifndef HASH_BLOCK_HOST_ORDER | ||
154 | #error "HASH_BLOCK_HOST_ORDER must be defined!" | ||
155 | #endif | ||
156 | |||
157 | #if 0 | ||
158 | /* | ||
159 | * Moved below as it's required only if HASH_BLOCK_DATA_ORDER_ALIGNED | ||
160 | * isn't defined. | ||
161 | */ | ||
162 | #ifndef HASH_BLOCK_DATA_ORDER | ||
163 | #error "HASH_BLOCK_DATA_ORDER must be defined!" | ||
164 | #endif | ||
165 | #endif | ||
166 | |||
167 | #ifndef HASH_LBLOCK | ||
168 | #define HASH_LBLOCK (HASH_CBLOCK/4) | ||
169 | #endif | ||
170 | |||
171 | #ifndef HASH_LONG_LOG2 | ||
172 | #define HASH_LONG_LOG2 2 | ||
173 | #endif | ||
174 | |||
175 | /* | ||
176 | * Engage compiler specific rotate intrinsic function if available. | ||
177 | */ | ||
178 | #undef ROTATE | ||
179 | #ifndef PEDANTIC | ||
180 | # if defined(_MSC_VER) | ||
181 | # define ROTATE(a,n) _lrotl(a,n) | ||
182 | # elif defined(__GNUC__) && __GNUC__>=2 && !defined(NO_ASM) | ||
183 | /* | ||
184 | * Some GNU C inline assembler templates. Note that these are | ||
185 | * rotates by *constant* number of bits! But that's exactly | ||
186 | * what we need here... | ||
187 | * | ||
188 | * <appro@fy.chalmers.se> | ||
189 | */ | ||
190 | # if defined(__i386) | ||
191 | # define ROTATE(a,n) ({ register unsigned int ret; \ | ||
192 | asm volatile ( \ | ||
193 | "roll %1,%0" \ | ||
194 | : "=r"(ret) \ | ||
195 | : "I"(n), "0"(a) \ | ||
196 | : "cc"); \ | ||
197 | ret; \ | ||
198 | }) | ||
199 | # elif defined(__powerpc) | ||
200 | # define ROTATE(a,n) ({ register unsigned int ret; \ | ||
201 | asm volatile ( \ | ||
202 | "rlwinm %0,%1,%2,0,31" \ | ||
203 | : "=r"(ret) \ | ||
204 | : "r"(a), "I"(n)); \ | ||
205 | ret; \ | ||
206 | }) | ||
207 | # endif | ||
208 | # endif | ||
209 | |||
210 | /* | ||
211 | * Engage compiler specific "fetch in reverse byte order" | ||
212 | * intrinsic function if available. | ||
213 | */ | ||
214 | # if defined(__GNUC__) && __GNUC__>=2 && !defined(NO_ASM) | ||
215 | /* some GNU C inline assembler templates by <appro@fy.chalmers.se> */ | ||
216 | # if defined(__i386) && !defined(I386_ONLY) | ||
217 | # define BE_FETCH32(a) ({ register unsigned int l=(a);\ | ||
218 | asm volatile ( \ | ||
219 | "bswapl %0" \ | ||
220 | : "=r"(l) : "0"(l)); \ | ||
221 | l; \ | ||
222 | }) | ||
223 | # elif defined(__powerpc) | ||
224 | # define LE_FETCH32(a) ({ register unsigned int l; \ | ||
225 | asm volatile ( \ | ||
226 | "lwbrx %0,0,%1" \ | ||
227 | : "=r"(l) \ | ||
228 | : "r"(a)); \ | ||
229 | l; \ | ||
230 | }) | ||
231 | |||
232 | # elif defined(__sparc) && defined(ULTRASPARC) | ||
233 | # define LE_FETCH32(a) ({ register unsigned int l; \ | ||
234 | asm volatile ( \ | ||
235 | "lda [%1]#ASI_PRIMARY_LITTLE,%0"\ | ||
236 | : "=r"(l) \ | ||
237 | : "r"(a)); \ | ||
238 | l; \ | ||
239 | }) | ||
240 | # endif | ||
241 | # endif | ||
242 | #endif /* PEDANTIC */ | ||
243 | |||
244 | #if HASH_LONG_LOG2==2 /* Engage only if sizeof(HASH_LONG)== 4 */ | ||
245 | /* A nice byte order reversal from Wei Dai <weidai@eskimo.com> */ | ||
246 | #ifdef ROTATE | ||
247 | /* 5 instructions with rotate instruction, else 9 */ | ||
248 | #define REVERSE_FETCH32(a,l) ( \ | ||
249 | l=*(const HASH_LONG *)(a), \ | ||
250 | ((ROTATE(l,8)&0x00FF00FF)|(ROTATE((l&0x00FF00FF),24))) \ | ||
251 | ) | ||
252 | #else | ||
253 | /* 6 instructions with rotate instruction, else 8 */ | ||
254 | #define REVERSE_FETCH32(a,l) ( \ | ||
255 | l=*(const HASH_LONG *)(a), \ | ||
256 | l=(((l>>8)&0x00FF00FF)|((l&0x00FF00FF)<<8)), \ | ||
257 | ROTATE(l,16) \ | ||
258 | ) | ||
259 | /* | ||
260 | * Originally the middle line started with l=(((l&0xFF00FF00)>>8)|... | ||
261 | * It's rewritten as above for two reasons: | ||
262 | * - RISCs aren't good at long constants and have to explicitely | ||
263 | * compose 'em with several (well, usually 2) instructions in a | ||
264 | * register before performing the actual operation and (as you | ||
265 | * already realized:-) having same constant should inspire the | ||
266 | * compiler to permanently allocate the only register for it; | ||
267 | * - most modern CPUs have two ALUs, but usually only one has | ||
268 | * circuitry for shifts:-( this minor tweak inspires compiler | ||
269 | * to schedule shift instructions in a better way... | ||
270 | * | ||
271 | * <appro@fy.chalmers.se> | ||
272 | */ | ||
273 | #endif | ||
274 | #endif | ||
275 | |||
276 | #ifndef ROTATE | ||
277 | #define ROTATE(a,n) (((a)<<(n))|(((a)&0xffffffff)>>(32-(n)))) | ||
278 | #endif | ||
279 | |||
280 | /* | ||
281 | * Make some obvious choices. E.g., HASH_BLOCK_DATA_ORDER_ALIGNED | ||
282 | * and HASH_BLOCK_HOST_ORDER ought to be the same if input data | ||
283 | * and host are of the same "endianess". It's possible to mask | ||
284 | * this with blank #define HASH_BLOCK_DATA_ORDER though... | ||
285 | * | ||
286 | * <appro@fy.chalmers.se> | ||
287 | */ | ||
288 | #if defined(B_ENDIAN) | ||
289 | # if defined(DATA_ORDER_IS_BIG_ENDIAN) | ||
290 | # if !defined(HASH_BLOCK_DATA_ORDER_ALIGNED) && HASH_LONG_LOG2==2 | ||
291 | # define HASH_BLOCK_DATA_ORDER_ALIGNED HASH_BLOCK_HOST_ORDER | ||
292 | # endif | ||
293 | # elif defined(DATA_ORDER_IS_LITTLE_ENDIAN) | ||
294 | # ifndef HOST_FETCH32 | ||
295 | # ifdef LE_FETCH32 | ||
296 | # define HOST_FETCH32(p,l) LE_FETCH32(p) | ||
297 | # elif defined(REVERSE_FETCH32) | ||
298 | # define HOST_FETCH32(p,l) REVERSE_FETCH32(p,l) | ||
299 | # endif | ||
300 | # endif | ||
301 | # endif | ||
302 | #elif defined(L_ENDIAN) | ||
303 | # if defined(DATA_ORDER_IS_LITTLE_ENDIAN) | ||
304 | # if !defined(HASH_BLOCK_DATA_ORDER_ALIGNED) && HASH_LONG_LOG2==2 | ||
305 | # define HASH_BLOCK_DATA_ORDER_ALIGNED HASH_BLOCK_HOST_ORDER | ||
306 | # endif | ||
307 | # elif defined(DATA_ORDER_IS_BIG_ENDIAN) | ||
308 | # ifndef HOST_FETCH32 | ||
309 | # ifdef BE_FETCH32 | ||
310 | # define HOST_FETCH32(p,l) BE_FETCH32(p) | ||
311 | # elif defined(REVERSE_FETCH32) | ||
312 | # define HOST_FETCH32(p,l) REVERSE_FETCH32(p,l) | ||
313 | # endif | ||
314 | # endif | ||
315 | # endif | ||
316 | #endif | ||
317 | |||
318 | #if !defined(HASH_BLOCK_DATA_ORDER_ALIGNED) | ||
319 | #ifndef HASH_BLOCK_DATA_ORDER | ||
320 | #error "HASH_BLOCK_DATA_ORDER must be defined!" | ||
321 | #endif | ||
322 | #endif | ||
323 | |||
324 | #if defined(DATA_ORDER_IS_BIG_ENDIAN) | ||
325 | |||
326 | #define HOST_c2l(c,l) (l =(((unsigned long)(*((c)++)))<<24), \ | ||
327 | l|=(((unsigned long)(*((c)++)))<<16), \ | ||
328 | l|=(((unsigned long)(*((c)++)))<< 8), \ | ||
329 | l|=(((unsigned long)(*((c)++))) ), \ | ||
330 | l) | ||
331 | #define HOST_p_c2l(c,l,n) { \ | ||
332 | switch (n) { \ | ||
333 | case 0: l =((unsigned long)(*((c)++)))<<24; \ | ||
334 | case 1: l|=((unsigned long)(*((c)++)))<<16; \ | ||
335 | case 2: l|=((unsigned long)(*((c)++)))<< 8; \ | ||
336 | case 3: l|=((unsigned long)(*((c)++))); \ | ||
337 | } } | ||
338 | #define HOST_p_c2l_p(c,l,sc,len) { \ | ||
339 | switch (sc) { \ | ||
340 | case 0: l =((unsigned long)(*((c)++)))<<24; \ | ||
341 | if (--len == 0) break; \ | ||
342 | case 1: l|=((unsigned long)(*((c)++)))<<16; \ | ||
343 | if (--len == 0) break; \ | ||
344 | case 2: l|=((unsigned long)(*((c)++)))<< 8; \ | ||
345 | } } | ||
346 | /* NOTE the pointer is not incremented at the end of this */ | ||
347 | #define HOST_c2l_p(c,l,n) { \ | ||
348 | l=0; (c)+=n; \ | ||
349 | switch (n) { \ | ||
350 | case 3: l =((unsigned long)(*(--(c))))<< 8; \ | ||
351 | case 2: l|=((unsigned long)(*(--(c))))<<16; \ | ||
352 | case 1: l|=((unsigned long)(*(--(c))))<<24; \ | ||
353 | } } | ||
354 | #define HOST_l2c(l,c) (*((c)++)=(unsigned char)(((l)>>24)&0xff), \ | ||
355 | *((c)++)=(unsigned char)(((l)>>16)&0xff), \ | ||
356 | *((c)++)=(unsigned char)(((l)>> 8)&0xff), \ | ||
357 | *((c)++)=(unsigned char)(((l) )&0xff), \ | ||
358 | l) | ||
359 | |||
360 | #elif defined(DATA_ORDER_IS_LITTLE_ENDIAN) | ||
361 | |||
362 | #define HOST_c2l(c,l) (l =(((unsigned long)(*((c)++))) ), \ | ||
363 | l|=(((unsigned long)(*((c)++)))<< 8), \ | ||
364 | l|=(((unsigned long)(*((c)++)))<<16), \ | ||
365 | l|=(((unsigned long)(*((c)++)))<<24), \ | ||
366 | l) | ||
367 | #define HOST_p_c2l(c,l,n) { \ | ||
368 | switch (n) { \ | ||
369 | case 0: l =((unsigned long)(*((c)++))); \ | ||
370 | case 1: l|=((unsigned long)(*((c)++)))<< 8; \ | ||
371 | case 2: l|=((unsigned long)(*((c)++)))<<16; \ | ||
372 | case 3: l|=((unsigned long)(*((c)++)))<<24; \ | ||
373 | } } | ||
374 | #define HOST_p_c2l_p(c,l,sc,len) { \ | ||
375 | switch (sc) { \ | ||
376 | case 0: l =((unsigned long)(*((c)++))); \ | ||
377 | if (--len == 0) break; \ | ||
378 | case 1: l|=((unsigned long)(*((c)++)))<< 8; \ | ||
379 | if (--len == 0) break; \ | ||
380 | case 2: l|=((unsigned long)(*((c)++)))<<16; \ | ||
381 | } } | ||
382 | /* NOTE the pointer is not incremented at the end of this */ | ||
383 | #define HOST_c2l_p(c,l,n) { \ | ||
384 | l=0; (c)+=n; \ | ||
385 | switch (n) { \ | ||
386 | case 3: l =((unsigned long)(*(--(c))))<<16; \ | ||
387 | case 2: l|=((unsigned long)(*(--(c))))<< 8; \ | ||
388 | case 1: l|=((unsigned long)(*(--(c)))); \ | ||
389 | } } | ||
390 | #define HOST_l2c(l,c) (*((c)++)=(unsigned char)(((l) )&0xff), \ | ||
391 | *((c)++)=(unsigned char)(((l)>> 8)&0xff), \ | ||
392 | *((c)++)=(unsigned char)(((l)>>16)&0xff), \ | ||
393 | *((c)++)=(unsigned char)(((l)>>24)&0xff), \ | ||
394 | l) | ||
395 | |||
396 | #endif | ||
397 | |||
398 | /* | ||
399 | * Time for some action:-) | ||
400 | */ | ||
401 | |||
402 | void HASH_UPDATE (HASH_CTX *c, const unsigned char *data, unsigned long len) | ||
403 | { | ||
404 | register HASH_LONG * p; | ||
405 | register unsigned long l; | ||
406 | int sw,sc,ew,ec; | ||
407 | |||
408 | if (len==0) return; | ||
409 | |||
410 | l=(c->Nl+(len<<3))&0xffffffffL; | ||
411 | /* 95-05-24 eay Fixed a bug with the overflow handling, thanks to | ||
412 | * Wei Dai <weidai@eskimo.com> for pointing it out. */ | ||
413 | if (l < c->Nl) /* overflow */ | ||
414 | c->Nh++; | ||
415 | c->Nh+=(len>>29); | ||
416 | c->Nl=l; | ||
417 | |||
418 | if (c->num != 0) | ||
419 | { | ||
420 | p=c->data; | ||
421 | sw=c->num>>2; | ||
422 | sc=c->num&0x03; | ||
423 | |||
424 | if ((c->num+len) >= HASH_CBLOCK) | ||
425 | { | ||
426 | l=p[sw]; HOST_p_c2l(data,l,sc); p[sw++]=l; | ||
427 | for (; sw<HASH_LBLOCK; sw++) | ||
428 | { | ||
429 | HOST_c2l(data,l); p[sw]=l; | ||
430 | } | ||
431 | HASH_BLOCK_HOST_ORDER (c,p,1); | ||
432 | len-=(HASH_CBLOCK-c->num); | ||
433 | c->num=0; | ||
434 | /* drop through and do the rest */ | ||
435 | } | ||
436 | else | ||
437 | { | ||
438 | c->num+=len; | ||
439 | if ((sc+len) < 4) /* ugly, add char's to a word */ | ||
440 | { | ||
441 | l=p[sw]; HOST_p_c2l_p(data,l,sc,len); p[sw]=l; | ||
442 | } | ||
443 | else | ||
444 | { | ||
445 | ew=(c->num>>2); | ||
446 | ec=(c->num&0x03); | ||
447 | l=p[sw]; HOST_p_c2l(data,l,sc); p[sw++]=l; | ||
448 | for (; sw < ew; sw++) | ||
449 | { | ||
450 | HOST_c2l(data,l); p[sw]=l; | ||
451 | } | ||
452 | if (ec) | ||
453 | { | ||
454 | HOST_c2l_p(data,l,ec); p[sw]=l; | ||
455 | } | ||
456 | } | ||
457 | return; | ||
458 | } | ||
459 | } | ||
460 | |||
461 | sw=len/HASH_CBLOCK; | ||
462 | if (sw > 0) | ||
463 | { | ||
464 | #if defined(HASH_BLOCK_DATA_ORDER_ALIGNED) | ||
465 | /* | ||
466 | * Note that HASH_BLOCK_DATA_ORDER_ALIGNED gets defined | ||
467 | * only if sizeof(HASH_LONG)==4. | ||
468 | */ | ||
469 | if ((((unsigned long)data)%4) == 0) | ||
470 | { | ||
471 | /* data is properly aligned so that we can cast it: */ | ||
472 | HASH_BLOCK_DATA_ORDER_ALIGNED (c,(HASH_LONG *)data,sw); | ||
473 | sw*=HASH_CBLOCK; | ||
474 | data+=sw; | ||
475 | len-=sw; | ||
476 | } | ||
477 | else | ||
478 | #if !defined(HASH_BLOCK_DATA_ORDER) | ||
479 | while (sw--) | ||
480 | { | ||
481 | memcpy (p=c->data,data,HASH_CBLOCK); | ||
482 | HASH_BLOCK_DATA_ORDER_ALIGNED(c,p,1); | ||
483 | data+=HASH_CBLOCK; | ||
484 | len-=HASH_CBLOCK; | ||
485 | } | ||
486 | #endif | ||
487 | #endif | ||
488 | #if defined(HASH_BLOCK_DATA_ORDER) | ||
489 | { | ||
490 | HASH_BLOCK_DATA_ORDER(c,data,sw); | ||
491 | sw*=HASH_CBLOCK; | ||
492 | data+=sw; | ||
493 | len-=sw; | ||
494 | } | ||
495 | #endif | ||
496 | } | ||
497 | |||
498 | if (len!=0) | ||
499 | { | ||
500 | p = c->data; | ||
501 | c->num = len; | ||
502 | ew=len>>2; /* words to copy */ | ||
503 | ec=len&0x03; | ||
504 | for (; ew; ew--,p++) | ||
505 | { | ||
506 | HOST_c2l(data,l); *p=l; | ||
507 | } | ||
508 | HOST_c2l_p(data,l,ec); | ||
509 | *p=l; | ||
510 | } | ||
511 | } | ||
512 | |||
513 | |||
514 | void HASH_TRANSFORM (HASH_CTX *c, const unsigned char *data) | ||
515 | { | ||
516 | #if defined(HASH_BLOCK_DATA_ORDER_ALIGNED) | ||
517 | if ((((unsigned long)data)%4) == 0) | ||
518 | /* data is properly aligned so that we can cast it: */ | ||
519 | HASH_BLOCK_DATA_ORDER_ALIGNED (c,(HASH_LONG *)data,1); | ||
520 | else | ||
521 | #if !defined(HASH_BLOCK_DATA_ORDER) | ||
522 | { | ||
523 | memcpy (c->data,data,HASH_CBLOCK); | ||
524 | HASH_BLOCK_DATA_ORDER_ALIGNED (c,c->data,1); | ||
525 | } | ||
526 | #endif | ||
527 | #endif | ||
528 | #if defined(HASH_BLOCK_DATA_ORDER) | ||
529 | HASH_BLOCK_DATA_ORDER (c,data,1); | ||
530 | #endif | ||
531 | } | ||
532 | |||
533 | |||
534 | void HASH_FINAL (unsigned char *md, HASH_CTX *c) | ||
535 | { | ||
536 | register HASH_LONG *p; | ||
537 | register unsigned long l; | ||
538 | register int i,j; | ||
539 | static const unsigned char end[4]={0x80,0x00,0x00,0x00}; | ||
540 | const unsigned char *cp=end; | ||
541 | |||
542 | /* c->num should definitly have room for at least one more byte. */ | ||
543 | p=c->data; | ||
544 | i=c->num>>2; | ||
545 | j=c->num&0x03; | ||
546 | |||
547 | #if 0 | ||
548 | /* purify often complains about the following line as an | ||
549 | * Uninitialized Memory Read. While this can be true, the | ||
550 | * following p_c2l macro will reset l when that case is true. | ||
551 | * This is because j&0x03 contains the number of 'valid' bytes | ||
552 | * already in p[i]. If and only if j&0x03 == 0, the UMR will | ||
553 | * occur but this is also the only time p_c2l will do | ||
554 | * l= *(cp++) instead of l|= *(cp++) | ||
555 | * Many thanks to Alex Tang <altitude@cic.net> for pickup this | ||
556 | * 'potential bug' */ | ||
557 | #ifdef PURIFY | ||
558 | if (j==0) p[i]=0; /* Yeah, but that's not the way to fix it:-) */ | ||
559 | #endif | ||
560 | l=p[i]; | ||
561 | #else | ||
562 | l = (j==0) ? 0 : p[i]; | ||
563 | #endif | ||
564 | HOST_p_c2l(cp,l,j); p[i++]=l; /* i is the next 'undefined word' */ | ||
565 | |||
566 | if (i>(HASH_LBLOCK-2)) /* save room for Nl and Nh */ | ||
567 | { | ||
568 | if (i<HASH_LBLOCK) p[i]=0; | ||
569 | HASH_BLOCK_HOST_ORDER (c,p,1); | ||
570 | i=0; | ||
571 | } | ||
572 | for (; i<(HASH_LBLOCK-2); i++) | ||
573 | p[i]=0; | ||
574 | |||
575 | #if defined(DATA_ORDER_IS_BIG_ENDIAN) | ||
576 | p[HASH_LBLOCK-2]=c->Nh; | ||
577 | p[HASH_LBLOCK-1]=c->Nl; | ||
578 | #elif defined(DATA_ORDER_IS_LITTLE_ENDIAN) | ||
579 | p[HASH_LBLOCK-2]=c->Nl; | ||
580 | p[HASH_LBLOCK-1]=c->Nh; | ||
581 | #endif | ||
582 | HASH_BLOCK_HOST_ORDER (c,p,1); | ||
583 | |||
584 | l=c->A; HOST_l2c(l,md); | ||
585 | l=c->B; HOST_l2c(l,md); | ||
586 | l=c->C; HOST_l2c(l,md); | ||
587 | l=c->D; HOST_l2c(l,md); | ||
588 | |||
589 | c->num=0; | ||
590 | /* clear stuff, HASH_BLOCK may be leaving some stuff on the stack | ||
591 | * but I'm not worried :-) | ||
592 | memset((void *)c,0,sizeof(HASH_CTX)); | ||
593 | */ | ||
594 | } | ||
diff --git a/src/lib/libcrypto/md4/md4.h b/src/lib/libcrypto/md4/md4.h new file mode 100644 index 0000000000..c794e186db --- /dev/null +++ b/src/lib/libcrypto/md4/md4.h | |||
@@ -0,0 +1,114 @@ | |||
1 | /* crypto/md4/md4.h */ | ||
2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) | ||
3 | * All rights reserved. | ||
4 | * | ||
5 | * This package is an SSL implementation written | ||
6 | * by Eric Young (eay@cryptsoft.com). | ||
7 | * The implementation was written so as to conform with Netscapes SSL. | ||
8 | * | ||
9 | * This library is free for commercial and non-commercial use as long as | ||
10 | * the following conditions are aheared to. The following conditions | ||
11 | * apply to all code found in this distribution, be it the RC4, RSA, | ||
12 | * lhash, DES, etc., code; not just the SSL code. The SSL documentation | ||
13 | * included with this distribution is covered by the same copyright terms | ||
14 | * except that the holder is Tim Hudson (tjh@cryptsoft.com). | ||
15 | * | ||
16 | * Copyright remains Eric Young's, and as such any Copyright notices in | ||
17 | * the code are not to be removed. | ||
18 | * If this package is used in a product, Eric Young should be given attribution | ||
19 | * as the author of the parts of the library used. | ||
20 | * This can be in the form of a textual message at program startup or | ||
21 | * in documentation (online or textual) provided with the package. | ||
22 | * | ||
23 | * Redistribution and use in source and binary forms, with or without | ||
24 | * modification, are permitted provided that the following conditions | ||
25 | * are met: | ||
26 | * 1. Redistributions of source code must retain the copyright | ||
27 | * notice, this list of conditions and the following disclaimer. | ||
28 | * 2. Redistributions in binary form must reproduce the above copyright | ||
29 | * notice, this list of conditions and the following disclaimer in the | ||
30 | * documentation and/or other materials provided with the distribution. | ||
31 | * 3. All advertising materials mentioning features or use of this software | ||
32 | * must display the following acknowledgement: | ||
33 | * "This product includes cryptographic software written by | ||
34 | * Eric Young (eay@cryptsoft.com)" | ||
35 | * The word 'cryptographic' can be left out if the rouines from the library | ||
36 | * being used are not cryptographic related :-). | ||
37 | * 4. If you include any Windows specific code (or a derivative thereof) from | ||
38 | * the apps directory (application code) you must include an acknowledgement: | ||
39 | * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" | ||
40 | * | ||
41 | * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND | ||
42 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
43 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
44 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | ||
45 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
46 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
47 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
48 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
49 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
50 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
51 | * SUCH DAMAGE. | ||
52 | * | ||
53 | * The licence and distribution terms for any publically available version or | ||
54 | * derivative of this code cannot be changed. i.e. this code cannot simply be | ||
55 | * copied and put under another distribution licence | ||
56 | * [including the GNU Public Licence.] | ||
57 | */ | ||
58 | |||
59 | #ifndef HEADER_MD4_H | ||
60 | #define HEADER_MD4_H | ||
61 | |||
62 | #ifdef __cplusplus | ||
63 | extern "C" { | ||
64 | #endif | ||
65 | |||
66 | #ifdef NO_MD4 | ||
67 | #error MD4 is disabled. | ||
68 | #endif | ||
69 | |||
70 | /* | ||
71 | * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | ||
72 | * ! MD4_LONG has to be at least 32 bits wide. If it's wider, then ! | ||
73 | * ! MD4_LONG_LOG2 has to be defined along. ! | ||
74 | * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | ||
75 | */ | ||
76 | |||
77 | #if defined(WIN16) || defined(__LP32__) | ||
78 | #define MD4_LONG unsigned long | ||
79 | #elif defined(_CRAY) || defined(__ILP64__) | ||
80 | #define MD4_LONG unsigned long | ||
81 | #define MD4_LONG_LOG2 3 | ||
82 | /* | ||
83 | * _CRAY note. I could declare short, but I have no idea what impact | ||
84 | * does it have on performance on none-T3E machines. I could declare | ||
85 | * int, but at least on C90 sizeof(int) can be chosen at compile time. | ||
86 | * So I've chosen long... | ||
87 | * <appro@fy.chalmers.se> | ||
88 | */ | ||
89 | #else | ||
90 | #define MD4_LONG unsigned int | ||
91 | #endif | ||
92 | |||
93 | #define MD4_CBLOCK 64 | ||
94 | #define MD4_LBLOCK (MD4_CBLOCK/4) | ||
95 | #define MD4_DIGEST_LENGTH 16 | ||
96 | |||
97 | typedef struct MD4state_st | ||
98 | { | ||
99 | MD4_LONG A,B,C,D; | ||
100 | MD4_LONG Nl,Nh; | ||
101 | MD4_LONG data[MD4_LBLOCK]; | ||
102 | int num; | ||
103 | } MD4_CTX; | ||
104 | |||
105 | void MD4_Init(MD4_CTX *c); | ||
106 | void MD4_Update(MD4_CTX *c, const void *data, unsigned long len); | ||
107 | void MD4_Final(unsigned char *md, MD4_CTX *c); | ||
108 | unsigned char *MD4(const unsigned char *d, unsigned long n, unsigned char *md); | ||
109 | void MD4_Transform(MD4_CTX *c, const unsigned char *b); | ||
110 | #ifdef __cplusplus | ||
111 | } | ||
112 | #endif | ||
113 | |||
114 | #endif | ||
diff --git a/src/lib/libcrypto/md4/md4_dgst.c b/src/lib/libcrypto/md4/md4_dgst.c new file mode 100644 index 0000000000..81488ae2e2 --- /dev/null +++ b/src/lib/libcrypto/md4/md4_dgst.c | |||
@@ -0,0 +1,285 @@ | |||
1 | /* crypto/md4/md4_dgst.c */ | ||
2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) | ||
3 | * All rights reserved. | ||
4 | * | ||
5 | * This package is an SSL implementation written | ||
6 | * by Eric Young (eay@cryptsoft.com). | ||
7 | * The implementation was written so as to conform with Netscapes SSL. | ||
8 | * | ||
9 | * This library is free for commercial and non-commercial use as long as | ||
10 | * the following conditions are aheared to. The following conditions | ||
11 | * apply to all code found in this distribution, be it the RC4, RSA, | ||
12 | * lhash, DES, etc., code; not just the SSL code. The SSL documentation | ||
13 | * included with this distribution is covered by the same copyright terms | ||
14 | * except that the holder is Tim Hudson (tjh@cryptsoft.com). | ||
15 | * | ||
16 | * Copyright remains Eric Young's, and as such any Copyright notices in | ||
17 | * the code are not to be removed. | ||
18 | * If this package is used in a product, Eric Young should be given attribution | ||
19 | * as the author of the parts of the library used. | ||
20 | * This can be in the form of a textual message at program startup or | ||
21 | * in documentation (online or textual) provided with the package. | ||
22 | * | ||
23 | * Redistribution and use in source and binary forms, with or without | ||
24 | * modification, are permitted provided that the following conditions | ||
25 | * are met: | ||
26 | * 1. Redistributions of source code must retain the copyright | ||
27 | * notice, this list of conditions and the following disclaimer. | ||
28 | * 2. Redistributions in binary form must reproduce the above copyright | ||
29 | * notice, this list of conditions and the following disclaimer in the | ||
30 | * documentation and/or other materials provided with the distribution. | ||
31 | * 3. All advertising materials mentioning features or use of this software | ||
32 | * must display the following acknowledgement: | ||
33 | * "This product includes cryptographic software written by | ||
34 | * Eric Young (eay@cryptsoft.com)" | ||
35 | * The word 'cryptographic' can be left out if the rouines from the library | ||
36 | * being used are not cryptographic related :-). | ||
37 | * 4. If you include any Windows specific code (or a derivative thereof) from | ||
38 | * the apps directory (application code) you must include an acknowledgement: | ||
39 | * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" | ||
40 | * | ||
41 | * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND | ||
42 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
43 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
44 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | ||
45 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
46 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
47 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
48 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
49 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
50 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
51 | * SUCH DAMAGE. | ||
52 | * | ||
53 | * The licence and distribution terms for any publically available version or | ||
54 | * derivative of this code cannot be changed. i.e. this code cannot simply be | ||
55 | * copied and put under another distribution licence | ||
56 | * [including the GNU Public Licence.] | ||
57 | */ | ||
58 | |||
59 | #include <stdio.h> | ||
60 | #include "md4_locl.h" | ||
61 | #include <openssl/opensslv.h> | ||
62 | |||
63 | const char *MD4_version="MD4" OPENSSL_VERSION_PTEXT; | ||
64 | |||
65 | /* Implemented from RFC1186 The MD4 Message-Digest Algorithm | ||
66 | */ | ||
67 | |||
68 | #define INIT_DATA_A (unsigned long)0x67452301L | ||
69 | #define INIT_DATA_B (unsigned long)0xefcdab89L | ||
70 | #define INIT_DATA_C (unsigned long)0x98badcfeL | ||
71 | #define INIT_DATA_D (unsigned long)0x10325476L | ||
72 | |||
73 | void MD4_Init(MD4_CTX *c) | ||
74 | { | ||
75 | c->A=INIT_DATA_A; | ||
76 | c->B=INIT_DATA_B; | ||
77 | c->C=INIT_DATA_C; | ||
78 | c->D=INIT_DATA_D; | ||
79 | c->Nl=0; | ||
80 | c->Nh=0; | ||
81 | c->num=0; | ||
82 | } | ||
83 | |||
84 | #ifndef md4_block_host_order | ||
85 | void md4_block_host_order (MD4_CTX *c, const void *data, int num) | ||
86 | { | ||
87 | const MD4_LONG *X=data; | ||
88 | register unsigned long A,B,C,D; | ||
89 | /* | ||
90 | * In case you wonder why A-D are declared as long and not | ||
91 | * as MD4_LONG. Doing so results in slight performance | ||
92 | * boost on LP64 architectures. The catch is we don't | ||
93 | * really care if 32 MSBs of a 64-bit register get polluted | ||
94 | * with eventual overflows as we *save* only 32 LSBs in | ||
95 | * *either* case. Now declaring 'em long excuses the compiler | ||
96 | * from keeping 32 MSBs zeroed resulting in 13% performance | ||
97 | * improvement under SPARC Solaris7/64 and 5% under AlphaLinux. | ||
98 | * Well, to be honest it should say that this *prevents* | ||
99 | * performance degradation. | ||
100 | * | ||
101 | * <appro@fy.chalmers.se> | ||
102 | */ | ||
103 | |||
104 | A=c->A; | ||
105 | B=c->B; | ||
106 | C=c->C; | ||
107 | D=c->D; | ||
108 | |||
109 | for (;num--;X+=HASH_LBLOCK) | ||
110 | { | ||
111 | /* Round 0 */ | ||
112 | R0(A,B,C,D,X[ 0], 3,0); | ||
113 | R0(D,A,B,C,X[ 1], 7,0); | ||
114 | R0(C,D,A,B,X[ 2],11,0); | ||
115 | R0(B,C,D,A,X[ 3],19,0); | ||
116 | R0(A,B,C,D,X[ 4], 3,0); | ||
117 | R0(D,A,B,C,X[ 5], 7,0); | ||
118 | R0(C,D,A,B,X[ 6],11,0); | ||
119 | R0(B,C,D,A,X[ 7],19,0); | ||
120 | R0(A,B,C,D,X[ 8], 3,0); | ||
121 | R0(D,A,B,C,X[ 9], 7,0); | ||
122 | R0(C,D,A,B,X[10],11,0); | ||
123 | R0(B,C,D,A,X[11],19,0); | ||
124 | R0(A,B,C,D,X[12], 3,0); | ||
125 | R0(D,A,B,C,X[13], 7,0); | ||
126 | R0(C,D,A,B,X[14],11,0); | ||
127 | R0(B,C,D,A,X[15],19,0); | ||
128 | /* Round 1 */ | ||
129 | R1(A,B,C,D,X[ 0], 3,0x5A827999L); | ||
130 | R1(D,A,B,C,X[ 4], 5,0x5A827999L); | ||
131 | R1(C,D,A,B,X[ 8], 9,0x5A827999L); | ||
132 | R1(B,C,D,A,X[12],13,0x5A827999L); | ||
133 | R1(A,B,C,D,X[ 1], 3,0x5A827999L); | ||
134 | R1(D,A,B,C,X[ 5], 5,0x5A827999L); | ||
135 | R1(C,D,A,B,X[ 9], 9,0x5A827999L); | ||
136 | R1(B,C,D,A,X[13],13,0x5A827999L); | ||
137 | R1(A,B,C,D,X[ 2], 3,0x5A827999L); | ||
138 | R1(D,A,B,C,X[ 6], 5,0x5A827999L); | ||
139 | R1(C,D,A,B,X[10], 9,0x5A827999L); | ||
140 | R1(B,C,D,A,X[14],13,0x5A827999L); | ||
141 | R1(A,B,C,D,X[ 3], 3,0x5A827999L); | ||
142 | R1(D,A,B,C,X[ 7], 5,0x5A827999L); | ||
143 | R1(C,D,A,B,X[11], 9,0x5A827999L); | ||
144 | R1(B,C,D,A,X[15],13,0x5A827999L); | ||
145 | /* Round 2 */ | ||
146 | R2(A,B,C,D,X[ 0], 3,0x6ED9EBA1); | ||
147 | R2(D,A,B,C,X[ 8], 9,0x6ED9EBA1); | ||
148 | R2(C,D,A,B,X[ 4],11,0x6ED9EBA1); | ||
149 | R2(B,C,D,A,X[12],15,0x6ED9EBA1); | ||
150 | R2(A,B,C,D,X[ 2], 3,0x6ED9EBA1); | ||
151 | R2(D,A,B,C,X[10], 9,0x6ED9EBA1); | ||
152 | R2(C,D,A,B,X[ 6],11,0x6ED9EBA1); | ||
153 | R2(B,C,D,A,X[14],15,0x6ED9EBA1); | ||
154 | R2(A,B,C,D,X[ 1], 3,0x6ED9EBA1); | ||
155 | R2(D,A,B,C,X[ 9], 9,0x6ED9EBA1); | ||
156 | R2(C,D,A,B,X[ 5],11,0x6ED9EBA1); | ||
157 | R2(B,C,D,A,X[13],15,0x6ED9EBA1); | ||
158 | R2(A,B,C,D,X[ 3], 3,0x6ED9EBA1); | ||
159 | R2(D,A,B,C,X[11], 9,0x6ED9EBA1); | ||
160 | R2(C,D,A,B,X[ 7],11,0x6ED9EBA1); | ||
161 | R2(B,C,D,A,X[15],15,0x6ED9EBA1); | ||
162 | |||
163 | A = c->A += A; | ||
164 | B = c->B += B; | ||
165 | C = c->C += C; | ||
166 | D = c->D += D; | ||
167 | } | ||
168 | } | ||
169 | #endif | ||
170 | |||
171 | #ifndef md4_block_data_order | ||
172 | #ifdef X | ||
173 | #undef X | ||
174 | #endif | ||
175 | void md4_block_data_order (MD4_CTX *c, const void *data_, int num) | ||
176 | { | ||
177 | const unsigned char *data=data_; | ||
178 | register unsigned long A,B,C,D,l; | ||
179 | /* | ||
180 | * In case you wonder why A-D are declared as long and not | ||
181 | * as MD4_LONG. Doing so results in slight performance | ||
182 | * boost on LP64 architectures. The catch is we don't | ||
183 | * really care if 32 MSBs of a 64-bit register get polluted | ||
184 | * with eventual overflows as we *save* only 32 LSBs in | ||
185 | * *either* case. Now declaring 'em long excuses the compiler | ||
186 | * from keeping 32 MSBs zeroed resulting in 13% performance | ||
187 | * improvement under SPARC Solaris7/64 and 5% under AlphaLinux. | ||
188 | * Well, to be honest it should say that this *prevents* | ||
189 | * performance degradation. | ||
190 | * | ||
191 | * <appro@fy.chalmers.se> | ||
192 | */ | ||
193 | #ifndef MD32_XARRAY | ||
194 | /* See comment in crypto/sha/sha_locl.h for details. */ | ||
195 | unsigned long XX0, XX1, XX2, XX3, XX4, XX5, XX6, XX7, | ||
196 | XX8, XX9,XX10,XX11,XX12,XX13,XX14,XX15; | ||
197 | # define X(i) XX##i | ||
198 | #else | ||
199 | MD4_LONG XX[MD4_LBLOCK]; | ||
200 | # define X(i) XX[i] | ||
201 | #endif | ||
202 | |||
203 | A=c->A; | ||
204 | B=c->B; | ||
205 | C=c->C; | ||
206 | D=c->D; | ||
207 | |||
208 | for (;num--;) | ||
209 | { | ||
210 | HOST_c2l(data,l); X( 0)=l; HOST_c2l(data,l); X( 1)=l; | ||
211 | /* Round 0 */ | ||
212 | R0(A,B,C,D,X( 0), 3,0); HOST_c2l(data,l); X( 2)=l; | ||
213 | R0(D,A,B,C,X( 1), 7,0); HOST_c2l(data,l); X( 3)=l; | ||
214 | R0(C,D,A,B,X( 2),11,0); HOST_c2l(data,l); X( 4)=l; | ||
215 | R0(B,C,D,A,X( 3),19,0); HOST_c2l(data,l); X( 5)=l; | ||
216 | R0(A,B,C,D,X( 4), 3,0); HOST_c2l(data,l); X( 6)=l; | ||
217 | R0(D,A,B,C,X( 5), 7,0); HOST_c2l(data,l); X( 7)=l; | ||
218 | R0(C,D,A,B,X( 6),11,0); HOST_c2l(data,l); X( 8)=l; | ||
219 | R0(B,C,D,A,X( 7),19,0); HOST_c2l(data,l); X( 9)=l; | ||
220 | R0(A,B,C,D,X( 8), 3,0); HOST_c2l(data,l); X(10)=l; | ||
221 | R0(D,A,B,C,X( 9), 7,0); HOST_c2l(data,l); X(11)=l; | ||
222 | R0(C,D,A,B,X(10),11,0); HOST_c2l(data,l); X(12)=l; | ||
223 | R0(B,C,D,A,X(11),19,0); HOST_c2l(data,l); X(13)=l; | ||
224 | R0(A,B,C,D,X(12), 3,0); HOST_c2l(data,l); X(14)=l; | ||
225 | R0(D,A,B,C,X(13), 7,0); HOST_c2l(data,l); X(15)=l; | ||
226 | R0(C,D,A,B,X(14),11,0); | ||
227 | R0(B,C,D,A,X(15),19,0); | ||
228 | /* Round 1 */ | ||
229 | R1(A,B,C,D,X( 0), 3,0x5A827999L); | ||
230 | R1(D,A,B,C,X( 4), 5,0x5A827999L); | ||
231 | R1(C,D,A,B,X( 8), 9,0x5A827999L); | ||
232 | R1(B,C,D,A,X(12),13,0x5A827999L); | ||
233 | R1(A,B,C,D,X( 1), 3,0x5A827999L); | ||
234 | R1(D,A,B,C,X( 5), 5,0x5A827999L); | ||
235 | R1(C,D,A,B,X( 9), 9,0x5A827999L); | ||
236 | R1(B,C,D,A,X(13),13,0x5A827999L); | ||
237 | R1(A,B,C,D,X( 2), 3,0x5A827999L); | ||
238 | R1(D,A,B,C,X( 6), 5,0x5A827999L); | ||
239 | R1(C,D,A,B,X(10), 9,0x5A827999L); | ||
240 | R1(B,C,D,A,X(14),13,0x5A827999L); | ||
241 | R1(A,B,C,D,X( 3), 3,0x5A827999L); | ||
242 | R1(D,A,B,C,X( 7), 5,0x5A827999L); | ||
243 | R1(C,D,A,B,X(11), 9,0x5A827999L); | ||
244 | R1(B,C,D,A,X(15),13,0x5A827999L); | ||
245 | /* Round 2 */ | ||
246 | R2(A,B,C,D,X( 0), 3,0x6ED9EBA1L); | ||
247 | R2(D,A,B,C,X( 8), 9,0x6ED9EBA1L); | ||
248 | R2(C,D,A,B,X( 4),11,0x6ED9EBA1L); | ||
249 | R2(B,C,D,A,X(12),15,0x6ED9EBA1L); | ||
250 | R2(A,B,C,D,X( 2), 3,0x6ED9EBA1L); | ||
251 | R2(D,A,B,C,X(10), 9,0x6ED9EBA1L); | ||
252 | R2(C,D,A,B,X( 6),11,0x6ED9EBA1L); | ||
253 | R2(B,C,D,A,X(14),15,0x6ED9EBA1L); | ||
254 | R2(A,B,C,D,X( 1), 3,0x6ED9EBA1L); | ||
255 | R2(D,A,B,C,X( 9), 9,0x6ED9EBA1L); | ||
256 | R2(C,D,A,B,X( 5),11,0x6ED9EBA1L); | ||
257 | R2(B,C,D,A,X(13),15,0x6ED9EBA1L); | ||
258 | R2(A,B,C,D,X( 3), 3,0x6ED9EBA1L); | ||
259 | R2(D,A,B,C,X(11), 9,0x6ED9EBA1L); | ||
260 | R2(C,D,A,B,X( 7),11,0x6ED9EBA1L); | ||
261 | R2(B,C,D,A,X(15),15,0x6ED9EBA1L); | ||
262 | |||
263 | A = c->A += A; | ||
264 | B = c->B += B; | ||
265 | C = c->C += C; | ||
266 | D = c->D += D; | ||
267 | } | ||
268 | } | ||
269 | #endif | ||
270 | |||
271 | #ifdef undef | ||
272 | int printit(unsigned long *l) | ||
273 | { | ||
274 | int i,ii; | ||
275 | |||
276 | for (i=0; i<2; i++) | ||
277 | { | ||
278 | for (ii=0; ii<8; ii++) | ||
279 | { | ||
280 | fprintf(stderr,"%08lx ",l[i*8+ii]); | ||
281 | } | ||
282 | fprintf(stderr,"\n"); | ||
283 | } | ||
284 | } | ||
285 | #endif | ||
diff --git a/src/lib/libcrypto/md4/md4_locl.h b/src/lib/libcrypto/md4/md4_locl.h new file mode 100644 index 0000000000..0a2b39018d --- /dev/null +++ b/src/lib/libcrypto/md4/md4_locl.h | |||
@@ -0,0 +1,154 @@ | |||
1 | /* crypto/md4/md4_locl.h */ | ||
2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) | ||
3 | * All rights reserved. | ||
4 | * | ||
5 | * This package is an SSL implementation written | ||
6 | * by Eric Young (eay@cryptsoft.com). | ||
7 | * The implementation was written so as to conform with Netscapes SSL. | ||
8 | * | ||
9 | * This library is free for commercial and non-commercial use as long as | ||
10 | * the following conditions are aheared to. The following conditions | ||
11 | * apply to all code found in this distribution, be it the RC4, RSA, | ||
12 | * lhash, DES, etc., code; not just the SSL code. The SSL documentation | ||
13 | * included with this distribution is covered by the same copyright terms | ||
14 | * except that the holder is Tim Hudson (tjh@cryptsoft.com). | ||
15 | * | ||
16 | * Copyright remains Eric Young's, and as such any Copyright notices in | ||
17 | * the code are not to be removed. | ||
18 | * If this package is used in a product, Eric Young should be given attribution | ||
19 | * as the author of the parts of the library used. | ||
20 | * This can be in the form of a textual message at program startup or | ||
21 | * in documentation (online or textual) provided with the package. | ||
22 | * | ||
23 | * Redistribution and use in source and binary forms, with or without | ||
24 | * modification, are permitted provided that the following conditions | ||
25 | * are met: | ||
26 | * 1. Redistributions of source code must retain the copyright | ||
27 | * notice, this list of conditions and the following disclaimer. | ||
28 | * 2. Redistributions in binary form must reproduce the above copyright | ||
29 | * notice, this list of conditions and the following disclaimer in the | ||
30 | * documentation and/or other materials provided with the distribution. | ||
31 | * 3. All advertising materials mentioning features or use of this software | ||
32 | * must display the following acknowledgement: | ||
33 | * "This product includes cryptographic software written by | ||
34 | * Eric Young (eay@cryptsoft.com)" | ||
35 | * The word 'cryptographic' can be left out if the rouines from the library | ||
36 | * being used are not cryptographic related :-). | ||
37 | * 4. If you include any Windows specific code (or a derivative thereof) from | ||
38 | * the apps directory (application code) you must include an acknowledgement: | ||
39 | * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" | ||
40 | * | ||
41 | * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND | ||
42 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
43 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
44 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | ||
45 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
46 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
47 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
48 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
49 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
50 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
51 | * SUCH DAMAGE. | ||
52 | * | ||
53 | * The licence and distribution terms for any publically available version or | ||
54 | * derivative of this code cannot be changed. i.e. this code cannot simply be | ||
55 | * copied and put under another distribution licence | ||
56 | * [including the GNU Public Licence.] | ||
57 | */ | ||
58 | |||
59 | #include <stdlib.h> | ||
60 | #include <string.h> | ||
61 | #include <openssl/opensslconf.h> | ||
62 | #include <openssl/md4.h> | ||
63 | |||
64 | #ifndef MD4_LONG_LOG2 | ||
65 | #define MD4_LONG_LOG2 2 /* default to 32 bits */ | ||
66 | #endif | ||
67 | |||
68 | void md4_block_host_order (MD4_CTX *c, const void *p,int num); | ||
69 | void md4_block_data_order (MD4_CTX *c, const void *p,int num); | ||
70 | |||
71 | #if defined(__i386) || defined(_M_IX86) || defined(__INTEL__) | ||
72 | /* | ||
73 | * *_block_host_order is expected to handle aligned data while | ||
74 | * *_block_data_order - unaligned. As algorithm and host (x86) | ||
75 | * are in this case of the same "endianness" these two are | ||
76 | * otherwise indistinguishable. But normally you don't want to | ||
77 | * call the same function because unaligned access in places | ||
78 | * where alignment is expected is usually a "Bad Thing". Indeed, | ||
79 | * on RISCs you get punished with BUS ERROR signal or *severe* | ||
80 | * performance degradation. Intel CPUs are in turn perfectly | ||
81 | * capable of loading unaligned data without such drastic side | ||
82 | * effect. Yes, they say it's slower than aligned load, but no | ||
83 | * exception is generated and therefore performance degradation | ||
84 | * is *incomparable* with RISCs. What we should weight here is | ||
85 | * costs of unaligned access against costs of aligning data. | ||
86 | * According to my measurements allowing unaligned access results | ||
87 | * in ~9% performance improvement on Pentium II operating at | ||
88 | * 266MHz. I won't be surprised if the difference will be higher | ||
89 | * on faster systems:-) | ||
90 | * | ||
91 | * <appro@fy.chalmers.se> | ||
92 | */ | ||
93 | #define md4_block_data_order md4_block_host_order | ||
94 | #endif | ||
95 | |||
96 | #define DATA_ORDER_IS_LITTLE_ENDIAN | ||
97 | |||
98 | #define HASH_LONG MD4_LONG | ||
99 | #define HASH_LONG_LOG2 MD4_LONG_LOG2 | ||
100 | #define HASH_CTX MD4_CTX | ||
101 | #define HASH_CBLOCK MD4_CBLOCK | ||
102 | #define HASH_LBLOCK MD4_LBLOCK | ||
103 | #define HASH_UPDATE MD4_Update | ||
104 | #define HASH_TRANSFORM MD4_Transform | ||
105 | #define HASH_FINAL MD4_Final | ||
106 | #define HASH_MAKE_STRING(c,s) do { \ | ||
107 | unsigned long ll; \ | ||
108 | ll=(c)->A; HOST_l2c(ll,(s)); \ | ||
109 | ll=(c)->B; HOST_l2c(ll,(s)); \ | ||
110 | ll=(c)->C; HOST_l2c(ll,(s)); \ | ||
111 | ll=(c)->D; HOST_l2c(ll,(s)); \ | ||
112 | } while (0) | ||
113 | #define HASH_BLOCK_HOST_ORDER md4_block_host_order | ||
114 | #if !defined(L_ENDIAN) || defined(md4_block_data_order) | ||
115 | #define HASH_BLOCK_DATA_ORDER md4_block_data_order | ||
116 | /* | ||
117 | * Little-endians (Intel and Alpha) feel better without this. | ||
118 | * It looks like memcpy does better job than generic | ||
119 | * md4_block_data_order on copying-n-aligning input data. | ||
120 | * But frankly speaking I didn't expect such result on Alpha. | ||
121 | * On the other hand I've got this with egcs-1.0.2 and if | ||
122 | * program is compiled with another (better?) compiler it | ||
123 | * might turn out other way around. | ||
124 | * | ||
125 | * <appro@fy.chalmers.se> | ||
126 | */ | ||
127 | #endif | ||
128 | |||
129 | #include "md32_common.h" | ||
130 | |||
131 | /* | ||
132 | #define F(x,y,z) (((x) & (y)) | ((~(x)) & (z))) | ||
133 | #define G(x,y,z) (((x) & (y)) | ((x) & ((z))) | ((y) & ((z)))) | ||
134 | */ | ||
135 | |||
136 | /* As pointed out by Wei Dai <weidai@eskimo.com>, the above can be | ||
137 | * simplified to the code below. Wei attributes these optimizations | ||
138 | * to Peter Gutmann's SHS code, and he attributes it to Rich Schroeppel. | ||
139 | */ | ||
140 | #define F(b,c,d) ((((c) ^ (d)) & (b)) ^ (d)) | ||
141 | #define G(b,c,d) (((b) & (c)) | ((b) & (d)) | ((c) & (d))) | ||
142 | #define H(b,c,d) ((b) ^ (c) ^ (d)) | ||
143 | |||
144 | #define R0(a,b,c,d,k,s,t) { \ | ||
145 | a+=((k)+(t)+F((b),(c),(d))); \ | ||
146 | a=ROTATE(a,s); }; | ||
147 | |||
148 | #define R1(a,b,c,d,k,s,t) { \ | ||
149 | a+=((k)+(t)+G((b),(c),(d))); \ | ||
150 | a=ROTATE(a,s); };\ | ||
151 | |||
152 | #define R2(a,b,c,d,k,s,t) { \ | ||
153 | a+=((k)+(t)+H((b),(c),(d))); \ | ||
154 | a=ROTATE(a,s); }; | ||
diff --git a/src/lib/libcrypto/md4/md4_one.c b/src/lib/libcrypto/md4/md4_one.c new file mode 100644 index 0000000000..87a995d38d --- /dev/null +++ b/src/lib/libcrypto/md4/md4_one.c | |||
@@ -0,0 +1,95 @@ | |||
1 | /* crypto/md4/md4_one.c */ | ||
2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) | ||
3 | * All rights reserved. | ||
4 | * | ||
5 | * This package is an SSL implementation written | ||
6 | * by Eric Young (eay@cryptsoft.com). | ||
7 | * The implementation was written so as to conform with Netscapes SSL. | ||
8 | * | ||
9 | * This library is free for commercial and non-commercial use as long as | ||
10 | * the following conditions are aheared to. The following conditions | ||
11 | * apply to all code found in this distribution, be it the RC4, RSA, | ||
12 | * lhash, DES, etc., code; not just the SSL code. The SSL documentation | ||
13 | * included with this distribution is covered by the same copyright terms | ||
14 | * except that the holder is Tim Hudson (tjh@cryptsoft.com). | ||
15 | * | ||
16 | * Copyright remains Eric Young's, and as such any Copyright notices in | ||
17 | * the code are not to be removed. | ||
18 | * If this package is used in a product, Eric Young should be given attribution | ||
19 | * as the author of the parts of the library used. | ||
20 | * This can be in the form of a textual message at program startup or | ||
21 | * in documentation (online or textual) provided with the package. | ||
22 | * | ||
23 | * Redistribution and use in source and binary forms, with or without | ||
24 | * modification, are permitted provided that the following conditions | ||
25 | * are met: | ||
26 | * 1. Redistributions of source code must retain the copyright | ||
27 | * notice, this list of conditions and the following disclaimer. | ||
28 | * 2. Redistributions in binary form must reproduce the above copyright | ||
29 | * notice, this list of conditions and the following disclaimer in the | ||
30 | * documentation and/or other materials provided with the distribution. | ||
31 | * 3. All advertising materials mentioning features or use of this software | ||
32 | * must display the following acknowledgement: | ||
33 | * "This product includes cryptographic software written by | ||
34 | * Eric Young (eay@cryptsoft.com)" | ||
35 | * The word 'cryptographic' can be left out if the rouines from the library | ||
36 | * being used are not cryptographic related :-). | ||
37 | * 4. If you include any Windows specific code (or a derivative thereof) from | ||
38 | * the apps directory (application code) you must include an acknowledgement: | ||
39 | * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" | ||
40 | * | ||
41 | * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND | ||
42 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
43 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
44 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | ||
45 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
46 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
47 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
48 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
49 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
50 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
51 | * SUCH DAMAGE. | ||
52 | * | ||
53 | * The licence and distribution terms for any publically available version or | ||
54 | * derivative of this code cannot be changed. i.e. this code cannot simply be | ||
55 | * copied and put under another distribution licence | ||
56 | * [including the GNU Public Licence.] | ||
57 | */ | ||
58 | |||
59 | #include <stdio.h> | ||
60 | #include <string.h> | ||
61 | #include <openssl/md4.h> | ||
62 | |||
63 | #ifdef CHARSET_EBCDIC | ||
64 | #include <openssl/ebcdic.h> | ||
65 | #endif | ||
66 | |||
67 | unsigned char *MD4(const unsigned char *d, unsigned long n, unsigned char *md) | ||
68 | { | ||
69 | MD4_CTX c; | ||
70 | static unsigned char m[MD4_DIGEST_LENGTH]; | ||
71 | |||
72 | if (md == NULL) md=m; | ||
73 | MD4_Init(&c); | ||
74 | #ifndef CHARSET_EBCDIC | ||
75 | MD4_Update(&c,d,n); | ||
76 | #else | ||
77 | { | ||
78 | char temp[1024]; | ||
79 | unsigned long chunk; | ||
80 | |||
81 | while (n > 0) | ||
82 | { | ||
83 | chunk = (n > sizeof(temp)) ? sizeof(temp) : n; | ||
84 | ebcdic2ascii(temp, d, chunk); | ||
85 | MD4_Update(&c,temp,chunk); | ||
86 | n -= chunk; | ||
87 | d += chunk; | ||
88 | } | ||
89 | } | ||
90 | #endif | ||
91 | MD4_Final(md,&c); | ||
92 | memset(&c,0,sizeof(c)); /* security consideration */ | ||
93 | return(md); | ||
94 | } | ||
95 | |||
diff --git a/src/lib/libcrypto/mem_dbg.c b/src/lib/libcrypto/mem_dbg.c new file mode 100644 index 0000000000..14770c0733 --- /dev/null +++ b/src/lib/libcrypto/mem_dbg.c | |||
@@ -0,0 +1,703 @@ | |||
1 | /* crypto/mem_dbg.c */ | ||
2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) | ||
3 | * All rights reserved. | ||
4 | * | ||
5 | * This package is an SSL implementation written | ||
6 | * by Eric Young (eay@cryptsoft.com). | ||
7 | * The implementation was written so as to conform with Netscapes SSL. | ||
8 | * | ||
9 | * This library is free for commercial and non-commercial use as long as | ||
10 | * the following conditions are aheared to. The following conditions | ||
11 | * apply to all code found in this distribution, be it the RC4, RSA, | ||
12 | * lhash, DES, etc., code; not just the SSL code. The SSL documentation | ||
13 | * included with this distribution is covered by the same copyright terms | ||
14 | * except that the holder is Tim Hudson (tjh@cryptsoft.com). | ||
15 | * | ||
16 | * Copyright remains Eric Young's, and as such any Copyright notices in | ||
17 | * the code are not to be removed. | ||
18 | * If this package is used in a product, Eric Young should be given attribution | ||
19 | * as the author of the parts of the library used. | ||
20 | * This can be in the form of a textual message at program startup or | ||
21 | * in documentation (online or textual) provided with the package. | ||
22 | * | ||
23 | * Redistribution and use in source and binary forms, with or without | ||
24 | * modification, are permitted provided that the following conditions | ||
25 | * are met: | ||
26 | * 1. Redistributions of source code must retain the copyright | ||
27 | * notice, this list of conditions and the following disclaimer. | ||
28 | * 2. Redistributions in binary form must reproduce the above copyright | ||
29 | * notice, this list of conditions and the following disclaimer in the | ||
30 | * documentation and/or other materials provided with the distribution. | ||
31 | * 3. All advertising materials mentioning features or use of this software | ||
32 | * must display the following acknowledgement: | ||
33 | * "This product includes cryptographic software written by | ||
34 | * Eric Young (eay@cryptsoft.com)" | ||
35 | * The word 'cryptographic' can be left out if the rouines from the library | ||
36 | * being used are not cryptographic related :-). | ||
37 | * 4. If you include any Windows specific code (or a derivative thereof) from | ||
38 | * the apps directory (application code) you must include an acknowledgement: | ||
39 | * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" | ||
40 | * | ||
41 | * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND | ||
42 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
43 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
44 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | ||
45 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
46 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
47 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
48 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
49 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
50 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
51 | * SUCH DAMAGE. | ||
52 | * | ||
53 | * The licence and distribution terms for any publically available version or | ||
54 | * derivative of this code cannot be changed. i.e. this code cannot simply be | ||
55 | * copied and put under another distribution licence | ||
56 | * [including the GNU Public Licence.] | ||
57 | */ | ||
58 | |||
59 | #include <stdio.h> | ||
60 | #include <stdlib.h> | ||
61 | #include <time.h> | ||
62 | #include <openssl/crypto.h> | ||
63 | #include <openssl/buffer.h> | ||
64 | #include <openssl/bio.h> | ||
65 | #include <openssl/lhash.h> | ||
66 | #include "cryptlib.h" | ||
67 | |||
68 | static int mh_mode=CRYPTO_MEM_CHECK_OFF; | ||
69 | /* The state changes to CRYPTO_MEM_CHECK_ON | CRYPTO_MEM_CHECK_ENABLE | ||
70 | * when the application asks for it (usually after library initialisation | ||
71 | * for which no book-keeping is desired). | ||
72 | * | ||
73 | * State CRYPTO_MEM_CHECK_ON exists only temporarily when the library | ||
74 | * thinks that certain allocations should not be checked (e.g. the data | ||
75 | * structures used for memory checking). It is not suitable as an initial | ||
76 | * state: the library will unexpectedly enable memory checking when it | ||
77 | * executes one of those sections that want to disable checking | ||
78 | * temporarily. | ||
79 | * | ||
80 | * State CRYPTO_MEM_CHECK_ENABLE without ..._ON makes no sense whatsoever. | ||
81 | */ | ||
82 | |||
83 | static unsigned long order = 0; /* number of memory requests */ | ||
84 | static LHASH *mh=NULL; /* hash-table of memory requests (address as key) */ | ||
85 | |||
86 | |||
87 | typedef struct app_mem_info_st | ||
88 | /* For application-defined information (static C-string `info') | ||
89 | * to be displayed in memory leak list. | ||
90 | * Each thread has its own stack. For applications, there is | ||
91 | * CRYPTO_push_info("...") to push an entry, | ||
92 | * CRYPTO_pop_info() to pop an entry, | ||
93 | * CRYPTO_remove_all_info() to pop all entries. | ||
94 | */ | ||
95 | { | ||
96 | unsigned long thread; | ||
97 | const char *file; | ||
98 | int line; | ||
99 | const char *info; | ||
100 | struct app_mem_info_st *next; /* tail of thread's stack */ | ||
101 | int references; | ||
102 | } APP_INFO; | ||
103 | |||
104 | static LHASH *amih=NULL; /* hash-table with those app_mem_info_st's | ||
105 | * that are at the top of their thread's stack | ||
106 | * (with `thread' as key) */ | ||
107 | |||
108 | typedef struct mem_st | ||
109 | /* memory-block description */ | ||
110 | { | ||
111 | char *addr; | ||
112 | int num; | ||
113 | const char *file; | ||
114 | int line; | ||
115 | unsigned long thread; | ||
116 | unsigned long order; | ||
117 | time_t time; | ||
118 | APP_INFO *app_info; | ||
119 | } MEM; | ||
120 | |||
121 | static long options = /* extra information to be recorded */ | ||
122 | #if defined(CRYPTO_MDEBUG_TIME) || defined(CRYPTO_MDEBUG_ALL) | ||
123 | V_CRYPTO_MDEBUG_TIME | | ||
124 | #endif | ||
125 | #if defined(CRYPTO_MDEBUG_THREAD) || defined(CRYPTO_MDEBUG_ALL) | ||
126 | V_CRYPTO_MDEBUG_THREAD | | ||
127 | #endif | ||
128 | 0; | ||
129 | |||
130 | |||
131 | static unsigned long disabling_thread = 0; | ||
132 | |||
133 | int CRYPTO_mem_ctrl(int mode) | ||
134 | { | ||
135 | int ret=mh_mode; | ||
136 | |||
137 | CRYPTO_w_lock(CRYPTO_LOCK_MALLOC); | ||
138 | switch (mode) | ||
139 | { | ||
140 | /* for applications: */ | ||
141 | case CRYPTO_MEM_CHECK_ON: /* aka MemCheck_start() */ | ||
142 | mh_mode = CRYPTO_MEM_CHECK_ON|CRYPTO_MEM_CHECK_ENABLE; | ||
143 | disabling_thread = 0; | ||
144 | break; | ||
145 | case CRYPTO_MEM_CHECK_OFF: /* aka MemCheck_stop() */ | ||
146 | mh_mode = 0; | ||
147 | disabling_thread = 0; | ||
148 | break; | ||
149 | |||
150 | /* switch off temporarily (for library-internal use): */ | ||
151 | case CRYPTO_MEM_CHECK_DISABLE: /* aka MemCheck_off() */ | ||
152 | if (mh_mode & CRYPTO_MEM_CHECK_ON) | ||
153 | { | ||
154 | mh_mode&= ~CRYPTO_MEM_CHECK_ENABLE; | ||
155 | if (disabling_thread != CRYPTO_thread_id()) /* otherwise we already have the MALLOC2 lock */ | ||
156 | { | ||
157 | /* Long-time lock CRYPTO_LOCK_MALLOC2 must not be claimed while | ||
158 | * we're holding CRYPTO_LOCK_MALLOC, or we'll deadlock if | ||
159 | * somebody else holds CRYPTO_LOCK_MALLOC2 (and cannot release | ||
160 | * it because we block entry to this function). | ||
161 | * Give them a chance, first, and then claim the locks in | ||
162 | * appropriate order (long-time lock first). | ||
163 | */ | ||
164 | CRYPTO_w_unlock(CRYPTO_LOCK_MALLOC); | ||
165 | /* Note that after we have waited for CRYPTO_LOCK_MALLOC2 | ||
166 | * and CRYPTO_LOCK_MALLOC, we'll still be in the right | ||
167 | * "case" and "if" branch because MemCheck_start and | ||
168 | * MemCheck_stop may never be used while there are multiple | ||
169 | * OpenSSL threads. */ | ||
170 | CRYPTO_w_lock(CRYPTO_LOCK_MALLOC2); | ||
171 | CRYPTO_w_lock(CRYPTO_LOCK_MALLOC); | ||
172 | disabling_thread=CRYPTO_thread_id(); | ||
173 | } | ||
174 | } | ||
175 | break; | ||
176 | case CRYPTO_MEM_CHECK_ENABLE: /* aka MemCheck_on() */ | ||
177 | if (mh_mode & CRYPTO_MEM_CHECK_ON) | ||
178 | { | ||
179 | mh_mode|=CRYPTO_MEM_CHECK_ENABLE; | ||
180 | if (disabling_thread != 0) | ||
181 | { | ||
182 | disabling_thread=0; | ||
183 | CRYPTO_w_unlock(CRYPTO_LOCK_MALLOC2); | ||
184 | } | ||
185 | } | ||
186 | break; | ||
187 | |||
188 | default: | ||
189 | break; | ||
190 | } | ||
191 | CRYPTO_w_unlock(CRYPTO_LOCK_MALLOC); | ||
192 | return(ret); | ||
193 | } | ||
194 | |||
195 | int CRYPTO_is_mem_check_on(void) | ||
196 | { | ||
197 | int ret = 0; | ||
198 | |||
199 | if (mh_mode & CRYPTO_MEM_CHECK_ON) | ||
200 | { | ||
201 | CRYPTO_w_lock(CRYPTO_LOCK_MALLOC); | ||
202 | |||
203 | ret = (mh_mode & CRYPTO_MEM_CHECK_ENABLE) | ||
204 | && disabling_thread != CRYPTO_thread_id(); | ||
205 | |||
206 | CRYPTO_w_unlock(CRYPTO_LOCK_MALLOC); | ||
207 | } | ||
208 | return(ret); | ||
209 | } | ||
210 | |||
211 | |||
212 | void CRYPTO_dbg_set_options(long bits) | ||
213 | { | ||
214 | options = bits; | ||
215 | } | ||
216 | |||
217 | long CRYPTO_dbg_get_options(void) | ||
218 | { | ||
219 | return options; | ||
220 | } | ||
221 | |||
222 | static int mem_cmp(MEM *a, MEM *b) | ||
223 | { | ||
224 | return(a->addr - b->addr); | ||
225 | } | ||
226 | |||
227 | static unsigned long mem_hash(MEM *a) | ||
228 | { | ||
229 | unsigned long ret; | ||
230 | |||
231 | ret=(unsigned long)a->addr; | ||
232 | |||
233 | ret=ret*17851+(ret>>14)*7+(ret>>4)*251; | ||
234 | return(ret); | ||
235 | } | ||
236 | |||
237 | static int app_info_cmp(APP_INFO *a, APP_INFO *b) | ||
238 | { | ||
239 | return(a->thread != b->thread); | ||
240 | } | ||
241 | |||
242 | static unsigned long app_info_hash(APP_INFO *a) | ||
243 | { | ||
244 | unsigned long ret; | ||
245 | |||
246 | ret=(unsigned long)a->thread; | ||
247 | |||
248 | ret=ret*17851+(ret>>14)*7+(ret>>4)*251; | ||
249 | return(ret); | ||
250 | } | ||
251 | |||
252 | static APP_INFO *pop_info() | ||
253 | { | ||
254 | APP_INFO tmp; | ||
255 | APP_INFO *ret = NULL; | ||
256 | |||
257 | if (amih != NULL) | ||
258 | { | ||
259 | tmp.thread=CRYPTO_thread_id(); | ||
260 | if ((ret=(APP_INFO *)lh_delete(amih,&tmp)) != NULL) | ||
261 | { | ||
262 | APP_INFO *next=ret->next; | ||
263 | |||
264 | if (next != NULL) | ||
265 | { | ||
266 | next->references++; | ||
267 | lh_insert(amih,(char *)next); | ||
268 | } | ||
269 | #ifdef LEVITTE_DEBUG | ||
270 | if (ret->thread != tmp.thread) | ||
271 | { | ||
272 | fprintf(stderr, "pop_info(): deleted info has other thread ID (%lu) than the current thread (%lu)!!!!\n", | ||
273 | ret->thread, tmp.thread); | ||
274 | abort(); | ||
275 | } | ||
276 | #endif | ||
277 | if (--(ret->references) <= 0) | ||
278 | { | ||
279 | ret->next = NULL; | ||
280 | if (next != NULL) | ||
281 | next->references--; | ||
282 | Free(ret); | ||
283 | } | ||
284 | } | ||
285 | } | ||
286 | return(ret); | ||
287 | } | ||
288 | |||
289 | int CRYPTO_push_info_(const char *info, const char *file, int line) | ||
290 | { | ||
291 | APP_INFO *ami, *amim; | ||
292 | int ret=0; | ||
293 | |||
294 | if (is_MemCheck_on()) | ||
295 | { | ||
296 | MemCheck_off(); /* obtains CRYPTO_LOCK_MALLOC2 */ | ||
297 | |||
298 | if ((ami = (APP_INFO *)Malloc(sizeof(APP_INFO))) == NULL) | ||
299 | { | ||
300 | ret=0; | ||
301 | goto err; | ||
302 | } | ||
303 | if (amih == NULL) | ||
304 | { | ||
305 | if ((amih=lh_new(app_info_hash,app_info_cmp)) == NULL) | ||
306 | { | ||
307 | Free(ami); | ||
308 | ret=0; | ||
309 | goto err; | ||
310 | } | ||
311 | } | ||
312 | |||
313 | ami->thread=CRYPTO_thread_id(); | ||
314 | ami->file=file; | ||
315 | ami->line=line; | ||
316 | ami->info=info; | ||
317 | ami->references=1; | ||
318 | ami->next=NULL; | ||
319 | |||
320 | if ((amim=(APP_INFO *)lh_insert(amih,(char *)ami)) != NULL) | ||
321 | { | ||
322 | #ifdef LEVITTE_DEBUG | ||
323 | if (ami->thread != amim->thread) | ||
324 | { | ||
325 | fprintf(stderr, "CRYPTO_push_info(): previous info has other thread ID (%lu) than the current thread (%lu)!!!!\n", | ||
326 | amim->thread, ami->thread); | ||
327 | abort(); | ||
328 | } | ||
329 | #endif | ||
330 | ami->next=amim; | ||
331 | } | ||
332 | err: | ||
333 | MemCheck_on(); /* releases CRYPTO_LOCK_MALLOC2 */ | ||
334 | } | ||
335 | |||
336 | return(ret); | ||
337 | } | ||
338 | |||
339 | int CRYPTO_pop_info(void) | ||
340 | { | ||
341 | int ret=0; | ||
342 | |||
343 | if (is_MemCheck_on()) /* _must_ be true, or something went severely wrong */ | ||
344 | { | ||
345 | MemCheck_off(); /* obtains CRYPTO_LOCK_MALLOC2 */ | ||
346 | |||
347 | ret=(pop_info() != NULL); | ||
348 | |||
349 | MemCheck_on(); /* releases CRYPTO_LOCK_MALLOC2 */ | ||
350 | } | ||
351 | return(ret); | ||
352 | } | ||
353 | |||
354 | int CRYPTO_remove_all_info(void) | ||
355 | { | ||
356 | int ret=0; | ||
357 | |||
358 | if (is_MemCheck_on()) /* _must_ be true */ | ||
359 | { | ||
360 | MemCheck_off(); /* obtains CRYPTO_LOCK_MALLOC2 */ | ||
361 | |||
362 | while(pop_info() != NULL) | ||
363 | ret++; | ||
364 | |||
365 | MemCheck_on(); /* releases CRYPTO_LOCK_MALLOC2 */ | ||
366 | } | ||
367 | return(ret); | ||
368 | } | ||
369 | |||
370 | |||
371 | static unsigned long break_order_num=0; | ||
372 | void CRYPTO_dbg_malloc(void *addr, int num, const char *file, int line, | ||
373 | int before_p) | ||
374 | { | ||
375 | MEM *m,*mm; | ||
376 | APP_INFO tmp,*amim; | ||
377 | |||
378 | switch(before_p & 127) | ||
379 | { | ||
380 | case 0: | ||
381 | break; | ||
382 | case 1: | ||
383 | if (addr == NULL) | ||
384 | break; | ||
385 | |||
386 | if (is_MemCheck_on()) | ||
387 | { | ||
388 | MemCheck_off(); /* obtains CRYPTO_LOCK_MALLOC2 */ | ||
389 | if ((m=(MEM *)Malloc(sizeof(MEM))) == NULL) | ||
390 | { | ||
391 | Free(addr); | ||
392 | MemCheck_on(); /* releases CRYPTO_LOCK_MALLOC2 */ | ||
393 | return; | ||
394 | } | ||
395 | if (mh == NULL) | ||
396 | { | ||
397 | if ((mh=lh_new(mem_hash,mem_cmp)) == NULL) | ||
398 | { | ||
399 | Free(addr); | ||
400 | Free(m); | ||
401 | addr=NULL; | ||
402 | goto err; | ||
403 | } | ||
404 | } | ||
405 | |||
406 | m->addr=addr; | ||
407 | m->file=file; | ||
408 | m->line=line; | ||
409 | m->num=num; | ||
410 | if (options & V_CRYPTO_MDEBUG_THREAD) | ||
411 | m->thread=CRYPTO_thread_id(); | ||
412 | else | ||
413 | m->thread=0; | ||
414 | |||
415 | if (order == break_order_num) | ||
416 | { | ||
417 | /* BREAK HERE */ | ||
418 | m->order=order; | ||
419 | } | ||
420 | m->order=order++; | ||
421 | #ifdef LEVITTE_DEBUG | ||
422 | fprintf(stderr, "LEVITTE_DEBUG: [%5d] %c 0x%p (%d)\n", | ||
423 | m->order, | ||
424 | (before_p & 128) ? '*' : '+', | ||
425 | m->addr, m->num); | ||
426 | #endif | ||
427 | if (options & V_CRYPTO_MDEBUG_TIME) | ||
428 | m->time=time(NULL); | ||
429 | else | ||
430 | m->time=0; | ||
431 | |||
432 | tmp.thread=CRYPTO_thread_id(); | ||
433 | m->app_info=NULL; | ||
434 | if (amih != NULL | ||
435 | && (amim=(APP_INFO *)lh_retrieve(amih,(char *)&tmp)) != NULL) | ||
436 | { | ||
437 | m->app_info = amim; | ||
438 | amim->references++; | ||
439 | } | ||
440 | |||
441 | if ((mm=(MEM *)lh_insert(mh,(char *)m)) != NULL) | ||
442 | { | ||
443 | /* Not good, but don't sweat it */ | ||
444 | if (mm->app_info != NULL) | ||
445 | { | ||
446 | mm->app_info->references--; | ||
447 | } | ||
448 | Free(mm); | ||
449 | } | ||
450 | err: | ||
451 | MemCheck_on(); /* releases CRYPTO_LOCK_MALLOC2 */ | ||
452 | } | ||
453 | break; | ||
454 | } | ||
455 | return; | ||
456 | } | ||
457 | |||
458 | void CRYPTO_dbg_free(void *addr, int before_p) | ||
459 | { | ||
460 | MEM m,*mp; | ||
461 | |||
462 | switch(before_p) | ||
463 | { | ||
464 | case 0: | ||
465 | if (addr == NULL) | ||
466 | break; | ||
467 | |||
468 | if (is_MemCheck_on() && (mh != NULL)) | ||
469 | { | ||
470 | MemCheck_off(); | ||
471 | |||
472 | m.addr=addr; | ||
473 | mp=(MEM *)lh_delete(mh,(char *)&m); | ||
474 | if (mp != NULL) | ||
475 | { | ||
476 | #ifdef LEVITTE_DEBUG | ||
477 | fprintf(stderr, "LEVITTE_DEBUG: [%5d] - 0x%p (%d)\n", | ||
478 | mp->order, mp->addr, mp->num); | ||
479 | #endif | ||
480 | if (mp->app_info != NULL) | ||
481 | { | ||
482 | mp->app_info->references--; | ||
483 | } | ||
484 | Free(mp); | ||
485 | } | ||
486 | |||
487 | MemCheck_on(); /* releases CRYPTO_LOCK_MALLOC2 */ | ||
488 | } | ||
489 | break; | ||
490 | case 1: | ||
491 | break; | ||
492 | } | ||
493 | } | ||
494 | |||
495 | void CRYPTO_dbg_realloc(void *addr1, void *addr2, int num, | ||
496 | const char *file, int line, int before_p) | ||
497 | { | ||
498 | MEM m,*mp; | ||
499 | |||
500 | #ifdef LEVITTE_DEBUG | ||
501 | fprintf(stderr, "LEVITTE_DEBUG: --> CRYPTO_dbg_malloc(addr1 = %p, addr2 = %p, num = %d, file = \"%s\", line = %d, before_p = %d)\n", | ||
502 | addr1, addr2, num, file, line, before_p); | ||
503 | #endif | ||
504 | |||
505 | switch(before_p) | ||
506 | { | ||
507 | case 0: | ||
508 | break; | ||
509 | case 1: | ||
510 | if (addr2 == NULL) | ||
511 | break; | ||
512 | |||
513 | if (addr1 == NULL) | ||
514 | { | ||
515 | CRYPTO_dbg_malloc(addr2, num, file, line, 128 | before_p); | ||
516 | break; | ||
517 | } | ||
518 | |||
519 | if (is_MemCheck_on()) | ||
520 | { | ||
521 | MemCheck_off(); /* obtains CRYPTO_LOCK_MALLOC2 */ | ||
522 | |||
523 | m.addr=addr1; | ||
524 | mp=(MEM *)lh_delete(mh,(char *)&m); | ||
525 | if (mp != NULL) | ||
526 | { | ||
527 | #ifdef LEVITTE_DEBUG | ||
528 | fprintf(stderr, "LEVITTE_DEBUG: [%5d] * 0x%p (%d) -> 0x%p (%d)\n", | ||
529 | mp->order, | ||
530 | mp->addr, mp->num, | ||
531 | addr2, num); | ||
532 | #endif | ||
533 | mp->addr=addr2; | ||
534 | mp->num=num; | ||
535 | lh_insert(mh,(char *)mp); | ||
536 | } | ||
537 | |||
538 | MemCheck_on(); /* releases CRYPTO_LOCK_MALLOC2 */ | ||
539 | } | ||
540 | break; | ||
541 | } | ||
542 | return; | ||
543 | } | ||
544 | |||
545 | |||
546 | typedef struct mem_leak_st | ||
547 | { | ||
548 | BIO *bio; | ||
549 | int chunks; | ||
550 | long bytes; | ||
551 | } MEM_LEAK; | ||
552 | |||
553 | static void print_leak(MEM *m, MEM_LEAK *l) | ||
554 | { | ||
555 | char buf[1024]; | ||
556 | char *bufp = buf; | ||
557 | APP_INFO *amip; | ||
558 | int ami_cnt; | ||
559 | struct tm *lcl = NULL; | ||
560 | unsigned long ti; | ||
561 | |||
562 | if(m->addr == (char *)l->bio) | ||
563 | return; | ||
564 | |||
565 | if (options & V_CRYPTO_MDEBUG_TIME) | ||
566 | { | ||
567 | lcl = localtime(&m->time); | ||
568 | |||
569 | sprintf(bufp, "[%02d:%02d:%02d] ", | ||
570 | lcl->tm_hour,lcl->tm_min,lcl->tm_sec); | ||
571 | bufp += strlen(bufp); | ||
572 | } | ||
573 | |||
574 | sprintf(bufp, "%5lu file=%s, line=%d, ", | ||
575 | m->order,m->file,m->line); | ||
576 | bufp += strlen(bufp); | ||
577 | |||
578 | if (options & V_CRYPTO_MDEBUG_THREAD) | ||
579 | { | ||
580 | sprintf(bufp, "thread=%lu, ", m->thread); | ||
581 | bufp += strlen(bufp); | ||
582 | } | ||
583 | |||
584 | sprintf(bufp, "number=%d, address=%08lX\n", | ||
585 | m->num,(unsigned long)m->addr); | ||
586 | bufp += strlen(bufp); | ||
587 | |||
588 | BIO_puts(l->bio,buf); | ||
589 | |||
590 | l->chunks++; | ||
591 | l->bytes+=m->num; | ||
592 | |||
593 | amip=m->app_info; | ||
594 | ami_cnt=0; | ||
595 | if (!amip) | ||
596 | return; | ||
597 | ti=amip->thread; | ||
598 | |||
599 | do | ||
600 | { | ||
601 | int buf_len; | ||
602 | int info_len; | ||
603 | |||
604 | ami_cnt++; | ||
605 | memset(buf,'>',ami_cnt); | ||
606 | sprintf(buf + ami_cnt, | ||
607 | " thread=%lu, file=%s, line=%d, info=\"", | ||
608 | amip->thread, amip->file, amip->line); | ||
609 | buf_len=strlen(buf); | ||
610 | info_len=strlen(amip->info); | ||
611 | if (128 - buf_len - 3 < info_len) | ||
612 | { | ||
613 | memcpy(buf + buf_len, amip->info, 128 - buf_len - 3); | ||
614 | buf_len = 128 - 3; | ||
615 | } | ||
616 | else | ||
617 | { | ||
618 | strcpy(buf + buf_len, amip->info); | ||
619 | buf_len = strlen(buf); | ||
620 | } | ||
621 | sprintf(buf + buf_len, "\"\n"); | ||
622 | |||
623 | BIO_puts(l->bio,buf); | ||
624 | |||
625 | amip = amip->next; | ||
626 | } | ||
627 | while(amip && amip->thread == ti); | ||
628 | |||
629 | #ifdef LEVITTE_DEBUG | ||
630 | if (amip) | ||
631 | { | ||
632 | fprintf(stderr, "Thread switch detected in backtrace!!!!\n"); | ||
633 | abort(); | ||
634 | } | ||
635 | #endif | ||
636 | } | ||
637 | |||
638 | void CRYPTO_mem_leaks(BIO *b) | ||
639 | { | ||
640 | MEM_LEAK ml; | ||
641 | char buf[80]; | ||
642 | |||
643 | if (mh == NULL) return; | ||
644 | ml.bio=b; | ||
645 | ml.bytes=0; | ||
646 | ml.chunks=0; | ||
647 | CRYPTO_w_lock(CRYPTO_LOCK_MALLOC2); | ||
648 | lh_doall_arg(mh,(void (*)())print_leak,(char *)&ml); | ||
649 | CRYPTO_w_unlock(CRYPTO_LOCK_MALLOC2); | ||
650 | if (ml.chunks != 0) | ||
651 | { | ||
652 | sprintf(buf,"%ld bytes leaked in %d chunks\n", | ||
653 | ml.bytes,ml.chunks); | ||
654 | BIO_puts(b,buf); | ||
655 | } | ||
656 | |||
657 | #if 0 | ||
658 | lh_stats_bio(mh,b); | ||
659 | lh_node_stats_bio(mh,b); | ||
660 | lh_node_usage_stats_bio(mh,b); | ||
661 | #endif | ||
662 | } | ||
663 | |||
664 | union void_fn_to_char_u | ||
665 | { | ||
666 | char *char_p; | ||
667 | void (*fn_p)(); | ||
668 | }; | ||
669 | |||
670 | static void cb_leak(MEM *m, char *cb) | ||
671 | { | ||
672 | union void_fn_to_char_u mem_callback; | ||
673 | |||
674 | mem_callback.char_p=cb; | ||
675 | mem_callback.fn_p(m->order,m->file,m->line,m->num,m->addr); | ||
676 | } | ||
677 | |||
678 | void CRYPTO_mem_leaks_cb(void (*cb)()) | ||
679 | { | ||
680 | union void_fn_to_char_u mem_cb; | ||
681 | |||
682 | if (mh == NULL) return; | ||
683 | CRYPTO_w_lock(CRYPTO_LOCK_MALLOC2); | ||
684 | mem_cb.fn_p=cb; | ||
685 | lh_doall_arg(mh,(void (*)())cb_leak,mem_cb.char_p); | ||
686 | mem_cb.char_p=NULL; | ||
687 | CRYPTO_w_unlock(CRYPTO_LOCK_MALLOC2); | ||
688 | } | ||
689 | |||
690 | #ifndef NO_FP_API | ||
691 | void CRYPTO_mem_leaks_fp(FILE *fp) | ||
692 | { | ||
693 | BIO *b; | ||
694 | |||
695 | if (mh == NULL) return; | ||
696 | if ((b=BIO_new(BIO_s_file())) == NULL) | ||
697 | return; | ||
698 | BIO_set_fp(b,fp,BIO_NOCLOSE); | ||
699 | CRYPTO_mem_leaks(b); | ||
700 | BIO_free(b); | ||
701 | } | ||
702 | #endif | ||
703 | |||
diff --git a/src/lib/libcrypto/o_time.c b/src/lib/libcrypto/o_time.c new file mode 100644 index 0000000000..1bc0297b36 --- /dev/null +++ b/src/lib/libcrypto/o_time.c | |||
@@ -0,0 +1,203 @@ | |||
1 | /* crypto/o_time.c -*- mode:C; c-file-style: "eay" -*- */ | ||
2 | /* Written by Richard Levitte (richard@levitte.org) for the OpenSSL | ||
3 | * project 2001. | ||
4 | */ | ||
5 | /* ==================================================================== | ||
6 | * Copyright (c) 2001 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/e_os2.h> | ||
60 | #include <string.h> | ||
61 | #include "o_time.h" | ||
62 | |||
63 | #ifdef OPENSSL_SYS_VMS | ||
64 | # include <libdtdef.h> | ||
65 | # include <lib$routines.h> | ||
66 | # include <lnmdef.h> | ||
67 | # include <starlet.h> | ||
68 | # include <descrip.h> | ||
69 | # include <stdlib.h> | ||
70 | #endif | ||
71 | |||
72 | struct tm *OPENSSL_gmtime(const time_t *timer, struct tm *result) | ||
73 | { | ||
74 | struct tm *ts = NULL; | ||
75 | |||
76 | #if defined(OPENSSL_THREADS) && !defined(OPENSSL_SYS_WIN32) && !defined(OPENSSL_SYS_OS2) && !defined(__CYGWIN32__) && (!defined(OPENSSL_SYS_VMS) || defined(gmtime_r)) && !defined(OPENSSL_SYS_MACOSX) | ||
77 | /* should return &data, but doesn't on some systems, | ||
78 | so we don't even look at the return value */ | ||
79 | gmtime_r(timer,result); | ||
80 | ts = result; | ||
81 | #elif !defined(OPENSSL_SYS_VMS) | ||
82 | ts = gmtime(timer); | ||
83 | memcpy(result, ts, sizeof(struct tm)); | ||
84 | ts = result; | ||
85 | #endif | ||
86 | #ifdef OPENSSL_SYS_VMS | ||
87 | if (ts == NULL) | ||
88 | { | ||
89 | static $DESCRIPTOR(tabnam,"LNM$DCL_LOGICAL"); | ||
90 | static $DESCRIPTOR(lognam,"SYS$TIMEZONE_DIFFERENTIAL"); | ||
91 | char logvalue[256]; | ||
92 | unsigned int reslen = 0; | ||
93 | struct { | ||
94 | short buflen; | ||
95 | short code; | ||
96 | void *bufaddr; | ||
97 | unsigned int *reslen; | ||
98 | } itemlist[] = { | ||
99 | { 0, LNM$_STRING, 0, 0 }, | ||
100 | { 0, 0, 0, 0 }, | ||
101 | }; | ||
102 | int status; | ||
103 | time_t t; | ||
104 | |||
105 | /* Get the value for SYS$TIMEZONE_DIFFERENTIAL */ | ||
106 | itemlist[0].buflen = sizeof(logvalue); | ||
107 | itemlist[0].bufaddr = logvalue; | ||
108 | itemlist[0].reslen = &reslen; | ||
109 | status = sys$trnlnm(0, &tabnam, &lognam, 0, itemlist); | ||
110 | if (!(status & 1)) | ||
111 | return NULL; | ||
112 | logvalue[reslen] = '\0'; | ||
113 | |||
114 | /* Get the numerical value of the equivalence string */ | ||
115 | status = atoi(logvalue); | ||
116 | |||
117 | /* and use it to move time to GMT */ | ||
118 | t = *timer - status; | ||
119 | |||
120 | /* then convert the result to the time structure */ | ||
121 | #ifndef OPENSSL_THREADS | ||
122 | ts=(struct tm *)localtime(&t); | ||
123 | #else | ||
124 | /* Since there was no gmtime_r() to do this stuff for us, | ||
125 | we have to do it the hard way. */ | ||
126 | { | ||
127 | /* The VMS epoch is the astronomical Smithsonian date, | ||
128 | if I remember correctly, which is November 17, 1858. | ||
129 | Furthermore, time is measure in thenths of microseconds | ||
130 | and stored in quadwords (64 bit integers). unix_epoch | ||
131 | below is January 1st 1970 expressed as a VMS time. The | ||
132 | following code was used to get this number: | ||
133 | |||
134 | #include <stdio.h> | ||
135 | #include <stdlib.h> | ||
136 | #include <lib$routines.h> | ||
137 | #include <starlet.h> | ||
138 | |||
139 | main() | ||
140 | { | ||
141 | unsigned long systime[2]; | ||
142 | unsigned short epoch_values[7] = | ||
143 | { 1970, 1, 1, 0, 0, 0, 0 }; | ||
144 | |||
145 | lib$cvt_vectim(epoch_values, systime); | ||
146 | |||
147 | printf("%u %u", systime[0], systime[1]); | ||
148 | } | ||
149 | */ | ||
150 | unsigned long unix_epoch[2] = { 1273708544, 8164711 }; | ||
151 | unsigned long deltatime[2]; | ||
152 | unsigned long systime[2]; | ||
153 | struct vms_vectime | ||
154 | { | ||
155 | short year, month, day, hour, minute, second, | ||
156 | centi_second; | ||
157 | } time_values; | ||
158 | long operation; | ||
159 | |||
160 | /* Turn the number of seconds since January 1st 1970 to | ||
161 | an internal delta time. | ||
162 | Note that lib$cvt_to_internal_time() will assume | ||
163 | that t is signed, and will therefore break on 32-bit | ||
164 | systems some time in 2038. | ||
165 | */ | ||
166 | operation = LIB$K_DELTA_SECONDS; | ||
167 | status = lib$cvt_to_internal_time(&operation, | ||
168 | &t, deltatime); | ||
169 | |||
170 | /* Add the delta time with the Unix epoch and we have | ||
171 | the current UTC time in internal format */ | ||
172 | status = lib$add_times(unix_epoch, deltatime, systime); | ||
173 | |||
174 | /* Turn the internal time into a time vector */ | ||
175 | status = sys$numtim(&time_values, systime); | ||
176 | |||
177 | /* Fill in the struct tm with the result */ | ||
178 | result->tm_sec = time_values.second; | ||
179 | result->tm_min = time_values.minute; | ||
180 | result->tm_hour = time_values.hour; | ||
181 | result->tm_mday = time_values.day; | ||
182 | result->tm_mon = time_values.month - 1; | ||
183 | result->tm_year = time_values.year - 1900; | ||
184 | |||
185 | operation = LIB$K_DAY_OF_WEEK; | ||
186 | status = lib$cvt_from_internal_time(&operation, | ||
187 | &result->tm_wday, systime); | ||
188 | result->tm_wday %= 7; | ||
189 | |||
190 | operation = LIB$K_DAY_OF_YEAR; | ||
191 | status = lib$cvt_from_internal_time(&operation, | ||
192 | &result->tm_yday, systime); | ||
193 | result->tm_yday--; | ||
194 | |||
195 | result->tm_isdst = 0; /* There's no way to know... */ | ||
196 | |||
197 | ts = result; | ||
198 | #endif | ||
199 | } | ||
200 | } | ||
201 | #endif | ||
202 | return ts; | ||
203 | } | ||
diff --git a/src/lib/libcrypto/o_time.h b/src/lib/libcrypto/o_time.h new file mode 100644 index 0000000000..e66044626d --- /dev/null +++ b/src/lib/libcrypto/o_time.h | |||
@@ -0,0 +1,66 @@ | |||
1 | /* crypto/o_time.h -*- mode:C; c-file-style: "eay" -*- */ | ||
2 | /* Written by Richard Levitte (richard@levitte.org) for the OpenSSL | ||
3 | * project 2001. | ||
4 | */ | ||
5 | /* ==================================================================== | ||
6 | * Copyright (c) 2001 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_O_TIME_H | ||
60 | #define HEADER_O_TIME_H | ||
61 | |||
62 | #include <time.h> | ||
63 | |||
64 | struct tm *OPENSSL_gmtime(const time_t *timer, struct tm *result); | ||
65 | |||
66 | #endif | ||
diff --git a/src/lib/libcrypto/objects/o_names.c b/src/lib/libcrypto/objects/o_names.c new file mode 100644 index 0000000000..4da5e45b9c --- /dev/null +++ b/src/lib/libcrypto/objects/o_names.c | |||
@@ -0,0 +1,243 @@ | |||
1 | #include <stdio.h> | ||
2 | #include <stdlib.h> | ||
3 | #include <string.h> | ||
4 | |||
5 | #include <openssl/lhash.h> | ||
6 | #include <openssl/objects.h> | ||
7 | |||
8 | /* I use the ex_data stuff to manage the identifiers for the obj_name_types | ||
9 | * that applications may define. I only really use the free function field. | ||
10 | */ | ||
11 | static LHASH *names_lh=NULL; | ||
12 | static int names_type_num=OBJ_NAME_TYPE_NUM; | ||
13 | static STACK *names_cmp=NULL; | ||
14 | static STACK *names_hash=NULL; | ||
15 | static STACK *names_free=NULL; | ||
16 | |||
17 | static unsigned long obj_name_hash(OBJ_NAME *a); | ||
18 | static int obj_name_cmp(OBJ_NAME *a,OBJ_NAME *b); | ||
19 | |||
20 | int OBJ_NAME_init(void) | ||
21 | { | ||
22 | if (names_lh != NULL) return(1); | ||
23 | MemCheck_off(); | ||
24 | names_lh=lh_new(obj_name_hash,obj_name_cmp); | ||
25 | MemCheck_on(); | ||
26 | return(names_lh != NULL); | ||
27 | } | ||
28 | |||
29 | int OBJ_NAME_new_index(unsigned long (*hash_func)(), int (*cmp_func)(), | ||
30 | void (*free_func)()) | ||
31 | { | ||
32 | int ret; | ||
33 | int i; | ||
34 | |||
35 | if (names_free == NULL) | ||
36 | { | ||
37 | MemCheck_off(); | ||
38 | names_hash=sk_new_null(); | ||
39 | names_cmp=sk_new_null(); | ||
40 | names_free=sk_new_null(); | ||
41 | MemCheck_on(); | ||
42 | } | ||
43 | if ((names_free == NULL) || (names_hash == NULL) || (names_cmp == NULL)) | ||
44 | { | ||
45 | /* ERROR */ | ||
46 | return(0); | ||
47 | } | ||
48 | ret=names_type_num; | ||
49 | names_type_num++; | ||
50 | for (i=sk_num(names_free); i<names_type_num; i++) | ||
51 | { | ||
52 | MemCheck_off(); | ||
53 | sk_push(names_hash,(char *)strcmp); | ||
54 | sk_push(names_cmp,(char *)lh_strhash); | ||
55 | sk_push(names_free,NULL); | ||
56 | MemCheck_on(); | ||
57 | } | ||
58 | if (hash_func != NULL) | ||
59 | sk_set(names_hash,ret,(char *)hash_func); | ||
60 | if (cmp_func != NULL) | ||
61 | sk_set(names_cmp,ret,(char *)cmp_func); | ||
62 | if (free_func != NULL) | ||
63 | sk_set(names_free,ret,(char *)free_func); | ||
64 | return(ret); | ||
65 | } | ||
66 | |||
67 | static int obj_name_cmp(OBJ_NAME *a, OBJ_NAME *b) | ||
68 | { | ||
69 | int ret; | ||
70 | int (*cmp)(); | ||
71 | |||
72 | ret=a->type-b->type; | ||
73 | if (ret == 0) | ||
74 | { | ||
75 | if ((names_cmp != NULL) && (sk_num(names_cmp) > a->type)) | ||
76 | { | ||
77 | cmp=(int (*)())sk_value(names_cmp,a->type); | ||
78 | ret=cmp(a->name,b->name); | ||
79 | } | ||
80 | else | ||
81 | ret=strcmp(a->name,b->name); | ||
82 | } | ||
83 | return(ret); | ||
84 | } | ||
85 | |||
86 | static unsigned long obj_name_hash(OBJ_NAME *a) | ||
87 | { | ||
88 | unsigned long ret; | ||
89 | unsigned long (*hash)(); | ||
90 | |||
91 | if ((names_hash != NULL) && (sk_num(names_hash) > a->type)) | ||
92 | { | ||
93 | hash=(unsigned long (*)())sk_value(names_hash,a->type); | ||
94 | ret=hash(a->name); | ||
95 | } | ||
96 | else | ||
97 | { | ||
98 | ret=lh_strhash(a->name); | ||
99 | } | ||
100 | ret^=a->type; | ||
101 | return(ret); | ||
102 | } | ||
103 | |||
104 | const char *OBJ_NAME_get(const char *name, int type) | ||
105 | { | ||
106 | OBJ_NAME on,*ret; | ||
107 | int num=0,alias; | ||
108 | |||
109 | if (name == NULL) return(NULL); | ||
110 | if ((names_lh == NULL) && !OBJ_NAME_init()) return(NULL); | ||
111 | |||
112 | alias=type&OBJ_NAME_ALIAS; | ||
113 | type&= ~OBJ_NAME_ALIAS; | ||
114 | |||
115 | on.name=name; | ||
116 | on.type=type; | ||
117 | |||
118 | for (;;) | ||
119 | { | ||
120 | ret=(OBJ_NAME *)lh_retrieve(names_lh,(char *)&on); | ||
121 | if (ret == NULL) return(NULL); | ||
122 | if ((ret->alias) && !alias) | ||
123 | { | ||
124 | if (++num > 10) return(NULL); | ||
125 | on.name=ret->data; | ||
126 | } | ||
127 | else | ||
128 | { | ||
129 | return(ret->data); | ||
130 | } | ||
131 | } | ||
132 | } | ||
133 | |||
134 | int OBJ_NAME_add(const char *name, int type, const char *data) | ||
135 | { | ||
136 | void (*f)(); | ||
137 | OBJ_NAME *onp,*ret; | ||
138 | int alias; | ||
139 | |||
140 | if ((names_lh == NULL) && !OBJ_NAME_init()) return(0); | ||
141 | |||
142 | alias=type&OBJ_NAME_ALIAS; | ||
143 | type&= ~OBJ_NAME_ALIAS; | ||
144 | |||
145 | onp=(OBJ_NAME *)Malloc(sizeof(OBJ_NAME)); | ||
146 | if (onp == NULL) | ||
147 | { | ||
148 | /* ERROR */ | ||
149 | return(0); | ||
150 | } | ||
151 | |||
152 | onp->name=name; | ||
153 | onp->alias=alias; | ||
154 | onp->type=type; | ||
155 | onp->data=data; | ||
156 | |||
157 | ret=(OBJ_NAME *)lh_insert(names_lh,(char *)onp); | ||
158 | if (ret != NULL) | ||
159 | { | ||
160 | /* free things */ | ||
161 | if ((names_free != NULL) && (sk_num(names_free) > ret->type)) | ||
162 | { | ||
163 | f=(void (*)())sk_value(names_free,ret->type); | ||
164 | f(ret->name,ret->type,ret->data); | ||
165 | } | ||
166 | Free((char *)ret); | ||
167 | } | ||
168 | else | ||
169 | { | ||
170 | if (lh_error(names_lh)) | ||
171 | { | ||
172 | /* ERROR */ | ||
173 | return(0); | ||
174 | } | ||
175 | } | ||
176 | return(1); | ||
177 | } | ||
178 | |||
179 | int OBJ_NAME_remove(const char *name, int type) | ||
180 | { | ||
181 | OBJ_NAME on,*ret; | ||
182 | void (*f)(); | ||
183 | |||
184 | if (names_lh == NULL) return(0); | ||
185 | |||
186 | type&= ~OBJ_NAME_ALIAS; | ||
187 | on.name=name; | ||
188 | on.type=type; | ||
189 | ret=(OBJ_NAME *)lh_delete(names_lh,(char *)&on); | ||
190 | if (ret != NULL) | ||
191 | { | ||
192 | /* free things */ | ||
193 | if ((names_free != NULL) && (sk_num(names_free) > type)) | ||
194 | { | ||
195 | f=(void (*)())sk_value(names_free,type); | ||
196 | f(ret->name,ret->type,ret->data); | ||
197 | } | ||
198 | Free((char *)ret); | ||
199 | return(1); | ||
200 | } | ||
201 | else | ||
202 | return(0); | ||
203 | } | ||
204 | |||
205 | static int free_type; | ||
206 | |||
207 | static void names_lh_free(OBJ_NAME *onp, int type) | ||
208 | { | ||
209 | if(onp == NULL) | ||
210 | return; | ||
211 | |||
212 | if ((free_type < 0) || (free_type == onp->type)) | ||
213 | { | ||
214 | OBJ_NAME_remove(onp->name,onp->type); | ||
215 | } | ||
216 | } | ||
217 | |||
218 | void OBJ_NAME_cleanup(int type) | ||
219 | { | ||
220 | unsigned long down_load; | ||
221 | |||
222 | if (names_lh == NULL) return; | ||
223 | |||
224 | free_type=type; | ||
225 | down_load=names_lh->down_load; | ||
226 | names_lh->down_load=0; | ||
227 | |||
228 | lh_doall(names_lh,names_lh_free); | ||
229 | if (type < 0) | ||
230 | { | ||
231 | lh_free(names_lh); | ||
232 | sk_free(names_hash); | ||
233 | sk_free(names_cmp); | ||
234 | sk_free(names_free); | ||
235 | names_lh=NULL; | ||
236 | names_hash=NULL; | ||
237 | names_cmp=NULL; | ||
238 | names_free=NULL; | ||
239 | } | ||
240 | else | ||
241 | names_lh->down_load=down_load; | ||
242 | } | ||
243 | |||
diff --git a/src/lib/libcrypto/objects/obj_mac.num b/src/lib/libcrypto/objects/obj_mac.num new file mode 100644 index 0000000000..d73a51370f --- /dev/null +++ b/src/lib/libcrypto/objects/obj_mac.num | |||
@@ -0,0 +1,392 @@ | |||
1 | undef 0 | ||
2 | rsadsi 1 | ||
3 | pkcs 2 | ||
4 | md2 3 | ||
5 | md5 4 | ||
6 | rc4 5 | ||
7 | rsaEncryption 6 | ||
8 | md2WithRSAEncryption 7 | ||
9 | md5WithRSAEncryption 8 | ||
10 | pbeWithMD2AndDES_CBC 9 | ||
11 | pbeWithMD5AndDES_CBC 10 | ||
12 | X500 11 | ||
13 | X509 12 | ||
14 | commonName 13 | ||
15 | countryName 14 | ||
16 | localityName 15 | ||
17 | stateOrProvinceName 16 | ||
18 | organizationName 17 | ||
19 | organizationalUnitName 18 | ||
20 | rsa 19 | ||
21 | pkcs7 20 | ||
22 | pkcs7_data 21 | ||
23 | pkcs7_signed 22 | ||
24 | pkcs7_enveloped 23 | ||
25 | pkcs7_signedAndEnveloped 24 | ||
26 | pkcs7_digest 25 | ||
27 | pkcs7_encrypted 26 | ||
28 | pkcs3 27 | ||
29 | dhKeyAgreement 28 | ||
30 | des_ecb 29 | ||
31 | des_cfb64 30 | ||
32 | des_cbc 31 | ||
33 | des_ede 32 | ||
34 | des_ede3 33 | ||
35 | idea_cbc 34 | ||
36 | idea_cfb64 35 | ||
37 | idea_ecb 36 | ||
38 | rc2_cbc 37 | ||
39 | rc2_ecb 38 | ||
40 | rc2_cfb64 39 | ||
41 | rc2_ofb64 40 | ||
42 | sha 41 | ||
43 | shaWithRSAEncryption 42 | ||
44 | des_ede_cbc 43 | ||
45 | des_ede3_cbc 44 | ||
46 | des_ofb64 45 | ||
47 | idea_ofb64 46 | ||
48 | pkcs9 47 | ||
49 | pkcs9_emailAddress 48 | ||
50 | pkcs9_unstructuredName 49 | ||
51 | pkcs9_contentType 50 | ||
52 | pkcs9_messageDigest 51 | ||
53 | pkcs9_signingTime 52 | ||
54 | pkcs9_countersignature 53 | ||
55 | pkcs9_challengePassword 54 | ||
56 | pkcs9_unstructuredAddress 55 | ||
57 | pkcs9_extCertAttributes 56 | ||
58 | netscape 57 | ||
59 | netscape_cert_extension 58 | ||
60 | netscape_data_type 59 | ||
61 | des_ede_cfb64 60 | ||
62 | des_ede3_cfb64 61 | ||
63 | des_ede_ofb64 62 | ||
64 | des_ede3_ofb64 63 | ||
65 | sha1 64 | ||
66 | sha1WithRSAEncryption 65 | ||
67 | dsaWithSHA 66 | ||
68 | dsa_2 67 | ||
69 | pbeWithSHA1AndRC2_CBC 68 | ||
70 | id_pbkdf2 69 | ||
71 | dsaWithSHA1_2 70 | ||
72 | netscape_cert_type 71 | ||
73 | netscape_base_url 72 | ||
74 | netscape_revocation_url 73 | ||
75 | netscape_ca_revocation_url 74 | ||
76 | netscape_renewal_url 75 | ||
77 | netscape_ca_policy_url 76 | ||
78 | netscape_ssl_server_name 77 | ||
79 | netscape_comment 78 | ||
80 | netscape_cert_sequence 79 | ||
81 | desx_cbc 80 | ||
82 | id_ce 81 | ||
83 | subject_key_identifier 82 | ||
84 | key_usage 83 | ||
85 | private_key_usage_period 84 | ||
86 | subject_alt_name 85 | ||
87 | issuer_alt_name 86 | ||
88 | basic_constraints 87 | ||
89 | crl_number 88 | ||
90 | certificate_policies 89 | ||
91 | authority_key_identifier 90 | ||
92 | bf_cbc 91 | ||
93 | bf_ecb 92 | ||
94 | bf_cfb64 93 | ||
95 | bf_ofb64 94 | ||
96 | mdc2 95 | ||
97 | mdc2WithRSA 96 | ||
98 | rc4_40 97 | ||
99 | rc2_40_cbc 98 | ||
100 | givenName 99 | ||
101 | surname 100 | ||
102 | initials 101 | ||
103 | uniqueIdentifier 102 | ||
104 | crl_distribution_points 103 | ||
105 | md5WithRSA 104 | ||
106 | serialNumber 105 | ||
107 | title 106 | ||
108 | description 107 | ||
109 | cast5_cbc 108 | ||
110 | cast5_ecb 109 | ||
111 | cast5_cfb64 110 | ||
112 | cast5_ofb64 111 | ||
113 | pbeWithMD5AndCast5_CBC 112 | ||
114 | dsaWithSHA1 113 | ||
115 | md5_sha1 114 | ||
116 | sha1WithRSA 115 | ||
117 | dsa 116 | ||
118 | ripemd160 117 | ||
119 | ripemd160WithRSA 119 | ||
120 | rc5_cbc 120 | ||
121 | rc5_ecb 121 | ||
122 | rc5_cfb64 122 | ||
123 | rc5_ofb64 123 | ||
124 | rle_compression 124 | ||
125 | zlib_compression 125 | ||
126 | ext_key_usage 126 | ||
127 | id_pkix 127 | ||
128 | id_kp 128 | ||
129 | server_auth 129 | ||
130 | client_auth 130 | ||
131 | code_sign 131 | ||
132 | email_protect 132 | ||
133 | time_stamp 133 | ||
134 | ms_code_ind 134 | ||
135 | ms_code_com 135 | ||
136 | ms_ctl_sign 136 | ||
137 | ms_sgc 137 | ||
138 | ms_efs 138 | ||
139 | ns_sgc 139 | ||
140 | delta_crl 140 | ||
141 | crl_reason 141 | ||
142 | invalidity_date 142 | ||
143 | sxnet 143 | ||
144 | pbe_WithSHA1And128BitRC4 144 | ||
145 | pbe_WithSHA1And40BitRC4 145 | ||
146 | pbe_WithSHA1And3_Key_TripleDES_CBC 146 | ||
147 | pbe_WithSHA1And2_Key_TripleDES_CBC 147 | ||
148 | pbe_WithSHA1And128BitRC2_CBC 148 | ||
149 | pbe_WithSHA1And40BitRC2_CBC 149 | ||
150 | keyBag 150 | ||
151 | pkcs8ShroudedKeyBag 151 | ||
152 | certBag 152 | ||
153 | crlBag 153 | ||
154 | secretBag 154 | ||
155 | safeContentsBag 155 | ||
156 | friendlyName 156 | ||
157 | localKeyID 157 | ||
158 | x509Certificate 158 | ||
159 | sdsiCertificate 159 | ||
160 | x509Crl 160 | ||
161 | pbes2 161 | ||
162 | pbmac1 162 | ||
163 | hmacWithSHA1 163 | ||
164 | id_qt_cps 164 | ||
165 | id_qt_unotice 165 | ||
166 | rc2_64_cbc 166 | ||
167 | SMIMECapabilities 167 | ||
168 | pbeWithMD2AndRC2_CBC 168 | ||
169 | pbeWithMD5AndRC2_CBC 169 | ||
170 | pbeWithSHA1AndDES_CBC 170 | ||
171 | ms_ext_req 171 | ||
172 | ext_req 172 | ||
173 | name 173 | ||
174 | dnQualifier 174 | ||
175 | id_pe 175 | ||
176 | id_ad 176 | ||
177 | info_access 177 | ||
178 | ad_OCSP 178 | ||
179 | ad_ca_issuers 179 | ||
180 | OCSP_sign 180 | ||
181 | iso 181 | ||
182 | member_body 182 | ||
183 | ISO_US 183 | ||
184 | X9_57 184 | ||
185 | X9cm 185 | ||
186 | pkcs1 186 | ||
187 | pkcs5 187 | ||
188 | SMIME 188 | ||
189 | id_smime_mod 189 | ||
190 | id_smime_ct 190 | ||
191 | id_smime_aa 191 | ||
192 | id_smime_alg 192 | ||
193 | id_smime_cd 193 | ||
194 | id_smime_spq 194 | ||
195 | id_smime_cti 195 | ||
196 | id_smime_mod_cms 196 | ||
197 | id_smime_mod_ess 197 | ||
198 | id_smime_mod_oid 198 | ||
199 | id_smime_mod_msg_v3 199 | ||
200 | id_smime_mod_ets_eSignature_88 200 | ||
201 | id_smime_mod_ets_eSignature_97 201 | ||
202 | id_smime_mod_ets_eSigPolicy_88 202 | ||
203 | id_smime_mod_ets_eSigPolicy_97 203 | ||
204 | id_smime_ct_receipt 204 | ||
205 | id_smime_ct_authData 205 | ||
206 | id_smime_ct_publishCert 206 | ||
207 | id_smime_ct_TSTInfo 207 | ||
208 | id_smime_ct_TDTInfo 208 | ||
209 | id_smime_ct_contentInfo 209 | ||
210 | id_smime_ct_DVCSRequestData 210 | ||
211 | id_smime_ct_DVCSResponseData 211 | ||
212 | id_smime_aa_receiptRequest 212 | ||
213 | id_smime_aa_securityLabel 213 | ||
214 | id_smime_aa_mlExpandHistory 214 | ||
215 | id_smime_aa_contentHint 215 | ||
216 | id_smime_aa_msgSigDigest 216 | ||
217 | id_smime_aa_encapContentType 217 | ||
218 | id_smime_aa_contentIdentifier 218 | ||
219 | id_smime_aa_macValue 219 | ||
220 | id_smime_aa_equivalentLabels 220 | ||
221 | id_smime_aa_contentReference 221 | ||
222 | id_smime_aa_encrypKeyPref 222 | ||
223 | id_smime_aa_signingCertificate 223 | ||
224 | id_smime_aa_smimeEncryptCerts 224 | ||
225 | id_smime_aa_timeStampToken 225 | ||
226 | id_smime_aa_ets_sigPolicyId 226 | ||
227 | id_smime_aa_ets_commitmentType 227 | ||
228 | id_smime_aa_ets_signerLocation 228 | ||
229 | id_smime_aa_ets_signerAttr 229 | ||
230 | id_smime_aa_ets_otherSigCert 230 | ||
231 | id_smime_aa_ets_contentTimestamp 231 | ||
232 | id_smime_aa_ets_CertificateRefs 232 | ||
233 | id_smime_aa_ets_RevocationRefs 233 | ||
234 | id_smime_aa_ets_certValues 234 | ||
235 | id_smime_aa_ets_revocationValues 235 | ||
236 | id_smime_aa_ets_escTimeStamp 236 | ||
237 | id_smime_aa_ets_certCRLTimestamp 237 | ||
238 | id_smime_aa_ets_archiveTimeStamp 238 | ||
239 | id_smime_aa_signatureType 239 | ||
240 | id_smime_aa_dvcs_dvc 240 | ||
241 | id_smime_alg_ESDHwith3DES 241 | ||
242 | id_smime_alg_ESDHwithRC2 242 | ||
243 | id_smime_alg_3DESwrap 243 | ||
244 | id_smime_alg_RC2wrap 244 | ||
245 | id_smime_alg_ESDH 245 | ||
246 | id_smime_alg_CMS3DESwrap 246 | ||
247 | id_smime_alg_CMSRC2wrap 247 | ||
248 | id_smime_cd_ldap 248 | ||
249 | id_smime_spq_ets_sqt_uri 249 | ||
250 | id_smime_spq_ets_sqt_unotice 250 | ||
251 | id_smime_cti_ets_proofOfOrigin 251 | ||
252 | id_smime_cti_ets_proofOfReceipt 252 | ||
253 | id_smime_cti_ets_proofOfDelivery 253 | ||
254 | id_smime_cti_ets_proofOfSender 254 | ||
255 | id_smime_cti_ets_proofOfApproval 255 | ||
256 | id_smime_cti_ets_proofOfCreation 256 | ||
257 | md4 257 | ||
258 | id_pkix_mod 258 | ||
259 | id_qt 259 | ||
260 | id_it 260 | ||
261 | id_pkip 261 | ||
262 | id_alg 262 | ||
263 | id_cmc 263 | ||
264 | id_on 264 | ||
265 | id_pda 265 | ||
266 | id_aca 266 | ||
267 | id_qcs 267 | ||
268 | id_cct 268 | ||
269 | id_pkix1_explicit_88 269 | ||
270 | id_pkix1_implicit_88 270 | ||
271 | id_pkix1_explicit_93 271 | ||
272 | id_pkix1_implicit_93 272 | ||
273 | id_mod_crmf 273 | ||
274 | id_mod_cmc 274 | ||
275 | id_mod_kea_profile_88 275 | ||
276 | id_mod_kea_profile_93 276 | ||
277 | id_mod_cmp 277 | ||
278 | id_mod_qualified_cert_88 278 | ||
279 | id_mod_qualified_cert_93 279 | ||
280 | id_mod_attribute_cert 280 | ||
281 | id_mod_timestamp_protocol 281 | ||
282 | id_mod_ocsp 282 | ||
283 | id_mod_dvcs 283 | ||
284 | id_mod_cmp2000 284 | ||
285 | biometricInfo 285 | ||
286 | qcStatements 286 | ||
287 | ac_auditEntity 287 | ||
288 | ac_targeting 288 | ||
289 | aaControls 289 | ||
290 | sbqp_ipAddrBlock 290 | ||
291 | sbqp_autonomousSysNum 291 | ||
292 | sbqp_routerIdentifier 292 | ||
293 | textNotice 293 | ||
294 | ipsecEndSystem 294 | ||
295 | ipsecTunnel 295 | ||
296 | ipsecUser 296 | ||
297 | dvcs 297 | ||
298 | id_it_caProtEncCert 298 | ||
299 | id_it_signKeyPairTypes 299 | ||
300 | id_it_encKeyPairTypes 300 | ||
301 | id_it_preferredSymmAlg 301 | ||
302 | id_it_caKeyUpdateInfo 302 | ||
303 | id_it_currentCRL 303 | ||
304 | id_it_unsupportedOIDs 304 | ||
305 | id_it_subscriptionRequest 305 | ||
306 | id_it_subscriptionResponse 306 | ||
307 | id_it_keyPairParamReq 307 | ||
308 | id_it_keyPairParamRep 308 | ||
309 | id_it_revPassphrase 309 | ||
310 | id_it_implicitConfirm 310 | ||
311 | id_it_confirmWaitTime 311 | ||
312 | id_it_origPKIMessage 312 | ||
313 | id_regCtrl 313 | ||
314 | id_regInfo 314 | ||
315 | id_regCtrl_regToken 315 | ||
316 | id_regCtrl_authenticator 316 | ||
317 | id_regCtrl_pkiPublicationInfo 317 | ||
318 | id_regCtrl_pkiArchiveOptions 318 | ||
319 | id_regCtrl_oldCertID 319 | ||
320 | id_regCtrl_protocolEncrKey 320 | ||
321 | id_regInfo_utf8Pairs 321 | ||
322 | id_regInfo_certReq 322 | ||
323 | id_alg_des40 323 | ||
324 | id_alg_noSignature 324 | ||
325 | id_alg_dh_sig_hmac_sha1 325 | ||
326 | id_alg_dh_pop 326 | ||
327 | id_cmc_statusInfo 327 | ||
328 | id_cmc_identification 328 | ||
329 | id_cmc_identityProof 329 | ||
330 | id_cmc_dataReturn 330 | ||
331 | id_cmc_transactionId 331 | ||
332 | id_cmc_senderNonce 332 | ||
333 | id_cmc_recipientNonce 333 | ||
334 | id_cmc_addExtensions 334 | ||
335 | id_cmc_encryptedPOP 335 | ||
336 | id_cmc_decryptedPOP 336 | ||
337 | id_cmc_lraPOPWitness 337 | ||
338 | id_cmc_getCert 338 | ||
339 | id_cmc_getCRL 339 | ||
340 | id_cmc_revokeRequest 340 | ||
341 | id_cmc_regInfo 341 | ||
342 | id_cmc_responseInfo 342 | ||
343 | id_cmc_queryPending 343 | ||
344 | id_cmc_popLinkRandom 344 | ||
345 | id_cmc_popLinkWitness 345 | ||
346 | id_cmc_confirmCertAcceptance 346 | ||
347 | id_on_personalData 347 | ||
348 | id_pda_dateOfBirth 348 | ||
349 | id_pda_placeOfBirth 349 | ||
350 | id_pda_pseudonym 350 | ||
351 | id_pda_gender 351 | ||
352 | id_pda_countryOfCitizenship 352 | ||
353 | id_pda_countryOfResidence 353 | ||
354 | id_aca_authenticationInfo 354 | ||
355 | id_aca_accessIdentity 355 | ||
356 | id_aca_chargingIdentity 356 | ||
357 | id_aca_group 357 | ||
358 | id_aca_role 358 | ||
359 | id_qcs_pkixQCSyntax_v1 359 | ||
360 | id_cct_crs 360 | ||
361 | id_cct_PKIData 361 | ||
362 | id_cct_PKIResponse 362 | ||
363 | ad_timeStamping 363 | ||
364 | ad_dvcs 364 | ||
365 | id_pkix_OCSP_basic 365 | ||
366 | id_pkix_OCSP_Nonce 366 | ||
367 | id_pkix_OCSP_CrlID 367 | ||
368 | id_pkix_OCSP_acceptableResponses 368 | ||
369 | id_pkix_OCSP_noCheck 369 | ||
370 | id_pkix_OCSP_archiveCutoff 370 | ||
371 | id_pkix_OCSP_serviceLocator 371 | ||
372 | id_pkix_OCSP_extendedStatus 372 | ||
373 | id_pkix_OCSP_valid 373 | ||
374 | id_pkix_OCSP_path 374 | ||
375 | id_pkix_OCSP_trustRoot 375 | ||
376 | algorithm 376 | ||
377 | rsaSignature 377 | ||
378 | X500algorithms 378 | ||
379 | org 379 | ||
380 | dod 380 | ||
381 | iana 381 | ||
382 | Directory 382 | ||
383 | Management 383 | ||
384 | Experimental 384 | ||
385 | Private 385 | ||
386 | Security 386 | ||
387 | SNMPv2 387 | ||
388 | Mail 388 | ||
389 | Enterprises 389 | ||
390 | dcObject 390 | ||
391 | domainComponent 391 | ||
392 | Domain 392 | ||
diff --git a/src/lib/libcrypto/objects/objects.README b/src/lib/libcrypto/objects/objects.README new file mode 100644 index 0000000000..4d745508d8 --- /dev/null +++ b/src/lib/libcrypto/objects/objects.README | |||
@@ -0,0 +1,44 @@ | |||
1 | objects.txt syntax | ||
2 | ------------------ | ||
3 | |||
4 | To cover all the naming hacks that were previously in objects.h needed some | ||
5 | kind of hacks in objects.txt. | ||
6 | |||
7 | The basic syntax for adding an object is as follows: | ||
8 | |||
9 | 1 2 3 4 : shortName : Long Name | ||
10 | |||
11 | If the long name doesn't contain spaces, or no short name | ||
12 | exists, the long name is used as basis for the base name | ||
13 | in C. Otherwise, the short name is used. | ||
14 | |||
15 | The base name (let's call it 'base') will then be used to | ||
16 | create the C macros SN_base, LN_base, NID_base and OBJ_base. | ||
17 | |||
18 | Note that if the base name contains spaces, dashes or periods, | ||
19 | those will be converte to underscore. | ||
20 | |||
21 | Then there are some extra commands: | ||
22 | |||
23 | !Alias foo 1 2 3 4 | ||
24 | |||
25 | This juts makes a name foo for an OID. The C macro | ||
26 | OBJ_foo will be created as a result. | ||
27 | |||
28 | !Cname foo | ||
29 | |||
30 | This makes sure that the name foo will be used as base name | ||
31 | in C. | ||
32 | |||
33 | !module foo | ||
34 | 1 2 3 4 : shortName : Long Name | ||
35 | !global | ||
36 | |||
37 | The !module command was meant to define a kind of modularity. | ||
38 | What it does is to make sure the module name is prepended | ||
39 | to the base name. !global turns this off. This construction | ||
40 | is not recursive. | ||
41 | |||
42 | Lines starting with # are treated as comments, as well as any line starting | ||
43 | with ! and not matching the commands above. | ||
44 | |||
diff --git a/src/lib/libcrypto/objects/objects.pl b/src/lib/libcrypto/objects/objects.pl new file mode 100644 index 0000000000..c956bbb841 --- /dev/null +++ b/src/lib/libcrypto/objects/objects.pl | |||
@@ -0,0 +1,224 @@ | |||
1 | #!/usr/local/bin/perl | ||
2 | |||
3 | open (NUMIN,"$ARGV[1]") || die "Can't open number file $ARGV[1]"; | ||
4 | $max_nid=0; | ||
5 | $o=0; | ||
6 | while(<NUMIN>) | ||
7 | { | ||
8 | chop; | ||
9 | $o++; | ||
10 | s/#.*$//; | ||
11 | next if /^\s*$/; | ||
12 | ($Cname,$mynum) = split; | ||
13 | if (defined($nidn{$mynum})) | ||
14 | { die "$ARGV[1]:$o:There's already an object with NID ",$mynum," on line ",$order{$mynum},"\n"; } | ||
15 | $nid{$Cname} = $mynum; | ||
16 | $nidn{$mynum} = $Cname; | ||
17 | $order{$mynum} = $o; | ||
18 | $max_nid = $mynum if $mynum > $max_nid; | ||
19 | } | ||
20 | close NUMIN; | ||
21 | |||
22 | open (IN,"$ARGV[0]") || die "Can't open input file $ARGV[0]"; | ||
23 | $Cname=""; | ||
24 | $o=0; | ||
25 | while (<IN>) | ||
26 | { | ||
27 | chop; | ||
28 | $o++; | ||
29 | if (/^!module\s+(.*)$/) | ||
30 | { | ||
31 | $module = $1."-"; | ||
32 | $module =~ s/\./_/g; | ||
33 | $module =~ s/-/_/g; | ||
34 | } | ||
35 | if (/^!global$/) | ||
36 | { $module = ""; } | ||
37 | if (/^!Cname\s+(.*)$/) | ||
38 | { $Cname = $1; } | ||
39 | if (/^!Alias\s+(.+?)\s+(.*)$/) | ||
40 | { | ||
41 | $Cname = $module.$1; | ||
42 | $myoid = $2; | ||
43 | $myoid = &process_oid($myoid); | ||
44 | $Cname =~ s/-/_/g; | ||
45 | $ordern{$o} = $Cname; | ||
46 | $order{$Cname} = $o; | ||
47 | $obj{$Cname} = $myoid; | ||
48 | $_ = ""; | ||
49 | $Cname = ""; | ||
50 | } | ||
51 | s/!.*$//; | ||
52 | s/#.*$//; | ||
53 | next if /^\s*$/; | ||
54 | ($myoid,$mysn,$myln) = split ':'; | ||
55 | $mysn =~ s/^\s*//; | ||
56 | $mysn =~ s/\s*$//; | ||
57 | $myln =~ s/^\s*//; | ||
58 | $myln =~ s/\s*$//; | ||
59 | $myoid =~ s/^\s*//; | ||
60 | $myoid =~ s/\s*$//; | ||
61 | if ($myoid ne "") | ||
62 | { | ||
63 | $myoid = &process_oid($myoid); | ||
64 | } | ||
65 | |||
66 | if ($Cname eq "" && !($myln =~ / /)) | ||
67 | { | ||
68 | $Cname = $myln; | ||
69 | $Cname =~ s/\./_/g; | ||
70 | $Cname =~ s/-/_/g; | ||
71 | if ($Cname ne "" && defined($ln{$module.$Cname})) | ||
72 | { die "objects.txt:$o:There's already an object with long name ",$ln{$module.$Cname}," on line ",$order{$module.$Cname},"\n"; } | ||
73 | } | ||
74 | if ($Cname eq "") | ||
75 | { | ||
76 | $Cname = $mysn; | ||
77 | $Cname =~ s/-/_/g; | ||
78 | if ($Cname ne "" && defined($sn{$module.$Cname})) | ||
79 | { die "objects.txt:$o:There's already an object with short name ",$sn{$module.$Cname}," on line ",$order{$module.$Cname},"\n"; } | ||
80 | } | ||
81 | if ($Cname eq "") | ||
82 | { | ||
83 | $Cname = $myln; | ||
84 | $Cname =~ s/-/_/g; | ||
85 | $Cname =~ s/\./_/g; | ||
86 | $Cname =~ s/ /_/g; | ||
87 | if ($Cname ne "" && defined($ln{$module.$Cname})) | ||
88 | { die "objects.txt:$o:There's already an object with long name ",$ln{$module.$Cname}," on line ",$order{$module.$Cname},"\n"; } | ||
89 | } | ||
90 | $Cname =~ s/\./_/g; | ||
91 | $Cname =~ s/-/_/g; | ||
92 | $Cname = $module.$Cname; | ||
93 | $ordern{$o} = $Cname; | ||
94 | $order{$Cname} = $o; | ||
95 | $sn{$Cname} = $mysn; | ||
96 | $ln{$Cname} = $myln; | ||
97 | $obj{$Cname} = $myoid; | ||
98 | if (!defined($nid{$Cname})) | ||
99 | { | ||
100 | $max_nid++; | ||
101 | $nid{$Cname} = $max_nid; | ||
102 | $nidn{$max_nid} = $Cname; | ||
103 | } | ||
104 | $Cname=""; | ||
105 | } | ||
106 | close IN; | ||
107 | |||
108 | open (NUMOUT,">$ARGV[1]") || die "Can't open output file $ARGV[1]"; | ||
109 | foreach (sort { $a <=> $b } keys %nidn) | ||
110 | { | ||
111 | print NUMOUT $nidn{$_},"\t\t",$_,"\n"; | ||
112 | } | ||
113 | close NUMOUT; | ||
114 | |||
115 | open (OUT,">$ARGV[2]") || die "Can't open output file $ARGV[2]"; | ||
116 | print OUT <<'EOF'; | ||
117 | /* lib/obj/obj_mac.h */ | ||
118 | /* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) | ||
119 | * All rights reserved. | ||
120 | * | ||
121 | * This package is an SSL implementation written | ||
122 | * by Eric Young (eay@cryptsoft.com). | ||
123 | * The implementation was written so as to conform with Netscapes SSL. | ||
124 | * | ||
125 | * This library is free for commercial and non-commercial use as long as | ||
126 | * the following conditions are aheared to. The following conditions | ||
127 | * apply to all code found in this distribution, be it the RC4, RSA, | ||
128 | * lhash, DES, etc., code; not just the SSL code. The SSL documentation | ||
129 | * included with this distribution is covered by the same copyright terms | ||
130 | * except that the holder is Tim Hudson (tjh@cryptsoft.com). | ||
131 | * | ||
132 | * Copyright remains Eric Young's, and as such any Copyright notices in | ||
133 | * the code are not to be removed. | ||
134 | * If this package is used in a product, Eric Young should be given attribution | ||
135 | * as the author of the parts of the library used. | ||
136 | * This can be in the form of a textual message at program startup or | ||
137 | * in documentation (online or textual) provided with the package. | ||
138 | * | ||
139 | * Redistribution and use in source and binary forms, with or without | ||
140 | * modification, are permitted provided that the following conditions | ||
141 | * are met: | ||
142 | * 1. Redistributions of source code must retain the copyright | ||
143 | * notice, this list of conditions and the following disclaimer. | ||
144 | * 2. Redistributions in binary form must reproduce the above copyright | ||
145 | * notice, this list of conditions and the following disclaimer in the | ||
146 | * documentation and/or other materials provided with the distribution. | ||
147 | * 3. All advertising materials mentioning features or use of this software | ||
148 | * must display the following acknowledgement: | ||
149 | * "This product includes cryptographic software written by | ||
150 | * Eric Young (eay@cryptsoft.com)" | ||
151 | * The word 'cryptographic' can be left out if the rouines from the library | ||
152 | * being used are not cryptographic related :-). | ||
153 | * 4. If you include any Windows specific code (or a derivative thereof) from | ||
154 | * the apps directory (application code) you must include an acknowledgement: | ||
155 | * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" | ||
156 | * | ||
157 | * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND | ||
158 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
159 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
160 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | ||
161 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
162 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
163 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
164 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
165 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
166 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
167 | * SUCH DAMAGE. | ||
168 | * | ||
169 | * The licence and distribution terms for any publically available version or | ||
170 | * derivative of this code cannot be changed. i.e. this code cannot simply be | ||
171 | * copied and put under another distribution licence | ||
172 | * [including the GNU Public Licence.] | ||
173 | */ | ||
174 | |||
175 | /* THIS FILE IS GENERATED FROM objects.txt by objects.pl via the | ||
176 | * following command: | ||
177 | * perl objects.pl objects.txt obj_mac.num obj_mac.h | ||
178 | */ | ||
179 | |||
180 | #define SN_undef "UNDEF" | ||
181 | #define LN_undef "undefined" | ||
182 | #define NID_undef 0 | ||
183 | #define OBJ_undef 0L | ||
184 | |||
185 | EOF | ||
186 | |||
187 | foreach (sort { $a <=> $b } keys %ordern) | ||
188 | { | ||
189 | $Cname=$ordern{$_}; | ||
190 | print OUT "#define SN_",$Cname,"\t\t\"",$sn{$Cname},"\"\n" if $sn{$Cname} ne ""; | ||
191 | print OUT "#define LN_",$Cname,"\t\t\"",$ln{$Cname},"\"\n" if $ln{$Cname} ne ""; | ||
192 | print OUT "#define NID_",$Cname,"\t\t",$nid{$Cname},"\n" if $nid{$Cname} ne ""; | ||
193 | print OUT "#define OBJ_",$Cname,"\t\t",$obj{$Cname},"\n" if $obj{$Cname} ne ""; | ||
194 | print OUT "\n"; | ||
195 | } | ||
196 | |||
197 | close OUT; | ||
198 | |||
199 | sub process_oid | ||
200 | { | ||
201 | local($oid)=@_; | ||
202 | local(@a,$oid_pref); | ||
203 | |||
204 | @a = split(/\s+/,$myoid); | ||
205 | $pref_oid = ""; | ||
206 | $pref_sep = ""; | ||
207 | if (!($a[0] =~ /^[0-9]+$/)) | ||
208 | { | ||
209 | $a[0] =~ s/-/_/g; | ||
210 | $pref_oid = "OBJ_" . $a[0]; | ||
211 | $pref_sep = ","; | ||
212 | shift @a; | ||
213 | } | ||
214 | $oids = join('L,',@a) . "L"; | ||
215 | if ($oids ne "L") | ||
216 | { | ||
217 | $oids = $pref_oid . $pref_sep . $oids; | ||
218 | } | ||
219 | else | ||
220 | { | ||
221 | $oids = $pref_oid; | ||
222 | } | ||
223 | return($oids); | ||
224 | } | ||
diff --git a/src/lib/libcrypto/ocsp/ocsp.h b/src/lib/libcrypto/ocsp/ocsp.h new file mode 100644 index 0000000000..fab3c03182 --- /dev/null +++ b/src/lib/libcrypto/ocsp/ocsp.h | |||
@@ -0,0 +1,619 @@ | |||
1 | /* ocsp.h */ | ||
2 | /* Written by Tom Titchener <Tom_Titchener@groove.net> for the OpenSSL | ||
3 | * project. */ | ||
4 | |||
5 | /* History: | ||
6 | This file was transfered to Richard Levitte from CertCo by Kathy | ||
7 | Weinhold in mid-spring 2000 to be included in OpenSSL or released | ||
8 | as a patch kit. */ | ||
9 | |||
10 | /* ==================================================================== | ||
11 | * Copyright (c) 1998-2000 The OpenSSL Project. All rights reserved. | ||
12 | * | ||
13 | * Redistribution and use in source and binary forms, with or without | ||
14 | * modification, are permitted provided that the following conditions | ||
15 | * are met: | ||
16 | * | ||
17 | * 1. Redistributions of source code must retain the above copyright | ||
18 | * notice, this list of conditions and the following disclaimer. | ||
19 | * | ||
20 | * 2. Redistributions in binary form must reproduce the above copyright | ||
21 | * notice, this list of conditions and the following disclaimer in | ||
22 | * the documentation and/or other materials provided with the | ||
23 | * distribution. | ||
24 | * | ||
25 | * 3. All advertising materials mentioning features or use of this | ||
26 | * software must display the following acknowledgment: | ||
27 | * "This product includes software developed by the OpenSSL Project | ||
28 | * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" | ||
29 | * | ||
30 | * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to | ||
31 | * endorse or promote products derived from this software without | ||
32 | * prior written permission. For written permission, please contact | ||
33 | * openssl-core@openssl.org. | ||
34 | * | ||
35 | * 5. Products derived from this software may not be called "OpenSSL" | ||
36 | * nor may "OpenSSL" appear in their names without prior written | ||
37 | * permission of the OpenSSL Project. | ||
38 | * | ||
39 | * 6. Redistributions of any form whatsoever must retain the following | ||
40 | * acknowledgment: | ||
41 | * "This product includes software developed by the OpenSSL Project | ||
42 | * for use in the OpenSSL Toolkit (http://www.openssl.org/)" | ||
43 | * | ||
44 | * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY | ||
45 | * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
46 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | ||
47 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR | ||
48 | * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
49 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
50 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
51 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
52 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
53 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
54 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED | ||
55 | * OF THE POSSIBILITY OF SUCH DAMAGE. | ||
56 | * ==================================================================== | ||
57 | * | ||
58 | * This product includes cryptographic software written by Eric Young | ||
59 | * (eay@cryptsoft.com). This product includes software written by Tim | ||
60 | * Hudson (tjh@cryptsoft.com). | ||
61 | * | ||
62 | */ | ||
63 | |||
64 | #ifndef HEADER_OCSP_H | ||
65 | #define HEADER_OCSP_H | ||
66 | |||
67 | #include <openssl/x509.h> | ||
68 | #include <openssl/x509v3.h> | ||
69 | #include <openssl/safestack.h> | ||
70 | |||
71 | #ifdef __cplusplus | ||
72 | extern "C" { | ||
73 | #endif | ||
74 | |||
75 | /* Various flags and values */ | ||
76 | |||
77 | #define OCSP_DEFAULT_NONCE_LENGTH 16 | ||
78 | |||
79 | #define OCSP_NOCERTS 0x1 | ||
80 | #define OCSP_NOINTERN 0x2 | ||
81 | #define OCSP_NOSIGS 0x4 | ||
82 | #define OCSP_NOCHAIN 0x8 | ||
83 | #define OCSP_NOVERIFY 0x10 | ||
84 | #define OCSP_NOEXPLICIT 0x20 | ||
85 | #define OCSP_NOCASIGN 0x40 | ||
86 | #define OCSP_NODELEGATED 0x80 | ||
87 | #define OCSP_NOCHECKS 0x100 | ||
88 | #define OCSP_TRUSTOTHER 0x200 | ||
89 | #define OCSP_RESPID_KEY 0x400 | ||
90 | #define OCSP_NOTIME 0x800 | ||
91 | |||
92 | /* CertID ::= SEQUENCE { | ||
93 | * hashAlgorithm AlgorithmIdentifier, | ||
94 | * issuerNameHash OCTET STRING, -- Hash of Issuer's DN | ||
95 | * issuerKeyHash OCTET STRING, -- Hash of Issuers public key (excluding the tag & length fields) | ||
96 | * serialNumber CertificateSerialNumber } | ||
97 | */ | ||
98 | typedef struct ocsp_cert_id_st | ||
99 | { | ||
100 | X509_ALGOR *hashAlgorithm; | ||
101 | ASN1_OCTET_STRING *issuerNameHash; | ||
102 | ASN1_OCTET_STRING *issuerKeyHash; | ||
103 | ASN1_INTEGER *serialNumber; | ||
104 | } OCSP_CERTID; | ||
105 | |||
106 | DECLARE_STACK_OF(OCSP_CERTID) | ||
107 | |||
108 | /* Request ::= SEQUENCE { | ||
109 | * reqCert CertID, | ||
110 | * singleRequestExtensions [0] EXPLICIT Extensions OPTIONAL } | ||
111 | */ | ||
112 | typedef struct ocsp_one_request_st | ||
113 | { | ||
114 | OCSP_CERTID *reqCert; | ||
115 | STACK_OF(X509_EXTENSION) *singleRequestExtensions; | ||
116 | } OCSP_ONEREQ; | ||
117 | |||
118 | DECLARE_STACK_OF(OCSP_ONEREQ) | ||
119 | DECLARE_ASN1_SET_OF(OCSP_ONEREQ) | ||
120 | |||
121 | |||
122 | /* TBSRequest ::= SEQUENCE { | ||
123 | * version [0] EXPLICIT Version DEFAULT v1, | ||
124 | * requestorName [1] EXPLICIT GeneralName OPTIONAL, | ||
125 | * requestList SEQUENCE OF Request, | ||
126 | * requestExtensions [2] EXPLICIT Extensions OPTIONAL } | ||
127 | */ | ||
128 | typedef struct ocsp_req_info_st | ||
129 | { | ||
130 | ASN1_INTEGER *version; | ||
131 | GENERAL_NAME *requestorName; | ||
132 | STACK_OF(OCSP_ONEREQ) *requestList; | ||
133 | STACK_OF(X509_EXTENSION) *requestExtensions; | ||
134 | } OCSP_REQINFO; | ||
135 | |||
136 | /* Signature ::= SEQUENCE { | ||
137 | * signatureAlgorithm AlgorithmIdentifier, | ||
138 | * signature BIT STRING, | ||
139 | * certs [0] EXPLICIT SEQUENCE OF Certificate OPTIONAL } | ||
140 | */ | ||
141 | typedef struct ocsp_signature_st | ||
142 | { | ||
143 | X509_ALGOR *signatureAlgorithm; | ||
144 | ASN1_BIT_STRING *signature; | ||
145 | STACK_OF(X509) *certs; | ||
146 | } OCSP_SIGNATURE; | ||
147 | |||
148 | /* OCSPRequest ::= SEQUENCE { | ||
149 | * tbsRequest TBSRequest, | ||
150 | * optionalSignature [0] EXPLICIT Signature OPTIONAL } | ||
151 | */ | ||
152 | typedef struct ocsp_request_st | ||
153 | { | ||
154 | OCSP_REQINFO *tbsRequest; | ||
155 | OCSP_SIGNATURE *optionalSignature; /* OPTIONAL */ | ||
156 | } OCSP_REQUEST; | ||
157 | |||
158 | /* OCSPResponseStatus ::= ENUMERATED { | ||
159 | * successful (0), --Response has valid confirmations | ||
160 | * malformedRequest (1), --Illegal confirmation request | ||
161 | * internalError (2), --Internal error in issuer | ||
162 | * tryLater (3), --Try again later | ||
163 | * --(4) is not used | ||
164 | * sigRequired (5), --Must sign the request | ||
165 | * unauthorized (6) --Request unauthorized | ||
166 | * } | ||
167 | */ | ||
168 | #define OCSP_RESPONSE_STATUS_SUCCESSFUL 0 | ||
169 | #define OCSP_RESPONSE_STATUS_MALFORMEDREQUEST 1 | ||
170 | #define OCSP_RESPONSE_STATUS_INTERNALERROR 2 | ||
171 | #define OCSP_RESPONSE_STATUS_TRYLATER 3 | ||
172 | #define OCSP_RESPONSE_STATUS_SIGREQUIRED 5 | ||
173 | #define OCSP_RESPONSE_STATUS_UNAUTHORIZED 6 | ||
174 | |||
175 | /* ResponseBytes ::= SEQUENCE { | ||
176 | * responseType OBJECT IDENTIFIER, | ||
177 | * response OCTET STRING } | ||
178 | */ | ||
179 | typedef struct ocsp_resp_bytes_st | ||
180 | { | ||
181 | ASN1_OBJECT *responseType; | ||
182 | ASN1_OCTET_STRING *response; | ||
183 | } OCSP_RESPBYTES; | ||
184 | |||
185 | /* OCSPResponse ::= SEQUENCE { | ||
186 | * responseStatus OCSPResponseStatus, | ||
187 | * responseBytes [0] EXPLICIT ResponseBytes OPTIONAL } | ||
188 | */ | ||
189 | typedef struct ocsp_response_st | ||
190 | { | ||
191 | ASN1_ENUMERATED *responseStatus; | ||
192 | OCSP_RESPBYTES *responseBytes; | ||
193 | } OCSP_RESPONSE; | ||
194 | |||
195 | /* ResponderID ::= CHOICE { | ||
196 | * byName [1] Name, | ||
197 | * byKey [2] KeyHash } | ||
198 | */ | ||
199 | #define V_OCSP_RESPID_NAME 0 | ||
200 | #define V_OCSP_RESPID_KEY 1 | ||
201 | typedef struct ocsp_responder_id_st | ||
202 | { | ||
203 | int type; | ||
204 | union { | ||
205 | X509_NAME* byName; | ||
206 | ASN1_OCTET_STRING *byKey; | ||
207 | } value; | ||
208 | } OCSP_RESPID; | ||
209 | /* KeyHash ::= OCTET STRING --SHA-1 hash of responder's public key | ||
210 | * --(excluding the tag and length fields) | ||
211 | */ | ||
212 | |||
213 | /* RevokedInfo ::= SEQUENCE { | ||
214 | * revocationTime GeneralizedTime, | ||
215 | * revocationReason [0] EXPLICIT CRLReason OPTIONAL } | ||
216 | */ | ||
217 | typedef struct ocsp_revoked_info_st | ||
218 | { | ||
219 | ASN1_GENERALIZEDTIME *revocationTime; | ||
220 | ASN1_ENUMERATED *revocationReason; | ||
221 | } OCSP_REVOKEDINFO; | ||
222 | |||
223 | /* CertStatus ::= CHOICE { | ||
224 | * good [0] IMPLICIT NULL, | ||
225 | * revoked [1] IMPLICIT RevokedInfo, | ||
226 | * unknown [2] IMPLICIT UnknownInfo } | ||
227 | */ | ||
228 | #define V_OCSP_CERTSTATUS_GOOD 0 | ||
229 | #define V_OCSP_CERTSTATUS_REVOKED 1 | ||
230 | #define V_OCSP_CERTSTATUS_UNKNOWN 2 | ||
231 | typedef struct ocsp_cert_status_st | ||
232 | { | ||
233 | int type; | ||
234 | union { | ||
235 | ASN1_NULL *good; | ||
236 | OCSP_REVOKEDINFO *revoked; | ||
237 | ASN1_NULL *unknown; | ||
238 | } value; | ||
239 | } OCSP_CERTSTATUS; | ||
240 | |||
241 | /* SingleResponse ::= SEQUENCE { | ||
242 | * certID CertID, | ||
243 | * certStatus CertStatus, | ||
244 | * thisUpdate GeneralizedTime, | ||
245 | * nextUpdate [0] EXPLICIT GeneralizedTime OPTIONAL, | ||
246 | * singleExtensions [1] EXPLICIT Extensions OPTIONAL } | ||
247 | */ | ||
248 | typedef struct ocsp_single_response_st | ||
249 | { | ||
250 | OCSP_CERTID *certId; | ||
251 | OCSP_CERTSTATUS *certStatus; | ||
252 | ASN1_GENERALIZEDTIME *thisUpdate; | ||
253 | ASN1_GENERALIZEDTIME *nextUpdate; | ||
254 | STACK_OF(X509_EXTENSION) *singleExtensions; | ||
255 | } OCSP_SINGLERESP; | ||
256 | |||
257 | DECLARE_STACK_OF(OCSP_SINGLERESP) | ||
258 | DECLARE_ASN1_SET_OF(OCSP_SINGLERESP) | ||
259 | |||
260 | /* ResponseData ::= SEQUENCE { | ||
261 | * version [0] EXPLICIT Version DEFAULT v1, | ||
262 | * responderID ResponderID, | ||
263 | * producedAt GeneralizedTime, | ||
264 | * responses SEQUENCE OF SingleResponse, | ||
265 | * responseExtensions [1] EXPLICIT Extensions OPTIONAL } | ||
266 | */ | ||
267 | typedef struct ocsp_response_data_st | ||
268 | { | ||
269 | ASN1_INTEGER *version; | ||
270 | OCSP_RESPID *responderId; | ||
271 | ASN1_GENERALIZEDTIME *producedAt; | ||
272 | STACK_OF(OCSP_SINGLERESP) *responses; | ||
273 | STACK_OF(X509_EXTENSION) *responseExtensions; | ||
274 | } OCSP_RESPDATA; | ||
275 | |||
276 | /* BasicOCSPResponse ::= SEQUENCE { | ||
277 | * tbsResponseData ResponseData, | ||
278 | * signatureAlgorithm AlgorithmIdentifier, | ||
279 | * signature BIT STRING, | ||
280 | * certs [0] EXPLICIT SEQUENCE OF Certificate OPTIONAL } | ||
281 | */ | ||
282 | /* Note 1: | ||
283 | The value for "signature" is specified in the OCSP rfc2560 as follows: | ||
284 | "The value for the signature SHALL be computed on the hash of the DER | ||
285 | encoding ResponseData." This means that you must hash the DER-encoded | ||
286 | tbsResponseData, and then run it through a crypto-signing function, which | ||
287 | will (at least w/RSA) do a hash-'n'-private-encrypt operation. This seems | ||
288 | a bit odd, but that's the spec. Also note that the data structures do not | ||
289 | leave anywhere to independently specify the algorithm used for the initial | ||
290 | hash. So, we look at the signature-specification algorithm, and try to do | ||
291 | something intelligent. -- Kathy Weinhold, CertCo */ | ||
292 | /* Note 2: | ||
293 | It seems that the mentioned passage from RFC 2560 (section 4.2.1) is open | ||
294 | for interpretation. I've done tests against another responder, and found | ||
295 | that it doesn't do the double hashing that the RFC seems to say one | ||
296 | should. Therefore, all relevant functions take a flag saying which | ||
297 | variant should be used. -- Richard Levitte, OpenSSL team and CeloCom */ | ||
298 | typedef struct ocsp_basic_response_st | ||
299 | { | ||
300 | OCSP_RESPDATA *tbsResponseData; | ||
301 | X509_ALGOR *signatureAlgorithm; | ||
302 | ASN1_BIT_STRING *signature; | ||
303 | STACK_OF(X509) *certs; | ||
304 | } OCSP_BASICRESP; | ||
305 | |||
306 | /* | ||
307 | * CRLReason ::= ENUMERATED { | ||
308 | * unspecified (0), | ||
309 | * keyCompromise (1), | ||
310 | * cACompromise (2), | ||
311 | * affiliationChanged (3), | ||
312 | * superseded (4), | ||
313 | * cessationOfOperation (5), | ||
314 | * certificateHold (6), | ||
315 | * removeFromCRL (8) } | ||
316 | */ | ||
317 | #define OCSP_REVOKED_STATUS_NOSTATUS -1 | ||
318 | #define OCSP_REVOKED_STATUS_UNSPECIFIED 0 | ||
319 | #define OCSP_REVOKED_STATUS_KEYCOMPROMISE 1 | ||
320 | #define OCSP_REVOKED_STATUS_CACOMPROMISE 2 | ||
321 | #define OCSP_REVOKED_STATUS_AFFILIATIONCHANGED 3 | ||
322 | #define OCSP_REVOKED_STATUS_SUPERSEDED 4 | ||
323 | #define OCSP_REVOKED_STATUS_CESSATIONOFOPERATION 5 | ||
324 | #define OCSP_REVOKED_STATUS_CERTIFICATEHOLD 6 | ||
325 | #define OCSP_REVOKED_STATUS_REMOVEFROMCRL 8 | ||
326 | |||
327 | /* CrlID ::= SEQUENCE { | ||
328 | * crlUrl [0] EXPLICIT IA5String OPTIONAL, | ||
329 | * crlNum [1] EXPLICIT INTEGER OPTIONAL, | ||
330 | * crlTime [2] EXPLICIT GeneralizedTime OPTIONAL } | ||
331 | */ | ||
332 | typedef struct ocsp_crl_id_st | ||
333 | { | ||
334 | ASN1_IA5STRING *crlUrl; | ||
335 | ASN1_INTEGER *crlNum; | ||
336 | ASN1_GENERALIZEDTIME *crlTime; | ||
337 | } OCSP_CRLID; | ||
338 | |||
339 | /* ServiceLocator ::= SEQUENCE { | ||
340 | * issuer Name, | ||
341 | * locator AuthorityInfoAccessSyntax OPTIONAL } | ||
342 | */ | ||
343 | typedef struct ocsp_service_locator_st | ||
344 | { | ||
345 | X509_NAME* issuer; | ||
346 | STACK_OF(ACCESS_DESCRIPTION) *locator; | ||
347 | } OCSP_SERVICELOC; | ||
348 | |||
349 | #define PEM_STRING_OCSP_REQUEST "OCSP REQUEST" | ||
350 | #define PEM_STRING_OCSP_RESPONSE "OCSP RESPONSE" | ||
351 | |||
352 | #define d2i_OCSP_REQUEST_bio(bp,p) (OCSP_REQUEST*)ASN1_d2i_bio((char*(*)()) \ | ||
353 | OCSP_REQUEST_new,(char *(*)())d2i_OCSP_REQUEST, (bp),\ | ||
354 | (unsigned char **)(p)) | ||
355 | |||
356 | #define d2i_OCSP_RESPONSE_bio(bp,p) (OCSP_RESPONSE*)ASN1_d2i_bio((char*(*)())\ | ||
357 | OCSP_REQUEST_new,(char *(*)())d2i_OCSP_RESPONSE, (bp),\ | ||
358 | (unsigned char **)(p)) | ||
359 | |||
360 | #define PEM_read_bio_OCSP_REQUEST(bp,x,cb) (OCSP_REQUEST *)PEM_ASN1_read_bio( \ | ||
361 | (char *(*)())d2i_OCSP_REQUEST,PEM_STRING_OCSP_REQUEST,bp,(char **)x,cb,NULL) | ||
362 | |||
363 | #define PEM_read_bio_OCSP_RESPONSE(bp,x,cb)(OCSP_RESPONSE *)PEM_ASN1_read_bio(\ | ||
364 | (char *(*)())d2i_OCSP_RESPONSE,PEM_STRING_OCSP_RESPONSE,bp,(char **)x,cb,NULL) | ||
365 | |||
366 | #define PEM_write_bio_OCSP_REQUEST(bp,o) \ | ||
367 | PEM_ASN1_write_bio((int (*)())i2d_OCSP_REQUEST,PEM_STRING_OCSP_REQUEST,\ | ||
368 | bp,(char *)o, NULL,NULL,0,NULL,NULL) | ||
369 | |||
370 | #define PEM_write_bio_OCSP_RESPONSE(bp,o) \ | ||
371 | PEM_ASN1_write_bio((int (*)())i2d_OCSP_RESPONSE,PEM_STRING_OCSP_RESPONSE,\ | ||
372 | bp,(char *)o, NULL,NULL,0,NULL,NULL) | ||
373 | |||
374 | #define i2d_OCSP_RESPONSE_bio(bp,o) ASN1_i2d_bio(i2d_OCSP_RESPONSE,bp,\ | ||
375 | (unsigned char *)o) | ||
376 | |||
377 | #define i2d_OCSP_REQUEST_bio(bp,o) ASN1_i2d_bio(i2d_OCSP_REQUEST,bp,\ | ||
378 | (unsigned char *)o) | ||
379 | |||
380 | #define OCSP_REQUEST_sign(o,pkey,md) \ | ||
381 | ASN1_item_sign(ASN1_ITEM_rptr(OCSP_REQINFO),\ | ||
382 | o->optionalSignature->signatureAlgorithm,NULL,\ | ||
383 | o->optionalSignature->signature,o->tbsRequest,pkey,md) | ||
384 | |||
385 | #define OCSP_BASICRESP_sign(o,pkey,md,d) \ | ||
386 | ASN1_item_sign(ASN1_ITEM_rptr(OCSP_RESPDATA),o->signatureAlgorithm,NULL,\ | ||
387 | o->signature,o->tbsResponseData,pkey,md) | ||
388 | |||
389 | #define OCSP_REQUEST_verify(a,r) ASN1_item_verify(ASN1_ITEM_rptr(OCSP_REQINFO),\ | ||
390 | a->optionalSignature->signatureAlgorithm,\ | ||
391 | a->optionalSignature->signature,a->tbsRequest,r) | ||
392 | |||
393 | #define OCSP_BASICRESP_verify(a,r,d) ASN1_item_verify(ASN1_ITEM_rptr(OCSP_RESPDATA),\ | ||
394 | a->signatureAlgorithm,a->signature,a->tbsResponseData,r) | ||
395 | |||
396 | #define ASN1_BIT_STRING_digest(data,type,md,len) \ | ||
397 | ASN1_item_digest(ASN1_ITEM_rptr(ASN1_BIT_STRING),type,data,md,len) | ||
398 | |||
399 | #define OCSP_CERTID_dup(cid) (OCSP_CERTID*)ASN1_dup((int(*)())i2d_OCSP_CERTID,\ | ||
400 | (char *(*)())d2i_OCSP_CERTID,(char *)(cid)) | ||
401 | |||
402 | #define OCSP_CERTSTATUS_dup(cs)\ | ||
403 | (OCSP_CERTSTATUS*)ASN1_dup((int(*)())i2d_OCSP_CERTSTATUS,\ | ||
404 | (char *(*)())d2i_OCSP_CERTSTATUS,(char *)(cs)) | ||
405 | |||
406 | OCSP_RESPONSE *OCSP_sendreq_bio(BIO *b, char *path, OCSP_REQUEST *req); | ||
407 | |||
408 | OCSP_CERTID *OCSP_cert_to_id(const EVP_MD *dgst, X509 *subject, X509 *issuer); | ||
409 | |||
410 | OCSP_CERTID *OCSP_cert_id_new(const EVP_MD *dgst, | ||
411 | X509_NAME *issuerName, | ||
412 | ASN1_BIT_STRING* issuerKey, | ||
413 | ASN1_INTEGER *serialNumber); | ||
414 | |||
415 | OCSP_ONEREQ *OCSP_request_add0_id(OCSP_REQUEST *req, OCSP_CERTID *cid); | ||
416 | |||
417 | int OCSP_request_add1_nonce(OCSP_REQUEST *req, unsigned char *val, int len); | ||
418 | int OCSP_basic_add1_nonce(OCSP_BASICRESP *resp, unsigned char *val, int len); | ||
419 | int OCSP_check_nonce(OCSP_REQUEST *req, OCSP_BASICRESP *bs); | ||
420 | int OCSP_copy_nonce(OCSP_BASICRESP *resp, OCSP_REQUEST *req); | ||
421 | |||
422 | int OCSP_request_set1_name(OCSP_REQUEST *req, X509_NAME *nm); | ||
423 | int OCSP_request_add1_cert(OCSP_REQUEST *req, X509 *cert); | ||
424 | |||
425 | int OCSP_request_sign(OCSP_REQUEST *req, | ||
426 | X509 *signer, | ||
427 | EVP_PKEY *key, | ||
428 | const EVP_MD *dgst, | ||
429 | STACK_OF(X509) *certs, | ||
430 | unsigned long flags); | ||
431 | |||
432 | int OCSP_response_status(OCSP_RESPONSE *resp); | ||
433 | OCSP_BASICRESP *OCSP_response_get1_basic(OCSP_RESPONSE *resp); | ||
434 | |||
435 | int OCSP_resp_count(OCSP_BASICRESP *bs); | ||
436 | OCSP_SINGLERESP *OCSP_resp_get0(OCSP_BASICRESP *bs, int idx); | ||
437 | int OCSP_resp_find(OCSP_BASICRESP *bs, OCSP_CERTID *id, int last); | ||
438 | int OCSP_single_get0_status(OCSP_SINGLERESP *single, int *reason, | ||
439 | ASN1_GENERALIZEDTIME **revtime, | ||
440 | ASN1_GENERALIZEDTIME **thisupd, | ||
441 | ASN1_GENERALIZEDTIME **nextupd); | ||
442 | int OCSP_resp_find_status(OCSP_BASICRESP *bs, OCSP_CERTID *id, int *status, | ||
443 | int *reason, | ||
444 | ASN1_GENERALIZEDTIME **revtime, | ||
445 | ASN1_GENERALIZEDTIME **thisupd, | ||
446 | ASN1_GENERALIZEDTIME **nextupd); | ||
447 | int OCSP_check_validity(ASN1_GENERALIZEDTIME *thisupd, | ||
448 | ASN1_GENERALIZEDTIME *nextupd, | ||
449 | long sec, long maxsec); | ||
450 | |||
451 | int OCSP_request_verify(OCSP_REQUEST *req, STACK_OF(X509) *certs, X509_STORE *store, unsigned long flags); | ||
452 | |||
453 | int OCSP_parse_url(char *url, char **phost, char **pport, char **ppath, int *pssl); | ||
454 | |||
455 | int OCSP_id_issuer_cmp(OCSP_CERTID *a, OCSP_CERTID *b); | ||
456 | int OCSP_id_cmp(OCSP_CERTID *a, OCSP_CERTID *b); | ||
457 | |||
458 | int OCSP_request_onereq_count(OCSP_REQUEST *req); | ||
459 | OCSP_ONEREQ *OCSP_request_onereq_get0(OCSP_REQUEST *req, int i); | ||
460 | OCSP_CERTID *OCSP_onereq_get0_id(OCSP_ONEREQ *one); | ||
461 | int OCSP_id_get0_info(ASN1_OCTET_STRING **piNameHash, ASN1_OBJECT **pmd, | ||
462 | ASN1_OCTET_STRING **pikeyHash, | ||
463 | ASN1_INTEGER **pserial, OCSP_CERTID *cid); | ||
464 | int OCSP_request_is_signed(OCSP_REQUEST *req); | ||
465 | OCSP_RESPONSE *OCSP_response_create(int status, OCSP_BASICRESP *bs); | ||
466 | OCSP_SINGLERESP *OCSP_basic_add1_status(OCSP_BASICRESP *rsp, | ||
467 | OCSP_CERTID *cid, | ||
468 | int status, int reason, | ||
469 | ASN1_TIME *revtime, | ||
470 | ASN1_TIME *thisupd, ASN1_TIME *nextupd); | ||
471 | int OCSP_basic_add1_cert(OCSP_BASICRESP *resp, X509 *cert); | ||
472 | int OCSP_basic_sign(OCSP_BASICRESP *brsp, | ||
473 | X509 *signer, EVP_PKEY *key, const EVP_MD *dgst, | ||
474 | STACK_OF(X509) *certs, unsigned long flags); | ||
475 | |||
476 | ASN1_STRING *ASN1_STRING_encode(ASN1_STRING *s, int (*i2d)(), | ||
477 | char *data, STACK_OF(ASN1_OBJECT) *sk); | ||
478 | |||
479 | X509_EXTENSION *OCSP_crlID_new(char *url, long *n, char *tim); | ||
480 | |||
481 | X509_EXTENSION *OCSP_accept_responses_new(char **oids); | ||
482 | |||
483 | X509_EXTENSION *OCSP_archive_cutoff_new(char* tim); | ||
484 | |||
485 | X509_EXTENSION *OCSP_url_svcloc_new(X509_NAME* issuer, char **urls); | ||
486 | |||
487 | int OCSP_REQUEST_get_ext_count(OCSP_REQUEST *x); | ||
488 | int OCSP_REQUEST_get_ext_by_NID(OCSP_REQUEST *x, int nid, int lastpos); | ||
489 | int OCSP_REQUEST_get_ext_by_OBJ(OCSP_REQUEST *x, ASN1_OBJECT *obj, int lastpos); | ||
490 | int OCSP_REQUEST_get_ext_by_critical(OCSP_REQUEST *x, int crit, int lastpos); | ||
491 | X509_EXTENSION *OCSP_REQUEST_get_ext(OCSP_REQUEST *x, int loc); | ||
492 | X509_EXTENSION *OCSP_REQUEST_delete_ext(OCSP_REQUEST *x, int loc); | ||
493 | void *OCSP_REQUEST_get1_ext_d2i(OCSP_REQUEST *x, int nid, int *crit, int *idx); | ||
494 | int OCSP_REQUEST_add1_ext_i2d(OCSP_REQUEST *x, int nid, void *value, int crit, | ||
495 | unsigned long flags); | ||
496 | int OCSP_REQUEST_add_ext(OCSP_REQUEST *x, X509_EXTENSION *ex, int loc); | ||
497 | |||
498 | int OCSP_ONEREQ_get_ext_count(OCSP_ONEREQ *x); | ||
499 | int OCSP_ONEREQ_get_ext_by_NID(OCSP_ONEREQ *x, int nid, int lastpos); | ||
500 | int OCSP_ONEREQ_get_ext_by_OBJ(OCSP_ONEREQ *x, ASN1_OBJECT *obj, int lastpos); | ||
501 | int OCSP_ONEREQ_get_ext_by_critical(OCSP_ONEREQ *x, int crit, int lastpos); | ||
502 | X509_EXTENSION *OCSP_ONEREQ_get_ext(OCSP_ONEREQ *x, int loc); | ||
503 | X509_EXTENSION *OCSP_ONEREQ_delete_ext(OCSP_ONEREQ *x, int loc); | ||
504 | void *OCSP_ONEREQ_get1_ext_d2i(OCSP_ONEREQ *x, int nid, int *crit, int *idx); | ||
505 | int OCSP_ONEREQ_add1_ext_i2d(OCSP_ONEREQ *x, int nid, void *value, int crit, | ||
506 | unsigned long flags); | ||
507 | int OCSP_ONEREQ_add_ext(OCSP_ONEREQ *x, X509_EXTENSION *ex, int loc); | ||
508 | |||
509 | int OCSP_BASICRESP_get_ext_count(OCSP_BASICRESP *x); | ||
510 | int OCSP_BASICRESP_get_ext_by_NID(OCSP_BASICRESP *x, int nid, int lastpos); | ||
511 | int OCSP_BASICRESP_get_ext_by_OBJ(OCSP_BASICRESP *x, ASN1_OBJECT *obj, int lastpos); | ||
512 | int OCSP_BASICRESP_get_ext_by_critical(OCSP_BASICRESP *x, int crit, int lastpos); | ||
513 | X509_EXTENSION *OCSP_BASICRESP_get_ext(OCSP_BASICRESP *x, int loc); | ||
514 | X509_EXTENSION *OCSP_BASICRESP_delete_ext(OCSP_BASICRESP *x, int loc); | ||
515 | void *OCSP_BASICRESP_get1_ext_d2i(OCSP_BASICRESP *x, int nid, int *crit, int *idx); | ||
516 | int OCSP_BASICRESP_add1_ext_i2d(OCSP_BASICRESP *x, int nid, void *value, int crit, | ||
517 | unsigned long flags); | ||
518 | int OCSP_BASICRESP_add_ext(OCSP_BASICRESP *x, X509_EXTENSION *ex, int loc); | ||
519 | |||
520 | int OCSP_SINGLERESP_get_ext_count(OCSP_SINGLERESP *x); | ||
521 | int OCSP_SINGLERESP_get_ext_by_NID(OCSP_SINGLERESP *x, int nid, int lastpos); | ||
522 | int OCSP_SINGLERESP_get_ext_by_OBJ(OCSP_SINGLERESP *x, ASN1_OBJECT *obj, int lastpos); | ||
523 | int OCSP_SINGLERESP_get_ext_by_critical(OCSP_SINGLERESP *x, int crit, int lastpos); | ||
524 | X509_EXTENSION *OCSP_SINGLERESP_get_ext(OCSP_SINGLERESP *x, int loc); | ||
525 | X509_EXTENSION *OCSP_SINGLERESP_delete_ext(OCSP_SINGLERESP *x, int loc); | ||
526 | void *OCSP_SINGLERESP_get1_ext_d2i(OCSP_SINGLERESP *x, int nid, int *crit, int *idx); | ||
527 | int OCSP_SINGLERESP_add1_ext_i2d(OCSP_SINGLERESP *x, int nid, void *value, int crit, | ||
528 | unsigned long flags); | ||
529 | int OCSP_SINGLERESP_add_ext(OCSP_SINGLERESP *x, X509_EXTENSION *ex, int loc); | ||
530 | |||
531 | DECLARE_ASN1_FUNCTIONS(OCSP_SINGLERESP) | ||
532 | DECLARE_ASN1_FUNCTIONS(OCSP_CERTSTATUS) | ||
533 | DECLARE_ASN1_FUNCTIONS(OCSP_REVOKEDINFO) | ||
534 | DECLARE_ASN1_FUNCTIONS(OCSP_BASICRESP) | ||
535 | DECLARE_ASN1_FUNCTIONS(OCSP_RESPDATA) | ||
536 | DECLARE_ASN1_FUNCTIONS(OCSP_RESPID) | ||
537 | DECLARE_ASN1_FUNCTIONS(OCSP_RESPONSE) | ||
538 | DECLARE_ASN1_FUNCTIONS(OCSP_RESPBYTES) | ||
539 | DECLARE_ASN1_FUNCTIONS(OCSP_ONEREQ) | ||
540 | DECLARE_ASN1_FUNCTIONS(OCSP_CERTID) | ||
541 | DECLARE_ASN1_FUNCTIONS(OCSP_REQUEST) | ||
542 | DECLARE_ASN1_FUNCTIONS(OCSP_SIGNATURE) | ||
543 | DECLARE_ASN1_FUNCTIONS(OCSP_REQINFO) | ||
544 | DECLARE_ASN1_FUNCTIONS(OCSP_CRLID) | ||
545 | DECLARE_ASN1_FUNCTIONS(OCSP_SERVICELOC) | ||
546 | |||
547 | char *OCSP_response_status_str(long s); | ||
548 | char *OCSP_cert_status_str(long s); | ||
549 | char *OCSP_crl_reason_str(long s); | ||
550 | |||
551 | int OCSP_REQUEST_print(BIO *bp, OCSP_REQUEST* a, unsigned long flags); | ||
552 | int OCSP_RESPONSE_print(BIO *bp, OCSP_RESPONSE* o, unsigned long flags); | ||
553 | |||
554 | int OCSP_basic_verify(OCSP_BASICRESP *bs, STACK_OF(X509) *certs, | ||
555 | X509_STORE *st, unsigned long flags); | ||
556 | |||
557 | /* BEGIN ERROR CODES */ | ||
558 | /* The following lines are auto generated by the script mkerr.pl. Any changes | ||
559 | * made after this point may be overwritten when the script is next run. | ||
560 | */ | ||
561 | void ERR_load_OCSP_strings(void); | ||
562 | |||
563 | /* Error codes for the OCSP functions. */ | ||
564 | |||
565 | /* Function codes. */ | ||
566 | #define OCSP_F_ASN1_STRING_ENCODE 100 | ||
567 | #define OCSP_F_CERT_ID_NEW 101 | ||
568 | #define OCSP_F_D2I_OCSP_NONCE 102 | ||
569 | #define OCSP_F_OCSP_BASIC_ADD1_STATUS 103 | ||
570 | #define OCSP_F_OCSP_BASIC_SIGN 104 | ||
571 | #define OCSP_F_OCSP_BASIC_VERIFY 105 | ||
572 | #define OCSP_F_OCSP_CHECK_DELEGATED 106 | ||
573 | #define OCSP_F_OCSP_CHECK_IDS 107 | ||
574 | #define OCSP_F_OCSP_CHECK_ISSUER 108 | ||
575 | #define OCSP_F_OCSP_CHECK_VALIDITY 115 | ||
576 | #define OCSP_F_OCSP_MATCH_ISSUERID 109 | ||
577 | #define OCSP_F_OCSP_PARSE_URL 114 | ||
578 | #define OCSP_F_OCSP_REQUEST_SIGN 110 | ||
579 | #define OCSP_F_OCSP_REQUEST_VERIFY 116 | ||
580 | #define OCSP_F_OCSP_RESPONSE_GET1_BASIC 111 | ||
581 | #define OCSP_F_OCSP_SENDREQ_BIO 112 | ||
582 | #define OCSP_F_REQUEST_VERIFY 113 | ||
583 | |||
584 | /* Reason codes. */ | ||
585 | #define OCSP_R_BAD_DATA 100 | ||
586 | #define OCSP_R_CERTIFICATE_VERIFY_ERROR 101 | ||
587 | #define OCSP_R_DIGEST_ERR 102 | ||
588 | #define OCSP_R_ERROR_IN_NEXTUPDATE_FIELD 122 | ||
589 | #define OCSP_R_ERROR_IN_THISUPDATE_FIELD 123 | ||
590 | #define OCSP_R_ERROR_PARSING_URL 121 | ||
591 | #define OCSP_R_MISSING_OCSPSIGNING_USAGE 103 | ||
592 | #define OCSP_R_NEXTUPDATE_BEFORE_THISUPDATE 124 | ||
593 | #define OCSP_R_NOT_BASIC_RESPONSE 104 | ||
594 | #define OCSP_R_NO_CERTIFICATES_IN_CHAIN 105 | ||
595 | #define OCSP_R_NO_CONTENT 106 | ||
596 | #define OCSP_R_NO_PUBLIC_KEY 107 | ||
597 | #define OCSP_R_NO_RESPONSE_DATA 108 | ||
598 | #define OCSP_R_NO_REVOKED_TIME 109 | ||
599 | #define OCSP_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE 110 | ||
600 | #define OCSP_R_REQUEST_NOT_SIGNED 128 | ||
601 | #define OCSP_R_RESPONSE_CONTAINS_NO_REVOCATION_DATA 111 | ||
602 | #define OCSP_R_ROOT_CA_NOT_TRUSTED 112 | ||
603 | #define OCSP_R_SERVER_READ_ERROR 113 | ||
604 | #define OCSP_R_SERVER_RESPONSE_ERROR 114 | ||
605 | #define OCSP_R_SERVER_RESPONSE_PARSE_ERROR 115 | ||
606 | #define OCSP_R_SERVER_WRITE_ERROR 116 | ||
607 | #define OCSP_R_SIGNATURE_FAILURE 117 | ||
608 | #define OCSP_R_SIGNER_CERTIFICATE_NOT_FOUND 118 | ||
609 | #define OCSP_R_STATUS_EXPIRED 125 | ||
610 | #define OCSP_R_STATUS_NOT_YET_VALID 126 | ||
611 | #define OCSP_R_STATUS_TOO_OLD 127 | ||
612 | #define OCSP_R_UNKNOWN_MESSAGE_DIGEST 119 | ||
613 | #define OCSP_R_UNKNOWN_NID 120 | ||
614 | #define OCSP_R_UNSUPPORTED_REQUESTORNAME_TYPE 129 | ||
615 | |||
616 | #ifdef __cplusplus | ||
617 | } | ||
618 | #endif | ||
619 | #endif | ||
diff --git a/src/lib/libcrypto/ocsp/ocsp_asn.c b/src/lib/libcrypto/ocsp/ocsp_asn.c new file mode 100644 index 0000000000..8c148cda6a --- /dev/null +++ b/src/lib/libcrypto/ocsp/ocsp_asn.c | |||
@@ -0,0 +1,182 @@ | |||
1 | /* ocsp_asn.c */ | ||
2 | /* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL | ||
3 | * project 2000. | ||
4 | */ | ||
5 | /* ==================================================================== | ||
6 | * Copyright (c) 2000 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 | #include <openssl/asn1.h> | ||
59 | #include <openssl/asn1t.h> | ||
60 | #include <openssl/ocsp.h> | ||
61 | |||
62 | ASN1_SEQUENCE(OCSP_SIGNATURE) = { | ||
63 | ASN1_SIMPLE(OCSP_SIGNATURE, signatureAlgorithm, X509_ALGOR), | ||
64 | ASN1_SIMPLE(OCSP_SIGNATURE, signature, ASN1_BIT_STRING), | ||
65 | ASN1_EXP_SEQUENCE_OF(OCSP_SIGNATURE, certs, X509, 0) | ||
66 | } ASN1_SEQUENCE_END(OCSP_SIGNATURE) | ||
67 | |||
68 | IMPLEMENT_ASN1_FUNCTIONS(OCSP_SIGNATURE) | ||
69 | |||
70 | ASN1_SEQUENCE(OCSP_CERTID) = { | ||
71 | ASN1_SIMPLE(OCSP_CERTID, hashAlgorithm, X509_ALGOR), | ||
72 | ASN1_SIMPLE(OCSP_CERTID, issuerNameHash, ASN1_OCTET_STRING), | ||
73 | ASN1_SIMPLE(OCSP_CERTID, issuerKeyHash, ASN1_OCTET_STRING), | ||
74 | ASN1_SIMPLE(OCSP_CERTID, serialNumber, ASN1_INTEGER) | ||
75 | } ASN1_SEQUENCE_END(OCSP_CERTID) | ||
76 | |||
77 | IMPLEMENT_ASN1_FUNCTIONS(OCSP_CERTID) | ||
78 | |||
79 | ASN1_SEQUENCE(OCSP_ONEREQ) = { | ||
80 | ASN1_SIMPLE(OCSP_ONEREQ, reqCert, OCSP_CERTID), | ||
81 | ASN1_EXP_SEQUENCE_OF_OPT(OCSP_ONEREQ, singleRequestExtensions, X509_EXTENSION, 0) | ||
82 | } ASN1_SEQUENCE_END(OCSP_ONEREQ) | ||
83 | |||
84 | IMPLEMENT_ASN1_FUNCTIONS(OCSP_ONEREQ) | ||
85 | |||
86 | ASN1_SEQUENCE(OCSP_REQINFO) = { | ||
87 | ASN1_EXP_OPT(OCSP_REQINFO, version, ASN1_INTEGER, 0), | ||
88 | ASN1_EXP_OPT(OCSP_REQINFO, requestorName, GENERAL_NAME, 1), | ||
89 | ASN1_SEQUENCE_OF(OCSP_REQINFO, requestList, OCSP_ONEREQ), | ||
90 | ASN1_EXP_SEQUENCE_OF_OPT(OCSP_REQINFO, requestExtensions, X509_EXTENSION, 2) | ||
91 | } ASN1_SEQUENCE_END(OCSP_REQINFO) | ||
92 | |||
93 | IMPLEMENT_ASN1_FUNCTIONS(OCSP_REQINFO) | ||
94 | |||
95 | ASN1_SEQUENCE(OCSP_REQUEST) = { | ||
96 | ASN1_SIMPLE(OCSP_REQUEST, tbsRequest, OCSP_REQINFO), | ||
97 | ASN1_EXP_OPT(OCSP_REQUEST, optionalSignature, OCSP_SIGNATURE, 0) | ||
98 | } ASN1_SEQUENCE_END(OCSP_REQUEST) | ||
99 | |||
100 | IMPLEMENT_ASN1_FUNCTIONS(OCSP_REQUEST) | ||
101 | |||
102 | /* OCSP_RESPONSE templates */ | ||
103 | |||
104 | ASN1_SEQUENCE(OCSP_RESPBYTES) = { | ||
105 | ASN1_SIMPLE(OCSP_RESPBYTES, responseType, ASN1_OBJECT), | ||
106 | ASN1_SIMPLE(OCSP_RESPBYTES, response, ASN1_OCTET_STRING) | ||
107 | } ASN1_SEQUENCE_END(OCSP_RESPBYTES) | ||
108 | |||
109 | IMPLEMENT_ASN1_FUNCTIONS(OCSP_RESPBYTES) | ||
110 | |||
111 | ASN1_SEQUENCE(OCSP_RESPONSE) = { | ||
112 | ASN1_SIMPLE(OCSP_RESPONSE, responseStatus, ASN1_ENUMERATED), | ||
113 | ASN1_EXP_OPT(OCSP_RESPONSE, responseBytes, OCSP_RESPBYTES, 0) | ||
114 | } ASN1_SEQUENCE_END(OCSP_RESPONSE) | ||
115 | |||
116 | IMPLEMENT_ASN1_FUNCTIONS(OCSP_RESPONSE) | ||
117 | |||
118 | ASN1_CHOICE(OCSP_RESPID) = { | ||
119 | ASN1_EXP(OCSP_RESPID, value.byName, X509_NAME, 1), | ||
120 | ASN1_IMP(OCSP_RESPID, value.byKey, ASN1_OCTET_STRING, 2) | ||
121 | } ASN1_CHOICE_END(OCSP_RESPID) | ||
122 | |||
123 | IMPLEMENT_ASN1_FUNCTIONS(OCSP_RESPID) | ||
124 | |||
125 | ASN1_SEQUENCE(OCSP_REVOKEDINFO) = { | ||
126 | ASN1_SIMPLE(OCSP_REVOKEDINFO, revocationTime, ASN1_GENERALIZEDTIME), | ||
127 | ASN1_EXP_OPT(OCSP_REVOKEDINFO, revocationReason, ASN1_ENUMERATED, 0) | ||
128 | } ASN1_SEQUENCE_END(OCSP_REVOKEDINFO) | ||
129 | |||
130 | IMPLEMENT_ASN1_FUNCTIONS(OCSP_REVOKEDINFO) | ||
131 | |||
132 | ASN1_CHOICE(OCSP_CERTSTATUS) = { | ||
133 | ASN1_IMP(OCSP_CERTSTATUS, value.good, ASN1_NULL, 0), | ||
134 | ASN1_IMP(OCSP_CERTSTATUS, value.revoked, OCSP_REVOKEDINFO, 1), | ||
135 | ASN1_IMP(OCSP_CERTSTATUS, value.unknown, ASN1_NULL, 2) | ||
136 | } ASN1_CHOICE_END(OCSP_CERTSTATUS) | ||
137 | |||
138 | IMPLEMENT_ASN1_FUNCTIONS(OCSP_CERTSTATUS) | ||
139 | |||
140 | ASN1_SEQUENCE(OCSP_SINGLERESP) = { | ||
141 | ASN1_SIMPLE(OCSP_SINGLERESP, certId, OCSP_CERTID), | ||
142 | ASN1_SIMPLE(OCSP_SINGLERESP, certStatus, OCSP_CERTSTATUS), | ||
143 | ASN1_SIMPLE(OCSP_SINGLERESP, thisUpdate, ASN1_GENERALIZEDTIME), | ||
144 | ASN1_EXP_OPT(OCSP_SINGLERESP, nextUpdate, ASN1_GENERALIZEDTIME, 0), | ||
145 | ASN1_EXP_SEQUENCE_OF_OPT(OCSP_SINGLERESP, singleExtensions, X509_EXTENSION, 1) | ||
146 | } ASN1_SEQUENCE_END(OCSP_SINGLERESP) | ||
147 | |||
148 | IMPLEMENT_ASN1_FUNCTIONS(OCSP_SINGLERESP) | ||
149 | |||
150 | ASN1_SEQUENCE(OCSP_RESPDATA) = { | ||
151 | ASN1_EXP_OPT(OCSP_RESPDATA, version, ASN1_INTEGER, 0), | ||
152 | ASN1_SIMPLE(OCSP_RESPDATA, responderId, OCSP_RESPID), | ||
153 | ASN1_SIMPLE(OCSP_RESPDATA, producedAt, ASN1_GENERALIZEDTIME), | ||
154 | ASN1_SEQUENCE_OF(OCSP_RESPDATA, responses, OCSP_SINGLERESP), | ||
155 | ASN1_EXP_SEQUENCE_OF_OPT(OCSP_RESPDATA, responseExtensions, X509_EXTENSION, 1) | ||
156 | } ASN1_SEQUENCE_END(OCSP_RESPDATA) | ||
157 | |||
158 | IMPLEMENT_ASN1_FUNCTIONS(OCSP_RESPDATA) | ||
159 | |||
160 | ASN1_SEQUENCE(OCSP_BASICRESP) = { | ||
161 | ASN1_SIMPLE(OCSP_BASICRESP, tbsResponseData, OCSP_RESPDATA), | ||
162 | ASN1_SIMPLE(OCSP_BASICRESP, signatureAlgorithm, X509_ALGOR), | ||
163 | ASN1_SIMPLE(OCSP_BASICRESP, signature, ASN1_BIT_STRING), | ||
164 | ASN1_EXP_SEQUENCE_OF_OPT(OCSP_BASICRESP, certs, X509, 0) | ||
165 | } ASN1_SEQUENCE_END(OCSP_BASICRESP) | ||
166 | |||
167 | IMPLEMENT_ASN1_FUNCTIONS(OCSP_BASICRESP) | ||
168 | |||
169 | ASN1_SEQUENCE(OCSP_CRLID) = { | ||
170 | ASN1_EXP_OPT(OCSP_CRLID, crlUrl, ASN1_IA5STRING, 0), | ||
171 | ASN1_EXP_OPT(OCSP_CRLID, crlNum, ASN1_INTEGER, 1), | ||
172 | ASN1_EXP_OPT(OCSP_CRLID, crlTime, ASN1_GENERALIZEDTIME, 2) | ||
173 | } ASN1_SEQUENCE_END(OCSP_CRLID) | ||
174 | |||
175 | IMPLEMENT_ASN1_FUNCTIONS(OCSP_CRLID) | ||
176 | |||
177 | ASN1_SEQUENCE(OCSP_SERVICELOC) = { | ||
178 | ASN1_SIMPLE(OCSP_SERVICELOC, issuer, X509_NAME), | ||
179 | ASN1_SEQUENCE_OF_OPT(OCSP_SERVICELOC, locator, ACCESS_DESCRIPTION) | ||
180 | } ASN1_SEQUENCE_END(OCSP_SERVICELOC) | ||
181 | |||
182 | IMPLEMENT_ASN1_FUNCTIONS(OCSP_SERVICELOC) | ||
diff --git a/src/lib/libcrypto/ocsp/ocsp_cl.c b/src/lib/libcrypto/ocsp/ocsp_cl.c new file mode 100644 index 0000000000..9b3e6dd8ca --- /dev/null +++ b/src/lib/libcrypto/ocsp/ocsp_cl.c | |||
@@ -0,0 +1,370 @@ | |||
1 | /* ocsp_cl.c */ | ||
2 | /* Written by Tom Titchener <Tom_Titchener@groove.net> for the OpenSSL | ||
3 | * project. */ | ||
4 | |||
5 | /* History: | ||
6 | This file was transfered to Richard Levitte from CertCo by Kathy | ||
7 | Weinhold in mid-spring 2000 to be included in OpenSSL or released | ||
8 | as a patch kit. */ | ||
9 | |||
10 | /* ==================================================================== | ||
11 | * Copyright (c) 1998-2000 The OpenSSL Project. All rights reserved. | ||
12 | * | ||
13 | * Redistribution and use in source and binary forms, with or without | ||
14 | * modification, are permitted provided that the following conditions | ||
15 | * are met: | ||
16 | * | ||
17 | * 1. Redistributions of source code must retain the above copyright | ||
18 | * notice, this list of conditions and the following disclaimer. | ||
19 | * | ||
20 | * 2. Redistributions in binary form must reproduce the above copyright | ||
21 | * notice, this list of conditions and the following disclaimer in | ||
22 | * the documentation and/or other materials provided with the | ||
23 | * distribution. | ||
24 | * | ||
25 | * 3. All advertising materials mentioning features or use of this | ||
26 | * software must display the following acknowledgment: | ||
27 | * "This product includes software developed by the OpenSSL Project | ||
28 | * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" | ||
29 | * | ||
30 | * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to | ||
31 | * endorse or promote products derived from this software without | ||
32 | * prior written permission. For written permission, please contact | ||
33 | * openssl-core@openssl.org. | ||
34 | * | ||
35 | * 5. Products derived from this software may not be called "OpenSSL" | ||
36 | * nor may "OpenSSL" appear in their names without prior written | ||
37 | * permission of the OpenSSL Project. | ||
38 | * | ||
39 | * 6. Redistributions of any form whatsoever must retain the following | ||
40 | * acknowledgment: | ||
41 | * "This product includes software developed by the OpenSSL Project | ||
42 | * for use in the OpenSSL Toolkit (http://www.openssl.org/)" | ||
43 | * | ||
44 | * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY | ||
45 | * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
46 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | ||
47 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR | ||
48 | * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
49 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
50 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
51 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
52 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
53 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
54 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED | ||
55 | * OF THE POSSIBILITY OF SUCH DAMAGE. | ||
56 | * ==================================================================== | ||
57 | * | ||
58 | * This product includes cryptographic software written by Eric Young | ||
59 | * (eay@cryptsoft.com). This product includes software written by Tim | ||
60 | * Hudson (tjh@cryptsoft.com). | ||
61 | * | ||
62 | */ | ||
63 | |||
64 | #include <stdio.h> | ||
65 | #include <time.h> | ||
66 | #include <cryptlib.h> | ||
67 | #include <openssl/objects.h> | ||
68 | #include <openssl/rand.h> | ||
69 | #include <openssl/x509.h> | ||
70 | #include <openssl/pem.h> | ||
71 | #include <openssl/x509v3.h> | ||
72 | #include <openssl/ocsp.h> | ||
73 | |||
74 | /* Utility functions related to sending OCSP requests and extracting | ||
75 | * relevant information from the response. | ||
76 | */ | ||
77 | |||
78 | /* Add an OCSP_CERTID to an OCSP request. Return new OCSP_ONEREQ | ||
79 | * pointer: useful if we want to add extensions. | ||
80 | */ | ||
81 | |||
82 | OCSP_ONEREQ *OCSP_request_add0_id(OCSP_REQUEST *req, OCSP_CERTID *cid) | ||
83 | { | ||
84 | OCSP_ONEREQ *one = NULL; | ||
85 | |||
86 | if (!(one = OCSP_ONEREQ_new())) goto err; | ||
87 | if (one->reqCert) OCSP_CERTID_free(one->reqCert); | ||
88 | one->reqCert = cid; | ||
89 | if (req && | ||
90 | !sk_OCSP_ONEREQ_push(req->tbsRequest->requestList, one)) | ||
91 | goto err; | ||
92 | return one; | ||
93 | err: | ||
94 | OCSP_ONEREQ_free(one); | ||
95 | return NULL; | ||
96 | } | ||
97 | |||
98 | /* Set requestorName from an X509_NAME structure */ | ||
99 | |||
100 | int OCSP_request_set1_name(OCSP_REQUEST *req, X509_NAME *nm) | ||
101 | { | ||
102 | GENERAL_NAME *gen; | ||
103 | gen = GENERAL_NAME_new(); | ||
104 | if (!X509_NAME_set(&gen->d.directoryName, nm)) | ||
105 | { | ||
106 | GENERAL_NAME_free(gen); | ||
107 | return 0; | ||
108 | } | ||
109 | gen->type = GEN_DIRNAME; | ||
110 | if (req->tbsRequest->requestorName) | ||
111 | GENERAL_NAME_free(req->tbsRequest->requestorName); | ||
112 | req->tbsRequest->requestorName = gen; | ||
113 | return 1; | ||
114 | } | ||
115 | |||
116 | |||
117 | /* Add a certificate to an OCSP request */ | ||
118 | |||
119 | int OCSP_request_add1_cert(OCSP_REQUEST *req, X509 *cert) | ||
120 | { | ||
121 | OCSP_SIGNATURE *sig; | ||
122 | if (!req->optionalSignature) | ||
123 | req->optionalSignature = OCSP_SIGNATURE_new(); | ||
124 | sig = req->optionalSignature; | ||
125 | if (!sig) return 0; | ||
126 | if (!cert) return 1; | ||
127 | if (!sig->certs && !(sig->certs = sk_X509_new_null())) | ||
128 | return 0; | ||
129 | |||
130 | if(!sk_X509_push(sig->certs, cert)) return 0; | ||
131 | CRYPTO_add(&cert->references, 1, CRYPTO_LOCK_X509); | ||
132 | return 1; | ||
133 | } | ||
134 | |||
135 | /* Sign an OCSP request set the requestorName to the subjec | ||
136 | * name of an optional signers certificate and include one | ||
137 | * or more optional certificates in the request. Behaves | ||
138 | * like PKCS7_sign(). | ||
139 | */ | ||
140 | |||
141 | int OCSP_request_sign(OCSP_REQUEST *req, | ||
142 | X509 *signer, | ||
143 | EVP_PKEY *key, | ||
144 | const EVP_MD *dgst, | ||
145 | STACK_OF(X509) *certs, | ||
146 | unsigned long flags) | ||
147 | { | ||
148 | int i; | ||
149 | OCSP_SIGNATURE *sig; | ||
150 | X509 *x; | ||
151 | |||
152 | if (!OCSP_request_set1_name(req, X509_get_subject_name(signer))) | ||
153 | goto err; | ||
154 | |||
155 | if (!(req->optionalSignature = sig = OCSP_SIGNATURE_new())) goto err; | ||
156 | if (!dgst) dgst = EVP_sha1(); | ||
157 | if (key) | ||
158 | { | ||
159 | if (!X509_check_private_key(signer, key)) | ||
160 | { | ||
161 | OCSPerr(OCSP_F_OCSP_REQUEST_SIGN, OCSP_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE); | ||
162 | goto err; | ||
163 | } | ||
164 | if (!OCSP_REQUEST_sign(req, key, dgst)) goto err; | ||
165 | } | ||
166 | |||
167 | if (!(flags & OCSP_NOCERTS)) | ||
168 | { | ||
169 | if(!OCSP_request_add1_cert(req, signer)) goto err; | ||
170 | for (i = 0; i < sk_X509_num(certs); i++) | ||
171 | { | ||
172 | x = sk_X509_value(certs, i); | ||
173 | if (!OCSP_request_add1_cert(req, x)) goto err; | ||
174 | } | ||
175 | } | ||
176 | |||
177 | return 1; | ||
178 | err: | ||
179 | OCSP_SIGNATURE_free(req->optionalSignature); | ||
180 | req->optionalSignature = NULL; | ||
181 | return 0; | ||
182 | } | ||
183 | |||
184 | /* Get response status */ | ||
185 | |||
186 | int OCSP_response_status(OCSP_RESPONSE *resp) | ||
187 | { | ||
188 | return ASN1_ENUMERATED_get(resp->responseStatus); | ||
189 | } | ||
190 | |||
191 | /* Extract basic response from OCSP_RESPONSE or NULL if | ||
192 | * no basic response present. | ||
193 | */ | ||
194 | |||
195 | |||
196 | OCSP_BASICRESP *OCSP_response_get1_basic(OCSP_RESPONSE *resp) | ||
197 | { | ||
198 | OCSP_RESPBYTES *rb; | ||
199 | rb = resp->responseBytes; | ||
200 | if (!rb) | ||
201 | { | ||
202 | OCSPerr(OCSP_F_OCSP_RESPONSE_GET1_BASIC, OCSP_R_NO_RESPONSE_DATA); | ||
203 | return NULL; | ||
204 | } | ||
205 | if (OBJ_obj2nid(rb->responseType) != NID_id_pkix_OCSP_basic) | ||
206 | { | ||
207 | OCSPerr(OCSP_F_OCSP_RESPONSE_GET1_BASIC, OCSP_R_NOT_BASIC_RESPONSE); | ||
208 | return NULL; | ||
209 | } | ||
210 | |||
211 | return ASN1_item_unpack(rb->response, ASN1_ITEM_rptr(OCSP_BASICRESP)); | ||
212 | } | ||
213 | |||
214 | /* Return number of OCSP_SINGLERESP reponses present in | ||
215 | * a basic response. | ||
216 | */ | ||
217 | |||
218 | int OCSP_resp_count(OCSP_BASICRESP *bs) | ||
219 | { | ||
220 | if (!bs) return -1; | ||
221 | return sk_OCSP_SINGLERESP_num(bs->tbsResponseData->responses); | ||
222 | } | ||
223 | |||
224 | /* Extract an OCSP_SINGLERESP response with a given index */ | ||
225 | |||
226 | OCSP_SINGLERESP *OCSP_resp_get0(OCSP_BASICRESP *bs, int idx) | ||
227 | { | ||
228 | if (!bs) return NULL; | ||
229 | return sk_OCSP_SINGLERESP_value(bs->tbsResponseData->responses, idx); | ||
230 | } | ||
231 | |||
232 | /* Look single response matching a given certificate ID */ | ||
233 | |||
234 | int OCSP_resp_find(OCSP_BASICRESP *bs, OCSP_CERTID *id, int last) | ||
235 | { | ||
236 | int i; | ||
237 | STACK_OF(OCSP_SINGLERESP) *sresp; | ||
238 | OCSP_SINGLERESP *single; | ||
239 | if (!bs) return -1; | ||
240 | if (last < 0) last = 0; | ||
241 | else last++; | ||
242 | sresp = bs->tbsResponseData->responses; | ||
243 | for (i = last; i < sk_OCSP_SINGLERESP_num(sresp); i++) | ||
244 | { | ||
245 | single = sk_OCSP_SINGLERESP_value(sresp, i); | ||
246 | if (!OCSP_id_cmp(id, single->certId)) return i; | ||
247 | } | ||
248 | return -1; | ||
249 | } | ||
250 | |||
251 | /* Extract status information from an OCSP_SINGLERESP structure. | ||
252 | * Note: the revtime and reason values are only set if the | ||
253 | * certificate status is revoked. Returns numerical value of | ||
254 | * status. | ||
255 | */ | ||
256 | |||
257 | int OCSP_single_get0_status(OCSP_SINGLERESP *single, int *reason, | ||
258 | ASN1_GENERALIZEDTIME **revtime, | ||
259 | ASN1_GENERALIZEDTIME **thisupd, | ||
260 | ASN1_GENERALIZEDTIME **nextupd) | ||
261 | { | ||
262 | int ret; | ||
263 | OCSP_CERTSTATUS *cst; | ||
264 | if(!single) return -1; | ||
265 | cst = single->certStatus; | ||
266 | ret = cst->type; | ||
267 | if (ret == V_OCSP_CERTSTATUS_REVOKED) | ||
268 | { | ||
269 | OCSP_REVOKEDINFO *rev = cst->value.revoked; | ||
270 | if (revtime) *revtime = rev->revocationTime; | ||
271 | if (reason) | ||
272 | { | ||
273 | if(rev->revocationReason) | ||
274 | *reason = ASN1_ENUMERATED_get(rev->revocationReason); | ||
275 | else *reason = -1; | ||
276 | } | ||
277 | } | ||
278 | if(thisupd) *thisupd = single->thisUpdate; | ||
279 | if(nextupd) *nextupd = single->nextUpdate; | ||
280 | return ret; | ||
281 | } | ||
282 | |||
283 | /* This function combines the previous ones: look up a certificate ID and | ||
284 | * if found extract status information. Return 0 is successful. | ||
285 | */ | ||
286 | |||
287 | int OCSP_resp_find_status(OCSP_BASICRESP *bs, OCSP_CERTID *id, int *status, | ||
288 | int *reason, | ||
289 | ASN1_GENERALIZEDTIME **revtime, | ||
290 | ASN1_GENERALIZEDTIME **thisupd, | ||
291 | ASN1_GENERALIZEDTIME **nextupd) | ||
292 | { | ||
293 | int i; | ||
294 | OCSP_SINGLERESP *single; | ||
295 | i = OCSP_resp_find(bs, id, -1); | ||
296 | /* Maybe check for multiple responses and give an error? */ | ||
297 | if(i < 0) return 0; | ||
298 | single = OCSP_resp_get0(bs, i); | ||
299 | i = OCSP_single_get0_status(single, reason, revtime, thisupd, nextupd); | ||
300 | if(status) *status = i; | ||
301 | return 1; | ||
302 | } | ||
303 | |||
304 | /* Check validity of thisUpdate and nextUpdate fields. It is possible that the request will | ||
305 | * take a few seconds to process and/or the time wont be totally accurate. Therefore to avoid | ||
306 | * rejecting otherwise valid time we allow the times to be within 'nsec' of the current time. | ||
307 | * Also to avoid accepting very old responses without a nextUpdate field an optional maxage | ||
308 | * parameter specifies the maximum age the thisUpdate field can be. | ||
309 | */ | ||
310 | |||
311 | int OCSP_check_validity(ASN1_GENERALIZEDTIME *thisupd, ASN1_GENERALIZEDTIME *nextupd, long nsec, long maxsec) | ||
312 | { | ||
313 | int ret = 1; | ||
314 | time_t t_now, t_tmp; | ||
315 | time(&t_now); | ||
316 | /* Check thisUpdate is valid and not more than nsec in the future */ | ||
317 | if (!ASN1_GENERALIZEDTIME_check(thisupd)) | ||
318 | { | ||
319 | OCSPerr(OCSP_F_OCSP_CHECK_VALIDITY, OCSP_R_ERROR_IN_THISUPDATE_FIELD); | ||
320 | ret = 0; | ||
321 | } | ||
322 | else | ||
323 | { | ||
324 | t_tmp = t_now + nsec; | ||
325 | if (X509_cmp_time(thisupd, &t_tmp) > 0) | ||
326 | { | ||
327 | OCSPerr(OCSP_F_OCSP_CHECK_VALIDITY, OCSP_R_STATUS_NOT_YET_VALID); | ||
328 | ret = 0; | ||
329 | } | ||
330 | |||
331 | /* If maxsec specified check thisUpdate is not more than maxsec in the past */ | ||
332 | if (maxsec >= 0) | ||
333 | { | ||
334 | t_tmp = t_now - maxsec; | ||
335 | if (X509_cmp_time(thisupd, &t_tmp) < 0) | ||
336 | { | ||
337 | OCSPerr(OCSP_F_OCSP_CHECK_VALIDITY, OCSP_R_STATUS_TOO_OLD); | ||
338 | ret = 0; | ||
339 | } | ||
340 | } | ||
341 | } | ||
342 | |||
343 | |||
344 | if (!nextupd) return ret; | ||
345 | |||
346 | /* Check nextUpdate is valid and not more than nsec in the past */ | ||
347 | if (!ASN1_GENERALIZEDTIME_check(nextupd)) | ||
348 | { | ||
349 | OCSPerr(OCSP_F_OCSP_CHECK_VALIDITY, OCSP_R_ERROR_IN_NEXTUPDATE_FIELD); | ||
350 | ret = 0; | ||
351 | } | ||
352 | else | ||
353 | { | ||
354 | t_tmp = t_now - nsec; | ||
355 | if (X509_cmp_time(nextupd, &t_tmp) < 0) | ||
356 | { | ||
357 | OCSPerr(OCSP_F_OCSP_CHECK_VALIDITY, OCSP_R_STATUS_EXPIRED); | ||
358 | ret = 0; | ||
359 | } | ||
360 | } | ||
361 | |||
362 | /* Also don't allow nextUpdate to precede thisUpdate */ | ||
363 | if (ASN1_STRING_cmp(nextupd, thisupd) < 0) | ||
364 | { | ||
365 | OCSPerr(OCSP_F_OCSP_CHECK_VALIDITY, OCSP_R_NEXTUPDATE_BEFORE_THISUPDATE); | ||
366 | ret = 0; | ||
367 | } | ||
368 | |||
369 | return ret; | ||
370 | } | ||
diff --git a/src/lib/libcrypto/ocsp/ocsp_err.c b/src/lib/libcrypto/ocsp/ocsp_err.c new file mode 100644 index 0000000000..4c4d8306f8 --- /dev/null +++ b/src/lib/libcrypto/ocsp/ocsp_err.c | |||
@@ -0,0 +1,139 @@ | |||
1 | /* crypto/ocsp/ocsp_err.c */ | ||
2 | /* ==================================================================== | ||
3 | * Copyright (c) 1999 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/ocsp.h> | ||
64 | |||
65 | /* BEGIN ERROR CODES */ | ||
66 | #ifndef OPENSSL_NO_ERR | ||
67 | static ERR_STRING_DATA OCSP_str_functs[]= | ||
68 | { | ||
69 | {ERR_PACK(0,OCSP_F_ASN1_STRING_ENCODE,0), "ASN1_STRING_encode"}, | ||
70 | {ERR_PACK(0,OCSP_F_CERT_ID_NEW,0), "CERT_ID_NEW"}, | ||
71 | {ERR_PACK(0,OCSP_F_D2I_OCSP_NONCE,0), "D2I_OCSP_NONCE"}, | ||
72 | {ERR_PACK(0,OCSP_F_OCSP_BASIC_ADD1_STATUS,0), "OCSP_basic_add1_status"}, | ||
73 | {ERR_PACK(0,OCSP_F_OCSP_BASIC_SIGN,0), "OCSP_basic_sign"}, | ||
74 | {ERR_PACK(0,OCSP_F_OCSP_BASIC_VERIFY,0), "OCSP_basic_verify"}, | ||
75 | {ERR_PACK(0,OCSP_F_OCSP_CHECK_DELEGATED,0), "OCSP_CHECK_DELEGATED"}, | ||
76 | {ERR_PACK(0,OCSP_F_OCSP_CHECK_IDS,0), "OCSP_CHECK_IDS"}, | ||
77 | {ERR_PACK(0,OCSP_F_OCSP_CHECK_ISSUER,0), "OCSP_CHECK_ISSUER"}, | ||
78 | {ERR_PACK(0,OCSP_F_OCSP_CHECK_VALIDITY,0), "OCSP_check_validity"}, | ||
79 | {ERR_PACK(0,OCSP_F_OCSP_MATCH_ISSUERID,0), "OCSP_MATCH_ISSUERID"}, | ||
80 | {ERR_PACK(0,OCSP_F_OCSP_PARSE_URL,0), "OCSP_parse_url"}, | ||
81 | {ERR_PACK(0,OCSP_F_OCSP_REQUEST_SIGN,0), "OCSP_request_sign"}, | ||
82 | {ERR_PACK(0,OCSP_F_OCSP_REQUEST_VERIFY,0), "OCSP_request_verify"}, | ||
83 | {ERR_PACK(0,OCSP_F_OCSP_RESPONSE_GET1_BASIC,0), "OCSP_response_get1_basic"}, | ||
84 | {ERR_PACK(0,OCSP_F_OCSP_SENDREQ_BIO,0), "OCSP_sendreq_bio"}, | ||
85 | {ERR_PACK(0,OCSP_F_REQUEST_VERIFY,0), "REQUEST_VERIFY"}, | ||
86 | {0,NULL} | ||
87 | }; | ||
88 | |||
89 | static ERR_STRING_DATA OCSP_str_reasons[]= | ||
90 | { | ||
91 | {OCSP_R_BAD_DATA ,"bad data"}, | ||
92 | {OCSP_R_CERTIFICATE_VERIFY_ERROR ,"certificate verify error"}, | ||
93 | {OCSP_R_DIGEST_ERR ,"digest err"}, | ||
94 | {OCSP_R_ERROR_IN_NEXTUPDATE_FIELD ,"error in nextupdate field"}, | ||
95 | {OCSP_R_ERROR_IN_THISUPDATE_FIELD ,"error in thisupdate field"}, | ||
96 | {OCSP_R_ERROR_PARSING_URL ,"error parsing url"}, | ||
97 | {OCSP_R_MISSING_OCSPSIGNING_USAGE ,"missing ocspsigning usage"}, | ||
98 | {OCSP_R_NEXTUPDATE_BEFORE_THISUPDATE ,"nextupdate before thisupdate"}, | ||
99 | {OCSP_R_NOT_BASIC_RESPONSE ,"not basic response"}, | ||
100 | {OCSP_R_NO_CERTIFICATES_IN_CHAIN ,"no certificates in chain"}, | ||
101 | {OCSP_R_NO_CONTENT ,"no content"}, | ||
102 | {OCSP_R_NO_PUBLIC_KEY ,"no public key"}, | ||
103 | {OCSP_R_NO_RESPONSE_DATA ,"no response data"}, | ||
104 | {OCSP_R_NO_REVOKED_TIME ,"no revoked time"}, | ||
105 | {OCSP_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE,"private key does not match certificate"}, | ||
106 | {OCSP_R_REQUEST_NOT_SIGNED ,"request not signed"}, | ||
107 | {OCSP_R_RESPONSE_CONTAINS_NO_REVOCATION_DATA,"response contains no revocation data"}, | ||
108 | {OCSP_R_ROOT_CA_NOT_TRUSTED ,"root ca not trusted"}, | ||
109 | {OCSP_R_SERVER_READ_ERROR ,"server read error"}, | ||
110 | {OCSP_R_SERVER_RESPONSE_ERROR ,"server response error"}, | ||
111 | {OCSP_R_SERVER_RESPONSE_PARSE_ERROR ,"server response parse error"}, | ||
112 | {OCSP_R_SERVER_WRITE_ERROR ,"server write error"}, | ||
113 | {OCSP_R_SIGNATURE_FAILURE ,"signature failure"}, | ||
114 | {OCSP_R_SIGNER_CERTIFICATE_NOT_FOUND ,"signer certificate not found"}, | ||
115 | {OCSP_R_STATUS_EXPIRED ,"status expired"}, | ||
116 | {OCSP_R_STATUS_NOT_YET_VALID ,"status not yet valid"}, | ||
117 | {OCSP_R_STATUS_TOO_OLD ,"status too old"}, | ||
118 | {OCSP_R_UNKNOWN_MESSAGE_DIGEST ,"unknown message digest"}, | ||
119 | {OCSP_R_UNKNOWN_NID ,"unknown nid"}, | ||
120 | {OCSP_R_UNSUPPORTED_REQUESTORNAME_TYPE ,"unsupported requestorname type"}, | ||
121 | {0,NULL} | ||
122 | }; | ||
123 | |||
124 | #endif | ||
125 | |||
126 | void ERR_load_OCSP_strings(void) | ||
127 | { | ||
128 | static int init=1; | ||
129 | |||
130 | if (init) | ||
131 | { | ||
132 | init=0; | ||
133 | #ifndef OPENSSL_NO_ERR | ||
134 | ERR_load_strings(ERR_LIB_OCSP,OCSP_str_functs); | ||
135 | ERR_load_strings(ERR_LIB_OCSP,OCSP_str_reasons); | ||
136 | #endif | ||
137 | |||
138 | } | ||
139 | } | ||
diff --git a/src/lib/libcrypto/ocsp/ocsp_ext.c b/src/lib/libcrypto/ocsp/ocsp_ext.c new file mode 100644 index 0000000000..d6c8899f58 --- /dev/null +++ b/src/lib/libcrypto/ocsp/ocsp_ext.c | |||
@@ -0,0 +1,528 @@ | |||
1 | /* ocsp_ext.c */ | ||
2 | /* Written by Tom Titchener <Tom_Titchener@groove.net> for the OpenSSL | ||
3 | * project. */ | ||
4 | |||
5 | /* History: | ||
6 | This file was transfered to Richard Levitte from CertCo by Kathy | ||
7 | Weinhold in mid-spring 2000 to be included in OpenSSL or released | ||
8 | as a patch kit. */ | ||
9 | |||
10 | /* ==================================================================== | ||
11 | * Copyright (c) 1998-2000 The OpenSSL Project. All rights reserved. | ||
12 | * | ||
13 | * Redistribution and use in source and binary forms, with or without | ||
14 | * modification, are permitted provided that the following conditions | ||
15 | * are met: | ||
16 | * | ||
17 | * 1. Redistributions of source code must retain the above copyright | ||
18 | * notice, this list of conditions and the following disclaimer. | ||
19 | * | ||
20 | * 2. Redistributions in binary form must reproduce the above copyright | ||
21 | * notice, this list of conditions and the following disclaimer in | ||
22 | * the documentation and/or other materials provided with the | ||
23 | * distribution. | ||
24 | * | ||
25 | * 3. All advertising materials mentioning features or use of this | ||
26 | * software must display the following acknowledgment: | ||
27 | * "This product includes software developed by the OpenSSL Project | ||
28 | * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" | ||
29 | * | ||
30 | * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to | ||
31 | * endorse or promote products derived from this software without | ||
32 | * prior written permission. For written permission, please contact | ||
33 | * openssl-core@openssl.org. | ||
34 | * | ||
35 | * 5. Products derived from this software may not be called "OpenSSL" | ||
36 | * nor may "OpenSSL" appear in their names without prior written | ||
37 | * permission of the OpenSSL Project. | ||
38 | * | ||
39 | * 6. Redistributions of any form whatsoever must retain the following | ||
40 | * acknowledgment: | ||
41 | * "This product includes software developed by the OpenSSL Project | ||
42 | * for use in the OpenSSL Toolkit (http://www.openssl.org/)" | ||
43 | * | ||
44 | * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY | ||
45 | * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
46 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | ||
47 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR | ||
48 | * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
49 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
50 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
51 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
52 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
53 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
54 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED | ||
55 | * OF THE POSSIBILITY OF SUCH DAMAGE. | ||
56 | * ==================================================================== | ||
57 | * | ||
58 | * This product includes cryptographic software written by Eric Young | ||
59 | * (eay@cryptsoft.com). This product includes software written by Tim | ||
60 | * Hudson (tjh@cryptsoft.com). | ||
61 | * | ||
62 | */ | ||
63 | |||
64 | #include <stdio.h> | ||
65 | #include <cryptlib.h> | ||
66 | #include <openssl/objects.h> | ||
67 | #include <openssl/x509.h> | ||
68 | #include <openssl/ocsp.h> | ||
69 | #include <openssl/rand.h> | ||
70 | #include <openssl/x509v3.h> | ||
71 | |||
72 | /* Standard wrapper functions for extensions */ | ||
73 | |||
74 | /* OCSP request extensions */ | ||
75 | |||
76 | int OCSP_REQUEST_get_ext_count(OCSP_REQUEST *x) | ||
77 | { | ||
78 | return(X509v3_get_ext_count(x->tbsRequest->requestExtensions)); | ||
79 | } | ||
80 | |||
81 | int OCSP_REQUEST_get_ext_by_NID(OCSP_REQUEST *x, int nid, int lastpos) | ||
82 | { | ||
83 | return(X509v3_get_ext_by_NID(x->tbsRequest->requestExtensions,nid,lastpos)); | ||
84 | } | ||
85 | |||
86 | int OCSP_REQUEST_get_ext_by_OBJ(OCSP_REQUEST *x, ASN1_OBJECT *obj, int lastpos) | ||
87 | { | ||
88 | return(X509v3_get_ext_by_OBJ(x->tbsRequest->requestExtensions,obj,lastpos)); | ||
89 | } | ||
90 | |||
91 | int OCSP_REQUEST_get_ext_by_critical(OCSP_REQUEST *x, int crit, int lastpos) | ||
92 | { | ||
93 | return(X509v3_get_ext_by_critical(x->tbsRequest->requestExtensions,crit,lastpos)); | ||
94 | } | ||
95 | |||
96 | X509_EXTENSION *OCSP_REQUEST_get_ext(OCSP_REQUEST *x, int loc) | ||
97 | { | ||
98 | return(X509v3_get_ext(x->tbsRequest->requestExtensions,loc)); | ||
99 | } | ||
100 | |||
101 | X509_EXTENSION *OCSP_REQUEST_delete_ext(OCSP_REQUEST *x, int loc) | ||
102 | { | ||
103 | return(X509v3_delete_ext(x->tbsRequest->requestExtensions,loc)); | ||
104 | } | ||
105 | |||
106 | void *OCSP_REQUEST_get1_ext_d2i(OCSP_REQUEST *x, int nid, int *crit, int *idx) | ||
107 | { | ||
108 | return X509V3_get_d2i(x->tbsRequest->requestExtensions, nid, crit, idx); | ||
109 | } | ||
110 | |||
111 | int OCSP_REQUEST_add1_ext_i2d(OCSP_REQUEST *x, int nid, void *value, int crit, | ||
112 | unsigned long flags) | ||
113 | { | ||
114 | return X509V3_add1_i2d(&x->tbsRequest->requestExtensions, nid, value, crit, flags); | ||
115 | } | ||
116 | |||
117 | int OCSP_REQUEST_add_ext(OCSP_REQUEST *x, X509_EXTENSION *ex, int loc) | ||
118 | { | ||
119 | return(X509v3_add_ext(&(x->tbsRequest->requestExtensions),ex,loc) != NULL); | ||
120 | } | ||
121 | |||
122 | /* Single extensions */ | ||
123 | |||
124 | int OCSP_ONEREQ_get_ext_count(OCSP_ONEREQ *x) | ||
125 | { | ||
126 | return(X509v3_get_ext_count(x->singleRequestExtensions)); | ||
127 | } | ||
128 | |||
129 | int OCSP_ONEREQ_get_ext_by_NID(OCSP_ONEREQ *x, int nid, int lastpos) | ||
130 | { | ||
131 | return(X509v3_get_ext_by_NID(x->singleRequestExtensions,nid,lastpos)); | ||
132 | } | ||
133 | |||
134 | int OCSP_ONEREQ_get_ext_by_OBJ(OCSP_ONEREQ *x, ASN1_OBJECT *obj, int lastpos) | ||
135 | { | ||
136 | return(X509v3_get_ext_by_OBJ(x->singleRequestExtensions,obj,lastpos)); | ||
137 | } | ||
138 | |||
139 | int OCSP_ONEREQ_get_ext_by_critical(OCSP_ONEREQ *x, int crit, int lastpos) | ||
140 | { | ||
141 | return(X509v3_get_ext_by_critical(x->singleRequestExtensions,crit,lastpos)); | ||
142 | } | ||
143 | |||
144 | X509_EXTENSION *OCSP_ONEREQ_get_ext(OCSP_ONEREQ *x, int loc) | ||
145 | { | ||
146 | return(X509v3_get_ext(x->singleRequestExtensions,loc)); | ||
147 | } | ||
148 | |||
149 | X509_EXTENSION *OCSP_ONEREQ_delete_ext(OCSP_ONEREQ *x, int loc) | ||
150 | { | ||
151 | return(X509v3_delete_ext(x->singleRequestExtensions,loc)); | ||
152 | } | ||
153 | |||
154 | void *OCSP_ONEREQ_get1_ext_d2i(OCSP_ONEREQ *x, int nid, int *crit, int *idx) | ||
155 | { | ||
156 | return X509V3_get_d2i(x->singleRequestExtensions, nid, crit, idx); | ||
157 | } | ||
158 | |||
159 | int OCSP_ONEREQ_add1_ext_i2d(OCSP_ONEREQ *x, int nid, void *value, int crit, | ||
160 | unsigned long flags) | ||
161 | { | ||
162 | return X509V3_add1_i2d(&x->singleRequestExtensions, nid, value, crit, flags); | ||
163 | } | ||
164 | |||
165 | int OCSP_ONEREQ_add_ext(OCSP_ONEREQ *x, X509_EXTENSION *ex, int loc) | ||
166 | { | ||
167 | return(X509v3_add_ext(&(x->singleRequestExtensions),ex,loc) != NULL); | ||
168 | } | ||
169 | |||
170 | /* OCSP Basic response */ | ||
171 | |||
172 | int OCSP_BASICRESP_get_ext_count(OCSP_BASICRESP *x) | ||
173 | { | ||
174 | return(X509v3_get_ext_count(x->tbsResponseData->responseExtensions)); | ||
175 | } | ||
176 | |||
177 | int OCSP_BASICRESP_get_ext_by_NID(OCSP_BASICRESP *x, int nid, int lastpos) | ||
178 | { | ||
179 | return(X509v3_get_ext_by_NID(x->tbsResponseData->responseExtensions,nid,lastpos)); | ||
180 | } | ||
181 | |||
182 | int OCSP_BASICRESP_get_ext_by_OBJ(OCSP_BASICRESP *x, ASN1_OBJECT *obj, int lastpos) | ||
183 | { | ||
184 | return(X509v3_get_ext_by_OBJ(x->tbsResponseData->responseExtensions,obj,lastpos)); | ||
185 | } | ||
186 | |||
187 | int OCSP_BASICRESP_get_ext_by_critical(OCSP_BASICRESP *x, int crit, int lastpos) | ||
188 | { | ||
189 | return(X509v3_get_ext_by_critical(x->tbsResponseData->responseExtensions,crit,lastpos)); | ||
190 | } | ||
191 | |||
192 | X509_EXTENSION *OCSP_BASICRESP_get_ext(OCSP_BASICRESP *x, int loc) | ||
193 | { | ||
194 | return(X509v3_get_ext(x->tbsResponseData->responseExtensions,loc)); | ||
195 | } | ||
196 | |||
197 | X509_EXTENSION *OCSP_BASICRESP_delete_ext(OCSP_BASICRESP *x, int loc) | ||
198 | { | ||
199 | return(X509v3_delete_ext(x->tbsResponseData->responseExtensions,loc)); | ||
200 | } | ||
201 | |||
202 | void *OCSP_BASICRESP_get1_ext_d2i(OCSP_BASICRESP *x, int nid, int *crit, int *idx) | ||
203 | { | ||
204 | return X509V3_get_d2i(x->tbsResponseData->responseExtensions, nid, crit, idx); | ||
205 | } | ||
206 | |||
207 | int OCSP_BASICRESP_add1_ext_i2d(OCSP_BASICRESP *x, int nid, void *value, int crit, | ||
208 | unsigned long flags) | ||
209 | { | ||
210 | return X509V3_add1_i2d(&x->tbsResponseData->responseExtensions, nid, value, crit, flags); | ||
211 | } | ||
212 | |||
213 | int OCSP_BASICRESP_add_ext(OCSP_BASICRESP *x, X509_EXTENSION *ex, int loc) | ||
214 | { | ||
215 | return(X509v3_add_ext(&(x->tbsResponseData->responseExtensions),ex,loc) != NULL); | ||
216 | } | ||
217 | |||
218 | /* OCSP single response extensions */ | ||
219 | |||
220 | int OCSP_SINGLERESP_get_ext_count(OCSP_SINGLERESP *x) | ||
221 | { | ||
222 | return(X509v3_get_ext_count(x->singleExtensions)); | ||
223 | } | ||
224 | |||
225 | int OCSP_SINGLERESP_get_ext_by_NID(OCSP_SINGLERESP *x, int nid, int lastpos) | ||
226 | { | ||
227 | return(X509v3_get_ext_by_NID(x->singleExtensions,nid,lastpos)); | ||
228 | } | ||
229 | |||
230 | int OCSP_SINGLERESP_get_ext_by_OBJ(OCSP_SINGLERESP *x, ASN1_OBJECT *obj, int lastpos) | ||
231 | { | ||
232 | return(X509v3_get_ext_by_OBJ(x->singleExtensions,obj,lastpos)); | ||
233 | } | ||
234 | |||
235 | int OCSP_SINGLERESP_get_ext_by_critical(OCSP_SINGLERESP *x, int crit, int lastpos) | ||
236 | { | ||
237 | return(X509v3_get_ext_by_critical(x->singleExtensions,crit,lastpos)); | ||
238 | } | ||
239 | |||
240 | X509_EXTENSION *OCSP_SINGLERESP_get_ext(OCSP_SINGLERESP *x, int loc) | ||
241 | { | ||
242 | return(X509v3_get_ext(x->singleExtensions,loc)); | ||
243 | } | ||
244 | |||
245 | X509_EXTENSION *OCSP_SINGLERESP_delete_ext(OCSP_SINGLERESP *x, int loc) | ||
246 | { | ||
247 | return(X509v3_delete_ext(x->singleExtensions,loc)); | ||
248 | } | ||
249 | |||
250 | void *OCSP_SINGLERESP_get1_ext_d2i(OCSP_SINGLERESP *x, int nid, int *crit, int *idx) | ||
251 | { | ||
252 | return X509V3_get_d2i(x->singleExtensions, nid, crit, idx); | ||
253 | } | ||
254 | |||
255 | int OCSP_SINGLERESP_add1_ext_i2d(OCSP_SINGLERESP *x, int nid, void *value, int crit, | ||
256 | unsigned long flags) | ||
257 | { | ||
258 | return X509V3_add1_i2d(&x->singleExtensions, nid, value, crit, flags); | ||
259 | } | ||
260 | |||
261 | int OCSP_SINGLERESP_add_ext(OCSP_SINGLERESP *x, X509_EXTENSION *ex, int loc) | ||
262 | { | ||
263 | return(X509v3_add_ext(&(x->singleExtensions),ex,loc) != NULL); | ||
264 | } | ||
265 | |||
266 | /* also CRL Entry Extensions */ | ||
267 | |||
268 | ASN1_STRING *ASN1_STRING_encode(ASN1_STRING *s, int (*i2d)(), | ||
269 | char *data, STACK_OF(ASN1_OBJECT) *sk) | ||
270 | { | ||
271 | int i; | ||
272 | unsigned char *p, *b = NULL; | ||
273 | |||
274 | if (data) | ||
275 | { | ||
276 | if ((i=i2d(data,NULL)) <= 0) goto err; | ||
277 | if (!(b=p=(unsigned char*)OPENSSL_malloc((unsigned int)i))) | ||
278 | goto err; | ||
279 | if (i2d(data, &p) <= 0) goto err; | ||
280 | } | ||
281 | else if (sk) | ||
282 | { | ||
283 | if ((i=i2d_ASN1_SET_OF_ASN1_OBJECT(sk,NULL,i2d,V_ASN1_SEQUENCE, | ||
284 | V_ASN1_UNIVERSAL,IS_SEQUENCE))<=0) goto err; | ||
285 | if (!(b=p=(unsigned char*)OPENSSL_malloc((unsigned int)i))) | ||
286 | goto err; | ||
287 | if (i2d_ASN1_SET_OF_ASN1_OBJECT(sk,&p,i2d,V_ASN1_SEQUENCE, | ||
288 | V_ASN1_UNIVERSAL,IS_SEQUENCE)<=0) goto err; | ||
289 | } | ||
290 | else | ||
291 | { | ||
292 | OCSPerr(OCSP_F_ASN1_STRING_ENCODE,OCSP_R_BAD_DATA); | ||
293 | goto err; | ||
294 | } | ||
295 | if (!s && !(s = ASN1_STRING_new())) goto err; | ||
296 | if (!(ASN1_STRING_set(s, b, i))) goto err; | ||
297 | OPENSSL_free(b); | ||
298 | return s; | ||
299 | err: | ||
300 | if (b) OPENSSL_free(b); | ||
301 | return NULL; | ||
302 | } | ||
303 | |||
304 | /* Nonce handling functions */ | ||
305 | |||
306 | /* Add a nonce to an extension stack. A nonce can be specificed or if NULL | ||
307 | * a random nonce will be generated. | ||
308 | */ | ||
309 | |||
310 | static int ocsp_add1_nonce(STACK_OF(X509_EXTENSION) **exts, unsigned char *val, int len) | ||
311 | { | ||
312 | unsigned char *tmpval; | ||
313 | ASN1_OCTET_STRING os; | ||
314 | int ret = 0; | ||
315 | if (len <= 0) len = OCSP_DEFAULT_NONCE_LENGTH; | ||
316 | if (val) tmpval = val; | ||
317 | else | ||
318 | { | ||
319 | if (!(tmpval = OPENSSL_malloc(len))) goto err; | ||
320 | RAND_pseudo_bytes(tmpval, len); | ||
321 | } | ||
322 | os.data = tmpval; | ||
323 | os.length = len; | ||
324 | if(!X509V3_add1_i2d(exts, NID_id_pkix_OCSP_Nonce, | ||
325 | &os, 0, X509V3_ADD_REPLACE)) | ||
326 | goto err; | ||
327 | ret = 1; | ||
328 | err: | ||
329 | if(!val) OPENSSL_free(tmpval); | ||
330 | return ret; | ||
331 | } | ||
332 | |||
333 | |||
334 | /* Add nonce to an OCSP request */ | ||
335 | |||
336 | int OCSP_request_add1_nonce(OCSP_REQUEST *req, unsigned char *val, int len) | ||
337 | { | ||
338 | return ocsp_add1_nonce(&req->tbsRequest->requestExtensions, val, len); | ||
339 | } | ||
340 | |||
341 | /* Same as above but for a response */ | ||
342 | |||
343 | int OCSP_basic_add1_nonce(OCSP_BASICRESP *resp, unsigned char *val, int len) | ||
344 | { | ||
345 | return ocsp_add1_nonce(&resp->tbsResponseData->responseExtensions, val, len); | ||
346 | } | ||
347 | |||
348 | /* Check nonce validity in a request and response. | ||
349 | * Return value reflects result: | ||
350 | * 1: nonces present and equal. | ||
351 | * 2: nonces both absent. | ||
352 | * 3: nonce present in response only. | ||
353 | * 0: nonces both present and not equal. | ||
354 | * -1: nonce in request only. | ||
355 | * | ||
356 | * For most responders clients can check return > 0. | ||
357 | * If responder doesn't handle nonces return != 0 may be | ||
358 | * necessary. return == 0 is always an error. | ||
359 | */ | ||
360 | |||
361 | int OCSP_check_nonce(OCSP_REQUEST *req, OCSP_BASICRESP *bs) | ||
362 | { | ||
363 | /* | ||
364 | * Since we are only interested in the presence or absence of | ||
365 | * the nonce and comparing its value there is no need to use | ||
366 | * the X509V3 routines: this way we can avoid them allocating an | ||
367 | * ASN1_OCTET_STRING structure for the value which would be | ||
368 | * freed immediately anyway. | ||
369 | */ | ||
370 | |||
371 | int req_idx, resp_idx; | ||
372 | X509_EXTENSION *req_ext, *resp_ext; | ||
373 | req_idx = OCSP_REQUEST_get_ext_by_NID(req, NID_id_pkix_OCSP_Nonce, -1); | ||
374 | resp_idx = OCSP_BASICRESP_get_ext_by_NID(bs, NID_id_pkix_OCSP_Nonce, -1); | ||
375 | /* Check both absent */ | ||
376 | if((req_idx < 0) && (resp_idx < 0)) | ||
377 | return 2; | ||
378 | /* Check in request only */ | ||
379 | if((req_idx >= 0) && (resp_idx < 0)) | ||
380 | return -1; | ||
381 | /* Check in response but not request */ | ||
382 | if((req_idx < 0) && (resp_idx >= 0)) | ||
383 | return 3; | ||
384 | /* Otherwise nonce in request and response so retrieve the extensions */ | ||
385 | req_ext = OCSP_REQUEST_get_ext(req, req_idx); | ||
386 | resp_ext = OCSP_BASICRESP_get_ext(bs, resp_idx); | ||
387 | if(ASN1_OCTET_STRING_cmp(req_ext->value, resp_ext->value)) | ||
388 | return 0; | ||
389 | return 1; | ||
390 | } | ||
391 | |||
392 | /* Copy the nonce value (if any) from an OCSP request to | ||
393 | * a response. | ||
394 | */ | ||
395 | |||
396 | int OCSP_copy_nonce(OCSP_BASICRESP *resp, OCSP_REQUEST *req) | ||
397 | { | ||
398 | X509_EXTENSION *req_ext; | ||
399 | int req_idx; | ||
400 | /* Check for nonce in request */ | ||
401 | req_idx = OCSP_REQUEST_get_ext_by_NID(req, NID_id_pkix_OCSP_Nonce, -1); | ||
402 | /* If no nonce that's OK */ | ||
403 | if (req_idx < 0) return 2; | ||
404 | req_ext = OCSP_REQUEST_get_ext(req, req_idx); | ||
405 | return OCSP_BASICRESP_add_ext(resp, req_ext, -1); | ||
406 | } | ||
407 | |||
408 | X509_EXTENSION *OCSP_crlID_new(char *url, long *n, char *tim) | ||
409 | { | ||
410 | X509_EXTENSION *x = NULL; | ||
411 | OCSP_CRLID *cid = NULL; | ||
412 | |||
413 | if (!(cid = OCSP_CRLID_new())) goto err; | ||
414 | if (url) | ||
415 | { | ||
416 | if (!(cid->crlUrl = ASN1_IA5STRING_new())) goto err; | ||
417 | if (!(ASN1_STRING_set(cid->crlUrl, url, -1))) goto err; | ||
418 | } | ||
419 | if (n) | ||
420 | { | ||
421 | if (!(cid->crlNum = ASN1_INTEGER_new())) goto err; | ||
422 | if (!(ASN1_INTEGER_set(cid->crlNum, *n))) goto err; | ||
423 | } | ||
424 | if (tim) | ||
425 | { | ||
426 | if (!(cid->crlTime = ASN1_GENERALIZEDTIME_new())) goto err; | ||
427 | if (!(ASN1_GENERALIZEDTIME_set_string(cid->crlTime, tim))) | ||
428 | goto err; | ||
429 | } | ||
430 | if (!(x = X509_EXTENSION_new())) goto err; | ||
431 | if (!(x->object = OBJ_nid2obj(NID_id_pkix_OCSP_CrlID))) goto err; | ||
432 | if (!(ASN1_STRING_encode(x->value,i2d_OCSP_CRLID,(char*)cid,NULL))) | ||
433 | goto err; | ||
434 | OCSP_CRLID_free(cid); | ||
435 | return x; | ||
436 | err: | ||
437 | if (x) X509_EXTENSION_free(x); | ||
438 | if (cid) OCSP_CRLID_free(cid); | ||
439 | return NULL; | ||
440 | } | ||
441 | |||
442 | /* AcceptableResponses ::= SEQUENCE OF OBJECT IDENTIFIER */ | ||
443 | X509_EXTENSION *OCSP_accept_responses_new(char **oids) | ||
444 | { | ||
445 | int nid; | ||
446 | STACK_OF(ASN1_OBJECT) *sk = NULL; | ||
447 | ASN1_OBJECT *o = NULL; | ||
448 | X509_EXTENSION *x = NULL; | ||
449 | |||
450 | if (!(sk = sk_ASN1_OBJECT_new_null())) goto err; | ||
451 | while (oids && *oids) | ||
452 | { | ||
453 | if ((nid=OBJ_txt2nid(*oids))!=NID_undef&&(o=OBJ_nid2obj(nid))) | ||
454 | sk_ASN1_OBJECT_push(sk, o); | ||
455 | oids++; | ||
456 | } | ||
457 | if (!(x = X509_EXTENSION_new())) goto err; | ||
458 | if (!(x->object = OBJ_nid2obj(NID_id_pkix_OCSP_acceptableResponses))) | ||
459 | goto err; | ||
460 | if (!(ASN1_STRING_encode(x->value,i2d_ASN1_OBJECT,NULL,sk))) | ||
461 | goto err; | ||
462 | sk_ASN1_OBJECT_pop_free(sk, ASN1_OBJECT_free); | ||
463 | return x; | ||
464 | err: | ||
465 | if (x) X509_EXTENSION_free(x); | ||
466 | if (sk) sk_ASN1_OBJECT_pop_free(sk, ASN1_OBJECT_free); | ||
467 | return NULL; | ||
468 | } | ||
469 | |||
470 | /* ArchiveCutoff ::= GeneralizedTime */ | ||
471 | X509_EXTENSION *OCSP_archive_cutoff_new(char* tim) | ||
472 | { | ||
473 | X509_EXTENSION *x=NULL; | ||
474 | ASN1_GENERALIZEDTIME *gt = NULL; | ||
475 | |||
476 | if (!(gt = ASN1_GENERALIZEDTIME_new())) goto err; | ||
477 | if (!(ASN1_GENERALIZEDTIME_set_string(gt, tim))) goto err; | ||
478 | if (!(x = X509_EXTENSION_new())) goto err; | ||
479 | if (!(x->object=OBJ_nid2obj(NID_id_pkix_OCSP_archiveCutoff)))goto err; | ||
480 | if (!(ASN1_STRING_encode(x->value,i2d_ASN1_GENERALIZEDTIME, | ||
481 | (char*)gt,NULL))) goto err; | ||
482 | ASN1_GENERALIZEDTIME_free(gt); | ||
483 | return x; | ||
484 | err: | ||
485 | if (gt) ASN1_GENERALIZEDTIME_free(gt); | ||
486 | if (x) X509_EXTENSION_free(x); | ||
487 | return NULL; | ||
488 | } | ||
489 | |||
490 | /* per ACCESS_DESCRIPTION parameter are oids, of which there are currently | ||
491 | * two--NID_ad_ocsp, NID_id_ad_caIssuers--and GeneralName value. This | ||
492 | * method forces NID_ad_ocsp and uniformResourceLocator [6] IA5String. | ||
493 | */ | ||
494 | X509_EXTENSION *OCSP_url_svcloc_new(X509_NAME* issuer, char **urls) | ||
495 | { | ||
496 | X509_EXTENSION *x = NULL; | ||
497 | ASN1_IA5STRING *ia5 = NULL; | ||
498 | OCSP_SERVICELOC *sloc = NULL; | ||
499 | ACCESS_DESCRIPTION *ad = NULL; | ||
500 | |||
501 | if (!(sloc = OCSP_SERVICELOC_new())) goto err; | ||
502 | if (!(sloc->issuer = X509_NAME_dup(issuer))) goto err; | ||
503 | if (urls && *urls && !(sloc->locator = sk_ACCESS_DESCRIPTION_new_null())) goto err; | ||
504 | while (urls && *urls) | ||
505 | { | ||
506 | if (!(ad = ACCESS_DESCRIPTION_new())) goto err; | ||
507 | if (!(ad->method=OBJ_nid2obj(NID_ad_OCSP))) goto err; | ||
508 | if (!(ad->location = GENERAL_NAME_new())) goto err; | ||
509 | if (!(ia5 = ASN1_IA5STRING_new())) goto err; | ||
510 | if (!ASN1_STRING_set((ASN1_STRING*)ia5, *urls, -1)) goto err; | ||
511 | ad->location->type = GEN_URI; | ||
512 | ad->location->d.ia5 = ia5; | ||
513 | if (!sk_ACCESS_DESCRIPTION_push(sloc->locator, ad)) goto err; | ||
514 | urls++; | ||
515 | } | ||
516 | if (!(x = X509_EXTENSION_new())) goto err; | ||
517 | if (!(x->object = OBJ_nid2obj(NID_id_pkix_OCSP_serviceLocator))) | ||
518 | goto err; | ||
519 | if (!(ASN1_STRING_encode(x->value, i2d_OCSP_SERVICELOC, | ||
520 | (char*)sloc, NULL))) goto err; | ||
521 | OCSP_SERVICELOC_free(sloc); | ||
522 | return x; | ||
523 | err: | ||
524 | if (x) X509_EXTENSION_free(x); | ||
525 | if (sloc) OCSP_SERVICELOC_free(sloc); | ||
526 | return NULL; | ||
527 | } | ||
528 | |||
diff --git a/src/lib/libcrypto/ocsp/ocsp_ht.c b/src/lib/libcrypto/ocsp/ocsp_ht.c new file mode 100644 index 0000000000..b78cd37092 --- /dev/null +++ b/src/lib/libcrypto/ocsp/ocsp_ht.c | |||
@@ -0,0 +1,164 @@ | |||
1 | /* ocsp_ht.c */ | ||
2 | /* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL | ||
3 | * project 2000. | ||
4 | */ | ||
5 | /* ==================================================================== | ||
6 | * Copyright (c) 2000 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 <stdio.h> | ||
61 | #include <stdlib.h> | ||
62 | #include <ctype.h> | ||
63 | #include <string.h> | ||
64 | #include <openssl/ocsp.h> | ||
65 | #include <openssl/err.h> | ||
66 | #include <openssl/buffer.h> | ||
67 | |||
68 | /* Quick and dirty HTTP OCSP request handler. | ||
69 | * Could make this a bit cleverer by adding | ||
70 | * support for non blocking BIOs and a few | ||
71 | * other refinements. | ||
72 | */ | ||
73 | |||
74 | OCSP_RESPONSE *OCSP_sendreq_bio(BIO *b, char *path, OCSP_REQUEST *req) | ||
75 | { | ||
76 | BIO *mem = NULL; | ||
77 | char tmpbuf[1024]; | ||
78 | OCSP_RESPONSE *resp = NULL; | ||
79 | char *p, *q, *r; | ||
80 | int len, retcode; | ||
81 | static char req_txt[] = | ||
82 | "POST %s HTTP/1.0\r\n\ | ||
83 | Content-Type: application/ocsp-request\r\n\ | ||
84 | Content-Length: %d\r\n\r\n"; | ||
85 | |||
86 | len = i2d_OCSP_REQUEST(req, NULL); | ||
87 | if(BIO_printf(b, req_txt, path, len) < 0) { | ||
88 | OCSPerr(OCSP_F_OCSP_SENDREQ_BIO,OCSP_R_SERVER_WRITE_ERROR); | ||
89 | goto err; | ||
90 | } | ||
91 | if(i2d_OCSP_REQUEST_bio(b, req) <= 0) { | ||
92 | OCSPerr(OCSP_F_OCSP_SENDREQ_BIO,OCSP_R_SERVER_WRITE_ERROR); | ||
93 | goto err; | ||
94 | } | ||
95 | if(!(mem = BIO_new(BIO_s_mem()))) goto err; | ||
96 | /* Copy response to a memory BIO: socket bios can't do gets! */ | ||
97 | while ((len = BIO_read(b, tmpbuf, 1024))) { | ||
98 | if(len < 0) { | ||
99 | OCSPerr(OCSP_F_OCSP_SENDREQ_BIO,OCSP_R_SERVER_READ_ERROR); | ||
100 | goto err; | ||
101 | } | ||
102 | BIO_write(mem, tmpbuf, len); | ||
103 | } | ||
104 | if(BIO_gets(mem, tmpbuf, 512) <= 0) { | ||
105 | OCSPerr(OCSP_F_OCSP_SENDREQ_BIO,OCSP_R_SERVER_RESPONSE_PARSE_ERROR); | ||
106 | goto err; | ||
107 | } | ||
108 | /* Parse the HTTP response. This will look like this: | ||
109 | * "HTTP/1.0 200 OK". We need to obtain the numeric code and | ||
110 | * informational message. | ||
111 | */ | ||
112 | |||
113 | /* Skip to first white space (passed protocol info) */ | ||
114 | for(p = tmpbuf; *p && !isspace((unsigned char)*p); p++) continue; | ||
115 | if(!*p) { | ||
116 | OCSPerr(OCSP_F_OCSP_SENDREQ_BIO,OCSP_R_SERVER_RESPONSE_PARSE_ERROR); | ||
117 | goto err; | ||
118 | } | ||
119 | /* Skip past white space to start of response code */ | ||
120 | while(*p && isspace((unsigned char)*p)) p++; | ||
121 | if(!*p) { | ||
122 | OCSPerr(OCSP_F_OCSP_SENDREQ_BIO,OCSP_R_SERVER_RESPONSE_PARSE_ERROR); | ||
123 | goto err; | ||
124 | } | ||
125 | /* Find end of response code: first whitespace after start of code */ | ||
126 | for(q = p; *q && !isspace((unsigned char)*q); q++) continue; | ||
127 | if(!*q) { | ||
128 | OCSPerr(OCSP_F_OCSP_SENDREQ_BIO,OCSP_R_SERVER_RESPONSE_PARSE_ERROR); | ||
129 | goto err; | ||
130 | } | ||
131 | /* Set end of response code and start of message */ | ||
132 | *q++ = 0; | ||
133 | /* Attempt to parse numeric code */ | ||
134 | retcode = strtoul(p, &r, 10); | ||
135 | if(*r) goto err; | ||
136 | /* Skip over any leading white space in message */ | ||
137 | while(*q && isspace((unsigned char)*q)) q++; | ||
138 | if(!*q) goto err; | ||
139 | /* Finally zap any trailing white space in message (include CRLF) */ | ||
140 | /* We know q has a non white space character so this is OK */ | ||
141 | for(r = q + strlen(q) - 1; isspace((unsigned char)*r); r--) *r = 0; | ||
142 | if(retcode != 200) { | ||
143 | OCSPerr(OCSP_F_OCSP_SENDREQ_BIO,OCSP_R_SERVER_RESPONSE_ERROR); | ||
144 | ERR_add_error_data(4, "Code=", p, ",Reason=", q); | ||
145 | goto err; | ||
146 | } | ||
147 | /* Find blank line marking beginning of content */ | ||
148 | while(BIO_gets(mem, tmpbuf, 512) > 0) | ||
149 | { | ||
150 | for(p = tmpbuf; *p && isspace((unsigned char)*p); p++) continue; | ||
151 | if(!*p) break; | ||
152 | } | ||
153 | if(*p) { | ||
154 | OCSPerr(OCSP_F_OCSP_SENDREQ_BIO,OCSP_R_NO_CONTENT); | ||
155 | goto err; | ||
156 | } | ||
157 | if(!(resp = d2i_OCSP_RESPONSE_bio(mem, NULL))) { | ||
158 | OCSPerr(OCSP_F_OCSP_SENDREQ_BIO,ERR_R_NESTED_ASN1_ERROR); | ||
159 | goto err; | ||
160 | } | ||
161 | err: | ||
162 | BIO_free(mem); | ||
163 | return resp; | ||
164 | } | ||
diff --git a/src/lib/libcrypto/ocsp/ocsp_lib.c b/src/lib/libcrypto/ocsp/ocsp_lib.c new file mode 100644 index 0000000000..3875af165c --- /dev/null +++ b/src/lib/libcrypto/ocsp/ocsp_lib.c | |||
@@ -0,0 +1,261 @@ | |||
1 | /* ocsp_lib.c */ | ||
2 | /* Written by Tom Titchener <Tom_Titchener@groove.net> for the OpenSSL | ||
3 | * project. */ | ||
4 | |||
5 | /* History: | ||
6 | This file was transfered to Richard Levitte from CertCo by Kathy | ||
7 | Weinhold in mid-spring 2000 to be included in OpenSSL or released | ||
8 | as a patch kit. */ | ||
9 | |||
10 | /* ==================================================================== | ||
11 | * Copyright (c) 1998-2000 The OpenSSL Project. All rights reserved. | ||
12 | * | ||
13 | * Redistribution and use in source and binary forms, with or without | ||
14 | * modification, are permitted provided that the following conditions | ||
15 | * are met: | ||
16 | * | ||
17 | * 1. Redistributions of source code must retain the above copyright | ||
18 | * notice, this list of conditions and the following disclaimer. | ||
19 | * | ||
20 | * 2. Redistributions in binary form must reproduce the above copyright | ||
21 | * notice, this list of conditions and the following disclaimer in | ||
22 | * the documentation and/or other materials provided with the | ||
23 | * distribution. | ||
24 | * | ||
25 | * 3. All advertising materials mentioning features or use of this | ||
26 | * software must display the following acknowledgment: | ||
27 | * "This product includes software developed by the OpenSSL Project | ||
28 | * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" | ||
29 | * | ||
30 | * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to | ||
31 | * endorse or promote products derived from this software without | ||
32 | * prior written permission. For written permission, please contact | ||
33 | * openssl-core@openssl.org. | ||
34 | * | ||
35 | * 5. Products derived from this software may not be called "OpenSSL" | ||
36 | * nor may "OpenSSL" appear in their names without prior written | ||
37 | * permission of the OpenSSL Project. | ||
38 | * | ||
39 | * 6. Redistributions of any form whatsoever must retain the following | ||
40 | * acknowledgment: | ||
41 | * "This product includes software developed by the OpenSSL Project | ||
42 | * for use in the OpenSSL Toolkit (http://www.openssl.org/)" | ||
43 | * | ||
44 | * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY | ||
45 | * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
46 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | ||
47 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR | ||
48 | * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
49 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
50 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
51 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
52 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
53 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
54 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED | ||
55 | * OF THE POSSIBILITY OF SUCH DAMAGE. | ||
56 | * ==================================================================== | ||
57 | * | ||
58 | * This product includes cryptographic software written by Eric Young | ||
59 | * (eay@cryptsoft.com). This product includes software written by Tim | ||
60 | * Hudson (tjh@cryptsoft.com). | ||
61 | * | ||
62 | */ | ||
63 | |||
64 | #include <stdio.h> | ||
65 | #include <cryptlib.h> | ||
66 | #include <openssl/objects.h> | ||
67 | #include <openssl/rand.h> | ||
68 | #include <openssl/x509.h> | ||
69 | #include <openssl/pem.h> | ||
70 | #include <openssl/x509v3.h> | ||
71 | #include <openssl/ocsp.h> | ||
72 | |||
73 | /* Convert a certificate and its issuer to an OCSP_CERTID */ | ||
74 | |||
75 | OCSP_CERTID *OCSP_cert_to_id(const EVP_MD *dgst, X509 *subject, X509 *issuer) | ||
76 | { | ||
77 | X509_NAME *iname; | ||
78 | ASN1_INTEGER *serial; | ||
79 | ASN1_BIT_STRING *ikey; | ||
80 | #ifndef OPENSSL_NO_SHA1 | ||
81 | if(!dgst) dgst = EVP_sha1(); | ||
82 | #endif | ||
83 | if (subject) | ||
84 | { | ||
85 | iname = X509_get_issuer_name(subject); | ||
86 | serial = X509_get_serialNumber(subject); | ||
87 | } | ||
88 | else | ||
89 | { | ||
90 | iname = X509_get_subject_name(issuer); | ||
91 | serial = NULL; | ||
92 | } | ||
93 | ikey = X509_get0_pubkey_bitstr(issuer); | ||
94 | return OCSP_cert_id_new(dgst, iname, ikey, serial); | ||
95 | } | ||
96 | |||
97 | |||
98 | OCSP_CERTID *OCSP_cert_id_new(const EVP_MD *dgst, | ||
99 | X509_NAME *issuerName, | ||
100 | ASN1_BIT_STRING* issuerKey, | ||
101 | ASN1_INTEGER *serialNumber) | ||
102 | { | ||
103 | int nid; | ||
104 | unsigned int i; | ||
105 | X509_ALGOR *alg; | ||
106 | OCSP_CERTID *cid = NULL; | ||
107 | unsigned char md[EVP_MAX_MD_SIZE]; | ||
108 | |||
109 | if (!(cid = OCSP_CERTID_new())) goto err; | ||
110 | |||
111 | alg = cid->hashAlgorithm; | ||
112 | if (alg->algorithm != NULL) ASN1_OBJECT_free(alg->algorithm); | ||
113 | if ((nid = EVP_MD_type(dgst)) == NID_undef) | ||
114 | { | ||
115 | OCSPerr(OCSP_F_CERT_ID_NEW,OCSP_R_UNKNOWN_NID); | ||
116 | goto err; | ||
117 | } | ||
118 | if (!(alg->algorithm=OBJ_nid2obj(nid))) goto err; | ||
119 | if ((alg->parameter=ASN1_TYPE_new()) == NULL) goto err; | ||
120 | alg->parameter->type=V_ASN1_NULL; | ||
121 | |||
122 | if (!X509_NAME_digest(issuerName, dgst, md, &i)) goto digerr; | ||
123 | if (!(ASN1_OCTET_STRING_set(cid->issuerNameHash, md, i))) goto err; | ||
124 | |||
125 | /* Calculate the issuerKey hash, excluding tag and length */ | ||
126 | EVP_Digest(issuerKey->data, issuerKey->length, md, &i, dgst, NULL); | ||
127 | |||
128 | if (!(ASN1_OCTET_STRING_set(cid->issuerKeyHash, md, i))) goto err; | ||
129 | |||
130 | if (serialNumber) | ||
131 | { | ||
132 | ASN1_INTEGER_free(cid->serialNumber); | ||
133 | if (!(cid->serialNumber = ASN1_INTEGER_dup(serialNumber))) goto err; | ||
134 | } | ||
135 | return cid; | ||
136 | digerr: | ||
137 | OCSPerr(OCSP_F_CERT_ID_NEW,OCSP_R_DIGEST_ERR); | ||
138 | err: | ||
139 | if (cid) OCSP_CERTID_free(cid); | ||
140 | return NULL; | ||
141 | } | ||
142 | |||
143 | int OCSP_id_issuer_cmp(OCSP_CERTID *a, OCSP_CERTID *b) | ||
144 | { | ||
145 | int ret; | ||
146 | ret = OBJ_cmp(a->hashAlgorithm->algorithm, b->hashAlgorithm->algorithm); | ||
147 | if (ret) return ret; | ||
148 | ret = ASN1_OCTET_STRING_cmp(a->issuerNameHash, b->issuerNameHash); | ||
149 | if (ret) return ret; | ||
150 | return ASN1_OCTET_STRING_cmp(a->issuerKeyHash, b->issuerKeyHash); | ||
151 | } | ||
152 | |||
153 | int OCSP_id_cmp(OCSP_CERTID *a, OCSP_CERTID *b) | ||
154 | { | ||
155 | int ret; | ||
156 | ret = OCSP_id_issuer_cmp(a, b); | ||
157 | if (ret) return ret; | ||
158 | return ASN1_INTEGER_cmp(a->serialNumber, b->serialNumber); | ||
159 | } | ||
160 | |||
161 | |||
162 | /* Parse a URL and split it up into host, port and path components and whether | ||
163 | * it is SSL. | ||
164 | */ | ||
165 | |||
166 | int OCSP_parse_url(char *url, char **phost, char **pport, char **ppath, int *pssl) | ||
167 | { | ||
168 | char *p, *buf; | ||
169 | |||
170 | char *host, *port; | ||
171 | |||
172 | /* dup the buffer since we are going to mess with it */ | ||
173 | buf = BUF_strdup(url); | ||
174 | if (!buf) goto mem_err; | ||
175 | |||
176 | *phost = NULL; | ||
177 | *pport = NULL; | ||
178 | *ppath = NULL; | ||
179 | |||
180 | /* Check for initial colon */ | ||
181 | p = strchr(buf, ':'); | ||
182 | |||
183 | if (!p) goto parse_err; | ||
184 | |||
185 | *(p++) = '\0'; | ||
186 | |||
187 | if (!strcmp(buf, "http")) | ||
188 | { | ||
189 | *pssl = 0; | ||
190 | port = "80"; | ||
191 | } | ||
192 | else if (!strcmp(buf, "https")) | ||
193 | { | ||
194 | *pssl = 1; | ||
195 | port = "443"; | ||
196 | } | ||
197 | else | ||
198 | goto parse_err; | ||
199 | |||
200 | /* Check for double slash */ | ||
201 | if ((p[0] != '/') || (p[1] != '/')) | ||
202 | goto parse_err; | ||
203 | |||
204 | p += 2; | ||
205 | |||
206 | host = p; | ||
207 | |||
208 | /* Check for trailing part of path */ | ||
209 | |||
210 | p = strchr(p, '/'); | ||
211 | |||
212 | if (!p) | ||
213 | *ppath = BUF_strdup("/"); | ||
214 | else | ||
215 | { | ||
216 | *ppath = BUF_strdup(p); | ||
217 | /* Set start of path to 0 so hostname is valid */ | ||
218 | *p = '\0'; | ||
219 | } | ||
220 | |||
221 | if (!*ppath) goto mem_err; | ||
222 | |||
223 | /* Look for optional ':' for port number */ | ||
224 | if ((p = strchr(host, ':'))) | ||
225 | { | ||
226 | *p = 0; | ||
227 | port = p + 1; | ||
228 | } | ||
229 | else | ||
230 | { | ||
231 | /* Not found: set default port */ | ||
232 | if (*pssl) port = "443"; | ||
233 | else port = "80"; | ||
234 | } | ||
235 | |||
236 | *pport = BUF_strdup(port); | ||
237 | if (!*pport) goto mem_err; | ||
238 | |||
239 | *phost = BUF_strdup(host); | ||
240 | |||
241 | if (!*phost) goto mem_err; | ||
242 | |||
243 | OPENSSL_free(buf); | ||
244 | |||
245 | return 1; | ||
246 | |||
247 | mem_err: | ||
248 | OCSPerr(OCSP_F_OCSP_PARSE_URL, ERR_R_MALLOC_FAILURE); | ||
249 | goto err; | ||
250 | |||
251 | parse_err: | ||
252 | OCSPerr(OCSP_F_OCSP_PARSE_URL, OCSP_R_ERROR_PARSING_URL); | ||
253 | |||
254 | |||
255 | err: | ||
256 | if (*ppath) OPENSSL_free(*ppath); | ||
257 | if (*pport) OPENSSL_free(*pport); | ||
258 | if (*phost) OPENSSL_free(*phost); | ||
259 | return 0; | ||
260 | |||
261 | } | ||
diff --git a/src/lib/libcrypto/ocsp/ocsp_prn.c b/src/lib/libcrypto/ocsp/ocsp_prn.c new file mode 100644 index 0000000000..4b7bc28769 --- /dev/null +++ b/src/lib/libcrypto/ocsp/ocsp_prn.c | |||
@@ -0,0 +1,291 @@ | |||
1 | /* ocsp_prn.c */ | ||
2 | /* Written by Tom Titchener <Tom_Titchener@groove.net> for the OpenSSL | ||
3 | * project. */ | ||
4 | |||
5 | /* History: | ||
6 | This file was originally part of ocsp.c and was transfered to Richard | ||
7 | Levitte from CertCo by Kathy Weinhold in mid-spring 2000 to be included | ||
8 | in OpenSSL or released as a patch kit. */ | ||
9 | |||
10 | /* ==================================================================== | ||
11 | * Copyright (c) 1998-2000 The OpenSSL Project. All rights reserved. | ||
12 | * | ||
13 | * Redistribution and use in source and binary forms, with or without | ||
14 | * modification, are permitted provided that the following conditions | ||
15 | * are met: | ||
16 | * | ||
17 | * 1. Redistributions of source code must retain the above copyright | ||
18 | * notice, this list of conditions and the following disclaimer. | ||
19 | * | ||
20 | * 2. Redistributions in binary form must reproduce the above copyright | ||
21 | * notice, this list of conditions and the following disclaimer in | ||
22 | * the documentation and/or other materials provided with the | ||
23 | * distribution. | ||
24 | * | ||
25 | * 3. All advertising materials mentioning features or use of this | ||
26 | * software must display the following acknowledgment: | ||
27 | * "This product includes software developed by the OpenSSL Project | ||
28 | * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" | ||
29 | * | ||
30 | * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to | ||
31 | * endorse or promote products derived from this software without | ||
32 | * prior written permission. For written permission, please contact | ||
33 | * openssl-core@openssl.org. | ||
34 | * | ||
35 | * 5. Products derived from this software may not be called "OpenSSL" | ||
36 | * nor may "OpenSSL" appear in their names without prior written | ||
37 | * permission of the OpenSSL Project. | ||
38 | * | ||
39 | * 6. Redistributions of any form whatsoever must retain the following | ||
40 | * acknowledgment: | ||
41 | * "This product includes software developed by the OpenSSL Project | ||
42 | * for use in the OpenSSL Toolkit (http://www.openssl.org/)" | ||
43 | * | ||
44 | * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY | ||
45 | * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
46 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | ||
47 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR | ||
48 | * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
49 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
50 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
51 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
52 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
53 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
54 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED | ||
55 | * OF THE POSSIBILITY OF SUCH DAMAGE. | ||
56 | * ==================================================================== | ||
57 | * | ||
58 | * This product includes cryptographic software written by Eric Young | ||
59 | * (eay@cryptsoft.com). This product includes software written by Tim | ||
60 | * Hudson (tjh@cryptsoft.com). | ||
61 | * | ||
62 | */ | ||
63 | |||
64 | #include <openssl/bio.h> | ||
65 | #include <openssl/err.h> | ||
66 | #include <openssl/ocsp.h> | ||
67 | #include <openssl/pem.h> | ||
68 | |||
69 | static int ocsp_certid_print(BIO *bp, OCSP_CERTID* a, int indent) | ||
70 | { | ||
71 | BIO_printf(bp, "%*sCertificate ID:\n", indent, ""); | ||
72 | indent += 2; | ||
73 | BIO_printf(bp, "%*sHash Algorithm: ", indent, ""); | ||
74 | i2a_ASN1_OBJECT(bp, a->hashAlgorithm->algorithm); | ||
75 | BIO_printf(bp, "\n%*sIssuer Name Hash: ", indent, ""); | ||
76 | i2a_ASN1_STRING(bp, a->issuerNameHash, V_ASN1_OCTET_STRING); | ||
77 | BIO_printf(bp, "\n%*sIssuer Key Hash: ", indent, ""); | ||
78 | i2a_ASN1_STRING(bp, a->issuerKeyHash, V_ASN1_OCTET_STRING); | ||
79 | BIO_printf(bp, "\n%*sSerial Number: ", indent, ""); | ||
80 | i2a_ASN1_INTEGER(bp, a->serialNumber); | ||
81 | BIO_printf(bp, "\n"); | ||
82 | return 1; | ||
83 | } | ||
84 | |||
85 | typedef struct | ||
86 | { | ||
87 | long t; | ||
88 | char *m; | ||
89 | } OCSP_TBLSTR; | ||
90 | |||
91 | static char *table2string(long s, OCSP_TBLSTR *ts, int len) | ||
92 | { | ||
93 | OCSP_TBLSTR *p; | ||
94 | for (p=ts; p < ts + len; p++) | ||
95 | if (p->t == s) | ||
96 | return p->m; | ||
97 | return "(UNKNOWN)"; | ||
98 | } | ||
99 | |||
100 | char *OCSP_response_status_str(long s) | ||
101 | { | ||
102 | static OCSP_TBLSTR rstat_tbl[] = { | ||
103 | { OCSP_RESPONSE_STATUS_SUCCESSFUL, "successful" }, | ||
104 | { OCSP_RESPONSE_STATUS_MALFORMEDREQUEST, "malformedrequest" }, | ||
105 | { OCSP_RESPONSE_STATUS_INTERNALERROR, "internalerror" }, | ||
106 | { OCSP_RESPONSE_STATUS_TRYLATER, "trylater" }, | ||
107 | { OCSP_RESPONSE_STATUS_SIGREQUIRED, "sigrequired" }, | ||
108 | { OCSP_RESPONSE_STATUS_UNAUTHORIZED, "unauthorized" } }; | ||
109 | return table2string(s, rstat_tbl, 6); | ||
110 | } | ||
111 | |||
112 | char *OCSP_cert_status_str(long s) | ||
113 | { | ||
114 | static OCSP_TBLSTR cstat_tbl[] = { | ||
115 | { V_OCSP_CERTSTATUS_GOOD, "good" }, | ||
116 | { V_OCSP_CERTSTATUS_REVOKED, "revoked" }, | ||
117 | { V_OCSP_CERTSTATUS_UNKNOWN, "unknown" } }; | ||
118 | return table2string(s, cstat_tbl, 3); | ||
119 | } | ||
120 | |||
121 | char *OCSP_crl_reason_str(long s) | ||
122 | { | ||
123 | OCSP_TBLSTR reason_tbl[] = { | ||
124 | { OCSP_REVOKED_STATUS_UNSPECIFIED, "unspecified" }, | ||
125 | { OCSP_REVOKED_STATUS_KEYCOMPROMISE, "keyCompromise" }, | ||
126 | { OCSP_REVOKED_STATUS_CACOMPROMISE, "cACompromise" }, | ||
127 | { OCSP_REVOKED_STATUS_AFFILIATIONCHANGED, "affiliationChanged" }, | ||
128 | { OCSP_REVOKED_STATUS_SUPERSEDED, "superseded" }, | ||
129 | { OCSP_REVOKED_STATUS_CESSATIONOFOPERATION, "cessationOfOperation" }, | ||
130 | { OCSP_REVOKED_STATUS_CERTIFICATEHOLD, "certificateHold" }, | ||
131 | { OCSP_REVOKED_STATUS_REMOVEFROMCRL, "removeFromCRL" } }; | ||
132 | return table2string(s, reason_tbl, 8); | ||
133 | } | ||
134 | |||
135 | int OCSP_REQUEST_print(BIO *bp, OCSP_REQUEST* o, unsigned long flags) | ||
136 | { | ||
137 | int i; | ||
138 | long l; | ||
139 | OCSP_CERTID* cid = NULL; | ||
140 | OCSP_ONEREQ *one = NULL; | ||
141 | OCSP_REQINFO *inf = o->tbsRequest; | ||
142 | OCSP_SIGNATURE *sig = o->optionalSignature; | ||
143 | |||
144 | if (BIO_write(bp,"OCSP Request Data:\n",19) <= 0) goto err; | ||
145 | l=ASN1_INTEGER_get(inf->version); | ||
146 | if (BIO_printf(bp," Version: %lu (0x%lx)",l+1,l) <= 0) goto err; | ||
147 | if (inf->requestorName != NULL) | ||
148 | { | ||
149 | if (BIO_write(bp,"\n Requestor Name: ",21) <= 0) | ||
150 | goto err; | ||
151 | GENERAL_NAME_print(bp, inf->requestorName); | ||
152 | } | ||
153 | if (BIO_write(bp,"\n Requestor List:\n",21) <= 0) goto err; | ||
154 | for (i = 0; i < sk_OCSP_ONEREQ_num(inf->requestList); i++) | ||
155 | { | ||
156 | one = sk_OCSP_ONEREQ_value(inf->requestList, i); | ||
157 | cid = one->reqCert; | ||
158 | ocsp_certid_print(bp, cid, 8); | ||
159 | if (!X509V3_extensions_print(bp, | ||
160 | "Request Single Extensions", | ||
161 | one->singleRequestExtensions, flags, 8)) | ||
162 | goto err; | ||
163 | } | ||
164 | if (!X509V3_extensions_print(bp, "Request Extensions", | ||
165 | inf->requestExtensions, flags, 4)) | ||
166 | goto err; | ||
167 | if (sig) | ||
168 | { | ||
169 | X509_signature_print(bp, sig->signatureAlgorithm, sig->signature); | ||
170 | for (i=0; i<sk_X509_num(sig->certs); i++) | ||
171 | { | ||
172 | X509_print(bp, sk_X509_value(sig->certs,i)); | ||
173 | PEM_write_bio_X509(bp,sk_X509_value(sig->certs,i)); | ||
174 | } | ||
175 | } | ||
176 | return 1; | ||
177 | err: | ||
178 | return 0; | ||
179 | } | ||
180 | |||
181 | int OCSP_RESPONSE_print(BIO *bp, OCSP_RESPONSE* o, unsigned long flags) | ||
182 | { | ||
183 | int i, ret = 0; | ||
184 | long l; | ||
185 | unsigned char *p; | ||
186 | OCSP_CERTID *cid = NULL; | ||
187 | OCSP_BASICRESP *br = NULL; | ||
188 | OCSP_RESPID *rid = NULL; | ||
189 | OCSP_RESPDATA *rd = NULL; | ||
190 | OCSP_CERTSTATUS *cst = NULL; | ||
191 | OCSP_REVOKEDINFO *rev = NULL; | ||
192 | OCSP_SINGLERESP *single = NULL; | ||
193 | OCSP_RESPBYTES *rb = o->responseBytes; | ||
194 | |||
195 | if (BIO_puts(bp,"OCSP Response Data:\n") <= 0) goto err; | ||
196 | l=ASN1_ENUMERATED_get(o->responseStatus); | ||
197 | if (BIO_printf(bp," OCSP Response Status: %s (0x%x)\n", | ||
198 | OCSP_response_status_str(l), l) <= 0) goto err; | ||
199 | if (rb == NULL) return 1; | ||
200 | if (BIO_puts(bp," Response Type: ") <= 0) | ||
201 | goto err; | ||
202 | if(i2a_ASN1_OBJECT(bp, rb->responseType) <= 0) | ||
203 | goto err; | ||
204 | if (OBJ_obj2nid(rb->responseType) != NID_id_pkix_OCSP_basic) | ||
205 | { | ||
206 | BIO_puts(bp," (unknown response type)\n"); | ||
207 | return 1; | ||
208 | } | ||
209 | |||
210 | p = ASN1_STRING_data(rb->response); | ||
211 | i = ASN1_STRING_length(rb->response); | ||
212 | if (!(br = OCSP_response_get1_basic(o))) goto err; | ||
213 | rd = br->tbsResponseData; | ||
214 | l=ASN1_INTEGER_get(rd->version); | ||
215 | if (BIO_printf(bp,"\n Version: %lu (0x%lx)\n", | ||
216 | l+1,l) <= 0) goto err; | ||
217 | if (BIO_puts(bp," Responder Id: ") <= 0) goto err; | ||
218 | |||
219 | rid = rd->responderId; | ||
220 | switch (rid->type) | ||
221 | { | ||
222 | case V_OCSP_RESPID_NAME: | ||
223 | X509_NAME_print_ex(bp, rid->value.byName, 0, XN_FLAG_ONELINE); | ||
224 | break; | ||
225 | case V_OCSP_RESPID_KEY: | ||
226 | i2a_ASN1_STRING(bp, rid->value.byKey, V_ASN1_OCTET_STRING); | ||
227 | break; | ||
228 | } | ||
229 | |||
230 | if (BIO_printf(bp,"\n Produced At: ")<=0) goto err; | ||
231 | if (!ASN1_GENERALIZEDTIME_print(bp, rd->producedAt)) goto err; | ||
232 | if (BIO_printf(bp,"\n Responses:\n") <= 0) goto err; | ||
233 | for (i = 0; i < sk_OCSP_SINGLERESP_num(rd->responses); i++) | ||
234 | { | ||
235 | if (! sk_OCSP_SINGLERESP_value(rd->responses, i)) continue; | ||
236 | single = sk_OCSP_SINGLERESP_value(rd->responses, i); | ||
237 | cid = single->certId; | ||
238 | if(ocsp_certid_print(bp, cid, 4) <= 0) goto err; | ||
239 | cst = single->certStatus; | ||
240 | if (BIO_printf(bp," Cert Status: %s", | ||
241 | OCSP_cert_status_str(cst->type)) <= 0) | ||
242 | goto err; | ||
243 | if (cst->type == V_OCSP_CERTSTATUS_REVOKED) | ||
244 | { | ||
245 | rev = cst->value.revoked; | ||
246 | if (BIO_printf(bp, "\n Revocation Time: ") <= 0) | ||
247 | goto err; | ||
248 | if (!ASN1_GENERALIZEDTIME_print(bp, | ||
249 | rev->revocationTime)) | ||
250 | goto err; | ||
251 | if (rev->revocationReason) | ||
252 | { | ||
253 | l=ASN1_ENUMERATED_get(rev->revocationReason); | ||
254 | if (BIO_printf(bp, | ||
255 | "\n Revocation Reason: %s (0x%x)", | ||
256 | OCSP_crl_reason_str(l), l) <= 0) | ||
257 | goto err; | ||
258 | } | ||
259 | } | ||
260 | if (BIO_printf(bp,"\n This Update: ") <= 0) goto err; | ||
261 | if (!ASN1_GENERALIZEDTIME_print(bp, single->thisUpdate)) | ||
262 | goto err; | ||
263 | if (single->nextUpdate) | ||
264 | { | ||
265 | if (BIO_printf(bp,"\n Next Update: ") <= 0)goto err; | ||
266 | if (!ASN1_GENERALIZEDTIME_print(bp,single->nextUpdate)) | ||
267 | goto err; | ||
268 | } | ||
269 | if (!BIO_write(bp,"\n",1)) goto err; | ||
270 | if (!X509V3_extensions_print(bp, | ||
271 | "Response Single Extensions", | ||
272 | single->singleExtensions, flags, 8)) | ||
273 | goto err; | ||
274 | if (!BIO_write(bp,"\n",1)) goto err; | ||
275 | } | ||
276 | if (!X509V3_extensions_print(bp, "Response Extensions", | ||
277 | rd->responseExtensions, flags, 4)) | ||
278 | if(X509_signature_print(bp, br->signatureAlgorithm, br->signature) <= 0) | ||
279 | goto err; | ||
280 | |||
281 | for (i=0; i<sk_X509_num(br->certs); i++) | ||
282 | { | ||
283 | X509_print(bp, sk_X509_value(br->certs,i)); | ||
284 | PEM_write_bio_X509(bp,sk_X509_value(br->certs,i)); | ||
285 | } | ||
286 | |||
287 | ret = 1; | ||
288 | err: | ||
289 | OCSP_BASICRESP_free(br); | ||
290 | return ret; | ||
291 | } | ||
diff --git a/src/lib/libcrypto/ocsp/ocsp_srv.c b/src/lib/libcrypto/ocsp/ocsp_srv.c new file mode 100644 index 0000000000..fffa134e75 --- /dev/null +++ b/src/lib/libcrypto/ocsp/ocsp_srv.c | |||
@@ -0,0 +1,264 @@ | |||
1 | /* ocsp_srv.c */ | ||
2 | /* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL | ||
3 | * project 2001. | ||
4 | */ | ||
5 | /* ==================================================================== | ||
6 | * Copyright (c) 1998-2001 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 <stdio.h> | ||
60 | #include <cryptlib.h> | ||
61 | #include <openssl/objects.h> | ||
62 | #include <openssl/rand.h> | ||
63 | #include <openssl/x509.h> | ||
64 | #include <openssl/pem.h> | ||
65 | #include <openssl/x509v3.h> | ||
66 | #include <openssl/ocsp.h> | ||
67 | |||
68 | /* Utility functions related to sending OCSP responses and extracting | ||
69 | * relevant information from the request. | ||
70 | */ | ||
71 | |||
72 | int OCSP_request_onereq_count(OCSP_REQUEST *req) | ||
73 | { | ||
74 | return sk_OCSP_ONEREQ_num(req->tbsRequest->requestList); | ||
75 | } | ||
76 | |||
77 | OCSP_ONEREQ *OCSP_request_onereq_get0(OCSP_REQUEST *req, int i) | ||
78 | { | ||
79 | return sk_OCSP_ONEREQ_value(req->tbsRequest->requestList, i); | ||
80 | } | ||
81 | |||
82 | OCSP_CERTID *OCSP_onereq_get0_id(OCSP_ONEREQ *one) | ||
83 | { | ||
84 | return one->reqCert; | ||
85 | } | ||
86 | |||
87 | int OCSP_id_get0_info(ASN1_OCTET_STRING **piNameHash, ASN1_OBJECT **pmd, | ||
88 | ASN1_OCTET_STRING **pikeyHash, | ||
89 | ASN1_INTEGER **pserial, OCSP_CERTID *cid) | ||
90 | { | ||
91 | if (!cid) return 0; | ||
92 | if (pmd) *pmd = cid->hashAlgorithm->algorithm; | ||
93 | if(piNameHash) *piNameHash = cid->issuerNameHash; | ||
94 | if (pikeyHash) *pikeyHash = cid->issuerKeyHash; | ||
95 | if (pserial) *pserial = cid->serialNumber; | ||
96 | return 1; | ||
97 | } | ||
98 | |||
99 | int OCSP_request_is_signed(OCSP_REQUEST *req) | ||
100 | { | ||
101 | if(req->optionalSignature) return 1; | ||
102 | return 0; | ||
103 | } | ||
104 | |||
105 | /* Create an OCSP response and encode an optional basic response */ | ||
106 | OCSP_RESPONSE *OCSP_response_create(int status, OCSP_BASICRESP *bs) | ||
107 | { | ||
108 | OCSP_RESPONSE *rsp = NULL; | ||
109 | |||
110 | if (!(rsp = OCSP_RESPONSE_new())) goto err; | ||
111 | if (!(ASN1_ENUMERATED_set(rsp->responseStatus, status))) goto err; | ||
112 | if (!bs) return rsp; | ||
113 | if (!(rsp->responseBytes = OCSP_RESPBYTES_new())) goto err; | ||
114 | rsp->responseBytes->responseType = OBJ_nid2obj(NID_id_pkix_OCSP_basic); | ||
115 | if (!ASN1_item_pack(bs, ASN1_ITEM_rptr(OCSP_BASICRESP), &rsp->responseBytes->response)) | ||
116 | goto err; | ||
117 | return rsp; | ||
118 | err: | ||
119 | if (rsp) OCSP_RESPONSE_free(rsp); | ||
120 | return NULL; | ||
121 | } | ||
122 | |||
123 | |||
124 | OCSP_SINGLERESP *OCSP_basic_add1_status(OCSP_BASICRESP *rsp, | ||
125 | OCSP_CERTID *cid, | ||
126 | int status, int reason, | ||
127 | ASN1_TIME *revtime, | ||
128 | ASN1_TIME *thisupd, ASN1_TIME *nextupd) | ||
129 | { | ||
130 | OCSP_SINGLERESP *single = NULL; | ||
131 | OCSP_CERTSTATUS *cs; | ||
132 | OCSP_REVOKEDINFO *ri; | ||
133 | |||
134 | if(!rsp->tbsResponseData->responses && | ||
135 | !(rsp->tbsResponseData->responses = sk_OCSP_SINGLERESP_new_null())) | ||
136 | goto err; | ||
137 | |||
138 | if (!(single = OCSP_SINGLERESP_new())) | ||
139 | goto err; | ||
140 | |||
141 | |||
142 | |||
143 | if (!ASN1_TIME_to_generalizedtime(thisupd, &single->thisUpdate)) | ||
144 | goto err; | ||
145 | if (nextupd && | ||
146 | !ASN1_TIME_to_generalizedtime(nextupd, &single->nextUpdate)) | ||
147 | goto err; | ||
148 | |||
149 | OCSP_CERTID_free(single->certId); | ||
150 | |||
151 | if(!(single->certId = OCSP_CERTID_dup(cid))) | ||
152 | goto err; | ||
153 | |||
154 | cs = single->certStatus; | ||
155 | switch(cs->type = status) | ||
156 | { | ||
157 | case V_OCSP_CERTSTATUS_REVOKED: | ||
158 | if (!revtime) | ||
159 | { | ||
160 | OCSPerr(OCSP_F_OCSP_BASIC_ADD1_STATUS,OCSP_R_NO_REVOKED_TIME); | ||
161 | goto err; | ||
162 | } | ||
163 | if (!(cs->value.revoked = ri = OCSP_REVOKEDINFO_new())) goto err; | ||
164 | if (!ASN1_TIME_to_generalizedtime(revtime, &ri->revocationTime)) | ||
165 | goto err; | ||
166 | if (reason != OCSP_REVOKED_STATUS_NOSTATUS) | ||
167 | { | ||
168 | if (!(ri->revocationReason = ASN1_ENUMERATED_new())) | ||
169 | goto err; | ||
170 | if (!(ASN1_ENUMERATED_set(ri->revocationReason, | ||
171 | reason))) | ||
172 | goto err; | ||
173 | } | ||
174 | break; | ||
175 | |||
176 | case V_OCSP_CERTSTATUS_GOOD: | ||
177 | cs->value.good = ASN1_NULL_new(); | ||
178 | break; | ||
179 | |||
180 | case V_OCSP_CERTSTATUS_UNKNOWN: | ||
181 | cs->value.unknown = ASN1_NULL_new(); | ||
182 | break; | ||
183 | |||
184 | default: | ||
185 | goto err; | ||
186 | |||
187 | } | ||
188 | if (!(sk_OCSP_SINGLERESP_push(rsp->tbsResponseData->responses, single))) | ||
189 | goto err; | ||
190 | return single; | ||
191 | err: | ||
192 | OCSP_SINGLERESP_free(single); | ||
193 | return NULL; | ||
194 | } | ||
195 | |||
196 | /* Add a certificate to an OCSP request */ | ||
197 | |||
198 | int OCSP_basic_add1_cert(OCSP_BASICRESP *resp, X509 *cert) | ||
199 | { | ||
200 | if (!resp->certs && !(resp->certs = sk_X509_new_null())) | ||
201 | return 0; | ||
202 | |||
203 | if(!sk_X509_push(resp->certs, cert)) return 0; | ||
204 | CRYPTO_add(&cert->references, 1, CRYPTO_LOCK_X509); | ||
205 | return 1; | ||
206 | } | ||
207 | |||
208 | int OCSP_basic_sign(OCSP_BASICRESP *brsp, | ||
209 | X509 *signer, EVP_PKEY *key, const EVP_MD *dgst, | ||
210 | STACK_OF(X509) *certs, unsigned long flags) | ||
211 | { | ||
212 | int i; | ||
213 | OCSP_RESPID *rid; | ||
214 | |||
215 | if (!X509_check_private_key(signer, key)) | ||
216 | { | ||
217 | OCSPerr(OCSP_F_OCSP_BASIC_SIGN, OCSP_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE); | ||
218 | goto err; | ||
219 | } | ||
220 | |||
221 | if(!(flags & OCSP_NOCERTS)) | ||
222 | { | ||
223 | if(!OCSP_basic_add1_cert(brsp, signer)) | ||
224 | goto err; | ||
225 | for (i = 0; i < sk_X509_num(certs); i++) | ||
226 | { | ||
227 | X509 *tmpcert = sk_X509_value(certs, i); | ||
228 | if(!OCSP_basic_add1_cert(brsp, tmpcert)) | ||
229 | goto err; | ||
230 | } | ||
231 | } | ||
232 | |||
233 | rid = brsp->tbsResponseData->responderId; | ||
234 | if (flags & OCSP_RESPID_KEY) | ||
235 | { | ||
236 | unsigned char md[SHA_DIGEST_LENGTH]; | ||
237 | X509_pubkey_digest(signer, EVP_sha1(), md, NULL); | ||
238 | if (!(rid->value.byKey = ASN1_OCTET_STRING_new())) | ||
239 | goto err; | ||
240 | if (!(ASN1_OCTET_STRING_set(rid->value.byKey, md, SHA_DIGEST_LENGTH))) | ||
241 | goto err; | ||
242 | rid->type = V_OCSP_RESPID_KEY; | ||
243 | } | ||
244 | else | ||
245 | { | ||
246 | if (!X509_NAME_set(&rid->value.byName, | ||
247 | X509_get_subject_name(signer))) | ||
248 | goto err; | ||
249 | rid->type = V_OCSP_RESPID_NAME; | ||
250 | } | ||
251 | |||
252 | if (!(flags & OCSP_NOTIME) && | ||
253 | !X509_gmtime_adj(brsp->tbsResponseData->producedAt, 0)) | ||
254 | goto err; | ||
255 | |||
256 | /* Right now, I think that not doing double hashing is the right | ||
257 | thing. -- Richard Levitte */ | ||
258 | |||
259 | if (!OCSP_BASICRESP_sign(brsp, key, dgst, 0)) goto err; | ||
260 | |||
261 | return 1; | ||
262 | err: | ||
263 | return 0; | ||
264 | } | ||
diff --git a/src/lib/libcrypto/ocsp/ocsp_vfy.c b/src/lib/libcrypto/ocsp/ocsp_vfy.c new file mode 100644 index 0000000000..1f5fda7ca3 --- /dev/null +++ b/src/lib/libcrypto/ocsp/ocsp_vfy.c | |||
@@ -0,0 +1,444 @@ | |||
1 | /* ocsp_vfy.c */ | ||
2 | /* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL | ||
3 | * project 2000. | ||
4 | */ | ||
5 | /* ==================================================================== | ||
6 | * Copyright (c) 2000 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/ocsp.h> | ||
60 | #include <openssl/err.h> | ||
61 | #include <string.h> | ||
62 | |||
63 | static int ocsp_find_signer(X509 **psigner, OCSP_BASICRESP *bs, STACK_OF(X509) *certs, | ||
64 | X509_STORE *st, unsigned long flags); | ||
65 | static X509 *ocsp_find_signer_sk(STACK_OF(X509) *certs, OCSP_RESPID *id); | ||
66 | static int ocsp_check_issuer(OCSP_BASICRESP *bs, STACK_OF(X509) *chain, unsigned long flags); | ||
67 | static int ocsp_check_ids(STACK_OF(OCSP_SINGLERESP) *sresp, OCSP_CERTID **ret); | ||
68 | static int ocsp_match_issuerid(X509 *cert, OCSP_CERTID *cid, STACK_OF(OCSP_SINGLERESP) *sresp); | ||
69 | static int ocsp_check_delegated(X509 *x, int flags); | ||
70 | static int ocsp_req_find_signer(X509 **psigner, OCSP_REQUEST *req, X509_NAME *nm, STACK_OF(X509) *certs, | ||
71 | X509_STORE *st, unsigned long flags); | ||
72 | |||
73 | /* Verify a basic response message */ | ||
74 | |||
75 | int OCSP_basic_verify(OCSP_BASICRESP *bs, STACK_OF(X509) *certs, | ||
76 | X509_STORE *st, unsigned long flags) | ||
77 | { | ||
78 | X509 *signer, *x; | ||
79 | STACK_OF(X509) *chain = NULL; | ||
80 | X509_STORE_CTX ctx; | ||
81 | int i, ret = 0; | ||
82 | ret = ocsp_find_signer(&signer, bs, certs, st, flags); | ||
83 | if (!ret) | ||
84 | { | ||
85 | OCSPerr(OCSP_F_OCSP_BASIC_VERIFY, OCSP_R_SIGNER_CERTIFICATE_NOT_FOUND); | ||
86 | goto end; | ||
87 | } | ||
88 | if ((ret == 2) && (flags & OCSP_TRUSTOTHER)) | ||
89 | flags |= OCSP_NOVERIFY; | ||
90 | if (!(flags & OCSP_NOSIGS)) | ||
91 | { | ||
92 | EVP_PKEY *skey; | ||
93 | skey = X509_get_pubkey(signer); | ||
94 | ret = OCSP_BASICRESP_verify(bs, skey, 0); | ||
95 | EVP_PKEY_free(skey); | ||
96 | if(ret <= 0) | ||
97 | { | ||
98 | OCSPerr(OCSP_F_OCSP_BASIC_VERIFY, OCSP_R_SIGNATURE_FAILURE); | ||
99 | goto end; | ||
100 | } | ||
101 | } | ||
102 | if (!(flags & OCSP_NOVERIFY)) | ||
103 | { | ||
104 | int init_res; | ||
105 | if(flags & OCSP_NOCHAIN) | ||
106 | init_res = X509_STORE_CTX_init(&ctx, st, signer, NULL); | ||
107 | else | ||
108 | init_res = X509_STORE_CTX_init(&ctx, st, signer, bs->certs); | ||
109 | if(!init_res) | ||
110 | { | ||
111 | OCSPerr(OCSP_F_OCSP_BASIC_VERIFY,ERR_R_X509_LIB); | ||
112 | goto end; | ||
113 | } | ||
114 | |||
115 | X509_STORE_CTX_set_purpose(&ctx, X509_PURPOSE_OCSP_HELPER); | ||
116 | ret = X509_verify_cert(&ctx); | ||
117 | chain = X509_STORE_CTX_get1_chain(&ctx); | ||
118 | X509_STORE_CTX_cleanup(&ctx); | ||
119 | if (ret <= 0) | ||
120 | { | ||
121 | i = X509_STORE_CTX_get_error(&ctx); | ||
122 | OCSPerr(OCSP_F_OCSP_BASIC_VERIFY,OCSP_R_CERTIFICATE_VERIFY_ERROR); | ||
123 | ERR_add_error_data(2, "Verify error:", | ||
124 | X509_verify_cert_error_string(i)); | ||
125 | goto end; | ||
126 | } | ||
127 | if(flags & OCSP_NOCHECKS) | ||
128 | { | ||
129 | ret = 1; | ||
130 | goto end; | ||
131 | } | ||
132 | /* At this point we have a valid certificate chain | ||
133 | * need to verify it against the OCSP issuer criteria. | ||
134 | */ | ||
135 | ret = ocsp_check_issuer(bs, chain, flags); | ||
136 | |||
137 | /* If fatal error or valid match then finish */ | ||
138 | if (ret != 0) goto end; | ||
139 | |||
140 | /* Easy case: explicitly trusted. Get root CA and | ||
141 | * check for explicit trust | ||
142 | */ | ||
143 | if(flags & OCSP_NOEXPLICIT) goto end; | ||
144 | |||
145 | x = sk_X509_value(chain, sk_X509_num(chain) - 1); | ||
146 | if(X509_check_trust(x, NID_OCSP_sign, 0) != X509_TRUST_TRUSTED) | ||
147 | { | ||
148 | OCSPerr(OCSP_F_OCSP_BASIC_VERIFY,OCSP_R_ROOT_CA_NOT_TRUSTED); | ||
149 | goto end; | ||
150 | } | ||
151 | ret = 1; | ||
152 | } | ||
153 | |||
154 | |||
155 | |||
156 | end: | ||
157 | if(chain) sk_X509_pop_free(chain, X509_free); | ||
158 | return ret; | ||
159 | } | ||
160 | |||
161 | |||
162 | static int ocsp_find_signer(X509 **psigner, OCSP_BASICRESP *bs, STACK_OF(X509) *certs, | ||
163 | X509_STORE *st, unsigned long flags) | ||
164 | { | ||
165 | X509 *signer; | ||
166 | OCSP_RESPID *rid = bs->tbsResponseData->responderId; | ||
167 | if ((signer = ocsp_find_signer_sk(certs, rid))) | ||
168 | { | ||
169 | *psigner = signer; | ||
170 | return 2; | ||
171 | } | ||
172 | if(!(flags & OCSP_NOINTERN) && | ||
173 | (signer = ocsp_find_signer_sk(bs->certs, rid))) | ||
174 | { | ||
175 | *psigner = signer; | ||
176 | return 1; | ||
177 | } | ||
178 | /* Maybe lookup from store if by subject name */ | ||
179 | |||
180 | *psigner = NULL; | ||
181 | return 0; | ||
182 | } | ||
183 | |||
184 | |||
185 | static X509 *ocsp_find_signer_sk(STACK_OF(X509) *certs, OCSP_RESPID *id) | ||
186 | { | ||
187 | int i; | ||
188 | unsigned char tmphash[SHA_DIGEST_LENGTH], *keyhash; | ||
189 | X509 *x; | ||
190 | |||
191 | /* Easy if lookup by name */ | ||
192 | if (id->type == V_OCSP_RESPID_NAME) | ||
193 | return X509_find_by_subject(certs, id->value.byName); | ||
194 | |||
195 | /* Lookup by key hash */ | ||
196 | |||
197 | /* If key hash isn't SHA1 length then forget it */ | ||
198 | if (id->value.byKey->length != SHA_DIGEST_LENGTH) return NULL; | ||
199 | keyhash = id->value.byKey->data; | ||
200 | /* Calculate hash of each key and compare */ | ||
201 | for (i = 0; i < sk_X509_num(certs); i++) | ||
202 | { | ||
203 | x = sk_X509_value(certs, i); | ||
204 | X509_pubkey_digest(x, EVP_sha1(), tmphash, NULL); | ||
205 | if(!memcmp(keyhash, tmphash, SHA_DIGEST_LENGTH)) | ||
206 | return x; | ||
207 | } | ||
208 | return NULL; | ||
209 | } | ||
210 | |||
211 | |||
212 | static int ocsp_check_issuer(OCSP_BASICRESP *bs, STACK_OF(X509) *chain, unsigned long flags) | ||
213 | { | ||
214 | STACK_OF(OCSP_SINGLERESP) *sresp; | ||
215 | X509 *signer, *sca; | ||
216 | OCSP_CERTID *caid = NULL; | ||
217 | int i; | ||
218 | sresp = bs->tbsResponseData->responses; | ||
219 | |||
220 | if (sk_X509_num(chain) <= 0) | ||
221 | { | ||
222 | OCSPerr(OCSP_F_OCSP_CHECK_ISSUER, OCSP_R_NO_CERTIFICATES_IN_CHAIN); | ||
223 | return -1; | ||
224 | } | ||
225 | |||
226 | /* See if the issuer IDs match. */ | ||
227 | i = ocsp_check_ids(sresp, &caid); | ||
228 | |||
229 | /* If ID mismatch or other error then return */ | ||
230 | if (i <= 0) return i; | ||
231 | |||
232 | signer = sk_X509_value(chain, 0); | ||
233 | /* Check to see if OCSP responder CA matches request CA */ | ||
234 | if (sk_X509_num(chain) > 1) | ||
235 | { | ||
236 | sca = sk_X509_value(chain, 1); | ||
237 | i = ocsp_match_issuerid(sca, caid, sresp); | ||
238 | if (i < 0) return i; | ||
239 | if (i) | ||
240 | { | ||
241 | /* We have a match, if extensions OK then success */ | ||
242 | if (ocsp_check_delegated(signer, flags)) return 1; | ||
243 | return 0; | ||
244 | } | ||
245 | } | ||
246 | |||
247 | /* Otherwise check if OCSP request signed directly by request CA */ | ||
248 | return ocsp_match_issuerid(signer, caid, sresp); | ||
249 | } | ||
250 | |||
251 | |||
252 | /* Check the issuer certificate IDs for equality. If there is a mismatch with the same | ||
253 | * algorithm then there's no point trying to match any certificates against the issuer. | ||
254 | * If the issuer IDs all match then we just need to check equality against one of them. | ||
255 | */ | ||
256 | |||
257 | static int ocsp_check_ids(STACK_OF(OCSP_SINGLERESP) *sresp, OCSP_CERTID **ret) | ||
258 | { | ||
259 | OCSP_CERTID *tmpid, *cid; | ||
260 | int i, idcount; | ||
261 | |||
262 | idcount = sk_OCSP_SINGLERESP_num(sresp); | ||
263 | if (idcount <= 0) | ||
264 | { | ||
265 | OCSPerr(OCSP_F_OCSP_CHECK_IDS, OCSP_R_RESPONSE_CONTAINS_NO_REVOCATION_DATA); | ||
266 | return -1; | ||
267 | } | ||
268 | |||
269 | cid = sk_OCSP_SINGLERESP_value(sresp, 0)->certId; | ||
270 | |||
271 | *ret = NULL; | ||
272 | |||
273 | for (i = 1; i < idcount; i++) | ||
274 | { | ||
275 | tmpid = sk_OCSP_SINGLERESP_value(sresp, 0)->certId; | ||
276 | /* Check to see if IDs match */ | ||
277 | if (OCSP_id_issuer_cmp(cid, tmpid)) | ||
278 | { | ||
279 | /* If algoritm mismatch let caller deal with it */ | ||
280 | if (OBJ_cmp(tmpid->hashAlgorithm->algorithm, | ||
281 | cid->hashAlgorithm->algorithm)) | ||
282 | return 2; | ||
283 | /* Else mismatch */ | ||
284 | return 0; | ||
285 | } | ||
286 | } | ||
287 | |||
288 | /* All IDs match: only need to check one ID */ | ||
289 | *ret = cid; | ||
290 | return 1; | ||
291 | } | ||
292 | |||
293 | |||
294 | static int ocsp_match_issuerid(X509 *cert, OCSP_CERTID *cid, | ||
295 | STACK_OF(OCSP_SINGLERESP) *sresp) | ||
296 | { | ||
297 | /* If only one ID to match then do it */ | ||
298 | if(cid) | ||
299 | { | ||
300 | const EVP_MD *dgst; | ||
301 | X509_NAME *iname; | ||
302 | int mdlen; | ||
303 | unsigned char md[EVP_MAX_MD_SIZE]; | ||
304 | if (!(dgst = EVP_get_digestbyobj(cid->hashAlgorithm->algorithm))) | ||
305 | { | ||
306 | OCSPerr(OCSP_F_OCSP_MATCH_ISSUERID, OCSP_R_UNKNOWN_MESSAGE_DIGEST); | ||
307 | return -1; | ||
308 | } | ||
309 | |||
310 | mdlen = EVP_MD_size(dgst); | ||
311 | if ((cid->issuerNameHash->length != mdlen) || | ||
312 | (cid->issuerKeyHash->length != mdlen)) | ||
313 | return 0; | ||
314 | iname = X509_get_subject_name(cert); | ||
315 | if (!X509_NAME_digest(iname, dgst, md, NULL)) | ||
316 | return -1; | ||
317 | if (memcmp(md, cid->issuerNameHash->data, mdlen)) | ||
318 | return 0; | ||
319 | X509_pubkey_digest(cert, EVP_sha1(), md, NULL); | ||
320 | if (memcmp(md, cid->issuerKeyHash->data, mdlen)) | ||
321 | return 0; | ||
322 | |||
323 | return 1; | ||
324 | |||
325 | } | ||
326 | else | ||
327 | { | ||
328 | /* We have to match the whole lot */ | ||
329 | int i, ret; | ||
330 | OCSP_CERTID *tmpid; | ||
331 | for (i = 0; i < sk_OCSP_SINGLERESP_num(sresp); i++) | ||
332 | { | ||
333 | tmpid = sk_OCSP_SINGLERESP_value(sresp, 0)->certId; | ||
334 | ret = ocsp_match_issuerid(cert, tmpid, NULL); | ||
335 | if (ret <= 0) return ret; | ||
336 | } | ||
337 | return 1; | ||
338 | } | ||
339 | |||
340 | } | ||
341 | |||
342 | static int ocsp_check_delegated(X509 *x, int flags) | ||
343 | { | ||
344 | X509_check_purpose(x, -1, 0); | ||
345 | if ((x->ex_flags & EXFLAG_XKUSAGE) && | ||
346 | (x->ex_xkusage & XKU_OCSP_SIGN)) | ||
347 | return 1; | ||
348 | OCSPerr(OCSP_F_OCSP_CHECK_DELEGATED, OCSP_R_MISSING_OCSPSIGNING_USAGE); | ||
349 | return 0; | ||
350 | } | ||
351 | |||
352 | /* Verify an OCSP request. This is fortunately much easier than OCSP | ||
353 | * response verify. Just find the signers certificate and verify it | ||
354 | * against a given trust value. | ||
355 | */ | ||
356 | |||
357 | int OCSP_request_verify(OCSP_REQUEST *req, STACK_OF(X509) *certs, X509_STORE *store, unsigned long flags) | ||
358 | { | ||
359 | X509 *signer; | ||
360 | X509_NAME *nm; | ||
361 | GENERAL_NAME *gen; | ||
362 | int ret; | ||
363 | X509_STORE_CTX ctx; | ||
364 | if (!req->optionalSignature) | ||
365 | { | ||
366 | OCSPerr(OCSP_F_OCSP_REQUEST_VERIFY, OCSP_R_REQUEST_NOT_SIGNED); | ||
367 | return 0; | ||
368 | } | ||
369 | gen = req->tbsRequest->requestorName; | ||
370 | if (gen->type != GEN_DIRNAME) | ||
371 | { | ||
372 | OCSPerr(OCSP_F_OCSP_REQUEST_VERIFY, OCSP_R_UNSUPPORTED_REQUESTORNAME_TYPE); | ||
373 | return 0; | ||
374 | } | ||
375 | nm = gen->d.directoryName; | ||
376 | ret = ocsp_req_find_signer(&signer, req, nm, certs, store, flags); | ||
377 | if (ret <= 0) | ||
378 | { | ||
379 | OCSPerr(OCSP_F_OCSP_REQUEST_VERIFY, OCSP_R_SIGNER_CERTIFICATE_NOT_FOUND); | ||
380 | return 0; | ||
381 | } | ||
382 | if ((ret == 2) && (flags & OCSP_TRUSTOTHER)) | ||
383 | flags |= OCSP_NOVERIFY; | ||
384 | if (!(flags & OCSP_NOSIGS)) | ||
385 | { | ||
386 | EVP_PKEY *skey; | ||
387 | skey = X509_get_pubkey(signer); | ||
388 | ret = OCSP_REQUEST_verify(req, skey); | ||
389 | EVP_PKEY_free(skey); | ||
390 | if(ret <= 0) | ||
391 | { | ||
392 | OCSPerr(OCSP_F_OCSP_REQUEST_VERIFY, OCSP_R_SIGNATURE_FAILURE); | ||
393 | return 0; | ||
394 | } | ||
395 | } | ||
396 | if (!(flags & OCSP_NOVERIFY)) | ||
397 | { | ||
398 | int init_res; | ||
399 | if(flags & OCSP_NOCHAIN) | ||
400 | init_res = X509_STORE_CTX_init(&ctx, store, signer, NULL); | ||
401 | else | ||
402 | init_res = X509_STORE_CTX_init(&ctx, store, signer, | ||
403 | req->optionalSignature->certs); | ||
404 | if(!init_res) | ||
405 | { | ||
406 | OCSPerr(OCSP_F_OCSP_REQUEST_VERIFY,ERR_R_X509_LIB); | ||
407 | return 0; | ||
408 | } | ||
409 | |||
410 | X509_STORE_CTX_set_purpose(&ctx, X509_PURPOSE_OCSP_HELPER); | ||
411 | X509_STORE_CTX_set_trust(&ctx, X509_TRUST_OCSP_REQUEST); | ||
412 | ret = X509_verify_cert(&ctx); | ||
413 | X509_STORE_CTX_cleanup(&ctx); | ||
414 | if (ret <= 0) | ||
415 | { | ||
416 | ret = X509_STORE_CTX_get_error(&ctx); | ||
417 | OCSPerr(OCSP_F_OCSP_REQUEST_VERIFY,OCSP_R_CERTIFICATE_VERIFY_ERROR); | ||
418 | ERR_add_error_data(2, "Verify error:", | ||
419 | X509_verify_cert_error_string(ret)); | ||
420 | return 0; | ||
421 | } | ||
422 | } | ||
423 | return 1; | ||
424 | } | ||
425 | |||
426 | static int ocsp_req_find_signer(X509 **psigner, OCSP_REQUEST *req, X509_NAME *nm, STACK_OF(X509) *certs, | ||
427 | X509_STORE *st, unsigned long flags) | ||
428 | { | ||
429 | X509 *signer; | ||
430 | if(!(flags & OCSP_NOINTERN)) | ||
431 | { | ||
432 | signer = X509_find_by_subject(req->optionalSignature->certs, nm); | ||
433 | *psigner = signer; | ||
434 | return 1; | ||
435 | } | ||
436 | |||
437 | signer = X509_find_by_subject(certs, nm); | ||
438 | if (signer) | ||
439 | { | ||
440 | *psigner = signer; | ||
441 | return 2; | ||
442 | } | ||
443 | return 0; | ||
444 | } | ||
diff --git a/src/lib/libcrypto/opensslv.h b/src/lib/libcrypto/opensslv.h new file mode 100644 index 0000000000..b841347f05 --- /dev/null +++ b/src/lib/libcrypto/opensslv.h | |||
@@ -0,0 +1,21 @@ | |||
1 | #ifndef HEADER_OPENSSLV_H | ||
2 | #define HEADER_OPENSSLV_H | ||
3 | |||
4 | /* Numeric release version identifier: | ||
5 | * MMNNFFRBB: major minor fix final beta/patch | ||
6 | * For example: | ||
7 | * 0.9.3-dev 0x00903000 | ||
8 | * 0.9.3beta1 0x00903001 | ||
9 | * 0.9.3beta2-dev 0x00903002 | ||
10 | * 0.9.3beta2 0x00903002 | ||
11 | * 0.9.3 0x00903100 | ||
12 | * 0.9.3a 0x00903101 | ||
13 | * 0.9.4 0x00904100 | ||
14 | * 1.2.3z 0x1020311a | ||
15 | * (Prior to 0.9.3-dev a different scheme was used: 0.9.2b is 0x0922.) | ||
16 | */ | ||
17 | #define OPENSSL_VERSION_NUMBER 0x00904100L | ||
18 | #define OPENSSL_VERSION_TEXT "OpenSSL 0.9.4 09 Aug 1999" | ||
19 | #define OPENSSL_VERSION_PTEXT " part of " OPENSSL_VERSION_TEXT | ||
20 | |||
21 | #endif /* HEADER_OPENSSLV_H */ | ||
diff --git a/src/lib/libcrypto/ossl_typ.h b/src/lib/libcrypto/ossl_typ.h new file mode 100644 index 0000000000..6bd42aee4d --- /dev/null +++ b/src/lib/libcrypto/ossl_typ.h | |||
@@ -0,0 +1,120 @@ | |||
1 | /* ==================================================================== | ||
2 | * Copyright (c) 1998-2001 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 | * openssl-core@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 | #ifndef HEADER_OPENSSL_TYPES_H | ||
56 | #define HEADER_OPENSSL_TYPES_H | ||
57 | |||
58 | #ifdef NO_ASN1_TYPEDEFS | ||
59 | #define ASN1_INTEGER ASN1_STRING | ||
60 | #define ASN1_ENUMERATED ASN1_STRING | ||
61 | #define ASN1_BIT_STRING ASN1_STRING | ||
62 | #define ASN1_OCTET_STRING ASN1_STRING | ||
63 | #define ASN1_PRINTABLESTRING ASN1_STRING | ||
64 | #define ASN1_T61STRING ASN1_STRING | ||
65 | #define ASN1_IA5STRING ASN1_STRING | ||
66 | #define ASN1_UTCTIME ASN1_STRING | ||
67 | #define ASN1_GENERALIZEDTIME ASN1_STRING | ||
68 | #define ASN1_TIME ASN1_STRING | ||
69 | #define ASN1_GENERALSTRING ASN1_STRING | ||
70 | #define ASN1_UNIVERSALSTRING ASN1_STRING | ||
71 | #define ASN1_BMPSTRING ASN1_STRING | ||
72 | #define ASN1_VISIBLESTRING ASN1_STRING | ||
73 | #define ASN1_UTF8STRING ASN1_STRING | ||
74 | #define ASN1_BOOLEAN int | ||
75 | #define ASN1_NULL int | ||
76 | #else | ||
77 | typedef struct asn1_string_st ASN1_INTEGER; | ||
78 | typedef struct asn1_string_st ASN1_ENUMERATED; | ||
79 | typedef struct asn1_string_st ASN1_BIT_STRING; | ||
80 | typedef struct asn1_string_st ASN1_OCTET_STRING; | ||
81 | typedef struct asn1_string_st ASN1_PRINTABLESTRING; | ||
82 | typedef struct asn1_string_st ASN1_T61STRING; | ||
83 | typedef struct asn1_string_st ASN1_IA5STRING; | ||
84 | typedef struct asn1_string_st ASN1_GENERALSTRING; | ||
85 | typedef struct asn1_string_st ASN1_UNIVERSALSTRING; | ||
86 | typedef struct asn1_string_st ASN1_BMPSTRING; | ||
87 | typedef struct asn1_string_st ASN1_UTCTIME; | ||
88 | typedef struct asn1_string_st ASN1_TIME; | ||
89 | typedef struct asn1_string_st ASN1_GENERALIZEDTIME; | ||
90 | typedef struct asn1_string_st ASN1_VISIBLESTRING; | ||
91 | typedef struct asn1_string_st ASN1_UTF8STRING; | ||
92 | typedef int ASN1_BOOLEAN; | ||
93 | typedef int ASN1_NULL; | ||
94 | #endif | ||
95 | |||
96 | #ifdef OPENSSL_SYS_WIN32 | ||
97 | #undef X509_NAME | ||
98 | #undef PKCS7_ISSUER_AND_SERIAL | ||
99 | #endif | ||
100 | |||
101 | typedef struct evp_cipher_st EVP_CIPHER; | ||
102 | typedef struct evp_cipher_ctx_st EVP_CIPHER_CTX; | ||
103 | typedef struct env_md_st EVP_MD; | ||
104 | typedef struct env_md_ctx_st EVP_MD_CTX; | ||
105 | typedef struct evp_pkey_st EVP_PKEY; | ||
106 | |||
107 | typedef struct x509_st X509; | ||
108 | typedef struct X509_algor_st X509_ALGOR; | ||
109 | typedef struct X509_crl_st X509_CRL; | ||
110 | typedef struct X509_name_st X509_NAME; | ||
111 | typedef struct x509_store_st X509_STORE; | ||
112 | typedef struct x509_store_ctx_st X509_STORE_CTX; | ||
113 | |||
114 | typedef struct engine_st ENGINE; | ||
115 | |||
116 | /* If placed in pkcs12.h, we end up with a circular depency with pkcs7.h */ | ||
117 | #define DECLARE_PKCS12_STACK_OF(type) /* Nothing */ | ||
118 | #define IMPLEMENT_PKCS12_STACK_OF(type) /* Nothing */ | ||
119 | |||
120 | #endif /* def HEADER_OPENSSL_TYPES_H */ | ||
diff --git a/src/lib/libcrypto/pem/pem2.h b/src/lib/libcrypto/pem/pem2.h new file mode 100644 index 0000000000..4a016aacd2 --- /dev/null +++ b/src/lib/libcrypto/pem/pem2.h | |||
@@ -0,0 +1,60 @@ | |||
1 | /* ==================================================================== | ||
2 | * Copyright (c) 1999 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 | /* | ||
56 | * This header only exists to break a circular dependency between pem and err | ||
57 | * Ben 30 Jan 1999. | ||
58 | */ | ||
59 | |||
60 | void ERR_load_PEM_strings(void); | ||
diff --git a/src/lib/libcrypto/pem/pem_oth.c b/src/lib/libcrypto/pem/pem_oth.c new file mode 100644 index 0000000000..8d9064ea7c --- /dev/null +++ b/src/lib/libcrypto/pem/pem_oth.c | |||
@@ -0,0 +1,85 @@ | |||
1 | /* crypto/pem/pem_oth.c */ | ||
2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) | ||
3 | * All rights reserved. | ||
4 | * | ||
5 | * This package is an SSL implementation written | ||
6 | * by Eric Young (eay@cryptsoft.com). | ||
7 | * The implementation was written so as to conform with Netscapes SSL. | ||
8 | * | ||
9 | * This library is free for commercial and non-commercial use as long as | ||
10 | * the following conditions are aheared to. The following conditions | ||
11 | * apply to all code found in this distribution, be it the RC4, RSA, | ||
12 | * lhash, DES, etc., code; not just the SSL code. The SSL documentation | ||
13 | * included with this distribution is covered by the same copyright terms | ||
14 | * except that the holder is Tim Hudson (tjh@cryptsoft.com). | ||
15 | * | ||
16 | * Copyright remains Eric Young's, and as such any Copyright notices in | ||
17 | * the code are not to be removed. | ||
18 | * If this package is used in a product, Eric Young should be given attribution | ||
19 | * as the author of the parts of the library used. | ||
20 | * This can be in the form of a textual message at program startup or | ||
21 | * in documentation (online or textual) provided with the package. | ||
22 | * | ||
23 | * Redistribution and use in source and binary forms, with or without | ||
24 | * modification, are permitted provided that the following conditions | ||
25 | * are met: | ||
26 | * 1. Redistributions of source code must retain the copyright | ||
27 | * notice, this list of conditions and the following disclaimer. | ||
28 | * 2. Redistributions in binary form must reproduce the above copyright | ||
29 | * notice, this list of conditions and the following disclaimer in the | ||
30 | * documentation and/or other materials provided with the distribution. | ||
31 | * 3. All advertising materials mentioning features or use of this software | ||
32 | * must display the following acknowledgement: | ||
33 | * "This product includes cryptographic software written by | ||
34 | * Eric Young (eay@cryptsoft.com)" | ||
35 | * The word 'cryptographic' can be left out if the rouines from the library | ||
36 | * being used are not cryptographic related :-). | ||
37 | * 4. If you include any Windows specific code (or a derivative thereof) from | ||
38 | * the apps directory (application code) you must include an acknowledgement: | ||
39 | * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" | ||
40 | * | ||
41 | * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND | ||
42 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
43 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
44 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | ||
45 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
46 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
47 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
48 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
49 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
50 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
51 | * SUCH DAMAGE. | ||
52 | * | ||
53 | * The licence and distribution terms for any publically available version or | ||
54 | * derivative of this code cannot be changed. i.e. this code cannot simply be | ||
55 | * copied and put under another distribution licence | ||
56 | * [including the GNU Public Licence.] | ||
57 | */ | ||
58 | |||
59 | #include <stdio.h> | ||
60 | #include "cryptlib.h" | ||
61 | #include <openssl/buffer.h> | ||
62 | #include <openssl/objects.h> | ||
63 | #include <openssl/evp.h> | ||
64 | #include <openssl/rand.h> | ||
65 | #include <openssl/x509.h> | ||
66 | #include <openssl/pem.h> | ||
67 | |||
68 | /* Handle 'other' PEMs: not private keys */ | ||
69 | |||
70 | char *PEM_ASN1_read_bio(char *(*d2i)(), const char *name, BIO *bp, char **x, | ||
71 | pem_password_cb *cb, void *u) | ||
72 | { | ||
73 | unsigned char *p=NULL,*data=NULL; | ||
74 | long len; | ||
75 | char *ret=NULL; | ||
76 | |||
77 | if (!PEM_bytes_read_bio(&data, &len, NULL, name, bp, cb, u)) | ||
78 | return NULL; | ||
79 | p = data; | ||
80 | ret=d2i(x,&p,len); | ||
81 | if (ret == NULL) | ||
82 | PEMerr(PEM_F_PEM_ASN1_READ_BIO,ERR_R_ASN1_LIB); | ||
83 | OPENSSL_free(data); | ||
84 | return(ret); | ||
85 | } | ||
diff --git a/src/lib/libcrypto/pem/pem_pk8.c b/src/lib/libcrypto/pem/pem_pk8.c new file mode 100644 index 0000000000..f44182ffb5 --- /dev/null +++ b/src/lib/libcrypto/pem/pem_pk8.c | |||
@@ -0,0 +1,243 @@ | |||
1 | /* crypto/pem/pem_pkey.c */ | ||
2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) | ||
3 | * All rights reserved. | ||
4 | * | ||
5 | * This package is an SSL implementation written | ||
6 | * by Eric Young (eay@cryptsoft.com). | ||
7 | * The implementation was written so as to conform with Netscapes SSL. | ||
8 | * | ||
9 | * This library is free for commercial and non-commercial use as long as | ||
10 | * the following conditions are aheared to. The following conditions | ||
11 | * apply to all code found in this distribution, be it the RC4, RSA, | ||
12 | * lhash, DES, etc., code; not just the SSL code. The SSL documentation | ||
13 | * included with this distribution is covered by the same copyright terms | ||
14 | * except that the holder is Tim Hudson (tjh@cryptsoft.com). | ||
15 | * | ||
16 | * Copyright remains Eric Young's, and as such any Copyright notices in | ||
17 | * the code are not to be removed. | ||
18 | * If this package is used in a product, Eric Young should be given attribution | ||
19 | * as the author of the parts of the library used. | ||
20 | * This can be in the form of a textual message at program startup or | ||
21 | * in documentation (online or textual) provided with the package. | ||
22 | * | ||
23 | * Redistribution and use in source and binary forms, with or without | ||
24 | * modification, are permitted provided that the following conditions | ||
25 | * are met: | ||
26 | * 1. Redistributions of source code must retain the copyright | ||
27 | * notice, this list of conditions and the following disclaimer. | ||
28 | * 2. Redistributions in binary form must reproduce the above copyright | ||
29 | * notice, this list of conditions and the following disclaimer in the | ||
30 | * documentation and/or other materials provided with the distribution. | ||
31 | * 3. All advertising materials mentioning features or use of this software | ||
32 | * must display the following acknowledgement: | ||
33 | * "This product includes cryptographic software written by | ||
34 | * Eric Young (eay@cryptsoft.com)" | ||
35 | * The word 'cryptographic' can be left out if the rouines from the library | ||
36 | * being used are not cryptographic related :-). | ||
37 | * 4. If you include any Windows specific code (or a derivative thereof) from | ||
38 | * the apps directory (application code) you must include an acknowledgement: | ||
39 | * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" | ||
40 | * | ||
41 | * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND | ||
42 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
43 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
44 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | ||
45 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
46 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
47 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
48 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
49 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
50 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
51 | * SUCH DAMAGE. | ||
52 | * | ||
53 | * The licence and distribution terms for any publically available version or | ||
54 | * derivative of this code cannot be changed. i.e. this code cannot simply be | ||
55 | * copied and put under another distribution licence | ||
56 | * [including the GNU Public Licence.] | ||
57 | */ | ||
58 | |||
59 | #include <stdio.h> | ||
60 | #include "cryptlib.h" | ||
61 | #include <openssl/buffer.h> | ||
62 | #include <openssl/objects.h> | ||
63 | #include <openssl/evp.h> | ||
64 | #include <openssl/rand.h> | ||
65 | #include <openssl/x509.h> | ||
66 | #include <openssl/pkcs12.h> | ||
67 | #include <openssl/pem.h> | ||
68 | |||
69 | static int do_pk8pkey(BIO *bp, EVP_PKEY *x, int isder, | ||
70 | int nid, const EVP_CIPHER *enc, | ||
71 | char *kstr, int klen, | ||
72 | pem_password_cb *cb, void *u); | ||
73 | static int do_pk8pkey_fp(FILE *bp, EVP_PKEY *x, int isder, | ||
74 | int nid, const EVP_CIPHER *enc, | ||
75 | char *kstr, int klen, | ||
76 | pem_password_cb *cb, void *u); | ||
77 | |||
78 | /* These functions write a private key in PKCS#8 format: it is a "drop in" | ||
79 | * replacement for PEM_write_bio_PrivateKey() and friends. As usual if 'enc' | ||
80 | * is NULL then it uses the unencrypted private key form. The 'nid' versions | ||
81 | * uses PKCS#5 v1.5 PBE algorithms whereas the others use PKCS#5 v2.0. | ||
82 | */ | ||
83 | |||
84 | int PEM_write_bio_PKCS8PrivateKey_nid(BIO *bp, EVP_PKEY *x, int nid, | ||
85 | char *kstr, int klen, | ||
86 | pem_password_cb *cb, void *u) | ||
87 | { | ||
88 | return do_pk8pkey(bp, x, 0, nid, NULL, kstr, klen, cb, u); | ||
89 | } | ||
90 | |||
91 | int PEM_write_bio_PKCS8PrivateKey(BIO *bp, EVP_PKEY *x, const EVP_CIPHER *enc, | ||
92 | char *kstr, int klen, | ||
93 | pem_password_cb *cb, void *u) | ||
94 | { | ||
95 | return do_pk8pkey(bp, x, 0, -1, enc, kstr, klen, cb, u); | ||
96 | } | ||
97 | |||
98 | int i2d_PKCS8PrivateKey_bio(BIO *bp, EVP_PKEY *x, const EVP_CIPHER *enc, | ||
99 | char *kstr, int klen, | ||
100 | pem_password_cb *cb, void *u) | ||
101 | { | ||
102 | return do_pk8pkey(bp, x, 1, -1, enc, kstr, klen, cb, u); | ||
103 | } | ||
104 | |||
105 | int i2d_PKCS8PrivateKey_nid_bio(BIO *bp, EVP_PKEY *x, int nid, | ||
106 | char *kstr, int klen, | ||
107 | pem_password_cb *cb, void *u) | ||
108 | { | ||
109 | return do_pk8pkey(bp, x, 1, nid, NULL, kstr, klen, cb, u); | ||
110 | } | ||
111 | |||
112 | static int do_pk8pkey(BIO *bp, EVP_PKEY *x, int isder, int nid, const EVP_CIPHER *enc, | ||
113 | char *kstr, int klen, | ||
114 | pem_password_cb *cb, void *u) | ||
115 | { | ||
116 | X509_SIG *p8; | ||
117 | PKCS8_PRIV_KEY_INFO *p8inf; | ||
118 | char buf[PEM_BUFSIZE]; | ||
119 | int ret; | ||
120 | if(!(p8inf = EVP_PKEY2PKCS8(x))) { | ||
121 | PEMerr(PEM_F_PEM_WRITE_BIO_PKCS8PRIVATEKEY, | ||
122 | PEM_R_ERROR_CONVERTING_PRIVATE_KEY); | ||
123 | return 0; | ||
124 | } | ||
125 | if(enc || (nid != -1)) { | ||
126 | if(!kstr) { | ||
127 | if(!cb) klen = PEM_def_callback(buf, PEM_BUFSIZE, 1, u); | ||
128 | else klen = cb(buf, PEM_BUFSIZE, 1, u); | ||
129 | if(klen <= 0) { | ||
130 | PEMerr(PEM_F_PEM_WRITE_BIO_PKCS8PRIVATEKEY, | ||
131 | PEM_R_READ_KEY); | ||
132 | PKCS8_PRIV_KEY_INFO_free(p8inf); | ||
133 | return 0; | ||
134 | } | ||
135 | |||
136 | kstr = buf; | ||
137 | } | ||
138 | p8 = PKCS8_encrypt(nid, enc, kstr, klen, NULL, 0, 0, p8inf); | ||
139 | if(kstr == buf) memset(buf, 0, klen); | ||
140 | PKCS8_PRIV_KEY_INFO_free(p8inf); | ||
141 | if(isder) ret = i2d_PKCS8_bio(bp, p8); | ||
142 | else ret = PEM_write_bio_PKCS8(bp, p8); | ||
143 | X509_SIG_free(p8); | ||
144 | return ret; | ||
145 | } else { | ||
146 | if(isder) ret = i2d_PKCS8_PRIV_KEY_INFO_bio(bp, p8inf); | ||
147 | else ret = PEM_write_bio_PKCS8_PRIV_KEY_INFO(bp, p8inf); | ||
148 | PKCS8_PRIV_KEY_INFO_free(p8inf); | ||
149 | return ret; | ||
150 | } | ||
151 | } | ||
152 | |||
153 | EVP_PKEY *d2i_PKCS8PrivateKey_bio(BIO *bp, EVP_PKEY **x, pem_password_cb *cb, void *u) | ||
154 | { | ||
155 | PKCS8_PRIV_KEY_INFO *p8inf = NULL; | ||
156 | X509_SIG *p8 = NULL; | ||
157 | int klen; | ||
158 | EVP_PKEY *ret; | ||
159 | char psbuf[PEM_BUFSIZE]; | ||
160 | p8 = d2i_PKCS8_bio(bp, NULL); | ||
161 | if(!p8) return NULL; | ||
162 | if (cb) klen=cb(psbuf,PEM_BUFSIZE,0,u); | ||
163 | else klen=PEM_def_callback(psbuf,PEM_BUFSIZE,0,u); | ||
164 | if (klen <= 0) { | ||
165 | PEMerr(PEM_F_D2I_PKCS8PRIVATEKEY_BIO, PEM_R_BAD_PASSWORD_READ); | ||
166 | X509_SIG_free(p8); | ||
167 | return NULL; | ||
168 | } | ||
169 | p8inf = PKCS8_decrypt(p8, psbuf, klen); | ||
170 | X509_SIG_free(p8); | ||
171 | if(!p8inf) return NULL; | ||
172 | ret = EVP_PKCS82PKEY(p8inf); | ||
173 | PKCS8_PRIV_KEY_INFO_free(p8inf); | ||
174 | if(!ret) return NULL; | ||
175 | if(x) { | ||
176 | if(*x) EVP_PKEY_free(*x); | ||
177 | *x = ret; | ||
178 | } | ||
179 | return ret; | ||
180 | } | ||
181 | |||
182 | #ifndef OPENSSL_NO_FP_API | ||
183 | |||
184 | int i2d_PKCS8PrivateKey_fp(FILE *fp, EVP_PKEY *x, const EVP_CIPHER *enc, | ||
185 | char *kstr, int klen, | ||
186 | pem_password_cb *cb, void *u) | ||
187 | { | ||
188 | return do_pk8pkey_fp(fp, x, 1, -1, enc, kstr, klen, cb, u); | ||
189 | } | ||
190 | |||
191 | int i2d_PKCS8PrivateKey_nid_fp(FILE *fp, EVP_PKEY *x, int nid, | ||
192 | char *kstr, int klen, | ||
193 | pem_password_cb *cb, void *u) | ||
194 | { | ||
195 | return do_pk8pkey_fp(fp, x, 1, nid, NULL, kstr, klen, cb, u); | ||
196 | } | ||
197 | |||
198 | int PEM_write_PKCS8PrivateKey_nid(FILE *fp, EVP_PKEY *x, int nid, | ||
199 | char *kstr, int klen, | ||
200 | pem_password_cb *cb, void *u) | ||
201 | { | ||
202 | return do_pk8pkey_fp(fp, x, 0, nid, NULL, kstr, klen, cb, u); | ||
203 | } | ||
204 | |||
205 | int PEM_write_PKCS8PrivateKey(FILE *fp, EVP_PKEY *x, const EVP_CIPHER *enc, | ||
206 | char *kstr, int klen, pem_password_cb *cb, void *u) | ||
207 | { | ||
208 | return do_pk8pkey_fp(fp, x, 0, -1, enc, kstr, klen, cb, u); | ||
209 | } | ||
210 | |||
211 | static int do_pk8pkey_fp(FILE *fp, EVP_PKEY *x, int isder, int nid, const EVP_CIPHER *enc, | ||
212 | char *kstr, int klen, | ||
213 | pem_password_cb *cb, void *u) | ||
214 | { | ||
215 | BIO *bp; | ||
216 | int ret; | ||
217 | if(!(bp = BIO_new_fp(fp, BIO_NOCLOSE))) { | ||
218 | PEMerr(PEM_F_PEM_F_DO_PK8KEY_FP,ERR_R_BUF_LIB); | ||
219 | return(0); | ||
220 | } | ||
221 | ret = do_pk8pkey(bp, x, isder, nid, enc, kstr, klen, cb, u); | ||
222 | BIO_free(bp); | ||
223 | return ret; | ||
224 | } | ||
225 | |||
226 | EVP_PKEY *d2i_PKCS8PrivateKey_fp(FILE *fp, EVP_PKEY **x, pem_password_cb *cb, void *u) | ||
227 | { | ||
228 | BIO *bp; | ||
229 | EVP_PKEY *ret; | ||
230 | if(!(bp = BIO_new_fp(fp, BIO_NOCLOSE))) { | ||
231 | PEMerr(PEM_F_D2I_PKCS8PRIVATEKEY_FP,ERR_R_BUF_LIB); | ||
232 | return NULL; | ||
233 | } | ||
234 | ret = d2i_PKCS8PrivateKey_bio(bp, x, cb, u); | ||
235 | BIO_free(bp); | ||
236 | return ret; | ||
237 | } | ||
238 | |||
239 | #endif | ||
240 | |||
241 | IMPLEMENT_PEM_rw(PKCS8, X509_SIG, PEM_STRING_PKCS8, X509_SIG) | ||
242 | IMPLEMENT_PEM_rw(PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO, PEM_STRING_PKCS8INF, | ||
243 | PKCS8_PRIV_KEY_INFO) | ||
diff --git a/src/lib/libcrypto/pem/pem_pkey.c b/src/lib/libcrypto/pem/pem_pkey.c new file mode 100644 index 0000000000..270892d72b --- /dev/null +++ b/src/lib/libcrypto/pem/pem_pkey.c | |||
@@ -0,0 +1,139 @@ | |||
1 | /* crypto/pem/pem_pkey.c */ | ||
2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) | ||
3 | * All rights reserved. | ||
4 | * | ||
5 | * This package is an SSL implementation written | ||
6 | * by Eric Young (eay@cryptsoft.com). | ||
7 | * The implementation was written so as to conform with Netscapes SSL. | ||
8 | * | ||
9 | * This library is free for commercial and non-commercial use as long as | ||
10 | * the following conditions are aheared to. The following conditions | ||
11 | * apply to all code found in this distribution, be it the RC4, RSA, | ||
12 | * lhash, DES, etc., code; not just the SSL code. The SSL documentation | ||
13 | * included with this distribution is covered by the same copyright terms | ||
14 | * except that the holder is Tim Hudson (tjh@cryptsoft.com). | ||
15 | * | ||
16 | * Copyright remains Eric Young's, and as such any Copyright notices in | ||
17 | * the code are not to be removed. | ||
18 | * If this package is used in a product, Eric Young should be given attribution | ||
19 | * as the author of the parts of the library used. | ||
20 | * This can be in the form of a textual message at program startup or | ||
21 | * in documentation (online or textual) provided with the package. | ||
22 | * | ||
23 | * Redistribution and use in source and binary forms, with or without | ||
24 | * modification, are permitted provided that the following conditions | ||
25 | * are met: | ||
26 | * 1. Redistributions of source code must retain the copyright | ||
27 | * notice, this list of conditions and the following disclaimer. | ||
28 | * 2. Redistributions in binary form must reproduce the above copyright | ||
29 | * notice, this list of conditions and the following disclaimer in the | ||
30 | * documentation and/or other materials provided with the distribution. | ||
31 | * 3. All advertising materials mentioning features or use of this software | ||
32 | * must display the following acknowledgement: | ||
33 | * "This product includes cryptographic software written by | ||
34 | * Eric Young (eay@cryptsoft.com)" | ||
35 | * The word 'cryptographic' can be left out if the rouines from the library | ||
36 | * being used are not cryptographic related :-). | ||
37 | * 4. If you include any Windows specific code (or a derivative thereof) from | ||
38 | * the apps directory (application code) you must include an acknowledgement: | ||
39 | * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" | ||
40 | * | ||
41 | * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND | ||
42 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
43 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
44 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | ||
45 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
46 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
47 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
48 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
49 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
50 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
51 | * SUCH DAMAGE. | ||
52 | * | ||
53 | * The licence and distribution terms for any publically available version or | ||
54 | * derivative of this code cannot be changed. i.e. this code cannot simply be | ||
55 | * copied and put under another distribution licence | ||
56 | * [including the GNU Public Licence.] | ||
57 | */ | ||
58 | |||
59 | #include <stdio.h> | ||
60 | #include "cryptlib.h" | ||
61 | #include <openssl/buffer.h> | ||
62 | #include <openssl/objects.h> | ||
63 | #include <openssl/evp.h> | ||
64 | #include <openssl/rand.h> | ||
65 | #include <openssl/x509.h> | ||
66 | #include <openssl/pkcs12.h> | ||
67 | #include <openssl/pem.h> | ||
68 | |||
69 | |||
70 | EVP_PKEY *PEM_read_bio_PrivateKey(BIO *bp, EVP_PKEY **x, pem_password_cb *cb, void *u) | ||
71 | { | ||
72 | char *nm=NULL; | ||
73 | unsigned char *p=NULL,*data=NULL; | ||
74 | long len; | ||
75 | EVP_PKEY *ret=NULL; | ||
76 | |||
77 | if (!PEM_bytes_read_bio(&data, &len, &nm, PEM_STRING_EVP_PKEY, bp, cb, u)) | ||
78 | return NULL; | ||
79 | p = data; | ||
80 | |||
81 | if (strcmp(nm,PEM_STRING_RSA) == 0) | ||
82 | ret=d2i_PrivateKey(EVP_PKEY_RSA,x,&p,len); | ||
83 | else if (strcmp(nm,PEM_STRING_DSA) == 0) | ||
84 | ret=d2i_PrivateKey(EVP_PKEY_DSA,x,&p,len); | ||
85 | else if (strcmp(nm,PEM_STRING_PKCS8INF) == 0) { | ||
86 | PKCS8_PRIV_KEY_INFO *p8inf; | ||
87 | p8inf=d2i_PKCS8_PRIV_KEY_INFO(NULL, &p, len); | ||
88 | ret = EVP_PKCS82PKEY(p8inf); | ||
89 | PKCS8_PRIV_KEY_INFO_free(p8inf); | ||
90 | } else if (strcmp(nm,PEM_STRING_PKCS8) == 0) { | ||
91 | PKCS8_PRIV_KEY_INFO *p8inf; | ||
92 | X509_SIG *p8; | ||
93 | int klen; | ||
94 | char psbuf[PEM_BUFSIZE]; | ||
95 | p8 = d2i_X509_SIG(NULL, &p, len); | ||
96 | if(!p8) goto p8err; | ||
97 | if (cb) klen=cb(psbuf,PEM_BUFSIZE,0,u); | ||
98 | else klen=PEM_def_callback(psbuf,PEM_BUFSIZE,0,u); | ||
99 | if (klen <= 0) { | ||
100 | PEMerr(PEM_F_PEM_ASN1_READ_BIO, | ||
101 | PEM_R_BAD_PASSWORD_READ); | ||
102 | goto err; | ||
103 | } | ||
104 | p8inf = PKCS8_decrypt(p8, psbuf, klen); | ||
105 | X509_SIG_free(p8); | ||
106 | if(!p8inf) goto p8err; | ||
107 | ret = EVP_PKCS82PKEY(p8inf); | ||
108 | if(x) { | ||
109 | if(*x) EVP_PKEY_free((EVP_PKEY *)*x); | ||
110 | *x = ret; | ||
111 | } | ||
112 | PKCS8_PRIV_KEY_INFO_free(p8inf); | ||
113 | } | ||
114 | p8err: | ||
115 | if (ret == NULL) | ||
116 | PEMerr(PEM_F_PEM_ASN1_READ_BIO,ERR_R_ASN1_LIB); | ||
117 | err: | ||
118 | OPENSSL_free(nm); | ||
119 | OPENSSL_free(data); | ||
120 | return(ret); | ||
121 | } | ||
122 | |||
123 | #ifndef OPENSSL_NO_FP_API | ||
124 | EVP_PKEY *PEM_read_PrivateKey(FILE *fp, EVP_PKEY **x, pem_password_cb *cb, void *u) | ||
125 | { | ||
126 | BIO *b; | ||
127 | EVP_PKEY *ret; | ||
128 | |||
129 | if ((b=BIO_new(BIO_s_file())) == NULL) | ||
130 | { | ||
131 | PEMerr(PEM_F_PEM_ASN1_READ,ERR_R_BUF_LIB); | ||
132 | return(0); | ||
133 | } | ||
134 | BIO_set_fp(b,fp,BIO_NOCLOSE); | ||
135 | ret=PEM_read_bio_PrivateKey(b,x,cb,u); | ||
136 | BIO_free(b); | ||
137 | return(ret); | ||
138 | } | ||
139 | #endif | ||
diff --git a/src/lib/libcrypto/pem/pem_x509.c b/src/lib/libcrypto/pem/pem_x509.c new file mode 100644 index 0000000000..19f88d8d3a --- /dev/null +++ b/src/lib/libcrypto/pem/pem_x509.c | |||
@@ -0,0 +1,69 @@ | |||
1 | /* pem_x509.c */ | ||
2 | /* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL | ||
3 | * project 2001. | ||
4 | */ | ||
5 | /* ==================================================================== | ||
6 | * Copyright (c) 2001 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 | #undef SSLEAY_MACROS | ||
61 | #include "cryptlib.h" | ||
62 | #include <openssl/bio.h> | ||
63 | #include <openssl/evp.h> | ||
64 | #include <openssl/x509.h> | ||
65 | #include <openssl/pkcs7.h> | ||
66 | #include <openssl/pem.h> | ||
67 | |||
68 | IMPLEMENT_PEM_rw(X509, X509, PEM_STRING_X509, X509) | ||
69 | |||
diff --git a/src/lib/libcrypto/pem/pem_xaux.c b/src/lib/libcrypto/pem/pem_xaux.c new file mode 100644 index 0000000000..2f579b5421 --- /dev/null +++ b/src/lib/libcrypto/pem/pem_xaux.c | |||
@@ -0,0 +1,68 @@ | |||
1 | /* pem_xaux.c */ | ||
2 | /* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL | ||
3 | * project 2001. | ||
4 | */ | ||
5 | /* ==================================================================== | ||
6 | * Copyright (c) 2001 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 | #undef SSLEAY_MACROS | ||
61 | #include "cryptlib.h" | ||
62 | #include <openssl/bio.h> | ||
63 | #include <openssl/evp.h> | ||
64 | #include <openssl/x509.h> | ||
65 | #include <openssl/pkcs7.h> | ||
66 | #include <openssl/pem.h> | ||
67 | |||
68 | IMPLEMENT_PEM_rw(X509_AUX, X509, PEM_STRING_X509_TRUSTED, X509_AUX) | ||
diff --git a/src/lib/libcrypto/pkcs12/p12_add.c b/src/lib/libcrypto/pkcs12/p12_add.c new file mode 100644 index 0000000000..ae3d9de3b4 --- /dev/null +++ b/src/lib/libcrypto/pkcs12/p12_add.c | |||
@@ -0,0 +1,214 @@ | |||
1 | /* p12_add.c */ | ||
2 | /* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL | ||
3 | * project 1999. | ||
4 | */ | ||
5 | /* ==================================================================== | ||
6 | * Copyright (c) 1999 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 | #include "cryptlib.h" | ||
61 | #include <openssl/pkcs12.h> | ||
62 | |||
63 | /* Pack an object into an OCTET STRING and turn into a safebag */ | ||
64 | |||
65 | PKCS12_SAFEBAG *PKCS12_pack_safebag (char *obj, int (*i2d)(), int nid1, | ||
66 | int nid2) | ||
67 | { | ||
68 | PKCS12_BAGS *bag; | ||
69 | PKCS12_SAFEBAG *safebag; | ||
70 | if (!(bag = PKCS12_BAGS_new ())) { | ||
71 | PKCS12err(PKCS12_F_PKCS12_PACK_SAFEBAG, ERR_R_MALLOC_FAILURE); | ||
72 | return NULL; | ||
73 | } | ||
74 | bag->type = OBJ_nid2obj(nid1); | ||
75 | if (!ASN1_pack_string(obj, i2d, &bag->value.octet)) { | ||
76 | PKCS12err(PKCS12_F_PKCS12_PACK_SAFEBAG, ERR_R_MALLOC_FAILURE); | ||
77 | return NULL; | ||
78 | } | ||
79 | if (!(safebag = PKCS12_SAFEBAG_new ())) { | ||
80 | PKCS12err(PKCS12_F_PKCS12_PACK_SAFEBAG, ERR_R_MALLOC_FAILURE); | ||
81 | return NULL; | ||
82 | } | ||
83 | safebag->value.bag = bag; | ||
84 | safebag->type = OBJ_nid2obj(nid2); | ||
85 | return safebag; | ||
86 | } | ||
87 | |||
88 | /* Turn PKCS8 object into a keybag */ | ||
89 | |||
90 | PKCS12_SAFEBAG *PKCS12_MAKE_KEYBAG (PKCS8_PRIV_KEY_INFO *p8) | ||
91 | { | ||
92 | PKCS12_SAFEBAG *bag; | ||
93 | if (!(bag = PKCS12_SAFEBAG_new())) { | ||
94 | PKCS12err(PKCS12_F_PKCS12_MAKE_KEYBAG,ERR_R_MALLOC_FAILURE); | ||
95 | return NULL; | ||
96 | } | ||
97 | bag->type = OBJ_nid2obj(NID_keyBag); | ||
98 | bag->value.keybag = p8; | ||
99 | return bag; | ||
100 | } | ||
101 | |||
102 | /* Turn PKCS8 object into a shrouded keybag */ | ||
103 | |||
104 | PKCS12_SAFEBAG *PKCS12_MAKE_SHKEYBAG (int pbe_nid, const char *pass, | ||
105 | int passlen, unsigned char *salt, int saltlen, int iter, | ||
106 | PKCS8_PRIV_KEY_INFO *p8) | ||
107 | { | ||
108 | PKCS12_SAFEBAG *bag; | ||
109 | |||
110 | /* Set up the safe bag */ | ||
111 | if (!(bag = PKCS12_SAFEBAG_new ())) { | ||
112 | PKCS12err(PKCS12_F_PKCS12_MAKE_SHKEYBAG, ERR_R_MALLOC_FAILURE); | ||
113 | return NULL; | ||
114 | } | ||
115 | |||
116 | bag->type = OBJ_nid2obj(NID_pkcs8ShroudedKeyBag); | ||
117 | if (!(bag->value.shkeybag = | ||
118 | PKCS8_encrypt(pbe_nid, NULL, pass, passlen, salt, saltlen, iter, | ||
119 | p8))) { | ||
120 | PKCS12err(PKCS12_F_PKCS12_MAKE_SHKEYBAG, ERR_R_MALLOC_FAILURE); | ||
121 | return NULL; | ||
122 | } | ||
123 | |||
124 | return bag; | ||
125 | } | ||
126 | |||
127 | /* Turn a stack of SAFEBAGS into a PKCS#7 data Contentinfo */ | ||
128 | PKCS7 *PKCS12_pack_p7data (STACK *sk) | ||
129 | { | ||
130 | PKCS7 *p7; | ||
131 | if (!(p7 = PKCS7_new())) { | ||
132 | PKCS12err(PKCS12_F_PKCS12_PACK_P7DATA, ERR_R_MALLOC_FAILURE); | ||
133 | return NULL; | ||
134 | } | ||
135 | p7->type = OBJ_nid2obj(NID_pkcs7_data); | ||
136 | if (!(p7->d.data = ASN1_OCTET_STRING_new())) { | ||
137 | PKCS12err(PKCS12_F_PKCS12_PACK_P7DATA, ERR_R_MALLOC_FAILURE); | ||
138 | return NULL; | ||
139 | } | ||
140 | |||
141 | if (!ASN1_seq_pack(sk, i2d_PKCS12_SAFEBAG, &p7->d.data->data, | ||
142 | &p7->d.data->length)) { | ||
143 | PKCS12err(PKCS12_F_PKCS12_PACK_P7DATA, PKCS12_R_CANT_PACK_STRUCTURE); | ||
144 | return NULL; | ||
145 | } | ||
146 | return p7; | ||
147 | } | ||
148 | |||
149 | /* Turn a stack of SAFEBAGS into a PKCS#7 encrypted data ContentInfo */ | ||
150 | |||
151 | PKCS7 *PKCS12_pack_p7encdata (int pbe_nid, const char *pass, int passlen, | ||
152 | unsigned char *salt, int saltlen, int iter, STACK *bags) | ||
153 | { | ||
154 | PKCS7 *p7; | ||
155 | X509_ALGOR *pbe; | ||
156 | if (!(p7 = PKCS7_new())) { | ||
157 | PKCS12err(PKCS12_F_PKCS12_PACK_P7ENCDATA, ERR_R_MALLOC_FAILURE); | ||
158 | return NULL; | ||
159 | } | ||
160 | p7->type = OBJ_nid2obj(NID_pkcs7_encrypted); | ||
161 | if (!(p7->d.encrypted = PKCS7_ENCRYPT_new ())) { | ||
162 | PKCS12err(PKCS12_F_PKCS12_PACK_P7ENCDATA, ERR_R_MALLOC_FAILURE); | ||
163 | return NULL; | ||
164 | } | ||
165 | ASN1_INTEGER_set (p7->d.encrypted->version, 0); | ||
166 | p7->d.encrypted->enc_data->content_type = OBJ_nid2obj(NID_pkcs7_data); | ||
167 | if (!(pbe = PKCS5_pbe_set (pbe_nid, iter, salt, saltlen))) { | ||
168 | PKCS12err(PKCS12_F_PKCS12_PACK_P7ENCDATA, ERR_R_MALLOC_FAILURE); | ||
169 | return NULL; | ||
170 | } | ||
171 | X509_ALGOR_free(p7->d.encrypted->enc_data->algorithm); | ||
172 | p7->d.encrypted->enc_data->algorithm = pbe; | ||
173 | ASN1_OCTET_STRING_free(p7->d.encrypted->enc_data->enc_data); | ||
174 | if (!(p7->d.encrypted->enc_data->enc_data = | ||
175 | PKCS12_i2d_encrypt (pbe, i2d_PKCS12_SAFEBAG, pass, passlen, | ||
176 | (char *)bags, 1))) { | ||
177 | PKCS12err(PKCS12_F_PKCS12_PACK_P7ENCDATA, PKCS12_R_ENCRYPT_ERROR); | ||
178 | return NULL; | ||
179 | } | ||
180 | |||
181 | return p7; | ||
182 | } | ||
183 | |||
184 | X509_SIG *PKCS8_encrypt(int pbe_nid, const EVP_CIPHER *cipher, | ||
185 | const char *pass, int passlen, | ||
186 | unsigned char *salt, int saltlen, int iter, | ||
187 | PKCS8_PRIV_KEY_INFO *p8inf) | ||
188 | { | ||
189 | X509_SIG *p8; | ||
190 | X509_ALGOR *pbe; | ||
191 | |||
192 | if (!(p8 = X509_SIG_new())) { | ||
193 | PKCS12err(PKCS12_F_PKCS8_ENCRYPT, ERR_R_MALLOC_FAILURE); | ||
194 | return NULL; | ||
195 | } | ||
196 | |||
197 | if(pbe_nid == -1) pbe = PKCS5_pbe2_set(cipher, iter, salt, saltlen); | ||
198 | else pbe = PKCS5_pbe_set(pbe_nid, iter, salt, saltlen); | ||
199 | if(!pbe) { | ||
200 | PKCS12err(PKCS12_F_PKCS8_ENCRYPT, ERR_R_MALLOC_FAILURE); | ||
201 | return NULL; | ||
202 | } | ||
203 | X509_ALGOR_free(p8->algor); | ||
204 | p8->algor = pbe; | ||
205 | ASN1_OCTET_STRING_free(p8->digest); | ||
206 | if (!(p8->digest = | ||
207 | PKCS12_i2d_encrypt (pbe, i2d_PKCS8_PRIV_KEY_INFO, pass, passlen, | ||
208 | (char *)p8inf, 0))) { | ||
209 | PKCS12err(PKCS12_F_PKCS8_ENCRYPT, PKCS12_R_ENCRYPT_ERROR); | ||
210 | return NULL; | ||
211 | } | ||
212 | |||
213 | return p8; | ||
214 | } | ||
diff --git a/src/lib/libcrypto/pkcs12/p12_asn.c b/src/lib/libcrypto/pkcs12/p12_asn.c new file mode 100644 index 0000000000..c327bdba03 --- /dev/null +++ b/src/lib/libcrypto/pkcs12/p12_asn.c | |||
@@ -0,0 +1,125 @@ | |||
1 | /* p12_asn.c */ | ||
2 | /* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL | ||
3 | * project 1999. | ||
4 | */ | ||
5 | /* ==================================================================== | ||
6 | * Copyright (c) 1999 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 | #include "cryptlib.h" | ||
61 | #include <openssl/asn1t.h> | ||
62 | #include <openssl/pkcs12.h> | ||
63 | |||
64 | /* PKCS#12 ASN1 module */ | ||
65 | |||
66 | ASN1_SEQUENCE(PKCS12) = { | ||
67 | ASN1_SIMPLE(PKCS12, version, ASN1_INTEGER), | ||
68 | ASN1_SIMPLE(PKCS12, authsafes, PKCS7), | ||
69 | ASN1_OPT(PKCS12, mac, PKCS12_MAC_DATA) | ||
70 | } ASN1_SEQUENCE_END(PKCS12) | ||
71 | |||
72 | IMPLEMENT_ASN1_FUNCTIONS(PKCS12) | ||
73 | |||
74 | ASN1_SEQUENCE(PKCS12_MAC_DATA) = { | ||
75 | ASN1_SIMPLE(PKCS12_MAC_DATA, dinfo, X509_SIG), | ||
76 | ASN1_SIMPLE(PKCS12_MAC_DATA, salt, ASN1_OCTET_STRING), | ||
77 | ASN1_OPT(PKCS12_MAC_DATA, iter, ASN1_INTEGER) | ||
78 | } ASN1_SEQUENCE_END(PKCS12_MAC_DATA) | ||
79 | |||
80 | IMPLEMENT_ASN1_FUNCTIONS(PKCS12_MAC_DATA) | ||
81 | |||
82 | ASN1_ADB_TEMPLATE(bag_default) = ASN1_EXP(PKCS12_BAGS, value.other, ASN1_ANY, 0); | ||
83 | |||
84 | ASN1_ADB(PKCS12_BAGS) = { | ||
85 | ADB_ENTRY(NID_x509Certificate, ASN1_EXP(PKCS12_BAGS, value.x509cert, ASN1_OCTET_STRING, 0)), | ||
86 | ADB_ENTRY(NID_x509Certificate, ASN1_EXP(PKCS12_BAGS, value.x509crl, ASN1_OCTET_STRING, 0)), | ||
87 | ADB_ENTRY(NID_x509Certificate, ASN1_EXP(PKCS12_BAGS, value.sdsicert, ASN1_IA5STRING, 0)), | ||
88 | } ASN1_ADB_END(PKCS12_BAGS, 0, type, 0, &bag_default_tt, NULL); | ||
89 | |||
90 | ASN1_SEQUENCE(PKCS12_BAGS) = { | ||
91 | ASN1_SIMPLE(PKCS12_BAGS, type, ASN1_OBJECT), | ||
92 | ASN1_ADB_OBJECT(PKCS12_BAGS), | ||
93 | } ASN1_SEQUENCE_END(PKCS12_BAGS) | ||
94 | |||
95 | IMPLEMENT_ASN1_FUNCTIONS(PKCS12_BAGS) | ||
96 | |||
97 | ASN1_ADB_TEMPLATE(safebag_default) = ASN1_EXP(PKCS12_SAFEBAG, value.other, ASN1_ANY, 0); | ||
98 | |||
99 | ASN1_ADB(PKCS12_SAFEBAG) = { | ||
100 | ADB_ENTRY(NID_keyBag, ASN1_EXP(PKCS12_SAFEBAG, value.keybag, PKCS8_PRIV_KEY_INFO, 0)), | ||
101 | ADB_ENTRY(NID_pkcs8ShroudedKeyBag, ASN1_EXP(PKCS12_SAFEBAG, value.keybag, X509_SIG, 0)), | ||
102 | ADB_ENTRY(NID_safeContentsBag, ASN1_EXP_SET_OF(PKCS12_SAFEBAG, value.safes, PKCS12_SAFEBAG, 0)), | ||
103 | ADB_ENTRY(NID_certBag, ASN1_EXP(PKCS12_SAFEBAG, value.bag, PKCS12_BAGS, 0)), | ||
104 | ADB_ENTRY(NID_crlBag, ASN1_EXP(PKCS12_SAFEBAG, value.bag, PKCS12_BAGS, 0)), | ||
105 | ADB_ENTRY(NID_secretBag, ASN1_EXP(PKCS12_SAFEBAG, value.bag, PKCS12_BAGS, 0)) | ||
106 | } ASN1_ADB_END(PKCS12_SAFEBAG, 0, type, 0, &safebag_default_tt, NULL); | ||
107 | |||
108 | ASN1_SEQUENCE(PKCS12_SAFEBAG) = { | ||
109 | ASN1_SIMPLE(PKCS12_SAFEBAG, type, ASN1_OBJECT), | ||
110 | ASN1_ADB_OBJECT(PKCS12_SAFEBAG), | ||
111 | ASN1_SET_OF_OPT(PKCS12_SAFEBAG, attrib, X509_ATTRIBUTE) | ||
112 | } ASN1_SEQUENCE_END(PKCS12_SAFEBAG) | ||
113 | |||
114 | IMPLEMENT_ASN1_FUNCTIONS(PKCS12_SAFEBAG) | ||
115 | |||
116 | /* SEQUENCE OF SafeBag */ | ||
117 | ASN1_ITEM_TEMPLATE(PKCS12_SAFEBAGS) = | ||
118 | ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, PKCS12_SAFEBAGS, PKCS12_SAFEBAG) | ||
119 | ASN1_ITEM_TEMPLATE_END(PKCS12_SAFEBAGS) | ||
120 | |||
121 | /* Authsafes: SEQUENCE OF PKCS7 */ | ||
122 | ASN1_ITEM_TEMPLATE(PKCS12_AUTHSAFES) = | ||
123 | ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, PKCS12_AUTHSAFES, PKCS7) | ||
124 | ASN1_ITEM_TEMPLATE_END(PKCS12_AUTHSAFES) | ||
125 | |||
diff --git a/src/lib/libcrypto/pkcs12/p12_attr.c b/src/lib/libcrypto/pkcs12/p12_attr.c new file mode 100644 index 0000000000..31c9782b77 --- /dev/null +++ b/src/lib/libcrypto/pkcs12/p12_attr.c | |||
@@ -0,0 +1,238 @@ | |||
1 | /* p12_attr.c */ | ||
2 | /* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL | ||
3 | * project 1999. | ||
4 | */ | ||
5 | /* ==================================================================== | ||
6 | * Copyright (c) 1999 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 | #include "cryptlib.h" | ||
61 | #include <openssl/pkcs12.h> | ||
62 | |||
63 | /* Add a local keyid to a safebag */ | ||
64 | |||
65 | int PKCS12_add_localkeyid (PKCS12_SAFEBAG *bag, unsigned char *name, | ||
66 | int namelen) | ||
67 | { | ||
68 | X509_ATTRIBUTE *attrib; | ||
69 | ASN1_BMPSTRING *oct; | ||
70 | ASN1_TYPE *keyid; | ||
71 | if (!(keyid = ASN1_TYPE_new ())) { | ||
72 | PKCS12err(PKCS12_F_PKCS12_ADD_LOCALKEYID, ERR_R_MALLOC_FAILURE); | ||
73 | return 0; | ||
74 | } | ||
75 | keyid->type = V_ASN1_OCTET_STRING; | ||
76 | if (!(oct = ASN1_OCTET_STRING_new())) { | ||
77 | PKCS12err(PKCS12_F_PKCS12_ADD_LOCALKEYID, ERR_R_MALLOC_FAILURE); | ||
78 | return 0; | ||
79 | } | ||
80 | if (!ASN1_OCTET_STRING_set(oct, name, namelen)) { | ||
81 | PKCS12err(PKCS12_F_PKCS12_ADD_LOCALKEYID, ERR_R_MALLOC_FAILURE); | ||
82 | return 0; | ||
83 | } | ||
84 | keyid->value.octet_string = oct; | ||
85 | if (!(attrib = X509_ATTRIBUTE_new ())) { | ||
86 | PKCS12err(PKCS12_F_PKCS12_ADD_LOCALKEYID, ERR_R_MALLOC_FAILURE); | ||
87 | return 0; | ||
88 | } | ||
89 | attrib->object = OBJ_nid2obj(NID_localKeyID); | ||
90 | if (!(attrib->value.set = sk_ASN1_TYPE_new(NULL))) { | ||
91 | PKCS12err(PKCS12_F_PKCS12_ADD_LOCALKEYID, ERR_R_MALLOC_FAILURE); | ||
92 | return 0; | ||
93 | } | ||
94 | sk_ASN1_TYPE_push (attrib->value.set,keyid); | ||
95 | attrib->set = 1; | ||
96 | if (!bag->attrib && !(bag->attrib = sk_X509_ATTRIBUTE_new (NULL))) { | ||
97 | PKCS12err(PKCS12_F_PKCS12_ADD_LOCALKEYID, ERR_R_MALLOC_FAILURE); | ||
98 | return 0; | ||
99 | } | ||
100 | sk_X509_ATTRIBUTE_push (bag->attrib, attrib); | ||
101 | return 1; | ||
102 | } | ||
103 | |||
104 | /* Add key usage to PKCS#8 structure */ | ||
105 | |||
106 | int PKCS8_add_keyusage (PKCS8_PRIV_KEY_INFO *p8, int usage) | ||
107 | { | ||
108 | X509_ATTRIBUTE *attrib; | ||
109 | ASN1_BIT_STRING *bstr; | ||
110 | ASN1_TYPE *keyid; | ||
111 | unsigned char us_val; | ||
112 | us_val = (unsigned char) usage; | ||
113 | if (!(keyid = ASN1_TYPE_new ())) { | ||
114 | PKCS12err(PKCS12_F_PKCS8_ADD_KEYUSAGE, ERR_R_MALLOC_FAILURE); | ||
115 | return 0; | ||
116 | } | ||
117 | keyid->type = V_ASN1_BIT_STRING; | ||
118 | if (!(bstr = ASN1_BIT_STRING_new())) { | ||
119 | PKCS12err(PKCS12_F_PKCS8_ADD_KEYUSAGE, ERR_R_MALLOC_FAILURE); | ||
120 | return 0; | ||
121 | } | ||
122 | if (!ASN1_BIT_STRING_set(bstr, &us_val, 1)) { | ||
123 | PKCS12err(PKCS12_F_PKCS8_ADD_KEYUSAGE, ERR_R_MALLOC_FAILURE); | ||
124 | return 0; | ||
125 | } | ||
126 | keyid->value.bit_string = bstr; | ||
127 | if (!(attrib = X509_ATTRIBUTE_new ())) { | ||
128 | PKCS12err(PKCS12_F_PKCS8_ADD_KEYUSAGE, ERR_R_MALLOC_FAILURE); | ||
129 | return 0; | ||
130 | } | ||
131 | attrib->object = OBJ_nid2obj(NID_key_usage); | ||
132 | if (!(attrib->value.set = sk_ASN1_TYPE_new(NULL))) { | ||
133 | PKCS12err(PKCS12_F_PKCS8_ADD_KEYUSAGE, ERR_R_MALLOC_FAILURE); | ||
134 | return 0; | ||
135 | } | ||
136 | sk_ASN1_TYPE_push (attrib->value.set,keyid); | ||
137 | attrib->set = 1; | ||
138 | if (!p8->attributes | ||
139 | && !(p8->attributes = sk_X509_ATTRIBUTE_new (NULL))) { | ||
140 | PKCS12err(PKCS12_F_PKCS8_ADD_KEYUSAGE, ERR_R_MALLOC_FAILURE); | ||
141 | return 0; | ||
142 | } | ||
143 | sk_X509_ATTRIBUTE_push (p8->attributes, attrib); | ||
144 | return 1; | ||
145 | } | ||
146 | |||
147 | /* Add a friendlyname to a safebag */ | ||
148 | |||
149 | int PKCS12_add_friendlyname_asc (PKCS12_SAFEBAG *bag, const char *name, | ||
150 | int namelen) | ||
151 | { | ||
152 | unsigned char *uniname; | ||
153 | int ret, unilen; | ||
154 | if (!asc2uni(name, &uniname, &unilen)) { | ||
155 | PKCS12err(PKCS12_F_PKCS12_ADD_FRIENDLYNAME_ASC, | ||
156 | ERR_R_MALLOC_FAILURE); | ||
157 | return 0; | ||
158 | } | ||
159 | ret = PKCS12_add_friendlyname_uni (bag, uniname, unilen); | ||
160 | Free(uniname); | ||
161 | return ret; | ||
162 | } | ||
163 | |||
164 | |||
165 | int PKCS12_add_friendlyname_uni (PKCS12_SAFEBAG *bag, | ||
166 | const unsigned char *name, int namelen) | ||
167 | { | ||
168 | X509_ATTRIBUTE *attrib; | ||
169 | ASN1_BMPSTRING *bmp; | ||
170 | ASN1_TYPE *fname; | ||
171 | /* Zap ending double null if included */ | ||
172 | if(!name[namelen - 1] && !name[namelen - 2]) namelen -= 2; | ||
173 | if (!(fname = ASN1_TYPE_new ())) { | ||
174 | PKCS12err(PKCS12_F_PKCS12_ADD_FRIENDLYNAME_UNI, | ||
175 | ERR_R_MALLOC_FAILURE); | ||
176 | return 0; | ||
177 | } | ||
178 | fname->type = V_ASN1_BMPSTRING; | ||
179 | if (!(bmp = ASN1_BMPSTRING_new())) { | ||
180 | PKCS12err(PKCS12_F_PKCS12_ADD_FRIENDLYNAME_UNI, | ||
181 | ERR_R_MALLOC_FAILURE); | ||
182 | return 0; | ||
183 | } | ||
184 | if (!(bmp->data = Malloc (namelen))) { | ||
185 | PKCS12err(PKCS12_F_PKCS12_ADD_FRIENDLYNAME_UNI, | ||
186 | ERR_R_MALLOC_FAILURE); | ||
187 | return 0; | ||
188 | } | ||
189 | memcpy (bmp->data, name, namelen); | ||
190 | bmp->length = namelen; | ||
191 | fname->value.bmpstring = bmp; | ||
192 | if (!(attrib = X509_ATTRIBUTE_new ())) { | ||
193 | PKCS12err(PKCS12_F_PKCS12_ADD_FRIENDLYNAME_UNI, | ||
194 | ERR_R_MALLOC_FAILURE); | ||
195 | return 0; | ||
196 | } | ||
197 | attrib->object = OBJ_nid2obj(NID_friendlyName); | ||
198 | if (!(attrib->value.set = sk_ASN1_TYPE_new(NULL))) { | ||
199 | PKCS12err(PKCS12_F_PKCS12_ADD_FRIENDLYNAME, | ||
200 | ERR_R_MALLOC_FAILURE); | ||
201 | return 0; | ||
202 | } | ||
203 | sk_ASN1_TYPE_push (attrib->value.set,fname); | ||
204 | attrib->set = 1; | ||
205 | if (!bag->attrib && !(bag->attrib = sk_X509_ATTRIBUTE_new (NULL))) { | ||
206 | PKCS12err(PKCS12_F_PKCS12_ADD_FRIENDLYNAME_UNI, | ||
207 | ERR_R_MALLOC_FAILURE); | ||
208 | return 0; | ||
209 | } | ||
210 | sk_X509_ATTRIBUTE_push (bag->attrib, attrib); | ||
211 | return PKCS12_OK; | ||
212 | } | ||
213 | |||
214 | ASN1_TYPE *PKCS12_get_attr_gen (STACK_OF(X509_ATTRIBUTE) *attrs, int attr_nid) | ||
215 | { | ||
216 | X509_ATTRIBUTE *attrib; | ||
217 | int i; | ||
218 | if (!attrs) return NULL; | ||
219 | for (i = 0; i < sk_X509_ATTRIBUTE_num (attrs); i++) { | ||
220 | attrib = sk_X509_ATTRIBUTE_value (attrs, i); | ||
221 | if (OBJ_obj2nid (attrib->object) == attr_nid) { | ||
222 | if (sk_ASN1_TYPE_num (attrib->value.set)) | ||
223 | return sk_ASN1_TYPE_value(attrib->value.set, 0); | ||
224 | else return NULL; | ||
225 | } | ||
226 | } | ||
227 | return NULL; | ||
228 | } | ||
229 | |||
230 | char *PKCS12_get_friendlyname(PKCS12_SAFEBAG *bag) | ||
231 | { | ||
232 | ASN1_TYPE *atype; | ||
233 | if (!(atype = PKCS12_get_attr(bag, NID_friendlyName))) return NULL; | ||
234 | if (atype->type != V_ASN1_BMPSTRING) return NULL; | ||
235 | return uni2asc(atype->value.bmpstring->data, | ||
236 | atype->value.bmpstring->length); | ||
237 | } | ||
238 | |||
diff --git a/src/lib/libcrypto/pkcs12/p12_crpt.c b/src/lib/libcrypto/pkcs12/p12_crpt.c new file mode 100644 index 0000000000..6de6f8128f --- /dev/null +++ b/src/lib/libcrypto/pkcs12/p12_crpt.c | |||
@@ -0,0 +1,122 @@ | |||
1 | /* p12_crpt.c */ | ||
2 | /* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL | ||
3 | * project 1999. | ||
4 | */ | ||
5 | /* ==================================================================== | ||
6 | * Copyright (c) 1999 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 | #include "cryptlib.h" | ||
61 | #include <openssl/pkcs12.h> | ||
62 | |||
63 | /* PKCS#12 specific PBE functions */ | ||
64 | |||
65 | void PKCS12_PBE_add(void) | ||
66 | { | ||
67 | #ifndef NO_RC4 | ||
68 | EVP_PBE_alg_add(NID_pbe_WithSHA1And128BitRC4, EVP_rc4(), EVP_sha1(), | ||
69 | PKCS12_PBE_keyivgen); | ||
70 | EVP_PBE_alg_add(NID_pbe_WithSHA1And40BitRC4, EVP_rc4_40(), EVP_sha1(), | ||
71 | PKCS12_PBE_keyivgen); | ||
72 | #endif | ||
73 | EVP_PBE_alg_add(NID_pbe_WithSHA1And3_Key_TripleDES_CBC, | ||
74 | EVP_des_ede3_cbc(), EVP_sha1(), PKCS12_PBE_keyivgen); | ||
75 | EVP_PBE_alg_add(NID_pbe_WithSHA1And2_Key_TripleDES_CBC, | ||
76 | EVP_des_ede_cbc(), EVP_sha1(), PKCS12_PBE_keyivgen); | ||
77 | #ifndef NO_RC2 | ||
78 | EVP_PBE_alg_add(NID_pbe_WithSHA1And128BitRC2_CBC, EVP_rc2_cbc(), | ||
79 | EVP_sha1(), PKCS12_PBE_keyivgen); | ||
80 | EVP_PBE_alg_add(NID_pbe_WithSHA1And40BitRC2_CBC, EVP_rc2_40_cbc(), | ||
81 | EVP_sha1(), PKCS12_PBE_keyivgen); | ||
82 | #endif | ||
83 | } | ||
84 | |||
85 | int PKCS12_PBE_keyivgen (EVP_CIPHER_CTX *ctx, const char *pass, int passlen, | ||
86 | ASN1_TYPE *param, EVP_CIPHER *cipher, EVP_MD *md, int en_de) | ||
87 | { | ||
88 | PBEPARAM *pbe; | ||
89 | int saltlen, iter; | ||
90 | unsigned char *salt, *pbuf; | ||
91 | unsigned char key[EVP_MAX_KEY_LENGTH], iv[EVP_MAX_IV_LENGTH]; | ||
92 | |||
93 | /* Extract useful info from parameter */ | ||
94 | pbuf = param->value.sequence->data; | ||
95 | if (!param || (param->type != V_ASN1_SEQUENCE) || | ||
96 | !(pbe = d2i_PBEPARAM (NULL, &pbuf, param->value.sequence->length))) { | ||
97 | EVPerr(PKCS12_F_PKCS12_PBE_KEYIVGEN,EVP_R_DECODE_ERROR); | ||
98 | return 0; | ||
99 | } | ||
100 | |||
101 | if (!pbe->iter) iter = 1; | ||
102 | else iter = ASN1_INTEGER_get (pbe->iter); | ||
103 | salt = pbe->salt->data; | ||
104 | saltlen = pbe->salt->length; | ||
105 | if (!PKCS12_key_gen (pass, passlen, salt, saltlen, PKCS12_KEY_ID, | ||
106 | iter, EVP_CIPHER_key_length(cipher), key, md)) { | ||
107 | PKCS12err(PKCS12_F_PKCS12_PBE_KEYIVGEN,PKCS12_R_KEY_GEN_ERROR); | ||
108 | PBEPARAM_free(pbe); | ||
109 | return 0; | ||
110 | } | ||
111 | if (!PKCS12_key_gen (pass, passlen, salt, saltlen, PKCS12_IV_ID, | ||
112 | iter, EVP_CIPHER_iv_length(cipher), iv, md)) { | ||
113 | PKCS12err(PKCS12_F_PKCS12_PBE_KEYIVGEN,PKCS12_R_IV_GEN_ERROR); | ||
114 | PBEPARAM_free(pbe); | ||
115 | return 0; | ||
116 | } | ||
117 | PBEPARAM_free(pbe); | ||
118 | EVP_CipherInit(ctx, cipher, key, iv, en_de); | ||
119 | memset(key, 0, EVP_MAX_KEY_LENGTH); | ||
120 | memset(iv, 0, EVP_MAX_IV_LENGTH); | ||
121 | return 1; | ||
122 | } | ||
diff --git a/src/lib/libcrypto/pkcs12/p12_crt.c b/src/lib/libcrypto/pkcs12/p12_crt.c new file mode 100644 index 0000000000..56d88b0759 --- /dev/null +++ b/src/lib/libcrypto/pkcs12/p12_crt.c | |||
@@ -0,0 +1,159 @@ | |||
1 | /* p12_crt.c */ | ||
2 | /* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL | ||
3 | * project 1999. | ||
4 | */ | ||
5 | /* ==================================================================== | ||
6 | * Copyright (c) 1999 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 | #include "cryptlib.h" | ||
61 | #include <openssl/pkcs12.h> | ||
62 | |||
63 | PKCS12 *PKCS12_create(char *pass, char *name, EVP_PKEY *pkey, X509 *cert, | ||
64 | STACK *ca, int nid_key, int nid_cert, int iter, int mac_iter, | ||
65 | int keytype) | ||
66 | { | ||
67 | PKCS12 *p12; | ||
68 | STACK *bags, *safes; | ||
69 | PKCS12_SAFEBAG *bag; | ||
70 | PKCS8_PRIV_KEY_INFO *p8; | ||
71 | PKCS7 *authsafe; | ||
72 | X509 *tcert; | ||
73 | int i; | ||
74 | unsigned char keyid[EVP_MAX_MD_SIZE]; | ||
75 | unsigned int keyidlen; | ||
76 | |||
77 | /* Set defaults */ | ||
78 | if(!nid_cert) nid_cert = NID_pbe_WithSHA1And40BitRC2_CBC; | ||
79 | if(!nid_key) nid_key = NID_pbe_WithSHA1And3_Key_TripleDES_CBC; | ||
80 | if(!iter) iter = PKCS12_DEFAULT_ITER; | ||
81 | if(!mac_iter) mac_iter = 1; | ||
82 | |||
83 | if(!pkey || !cert) { | ||
84 | PKCS12err(PKCS12_F_PKCS12_CREATE,PKCS12_R_INVALID_NULL_ARGUMENT); | ||
85 | return NULL; | ||
86 | } | ||
87 | |||
88 | if(!(bags = sk_new (NULL))) { | ||
89 | PKCS12err(PKCS12_F_PKCS12_CREATE,ERR_R_MALLOC_FAILURE); | ||
90 | return NULL; | ||
91 | } | ||
92 | |||
93 | /* Add user certificate */ | ||
94 | if(!(bag = M_PKCS12_x5092certbag(cert))) return NULL; | ||
95 | if(name && !PKCS12_add_friendlyname(bag, name, -1)) return NULL; | ||
96 | X509_digest(cert, EVP_sha1(), keyid, &keyidlen); | ||
97 | if(!PKCS12_add_localkeyid(bag, keyid, keyidlen)) return NULL; | ||
98 | |||
99 | if(!sk_push(bags, (char *)bag)) { | ||
100 | PKCS12err(PKCS12_F_PKCS12_CREATE,ERR_R_MALLOC_FAILURE); | ||
101 | return NULL; | ||
102 | } | ||
103 | |||
104 | /* Add all other certificates */ | ||
105 | if(ca) { | ||
106 | for(i = 0; i < sk_num(ca); i++) { | ||
107 | tcert = (X509 *)sk_value(ca, i); | ||
108 | if(!(bag = M_PKCS12_x5092certbag(tcert))) return NULL; | ||
109 | if(!sk_push(bags, (char *)bag)) { | ||
110 | PKCS12err(PKCS12_F_PKCS12_CREATE,ERR_R_MALLOC_FAILURE); | ||
111 | return NULL; | ||
112 | } | ||
113 | } | ||
114 | } | ||
115 | |||
116 | /* Turn certbags into encrypted authsafe */ | ||
117 | authsafe = PKCS12_pack_p7encdata (nid_cert, pass, -1, NULL, 0, | ||
118 | iter, bags); | ||
119 | sk_pop_free(bags, PKCS12_SAFEBAG_free); | ||
120 | |||
121 | if (!authsafe) return NULL; | ||
122 | |||
123 | if(!(safes = sk_new (NULL)) || !sk_push(safes, (char *)authsafe)) { | ||
124 | PKCS12err(PKCS12_F_PKCS12_CREATE,ERR_R_MALLOC_FAILURE); | ||
125 | return NULL; | ||
126 | } | ||
127 | |||
128 | /* Make a shrouded key bag */ | ||
129 | if(!(p8 = EVP_PKEY2PKCS8 (pkey))) return NULL; | ||
130 | if(keytype && !PKCS8_add_keyusage(p8, keytype)) return NULL; | ||
131 | bag = PKCS12_MAKE_SHKEYBAG (nid_key, pass, -1, NULL, 0, iter, p8); | ||
132 | if(!bag) return NULL; | ||
133 | PKCS8_PRIV_KEY_INFO_free(p8); | ||
134 | if (name && !PKCS12_add_friendlyname (bag, name, -1)) return NULL; | ||
135 | if(!PKCS12_add_localkeyid (bag, keyid, keyidlen)) return NULL; | ||
136 | if(!(bags = sk_new(NULL)) || !sk_push (bags, (char *)bag)) { | ||
137 | PKCS12err(PKCS12_F_PKCS12_CREATE,ERR_R_MALLOC_FAILURE); | ||
138 | return NULL; | ||
139 | } | ||
140 | /* Turn it into unencrypted safe bag */ | ||
141 | if(!(authsafe = PKCS12_pack_p7data (bags))) return NULL; | ||
142 | sk_pop_free(bags, PKCS12_SAFEBAG_free); | ||
143 | if(!sk_push(safes, (char *)authsafe)) { | ||
144 | PKCS12err(PKCS12_F_PKCS12_CREATE,ERR_R_MALLOC_FAILURE); | ||
145 | return NULL; | ||
146 | } | ||
147 | |||
148 | if(!(p12 = PKCS12_init (NID_pkcs7_data))) return NULL; | ||
149 | |||
150 | if(!M_PKCS12_pack_authsafes (p12, safes)) return NULL; | ||
151 | |||
152 | sk_pop_free(safes, PKCS7_free); | ||
153 | |||
154 | if(!PKCS12_set_mac (p12, pass, -1, NULL, 0, mac_iter, NULL)) | ||
155 | return NULL; | ||
156 | |||
157 | return p12; | ||
158 | |||
159 | } | ||
diff --git a/src/lib/libcrypto/pkcs12/p12_decr.c b/src/lib/libcrypto/pkcs12/p12_decr.c new file mode 100644 index 0000000000..d3d288e187 --- /dev/null +++ b/src/lib/libcrypto/pkcs12/p12_decr.c | |||
@@ -0,0 +1,185 @@ | |||
1 | /* p12_decr.c */ | ||
2 | /* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL | ||
3 | * project 1999. | ||
4 | */ | ||
5 | /* ==================================================================== | ||
6 | * Copyright (c) 1999 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 | #include "cryptlib.h" | ||
61 | #include <openssl/pkcs12.h> | ||
62 | |||
63 | /* Define this to dump decrypted output to files called DERnnn */ | ||
64 | /*#define DEBUG_DECRYPT*/ | ||
65 | |||
66 | |||
67 | /* Encrypt/Decrypt a buffer based on password and algor, result in a | ||
68 | * Malloc'ed buffer | ||
69 | */ | ||
70 | |||
71 | unsigned char * PKCS12_pbe_crypt (X509_ALGOR *algor, const char *pass, | ||
72 | int passlen, unsigned char *in, int inlen, unsigned char **data, | ||
73 | int *datalen, int en_de) | ||
74 | { | ||
75 | unsigned char *out; | ||
76 | int outlen, i; | ||
77 | EVP_CIPHER_CTX ctx; | ||
78 | |||
79 | /* Decrypt data */ | ||
80 | if (!EVP_PBE_CipherInit (algor->algorithm, pass, passlen, | ||
81 | algor->parameter, &ctx, en_de)) { | ||
82 | PKCS12err(PKCS12_F_PKCS12_PBE_CRYPT,PKCS12_R_PKCS12_ALGOR_CIPHERINIT_ERROR); | ||
83 | return NULL; | ||
84 | } | ||
85 | |||
86 | if(!(out = Malloc (inlen + EVP_CIPHER_CTX_block_size(&ctx)))) { | ||
87 | PKCS12err(PKCS12_F_PKCS12_PBE_CRYPT,ERR_R_MALLOC_FAILURE); | ||
88 | return NULL; | ||
89 | } | ||
90 | |||
91 | EVP_CipherUpdate (&ctx, out, &i, in, inlen); | ||
92 | outlen = i; | ||
93 | if(!EVP_CipherFinal (&ctx, out + i, &i)) { | ||
94 | Free (out); | ||
95 | PKCS12err(PKCS12_F_PKCS12_PBE_CRYPT,PKCS12_R_PKCS12_CIPHERFINAL_ERROR); | ||
96 | return NULL; | ||
97 | } | ||
98 | outlen += i; | ||
99 | if (datalen) *datalen = outlen; | ||
100 | if (data) *data = out; | ||
101 | return out; | ||
102 | |||
103 | } | ||
104 | |||
105 | /* Decrypt an OCTET STRING and decode ASN1 structure | ||
106 | * if seq & 1 'obj' is a stack of structures to be encoded | ||
107 | * if seq & 2 zero buffer after use | ||
108 | * as a sequence. | ||
109 | */ | ||
110 | |||
111 | char * PKCS12_decrypt_d2i (X509_ALGOR *algor, char * (*d2i)(), | ||
112 | void (*free_func)(), const char *pass, int passlen, | ||
113 | ASN1_OCTET_STRING *oct, int seq) | ||
114 | { | ||
115 | unsigned char *out, *p; | ||
116 | char *ret; | ||
117 | int outlen; | ||
118 | |||
119 | if (!PKCS12_pbe_crypt (algor, pass, passlen, oct->data, oct->length, | ||
120 | &out, &outlen, 0)) { | ||
121 | PKCS12err(PKCS12_F_PKCS12_DECRYPT_D2I,PKCS12_R_PKCS12_PBE_CRYPT_ERROR); | ||
122 | return NULL; | ||
123 | } | ||
124 | p = out; | ||
125 | #ifdef DEBUG_DECRYPT | ||
126 | { | ||
127 | FILE *op; | ||
128 | |||
129 | char fname[30]; | ||
130 | static int fnm = 1; | ||
131 | sprintf(fname, "DER%d", fnm++); | ||
132 | op = fopen(fname, "wb"); | ||
133 | fwrite (p, 1, outlen, op); | ||
134 | fclose(op); | ||
135 | } | ||
136 | #endif | ||
137 | if (seq & 1) ret = (char *) d2i_ASN1_SET(NULL, &p, outlen, d2i, | ||
138 | free_func, V_ASN1_SEQUENCE, V_ASN1_UNIVERSAL); | ||
139 | else ret = d2i(NULL, &p, outlen); | ||
140 | if (seq & 2) memset(out, 0, outlen); | ||
141 | if(!ret) PKCS12err(PKCS12_F_PKCS12_DECRYPT_D2I,PKCS12_R_DECODE_ERROR); | ||
142 | Free (out); | ||
143 | return ret; | ||
144 | } | ||
145 | |||
146 | /* Encode ASN1 structure and encrypt, return OCTET STRING | ||
147 | * if 'seq' is non-zero 'obj' is a stack of structures to be encoded | ||
148 | * as a sequence | ||
149 | */ | ||
150 | |||
151 | ASN1_OCTET_STRING *PKCS12_i2d_encrypt (X509_ALGOR *algor, int (*i2d)(), | ||
152 | const char *pass, int passlen, | ||
153 | char *obj, int seq) | ||
154 | { | ||
155 | ASN1_OCTET_STRING *oct; | ||
156 | unsigned char *in, *p; | ||
157 | int inlen; | ||
158 | if (!(oct = ASN1_OCTET_STRING_new ())) { | ||
159 | PKCS12err(PKCS12_F_PKCS12_I2D_ENCRYPT,ERR_R_MALLOC_FAILURE); | ||
160 | return NULL; | ||
161 | } | ||
162 | if (seq) inlen = i2d_ASN1_SET((STACK *)obj, NULL, i2d, V_ASN1_SEQUENCE, | ||
163 | V_ASN1_UNIVERSAL, IS_SEQUENCE); | ||
164 | else inlen = i2d (obj, NULL); | ||
165 | if (!inlen) { | ||
166 | PKCS12err(PKCS12_F_PKCS12_I2D_ENCRYPT,PKCS12_R_ENCODE_ERROR); | ||
167 | return NULL; | ||
168 | } | ||
169 | if (!(in = Malloc (inlen))) { | ||
170 | PKCS12err(PKCS12_F_PKCS12_I2D_ENCRYPT,ERR_R_MALLOC_FAILURE); | ||
171 | return NULL; | ||
172 | } | ||
173 | p = in; | ||
174 | if (seq) i2d_ASN1_SET((STACK *)obj, &p, i2d, V_ASN1_SEQUENCE, | ||
175 | V_ASN1_UNIVERSAL, IS_SEQUENCE); | ||
176 | else i2d (obj, &p); | ||
177 | if (!PKCS12_pbe_crypt (algor, pass, passlen, in, inlen, &oct->data, | ||
178 | &oct->length, 1)) { | ||
179 | PKCS12err(PKCS12_F_PKCS12_I2D_ENCRYPT,PKCS12_R_ENCRYPT_ERROR); | ||
180 | Free(in); | ||
181 | return NULL; | ||
182 | } | ||
183 | Free (in); | ||
184 | return oct; | ||
185 | } | ||
diff --git a/src/lib/libcrypto/pkcs12/p12_init.c b/src/lib/libcrypto/pkcs12/p12_init.c new file mode 100644 index 0000000000..dc6ab41db8 --- /dev/null +++ b/src/lib/libcrypto/pkcs12/p12_init.c | |||
@@ -0,0 +1,98 @@ | |||
1 | /* p12_init.c */ | ||
2 | /* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL | ||
3 | * project 1999. | ||
4 | */ | ||
5 | /* ==================================================================== | ||
6 | * Copyright (c) 1999 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 | #include "cryptlib.h" | ||
61 | #include <openssl/pkcs12.h> | ||
62 | |||
63 | /* Initialise a PKCS12 structure to take data */ | ||
64 | |||
65 | PKCS12 *PKCS12_init (int mode) | ||
66 | { | ||
67 | PKCS12 *pkcs12; | ||
68 | if (!(pkcs12 = PKCS12_new())) { | ||
69 | PKCS12err(PKCS12_F_PKCS12_INIT,ERR_R_MALLOC_FAILURE); | ||
70 | return NULL; | ||
71 | } | ||
72 | if (!(pkcs12->version = ASN1_INTEGER_new ())) { | ||
73 | PKCS12err(PKCS12_F_PKCS12_INIT,ERR_R_MALLOC_FAILURE); | ||
74 | return NULL; | ||
75 | } | ||
76 | ASN1_INTEGER_set (pkcs12->version, 3); | ||
77 | if (!(pkcs12->authsafes = PKCS7_new())) { | ||
78 | PKCS12err(PKCS12_F_PKCS12_INIT,ERR_R_MALLOC_FAILURE); | ||
79 | return NULL; | ||
80 | } | ||
81 | pkcs12->authsafes->type = OBJ_nid2obj(mode); | ||
82 | switch (mode) { | ||
83 | case NID_pkcs7_data: | ||
84 | if (!(pkcs12->authsafes->d.data = | ||
85 | ASN1_OCTET_STRING_new())) { | ||
86 | PKCS12err(PKCS12_F_PKCS12_INIT,ERR_R_MALLOC_FAILURE); | ||
87 | return NULL; | ||
88 | } | ||
89 | break; | ||
90 | default: | ||
91 | PKCS12err(PKCS12_F_PKCS12_INIT,PKCS12_R_UNSUPPORTED_PKCS12_MODE); | ||
92 | PKCS12_free(pkcs12); | ||
93 | return NULL; | ||
94 | break; | ||
95 | } | ||
96 | |||
97 | return pkcs12; | ||
98 | } | ||
diff --git a/src/lib/libcrypto/pkcs12/p12_key.c b/src/lib/libcrypto/pkcs12/p12_key.c new file mode 100644 index 0000000000..25d8cdae57 --- /dev/null +++ b/src/lib/libcrypto/pkcs12/p12_key.c | |||
@@ -0,0 +1,182 @@ | |||
1 | /* p12_key.c */ | ||
2 | /* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL | ||
3 | * project 1999. | ||
4 | */ | ||
5 | /* ==================================================================== | ||
6 | * Copyright (c) 1999 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 | #include "cryptlib.h" | ||
61 | #include <openssl/pkcs12.h> | ||
62 | |||
63 | |||
64 | /* Uncomment out this line to get debugging info about key generation */ | ||
65 | /*#define DEBUG_KEYGEN*/ | ||
66 | #ifdef DEBUG_KEYGEN | ||
67 | #include <bio.h> | ||
68 | extern BIO *bio_err; | ||
69 | void h__dump (unsigned char *p, int len); | ||
70 | #endif | ||
71 | |||
72 | /* PKCS12 compatible key/IV generation */ | ||
73 | #ifndef min | ||
74 | #define min(a,b) ((a) < (b) ? (a) : (b)) | ||
75 | #endif | ||
76 | |||
77 | int PKCS12_key_gen_asc (const char *pass, int passlen, unsigned char *salt, | ||
78 | int saltlen, int id, int iter, int n, unsigned char *out, | ||
79 | const EVP_MD *md_type) | ||
80 | { | ||
81 | int ret; | ||
82 | unsigned char *unipass; | ||
83 | int uniplen; | ||
84 | if (!asc2uni (pass, &unipass, &uniplen)) { | ||
85 | PKCS12err(PKCS12_F_PKCS12_KEY_GEN_ASC,ERR_R_MALLOC_FAILURE); | ||
86 | return 0; | ||
87 | } | ||
88 | ret = PKCS12_key_gen_uni (unipass, uniplen, salt, saltlen, | ||
89 | id, iter, n, out, md_type); | ||
90 | memset(unipass, 0, uniplen); /* Clear password from memory */ | ||
91 | Free(unipass); | ||
92 | return ret; | ||
93 | } | ||
94 | |||
95 | int PKCS12_key_gen_uni (unsigned char *pass, int passlen, unsigned char *salt, | ||
96 | int saltlen, int id, int iter, int n, unsigned char *out, | ||
97 | const EVP_MD *md_type) | ||
98 | { | ||
99 | unsigned char *B, *D, *I, *p, *Ai; | ||
100 | int Slen, Plen, Ilen; | ||
101 | int i, j, u, v; | ||
102 | BIGNUM *Ij, *Bpl1; /* These hold Ij and B + 1 */ | ||
103 | EVP_MD_CTX ctx; | ||
104 | #ifdef DEBUG_KEYGEN | ||
105 | unsigned char *tmpout = out; | ||
106 | int tmpn = n; | ||
107 | BIO_printf (bio_err, "KEYGEN DEBUG\n"); | ||
108 | BIO_printf (bio_err, "ID %d, ITER %d\n", id, iter); | ||
109 | BIO_printf (bio_err, "Password (length %d):\n", passlen); | ||
110 | h__dump (pass, passlen); | ||
111 | BIO_printf (bio_err, "Salt (length %d):\n", saltlen); | ||
112 | h__dump (salt, saltlen); | ||
113 | BIO_printf (bio_err, "ID %d, ITER %d\n\n", id, iter); | ||
114 | #endif | ||
115 | v = EVP_MD_block_size (md_type); | ||
116 | u = EVP_MD_size (md_type); | ||
117 | D = Malloc (v); | ||
118 | Ai = Malloc (u); | ||
119 | B = Malloc (v + 1); | ||
120 | Slen = v * ((saltlen+v-1)/v); | ||
121 | Plen = v * ((passlen+v-1)/v); | ||
122 | Ilen = Slen + Plen; | ||
123 | I = Malloc (Ilen); | ||
124 | Ij = BN_new(); | ||
125 | Bpl1 = BN_new(); | ||
126 | if (!D || !Ai || !B || !I || !Ij || !Bpl1) { | ||
127 | PKCS12err(PKCS12_F_PKCS12_KEY_GEN_UNI,ERR_R_MALLOC_FAILURE); | ||
128 | return 0; | ||
129 | } | ||
130 | for (i = 0; i < v; i++) D[i] = id; | ||
131 | p = I; | ||
132 | for (i = 0; i < Slen; i++) *p++ = salt[i % saltlen]; | ||
133 | for (i = 0; i < Plen; i++) *p++ = pass[i % passlen]; | ||
134 | for (;;) { | ||
135 | EVP_DigestInit (&ctx, md_type); | ||
136 | EVP_DigestUpdate (&ctx, D, v); | ||
137 | EVP_DigestUpdate (&ctx, I, Ilen); | ||
138 | EVP_DigestFinal (&ctx, Ai, NULL); | ||
139 | for (j = 1; j < iter; j++) { | ||
140 | EVP_DigestInit (&ctx, md_type); | ||
141 | EVP_DigestUpdate (&ctx, Ai, u); | ||
142 | EVP_DigestFinal (&ctx, Ai, NULL); | ||
143 | } | ||
144 | memcpy (out, Ai, min (n, u)); | ||
145 | if (u >= n) { | ||
146 | Free (Ai); | ||
147 | Free (B); | ||
148 | Free (D); | ||
149 | Free (I); | ||
150 | BN_free (Ij); | ||
151 | BN_free (Bpl1); | ||
152 | #ifdef DEBUG_KEYGEN | ||
153 | BIO_printf (bio_err, "Output KEY (length %d)\n", tmpn); | ||
154 | h__dump (tmpout, tmpn); | ||
155 | #endif | ||
156 | return 1; | ||
157 | } | ||
158 | n -= u; | ||
159 | out += u; | ||
160 | for (j = 0; j < v; j++) B[j] = Ai[j % u]; | ||
161 | /* Work out B + 1 first then can use B as tmp space */ | ||
162 | BN_bin2bn (B, v, Bpl1); | ||
163 | BN_add_word (Bpl1, 1); | ||
164 | for (j = 0; j < Ilen ; j+=v) { | ||
165 | BN_bin2bn (I + j, v, Ij); | ||
166 | BN_add (Ij, Ij, Bpl1); | ||
167 | BN_bn2bin (Ij, B); | ||
168 | /* If more than 2^(v*8) - 1 cut off MSB */ | ||
169 | if (BN_num_bytes (Ij) > v) { | ||
170 | BN_bn2bin (Ij, B); | ||
171 | memcpy (I + j, B + 1, v); | ||
172 | } else BN_bn2bin (Ij, I + j); | ||
173 | } | ||
174 | } | ||
175 | } | ||
176 | #ifdef DEBUG_KEYGEN | ||
177 | void h__dump (unsigned char *p, int len) | ||
178 | { | ||
179 | for (; len --; p++) BIO_printf (bio_err, "%02X", *p); | ||
180 | BIO_printf (bio_err, "\n"); | ||
181 | } | ||
182 | #endif | ||
diff --git a/src/lib/libcrypto/pkcs12/p12_kiss.c b/src/lib/libcrypto/pkcs12/p12_kiss.c new file mode 100644 index 0000000000..767e1303da --- /dev/null +++ b/src/lib/libcrypto/pkcs12/p12_kiss.c | |||
@@ -0,0 +1,238 @@ | |||
1 | /* p12_kiss.c */ | ||
2 | /* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL | ||
3 | * project 1999. | ||
4 | */ | ||
5 | /* ==================================================================== | ||
6 | * Copyright (c) 1999 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 | #include "cryptlib.h" | ||
61 | #include <openssl/pkcs12.h> | ||
62 | |||
63 | /* Simplified PKCS#12 routines */ | ||
64 | |||
65 | static int parse_pk12( PKCS12 *p12, const char *pass, int passlen, EVP_PKEY **pkey, X509 **cert, STACK **ca); | ||
66 | static int parse_bags( STACK *bags, const char *pass, int passlen, EVP_PKEY **pkey, X509 **cert, STACK **ca, ASN1_OCTET_STRING **keyid, char *keymatch); | ||
67 | static int parse_bag( PKCS12_SAFEBAG *bag, const char *pass, int passlen, EVP_PKEY **pkey, X509 **cert, STACK **ca, ASN1_OCTET_STRING **keyid, char *keymatch); | ||
68 | /* Parse and decrypt a PKCS#12 structure returning user key, user cert | ||
69 | * and other (CA) certs. Note either ca should be NULL, *ca should be NULL, | ||
70 | * or it should point to a valid STACK structure. pkey and cert can be | ||
71 | * passed unitialised. | ||
72 | */ | ||
73 | |||
74 | int PKCS12_parse (PKCS12 *p12, const char *pass, EVP_PKEY **pkey, X509 **cert, | ||
75 | STACK **ca) | ||
76 | { | ||
77 | |||
78 | /* Check for NULL PKCS12 structure */ | ||
79 | |||
80 | if(!p12) { | ||
81 | PKCS12err(PKCS12_F_PKCS12_PARSE,PKCS12_R_INVALID_NULL_PKCS12_POINTER); | ||
82 | return 0; | ||
83 | } | ||
84 | |||
85 | /* Allocate stack for ca certificates if needed */ | ||
86 | if ((ca != NULL) && (*ca == NULL)) { | ||
87 | if (!(*ca = sk_new(NULL))) { | ||
88 | PKCS12err(PKCS12_F_PKCS12_PARSE,ERR_R_MALLOC_FAILURE); | ||
89 | return 0; | ||
90 | } | ||
91 | } | ||
92 | |||
93 | if(pkey) *pkey = NULL; | ||
94 | if(cert) *cert = NULL; | ||
95 | |||
96 | /* Check the mac */ | ||
97 | |||
98 | if (!PKCS12_verify_mac (p12, pass, -1)) { | ||
99 | PKCS12err(PKCS12_F_PKCS12_PARSE,PKCS12_R_MAC_VERIFY_FAILURE); | ||
100 | goto err; | ||
101 | } | ||
102 | |||
103 | if (!parse_pk12 (p12, pass, -1, pkey, cert, ca)) { | ||
104 | PKCS12err(PKCS12_F_PKCS12_PARSE,PKCS12_R_PARSE_ERROR); | ||
105 | goto err; | ||
106 | } | ||
107 | |||
108 | return 1; | ||
109 | |||
110 | err: | ||
111 | |||
112 | if (pkey && *pkey) EVP_PKEY_free (*pkey); | ||
113 | if (cert && *cert) X509_free (*cert); | ||
114 | if (ca) sk_pop_free (*ca, X509_free); | ||
115 | return 0; | ||
116 | |||
117 | } | ||
118 | |||
119 | /* Parse the outer PKCS#12 structure */ | ||
120 | |||
121 | static int parse_pk12 (PKCS12 *p12, const char *pass, int passlen, | ||
122 | EVP_PKEY **pkey, X509 **cert, STACK **ca) | ||
123 | { | ||
124 | STACK *asafes, *bags; | ||
125 | int i, bagnid; | ||
126 | PKCS7 *p7; | ||
127 | ASN1_OCTET_STRING *keyid = NULL; | ||
128 | char keymatch = 0; | ||
129 | if (!( asafes = M_PKCS12_unpack_authsafes (p12))) return 0; | ||
130 | for (i = 0; i < sk_num (asafes); i++) { | ||
131 | p7 = (PKCS7 *) sk_value (asafes, i); | ||
132 | bagnid = OBJ_obj2nid (p7->type); | ||
133 | if (bagnid == NID_pkcs7_data) { | ||
134 | bags = M_PKCS12_unpack_p7data (p7); | ||
135 | } else if (bagnid == NID_pkcs7_encrypted) { | ||
136 | bags = M_PKCS12_unpack_p7encdata (p7, pass, passlen); | ||
137 | } else continue; | ||
138 | if (!bags) { | ||
139 | sk_pop_free (asafes, PKCS7_free); | ||
140 | return 0; | ||
141 | } | ||
142 | if (!parse_bags (bags, pass, passlen, pkey, cert, ca, | ||
143 | &keyid, &keymatch)) { | ||
144 | sk_pop_free (bags, PKCS12_SAFEBAG_free); | ||
145 | sk_pop_free (asafes, PKCS7_free); | ||
146 | return 0; | ||
147 | } | ||
148 | sk_pop_free (bags, PKCS12_SAFEBAG_free); | ||
149 | } | ||
150 | sk_pop_free (asafes, PKCS7_free); | ||
151 | if (keyid) ASN1_OCTET_STRING_free (keyid); | ||
152 | return 1; | ||
153 | } | ||
154 | |||
155 | |||
156 | static int parse_bags (STACK *bags, const char *pass, int passlen, | ||
157 | EVP_PKEY **pkey, X509 **cert, STACK **ca, | ||
158 | ASN1_OCTET_STRING **keyid, char *keymatch) | ||
159 | { | ||
160 | int i; | ||
161 | for (i = 0; i < sk_num (bags); i++) { | ||
162 | if (!parse_bag ((PKCS12_SAFEBAG *)sk_value (bags, i), | ||
163 | pass, passlen, pkey, cert, ca, keyid, | ||
164 | keymatch)) return 0; | ||
165 | } | ||
166 | return 1; | ||
167 | } | ||
168 | |||
169 | #define MATCH_KEY 0x1 | ||
170 | #define MATCH_CERT 0x2 | ||
171 | #define MATCH_ALL 0x3 | ||
172 | |||
173 | static int parse_bag (PKCS12_SAFEBAG *bag, const char *pass, int passlen, | ||
174 | EVP_PKEY **pkey, X509 **cert, STACK **ca, | ||
175 | ASN1_OCTET_STRING **keyid, | ||
176 | char *keymatch) | ||
177 | { | ||
178 | PKCS8_PRIV_KEY_INFO *p8; | ||
179 | X509 *x509; | ||
180 | ASN1_OCTET_STRING *lkey = NULL; | ||
181 | ASN1_TYPE *attrib; | ||
182 | |||
183 | |||
184 | if ((attrib = PKCS12_get_attr (bag, NID_localKeyID))) | ||
185 | lkey = attrib->value.octet_string; | ||
186 | |||
187 | /* Check for any local key id matching (if needed) */ | ||
188 | if (lkey && ((*keymatch & MATCH_ALL) != MATCH_ALL)) { | ||
189 | if (*keyid) { | ||
190 | if (ASN1_OCTET_STRING_cmp (*keyid, lkey)) lkey = NULL; | ||
191 | } else { | ||
192 | if (!(*keyid = ASN1_OCTET_STRING_dup (lkey))) { | ||
193 | PKCS12err(PKCS12_F_PARSE_BAGS,ERR_R_MALLOC_FAILURE); | ||
194 | return 0; | ||
195 | } | ||
196 | } | ||
197 | } | ||
198 | |||
199 | switch (M_PKCS12_bag_type(bag)) | ||
200 | { | ||
201 | case NID_keyBag: | ||
202 | if (!lkey || !pkey) return 1; | ||
203 | if (!(*pkey = EVP_PKCS82PKEY (bag->value.keybag))) return 0; | ||
204 | *keymatch |= MATCH_KEY; | ||
205 | break; | ||
206 | |||
207 | case NID_pkcs8ShroudedKeyBag: | ||
208 | if (!lkey || !pkey) return 1; | ||
209 | if (!(p8 = M_PKCS12_decrypt_skey (bag, pass, passlen))) | ||
210 | return 0; | ||
211 | *pkey = EVP_PKCS82PKEY (p8); | ||
212 | PKCS8_PRIV_KEY_INFO_free (p8); | ||
213 | if (!(*pkey)) return 0; | ||
214 | *keymatch |= MATCH_KEY; | ||
215 | break; | ||
216 | |||
217 | case NID_certBag: | ||
218 | if (M_PKCS12_cert_bag_type(bag) != NID_x509Certificate ) | ||
219 | return 1; | ||
220 | if (!(x509 = M_PKCS12_certbag2x509(bag))) return 0; | ||
221 | if (lkey) { | ||
222 | *keymatch |= MATCH_CERT; | ||
223 | if (cert) *cert = x509; | ||
224 | } else if (ca) sk_push (*ca, (char *)x509); | ||
225 | break; | ||
226 | |||
227 | case NID_safeContentsBag: | ||
228 | return parse_bags(bag->value.safes, pass, passlen, | ||
229 | pkey, cert, ca, keyid, keymatch); | ||
230 | break; | ||
231 | |||
232 | default: | ||
233 | return 1; | ||
234 | break; | ||
235 | } | ||
236 | return 1; | ||
237 | } | ||
238 | |||
diff --git a/src/lib/libcrypto/pkcs12/p12_mutl.c b/src/lib/libcrypto/pkcs12/p12_mutl.c new file mode 100644 index 0000000000..bac558d6b9 --- /dev/null +++ b/src/lib/libcrypto/pkcs12/p12_mutl.c | |||
@@ -0,0 +1,170 @@ | |||
1 | /* p12_mutl.c */ | ||
2 | /* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL | ||
3 | * project 1999. | ||
4 | */ | ||
5 | /* ==================================================================== | ||
6 | * Copyright (c) 1999 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 NO_HMAC | ||
60 | #include <stdio.h> | ||
61 | #include "cryptlib.h" | ||
62 | #include <openssl/hmac.h> | ||
63 | #include <openssl/rand.h> | ||
64 | #include <openssl/pkcs12.h> | ||
65 | |||
66 | /* Generate a MAC */ | ||
67 | int PKCS12_gen_mac (PKCS12 *p12, const char *pass, int passlen, | ||
68 | unsigned char *mac, unsigned int *maclen) | ||
69 | { | ||
70 | const EVP_MD *md_type; | ||
71 | HMAC_CTX hmac; | ||
72 | unsigned char key[PKCS12_MAC_KEY_LENGTH], *salt; | ||
73 | int saltlen, iter; | ||
74 | salt = p12->mac->salt->data; | ||
75 | saltlen = p12->mac->salt->length; | ||
76 | if (!p12->mac->iter) iter = 1; | ||
77 | else iter = ASN1_INTEGER_get (p12->mac->iter); | ||
78 | if(!(md_type = | ||
79 | EVP_get_digestbyobj (p12->mac->dinfo->algor->algorithm))) { | ||
80 | PKCS12err(PKCS12_F_PKCS12_GEN_MAC,PKCS12_R_UNKNOWN_DIGEST_ALGORITHM); | ||
81 | return 0; | ||
82 | } | ||
83 | if(!PKCS12_key_gen (pass, passlen, salt, saltlen, PKCS12_MAC_ID, iter, | ||
84 | PKCS12_MAC_KEY_LENGTH, key, md_type)) { | ||
85 | PKCS12err(PKCS12_F_PKCS12_GEN_MAC,PKCS12_R_KEY_GEN_ERROR); | ||
86 | return 0; | ||
87 | } | ||
88 | HMAC_Init (&hmac, key, PKCS12_MAC_KEY_LENGTH, md_type); | ||
89 | HMAC_Update (&hmac, p12->authsafes->d.data->data, | ||
90 | p12->authsafes->d.data->length); | ||
91 | HMAC_Final (&hmac, mac, maclen); | ||
92 | return 1; | ||
93 | } | ||
94 | |||
95 | /* Verify the mac */ | ||
96 | int PKCS12_verify_mac (PKCS12 *p12, const char *pass, int passlen) | ||
97 | { | ||
98 | unsigned char mac[EVP_MAX_MD_SIZE]; | ||
99 | unsigned int maclen; | ||
100 | if(p12->mac == NULL) { | ||
101 | PKCS12err(PKCS12_F_VERIFY_MAC,PKCS12_R_MAC_ABSENT); | ||
102 | return 0; | ||
103 | } | ||
104 | if (!PKCS12_gen_mac (p12, pass, passlen, mac, &maclen)) { | ||
105 | PKCS12err(PKCS12_F_VERIFY_MAC,PKCS12_R_MAC_GENERATION_ERROR); | ||
106 | return 0; | ||
107 | } | ||
108 | if ((maclen != (unsigned int)p12->mac->dinfo->digest->length) | ||
109 | || memcmp (mac, p12->mac->dinfo->digest->data, maclen)) { | ||
110 | PKCS12err(PKCS12_F_VERIFY_MAC,PKCS12_R_MAC_VERIFY_ERROR); | ||
111 | return 0; | ||
112 | } | ||
113 | return 1; | ||
114 | } | ||
115 | |||
116 | /* Set a mac */ | ||
117 | |||
118 | int PKCS12_set_mac (PKCS12 *p12, const char *pass, int passlen, | ||
119 | unsigned char *salt, int saltlen, int iter, EVP_MD *md_type) | ||
120 | { | ||
121 | unsigned char mac[EVP_MAX_MD_SIZE]; | ||
122 | unsigned int maclen; | ||
123 | |||
124 | if (!md_type) md_type = EVP_sha1(); | ||
125 | if (PKCS12_setup_mac (p12, iter, salt, saltlen, md_type) == | ||
126 | PKCS12_ERROR) { | ||
127 | PKCS12err(PKCS12_F_PKCS12_SET_MAC,PKCS12_R_MAC_SETUP_ERROR); | ||
128 | return 0; | ||
129 | } | ||
130 | if (!PKCS12_gen_mac (p12, pass, passlen, mac, &maclen)) { | ||
131 | PKCS12err(PKCS12_F_PKCS12_SET_MAC,PKCS12_R_MAC_GENERATION_ERROR); | ||
132 | return 0; | ||
133 | } | ||
134 | if (!(ASN1_OCTET_STRING_set (p12->mac->dinfo->digest, mac, maclen))) { | ||
135 | PKCS12err(PKCS12_F_PKCS12_SET_MAC,PKCS12_R_MAC_STRING_SET_ERROR); | ||
136 | return 0; | ||
137 | } | ||
138 | return 1; | ||
139 | } | ||
140 | |||
141 | /* Set up a mac structure */ | ||
142 | int PKCS12_setup_mac (PKCS12 *p12, int iter, unsigned char *salt, int saltlen, | ||
143 | EVP_MD *md_type) | ||
144 | { | ||
145 | if (!(p12->mac = PKCS12_MAC_DATA_new ())) return PKCS12_ERROR; | ||
146 | if (iter > 1) { | ||
147 | if(!(p12->mac->iter = ASN1_INTEGER_new())) { | ||
148 | PKCS12err(PKCS12_F_PKCS12_SETUP_MAC, ERR_R_MALLOC_FAILURE); | ||
149 | return 0; | ||
150 | } | ||
151 | ASN1_INTEGER_set (p12->mac->iter, iter); | ||
152 | } | ||
153 | if (!saltlen) saltlen = PKCS12_SALT_LEN; | ||
154 | p12->mac->salt->length = saltlen; | ||
155 | if (!(p12->mac->salt->data = Malloc (saltlen))) { | ||
156 | PKCS12err(PKCS12_F_PKCS12_SETUP_MAC, ERR_R_MALLOC_FAILURE); | ||
157 | return 0; | ||
158 | } | ||
159 | if (!salt) RAND_bytes (p12->mac->salt->data, saltlen); | ||
160 | else memcpy (p12->mac->salt->data, salt, saltlen); | ||
161 | p12->mac->dinfo->algor->algorithm = OBJ_nid2obj(EVP_MD_type(md_type)); | ||
162 | if (!(p12->mac->dinfo->algor->parameter = ASN1_TYPE_new())) { | ||
163 | PKCS12err(PKCS12_F_PKCS12_SETUP_MAC, ERR_R_MALLOC_FAILURE); | ||
164 | return 0; | ||
165 | } | ||
166 | p12->mac->dinfo->algor->parameter->type = V_ASN1_NULL; | ||
167 | |||
168 | return 1; | ||
169 | } | ||
170 | #endif | ||
diff --git a/src/lib/libcrypto/pkcs12/p12_npas.c b/src/lib/libcrypto/pkcs12/p12_npas.c new file mode 100644 index 0000000000..ee71707e2c --- /dev/null +++ b/src/lib/libcrypto/pkcs12/p12_npas.c | |||
@@ -0,0 +1,212 @@ | |||
1 | /* p12_npas.c */ | ||
2 | /* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL | ||
3 | * project 1999. | ||
4 | */ | ||
5 | /* ==================================================================== | ||
6 | * Copyright (c) 1999 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 | #include <stdlib.h> | ||
61 | #include <string.h> | ||
62 | #include <openssl/pem.h> | ||
63 | #include <openssl/err.h> | ||
64 | #include <openssl/pkcs12.h> | ||
65 | |||
66 | /* PKCS#12 password change routine */ | ||
67 | |||
68 | static int newpass_p12(PKCS12 *p12, char *oldpass, char *newpass); | ||
69 | static int newpass_bags(STACK *bags, char *oldpass, char *newpass); | ||
70 | static int newpass_bag(PKCS12_SAFEBAG *bag, char *oldpass, char *newpass); | ||
71 | static int alg_get(X509_ALGOR *alg, int *pnid, int *piter, int *psaltlen); | ||
72 | |||
73 | /* | ||
74 | * Change the password on a PKCS#12 structure. | ||
75 | */ | ||
76 | |||
77 | int PKCS12_newpass(PKCS12 *p12, char *oldpass, char *newpass) | ||
78 | { | ||
79 | |||
80 | /* Check for NULL PKCS12 structure */ | ||
81 | |||
82 | if(!p12) { | ||
83 | PKCS12err(PKCS12_F_PKCS12_NEWPASS,PKCS12_R_INVALID_NULL_PKCS12_POINTER); | ||
84 | return 0; | ||
85 | } | ||
86 | |||
87 | /* Check the mac */ | ||
88 | |||
89 | if (!PKCS12_verify_mac(p12, oldpass, -1)) { | ||
90 | PKCS12err(PKCS12_F_PKCS12_NEWPASS,PKCS12_R_MAC_VERIFY_FAILURE); | ||
91 | return 0; | ||
92 | } | ||
93 | |||
94 | if (!newpass_p12(p12, oldpass, newpass)) { | ||
95 | PKCS12err(PKCS12_F_PKCS12_NEWPASS,PKCS12_R_PARSE_ERROR); | ||
96 | return 0; | ||
97 | } | ||
98 | |||
99 | return 1; | ||
100 | |||
101 | } | ||
102 | |||
103 | /* Parse the outer PKCS#12 structure */ | ||
104 | |||
105 | static int newpass_p12(PKCS12 *p12, char *oldpass, char *newpass) | ||
106 | { | ||
107 | STACK *asafes, *newsafes, *bags; | ||
108 | int i, bagnid, pbe_nid, pbe_iter, pbe_saltlen; | ||
109 | PKCS7 *p7, *p7new; | ||
110 | ASN1_OCTET_STRING *p12_data_tmp = NULL, *macnew = NULL; | ||
111 | unsigned char mac[EVP_MAX_MD_SIZE]; | ||
112 | unsigned int maclen; | ||
113 | if (!(asafes = M_PKCS12_unpack_authsafes(p12))) return 0; | ||
114 | if(!(newsafes = sk_new(NULL))) return 0; | ||
115 | for (i = 0; i < sk_num (asafes); i++) { | ||
116 | p7 = (PKCS7 *) sk_value(asafes, i); | ||
117 | bagnid = OBJ_obj2nid(p7->type); | ||
118 | if (bagnid == NID_pkcs7_data) { | ||
119 | bags = M_PKCS12_unpack_p7data(p7); | ||
120 | } else if (bagnid == NID_pkcs7_encrypted) { | ||
121 | bags = M_PKCS12_unpack_p7encdata(p7, oldpass, -1); | ||
122 | alg_get(p7->d.encrypted->enc_data->algorithm, | ||
123 | &pbe_nid, &pbe_iter, &pbe_saltlen); | ||
124 | } else continue; | ||
125 | if (!bags) { | ||
126 | sk_pop_free(asafes, PKCS7_free); | ||
127 | return 0; | ||
128 | } | ||
129 | if (!newpass_bags(bags, oldpass, newpass)) { | ||
130 | sk_pop_free(bags, PKCS12_SAFEBAG_free); | ||
131 | sk_pop_free(asafes, PKCS7_free); | ||
132 | return 0; | ||
133 | } | ||
134 | /* Repack bag in same form with new password */ | ||
135 | if (bagnid == NID_pkcs7_data) p7new = PKCS12_pack_p7data(bags); | ||
136 | else p7new = PKCS12_pack_p7encdata(pbe_nid, newpass, -1, NULL, | ||
137 | pbe_saltlen, pbe_iter, bags); | ||
138 | sk_pop_free(bags, PKCS12_SAFEBAG_free); | ||
139 | if(!p7new) { | ||
140 | sk_pop_free(asafes, PKCS7_free); | ||
141 | return 0; | ||
142 | } | ||
143 | sk_push(newsafes, (char *)p7new); | ||
144 | } | ||
145 | sk_pop_free(asafes, PKCS7_free); | ||
146 | |||
147 | /* Repack safe: save old safe in case of error */ | ||
148 | |||
149 | p12_data_tmp = p12->authsafes->d.data; | ||
150 | if(!(p12->authsafes->d.data = ASN1_OCTET_STRING_new())) goto saferr; | ||
151 | if(!M_PKCS12_pack_authsafes(p12, newsafes)) goto saferr; | ||
152 | |||
153 | if(!PKCS12_gen_mac(p12, newpass, -1, mac, &maclen)) goto saferr; | ||
154 | if(!(macnew = ASN1_OCTET_STRING_new())) goto saferr; | ||
155 | if(!ASN1_OCTET_STRING_set(macnew, mac, maclen)) goto saferr; | ||
156 | ASN1_OCTET_STRING_free(p12->mac->dinfo->digest); | ||
157 | p12->mac->dinfo->digest = macnew; | ||
158 | ASN1_OCTET_STRING_free(p12_data_tmp); | ||
159 | |||
160 | return 1; | ||
161 | |||
162 | saferr: | ||
163 | /* Restore old safe */ | ||
164 | ASN1_OCTET_STRING_free(p12->authsafes->d.data); | ||
165 | ASN1_OCTET_STRING_free(macnew); | ||
166 | p12->authsafes->d.data = p12_data_tmp; | ||
167 | return 0; | ||
168 | |||
169 | } | ||
170 | |||
171 | |||
172 | static int newpass_bags(STACK *bags, char *oldpass, char *newpass) | ||
173 | { | ||
174 | int i; | ||
175 | for (i = 0; i < sk_num(bags); i++) { | ||
176 | if (!newpass_bag((PKCS12_SAFEBAG *)sk_value(bags, i), | ||
177 | oldpass, newpass)) return 0; | ||
178 | } | ||
179 | return 1; | ||
180 | } | ||
181 | |||
182 | /* Change password of safebag: only needs handle shrouded keybags */ | ||
183 | |||
184 | static int newpass_bag(PKCS12_SAFEBAG *bag, char *oldpass, char *newpass) | ||
185 | { | ||
186 | PKCS8_PRIV_KEY_INFO *p8; | ||
187 | X509_SIG *p8new; | ||
188 | int p8_nid, p8_saltlen, p8_iter; | ||
189 | |||
190 | if(M_PKCS12_bag_type(bag) != NID_pkcs8ShroudedKeyBag) return 1; | ||
191 | |||
192 | if (!(p8 = M_PKCS12_decrypt_skey(bag, oldpass, -1))) return 0; | ||
193 | alg_get(bag->value.shkeybag->algor, &p8_nid, &p8_iter, &p8_saltlen); | ||
194 | if(!(p8new = PKCS8_encrypt(p8_nid, NULL, newpass, -1, NULL, p8_saltlen, | ||
195 | p8_iter, p8))) return 0; | ||
196 | X509_SIG_free(bag->value.shkeybag); | ||
197 | bag->value.shkeybag = p8new; | ||
198 | return 1; | ||
199 | } | ||
200 | |||
201 | static int alg_get(X509_ALGOR *alg, int *pnid, int *piter, int *psaltlen) | ||
202 | { | ||
203 | PBEPARAM *pbe; | ||
204 | unsigned char *p; | ||
205 | p = alg->parameter->value.sequence->data; | ||
206 | pbe = d2i_PBEPARAM(NULL, &p, alg->parameter->value.sequence->length); | ||
207 | *pnid = OBJ_obj2nid(alg->algorithm); | ||
208 | *piter = ASN1_INTEGER_get(pbe->iter); | ||
209 | *psaltlen = pbe->salt->length; | ||
210 | PBEPARAM_free(pbe); | ||
211 | return 0; | ||
212 | } | ||
diff --git a/src/lib/libcrypto/pkcs12/p12_p8d.c b/src/lib/libcrypto/pkcs12/p12_p8d.c new file mode 100644 index 0000000000..3c6f377933 --- /dev/null +++ b/src/lib/libcrypto/pkcs12/p12_p8d.c | |||
@@ -0,0 +1,68 @@ | |||
1 | /* p12_p8d.c */ | ||
2 | /* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL | ||
3 | * project 2001. | ||
4 | */ | ||
5 | /* ==================================================================== | ||
6 | * Copyright (c) 2001 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 | #include "cryptlib.h" | ||
61 | #include <openssl/pkcs12.h> | ||
62 | |||
63 | PKCS8_PRIV_KEY_INFO *PKCS8_decrypt(X509_SIG *p8, const char *pass, int passlen) | ||
64 | { | ||
65 | return PKCS12_item_decrypt_d2i(p8->algor, ASN1_ITEM_rptr(PKCS8_PRIV_KEY_INFO), pass, | ||
66 | passlen, p8->digest, 1); | ||
67 | } | ||
68 | |||
diff --git a/src/lib/libcrypto/pkcs12/p12_p8e.c b/src/lib/libcrypto/pkcs12/p12_p8e.c new file mode 100644 index 0000000000..3d47956652 --- /dev/null +++ b/src/lib/libcrypto/pkcs12/p12_p8e.c | |||
@@ -0,0 +1,97 @@ | |||
1 | /* p12_p8e.c */ | ||
2 | /* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL | ||
3 | * project 2001. | ||
4 | */ | ||
5 | /* ==================================================================== | ||
6 | * Copyright (c) 2001 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 | #include "cryptlib.h" | ||
61 | #include <openssl/pkcs12.h> | ||
62 | |||
63 | X509_SIG *PKCS8_encrypt(int pbe_nid, const EVP_CIPHER *cipher, | ||
64 | const char *pass, int passlen, | ||
65 | unsigned char *salt, int saltlen, int iter, | ||
66 | PKCS8_PRIV_KEY_INFO *p8inf) | ||
67 | { | ||
68 | X509_SIG *p8 = NULL; | ||
69 | X509_ALGOR *pbe; | ||
70 | |||
71 | if (!(p8 = X509_SIG_new())) { | ||
72 | PKCS12err(PKCS12_F_PKCS8_ENCRYPT, ERR_R_MALLOC_FAILURE); | ||
73 | goto err; | ||
74 | } | ||
75 | |||
76 | if(pbe_nid == -1) pbe = PKCS5_pbe2_set(cipher, iter, salt, saltlen); | ||
77 | else pbe = PKCS5_pbe_set(pbe_nid, iter, salt, saltlen); | ||
78 | if(!pbe) { | ||
79 | PKCS12err(PKCS12_F_PKCS8_ENCRYPT, ERR_R_ASN1_LIB); | ||
80 | goto err; | ||
81 | } | ||
82 | X509_ALGOR_free(p8->algor); | ||
83 | p8->algor = pbe; | ||
84 | M_ASN1_OCTET_STRING_free(p8->digest); | ||
85 | p8->digest = PKCS12_item_i2d_encrypt(pbe, ASN1_ITEM_rptr(PKCS8_PRIV_KEY_INFO), | ||
86 | pass, passlen, p8inf, 1); | ||
87 | if(!p8->digest) { | ||
88 | PKCS12err(PKCS12_F_PKCS8_ENCRYPT, PKCS12_R_ENCRYPT_ERROR); | ||
89 | goto err; | ||
90 | } | ||
91 | |||
92 | return p8; | ||
93 | |||
94 | err: | ||
95 | X509_SIG_free(p8); | ||
96 | return NULL; | ||
97 | } | ||
diff --git a/src/lib/libcrypto/pkcs12/p12_utl.c b/src/lib/libcrypto/pkcs12/p12_utl.c new file mode 100644 index 0000000000..2adcbc95e1 --- /dev/null +++ b/src/lib/libcrypto/pkcs12/p12_utl.c | |||
@@ -0,0 +1,118 @@ | |||
1 | /* p12_utl.c */ | ||
2 | /* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL | ||
3 | * project 1999. | ||
4 | */ | ||
5 | /* ==================================================================== | ||
6 | * Copyright (c) 1999 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 | #include "cryptlib.h" | ||
61 | #include <openssl/pkcs12.h> | ||
62 | |||
63 | /* Cheap and nasty Unicode stuff */ | ||
64 | |||
65 | unsigned char *asc2uni (const char *asc, unsigned char **uni, int *unilen) | ||
66 | { | ||
67 | int ulen, i; | ||
68 | unsigned char *unitmp; | ||
69 | ulen = strlen(asc)*2 + 2; | ||
70 | if (!(unitmp = Malloc (ulen))) return NULL; | ||
71 | for (i = 0; i < ulen; i+=2) { | ||
72 | unitmp[i] = 0; | ||
73 | unitmp[i + 1] = asc[i>>1]; | ||
74 | } | ||
75 | if (unilen) *unilen = ulen; | ||
76 | if (uni) *uni = unitmp; | ||
77 | return unitmp; | ||
78 | } | ||
79 | |||
80 | char *uni2asc (unsigned char *uni, int unilen) | ||
81 | { | ||
82 | int asclen, i; | ||
83 | char *asctmp; | ||
84 | asclen = unilen / 2; | ||
85 | /* If no terminating zero allow for one */ | ||
86 | if (uni[unilen - 1]) asclen++; | ||
87 | uni++; | ||
88 | if (!(asctmp = Malloc (asclen))) return NULL; | ||
89 | for (i = 0; i < unilen; i+=2) asctmp[i>>1] = uni[i]; | ||
90 | asctmp[asclen - 1] = 0; | ||
91 | return asctmp; | ||
92 | } | ||
93 | |||
94 | int i2d_PKCS12_bio(BIO *bp, PKCS12 *p12) | ||
95 | { | ||
96 | return ASN1_i2d_bio((int(*)())i2d_PKCS12, bp, (unsigned char *)p12); | ||
97 | } | ||
98 | |||
99 | #ifndef NO_FP_API | ||
100 | int i2d_PKCS12_fp(FILE *fp, PKCS12 *p12) | ||
101 | { | ||
102 | return ASN1_i2d_fp((int(*)())i2d_PKCS12, fp, (unsigned char *)p12); | ||
103 | } | ||
104 | #endif | ||
105 | |||
106 | PKCS12 *d2i_PKCS12_bio(BIO *bp, PKCS12 **p12) | ||
107 | { | ||
108 | return (PKCS12 *)ASN1_d2i_bio((char *(*)())PKCS12_new, | ||
109 | (char *(*)())d2i_PKCS12, bp, (unsigned char **)p12); | ||
110 | } | ||
111 | #ifndef NO_FP_API | ||
112 | PKCS12 *d2i_PKCS12_fp(FILE *fp, PKCS12 **p12) | ||
113 | { | ||
114 | return (PKCS12 *)ASN1_d2i_fp((char *(*)())PKCS12_new, | ||
115 | (char *(*)())d2i_PKCS12, fp, (unsigned char **)(p12)); | ||
116 | } | ||
117 | #endif | ||
118 | |||
diff --git a/src/lib/libcrypto/pkcs12/pk12err.c b/src/lib/libcrypto/pkcs12/pk12err.c new file mode 100644 index 0000000000..38d7be7675 --- /dev/null +++ b/src/lib/libcrypto/pkcs12/pk12err.c | |||
@@ -0,0 +1,136 @@ | |||
1 | /* crypto/pkcs12/pk12err.c */ | ||
2 | /* ==================================================================== | ||
3 | * Copyright (c) 1999 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 | */ | ||
59 | |||
60 | #include <stdio.h> | ||
61 | #include <openssl/err.h> | ||
62 | #include <openssl/pkcs12.h> | ||
63 | |||
64 | /* BEGIN ERROR CODES */ | ||
65 | #ifndef NO_ERR | ||
66 | static ERR_STRING_DATA PKCS12_str_functs[]= | ||
67 | { | ||
68 | {ERR_PACK(0,PKCS12_F_PARSE_BAGS,0), "PARSE_BAGS"}, | ||
69 | {ERR_PACK(0,PKCS12_F_PKCS12_ADD_FRIENDLYNAME,0), "PKCS12_ADD_FRIENDLYNAME"}, | ||
70 | {ERR_PACK(0,PKCS12_F_PKCS12_ADD_FRIENDLYNAME_ASC,0), "PKCS12_add_friendlyname_asc"}, | ||
71 | {ERR_PACK(0,PKCS12_F_PKCS12_ADD_FRIENDLYNAME_UNI,0), "PKCS12_add_friendlyname_uni"}, | ||
72 | {ERR_PACK(0,PKCS12_F_PKCS12_ADD_LOCALKEYID,0), "PKCS12_add_localkeyid"}, | ||
73 | {ERR_PACK(0,PKCS12_F_PKCS12_CREATE,0), "PKCS12_create"}, | ||
74 | {ERR_PACK(0,PKCS12_F_PKCS12_DECRYPT_D2I,0), "PKCS12_decrypt_d2i"}, | ||
75 | {ERR_PACK(0,PKCS12_F_PKCS12_GEN_MAC,0), "PKCS12_gen_mac"}, | ||
76 | {ERR_PACK(0,PKCS12_F_PKCS12_I2D_ENCRYPT,0), "PKCS12_i2d_encrypt"}, | ||
77 | {ERR_PACK(0,PKCS12_F_PKCS12_INIT,0), "PKCS12_init"}, | ||
78 | {ERR_PACK(0,PKCS12_F_PKCS12_KEY_GEN_ASC,0), "PKCS12_key_gen_asc"}, | ||
79 | {ERR_PACK(0,PKCS12_F_PKCS12_KEY_GEN_UNI,0), "PKCS12_key_gen_uni"}, | ||
80 | {ERR_PACK(0,PKCS12_F_PKCS12_MAKE_KEYBAG,0), "PKCS12_MAKE_KEYBAG"}, | ||
81 | {ERR_PACK(0,PKCS12_F_PKCS12_MAKE_SHKEYBAG,0), "PKCS12_MAKE_SHKEYBAG"}, | ||
82 | {ERR_PACK(0,PKCS12_F_PKCS12_PACK_P7DATA,0), "PKCS12_pack_p7data"}, | ||
83 | {ERR_PACK(0,PKCS12_F_PKCS12_PACK_P7ENCDATA,0), "PKCS12_pack_p7encdata"}, | ||
84 | {ERR_PACK(0,PKCS12_F_PKCS12_PACK_SAFEBAG,0), "PKCS12_pack_safebag"}, | ||
85 | {ERR_PACK(0,PKCS12_F_PKCS12_PARSE,0), "PKCS12_parse"}, | ||
86 | {ERR_PACK(0,PKCS12_F_PKCS12_PBE_CRYPT,0), "PKCS12_pbe_crypt"}, | ||
87 | {ERR_PACK(0,PKCS12_F_PKCS12_PBE_KEYIVGEN,0), "PKCS12_PBE_keyivgen"}, | ||
88 | {ERR_PACK(0,PKCS12_F_PKCS12_SETUP_MAC,0), "PKCS12_setup_mac"}, | ||
89 | {ERR_PACK(0,PKCS12_F_PKCS12_SET_MAC,0), "PKCS12_set_mac"}, | ||
90 | {ERR_PACK(0,PKCS12_F_PKCS8_ADD_KEYUSAGE,0), "PKCS8_add_keyusage"}, | ||
91 | {ERR_PACK(0,PKCS12_F_PKCS8_ENCRYPT,0), "PKCS8_encrypt"}, | ||
92 | {ERR_PACK(0,PKCS12_F_VERIFY_MAC,0), "VERIFY_MAC"}, | ||
93 | {0,NULL} | ||
94 | }; | ||
95 | |||
96 | static ERR_STRING_DATA PKCS12_str_reasons[]= | ||
97 | { | ||
98 | {PKCS12_R_CANT_PACK_STRUCTURE ,"cant pack structure"}, | ||
99 | {PKCS12_R_DECODE_ERROR ,"decode error"}, | ||
100 | {PKCS12_R_ENCODE_ERROR ,"encode error"}, | ||
101 | {PKCS12_R_ENCRYPT_ERROR ,"encrypt error"}, | ||
102 | {PKCS12_R_INVALID_NULL_ARGUMENT ,"invalid null argument"}, | ||
103 | {PKCS12_R_INVALID_NULL_PKCS12_POINTER ,"invalid null pkcs12 pointer"}, | ||
104 | {PKCS12_R_IV_GEN_ERROR ,"iv gen error"}, | ||
105 | {PKCS12_R_KEY_GEN_ERROR ,"key gen error"}, | ||
106 | {PKCS12_R_MAC_ABSENT ,"mac absent"}, | ||
107 | {PKCS12_R_MAC_GENERATION_ERROR ,"mac generation error"}, | ||
108 | {PKCS12_R_MAC_SETUP_ERROR ,"mac setup error"}, | ||
109 | {PKCS12_R_MAC_STRING_SET_ERROR ,"mac string set error"}, | ||
110 | {PKCS12_R_MAC_VERIFY_ERROR ,"mac verify error"}, | ||
111 | {PKCS12_R_MAC_VERIFY_FAILURE ,"mac verify failure"}, | ||
112 | {PKCS12_R_PARSE_ERROR ,"parse error"}, | ||
113 | {PKCS12_R_PKCS12_ALGOR_CIPHERINIT_ERROR ,"pkcs12 algor cipherinit error"}, | ||
114 | {PKCS12_R_PKCS12_CIPHERFINAL_ERROR ,"pkcs12 cipherfinal error"}, | ||
115 | {PKCS12_R_PKCS12_PBE_CRYPT_ERROR ,"pkcs12 pbe crypt error"}, | ||
116 | {PKCS12_R_UNKNOWN_DIGEST_ALGORITHM ,"unknown digest algorithm"}, | ||
117 | {PKCS12_R_UNSUPPORTED_PKCS12_MODE ,"unsupported pkcs12 mode"}, | ||
118 | {0,NULL} | ||
119 | }; | ||
120 | |||
121 | #endif | ||
122 | |||
123 | void ERR_load_PKCS12_strings(void) | ||
124 | { | ||
125 | static int init=1; | ||
126 | |||
127 | if (init) | ||
128 | { | ||
129 | init=0; | ||
130 | #ifndef NO_ERR | ||
131 | ERR_load_strings(ERR_LIB_PKCS12,PKCS12_str_functs); | ||
132 | ERR_load_strings(ERR_LIB_PKCS12,PKCS12_str_reasons); | ||
133 | #endif | ||
134 | |||
135 | } | ||
136 | } | ||
diff --git a/src/lib/libcrypto/pkcs12/pkcs12.h b/src/lib/libcrypto/pkcs12/pkcs12.h new file mode 100644 index 0000000000..4cfba5e6c6 --- /dev/null +++ b/src/lib/libcrypto/pkcs12/pkcs12.h | |||
@@ -0,0 +1,337 @@ | |||
1 | /* pkcs12.h */ | ||
2 | /* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL | ||
3 | * project 1999. | ||
4 | */ | ||
5 | /* ==================================================================== | ||
6 | * Copyright (c) 1999 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_PKCS12_H | ||
60 | #define HEADER_PKCS12_H | ||
61 | |||
62 | #ifdef __cplusplus | ||
63 | extern "C" { | ||
64 | #endif | ||
65 | |||
66 | #include <openssl/bio.h> | ||
67 | #include <openssl/x509.h> | ||
68 | |||
69 | #define PKCS12_KEY_ID 1 | ||
70 | #define PKCS12_IV_ID 2 | ||
71 | #define PKCS12_MAC_ID 3 | ||
72 | |||
73 | /* Default iteration count */ | ||
74 | #ifndef PKCS12_DEFAULT_ITER | ||
75 | #define PKCS12_DEFAULT_ITER PKCS5_DEFAULT_ITER | ||
76 | #endif | ||
77 | |||
78 | #define PKCS12_MAC_KEY_LENGTH 20 | ||
79 | |||
80 | #define PKCS12_SALT_LEN 8 | ||
81 | |||
82 | /* Uncomment out next line for unicode password and names, otherwise ASCII */ | ||
83 | |||
84 | /*#define PBE_UNICODE*/ | ||
85 | |||
86 | #ifdef PBE_UNICODE | ||
87 | #define PKCS12_key_gen PKCS12_key_gen_uni | ||
88 | #define PKCS12_add_friendlyname PKCS12_add_friendlyname_uni | ||
89 | #else | ||
90 | #define PKCS12_key_gen PKCS12_key_gen_asc | ||
91 | #define PKCS12_add_friendlyname PKCS12_add_friendlyname_asc | ||
92 | #endif | ||
93 | |||
94 | /* MS key usage constants */ | ||
95 | |||
96 | #define KEY_EX 0x10 | ||
97 | #define KEY_SIG 0x80 | ||
98 | |||
99 | typedef struct { | ||
100 | X509_SIG *dinfo; | ||
101 | ASN1_OCTET_STRING *salt; | ||
102 | ASN1_INTEGER *iter; /* defaults to 1 */ | ||
103 | } PKCS12_MAC_DATA; | ||
104 | |||
105 | typedef struct { | ||
106 | ASN1_INTEGER *version; | ||
107 | PKCS12_MAC_DATA *mac; | ||
108 | PKCS7 *authsafes; | ||
109 | } PKCS12; | ||
110 | |||
111 | typedef struct { | ||
112 | ASN1_OBJECT *type; | ||
113 | union { | ||
114 | struct pkcs12_bag_st *bag; /* secret, crl and certbag */ | ||
115 | struct pkcs8_priv_key_info_st *keybag; /* keybag */ | ||
116 | X509_SIG *shkeybag; /* shrouded key bag */ | ||
117 | STACK /* PKCS12_SAFEBAG */ *safes; | ||
118 | ASN1_TYPE *other; | ||
119 | }value; | ||
120 | STACK_OF(X509_ATTRIBUTE) *attrib; | ||
121 | ASN1_TYPE *rest; | ||
122 | } PKCS12_SAFEBAG; | ||
123 | |||
124 | typedef struct pkcs12_bag_st { | ||
125 | ASN1_OBJECT *type; | ||
126 | union { | ||
127 | ASN1_OCTET_STRING *x509cert; | ||
128 | ASN1_OCTET_STRING *x509crl; | ||
129 | ASN1_OCTET_STRING *octet; | ||
130 | ASN1_IA5STRING *sdsicert; | ||
131 | ASN1_TYPE *other; /* Secret or other bag */ | ||
132 | }value; | ||
133 | } PKCS12_BAGS; | ||
134 | |||
135 | #define PKCS12_ERROR 0 | ||
136 | #define PKCS12_OK 1 | ||
137 | |||
138 | #define M_PKCS12_bag_type(bag) OBJ_obj2nid(bag->type) | ||
139 | #define M_PKCS12_cert_bag_type(bag) OBJ_obj2nid(bag->value.bag->type) | ||
140 | #define M_PKCS12_crl_bag_type M_PKCS12_cert_bag_type | ||
141 | |||
142 | #define M_PKCS12_x5092certbag(x509) \ | ||
143 | PKCS12_pack_safebag ((char *)(x509), i2d_X509, NID_x509Certificate, NID_certBag) | ||
144 | |||
145 | #define M_PKCS12_x509crl2certbag(crl) \ | ||
146 | PKCS12_pack_safebag ((char *)(crl), i2d_X509CRL, NID_x509Crl, NID_crlBag) | ||
147 | |||
148 | #define M_PKCS12_certbag2x509(bg) \ | ||
149 | (X509 *) ASN1_unpack_string ((bg)->value.bag->value.octet, \ | ||
150 | (char *(*)())d2i_X509) | ||
151 | |||
152 | #define M_PKCS12_certbag2x509crl(bg) \ | ||
153 | (X509CRL *) ASN1_unpack_string ((bg)->value.bag->value.octet, \ | ||
154 | (char *(*)())d2i_X509CRL) | ||
155 | |||
156 | /*#define M_PKCS12_pkcs82rsa(p8) \ | ||
157 | (RSA *) ASN1_unpack_string ((p8)->pkey, (char *(*)())d2i_RSAPrivateKey)*/ | ||
158 | |||
159 | #define M_PKCS12_unpack_p7data(p7) \ | ||
160 | ASN1_seq_unpack ((p7)->d.data->data, p7->d.data->length, \ | ||
161 | (char *(*)())d2i_PKCS12_SAFEBAG, PKCS12_SAFEBAG_free) | ||
162 | |||
163 | #define M_PKCS12_pack_authsafes(p12, safes) \ | ||
164 | ASN1_seq_pack((safes), (int (*)())i2d_PKCS7,\ | ||
165 | &(p12)->authsafes->d.data->data, &(p12)->authsafes->d.data->length) | ||
166 | |||
167 | #define M_PKCS12_unpack_authsafes(p12) \ | ||
168 | ASN1_seq_unpack((p12)->authsafes->d.data->data, \ | ||
169 | (p12)->authsafes->d.data->length, (char *(*)())d2i_PKCS7, \ | ||
170 | PKCS7_free) | ||
171 | |||
172 | #define M_PKCS12_unpack_p7encdata(p7, pass, passlen) \ | ||
173 | (STACK *) PKCS12_decrypt_d2i ((p7)->d.encrypted->enc_data->algorithm,\ | ||
174 | (char *(*)())d2i_PKCS12_SAFEBAG, PKCS12_SAFEBAG_free, \ | ||
175 | (pass), (passlen), \ | ||
176 | (p7)->d.encrypted->enc_data->enc_data, 3) | ||
177 | |||
178 | #define M_PKCS12_decrypt_skey(bag, pass, passlen) \ | ||
179 | (PKCS8_PRIV_KEY_INFO *) PKCS12_decrypt_d2i ((bag)->value.shkeybag->algor, \ | ||
180 | (char *(*)())d2i_PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO_free, \ | ||
181 | (pass), (passlen), \ | ||
182 | (bag)->value.shkeybag->digest, 2) | ||
183 | |||
184 | #define M_PKCS8_decrypt(p8, pass, passlen) \ | ||
185 | (PKCS8_PRIV_KEY_INFO *) PKCS12_decrypt_d2i ((p8)->algor, \ | ||
186 | (char *(*)())d2i_PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO_free,\ | ||
187 | (pass), (passlen), (p8)->digest, 2) | ||
188 | |||
189 | #define PKCS12_get_attr(bag, attr_nid) \ | ||
190 | PKCS12_get_attr_gen(bag->attrib, attr_nid) | ||
191 | |||
192 | #define PKCS8_get_attr(p8, attr_nid) \ | ||
193 | PKCS12_get_attr_gen(p8->attributes, attr_nid) | ||
194 | |||
195 | #define PKCS12_mac_present(p12) ((p12)->mac ? 1 : 0) | ||
196 | |||
197 | |||
198 | PKCS12_SAFEBAG *PKCS12_pack_safebag(char *obj, int (*i2d)(), int nid1, int nid2); | ||
199 | PKCS12_SAFEBAG *PKCS12_MAKE_KEYBAG(PKCS8_PRIV_KEY_INFO *p8); | ||
200 | X509_SIG *PKCS8_encrypt(int pbe_nid, const EVP_CIPHER *cipher, | ||
201 | const char *pass, int passlen, | ||
202 | unsigned char *salt, int saltlen, int iter, | ||
203 | PKCS8_PRIV_KEY_INFO *p8); | ||
204 | PKCS12_SAFEBAG *PKCS12_MAKE_SHKEYBAG(int pbe_nid, const char *pass, | ||
205 | int passlen, unsigned char *salt, | ||
206 | int saltlen, int iter, | ||
207 | PKCS8_PRIV_KEY_INFO *p8); | ||
208 | PKCS7 *PKCS12_pack_p7data(STACK *sk); | ||
209 | PKCS7 *PKCS12_pack_p7encdata(int pbe_nid, const char *pass, int passlen, | ||
210 | unsigned char *salt, int saltlen, int iter, | ||
211 | STACK *bags); | ||
212 | int PKCS12_add_localkeyid(PKCS12_SAFEBAG *bag, unsigned char *name, int namelen); | ||
213 | int PKCS12_add_friendlyname_asc(PKCS12_SAFEBAG *bag, const char *name, | ||
214 | int namelen); | ||
215 | int PKCS12_add_friendlyname_uni(PKCS12_SAFEBAG *bag, const unsigned char *name, | ||
216 | int namelen); | ||
217 | int PKCS8_add_keyusage(PKCS8_PRIV_KEY_INFO *p8, int usage); | ||
218 | ASN1_TYPE *PKCS12_get_attr_gen(STACK_OF(X509_ATTRIBUTE) *attrs, int attr_nid); | ||
219 | char *PKCS12_get_friendlyname(PKCS12_SAFEBAG *bag); | ||
220 | unsigned char *PKCS12_pbe_crypt(X509_ALGOR *algor, const char *pass, | ||
221 | int passlen, unsigned char *in, int inlen, | ||
222 | unsigned char **data, int *datalen, int en_de); | ||
223 | char *PKCS12_decrypt_d2i(X509_ALGOR *algor, char *(*d2i)(), | ||
224 | void (*free_func)(), const char *pass, int passlen, | ||
225 | ASN1_STRING *oct, int seq); | ||
226 | ASN1_STRING *PKCS12_i2d_encrypt(X509_ALGOR *algor, int (*i2d)(), | ||
227 | const char *pass, int passlen, char *obj, | ||
228 | int seq); | ||
229 | PKCS12 *PKCS12_init(int mode); | ||
230 | int PKCS12_key_gen_asc(const char *pass, int passlen, unsigned char *salt, | ||
231 | int saltlen, int id, int iter, int n, | ||
232 | unsigned char *out, const EVP_MD *md_type); | ||
233 | int PKCS12_key_gen_uni(unsigned char *pass, int passlen, unsigned char *salt, int saltlen, int id, int iter, int n, unsigned char *out, const EVP_MD *md_type); | ||
234 | int PKCS12_PBE_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen, | ||
235 | ASN1_TYPE *param, EVP_CIPHER *cipher, EVP_MD *md_type, | ||
236 | int en_de); | ||
237 | int PKCS12_gen_mac(PKCS12 *p12, const char *pass, int passlen, | ||
238 | unsigned char *mac, unsigned int *maclen); | ||
239 | int PKCS12_verify_mac(PKCS12 *p12, const char *pass, int passlen); | ||
240 | int PKCS12_set_mac(PKCS12 *p12, const char *pass, int passlen, | ||
241 | unsigned char *salt, int saltlen, int iter, | ||
242 | EVP_MD *md_type); | ||
243 | int PKCS12_setup_mac(PKCS12 *p12, int iter, unsigned char *salt, | ||
244 | int saltlen, EVP_MD *md_type); | ||
245 | unsigned char *asc2uni(const char *asc, unsigned char **uni, int *unilen); | ||
246 | char *uni2asc(unsigned char *uni, int unilen); | ||
247 | int i2d_PKCS12_BAGS(PKCS12_BAGS *a, unsigned char **pp); | ||
248 | PKCS12_BAGS *PKCS12_BAGS_new(void); | ||
249 | PKCS12_BAGS *d2i_PKCS12_BAGS(PKCS12_BAGS **a, unsigned char **pp, long length); | ||
250 | void PKCS12_BAGS_free(PKCS12_BAGS *a); | ||
251 | int i2d_PKCS12(PKCS12 *a, unsigned char **pp); | ||
252 | PKCS12 *d2i_PKCS12(PKCS12 **a, unsigned char **pp, long length); | ||
253 | PKCS12 *PKCS12_new(void); | ||
254 | void PKCS12_free(PKCS12 *a); | ||
255 | int i2d_PKCS12_MAC_DATA(PKCS12_MAC_DATA *a, unsigned char **pp); | ||
256 | PKCS12_MAC_DATA *PKCS12_MAC_DATA_new(void); | ||
257 | PKCS12_MAC_DATA *d2i_PKCS12_MAC_DATA(PKCS12_MAC_DATA **a, unsigned char **pp, | ||
258 | long length); | ||
259 | void PKCS12_MAC_DATA_free(PKCS12_MAC_DATA *a); | ||
260 | int i2d_PKCS12_SAFEBAG(PKCS12_SAFEBAG *a, unsigned char **pp); | ||
261 | PKCS12_SAFEBAG *PKCS12_SAFEBAG_new(void); | ||
262 | PKCS12_SAFEBAG *d2i_PKCS12_SAFEBAG(PKCS12_SAFEBAG **a, unsigned char **pp, | ||
263 | long length); | ||
264 | void PKCS12_SAFEBAG_free(PKCS12_SAFEBAG *a); | ||
265 | void ERR_load_PKCS12_strings(void); | ||
266 | void PKCS12_PBE_add(void); | ||
267 | int PKCS12_parse(PKCS12 *p12, const char *pass, EVP_PKEY **pkey, X509 **cert, | ||
268 | STACK **ca); | ||
269 | PKCS12 *PKCS12_create(char *pass, char *name, EVP_PKEY *pkey, X509 *cert, | ||
270 | STACK *ca, int nid_key, int nid_cert, int iter, | ||
271 | int mac_iter, int keytype); | ||
272 | int i2d_PKCS12_bio(BIO *bp, PKCS12 *p12); | ||
273 | int i2d_PKCS12_fp(FILE *fp, PKCS12 *p12); | ||
274 | PKCS12 *d2i_PKCS12_bio(BIO *bp, PKCS12 **p12); | ||
275 | PKCS12 *d2i_PKCS12_fp(FILE *fp, PKCS12 **p12); | ||
276 | |||
277 | /* BEGIN ERROR CODES */ | ||
278 | /* The following lines are auto generated by the script mkerr.pl. Any changes | ||
279 | * made after this point may be overwritten when the script is next run. | ||
280 | */ | ||
281 | |||
282 | /* Error codes for the PKCS12 functions. */ | ||
283 | |||
284 | /* Function codes. */ | ||
285 | #define PKCS12_F_PARSE_BAGS 103 | ||
286 | #define PKCS12_F_PKCS12_ADD_FRIENDLYNAME 100 | ||
287 | #define PKCS12_F_PKCS12_ADD_FRIENDLYNAME_ASC 127 | ||
288 | #define PKCS12_F_PKCS12_ADD_FRIENDLYNAME_UNI 102 | ||
289 | #define PKCS12_F_PKCS12_ADD_LOCALKEYID 104 | ||
290 | #define PKCS12_F_PKCS12_CREATE 105 | ||
291 | #define PKCS12_F_PKCS12_DECRYPT_D2I 106 | ||
292 | #define PKCS12_F_PKCS12_GEN_MAC 107 | ||
293 | #define PKCS12_F_PKCS12_I2D_ENCRYPT 108 | ||
294 | #define PKCS12_F_PKCS12_INIT 109 | ||
295 | #define PKCS12_F_PKCS12_KEY_GEN_ASC 110 | ||
296 | #define PKCS12_F_PKCS12_KEY_GEN_UNI 111 | ||
297 | #define PKCS12_F_PKCS12_MAKE_KEYBAG 112 | ||
298 | #define PKCS12_F_PKCS12_MAKE_SHKEYBAG 113 | ||
299 | #define PKCS12_F_PKCS12_PACK_P7DATA 114 | ||
300 | #define PKCS12_F_PKCS12_PACK_P7ENCDATA 115 | ||
301 | #define PKCS12_F_PKCS12_PACK_SAFEBAG 117 | ||
302 | #define PKCS12_F_PKCS12_PARSE 118 | ||
303 | #define PKCS12_F_PKCS12_PBE_CRYPT 119 | ||
304 | #define PKCS12_F_PKCS12_PBE_KEYIVGEN 120 | ||
305 | #define PKCS12_F_PKCS12_SETUP_MAC 122 | ||
306 | #define PKCS12_F_PKCS12_SET_MAC 123 | ||
307 | #define PKCS12_F_PKCS8_ADD_KEYUSAGE 124 | ||
308 | #define PKCS12_F_PKCS8_ENCRYPT 125 | ||
309 | #define PKCS12_F_VERIFY_MAC 126 | ||
310 | |||
311 | /* Reason codes. */ | ||
312 | #define PKCS12_R_CANT_PACK_STRUCTURE 100 | ||
313 | #define PKCS12_R_DECODE_ERROR 101 | ||
314 | #define PKCS12_R_ENCODE_ERROR 102 | ||
315 | #define PKCS12_R_ENCRYPT_ERROR 103 | ||
316 | #define PKCS12_R_INVALID_NULL_ARGUMENT 104 | ||
317 | #define PKCS12_R_INVALID_NULL_PKCS12_POINTER 105 | ||
318 | #define PKCS12_R_IV_GEN_ERROR 106 | ||
319 | #define PKCS12_R_KEY_GEN_ERROR 107 | ||
320 | #define PKCS12_R_MAC_ABSENT 108 | ||
321 | #define PKCS12_R_MAC_GENERATION_ERROR 109 | ||
322 | #define PKCS12_R_MAC_SETUP_ERROR 110 | ||
323 | #define PKCS12_R_MAC_STRING_SET_ERROR 111 | ||
324 | #define PKCS12_R_MAC_VERIFY_ERROR 112 | ||
325 | #define PKCS12_R_MAC_VERIFY_FAILURE 113 | ||
326 | #define PKCS12_R_PARSE_ERROR 114 | ||
327 | #define PKCS12_R_PKCS12_ALGOR_CIPHERINIT_ERROR 115 | ||
328 | #define PKCS12_R_PKCS12_CIPHERFINAL_ERROR 116 | ||
329 | #define PKCS12_R_PKCS12_PBE_CRYPT_ERROR 117 | ||
330 | #define PKCS12_R_UNKNOWN_DIGEST_ALGORITHM 118 | ||
331 | #define PKCS12_R_UNSUPPORTED_PKCS12_MODE 119 | ||
332 | |||
333 | #ifdef __cplusplus | ||
334 | } | ||
335 | #endif | ||
336 | #endif | ||
337 | |||
diff --git a/src/lib/libcrypto/pkcs7/pk7_asn1.c b/src/lib/libcrypto/pkcs7/pk7_asn1.c new file mode 100644 index 0000000000..46f0fc9375 --- /dev/null +++ b/src/lib/libcrypto/pkcs7/pk7_asn1.c | |||
@@ -0,0 +1,213 @@ | |||
1 | /* pk7_asn.c */ | ||
2 | /* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL | ||
3 | * project 2000. | ||
4 | */ | ||
5 | /* ==================================================================== | ||
6 | * Copyright (c) 2000 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 | #include "cryptlib.h" | ||
61 | #include <openssl/asn1t.h> | ||
62 | #include <openssl/pkcs7.h> | ||
63 | #include <openssl/x509.h> | ||
64 | |||
65 | /* PKCS#7 ASN1 module */ | ||
66 | |||
67 | /* This is the ANY DEFINED BY table for the top level PKCS#7 structure */ | ||
68 | |||
69 | ASN1_ADB_TEMPLATE(p7default) = ASN1_EXP_OPT(PKCS7, d.other, ASN1_ANY, 0); | ||
70 | |||
71 | ASN1_ADB(PKCS7) = { | ||
72 | ADB_ENTRY(NID_pkcs7_data, ASN1_EXP_OPT(PKCS7, d.data, ASN1_OCTET_STRING, 0)), | ||
73 | ADB_ENTRY(NID_pkcs7_signed, ASN1_EXP_OPT(PKCS7, d.sign, PKCS7_SIGNED, 0)), | ||
74 | ADB_ENTRY(NID_pkcs7_enveloped, ASN1_EXP_OPT(PKCS7, d.enveloped, PKCS7_ENVELOPE, 0)), | ||
75 | ADB_ENTRY(NID_pkcs7_signedAndEnveloped, ASN1_EXP_OPT(PKCS7, d.signed_and_enveloped, PKCS7_SIGN_ENVELOPE, 0)), | ||
76 | ADB_ENTRY(NID_pkcs7_digest, ASN1_EXP_OPT(PKCS7, d.digest, PKCS7_DIGEST, 0)), | ||
77 | ADB_ENTRY(NID_pkcs7_encrypted, ASN1_EXP_OPT(PKCS7, d.encrypted, PKCS7_ENCRYPT, 0)) | ||
78 | } ASN1_ADB_END(PKCS7, 0, type, 0, &p7default_tt, NULL); | ||
79 | |||
80 | ASN1_SEQUENCE(PKCS7) = { | ||
81 | ASN1_SIMPLE(PKCS7, type, ASN1_OBJECT), | ||
82 | ASN1_ADB_OBJECT(PKCS7) | ||
83 | }ASN1_SEQUENCE_END(PKCS7) | ||
84 | |||
85 | IMPLEMENT_ASN1_FUNCTIONS(PKCS7) | ||
86 | IMPLEMENT_ASN1_DUP_FUNCTION(PKCS7) | ||
87 | |||
88 | ASN1_SEQUENCE(PKCS7_SIGNED) = { | ||
89 | ASN1_SIMPLE(PKCS7_SIGNED, version, ASN1_INTEGER), | ||
90 | ASN1_SET_OF(PKCS7_SIGNED, md_algs, X509_ALGOR), | ||
91 | ASN1_SIMPLE(PKCS7_SIGNED, contents, PKCS7), | ||
92 | ASN1_IMP_SEQUENCE_OF_OPT(PKCS7_SIGNED, cert, X509, 0), | ||
93 | ASN1_IMP_SET_OF_OPT(PKCS7_SIGNED, crl, X509_CRL, 1), | ||
94 | ASN1_SET_OF(PKCS7_SIGNED, signer_info, PKCS7_SIGNER_INFO) | ||
95 | } ASN1_SEQUENCE_END(PKCS7_SIGNED) | ||
96 | |||
97 | IMPLEMENT_ASN1_FUNCTIONS(PKCS7_SIGNED) | ||
98 | |||
99 | /* Minor tweak to operation: free up EVP_PKEY */ | ||
100 | static int si_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it) | ||
101 | { | ||
102 | if(operation == ASN1_OP_FREE_POST) { | ||
103 | PKCS7_SIGNER_INFO *si = (PKCS7_SIGNER_INFO *)*pval; | ||
104 | EVP_PKEY_free(si->pkey); | ||
105 | } | ||
106 | return 1; | ||
107 | } | ||
108 | |||
109 | ASN1_SEQUENCE_cb(PKCS7_SIGNER_INFO, si_cb) = { | ||
110 | ASN1_SIMPLE(PKCS7_SIGNER_INFO, version, ASN1_INTEGER), | ||
111 | ASN1_SIMPLE(PKCS7_SIGNER_INFO, issuer_and_serial, PKCS7_ISSUER_AND_SERIAL), | ||
112 | ASN1_SIMPLE(PKCS7_SIGNER_INFO, digest_alg, X509_ALGOR), | ||
113 | /* NB this should be a SET OF but we use a SEQUENCE OF so the | ||
114 | * original order * is retained when the structure is reencoded. | ||
115 | * Since the attributes are implicitly tagged this will not affect | ||
116 | * the encoding. | ||
117 | */ | ||
118 | ASN1_IMP_SEQUENCE_OF_OPT(PKCS7_SIGNER_INFO, auth_attr, X509_ATTRIBUTE, 0), | ||
119 | ASN1_SIMPLE(PKCS7_SIGNER_INFO, digest_enc_alg, X509_ALGOR), | ||
120 | ASN1_SIMPLE(PKCS7_SIGNER_INFO, enc_digest, ASN1_OCTET_STRING), | ||
121 | ASN1_IMP_SET_OF_OPT(PKCS7_SIGNER_INFO, unauth_attr, X509_ATTRIBUTE, 1) | ||
122 | } ASN1_SEQUENCE_END_cb(PKCS7_SIGNER_INFO, PKCS7_SIGNER_INFO) | ||
123 | |||
124 | IMPLEMENT_ASN1_FUNCTIONS(PKCS7_SIGNER_INFO) | ||
125 | |||
126 | ASN1_SEQUENCE(PKCS7_ISSUER_AND_SERIAL) = { | ||
127 | ASN1_SIMPLE(PKCS7_ISSUER_AND_SERIAL, issuer, X509_NAME), | ||
128 | ASN1_SIMPLE(PKCS7_ISSUER_AND_SERIAL, serial, ASN1_INTEGER) | ||
129 | } ASN1_SEQUENCE_END(PKCS7_ISSUER_AND_SERIAL) | ||
130 | |||
131 | IMPLEMENT_ASN1_FUNCTIONS(PKCS7_ISSUER_AND_SERIAL) | ||
132 | |||
133 | ASN1_SEQUENCE(PKCS7_ENVELOPE) = { | ||
134 | ASN1_SIMPLE(PKCS7_ENVELOPE, version, ASN1_INTEGER), | ||
135 | ASN1_SET_OF(PKCS7_ENVELOPE, recipientinfo, PKCS7_RECIP_INFO), | ||
136 | ASN1_SIMPLE(PKCS7_ENVELOPE, enc_data, PKCS7_ENC_CONTENT) | ||
137 | } ASN1_SEQUENCE_END(PKCS7_ENVELOPE) | ||
138 | |||
139 | IMPLEMENT_ASN1_FUNCTIONS(PKCS7_ENVELOPE) | ||
140 | |||
141 | /* Minor tweak to operation: free up X509 */ | ||
142 | static int ri_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it) | ||
143 | { | ||
144 | if(operation == ASN1_OP_FREE_POST) { | ||
145 | PKCS7_RECIP_INFO *ri = (PKCS7_RECIP_INFO *)*pval; | ||
146 | X509_free(ri->cert); | ||
147 | } | ||
148 | return 1; | ||
149 | } | ||
150 | |||
151 | ASN1_SEQUENCE_cb(PKCS7_RECIP_INFO, ri_cb) = { | ||
152 | ASN1_SIMPLE(PKCS7_RECIP_INFO, version, ASN1_INTEGER), | ||
153 | ASN1_SIMPLE(PKCS7_RECIP_INFO, issuer_and_serial, PKCS7_ISSUER_AND_SERIAL), | ||
154 | ASN1_SIMPLE(PKCS7_RECIP_INFO, key_enc_algor, X509_ALGOR), | ||
155 | ASN1_SIMPLE(PKCS7_RECIP_INFO, enc_key, ASN1_OCTET_STRING) | ||
156 | } ASN1_SEQUENCE_END_cb(PKCS7_RECIP_INFO, PKCS7_RECIP_INFO) | ||
157 | |||
158 | IMPLEMENT_ASN1_FUNCTIONS(PKCS7_RECIP_INFO) | ||
159 | |||
160 | ASN1_SEQUENCE(PKCS7_ENC_CONTENT) = { | ||
161 | ASN1_SIMPLE(PKCS7_ENC_CONTENT, content_type, ASN1_OBJECT), | ||
162 | ASN1_SIMPLE(PKCS7_ENC_CONTENT, algorithm, X509_ALGOR), | ||
163 | ASN1_IMP_OPT(PKCS7_ENC_CONTENT, enc_data, ASN1_OCTET_STRING, 0) | ||
164 | } ASN1_SEQUENCE_END(PKCS7_ENC_CONTENT) | ||
165 | |||
166 | IMPLEMENT_ASN1_FUNCTIONS(PKCS7_ENC_CONTENT) | ||
167 | |||
168 | ASN1_SEQUENCE(PKCS7_SIGN_ENVELOPE) = { | ||
169 | ASN1_SIMPLE(PKCS7_SIGN_ENVELOPE, version, ASN1_INTEGER), | ||
170 | ASN1_SET_OF(PKCS7_SIGN_ENVELOPE, recipientinfo, PKCS7_RECIP_INFO), | ||
171 | ASN1_SET_OF(PKCS7_SIGN_ENVELOPE, md_algs, X509_ALGOR), | ||
172 | ASN1_SIMPLE(PKCS7_SIGN_ENVELOPE, enc_data, PKCS7_ENC_CONTENT), | ||
173 | ASN1_IMP_SET_OF_OPT(PKCS7_SIGN_ENVELOPE, cert, X509, 0), | ||
174 | ASN1_IMP_SET_OF_OPT(PKCS7_SIGN_ENVELOPE, crl, X509_CRL, 1), | ||
175 | ASN1_SET_OF(PKCS7_SIGN_ENVELOPE, signer_info, PKCS7_SIGNER_INFO) | ||
176 | } ASN1_SEQUENCE_END(PKCS7_SIGN_ENVELOPE) | ||
177 | |||
178 | IMPLEMENT_ASN1_FUNCTIONS(PKCS7_SIGN_ENVELOPE) | ||
179 | |||
180 | ASN1_SEQUENCE(PKCS7_ENCRYPT) = { | ||
181 | ASN1_SIMPLE(PKCS7_ENCRYPT, version, ASN1_INTEGER), | ||
182 | ASN1_SIMPLE(PKCS7_ENCRYPT, enc_data, PKCS7_ENC_CONTENT) | ||
183 | } ASN1_SEQUENCE_END(PKCS7_ENCRYPT) | ||
184 | |||
185 | IMPLEMENT_ASN1_FUNCTIONS(PKCS7_ENCRYPT) | ||
186 | |||
187 | ASN1_SEQUENCE(PKCS7_DIGEST) = { | ||
188 | ASN1_SIMPLE(PKCS7_DIGEST, version, ASN1_INTEGER), | ||
189 | ASN1_SIMPLE(PKCS7_DIGEST, md, X509_ALGOR), | ||
190 | ASN1_SIMPLE(PKCS7_DIGEST, contents, PKCS7), | ||
191 | ASN1_SIMPLE(PKCS7_DIGEST, digest, ASN1_OCTET_STRING) | ||
192 | } ASN1_SEQUENCE_END(PKCS7_DIGEST) | ||
193 | |||
194 | IMPLEMENT_ASN1_FUNCTIONS(PKCS7_DIGEST) | ||
195 | |||
196 | /* Specials for authenticated attributes */ | ||
197 | |||
198 | /* When signing attributes we want to reorder them to match the sorted | ||
199 | * encoding. | ||
200 | */ | ||
201 | |||
202 | ASN1_ITEM_TEMPLATE(PKCS7_ATTR_SIGN) = | ||
203 | ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SET_ORDER, 0, PKCS7_ATTRIBUTES, X509_ATTRIBUTE) | ||
204 | ASN1_ITEM_TEMPLATE_END(PKCS7_ATTR_SIGN) | ||
205 | |||
206 | /* When verifying attributes we need to use the received order. So | ||
207 | * we use SEQUENCE OF and tag it to SET OF | ||
208 | */ | ||
209 | |||
210 | ASN1_ITEM_TEMPLATE(PKCS7_ATTR_VERIFY) = | ||
211 | ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF | ASN1_TFLG_IMPTAG | ASN1_TFLG_UNIVERSAL, | ||
212 | V_ASN1_SET, PKCS7_ATTRIBUTES, X509_ATTRIBUTE) | ||
213 | ASN1_ITEM_TEMPLATE_END(PKCS7_ATTR_VERIFY) | ||
diff --git a/src/lib/libcrypto/pkcs7/pk7_attr.c b/src/lib/libcrypto/pkcs7/pk7_attr.c new file mode 100644 index 0000000000..3b9c0fe3f2 --- /dev/null +++ b/src/lib/libcrypto/pkcs7/pk7_attr.c | |||
@@ -0,0 +1,85 @@ | |||
1 | /* pk7_attr.c */ | ||
2 | /* S/MIME code. | ||
3 | * Copyright (C) 1997-8 Dr S N Henson (shenson@bigfoot.com) | ||
4 | * All Rights Reserved. | ||
5 | * Redistribution of this code without the authors permission is expressly | ||
6 | * prohibited. | ||
7 | */ | ||
8 | |||
9 | #include <stdio.h> | ||
10 | #include <stdlib.h> | ||
11 | #include <openssl/bio.h> | ||
12 | #include <openssl/asn1.h> | ||
13 | #include <openssl/pem.h> | ||
14 | #include <openssl/pkcs7.h> | ||
15 | #include <openssl/err.h> | ||
16 | |||
17 | int PKCS7_add_attrib_smimecap(PKCS7_SIGNER_INFO *si, STACK *cap) | ||
18 | { | ||
19 | ASN1_STRING *seq; | ||
20 | unsigned char *p, *pp; | ||
21 | int len; | ||
22 | len=i2d_ASN1_SET(cap,NULL,i2d_X509_ALGOR, V_ASN1_SEQUENCE, | ||
23 | V_ASN1_UNIVERSAL, IS_SEQUENCE); | ||
24 | if(!(pp=(unsigned char *)Malloc(len))) { | ||
25 | PKCS7err(PKCS7_F_PKCS7_ADD_ATTRIB_SMIMECAP,ERR_R_MALLOC_FAILURE); | ||
26 | return 0; | ||
27 | } | ||
28 | p=pp; | ||
29 | i2d_ASN1_SET(cap,&p,i2d_X509_ALGOR, V_ASN1_SEQUENCE, | ||
30 | V_ASN1_UNIVERSAL, IS_SEQUENCE); | ||
31 | if(!(seq = ASN1_STRING_new())) { | ||
32 | PKCS7err(PKCS7_F_PKCS7_ADD_ATTRIB_SMIMECAP,ERR_R_MALLOC_FAILURE); | ||
33 | return 0; | ||
34 | } | ||
35 | if(!ASN1_STRING_set (seq, pp, len)) { | ||
36 | PKCS7err(PKCS7_F_PKCS7_ADD_ATTRIB_SMIMECAP,ERR_R_MALLOC_FAILURE); | ||
37 | return 0; | ||
38 | } | ||
39 | Free (pp); | ||
40 | return PKCS7_add_signed_attribute(si, NID_SMIMECapabilities, | ||
41 | V_ASN1_SEQUENCE, seq); | ||
42 | } | ||
43 | |||
44 | STACK *PKCS7_get_smimecap(PKCS7_SIGNER_INFO *si) | ||
45 | { | ||
46 | ASN1_TYPE *cap; | ||
47 | unsigned char *p; | ||
48 | cap = PKCS7_get_signed_attribute(si, NID_SMIMECapabilities); | ||
49 | if (!cap) return NULL; | ||
50 | p = cap->value.sequence->data; | ||
51 | return d2i_ASN1_SET (NULL, &p, cap->value.sequence->length, | ||
52 | (char *(*)())d2i_X509_ALGOR, X509_ALGOR_free, V_ASN1_SEQUENCE, | ||
53 | V_ASN1_UNIVERSAL); | ||
54 | } | ||
55 | |||
56 | /* Basic smime-capabilities OID and optional integer arg */ | ||
57 | int PKCS7_simple_smimecap(STACK *sk, int nid, int arg) | ||
58 | { | ||
59 | X509_ALGOR *alg; | ||
60 | if(!(alg = X509_ALGOR_new())) { | ||
61 | PKCS7err(PKCS7_F_PKCS7_SIMPLE_SMIMECAP,ERR_R_MALLOC_FAILURE); | ||
62 | return 0; | ||
63 | } | ||
64 | ASN1_OBJECT_free(alg->algorithm); | ||
65 | alg->algorithm = OBJ_nid2obj (nid); | ||
66 | if (arg > 0) { | ||
67 | ASN1_INTEGER *nbit; | ||
68 | if(!(alg->parameter = ASN1_TYPE_new())) { | ||
69 | PKCS7err(PKCS7_F_PKCS7_SIMPLE_SMIMECAP,ERR_R_MALLOC_FAILURE); | ||
70 | return 0; | ||
71 | } | ||
72 | if(!(nbit = ASN1_INTEGER_new())) { | ||
73 | PKCS7err(PKCS7_F_PKCS7_SIMPLE_SMIMECAP,ERR_R_MALLOC_FAILURE); | ||
74 | return 0; | ||
75 | } | ||
76 | if(!ASN1_INTEGER_set (nbit, arg)) { | ||
77 | PKCS7err(PKCS7_F_PKCS7_SIMPLE_SMIMECAP,ERR_R_MALLOC_FAILURE); | ||
78 | return 0; | ||
79 | } | ||
80 | alg->parameter->value.integer = nbit; | ||
81 | alg->parameter->type = V_ASN1_INTEGER; | ||
82 | } | ||
83 | sk_push (sk, (char *)alg); | ||
84 | return 1; | ||
85 | } | ||
diff --git a/src/lib/libcrypto/pkcs7/pk7_mime.c b/src/lib/libcrypto/pkcs7/pk7_mime.c new file mode 100644 index 0000000000..734643be28 --- /dev/null +++ b/src/lib/libcrypto/pkcs7/pk7_mime.c | |||
@@ -0,0 +1,673 @@ | |||
1 | /* pk7_mime.c */ | ||
2 | /* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL | ||
3 | * project 1999. | ||
4 | */ | ||
5 | /* ==================================================================== | ||
6 | * Copyright (c) 1999 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 | #include <ctype.h> | ||
61 | #include "cryptlib.h" | ||
62 | #include <openssl/rand.h> | ||
63 | #include <openssl/x509.h> | ||
64 | |||
65 | /* MIME and related routines */ | ||
66 | |||
67 | /* MIME format structures | ||
68 | * Note that all are translated to lower case apart from | ||
69 | * parameter values. Quotes are stripped off | ||
70 | */ | ||
71 | |||
72 | typedef struct { | ||
73 | char *name; /* Name of line e.g. "content-type" */ | ||
74 | char *value; /* Value of line e.g. "text/plain" */ | ||
75 | STACK /* MIME_PARAM */ *params; /* Zero or more parameters */ | ||
76 | } MIME_HEADER; | ||
77 | |||
78 | typedef struct { | ||
79 | char *param_name; /* Param name e.g. "micalg" */ | ||
80 | char *param_value; /* Param value e.g. "sha1" */ | ||
81 | } MIME_PARAM; | ||
82 | |||
83 | |||
84 | static int B64_write_PKCS7(BIO *bio, PKCS7 *p7); | ||
85 | static PKCS7 *B64_read_PKCS7(BIO *bio); | ||
86 | static char * strip_ends(char *name); | ||
87 | static char * strip_start(char *name); | ||
88 | static char * strip_end(char *name); | ||
89 | static MIME_HEADER *mime_hdr_new(char *name, char *value); | ||
90 | static int mime_hdr_addparam(MIME_HEADER *mhdr, char *name, char *value); | ||
91 | static STACK *mime_parse_hdr(BIO *bio); | ||
92 | static int mime_hdr_cmp(MIME_HEADER **a, MIME_HEADER **b); | ||
93 | static int mime_param_cmp(MIME_PARAM **a, MIME_PARAM **b); | ||
94 | static void mime_param_free(MIME_PARAM *param); | ||
95 | static int mime_bound_check(char *line, int linelen, char *bound, int blen); | ||
96 | static int multi_split(BIO *bio, char *bound, STACK **ret); | ||
97 | static int iscrlf(char c); | ||
98 | static MIME_HEADER *mime_hdr_find(STACK *hdrs, char *name); | ||
99 | static MIME_PARAM *mime_param_find(MIME_HEADER *hdr, char *name); | ||
100 | static void mime_hdr_free(MIME_HEADER *hdr); | ||
101 | |||
102 | #define MAX_SMLEN 1024 | ||
103 | #define mime_debug(x) /* x */ | ||
104 | |||
105 | |||
106 | typedef void (*stkfree)(); | ||
107 | |||
108 | /* Base 64 read and write of PKCS#7 structure */ | ||
109 | |||
110 | static int B64_write_PKCS7(BIO *bio, PKCS7 *p7) | ||
111 | { | ||
112 | BIO *b64; | ||
113 | if(!(b64 = BIO_new(BIO_f_base64()))) { | ||
114 | PKCS7err(PKCS7_F_B64_WRITE_PKCS7,ERR_R_MALLOC_FAILURE); | ||
115 | return 0; | ||
116 | } | ||
117 | bio = BIO_push(b64, bio); | ||
118 | i2d_PKCS7_bio(bio, p7); | ||
119 | BIO_flush(bio); | ||
120 | bio = BIO_pop(bio); | ||
121 | BIO_free(b64); | ||
122 | return 1; | ||
123 | } | ||
124 | |||
125 | static PKCS7 *B64_read_PKCS7(BIO *bio) | ||
126 | { | ||
127 | BIO *b64; | ||
128 | PKCS7 *p7; | ||
129 | if(!(b64 = BIO_new(BIO_f_base64()))) { | ||
130 | PKCS7err(PKCS7_F_B64_READ_PKCS7,ERR_R_MALLOC_FAILURE); | ||
131 | return 0; | ||
132 | } | ||
133 | bio = BIO_push(b64, bio); | ||
134 | if(!(p7 = d2i_PKCS7_bio(bio, NULL))) | ||
135 | PKCS7err(PKCS7_F_B64_READ_PKCS7,PKCS7_R_DECODE_ERROR); | ||
136 | BIO_flush(bio); | ||
137 | bio = BIO_pop(bio); | ||
138 | BIO_free(b64); | ||
139 | return p7; | ||
140 | } | ||
141 | |||
142 | /* SMIME sender */ | ||
143 | |||
144 | int SMIME_write_PKCS7(BIO *bio, PKCS7 *p7, BIO *data, int flags) | ||
145 | { | ||
146 | char linebuf[MAX_SMLEN]; | ||
147 | char bound[33], c; | ||
148 | int i; | ||
149 | if((flags & PKCS7_DETACHED) && data) { | ||
150 | /* We want multipart/signed */ | ||
151 | /* Generate a random boundary */ | ||
152 | RAND_pseudo_bytes((unsigned char *)bound, 32); | ||
153 | for(i = 0; i < 32; i++) { | ||
154 | c = bound[i] & 0xf; | ||
155 | if(c < 10) c += '0'; | ||
156 | else c += 'A' - 10; | ||
157 | bound[i] = c; | ||
158 | } | ||
159 | bound[32] = 0; | ||
160 | BIO_printf(bio, "MIME-Version: 1.0\n"); | ||
161 | BIO_printf(bio, "Content-Type: multipart/signed ; "); | ||
162 | BIO_printf(bio, "protocol=\"application/x-pkcs7-signature\" ; "); | ||
163 | BIO_printf(bio, "micalg=sha1 ; boundary=\"----%s\"\n\n", bound); | ||
164 | BIO_printf(bio, "This is an S/MIME signed message\n\n"); | ||
165 | /* Now write out the first part */ | ||
166 | BIO_printf(bio, "------%s\r\n", bound); | ||
167 | if(flags & PKCS7_TEXT) BIO_printf(bio, "Content-Type: text/plain\n\n"); | ||
168 | while((i = BIO_read(data, linebuf, MAX_SMLEN)) > 0) | ||
169 | BIO_write(bio, linebuf, i); | ||
170 | BIO_printf(bio, "\n------%s\n", bound); | ||
171 | |||
172 | /* Headers for signature */ | ||
173 | |||
174 | BIO_printf(bio, "Content-Type: application/x-pkcs7-signature; name=\"smime.p7s\"\n"); | ||
175 | BIO_printf(bio, "Content-Transfer-Encoding: base64\n"); | ||
176 | BIO_printf(bio, "Content-Disposition: attachment; filename=\"smime.p7s\"\n\n"); | ||
177 | B64_write_PKCS7(bio, p7); | ||
178 | BIO_printf(bio,"\n------%s--\n\n", bound); | ||
179 | return 1; | ||
180 | } | ||
181 | /* MIME headers */ | ||
182 | BIO_printf(bio, "MIME-Version: 1.0\n"); | ||
183 | BIO_printf(bio, "Content-Disposition: attachment; filename=\"smime.p7m\"\n"); | ||
184 | BIO_printf(bio, "Content-Type: application/x-pkcs7-mime; name=\"smime.p7m\"\n"); | ||
185 | BIO_printf(bio, "Content-Transfer-Encoding: base64\n\n"); | ||
186 | B64_write_PKCS7(bio, p7); | ||
187 | BIO_printf(bio, "\n"); | ||
188 | return 1; | ||
189 | } | ||
190 | |||
191 | /* SMIME reader: handle multipart/signed and opaque signing. | ||
192 | * in multipart case the content is placed in a memory BIO | ||
193 | * pointed to by "bcont". In opaque this is set to NULL | ||
194 | */ | ||
195 | |||
196 | PKCS7 *SMIME_read_PKCS7(BIO *bio, BIO **bcont) | ||
197 | { | ||
198 | BIO *p7in; | ||
199 | STACK *headers = NULL; | ||
200 | STACK *parts = NULL; | ||
201 | MIME_HEADER *hdr; | ||
202 | MIME_PARAM *prm; | ||
203 | PKCS7 *p7; | ||
204 | int ret; | ||
205 | |||
206 | if(bcont) *bcont = NULL; | ||
207 | |||
208 | if (!(headers = mime_parse_hdr(bio))) { | ||
209 | PKCS7err(PKCS7_F_SMIME_READ_PKCS7,PKCS7_R_MIME_PARSE_ERROR); | ||
210 | return NULL; | ||
211 | } | ||
212 | |||
213 | if(!(hdr = mime_hdr_find(headers, "content-type")) || !hdr->value) { | ||
214 | sk_pop_free(headers, mime_hdr_free); | ||
215 | PKCS7err(PKCS7_F_SMIME_READ_PKCS7, PKCS7_R_NO_CONTENT_TYPE); | ||
216 | return NULL; | ||
217 | } | ||
218 | |||
219 | /* Handle multipart/signed */ | ||
220 | |||
221 | if(!strcmp(hdr->value, "multipart/signed")) { | ||
222 | /* Split into two parts */ | ||
223 | prm = mime_param_find(hdr, "boundary"); | ||
224 | if(!prm || !prm->param_value) { | ||
225 | sk_pop_free(headers, mime_hdr_free); | ||
226 | PKCS7err(PKCS7_F_SMIME_READ_PKCS7, PKCS7_R_NO_MULTIPART_BOUNDARY); | ||
227 | return NULL; | ||
228 | } | ||
229 | ret = multi_split(bio, prm->param_value, &parts); | ||
230 | sk_pop_free(headers, mime_hdr_free); | ||
231 | if(!ret || (sk_num(parts) != 2) ) { | ||
232 | PKCS7err(PKCS7_F_SMIME_READ_PKCS7, PKCS7_R_NO_MULTIPART_BODY_FAILURE); | ||
233 | sk_pop_free(parts, (stkfree)BIO_free); | ||
234 | return NULL; | ||
235 | } | ||
236 | |||
237 | /* Parse the signature piece */ | ||
238 | p7in = (BIO *)sk_value(parts, 1); | ||
239 | |||
240 | if (!(headers = mime_parse_hdr(p7in))) { | ||
241 | PKCS7err(PKCS7_F_SMIME_READ_PKCS7,PKCS7_R_MIME_SIG_PARSE_ERROR); | ||
242 | sk_pop_free(parts, (stkfree)BIO_free); | ||
243 | return NULL; | ||
244 | } | ||
245 | |||
246 | /* Get content type */ | ||
247 | |||
248 | if(!(hdr = mime_hdr_find(headers, "content-type")) || | ||
249 | !hdr->value) { | ||
250 | sk_pop_free(headers, mime_hdr_free); | ||
251 | PKCS7err(PKCS7_F_SMIME_READ_PKCS7, PKCS7_R_NO_SIG_CONTENT_TYPE); | ||
252 | return NULL; | ||
253 | } | ||
254 | |||
255 | if(strcmp(hdr->value, "application/x-pkcs7-signature") && | ||
256 | strcmp(hdr->value, "application/pkcs7-signature")) { | ||
257 | sk_pop_free(headers, mime_hdr_free); | ||
258 | PKCS7err(PKCS7_F_SMIME_READ_PKCS7,PKCS7_R_SIG_INVALID_MIME_TYPE); | ||
259 | ERR_add_error_data(2, "type: ", hdr->value); | ||
260 | sk_pop_free(parts, (stkfree)BIO_free); | ||
261 | return NULL; | ||
262 | } | ||
263 | sk_pop_free(headers, mime_hdr_free); | ||
264 | /* Read in PKCS#7 */ | ||
265 | if(!(p7 = B64_read_PKCS7(p7in))) { | ||
266 | PKCS7err(PKCS7_F_SMIME_READ_PKCS7,PKCS7_R_PKCS7_SIG_PARSE_ERROR); | ||
267 | sk_pop_free(parts, (stkfree)BIO_free); | ||
268 | return NULL; | ||
269 | } | ||
270 | |||
271 | if(bcont) { | ||
272 | *bcont = (BIO *)sk_value(parts, 0); | ||
273 | BIO_free(p7in); | ||
274 | sk_free(parts); | ||
275 | } else sk_pop_free(parts, (stkfree)BIO_free); | ||
276 | return p7; | ||
277 | } | ||
278 | |||
279 | /* OK, if not multipart/signed try opaque signature */ | ||
280 | |||
281 | if (strcmp (hdr->value, "application/x-pkcs7-mime") && | ||
282 | strcmp (hdr->value, "application/pkcs7-mime")) { | ||
283 | PKCS7err(PKCS7_F_SMIME_READ_PKCS7,PKCS7_R_INVALID_MIME_TYPE); | ||
284 | ERR_add_error_data(2, "type: ", hdr->value); | ||
285 | sk_pop_free(headers, mime_hdr_free); | ||
286 | return NULL; | ||
287 | } | ||
288 | |||
289 | sk_pop_free(headers, mime_hdr_free); | ||
290 | |||
291 | if(!(p7 = B64_read_PKCS7(bio))) { | ||
292 | PKCS7err(PKCS7_F_SMIME_READ_PKCS7, PKCS7_R_PKCS7_PARSE_ERROR); | ||
293 | return NULL; | ||
294 | } | ||
295 | return p7; | ||
296 | |||
297 | } | ||
298 | |||
299 | /* Copy text from one BIO to another making the output CRLF at EOL */ | ||
300 | int SMIME_crlf_copy(BIO *in, BIO *out, int flags) | ||
301 | { | ||
302 | char eol; | ||
303 | int len; | ||
304 | char linebuf[MAX_SMLEN]; | ||
305 | if(flags & PKCS7_BINARY) { | ||
306 | while((len = BIO_read(in, linebuf, MAX_SMLEN)) > 0) | ||
307 | BIO_write(out, linebuf, len); | ||
308 | return 1; | ||
309 | } | ||
310 | if(flags & PKCS7_TEXT) BIO_printf(out, "Content-Type: text/plain\r\n\r\n"); | ||
311 | while ((len = BIO_gets(in, linebuf, MAX_SMLEN)) > 0) { | ||
312 | eol = 0; | ||
313 | while(iscrlf(linebuf[len - 1])) { | ||
314 | len--; | ||
315 | eol = 1; | ||
316 | } | ||
317 | BIO_write(out, linebuf, len); | ||
318 | if(eol) BIO_write(out, "\r\n", 2); | ||
319 | } | ||
320 | return 1; | ||
321 | } | ||
322 | |||
323 | /* Strip off headers if they are text/plain */ | ||
324 | int SMIME_text(BIO *in, BIO *out) | ||
325 | { | ||
326 | char iobuf[4096]; | ||
327 | int len; | ||
328 | STACK *headers; | ||
329 | MIME_HEADER *hdr; | ||
330 | if (!(headers = mime_parse_hdr(in))) { | ||
331 | PKCS7err(PKCS7_F_SMIME_TEXT,PKCS7_R_MIME_PARSE_ERROR); | ||
332 | return 0; | ||
333 | } | ||
334 | if(!(hdr = mime_hdr_find(headers, "content-type")) || !hdr->value) { | ||
335 | PKCS7err(PKCS7_F_SMIME_TEXT,PKCS7_R_MIME_NO_CONTENT_TYPE); | ||
336 | sk_pop_free(headers, mime_hdr_free); | ||
337 | return 0; | ||
338 | } | ||
339 | if (strcmp (hdr->value, "text/plain")) { | ||
340 | PKCS7err(PKCS7_F_SMIME_TEXT,PKCS7_R_INVALID_MIME_TYPE); | ||
341 | ERR_add_error_data(2, "type: ", hdr->value); | ||
342 | sk_pop_free(headers, mime_hdr_free); | ||
343 | return 0; | ||
344 | } | ||
345 | sk_pop_free(headers, mime_hdr_free); | ||
346 | while ((len = BIO_read(in, iobuf, sizeof(iobuf))) > 0) | ||
347 | BIO_write(out, iobuf, len); | ||
348 | return 1; | ||
349 | } | ||
350 | |||
351 | /* Split a multipart/XXX message body into component parts: result is | ||
352 | * canonical parts in a STACK of bios | ||
353 | */ | ||
354 | |||
355 | static int multi_split(BIO *bio, char *bound, STACK **ret) | ||
356 | { | ||
357 | char linebuf[MAX_SMLEN]; | ||
358 | int len, blen; | ||
359 | BIO *bpart = NULL; | ||
360 | STACK *parts; | ||
361 | char state, part, first; | ||
362 | blen = strlen(bound); | ||
363 | part = 0; | ||
364 | state = 0; | ||
365 | first = 1; | ||
366 | parts = sk_new(NULL); | ||
367 | *ret = parts; | ||
368 | while ((len = BIO_gets(bio, linebuf, MAX_SMLEN)) > 0) { | ||
369 | state = mime_bound_check(linebuf, len, bound, blen); | ||
370 | if(state == 1) { | ||
371 | first = 1; | ||
372 | part++; | ||
373 | } else if(state == 2) { | ||
374 | sk_push(parts, (char *)bpart); | ||
375 | return 1; | ||
376 | } else if(part) { | ||
377 | if(first) { | ||
378 | first = 0; | ||
379 | if(bpart) sk_push(parts, (char *)bpart); | ||
380 | bpart = BIO_new(BIO_s_mem()); | ||
381 | |||
382 | } else BIO_write(bpart, "\r\n", 2); | ||
383 | /* Strip CR+LF from linebuf */ | ||
384 | while(iscrlf(linebuf[len - 1])) len--; | ||
385 | BIO_write(bpart, linebuf, len); | ||
386 | } | ||
387 | } | ||
388 | return 0; | ||
389 | } | ||
390 | |||
391 | static int iscrlf(char c) | ||
392 | { | ||
393 | if(c == '\r' || c == '\n') return 1; | ||
394 | return 0; | ||
395 | } | ||
396 | |||
397 | /* This is the big one: parse MIME header lines up to message body */ | ||
398 | |||
399 | #define MIME_INVALID 0 | ||
400 | #define MIME_START 1 | ||
401 | #define MIME_TYPE 2 | ||
402 | #define MIME_NAME 3 | ||
403 | #define MIME_VALUE 4 | ||
404 | #define MIME_QUOTE 5 | ||
405 | #define MIME_COMMENT 6 | ||
406 | |||
407 | |||
408 | static STACK *mime_parse_hdr(BIO *bio) | ||
409 | { | ||
410 | char *p, *q, c; | ||
411 | char *ntmp; | ||
412 | char linebuf[MAX_SMLEN]; | ||
413 | MIME_HEADER *mhdr = NULL; | ||
414 | STACK *headers; | ||
415 | int len, state, save_state = 0; | ||
416 | headers = sk_new(mime_hdr_cmp); | ||
417 | while ((len = BIO_gets(bio, linebuf, MAX_SMLEN)) > 0) { | ||
418 | /* If whitespace at line start then continuation line */ | ||
419 | if(mhdr && isspace((unsigned char)linebuf[0])) state = MIME_NAME; | ||
420 | else state = MIME_START; | ||
421 | ntmp = NULL; | ||
422 | /* Go through all characters */ | ||
423 | for(p = linebuf, q = linebuf; (c = *p) && (c!='\r') && (c!='\n'); p++) { | ||
424 | |||
425 | /* State machine to handle MIME headers | ||
426 | * if this looks horrible that's because it *is* | ||
427 | */ | ||
428 | |||
429 | switch(state) { | ||
430 | case MIME_START: | ||
431 | if(c == ':') { | ||
432 | state = MIME_TYPE; | ||
433 | *p = 0; | ||
434 | ntmp = strip_ends(q); | ||
435 | q = p + 1; | ||
436 | } | ||
437 | break; | ||
438 | |||
439 | case MIME_TYPE: | ||
440 | if(c == ';') { | ||
441 | mime_debug("Found End Value\n"); | ||
442 | *p = 0; | ||
443 | mhdr = mime_hdr_new(ntmp, strip_ends(q)); | ||
444 | sk_push(headers, (char *)mhdr); | ||
445 | ntmp = NULL; | ||
446 | q = p + 1; | ||
447 | state = MIME_NAME; | ||
448 | } else if(c == '(') { | ||
449 | save_state = state; | ||
450 | state = MIME_COMMENT; | ||
451 | } | ||
452 | break; | ||
453 | |||
454 | case MIME_COMMENT: | ||
455 | if(c == ')') { | ||
456 | state = save_state; | ||
457 | } | ||
458 | break; | ||
459 | |||
460 | case MIME_NAME: | ||
461 | if(c == '=') { | ||
462 | state = MIME_VALUE; | ||
463 | *p = 0; | ||
464 | ntmp = strip_ends(q); | ||
465 | q = p + 1; | ||
466 | } | ||
467 | break ; | ||
468 | |||
469 | case MIME_VALUE: | ||
470 | if(c == ';') { | ||
471 | state = MIME_NAME; | ||
472 | *p = 0; | ||
473 | mime_hdr_addparam(mhdr, ntmp, strip_ends(q)); | ||
474 | ntmp = NULL; | ||
475 | q = p + 1; | ||
476 | } else if (c == '"') { | ||
477 | mime_debug("Found Quote\n"); | ||
478 | state = MIME_QUOTE; | ||
479 | } else if(c == '(') { | ||
480 | save_state = state; | ||
481 | state = MIME_COMMENT; | ||
482 | } | ||
483 | break; | ||
484 | |||
485 | case MIME_QUOTE: | ||
486 | if(c == '"') { | ||
487 | mime_debug("Found Match Quote\n"); | ||
488 | state = MIME_VALUE; | ||
489 | } | ||
490 | break; | ||
491 | } | ||
492 | } | ||
493 | |||
494 | if(state == MIME_TYPE) { | ||
495 | mhdr = mime_hdr_new(ntmp, strip_ends(q)); | ||
496 | sk_push(headers, (char *)mhdr); | ||
497 | } else if(state == MIME_VALUE) | ||
498 | mime_hdr_addparam(mhdr, ntmp, strip_ends(q)); | ||
499 | if(p == linebuf) break; /* Blank line means end of headers */ | ||
500 | } | ||
501 | |||
502 | return headers; | ||
503 | |||
504 | } | ||
505 | |||
506 | static char *strip_ends(char *name) | ||
507 | { | ||
508 | return strip_end(strip_start(name)); | ||
509 | } | ||
510 | |||
511 | /* Strip a parameter of whitespace from start of param */ | ||
512 | static char *strip_start(char *name) | ||
513 | { | ||
514 | char *p, c; | ||
515 | /* Look for first non white space or quote */ | ||
516 | for(p = name; (c = *p) ;p++) { | ||
517 | if(c == '"') { | ||
518 | /* Next char is start of string if non null */ | ||
519 | if(p[1]) return p + 1; | ||
520 | /* Else null string */ | ||
521 | return NULL; | ||
522 | } | ||
523 | if(!isspace((unsigned char)c)) return p; | ||
524 | } | ||
525 | return NULL; | ||
526 | } | ||
527 | |||
528 | /* As above but strip from end of string : maybe should handle brackets? */ | ||
529 | static char *strip_end(char *name) | ||
530 | { | ||
531 | char *p, c; | ||
532 | if(!name) return NULL; | ||
533 | /* Look for first non white space or quote */ | ||
534 | for(p = name + strlen(name) - 1; p >= name ;p--) { | ||
535 | c = *p; | ||
536 | if(c == '"') { | ||
537 | if(p - 1 == name) return NULL; | ||
538 | *p = 0; | ||
539 | return name; | ||
540 | } | ||
541 | if(isspace((unsigned char)c)) *p = 0; | ||
542 | else return name; | ||
543 | } | ||
544 | return NULL; | ||
545 | } | ||
546 | |||
547 | static MIME_HEADER *mime_hdr_new(char *name, char *value) | ||
548 | { | ||
549 | MIME_HEADER *mhdr; | ||
550 | char *tmpname, *tmpval, *p; | ||
551 | int c; | ||
552 | if(name) { | ||
553 | if(!(tmpname = BUF_strdup(name))) return NULL; | ||
554 | for(p = tmpname ; *p; p++) { | ||
555 | c = *p; | ||
556 | if(isupper(c)) { | ||
557 | c = tolower(c); | ||
558 | *p = c; | ||
559 | } | ||
560 | } | ||
561 | } else tmpname = NULL; | ||
562 | if(value) { | ||
563 | if(!(tmpval = BUF_strdup(value))) return NULL; | ||
564 | for(p = tmpval ; *p; p++) { | ||
565 | c = *p; | ||
566 | if(isupper(c)) { | ||
567 | c = tolower(c); | ||
568 | *p = c; | ||
569 | } | ||
570 | } | ||
571 | } else tmpval = NULL; | ||
572 | mhdr = (MIME_HEADER *) Malloc(sizeof(MIME_HEADER)); | ||
573 | if(!mhdr) return NULL; | ||
574 | mhdr->name = tmpname; | ||
575 | mhdr->value = tmpval; | ||
576 | if(!(mhdr->params = sk_new(mime_param_cmp))) return NULL; | ||
577 | return mhdr; | ||
578 | } | ||
579 | |||
580 | static int mime_hdr_addparam(MIME_HEADER *mhdr, char *name, char *value) | ||
581 | { | ||
582 | char *tmpname, *tmpval, *p; | ||
583 | int c; | ||
584 | MIME_PARAM *mparam; | ||
585 | if(name) { | ||
586 | tmpname = BUF_strdup(name); | ||
587 | if(!tmpname) return 0; | ||
588 | for(p = tmpname ; *p; p++) { | ||
589 | c = *p; | ||
590 | if(isupper(c)) { | ||
591 | c = tolower(c); | ||
592 | *p = c; | ||
593 | } | ||
594 | } | ||
595 | } else tmpname = NULL; | ||
596 | if(value) { | ||
597 | tmpval = BUF_strdup(value); | ||
598 | if(!tmpval) return 0; | ||
599 | } else tmpval = NULL; | ||
600 | /* Parameter values are case sensitive so leave as is */ | ||
601 | mparam = (MIME_PARAM *) Malloc(sizeof(MIME_PARAM)); | ||
602 | if(!mparam) return 0; | ||
603 | mparam->param_name = tmpname; | ||
604 | mparam->param_value = tmpval; | ||
605 | sk_push(mhdr->params, (char *)mparam); | ||
606 | return 1; | ||
607 | } | ||
608 | |||
609 | static int mime_hdr_cmp(MIME_HEADER **a, MIME_HEADER **b) | ||
610 | { | ||
611 | return(strcmp((*a)->name, (*b)->name)); | ||
612 | } | ||
613 | |||
614 | static int mime_param_cmp(MIME_PARAM **a, MIME_PARAM **b) | ||
615 | { | ||
616 | return(strcmp((*a)->param_name, (*b)->param_name)); | ||
617 | } | ||
618 | |||
619 | /* Find a header with a given name (if possible) */ | ||
620 | |||
621 | static MIME_HEADER *mime_hdr_find(STACK *hdrs, char *name) | ||
622 | { | ||
623 | MIME_HEADER htmp; | ||
624 | int idx; | ||
625 | htmp.name = name; | ||
626 | idx = sk_find(hdrs, (char *)&htmp); | ||
627 | if(idx < 0) return NULL; | ||
628 | return (MIME_HEADER *)sk_value(hdrs, idx); | ||
629 | } | ||
630 | |||
631 | static MIME_PARAM *mime_param_find(MIME_HEADER *hdr, char *name) | ||
632 | { | ||
633 | MIME_PARAM param; | ||
634 | int idx; | ||
635 | param.param_name = name; | ||
636 | idx = sk_find(hdr->params, (char *)¶m); | ||
637 | if(idx < 0) return NULL; | ||
638 | return (MIME_PARAM *)sk_value(hdr->params, idx); | ||
639 | } | ||
640 | |||
641 | static void mime_hdr_free(MIME_HEADER *hdr) | ||
642 | { | ||
643 | if(hdr->name) Free(hdr->name); | ||
644 | if(hdr->value) Free(hdr->value); | ||
645 | if(hdr->params) sk_pop_free(hdr->params, mime_param_free); | ||
646 | Free(hdr); | ||
647 | } | ||
648 | |||
649 | static void mime_param_free(MIME_PARAM *param) | ||
650 | { | ||
651 | if(param->param_name) Free(param->param_name); | ||
652 | if(param->param_value) Free(param->param_value); | ||
653 | Free(param); | ||
654 | } | ||
655 | |||
656 | /* Check for a multipart boundary. Returns: | ||
657 | * 0 : no boundary | ||
658 | * 1 : part boundary | ||
659 | * 2 : final boundary | ||
660 | */ | ||
661 | static int mime_bound_check(char *line, int linelen, char *bound, int blen) | ||
662 | { | ||
663 | if(linelen == -1) linelen = strlen(line); | ||
664 | if(blen == -1) blen = strlen(bound); | ||
665 | /* Quickly eliminate if line length too short */ | ||
666 | if(blen + 2 > linelen) return 0; | ||
667 | /* Check for part boundary */ | ||
668 | if(!strncmp(line, "--", 2) && !strncmp(line + 2, bound, blen)) { | ||
669 | if(!strncmp(line + blen + 2, "--", 2)) return 2; | ||
670 | else return 1; | ||
671 | } | ||
672 | return 0; | ||
673 | } | ||
diff --git a/src/lib/libcrypto/pkcs7/pk7_smime.c b/src/lib/libcrypto/pkcs7/pk7_smime.c new file mode 100644 index 0000000000..b41f42ed04 --- /dev/null +++ b/src/lib/libcrypto/pkcs7/pk7_smime.c | |||
@@ -0,0 +1,427 @@ | |||
1 | /* pk7_smime.c */ | ||
2 | /* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL | ||
3 | * project 1999. | ||
4 | */ | ||
5 | /* ==================================================================== | ||
6 | * Copyright (c) 1999 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 | /* Simple PKCS#7 processing functions */ | ||
60 | |||
61 | #include <stdio.h> | ||
62 | #include "cryptlib.h" | ||
63 | #include <openssl/x509.h> | ||
64 | #include <openssl/x509v3.h> | ||
65 | |||
66 | PKCS7 *PKCS7_sign(X509 *signcert, EVP_PKEY *pkey, STACK_OF(X509) *certs, | ||
67 | BIO *data, int flags) | ||
68 | { | ||
69 | PKCS7 *p7; | ||
70 | PKCS7_SIGNER_INFO *si; | ||
71 | BIO *p7bio; | ||
72 | STACK *smcap; | ||
73 | int i; | ||
74 | |||
75 | if(!X509_check_private_key(signcert, pkey)) { | ||
76 | PKCS7err(PKCS7_F_PKCS7_SIGN,PKCS7_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE); | ||
77 | return NULL; | ||
78 | } | ||
79 | |||
80 | if(!(p7 = PKCS7_new())) { | ||
81 | PKCS7err(PKCS7_F_PKCS7_SIGN,ERR_R_MALLOC_FAILURE); | ||
82 | return NULL; | ||
83 | } | ||
84 | |||
85 | PKCS7_set_type(p7, NID_pkcs7_signed); | ||
86 | |||
87 | PKCS7_content_new(p7, NID_pkcs7_data); | ||
88 | |||
89 | if (!(si = PKCS7_add_signature(p7,signcert,pkey,EVP_sha1()))) { | ||
90 | PKCS7err(PKCS7_F_PKCS7_SIGN,PKCS7_R_PKCS7_ADD_SIGNATURE_ERROR); | ||
91 | return NULL; | ||
92 | } | ||
93 | |||
94 | if(!(flags & PKCS7_NOCERTS)) { | ||
95 | PKCS7_add_certificate(p7, signcert); | ||
96 | if(certs) for(i = 0; i < sk_X509_num(certs); i++) | ||
97 | PKCS7_add_certificate(p7, sk_X509_value(certs, i)); | ||
98 | } | ||
99 | |||
100 | if(!(p7bio = PKCS7_dataInit(p7, NULL))) { | ||
101 | PKCS7err(PKCS7_F_PKCS7_SIGN,ERR_R_MALLOC_FAILURE); | ||
102 | return NULL; | ||
103 | } | ||
104 | |||
105 | |||
106 | SMIME_crlf_copy(data, p7bio, flags); | ||
107 | |||
108 | if(!(flags & PKCS7_NOATTR)) { | ||
109 | PKCS7_add_signed_attribute(si, NID_pkcs9_contentType, | ||
110 | V_ASN1_OBJECT, OBJ_nid2obj(NID_pkcs7_data)); | ||
111 | /* Add SMIMECapabilities */ | ||
112 | if(!(smcap = sk_new(NULL))) { | ||
113 | PKCS7err(PKCS7_F_PKCS7_SIGN,ERR_R_MALLOC_FAILURE); | ||
114 | return NULL; | ||
115 | } | ||
116 | #ifndef NO_DES | ||
117 | PKCS7_simple_smimecap (smcap, NID_des_ede3_cbc, -1); | ||
118 | #endif | ||
119 | #ifndef NO_RC2 | ||
120 | PKCS7_simple_smimecap (smcap, NID_rc2_cbc, 128); | ||
121 | PKCS7_simple_smimecap (smcap, NID_rc2_cbc, 64); | ||
122 | #endif | ||
123 | #ifndef NO_DES | ||
124 | PKCS7_simple_smimecap (smcap, NID_des_cbc, -1); | ||
125 | #endif | ||
126 | #ifndef NO_RC2 | ||
127 | PKCS7_simple_smimecap (smcap, NID_rc2_cbc, 40); | ||
128 | #endif | ||
129 | PKCS7_add_attrib_smimecap (si, smcap); | ||
130 | sk_pop_free(smcap, X509_ALGOR_free); | ||
131 | } | ||
132 | |||
133 | if(flags & PKCS7_DETACHED)PKCS7_set_detached(p7, 1); | ||
134 | |||
135 | if (!PKCS7_dataFinal(p7,p7bio)) { | ||
136 | PKCS7err(PKCS7_F_PKCS7_SIGN,PKCS7_R_PKCS7_DATASIGN); | ||
137 | return NULL; | ||
138 | } | ||
139 | |||
140 | BIO_free_all(p7bio); | ||
141 | return p7; | ||
142 | } | ||
143 | |||
144 | int PKCS7_verify(PKCS7 *p7, STACK_OF(X509) *certs, X509_STORE *store, | ||
145 | BIO *indata, BIO *out, int flags) | ||
146 | { | ||
147 | STACK_OF(X509) *signers; | ||
148 | X509 *signer; | ||
149 | STACK_OF(PKCS7_SIGNER_INFO) *sinfos; | ||
150 | PKCS7_SIGNER_INFO *si; | ||
151 | X509_STORE_CTX cert_ctx; | ||
152 | char buf[4096]; | ||
153 | int i, j=0; | ||
154 | BIO *p7bio; | ||
155 | BIO *tmpout; | ||
156 | |||
157 | if(!p7) { | ||
158 | PKCS7err(PKCS7_F_PKCS7_VERIFY,PKCS7_R_INVALID_NULL_POINTER); | ||
159 | return 0; | ||
160 | } | ||
161 | |||
162 | if(!PKCS7_type_is_signed(p7)) { | ||
163 | PKCS7err(PKCS7_F_PKCS7_VERIFY,PKCS7_R_WRONG_CONTENT_TYPE); | ||
164 | return 0; | ||
165 | } | ||
166 | |||
167 | /* Check for no data and no content: no data to verify signature */ | ||
168 | if(PKCS7_get_detached(p7) && !indata) { | ||
169 | PKCS7err(PKCS7_F_PKCS7_VERIFY,PKCS7_R_NO_CONTENT); | ||
170 | return 0; | ||
171 | } | ||
172 | |||
173 | /* Check for data and content: two sets of data */ | ||
174 | if(!PKCS7_get_detached(p7) && indata) { | ||
175 | PKCS7err(PKCS7_F_PKCS7_VERIFY,PKCS7_R_CONTENT_AND_DATA_PRESENT); | ||
176 | return 0; | ||
177 | } | ||
178 | |||
179 | sinfos = PKCS7_get_signer_info(p7); | ||
180 | |||
181 | if(!sinfos || !sk_PKCS7_SIGNER_INFO_num(sinfos)) { | ||
182 | PKCS7err(PKCS7_F_PKCS7_VERIFY,PKCS7_R_NO_SIGNATURES_ON_DATA); | ||
183 | return 0; | ||
184 | } | ||
185 | |||
186 | |||
187 | signers = PKCS7_get0_signers(p7, certs, flags); | ||
188 | |||
189 | if(!signers) return 0; | ||
190 | |||
191 | /* Now verify the certificates */ | ||
192 | |||
193 | if (!(flags & PKCS7_NOVERIFY)) for (i = 0; i < sk_X509_num(signers); i++) { | ||
194 | signer = sk_X509_value (signers, i); | ||
195 | if (!(flags & PKCS7_NOCHAIN)) { | ||
196 | X509_STORE_CTX_init(&cert_ctx, store, signer, | ||
197 | p7->d.sign->cert); | ||
198 | X509_STORE_CTX_set_purpose(&cert_ctx, | ||
199 | X509_PURPOSE_SMIME_SIGN); | ||
200 | } else X509_STORE_CTX_init (&cert_ctx, store, signer, NULL); | ||
201 | i = X509_verify_cert(&cert_ctx); | ||
202 | if (i <= 0) j = X509_STORE_CTX_get_error(&cert_ctx); | ||
203 | X509_STORE_CTX_cleanup(&cert_ctx); | ||
204 | if (i <= 0) { | ||
205 | PKCS7err(PKCS7_F_PKCS7_VERIFY,PKCS7_R_CERTIFICATE_VERIFY_ERROR); | ||
206 | ERR_add_error_data(2, "Verify error:", | ||
207 | X509_verify_cert_error_string(j)); | ||
208 | sk_X509_free(signers); | ||
209 | return 0; | ||
210 | } | ||
211 | /* Check for revocation status here */ | ||
212 | } | ||
213 | |||
214 | p7bio=PKCS7_dataInit(p7,indata); | ||
215 | |||
216 | if(flags & PKCS7_TEXT) { | ||
217 | if(!(tmpout = BIO_new(BIO_s_mem()))) { | ||
218 | PKCS7err(PKCS7_F_PKCS7_VERIFY,ERR_R_MALLOC_FAILURE); | ||
219 | goto err; | ||
220 | } | ||
221 | } else tmpout = out; | ||
222 | |||
223 | /* We now have to 'read' from p7bio to calculate digests etc. */ | ||
224 | for (;;) | ||
225 | { | ||
226 | i=BIO_read(p7bio,buf,sizeof(buf)); | ||
227 | if (i <= 0) break; | ||
228 | if (tmpout) BIO_write(tmpout, buf, i); | ||
229 | } | ||
230 | |||
231 | if(flags & PKCS7_TEXT) { | ||
232 | if(!SMIME_text(tmpout, out)) { | ||
233 | PKCS7err(PKCS7_F_PKCS7_VERIFY,PKCS7_R_SMIME_TEXT_ERROR); | ||
234 | BIO_free(tmpout); | ||
235 | goto err; | ||
236 | } | ||
237 | BIO_free(tmpout); | ||
238 | } | ||
239 | |||
240 | /* Now Verify All Signatures */ | ||
241 | if (!(flags & PKCS7_NOSIGS)) | ||
242 | for (i=0; i<sk_PKCS7_SIGNER_INFO_num(sinfos); i++) | ||
243 | { | ||
244 | si=sk_PKCS7_SIGNER_INFO_value(sinfos,i); | ||
245 | signer = sk_X509_value (signers, i); | ||
246 | j=PKCS7_signatureVerify(p7bio,p7,si, signer); | ||
247 | if (j <= 0) { | ||
248 | PKCS7err(PKCS7_F_PKCS7_VERIFY,PKCS7_R_SIGNATURE_FAILURE); | ||
249 | goto err; | ||
250 | } | ||
251 | } | ||
252 | |||
253 | sk_X509_free(signers); | ||
254 | if(indata) BIO_pop(p7bio); | ||
255 | BIO_free_all(p7bio); | ||
256 | |||
257 | return 1; | ||
258 | |||
259 | err: | ||
260 | |||
261 | sk_X509_free(signers); | ||
262 | BIO_free(p7bio); | ||
263 | |||
264 | return 0; | ||
265 | } | ||
266 | |||
267 | STACK_OF(X509) *PKCS7_get0_signers(PKCS7 *p7, STACK_OF(X509) *certs, int flags) | ||
268 | { | ||
269 | STACK_OF(X509) *signers; | ||
270 | STACK_OF(PKCS7_SIGNER_INFO) *sinfos; | ||
271 | PKCS7_SIGNER_INFO *si; | ||
272 | PKCS7_ISSUER_AND_SERIAL *ias; | ||
273 | X509 *signer; | ||
274 | int i; | ||
275 | |||
276 | if(!p7) { | ||
277 | PKCS7err(PKCS7_F_PKCS7_GET0_SIGNERS,PKCS7_R_INVALID_NULL_POINTER); | ||
278 | return NULL; | ||
279 | } | ||
280 | |||
281 | if(!PKCS7_type_is_signed(p7)) { | ||
282 | PKCS7err(PKCS7_F_PKCS7_GET0_SIGNERS,PKCS7_R_WRONG_CONTENT_TYPE); | ||
283 | return NULL; | ||
284 | } | ||
285 | if(!(signers = sk_X509_new(NULL))) { | ||
286 | PKCS7err(PKCS7_F_PKCS7_GET0_SIGNERS,ERR_R_MALLOC_FAILURE); | ||
287 | return NULL; | ||
288 | } | ||
289 | |||
290 | /* Collect all the signers together */ | ||
291 | |||
292 | sinfos = PKCS7_get_signer_info(p7); | ||
293 | |||
294 | if(sk_PKCS7_SIGNER_INFO_num(sinfos) <= 0) { | ||
295 | PKCS7err(PKCS7_F_PKCS7_GET0_SIGNERS,PKCS7_R_NO_SIGNERS); | ||
296 | return 0; | ||
297 | } | ||
298 | |||
299 | for (i = 0; i < sk_PKCS7_SIGNER_INFO_num(sinfos); i++) | ||
300 | { | ||
301 | si = sk_PKCS7_SIGNER_INFO_value(sinfos, i); | ||
302 | ias = si->issuer_and_serial; | ||
303 | signer = NULL; | ||
304 | /* If any certificates passed they take priority */ | ||
305 | if (certs) signer = X509_find_by_issuer_and_serial (certs, | ||
306 | ias->issuer, ias->serial); | ||
307 | if (!signer && !(flags & PKCS7_NOINTERN) | ||
308 | && p7->d.sign->cert) signer = | ||
309 | X509_find_by_issuer_and_serial (p7->d.sign->cert, | ||
310 | ias->issuer, ias->serial); | ||
311 | if (!signer) { | ||
312 | PKCS7err(PKCS7_F_PKCS7_GET0_SIGNERS,PKCS7_R_SIGNER_CERTIFICATE_NOT_FOUND); | ||
313 | sk_X509_free(signers); | ||
314 | return 0; | ||
315 | } | ||
316 | |||
317 | sk_X509_push(signers, signer); | ||
318 | } | ||
319 | return signers; | ||
320 | } | ||
321 | |||
322 | |||
323 | /* Build a complete PKCS#7 enveloped data */ | ||
324 | |||
325 | PKCS7 *PKCS7_encrypt(STACK_OF(X509) *certs, BIO *in, EVP_CIPHER *cipher, | ||
326 | int flags) | ||
327 | { | ||
328 | PKCS7 *p7; | ||
329 | BIO *p7bio = NULL; | ||
330 | int i; | ||
331 | X509 *x509; | ||
332 | if(!(p7 = PKCS7_new())) { | ||
333 | PKCS7err(PKCS7_F_PKCS7_ENCRYPT,ERR_R_MALLOC_FAILURE); | ||
334 | return NULL; | ||
335 | } | ||
336 | |||
337 | PKCS7_set_type(p7, NID_pkcs7_enveloped); | ||
338 | if(!PKCS7_set_cipher(p7, cipher)) { | ||
339 | PKCS7err(PKCS7_F_PKCS7_ENCRYPT,PKCS7_R_ERROR_SETTING_CIPHER); | ||
340 | goto err; | ||
341 | } | ||
342 | |||
343 | for(i = 0; i < sk_X509_num(certs); i++) { | ||
344 | x509 = sk_X509_value(certs, i); | ||
345 | if(!PKCS7_add_recipient(p7, x509)) { | ||
346 | PKCS7err(PKCS7_F_PKCS7_ENCRYPT, | ||
347 | PKCS7_R_ERROR_ADDING_RECIPIENT); | ||
348 | goto err; | ||
349 | } | ||
350 | } | ||
351 | |||
352 | if(!(p7bio = PKCS7_dataInit(p7, NULL))) { | ||
353 | PKCS7err(PKCS7_F_PKCS7_ENCRYPT,ERR_R_MALLOC_FAILURE); | ||
354 | goto err; | ||
355 | } | ||
356 | |||
357 | SMIME_crlf_copy(in, p7bio, flags); | ||
358 | |||
359 | BIO_flush(p7bio); | ||
360 | |||
361 | if (!PKCS7_dataFinal(p7,p7bio)) { | ||
362 | PKCS7err(PKCS7_F_PKCS7_ENCRYPT,PKCS7_R_PKCS7_DATAFINAL_ERROR); | ||
363 | goto err; | ||
364 | } | ||
365 | BIO_free_all(p7bio); | ||
366 | |||
367 | return p7; | ||
368 | |||
369 | err: | ||
370 | |||
371 | BIO_free(p7bio); | ||
372 | PKCS7_free(p7); | ||
373 | return NULL; | ||
374 | |||
375 | } | ||
376 | |||
377 | int PKCS7_decrypt(PKCS7 *p7, EVP_PKEY *pkey, X509 *cert, BIO *data, int flags) | ||
378 | { | ||
379 | BIO *tmpmem; | ||
380 | int ret, i; | ||
381 | char buf[4096]; | ||
382 | |||
383 | if(!p7) { | ||
384 | PKCS7err(PKCS7_F_PKCS7_DECRYPT,PKCS7_R_INVALID_NULL_POINTER); | ||
385 | return 0; | ||
386 | } | ||
387 | |||
388 | if(!PKCS7_type_is_enveloped(p7)) { | ||
389 | PKCS7err(PKCS7_F_PKCS7_DECRYPT,PKCS7_R_WRONG_CONTENT_TYPE); | ||
390 | return 0; | ||
391 | } | ||
392 | |||
393 | if(!X509_check_private_key(cert, pkey)) { | ||
394 | PKCS7err(PKCS7_F_PKCS7_DECRYPT, | ||
395 | PKCS7_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE); | ||
396 | return 0; | ||
397 | } | ||
398 | |||
399 | if(!(tmpmem = PKCS7_dataDecode(p7, pkey, NULL, cert))) { | ||
400 | PKCS7err(PKCS7_F_PKCS7_DECRYPT, PKCS7_R_DECRYPT_ERROR); | ||
401 | return 0; | ||
402 | } | ||
403 | |||
404 | if (flags & PKCS7_TEXT) { | ||
405 | BIO *tmpbuf, *bread; | ||
406 | /* Encrypt BIOs can't do BIO_gets() so add a buffer BIO */ | ||
407 | if(!(tmpbuf = BIO_new(BIO_f_buffer()))) { | ||
408 | PKCS7err(PKCS7_F_PKCS7_DECRYPT, ERR_R_MALLOC_FAILURE); | ||
409 | return 0; | ||
410 | } | ||
411 | if(!(bread = BIO_push(tmpbuf, tmpmem))) { | ||
412 | PKCS7err(PKCS7_F_PKCS7_DECRYPT, ERR_R_MALLOC_FAILURE); | ||
413 | return 0; | ||
414 | } | ||
415 | ret = SMIME_text(bread, data); | ||
416 | BIO_free_all(bread); | ||
417 | return ret; | ||
418 | } else { | ||
419 | for(;;) { | ||
420 | i = BIO_read(tmpmem, buf, sizeof(buf)); | ||
421 | if(i <= 0) break; | ||
422 | BIO_write(data, buf, i); | ||
423 | } | ||
424 | BIO_free_all(tmpmem); | ||
425 | return 1; | ||
426 | } | ||
427 | } | ||
diff --git a/src/lib/libcrypto/rand/rand_err.c b/src/lib/libcrypto/rand/rand_err.c new file mode 100644 index 0000000000..d1263edf80 --- /dev/null +++ b/src/lib/libcrypto/rand/rand_err.c | |||
@@ -0,0 +1,93 @@ | |||
1 | /* crypto/rand/rand_err.c */ | ||
2 | /* ==================================================================== | ||
3 | * Copyright (c) 1999 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 | */ | ||
59 | |||
60 | #include <stdio.h> | ||
61 | #include <openssl/err.h> | ||
62 | #include <openssl/rand.h> | ||
63 | |||
64 | /* BEGIN ERROR CODES */ | ||
65 | #ifndef NO_ERR | ||
66 | static ERR_STRING_DATA RAND_str_functs[]= | ||
67 | { | ||
68 | {ERR_PACK(0,RAND_F_SSLEAY_RAND_BYTES,0), "SSLEAY_RAND_BYTES"}, | ||
69 | {0,NULL} | ||
70 | }; | ||
71 | |||
72 | static ERR_STRING_DATA RAND_str_reasons[]= | ||
73 | { | ||
74 | {RAND_R_PRNG_NOT_SEEDED ,"prng not seeded"}, | ||
75 | {0,NULL} | ||
76 | }; | ||
77 | |||
78 | #endif | ||
79 | |||
80 | void ERR_load_RAND_strings(void) | ||
81 | { | ||
82 | static int init=1; | ||
83 | |||
84 | if (init) | ||
85 | { | ||
86 | init=0; | ||
87 | #ifndef NO_ERR | ||
88 | ERR_load_strings(ERR_LIB_RAND,RAND_str_functs); | ||
89 | ERR_load_strings(ERR_LIB_RAND,RAND_str_reasons); | ||
90 | #endif | ||
91 | |||
92 | } | ||
93 | } | ||
diff --git a/src/lib/libcrypto/rand/rand_lib.c b/src/lib/libcrypto/rand/rand_lib.c new file mode 100644 index 0000000000..34c6d5b968 --- /dev/null +++ b/src/lib/libcrypto/rand/rand_lib.c | |||
@@ -0,0 +1,98 @@ | |||
1 | /* crypto/rand/rand_lib.c */ | ||
2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) | ||
3 | * All rights reserved. | ||
4 | * | ||
5 | * This package is an SSL implementation written | ||
6 | * by Eric Young (eay@cryptsoft.com). | ||
7 | * The implementation was written so as to conform with Netscapes SSL. | ||
8 | * | ||
9 | * This library is free for commercial and non-commercial use as long as | ||
10 | * the following conditions are aheared to. The following conditions | ||
11 | * apply to all code found in this distribution, be it the RC4, RSA, | ||
12 | * lhash, DES, etc., code; not just the SSL code. The SSL documentation | ||
13 | * included with this distribution is covered by the same copyright terms | ||
14 | * except that the holder is Tim Hudson (tjh@cryptsoft.com). | ||
15 | * | ||
16 | * Copyright remains Eric Young's, and as such any Copyright notices in | ||
17 | * the code are not to be removed. | ||
18 | * If this package is used in a product, Eric Young should be given attribution | ||
19 | * as the author of the parts of the library used. | ||
20 | * This can be in the form of a textual message at program startup or | ||
21 | * in documentation (online or textual) provided with the package. | ||
22 | * | ||
23 | * Redistribution and use in source and binary forms, with or without | ||
24 | * modification, are permitted provided that the following conditions | ||
25 | * are met: | ||
26 | * 1. Redistributions of source code must retain the copyright | ||
27 | * notice, this list of conditions and the following disclaimer. | ||
28 | * 2. Redistributions in binary form must reproduce the above copyright | ||
29 | * notice, this list of conditions and the following disclaimer in the | ||
30 | * documentation and/or other materials provided with the distribution. | ||
31 | * 3. All advertising materials mentioning features or use of this software | ||
32 | * must display the following acknowledgement: | ||
33 | * "This product includes cryptographic software written by | ||
34 | * Eric Young (eay@cryptsoft.com)" | ||
35 | * The word 'cryptographic' can be left out if the rouines from the library | ||
36 | * being used are not cryptographic related :-). | ||
37 | * 4. If you include any Windows specific code (or a derivative thereof) from | ||
38 | * the apps directory (application code) you must include an acknowledgement: | ||
39 | * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" | ||
40 | * | ||
41 | * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND | ||
42 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
43 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
44 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | ||
45 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
46 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
47 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
48 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
49 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
50 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
51 | * SUCH DAMAGE. | ||
52 | * | ||
53 | * The licence and distribution terms for any publically available version or | ||
54 | * derivative of this code cannot be changed. i.e. this code cannot simply be | ||
55 | * copied and put under another distribution licence | ||
56 | * [including the GNU Public Licence.] | ||
57 | */ | ||
58 | |||
59 | #include <stdio.h> | ||
60 | #include <sys/types.h> | ||
61 | #include <time.h> | ||
62 | #include <openssl/rand.h> | ||
63 | |||
64 | #ifdef NO_RAND | ||
65 | static RAND_METHOD *rand_meth=NULL; | ||
66 | #else | ||
67 | extern RAND_METHOD rand_ssleay_meth; | ||
68 | static RAND_METHOD *rand_meth= &rand_ssleay_meth; | ||
69 | #endif | ||
70 | |||
71 | void RAND_set_rand_method(RAND_METHOD *meth) | ||
72 | { | ||
73 | rand_meth=meth; | ||
74 | } | ||
75 | |||
76 | RAND_METHOD *RAND_get_rand_method(void) | ||
77 | { | ||
78 | return(rand_meth); | ||
79 | } | ||
80 | |||
81 | void RAND_cleanup(void) | ||
82 | { | ||
83 | if (rand_meth != NULL) | ||
84 | rand_meth->cleanup(); | ||
85 | } | ||
86 | |||
87 | void RAND_seed(const void *buf, int num) | ||
88 | { | ||
89 | if (rand_meth != NULL) | ||
90 | rand_meth->seed(buf,num); | ||
91 | } | ||
92 | |||
93 | void RAND_bytes(unsigned char *buf, int num) | ||
94 | { | ||
95 | if (rand_meth != NULL) | ||
96 | rand_meth->bytes(buf,num); | ||
97 | } | ||
98 | |||
diff --git a/src/lib/libcrypto/rc2/rc2.h b/src/lib/libcrypto/rc2/rc2.h new file mode 100644 index 0000000000..9571efb755 --- /dev/null +++ b/src/lib/libcrypto/rc2/rc2.h | |||
@@ -0,0 +1,99 @@ | |||
1 | /* crypto/rc2/rc2.h */ | ||
2 | /* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) | ||
3 | * All rights reserved. | ||
4 | * | ||
5 | * This package is an SSL implementation written | ||
6 | * by Eric Young (eay@cryptsoft.com). | ||
7 | * The implementation was written so as to conform with Netscapes SSL. | ||
8 | * | ||
9 | * This library is free for commercial and non-commercial use as long as | ||
10 | * the following conditions are aheared to. The following conditions | ||
11 | * apply to all code found in this distribution, be it the RC4, RSA, | ||
12 | * lhash, DES, etc., code; not just the SSL code. The SSL documentation | ||
13 | * included with this distribution is covered by the same copyright terms | ||
14 | * except that the holder is Tim Hudson (tjh@cryptsoft.com). | ||
15 | * | ||
16 | * Copyright remains Eric Young's, and as such any Copyright notices in | ||
17 | * the code are not to be removed. | ||
18 | * If this package is used in a product, Eric Young should be given attribution | ||
19 | * as the author of the parts of the library used. | ||
20 | * This can be in the form of a textual message at program startup or | ||
21 | * in documentation (online or textual) provided with the package. | ||
22 | * | ||
23 | * Redistribution and use in source and binary forms, with or without | ||
24 | * modification, are permitted provided that the following conditions | ||
25 | * are met: | ||
26 | * 1. Redistributions of source code must retain the copyright | ||
27 | * notice, this list of conditions and the following disclaimer. | ||
28 | * 2. Redistributions in binary form must reproduce the above copyright | ||
29 | * notice, this list of conditions and the following disclaimer in the | ||
30 | * documentation and/or other materials provided with the distribution. | ||
31 | * 3. All advertising materials mentioning features or use of this software | ||
32 | * must display the following acknowledgement: | ||
33 | * "This product includes cryptographic software written by | ||
34 | * Eric Young (eay@cryptsoft.com)" | ||
35 | * The word 'cryptographic' can be left out if the rouines from the library | ||
36 | * being used are not cryptographic related :-). | ||
37 | * 4. If you include any Windows specific code (or a derivative thereof) from | ||
38 | * the apps directory (application code) you must include an acknowledgement: | ||
39 | * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" | ||
40 | * | ||
41 | * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND | ||
42 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
43 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
44 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | ||
45 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
46 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
47 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
48 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
49 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
50 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
51 | * SUCH DAMAGE. | ||
52 | * | ||
53 | * The licence and distribution terms for any publically available version or | ||
54 | * derivative of this code cannot be changed. i.e. this code cannot simply be | ||
55 | * copied and put under another distribution licence | ||
56 | * [including the GNU Public Licence.] | ||
57 | */ | ||
58 | |||
59 | #ifndef HEADER_RC2_H | ||
60 | #define HEADER_RC2_H | ||
61 | |||
62 | #ifdef __cplusplus | ||
63 | extern "C" { | ||
64 | #endif | ||
65 | |||
66 | #ifdef NO_RC2 | ||
67 | #error RC2 is disabled. | ||
68 | #endif | ||
69 | |||
70 | #define RC2_ENCRYPT 1 | ||
71 | #define RC2_DECRYPT 0 | ||
72 | |||
73 | #include <openssl/opensslconf.h> /* RC2_INT */ | ||
74 | #define RC2_BLOCK 8 | ||
75 | #define RC2_KEY_LENGTH 16 | ||
76 | |||
77 | typedef struct rc2_key_st | ||
78 | { | ||
79 | RC2_INT data[64]; | ||
80 | } RC2_KEY; | ||
81 | |||
82 | |||
83 | void RC2_set_key(RC2_KEY *key, int len, unsigned char *data,int bits); | ||
84 | void RC2_ecb_encrypt(unsigned char *in,unsigned char *out,RC2_KEY *key, | ||
85 | int enc); | ||
86 | void RC2_encrypt(unsigned long *data,RC2_KEY *key); | ||
87 | void RC2_decrypt(unsigned long *data,RC2_KEY *key); | ||
88 | void RC2_cbc_encrypt(unsigned char *in, unsigned char *out, long length, | ||
89 | RC2_KEY *ks, unsigned char *iv, int enc); | ||
90 | void RC2_cfb64_encrypt(unsigned char *in, unsigned char *out, long length, | ||
91 | RC2_KEY *schedule, unsigned char *ivec, int *num, int enc); | ||
92 | void RC2_ofb64_encrypt(unsigned char *in, unsigned char *out, long length, | ||
93 | RC2_KEY *schedule, unsigned char *ivec, int *num); | ||
94 | |||
95 | #ifdef __cplusplus | ||
96 | } | ||
97 | #endif | ||
98 | |||
99 | #endif | ||
diff --git a/src/lib/libcrypto/rc4/rc4.h b/src/lib/libcrypto/rc4/rc4.h new file mode 100644 index 0000000000..7418c2a9a2 --- /dev/null +++ b/src/lib/libcrypto/rc4/rc4.h | |||
@@ -0,0 +1,88 @@ | |||
1 | /* crypto/rc4/rc4.h */ | ||
2 | /* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) | ||
3 | * All rights reserved. | ||
4 | * | ||
5 | * This package is an SSL implementation written | ||
6 | * by Eric Young (eay@cryptsoft.com). | ||
7 | * The implementation was written so as to conform with Netscapes SSL. | ||
8 | * | ||
9 | * This library is free for commercial and non-commercial use as long as | ||
10 | * the following conditions are aheared to. The following conditions | ||
11 | * apply to all code found in this distribution, be it the RC4, RSA, | ||
12 | * lhash, DES, etc., code; not just the SSL code. The SSL documentation | ||
13 | * included with this distribution is covered by the same copyright terms | ||
14 | * except that the holder is Tim Hudson (tjh@cryptsoft.com). | ||
15 | * | ||
16 | * Copyright remains Eric Young's, and as such any Copyright notices in | ||
17 | * the code are not to be removed. | ||
18 | * If this package is used in a product, Eric Young should be given attribution | ||
19 | * as the author of the parts of the library used. | ||
20 | * This can be in the form of a textual message at program startup or | ||
21 | * in documentation (online or textual) provided with the package. | ||
22 | * | ||
23 | * Redistribution and use in source and binary forms, with or without | ||
24 | * modification, are permitted provided that the following conditions | ||
25 | * are met: | ||
26 | * 1. Redistributions of source code must retain the copyright | ||
27 | * notice, this list of conditions and the following disclaimer. | ||
28 | * 2. Redistributions in binary form must reproduce the above copyright | ||
29 | * notice, this list of conditions and the following disclaimer in the | ||
30 | * documentation and/or other materials provided with the distribution. | ||
31 | * 3. All advertising materials mentioning features or use of this software | ||
32 | * must display the following acknowledgement: | ||
33 | * "This product includes cryptographic software written by | ||
34 | * Eric Young (eay@cryptsoft.com)" | ||
35 | * The word 'cryptographic' can be left out if the rouines from the library | ||
36 | * being used are not cryptographic related :-). | ||
37 | * 4. If you include any Windows specific code (or a derivative thereof) from | ||
38 | * the apps directory (application code) you must include an acknowledgement: | ||
39 | * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" | ||
40 | * | ||
41 | * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND | ||
42 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
43 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
44 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | ||
45 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
46 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
47 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
48 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
49 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
50 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
51 | * SUCH DAMAGE. | ||
52 | * | ||
53 | * The licence and distribution terms for any publically available version or | ||
54 | * derivative of this code cannot be changed. i.e. this code cannot simply be | ||
55 | * copied and put under another distribution licence | ||
56 | * [including the GNU Public Licence.] | ||
57 | */ | ||
58 | |||
59 | #ifndef HEADER_RC4_H | ||
60 | #define HEADER_RC4_H | ||
61 | |||
62 | #ifdef __cplusplus | ||
63 | extern "C" { | ||
64 | #endif | ||
65 | |||
66 | #ifdef NO_RC4 | ||
67 | #error RC4 is disabled. | ||
68 | #endif | ||
69 | |||
70 | #include <openssl/opensslconf.h> /* RC4_INT */ | ||
71 | |||
72 | typedef struct rc4_key_st | ||
73 | { | ||
74 | RC4_INT x,y; | ||
75 | RC4_INT data[256]; | ||
76 | } RC4_KEY; | ||
77 | |||
78 | |||
79 | const char *RC4_options(void); | ||
80 | void RC4_set_key(RC4_KEY *key, int len, unsigned char *data); | ||
81 | void RC4(RC4_KEY *key, unsigned long len, unsigned char *indata, | ||
82 | unsigned char *outdata); | ||
83 | |||
84 | #ifdef __cplusplus | ||
85 | } | ||
86 | #endif | ||
87 | |||
88 | #endif | ||
diff --git a/src/lib/libcrypto/rc4/rc4_locl.h b/src/lib/libcrypto/rc4/rc4_locl.h new file mode 100644 index 0000000000..3bb80b6ce9 --- /dev/null +++ b/src/lib/libcrypto/rc4/rc4_locl.h | |||
@@ -0,0 +1,4 @@ | |||
1 | #ifndef HEADER_RC4_LOCL_H | ||
2 | #define HEADER_RC4_LOCL_H | ||
3 | #include <openssl/opensslconf.h> | ||
4 | #endif | ||
diff --git a/src/lib/libcrypto/rsa/rsa_asn1.c b/src/lib/libcrypto/rsa/rsa_asn1.c new file mode 100644 index 0000000000..1455a7e0e4 --- /dev/null +++ b/src/lib/libcrypto/rsa/rsa_asn1.c | |||
@@ -0,0 +1,121 @@ | |||
1 | /* rsa_asn1.c */ | ||
2 | /* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL | ||
3 | * project 2000. | ||
4 | */ | ||
5 | /* ==================================================================== | ||
6 | * Copyright (c) 2000 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 | #include "cryptlib.h" | ||
61 | #include <openssl/bn.h> | ||
62 | #include <openssl/rsa.h> | ||
63 | #include <openssl/asn1t.h> | ||
64 | |||
65 | static ASN1_METHOD method={ | ||
66 | (int (*)()) i2d_RSAPrivateKey, | ||
67 | (char *(*)())d2i_RSAPrivateKey, | ||
68 | (char *(*)())RSA_new, | ||
69 | (void (*)()) RSA_free}; | ||
70 | |||
71 | ASN1_METHOD *RSAPrivateKey_asn1_meth(void) | ||
72 | { | ||
73 | return(&method); | ||
74 | } | ||
75 | |||
76 | /* Override the default free and new methods */ | ||
77 | static int rsa_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it) | ||
78 | { | ||
79 | if(operation == ASN1_OP_NEW_PRE) { | ||
80 | *pval = (ASN1_VALUE *)RSA_new(); | ||
81 | if(*pval) return 2; | ||
82 | return 0; | ||
83 | } else if(operation == ASN1_OP_FREE_PRE) { | ||
84 | RSA_free((RSA *)*pval); | ||
85 | *pval = NULL; | ||
86 | return 2; | ||
87 | } | ||
88 | return 1; | ||
89 | } | ||
90 | |||
91 | ASN1_SEQUENCE_cb(RSAPrivateKey, rsa_cb) = { | ||
92 | ASN1_SIMPLE(RSA, version, LONG), | ||
93 | ASN1_SIMPLE(RSA, n, BIGNUM), | ||
94 | ASN1_SIMPLE(RSA, e, BIGNUM), | ||
95 | ASN1_SIMPLE(RSA, d, BIGNUM), | ||
96 | ASN1_SIMPLE(RSA, p, BIGNUM), | ||
97 | ASN1_SIMPLE(RSA, q, BIGNUM), | ||
98 | ASN1_SIMPLE(RSA, dmp1, BIGNUM), | ||
99 | ASN1_SIMPLE(RSA, dmq1, BIGNUM), | ||
100 | ASN1_SIMPLE(RSA, iqmp, BIGNUM) | ||
101 | } ASN1_SEQUENCE_END_cb(RSA, RSAPrivateKey) | ||
102 | |||
103 | |||
104 | ASN1_SEQUENCE_cb(RSAPublicKey, rsa_cb) = { | ||
105 | ASN1_SIMPLE(RSA, n, BIGNUM), | ||
106 | ASN1_SIMPLE(RSA, e, BIGNUM), | ||
107 | } ASN1_SEQUENCE_END_cb(RSA, RSAPublicKey) | ||
108 | |||
109 | IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(RSA, RSAPrivateKey, RSAPrivateKey) | ||
110 | |||
111 | IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(RSA, RSAPublicKey, RSAPublicKey) | ||
112 | |||
113 | RSA *RSAPublicKey_dup(RSA *rsa) | ||
114 | { | ||
115 | return ASN1_item_dup(ASN1_ITEM_rptr(RSAPublicKey), rsa); | ||
116 | } | ||
117 | |||
118 | RSA *RSAPrivateKey_dup(RSA *rsa) | ||
119 | { | ||
120 | return ASN1_item_dup(ASN1_ITEM_rptr(RSAPrivateKey), rsa); | ||
121 | } | ||
diff --git a/src/lib/libcrypto/rsa/rsa_chk.c b/src/lib/libcrypto/rsa/rsa_chk.c new file mode 100644 index 0000000000..91b9115798 --- /dev/null +++ b/src/lib/libcrypto/rsa/rsa_chk.c | |||
@@ -0,0 +1,184 @@ | |||
1 | /* crypto/rsa/rsa_chk.c -*- Mode: C; c-file-style: "eay" -*- */ | ||
2 | /* ==================================================================== | ||
3 | * Copyright (c) 1999 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 | #include <openssl/bn.h> | ||
52 | #include <openssl/err.h> | ||
53 | #include <openssl/rsa.h> | ||
54 | |||
55 | |||
56 | int RSA_check_key(RSA *key) | ||
57 | { | ||
58 | BIGNUM *i, *j, *k, *l, *m; | ||
59 | BN_CTX *ctx; | ||
60 | int r; | ||
61 | int ret=1; | ||
62 | |||
63 | i = BN_new(); | ||
64 | j = BN_new(); | ||
65 | k = BN_new(); | ||
66 | l = BN_new(); | ||
67 | m = BN_new(); | ||
68 | ctx = BN_CTX_new(); | ||
69 | if (i == NULL || j == NULL || k == NULL || l == NULL || | ||
70 | m == NULL || ctx == NULL) | ||
71 | { | ||
72 | ret = -1; | ||
73 | RSAerr(RSA_F_RSA_CHECK_KEY, ERR_R_MALLOC_FAILURE); | ||
74 | goto err; | ||
75 | } | ||
76 | |||
77 | /* p prime? */ | ||
78 | r = BN_is_prime(key->p, BN_prime_checks, NULL, NULL, NULL); | ||
79 | if (r != 1) | ||
80 | { | ||
81 | ret = r; | ||
82 | if (r != 0) | ||
83 | goto err; | ||
84 | RSAerr(RSA_F_RSA_CHECK_KEY, RSA_R_P_NOT_PRIME); | ||
85 | } | ||
86 | |||
87 | /* q prime? */ | ||
88 | r = BN_is_prime(key->q, BN_prime_checks, NULL, NULL, NULL); | ||
89 | if (r != 1) | ||
90 | { | ||
91 | ret = r; | ||
92 | if (r != 0) | ||
93 | goto err; | ||
94 | RSAerr(RSA_F_RSA_CHECK_KEY, RSA_R_Q_NOT_PRIME); | ||
95 | } | ||
96 | |||
97 | /* n = p*q? */ | ||
98 | r = BN_mul(i, key->p, key->q, ctx); | ||
99 | if (!r) { ret = -1; goto err; } | ||
100 | |||
101 | if (BN_cmp(i, key->n) != 0) | ||
102 | { | ||
103 | ret = 0; | ||
104 | RSAerr(RSA_F_RSA_CHECK_KEY, RSA_R_N_DOES_NOT_EQUAL_P_Q); | ||
105 | } | ||
106 | |||
107 | /* d*e = 1 mod lcm(p-1,q-1)? */ | ||
108 | |||
109 | r = BN_sub(i, key->p, BN_value_one()); | ||
110 | if (!r) { ret = -1; goto err; } | ||
111 | r = BN_sub(j, key->q, BN_value_one()); | ||
112 | if (!r) { ret = -1; goto err; } | ||
113 | |||
114 | /* now compute k = lcm(i,j) */ | ||
115 | r = BN_mul(l, i, j, ctx); | ||
116 | if (!r) { ret = -1; goto err; } | ||
117 | r = BN_gcd(m, i, j, ctx); | ||
118 | if (!r) { ret = -1; goto err; } | ||
119 | r = BN_div(k, NULL, l, m, ctx); /* remainder is 0 */ | ||
120 | if (!r) { ret = -1; goto err; } | ||
121 | |||
122 | r = BN_mod_mul(i, key->d, key->e, k, ctx); | ||
123 | if (!r) { ret = -1; goto err; } | ||
124 | |||
125 | if (!BN_is_one(i)) | ||
126 | { | ||
127 | ret = 0; | ||
128 | RSAerr(RSA_F_RSA_CHECK_KEY, RSA_R_D_E_NOT_CONGRUENT_TO_1); | ||
129 | } | ||
130 | |||
131 | if (key->dmp1 != NULL && key->dmq1 != NULL && key->iqmp != NULL) | ||
132 | { | ||
133 | /* dmp1 = d mod (p-1)? */ | ||
134 | r = BN_sub(i, key->p, BN_value_one()); | ||
135 | if (!r) { ret = -1; goto err; } | ||
136 | |||
137 | r = BN_mod(j, key->d, i, ctx); | ||
138 | if (!r) { ret = -1; goto err; } | ||
139 | |||
140 | if (BN_cmp(j, key->dmp1) != 0) | ||
141 | { | ||
142 | ret = 0; | ||
143 | RSAerr(RSA_F_RSA_CHECK_KEY, | ||
144 | RSA_R_DMP1_NOT_CONGRUENT_TO_D); | ||
145 | } | ||
146 | |||
147 | /* dmq1 = d mod (q-1)? */ | ||
148 | r = BN_sub(i, key->q, BN_value_one()); | ||
149 | if (!r) { ret = -1; goto err; } | ||
150 | |||
151 | r = BN_mod(j, key->d, i, ctx); | ||
152 | if (!r) { ret = -1; goto err; } | ||
153 | |||
154 | if (BN_cmp(j, key->dmq1) != 0) | ||
155 | { | ||
156 | ret = 0; | ||
157 | RSAerr(RSA_F_RSA_CHECK_KEY, | ||
158 | RSA_R_DMQ1_NOT_CONGRUENT_TO_D); | ||
159 | } | ||
160 | |||
161 | /* iqmp = q^-1 mod p? */ | ||
162 | if(!BN_mod_inverse(i, key->q, key->p, ctx)) | ||
163 | { | ||
164 | ret = -1; | ||
165 | goto err; | ||
166 | } | ||
167 | |||
168 | if (BN_cmp(i, key->iqmp) != 0) | ||
169 | { | ||
170 | ret = 0; | ||
171 | RSAerr(RSA_F_RSA_CHECK_KEY, | ||
172 | RSA_R_IQMP_NOT_INVERSE_OF_Q); | ||
173 | } | ||
174 | } | ||
175 | |||
176 | err: | ||
177 | if (i != NULL) BN_free(i); | ||
178 | if (j != NULL) BN_free(j); | ||
179 | if (k != NULL) BN_free(k); | ||
180 | if (l != NULL) BN_free(l); | ||
181 | if (m != NULL) BN_free(m); | ||
182 | if (ctx != NULL) BN_CTX_free(ctx); | ||
183 | return (ret); | ||
184 | } | ||
diff --git a/src/lib/libcrypto/rsa/rsa_oaep.c b/src/lib/libcrypto/rsa/rsa_oaep.c new file mode 100644 index 0000000000..843c40c864 --- /dev/null +++ b/src/lib/libcrypto/rsa/rsa_oaep.c | |||
@@ -0,0 +1,162 @@ | |||
1 | /* crypto/rsa/rsa_oaep.c */ | ||
2 | /* Written by Ulf Moeller. This software is distributed on an "AS IS" | ||
3 | basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. */ | ||
4 | |||
5 | /* EME_OAEP as defined in RFC 2437 (PKCS #1 v2.0) */ | ||
6 | |||
7 | #if !defined(NO_SHA) && !defined(NO_SHA1) | ||
8 | #include <stdio.h> | ||
9 | #include "cryptlib.h" | ||
10 | #include <openssl/bn.h> | ||
11 | #include <openssl/rsa.h> | ||
12 | #include <openssl/sha.h> | ||
13 | #include <openssl/rand.h> | ||
14 | |||
15 | int MGF1(unsigned char *mask, long len, unsigned char *seed, long seedlen); | ||
16 | |||
17 | int RSA_padding_add_PKCS1_OAEP(unsigned char *to, int tlen, | ||
18 | unsigned char *from, int flen, unsigned char *param, int plen) | ||
19 | { | ||
20 | int i, emlen = tlen - 1; | ||
21 | unsigned char *db, *seed; | ||
22 | unsigned char *dbmask, seedmask[SHA_DIGEST_LENGTH]; | ||
23 | |||
24 | if (flen > emlen - 2 * SHA_DIGEST_LENGTH - 1) | ||
25 | { | ||
26 | RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_OAEP, | ||
27 | RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE); | ||
28 | return (0); | ||
29 | } | ||
30 | |||
31 | if (emlen < 2 * SHA_DIGEST_LENGTH + 1) | ||
32 | { | ||
33 | RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_OAEP, RSA_R_KEY_SIZE_TOO_SMALL); | ||
34 | return (0); | ||
35 | } | ||
36 | |||
37 | dbmask = Malloc(emlen - SHA_DIGEST_LENGTH); | ||
38 | if (dbmask == NULL) | ||
39 | { | ||
40 | RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_OAEP, ERR_R_MALLOC_FAILURE); | ||
41 | return (0); | ||
42 | } | ||
43 | |||
44 | to[0] = 0; | ||
45 | seed = to + 1; | ||
46 | db = to + SHA_DIGEST_LENGTH + 1; | ||
47 | |||
48 | SHA1(param, plen, db); | ||
49 | memset(db + SHA_DIGEST_LENGTH, 0, | ||
50 | emlen - flen - 2 * SHA_DIGEST_LENGTH - 1); | ||
51 | db[emlen - flen - SHA_DIGEST_LENGTH - 1] = 0x01; | ||
52 | memcpy(db + emlen - flen - SHA_DIGEST_LENGTH, from, (unsigned int) flen); | ||
53 | RAND_bytes(seed, SHA_DIGEST_LENGTH); | ||
54 | #ifdef PKCS_TESTVECT | ||
55 | memcpy(seed, | ||
56 | "\xaa\xfd\x12\xf6\x59\xca\xe6\x34\x89\xb4\x79\xe5\x07\x6d\xde\xc2\xf0\x6c\xb5\x8f", | ||
57 | 20); | ||
58 | #endif | ||
59 | |||
60 | MGF1(dbmask, emlen - SHA_DIGEST_LENGTH, seed, SHA_DIGEST_LENGTH); | ||
61 | for (i = 0; i < emlen - SHA_DIGEST_LENGTH; i++) | ||
62 | db[i] ^= dbmask[i]; | ||
63 | |||
64 | MGF1(seedmask, SHA_DIGEST_LENGTH, db, emlen - SHA_DIGEST_LENGTH); | ||
65 | for (i = 0; i < SHA_DIGEST_LENGTH; i++) | ||
66 | seed[i] ^= seedmask[i]; | ||
67 | |||
68 | Free(dbmask); | ||
69 | return (1); | ||
70 | } | ||
71 | |||
72 | int RSA_padding_check_PKCS1_OAEP(unsigned char *to, int tlen, | ||
73 | unsigned char *from, int flen, int num, unsigned char *param, | ||
74 | int plen) | ||
75 | { | ||
76 | int i, dblen, mlen = -1; | ||
77 | unsigned char *maskeddb; | ||
78 | int lzero; | ||
79 | unsigned char *db, seed[SHA_DIGEST_LENGTH], phash[SHA_DIGEST_LENGTH]; | ||
80 | |||
81 | if (--num < 2 * SHA_DIGEST_LENGTH + 1) | ||
82 | { | ||
83 | RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP, RSA_R_OAEP_DECODING_ERROR); | ||
84 | return (-1); | ||
85 | } | ||
86 | |||
87 | dblen = num - SHA_DIGEST_LENGTH; | ||
88 | db = Malloc(dblen); | ||
89 | if (db == NULL) | ||
90 | { | ||
91 | RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_OAEP, ERR_R_MALLOC_FAILURE); | ||
92 | return (-1); | ||
93 | } | ||
94 | |||
95 | lzero = num - flen; | ||
96 | maskeddb = from - lzero + SHA_DIGEST_LENGTH; | ||
97 | |||
98 | MGF1(seed, SHA_DIGEST_LENGTH, maskeddb, dblen); | ||
99 | for (i = lzero; i < SHA_DIGEST_LENGTH; i++) | ||
100 | seed[i] ^= from[i - lzero]; | ||
101 | |||
102 | MGF1(db, dblen, seed, SHA_DIGEST_LENGTH); | ||
103 | for (i = 0; i < dblen; i++) | ||
104 | db[i] ^= maskeddb[i]; | ||
105 | |||
106 | SHA1(param, plen, phash); | ||
107 | |||
108 | if (memcmp(db, phash, SHA_DIGEST_LENGTH) != 0) | ||
109 | RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP, RSA_R_OAEP_DECODING_ERROR); | ||
110 | else | ||
111 | { | ||
112 | for (i = SHA_DIGEST_LENGTH; i < dblen; i++) | ||
113 | if (db[i] != 0x00) | ||
114 | break; | ||
115 | if (db[i] != 0x01 || i++ >= dblen) | ||
116 | RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP, | ||
117 | RSA_R_OAEP_DECODING_ERROR); | ||
118 | else | ||
119 | { | ||
120 | mlen = dblen - i; | ||
121 | if (tlen < mlen) | ||
122 | { | ||
123 | RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_OAEP, RSA_R_DATA_TOO_LARGE); | ||
124 | mlen = -1; | ||
125 | } | ||
126 | else | ||
127 | memcpy(to, db + i, mlen); | ||
128 | } | ||
129 | } | ||
130 | Free(db); | ||
131 | return (mlen); | ||
132 | } | ||
133 | |||
134 | int MGF1(unsigned char *mask, long len, unsigned char *seed, long seedlen) | ||
135 | { | ||
136 | long i, outlen = 0; | ||
137 | unsigned char cnt[4]; | ||
138 | SHA_CTX c; | ||
139 | unsigned char md[SHA_DIGEST_LENGTH]; | ||
140 | |||
141 | for (i = 0; outlen < len; i++) | ||
142 | { | ||
143 | cnt[0] = (i >> 24) & 255, cnt[1] = (i >> 16) & 255, | ||
144 | cnt[2] = (i >> 8) & 255, cnt[3] = i & 255; | ||
145 | SHA1_Init(&c); | ||
146 | SHA1_Update(&c, seed, seedlen); | ||
147 | SHA1_Update(&c, cnt, 4); | ||
148 | if (outlen + SHA_DIGEST_LENGTH <= len) | ||
149 | { | ||
150 | SHA1_Final(mask + outlen, &c); | ||
151 | outlen += SHA_DIGEST_LENGTH; | ||
152 | } | ||
153 | else | ||
154 | { | ||
155 | SHA1_Final(md, &c); | ||
156 | memcpy(mask + outlen, md, len - outlen); | ||
157 | outlen = len; | ||
158 | } | ||
159 | } | ||
160 | return (0); | ||
161 | } | ||
162 | #endif | ||
diff --git a/src/lib/libcrypto/stack/safestack.h b/src/lib/libcrypto/stack/safestack.h new file mode 100644 index 0000000000..38934981e3 --- /dev/null +++ b/src/lib/libcrypto/stack/safestack.h | |||
@@ -0,0 +1,129 @@ | |||
1 | /* ==================================================================== | ||
2 | * Copyright (c) 1999 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 | * openssl-core@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 | #ifndef HEADER_SAFESTACK_H | ||
56 | #define HEADER_SAFESTACK_H | ||
57 | |||
58 | #include <openssl/stack.h> | ||
59 | |||
60 | #define STACK_OF(type) STACK_##type | ||
61 | |||
62 | #define DECLARE_STACK_OF(type) \ | ||
63 | typedef struct stack_st_##type \ | ||
64 | { \ | ||
65 | STACK stack; \ | ||
66 | } STACK_OF(type); \ | ||
67 | STACK_OF(type) *sk_##type##_new(int (*cmp)(type **,type **)); \ | ||
68 | STACK_OF(type) *sk_##type##_new_null(void); \ | ||
69 | void sk_##type##_free(STACK_OF(type) *sk); \ | ||
70 | int sk_##type##_num(const STACK_OF(type) *sk); \ | ||
71 | type *sk_##type##_value(const STACK_OF(type) *sk,int n); \ | ||
72 | type *sk_##type##_set(STACK_OF(type) *sk,int n,type *v); \ | ||
73 | void sk_##type##_zero(STACK_OF(type) *sk); \ | ||
74 | int sk_##type##_push(STACK_OF(type) *sk,type *v); \ | ||
75 | int sk_##type##_unshift(STACK_OF(type) *sk,type *v); \ | ||
76 | int sk_##type##_find(STACK_OF(type) *sk,type *v); \ | ||
77 | type *sk_##type##_delete(STACK_OF(type) *sk,int n); \ | ||
78 | void sk_##type##_delete_ptr(STACK_OF(type) *sk,type *v); \ | ||
79 | int sk_##type##_insert(STACK_OF(type) *sk,type *v,int n); \ | ||
80 | int (*sk_##type##_set_cmp_func(STACK_OF(type) *sk, \ | ||
81 | int (*cmp)(type **,type **)))(type **,type **); \ | ||
82 | STACK_OF(type) *sk_##type##_dup(STACK_OF(type) *sk); \ | ||
83 | void sk_##type##_pop_free(STACK_OF(type) *sk,void (*func)(type *)); \ | ||
84 | type *sk_##type##_shift(STACK_OF(type) *sk); \ | ||
85 | type *sk_##type##_pop(STACK_OF(type) *sk); \ | ||
86 | void sk_##type##_sort(STACK_OF(type) *sk); | ||
87 | |||
88 | #define IMPLEMENT_STACK_OF(type) \ | ||
89 | STACK_OF(type) *sk_##type##_new(int (*cmp)(type **,type **)) \ | ||
90 | { return (STACK_OF(type) *)sk_new(cmp); } \ | ||
91 | STACK_OF(type) *sk_##type##_new_null() \ | ||
92 | { return (STACK_OF(type) *)sk_new_null(); } \ | ||
93 | void sk_##type##_free(STACK_OF(type) *sk) \ | ||
94 | { sk_free((STACK *)sk); } \ | ||
95 | int sk_##type##_num(const STACK_OF(type) *sk) \ | ||
96 | { return M_sk_num((const STACK *)sk); } \ | ||
97 | type *sk_##type##_value(const STACK_OF(type) *sk,int n) \ | ||
98 | { return (type *)sk_value((STACK *)sk,n); } \ | ||
99 | type *sk_##type##_set(STACK_OF(type) *sk,int n,type *v) \ | ||
100 | { return (type *)(sk_set((STACK *)sk,n,(char *)v)); } \ | ||
101 | void sk_##type##_zero(STACK_OF(type) *sk) \ | ||
102 | { sk_zero((STACK *)sk); } \ | ||
103 | int sk_##type##_push(STACK_OF(type) *sk,type *v) \ | ||
104 | { return sk_push((STACK *)sk,(char *)v); } \ | ||
105 | int sk_##type##_unshift(STACK_OF(type) *sk,type *v) \ | ||
106 | { return sk_unshift((STACK *)sk,(char *)v); } \ | ||
107 | int sk_##type##_find(STACK_OF(type) *sk,type *v) \ | ||
108 | { return sk_find((STACK *)sk,(char *)v); } \ | ||
109 | type *sk_##type##_delete(STACK_OF(type) *sk,int n) \ | ||
110 | { return (type *)sk_delete((STACK *)sk,n); } \ | ||
111 | void sk_##type##_delete_ptr(STACK_OF(type) *sk,type *v) \ | ||
112 | { sk_delete_ptr((STACK *)sk,(char *)v); } \ | ||
113 | int sk_##type##_insert(STACK_OF(type) *sk,type *v,int n) \ | ||
114 | { return sk_insert((STACK *)sk,(char *)v,n); } \ | ||
115 | int (*sk_##type##_set_cmp_func(STACK_OF(type) *sk, \ | ||
116 | int (*cmp)(type **,type **)))(type **,type **) \ | ||
117 | { return (int (*)(type **,type **))sk_set_cmp_func((STACK *)sk,cmp); } \ | ||
118 | STACK_OF(type) *sk_##type##_dup(STACK_OF(type) *sk) \ | ||
119 | { return (STACK_OF(type) *)sk_dup((STACK *)sk); } \ | ||
120 | void sk_##type##_pop_free(STACK_OF(type) *sk,void (*func)(type *)) \ | ||
121 | { sk_pop_free((STACK *)sk,func); } \ | ||
122 | type *sk_##type##_shift(STACK_OF(type) *sk) \ | ||
123 | { return (type *)sk_shift((STACK *)sk); } \ | ||
124 | type *sk_##type##_pop(STACK_OF(type) *sk) \ | ||
125 | { return (type *)sk_pop((STACK *)sk); } \ | ||
126 | void sk_##type##_sort(STACK_OF(type) *sk) \ | ||
127 | { sk_sort((STACK *)sk); } | ||
128 | |||
129 | #endif /* ndef HEADER_SAFESTACK_H */ | ||
diff --git a/src/lib/libcrypto/ui/ui.h b/src/lib/libcrypto/ui/ui.h new file mode 100644 index 0000000000..735a2d988e --- /dev/null +++ b/src/lib/libcrypto/ui/ui.h | |||
@@ -0,0 +1,387 @@ | |||
1 | /* crypto/ui/ui.h -*- mode:C; c-file-style: "eay" -*- */ | ||
2 | /* Written by Richard Levitte (richard@levitte.org) for the OpenSSL | ||
3 | * project 2001. | ||
4 | */ | ||
5 | /* ==================================================================== | ||
6 | * Copyright (c) 2001 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 | #ifndef HEADER_UI_H | ||
60 | #define HEADER_UI_H | ||
61 | |||
62 | #include <openssl/crypto.h> | ||
63 | #include <openssl/safestack.h> | ||
64 | |||
65 | #ifdef __cplusplus | ||
66 | extern "C" { | ||
67 | #endif | ||
68 | |||
69 | /* The UI type is a holder for a specific user interface session. It can | ||
70 | contain an illimited number of informational or error strings as well | ||
71 | as things to prompt for, both passwords (noecho mode) and others (echo | ||
72 | mode), and verification of the same. All of these are called strings, | ||
73 | and are further described below. */ | ||
74 | typedef struct ui_st UI; | ||
75 | |||
76 | /* All instances of UI have a reference to a method structure, which is a | ||
77 | ordered vector of functions that implement the lower level things to do. | ||
78 | There is an instruction on the implementation further down, in the section | ||
79 | for method implementors. */ | ||
80 | typedef struct ui_method_st UI_METHOD; | ||
81 | |||
82 | |||
83 | /* All the following functions return -1 or NULL on error and in some cases | ||
84 | (UI_process()) -2 if interrupted or in some other way cancelled. | ||
85 | When everything is fine, they return 0, a positive value or a non-NULL | ||
86 | pointer, all depending on their purpose. */ | ||
87 | |||
88 | /* Creators and destructor. */ | ||
89 | UI *UI_new(void); | ||
90 | UI *UI_new_method(const UI_METHOD *method); | ||
91 | void UI_free(UI *ui); | ||
92 | |||
93 | /* The following functions are used to add strings to be printed and prompt | ||
94 | strings to prompt for data. The names are UI_{add,dup}_<function>_string | ||
95 | and UI_{add,dup}_input_boolean. | ||
96 | |||
97 | UI_{add,dup}_<function>_string have the following meanings: | ||
98 | add add a text or prompt string. The pointers given to these | ||
99 | functions are used verbatim, no copying is done. | ||
100 | dup make a copy of the text or prompt string, then add the copy | ||
101 | to the collection of strings in the user interface. | ||
102 | <function> | ||
103 | The function is a name for the functionality that the given | ||
104 | string shall be used for. It can be one of: | ||
105 | input use the string as data prompt. | ||
106 | verify use the string as verification prompt. This | ||
107 | is used to verify a previous input. | ||
108 | info use the string for informational output. | ||
109 | error use the string for error output. | ||
110 | Honestly, there's currently no difference between info and error for the | ||
111 | moment. | ||
112 | |||
113 | UI_{add,dup}_input_boolean have the same semantics for "add" and "dup", | ||
114 | and are typically used when one wants to prompt for a yes/no response. | ||
115 | |||
116 | |||
117 | All of the functions in this group take a UI and a prompt string. | ||
118 | The string input and verify addition functions also take a flag argument, | ||
119 | a buffer for the result to end up with, a minimum input size and a maximum | ||
120 | input size (the result buffer MUST be large enough to be able to contain | ||
121 | the maximum number of characters). Additionally, the verify addition | ||
122 | functions takes another buffer to compare the result against. | ||
123 | The boolean input functions take an action description string (which should | ||
124 | be safe to ignore if the expected user action is obvious, for example with | ||
125 | a dialog box with an OK button and a Cancel button), a string of acceptable | ||
126 | characters to mean OK and to mean Cancel. The two last strings are checked | ||
127 | to make sure they don't have common characters. Additionally, the same | ||
128 | flag argument as for the string input is taken, as well as a result buffer. | ||
129 | The result buffer is required to be at least one byte long. Depending on | ||
130 | the answer, the first character from the OK or the Cancel character strings | ||
131 | will be stored in the first byte of the result buffer. No NUL will be | ||
132 | added, so the result is *not* a string. | ||
133 | |||
134 | On success, the all return an index of the added information. That index | ||
135 | is usefull when retrieving results with UI_get0_result(). */ | ||
136 | int UI_add_input_string(UI *ui, const char *prompt, int flags, | ||
137 | char *result_buf, int minsize, int maxsize); | ||
138 | int UI_dup_input_string(UI *ui, const char *prompt, int flags, | ||
139 | char *result_buf, int minsize, int maxsize); | ||
140 | int UI_add_verify_string(UI *ui, const char *prompt, int flags, | ||
141 | char *result_buf, int minsize, int maxsize, const char *test_buf); | ||
142 | int UI_dup_verify_string(UI *ui, const char *prompt, int flags, | ||
143 | char *result_buf, int minsize, int maxsize, const char *test_buf); | ||
144 | int UI_add_input_boolean(UI *ui, const char *prompt, const char *action_desc, | ||
145 | const char *ok_chars, const char *cancel_chars, | ||
146 | int flags, char *result_buf); | ||
147 | int UI_dup_input_boolean(UI *ui, const char *prompt, const char *action_desc, | ||
148 | const char *ok_chars, const char *cancel_chars, | ||
149 | int flags, char *result_buf); | ||
150 | int UI_add_info_string(UI *ui, const char *text); | ||
151 | int UI_dup_info_string(UI *ui, const char *text); | ||
152 | int UI_add_error_string(UI *ui, const char *text); | ||
153 | int UI_dup_error_string(UI *ui, const char *text); | ||
154 | |||
155 | /* These are the possible flags. They can be or'ed together. */ | ||
156 | /* Use to have echoing of input */ | ||
157 | #define UI_INPUT_FLAG_ECHO 0x01 | ||
158 | /* Use a default password. Where that password is found is completely | ||
159 | up to the application, it might for example be in the user data set | ||
160 | with UI_add_user_data(). It is not recommended to have more than | ||
161 | one input in each UI being marked with this flag, or the application | ||
162 | might get confused. */ | ||
163 | #define UI_INPUT_FLAG_DEFAULT_PWD 0x02 | ||
164 | |||
165 | /* The user of these routines may want to define flags of their own. The core | ||
166 | UI won't look at those, but will pass them on to the method routines. They | ||
167 | must use higher bits so they don't get confused with the UI bits above. | ||
168 | UI_INPUT_FLAG_USER_BASE tells which is the lowest bit to use. A good | ||
169 | example of use is this: | ||
170 | |||
171 | #define MY_UI_FLAG1 (0x01 << UI_INPUT_FLAG_USER_BASE) | ||
172 | |||
173 | */ | ||
174 | #define UI_INPUT_FLAG_USER_BASE 16 | ||
175 | |||
176 | |||
177 | /* The following function helps construct a prompt. object_desc is a | ||
178 | textual short description of the object, for example "pass phrase", | ||
179 | and object_name is the name of the object (might be a card name or | ||
180 | a file name. | ||
181 | The returned string shall always be allocated on the heap with | ||
182 | OPENSSL_malloc(), and need to be free'd with OPENSSL_free(). | ||
183 | |||
184 | If the ui_method doesn't contain a pointer to a user-defined prompt | ||
185 | constructor, a default string is built, looking like this: | ||
186 | |||
187 | "Enter {object_desc} for {object_name}:" | ||
188 | |||
189 | So, if object_desc has the value "pass phrase" and object_name has | ||
190 | the value "foo.key", the resulting string is: | ||
191 | |||
192 | "Enter pass phrase for foo.key:" | ||
193 | */ | ||
194 | char *UI_construct_prompt(UI *ui_method, | ||
195 | const char *object_desc, const char *object_name); | ||
196 | |||
197 | |||
198 | /* The following function is used to store a pointer to user-specific data. | ||
199 | Any previous such pointer will be returned and replaced. | ||
200 | |||
201 | For callback purposes, this function makes a lot more sense than using | ||
202 | ex_data, since the latter requires that different parts of OpenSSL or | ||
203 | applications share the same ex_data index. | ||
204 | |||
205 | Note that the UI_OpenSSL() method completely ignores the user data. | ||
206 | Other methods may not, however. */ | ||
207 | void *UI_add_user_data(UI *ui, void *user_data); | ||
208 | /* We need a user data retrieving function as well. */ | ||
209 | void *UI_get0_user_data(UI *ui); | ||
210 | |||
211 | /* Return the result associated with a prompt given with the index i. */ | ||
212 | const char *UI_get0_result(UI *ui, int i); | ||
213 | |||
214 | /* When all strings have been added, process the whole thing. */ | ||
215 | int UI_process(UI *ui); | ||
216 | |||
217 | /* Give a user interface parametrised control commands. This can be used to | ||
218 | send down an integer, a data pointer or a function pointer, as well as | ||
219 | be used to get information from a UI. */ | ||
220 | int UI_ctrl(UI *ui, int cmd, long i, void *p, void (*f)()); | ||
221 | |||
222 | /* The commands */ | ||
223 | /* Use UI_CONTROL_PRINT_ERRORS with the value 1 to have UI_process print the | ||
224 | OpenSSL error stack before printing any info or added error messages and | ||
225 | before any prompting. */ | ||
226 | #define UI_CTRL_PRINT_ERRORS 1 | ||
227 | /* Check if a UI_process() is possible to do again with the same instance of | ||
228 | a user interface. This makes UI_ctrl() return 1 if it is redoable, and 0 | ||
229 | if not. */ | ||
230 | #define UI_CTRL_IS_REDOABLE 2 | ||
231 | |||
232 | |||
233 | /* Some methods may use extra data */ | ||
234 | #define UI_set_app_data(s,arg) UI_set_ex_data(s,0,arg) | ||
235 | #define UI_get_app_data(s) UI_get_ex_data(s,0) | ||
236 | int UI_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, | ||
237 | CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func); | ||
238 | int UI_set_ex_data(UI *r,int idx,void *arg); | ||
239 | void *UI_get_ex_data(UI *r, int idx); | ||
240 | |||
241 | /* Use specific methods instead of the built-in one */ | ||
242 | void UI_set_default_method(const UI_METHOD *meth); | ||
243 | const UI_METHOD *UI_get_default_method(void); | ||
244 | const UI_METHOD *UI_get_method(UI *ui); | ||
245 | const UI_METHOD *UI_set_method(UI *ui, const UI_METHOD *meth); | ||
246 | |||
247 | /* The method with all the built-in thingies */ | ||
248 | UI_METHOD *UI_OpenSSL(void); | ||
249 | |||
250 | |||
251 | /* ---------- For method writers ---------- */ | ||
252 | /* A method contains a number of functions that implement the low level | ||
253 | of the User Interface. The functions are: | ||
254 | |||
255 | an opener This function starts a session, maybe by opening | ||
256 | a channel to a tty, or by opening a window. | ||
257 | a writer This function is called to write a given string, | ||
258 | maybe to the tty, maybe as a field label in a | ||
259 | window. | ||
260 | a flusher This function is called to flush everything that | ||
261 | has been output so far. It can be used to actually | ||
262 | display a dialog box after it has been built. | ||
263 | a reader This function is called to read a given prompt, | ||
264 | maybe from the tty, maybe from a field in a | ||
265 | window. Note that it's called wth all string | ||
266 | structures, not only the prompt ones, so it must | ||
267 | check such things itself. | ||
268 | a closer This function closes the session, maybe by closing | ||
269 | the channel to the tty, or closing the window. | ||
270 | |||
271 | All these functions are expected to return: | ||
272 | |||
273 | 0 on error. | ||
274 | 1 on success. | ||
275 | -1 on out-of-band events, for example if some prompting has | ||
276 | been canceled (by pressing Ctrl-C, for example). This is | ||
277 | only checked when returned by the flusher or the reader. | ||
278 | |||
279 | The way this is used, the opener is first called, then the writer for all | ||
280 | strings, then the flusher, then the reader for all strings and finally the | ||
281 | closer. Note that if you want to prompt from a terminal or other command | ||
282 | line interface, the best is to have the reader also write the prompts | ||
283 | instead of having the writer do it. If you want to prompt from a dialog | ||
284 | box, the writer can be used to build up the contents of the box, and the | ||
285 | flusher to actually display the box and run the event loop until all data | ||
286 | has been given, after which the reader only grabs the given data and puts | ||
287 | them back into the UI strings. | ||
288 | |||
289 | All method functions take a UI as argument. Additionally, the writer and | ||
290 | the reader take a UI_STRING. | ||
291 | */ | ||
292 | |||
293 | /* The UI_STRING type is the data structure that contains all the needed info | ||
294 | about a string or a prompt, including test data for a verification prompt. | ||
295 | */ | ||
296 | DECLARE_STACK_OF(UI_STRING) | ||
297 | typedef struct ui_string_st UI_STRING; | ||
298 | |||
299 | /* The different types of strings that are currently supported. | ||
300 | This is only needed by method authors. */ | ||
301 | enum UI_string_types | ||
302 | { | ||
303 | UIT_NONE=0, | ||
304 | UIT_PROMPT, /* Prompt for a string */ | ||
305 | UIT_VERIFY, /* Prompt for a string and verify */ | ||
306 | UIT_BOOLEAN, /* Prompt for a yes/no response */ | ||
307 | UIT_INFO, /* Send info to the user */ | ||
308 | UIT_ERROR /* Send an error message to the user */ | ||
309 | }; | ||
310 | |||
311 | /* Create and manipulate methods */ | ||
312 | UI_METHOD *UI_create_method(char *name); | ||
313 | void UI_destroy_method(UI_METHOD *ui_method); | ||
314 | int UI_method_set_opener(UI_METHOD *method, int (*opener)(UI *ui)); | ||
315 | int UI_method_set_writer(UI_METHOD *method, int (*writer)(UI *ui, UI_STRING *uis)); | ||
316 | int UI_method_set_flusher(UI_METHOD *method, int (*flusher)(UI *ui)); | ||
317 | int UI_method_set_reader(UI_METHOD *method, int (*reader)(UI *ui, UI_STRING *uis)); | ||
318 | int UI_method_set_closer(UI_METHOD *method, int (*closer)(UI *ui)); | ||
319 | int (*UI_method_get_opener(UI_METHOD *method))(UI*); | ||
320 | int (*UI_method_get_writer(UI_METHOD *method))(UI*,UI_STRING*); | ||
321 | int (*UI_method_get_flusher(UI_METHOD *method))(UI*); | ||
322 | int (*UI_method_get_reader(UI_METHOD *method))(UI*,UI_STRING*); | ||
323 | int (*UI_method_get_closer(UI_METHOD *method))(UI*); | ||
324 | |||
325 | /* The following functions are helpers for method writers to access relevant | ||
326 | data from a UI_STRING. */ | ||
327 | |||
328 | /* Return type of the UI_STRING */ | ||
329 | enum UI_string_types UI_get_string_type(UI_STRING *uis); | ||
330 | /* Return input flags of the UI_STRING */ | ||
331 | int UI_get_input_flags(UI_STRING *uis); | ||
332 | /* Return the actual string to output (the prompt, info or error) */ | ||
333 | const char *UI_get0_output_string(UI_STRING *uis); | ||
334 | /* Return the optional action string to output (the boolean promtp instruction) */ | ||
335 | const char *UI_get0_action_string(UI_STRING *uis); | ||
336 | /* Return the result of a prompt */ | ||
337 | const char *UI_get0_result_string(UI_STRING *uis); | ||
338 | /* Return the string to test the result against. Only useful with verifies. */ | ||
339 | const char *UI_get0_test_string(UI_STRING *uis); | ||
340 | /* Return the required minimum size of the result */ | ||
341 | int UI_get_result_minsize(UI_STRING *uis); | ||
342 | /* Return the required maximum size of the result */ | ||
343 | int UI_get_result_maxsize(UI_STRING *uis); | ||
344 | /* Set the result of a UI_STRING. */ | ||
345 | int UI_set_result(UI *ui, UI_STRING *uis, const char *result); | ||
346 | |||
347 | |||
348 | /* A couple of popular utility functions */ | ||
349 | int UI_UTIL_read_pw_string(char *buf,int length,const char *prompt,int verify); | ||
350 | int UI_UTIL_read_pw(char *buf,char *buff,int size,const char *prompt,int verify); | ||
351 | |||
352 | |||
353 | /* BEGIN ERROR CODES */ | ||
354 | /* The following lines are auto generated by the script mkerr.pl. Any changes | ||
355 | * made after this point may be overwritten when the script is next run. | ||
356 | */ | ||
357 | void ERR_load_UI_strings(void); | ||
358 | |||
359 | /* Error codes for the UI functions. */ | ||
360 | |||
361 | /* Function codes. */ | ||
362 | #define UI_F_GENERAL_ALLOCATE_BOOLEAN 108 | ||
363 | #define UI_F_GENERAL_ALLOCATE_PROMPT 109 | ||
364 | #define UI_F_GENERAL_ALLOCATE_STRING 100 | ||
365 | #define UI_F_UI_CTRL 111 | ||
366 | #define UI_F_UI_DUP_ERROR_STRING 101 | ||
367 | #define UI_F_UI_DUP_INFO_STRING 102 | ||
368 | #define UI_F_UI_DUP_INPUT_BOOLEAN 110 | ||
369 | #define UI_F_UI_DUP_INPUT_STRING 103 | ||
370 | #define UI_F_UI_DUP_VERIFY_STRING 106 | ||
371 | #define UI_F_UI_GET0_RESULT 107 | ||
372 | #define UI_F_UI_NEW_METHOD 104 | ||
373 | #define UI_F_UI_SET_RESULT 105 | ||
374 | |||
375 | /* Reason codes. */ | ||
376 | #define UI_R_COMMON_OK_AND_CANCEL_CHARACTERS 104 | ||
377 | #define UI_R_INDEX_TOO_LARGE 102 | ||
378 | #define UI_R_INDEX_TOO_SMALL 103 | ||
379 | #define UI_R_NO_RESULT_BUFFER 105 | ||
380 | #define UI_R_RESULT_TOO_LARGE 100 | ||
381 | #define UI_R_RESULT_TOO_SMALL 101 | ||
382 | #define UI_R_UNKNOWN_CONTROL_COMMAND 106 | ||
383 | |||
384 | #ifdef __cplusplus | ||
385 | } | ||
386 | #endif | ||
387 | #endif | ||
diff --git a/src/lib/libcrypto/ui/ui_compat.h b/src/lib/libcrypto/ui/ui_compat.h new file mode 100644 index 0000000000..b35c9bb7fd --- /dev/null +++ b/src/lib/libcrypto/ui/ui_compat.h | |||
@@ -0,0 +1,83 @@ | |||
1 | /* crypto/ui/ui.h -*- mode:C; c-file-style: "eay" -*- */ | ||
2 | /* Written by Richard Levitte (richard@levitte.org) for the OpenSSL | ||
3 | * project 2001. | ||
4 | */ | ||
5 | /* ==================================================================== | ||
6 | * Copyright (c) 2001 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 | #ifndef HEADER_UI_COMPAT_H | ||
60 | #define HEADER_UI_COMPAT_H | ||
61 | |||
62 | #include <openssl/opensslconf.h> | ||
63 | #include <openssl/ui.h> | ||
64 | |||
65 | #ifdef __cplusplus | ||
66 | extern "C" { | ||
67 | #endif | ||
68 | |||
69 | /* The following functions were previously part of the DES section, | ||
70 | and are provided here for backward compatibility reasons. */ | ||
71 | |||
72 | #define des_read_pw_string(b,l,p,v) \ | ||
73 | _ossl_old_des_read_pw_string((b),(l),(p),(v)) | ||
74 | #define des_read_pw(b,bf,s,p,v) \ | ||
75 | _ossl_old_des_read_pw((b),(bf),(s),(p),(v)) | ||
76 | |||
77 | int _ossl_old_des_read_pw_string(char *buf,int length,const char *prompt,int verify); | ||
78 | int _ossl_old_des_read_pw(char *buf,char *buff,int size,const char *prompt,int verify); | ||
79 | |||
80 | #ifdef __cplusplus | ||
81 | } | ||
82 | #endif | ||
83 | #endif | ||
diff --git a/src/lib/libcrypto/ui/ui_err.c b/src/lib/libcrypto/ui/ui_err.c new file mode 100644 index 0000000000..39a62ae737 --- /dev/null +++ b/src/lib/libcrypto/ui/ui_err.c | |||
@@ -0,0 +1,111 @@ | |||
1 | /* crypto/ui/ui_err.c */ | ||
2 | /* ==================================================================== | ||
3 | * Copyright (c) 1999 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/ui.h> | ||
64 | |||
65 | /* BEGIN ERROR CODES */ | ||
66 | #ifndef OPENSSL_NO_ERR | ||
67 | static ERR_STRING_DATA UI_str_functs[]= | ||
68 | { | ||
69 | {ERR_PACK(0,UI_F_GENERAL_ALLOCATE_BOOLEAN,0), "GENERAL_ALLOCATE_BOOLEAN"}, | ||
70 | {ERR_PACK(0,UI_F_GENERAL_ALLOCATE_PROMPT,0), "GENERAL_ALLOCATE_PROMPT"}, | ||
71 | {ERR_PACK(0,UI_F_GENERAL_ALLOCATE_STRING,0), "GENERAL_ALLOCATE_STRING"}, | ||
72 | {ERR_PACK(0,UI_F_UI_CTRL,0), "UI_ctrl"}, | ||
73 | {ERR_PACK(0,UI_F_UI_DUP_ERROR_STRING,0), "UI_dup_error_string"}, | ||
74 | {ERR_PACK(0,UI_F_UI_DUP_INFO_STRING,0), "UI_dup_info_string"}, | ||
75 | {ERR_PACK(0,UI_F_UI_DUP_INPUT_BOOLEAN,0), "UI_dup_input_boolean"}, | ||
76 | {ERR_PACK(0,UI_F_UI_DUP_INPUT_STRING,0), "UI_dup_input_string"}, | ||
77 | {ERR_PACK(0,UI_F_UI_DUP_VERIFY_STRING,0), "UI_dup_verify_string"}, | ||
78 | {ERR_PACK(0,UI_F_UI_GET0_RESULT,0), "UI_get0_result"}, | ||
79 | {ERR_PACK(0,UI_F_UI_NEW_METHOD,0), "UI_new_method"}, | ||
80 | {ERR_PACK(0,UI_F_UI_SET_RESULT,0), "UI_set_result"}, | ||
81 | {0,NULL} | ||
82 | }; | ||
83 | |||
84 | static ERR_STRING_DATA UI_str_reasons[]= | ||
85 | { | ||
86 | {UI_R_COMMON_OK_AND_CANCEL_CHARACTERS ,"common ok and cancel characters"}, | ||
87 | {UI_R_INDEX_TOO_LARGE ,"index too large"}, | ||
88 | {UI_R_INDEX_TOO_SMALL ,"index too small"}, | ||
89 | {UI_R_NO_RESULT_BUFFER ,"no result buffer"}, | ||
90 | {UI_R_RESULT_TOO_LARGE ,"result too large"}, | ||
91 | {UI_R_RESULT_TOO_SMALL ,"result too small"}, | ||
92 | {UI_R_UNKNOWN_CONTROL_COMMAND ,"unknown control command"}, | ||
93 | {0,NULL} | ||
94 | }; | ||
95 | |||
96 | #endif | ||
97 | |||
98 | void ERR_load_UI_strings(void) | ||
99 | { | ||
100 | static int init=1; | ||
101 | |||
102 | if (init) | ||
103 | { | ||
104 | init=0; | ||
105 | #ifndef OPENSSL_NO_ERR | ||
106 | ERR_load_strings(ERR_LIB_UI,UI_str_functs); | ||
107 | ERR_load_strings(ERR_LIB_UI,UI_str_reasons); | ||
108 | #endif | ||
109 | |||
110 | } | ||
111 | } | ||
diff --git a/src/lib/libcrypto/ui/ui_lib.c b/src/lib/libcrypto/ui/ui_lib.c new file mode 100644 index 0000000000..16946cad95 --- /dev/null +++ b/src/lib/libcrypto/ui/ui_lib.c | |||
@@ -0,0 +1,899 @@ | |||
1 | /* crypto/ui/ui_lib.c -*- mode:C; c-file-style: "eay" -*- */ | ||
2 | /* Written by Richard Levitte (richard@levitte.org) for the OpenSSL | ||
3 | * project 2001. | ||
4 | */ | ||
5 | /* ==================================================================== | ||
6 | * Copyright (c) 2001 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 <string.h> | ||
60 | #include <openssl/e_os2.h> | ||
61 | #include <openssl/buffer.h> | ||
62 | #include <openssl/ui.h> | ||
63 | #include <openssl/err.h> | ||
64 | #include "ui_locl.h" | ||
65 | |||
66 | IMPLEMENT_STACK_OF(UI_STRING_ST) | ||
67 | |||
68 | static const UI_METHOD *default_UI_meth=NULL; | ||
69 | |||
70 | UI *UI_new(void) | ||
71 | { | ||
72 | return(UI_new_method(NULL)); | ||
73 | } | ||
74 | |||
75 | UI *UI_new_method(const UI_METHOD *method) | ||
76 | { | ||
77 | UI *ret; | ||
78 | |||
79 | ret=(UI *)OPENSSL_malloc(sizeof(UI)); | ||
80 | if (ret == NULL) | ||
81 | { | ||
82 | UIerr(UI_F_UI_NEW_METHOD,ERR_R_MALLOC_FAILURE); | ||
83 | return NULL; | ||
84 | } | ||
85 | if (method == NULL) | ||
86 | ret->meth=UI_get_default_method(); | ||
87 | else | ||
88 | ret->meth=method; | ||
89 | |||
90 | ret->strings=NULL; | ||
91 | ret->user_data=NULL; | ||
92 | CRYPTO_new_ex_data(CRYPTO_EX_INDEX_UI, ret, &ret->ex_data); | ||
93 | return ret; | ||
94 | } | ||
95 | |||
96 | static void free_string(UI_STRING *uis) | ||
97 | { | ||
98 | if (uis->flags & OUT_STRING_FREEABLE) | ||
99 | { | ||
100 | OPENSSL_free((char *)uis->out_string); | ||
101 | switch(uis->type) | ||
102 | { | ||
103 | case UIT_BOOLEAN: | ||
104 | OPENSSL_free((char *)uis->_.boolean_data.action_desc); | ||
105 | OPENSSL_free((char *)uis->_.boolean_data.ok_chars); | ||
106 | OPENSSL_free((char *)uis->_.boolean_data.cancel_chars); | ||
107 | break; | ||
108 | default: | ||
109 | break; | ||
110 | } | ||
111 | } | ||
112 | OPENSSL_free(uis); | ||
113 | } | ||
114 | |||
115 | void UI_free(UI *ui) | ||
116 | { | ||
117 | if (ui == NULL) | ||
118 | return; | ||
119 | sk_UI_STRING_pop_free(ui->strings,free_string); | ||
120 | CRYPTO_free_ex_data(CRYPTO_EX_INDEX_UI, ui, &ui->ex_data); | ||
121 | OPENSSL_free(ui); | ||
122 | } | ||
123 | |||
124 | static int allocate_string_stack(UI *ui) | ||
125 | { | ||
126 | if (ui->strings == NULL) | ||
127 | { | ||
128 | ui->strings=sk_UI_STRING_new_null(); | ||
129 | if (ui->strings == NULL) | ||
130 | { | ||
131 | return -1; | ||
132 | } | ||
133 | } | ||
134 | return 0; | ||
135 | } | ||
136 | |||
137 | static UI_STRING *general_allocate_prompt(UI *ui, const char *prompt, | ||
138 | int prompt_freeable, enum UI_string_types type, int input_flags, | ||
139 | char *result_buf) | ||
140 | { | ||
141 | UI_STRING *ret = NULL; | ||
142 | |||
143 | if (prompt == NULL) | ||
144 | { | ||
145 | UIerr(UI_F_GENERAL_ALLOCATE_PROMPT,ERR_R_PASSED_NULL_PARAMETER); | ||
146 | } | ||
147 | else if (result_buf == NULL) | ||
148 | { | ||
149 | UIerr(UI_F_GENERAL_ALLOCATE_PROMPT,UI_R_NO_RESULT_BUFFER); | ||
150 | } | ||
151 | else if ((ret = (UI_STRING *)OPENSSL_malloc(sizeof(UI_STRING)))) | ||
152 | { | ||
153 | ret->out_string=prompt; | ||
154 | ret->flags=prompt_freeable ? OUT_STRING_FREEABLE : 0; | ||
155 | ret->input_flags=input_flags; | ||
156 | ret->type=type; | ||
157 | ret->result_buf=result_buf; | ||
158 | } | ||
159 | return ret; | ||
160 | } | ||
161 | |||
162 | static int general_allocate_string(UI *ui, const char *prompt, | ||
163 | int prompt_freeable, enum UI_string_types type, int input_flags, | ||
164 | char *result_buf, int minsize, int maxsize, const char *test_buf) | ||
165 | { | ||
166 | int ret = -1; | ||
167 | UI_STRING *s = general_allocate_prompt(ui, prompt, prompt_freeable, | ||
168 | type, input_flags, result_buf); | ||
169 | |||
170 | if (s) | ||
171 | { | ||
172 | if (allocate_string_stack(ui) >= 0) | ||
173 | { | ||
174 | s->_.string_data.result_minsize=minsize; | ||
175 | s->_.string_data.result_maxsize=maxsize; | ||
176 | s->_.string_data.test_buf=test_buf; | ||
177 | ret=sk_UI_STRING_push(ui->strings, s); | ||
178 | /* sk_push() returns 0 on error. Let's addapt that */ | ||
179 | if (ret <= 0) ret--; | ||
180 | } | ||
181 | else | ||
182 | free_string(s); | ||
183 | } | ||
184 | return ret; | ||
185 | } | ||
186 | |||
187 | static int general_allocate_boolean(UI *ui, | ||
188 | const char *prompt, const char *action_desc, | ||
189 | const char *ok_chars, const char *cancel_chars, | ||
190 | int prompt_freeable, enum UI_string_types type, int input_flags, | ||
191 | char *result_buf) | ||
192 | { | ||
193 | int ret = -1; | ||
194 | UI_STRING *s; | ||
195 | const char *p; | ||
196 | |||
197 | if (ok_chars == NULL) | ||
198 | { | ||
199 | UIerr(UI_F_GENERAL_ALLOCATE_BOOLEAN,ERR_R_PASSED_NULL_PARAMETER); | ||
200 | } | ||
201 | else if (cancel_chars == NULL) | ||
202 | { | ||
203 | UIerr(UI_F_GENERAL_ALLOCATE_BOOLEAN,ERR_R_PASSED_NULL_PARAMETER); | ||
204 | } | ||
205 | else | ||
206 | { | ||
207 | for(p = ok_chars; *p; p++) | ||
208 | { | ||
209 | if (strchr(cancel_chars, *p)) | ||
210 | { | ||
211 | UIerr(UI_F_GENERAL_ALLOCATE_BOOLEAN, | ||
212 | UI_R_COMMON_OK_AND_CANCEL_CHARACTERS); | ||
213 | } | ||
214 | } | ||
215 | |||
216 | s = general_allocate_prompt(ui, prompt, prompt_freeable, | ||
217 | type, input_flags, result_buf); | ||
218 | |||
219 | if (s) | ||
220 | { | ||
221 | if (allocate_string_stack(ui) >= 0) | ||
222 | { | ||
223 | s->_.boolean_data.action_desc = action_desc; | ||
224 | s->_.boolean_data.ok_chars = ok_chars; | ||
225 | s->_.boolean_data.cancel_chars = cancel_chars; | ||
226 | ret=sk_UI_STRING_push(ui->strings, s); | ||
227 | /* sk_push() returns 0 on error. | ||
228 | Let's addapt that */ | ||
229 | if (ret <= 0) ret--; | ||
230 | } | ||
231 | else | ||
232 | free_string(s); | ||
233 | } | ||
234 | } | ||
235 | return ret; | ||
236 | } | ||
237 | |||
238 | /* Returns the index to the place in the stack or 0 for error. Uses a | ||
239 | direct reference to the prompt. */ | ||
240 | int UI_add_input_string(UI *ui, const char *prompt, int flags, | ||
241 | char *result_buf, int minsize, int maxsize) | ||
242 | { | ||
243 | return general_allocate_string(ui, prompt, 0, | ||
244 | UIT_PROMPT, flags, result_buf, minsize, maxsize, NULL); | ||
245 | } | ||
246 | |||
247 | /* Same as UI_add_input_string(), excepts it takes a copy of the prompt */ | ||
248 | int UI_dup_input_string(UI *ui, const char *prompt, int flags, | ||
249 | char *result_buf, int minsize, int maxsize) | ||
250 | { | ||
251 | char *prompt_copy=NULL; | ||
252 | |||
253 | if (prompt) | ||
254 | { | ||
255 | prompt_copy=BUF_strdup(prompt); | ||
256 | if (prompt_copy == NULL) | ||
257 | { | ||
258 | UIerr(UI_F_UI_DUP_INPUT_STRING,ERR_R_MALLOC_FAILURE); | ||
259 | return 0; | ||
260 | } | ||
261 | } | ||
262 | |||
263 | return general_allocate_string(ui, prompt_copy, 1, | ||
264 | UIT_PROMPT, flags, result_buf, minsize, maxsize, NULL); | ||
265 | } | ||
266 | |||
267 | int UI_add_verify_string(UI *ui, const char *prompt, int flags, | ||
268 | char *result_buf, int minsize, int maxsize, const char *test_buf) | ||
269 | { | ||
270 | return general_allocate_string(ui, prompt, 0, | ||
271 | UIT_VERIFY, flags, result_buf, minsize, maxsize, test_buf); | ||
272 | } | ||
273 | |||
274 | int UI_dup_verify_string(UI *ui, const char *prompt, int flags, | ||
275 | char *result_buf, int minsize, int maxsize, const char *test_buf) | ||
276 | { | ||
277 | char *prompt_copy=NULL; | ||
278 | |||
279 | if (prompt) | ||
280 | { | ||
281 | prompt_copy=BUF_strdup(prompt); | ||
282 | if (prompt_copy == NULL) | ||
283 | { | ||
284 | UIerr(UI_F_UI_DUP_VERIFY_STRING,ERR_R_MALLOC_FAILURE); | ||
285 | return -1; | ||
286 | } | ||
287 | } | ||
288 | |||
289 | return general_allocate_string(ui, prompt_copy, 1, | ||
290 | UIT_VERIFY, flags, result_buf, minsize, maxsize, test_buf); | ||
291 | } | ||
292 | |||
293 | int UI_add_input_boolean(UI *ui, const char *prompt, const char *action_desc, | ||
294 | const char *ok_chars, const char *cancel_chars, | ||
295 | int flags, char *result_buf) | ||
296 | { | ||
297 | return general_allocate_boolean(ui, prompt, action_desc, | ||
298 | ok_chars, cancel_chars, 0, UIT_BOOLEAN, flags, result_buf); | ||
299 | } | ||
300 | |||
301 | int UI_dup_input_boolean(UI *ui, const char *prompt, const char *action_desc, | ||
302 | const char *ok_chars, const char *cancel_chars, | ||
303 | int flags, char *result_buf) | ||
304 | { | ||
305 | char *prompt_copy = NULL; | ||
306 | char *action_desc_copy = NULL; | ||
307 | char *ok_chars_copy = NULL; | ||
308 | char *cancel_chars_copy = NULL; | ||
309 | |||
310 | if (prompt) | ||
311 | { | ||
312 | prompt_copy=BUF_strdup(prompt); | ||
313 | if (prompt_copy == NULL) | ||
314 | { | ||
315 | UIerr(UI_F_UI_DUP_INPUT_BOOLEAN,ERR_R_MALLOC_FAILURE); | ||
316 | goto err; | ||
317 | } | ||
318 | } | ||
319 | |||
320 | if (action_desc) | ||
321 | { | ||
322 | action_desc_copy=BUF_strdup(action_desc); | ||
323 | if (action_desc_copy == NULL) | ||
324 | { | ||
325 | UIerr(UI_F_UI_DUP_INPUT_BOOLEAN,ERR_R_MALLOC_FAILURE); | ||
326 | goto err; | ||
327 | } | ||
328 | } | ||
329 | |||
330 | if (ok_chars) | ||
331 | { | ||
332 | ok_chars_copy=BUF_strdup(ok_chars); | ||
333 | if (ok_chars_copy == NULL) | ||
334 | { | ||
335 | UIerr(UI_F_UI_DUP_INPUT_BOOLEAN,ERR_R_MALLOC_FAILURE); | ||
336 | goto err; | ||
337 | } | ||
338 | } | ||
339 | |||
340 | if (cancel_chars) | ||
341 | { | ||
342 | cancel_chars_copy=BUF_strdup(cancel_chars); | ||
343 | if (cancel_chars_copy == NULL) | ||
344 | { | ||
345 | UIerr(UI_F_UI_DUP_INPUT_BOOLEAN,ERR_R_MALLOC_FAILURE); | ||
346 | goto err; | ||
347 | } | ||
348 | } | ||
349 | |||
350 | return general_allocate_boolean(ui, prompt_copy, action_desc_copy, | ||
351 | ok_chars_copy, cancel_chars_copy, 1, UIT_BOOLEAN, flags, | ||
352 | result_buf); | ||
353 | err: | ||
354 | if (prompt_copy) OPENSSL_free(prompt_copy); | ||
355 | if (action_desc_copy) OPENSSL_free(action_desc_copy); | ||
356 | if (ok_chars_copy) OPENSSL_free(ok_chars_copy); | ||
357 | if (cancel_chars_copy) OPENSSL_free(cancel_chars_copy); | ||
358 | return -1; | ||
359 | } | ||
360 | |||
361 | int UI_add_info_string(UI *ui, const char *text) | ||
362 | { | ||
363 | return general_allocate_string(ui, text, 0, UIT_INFO, 0, NULL, 0, 0, | ||
364 | NULL); | ||
365 | } | ||
366 | |||
367 | int UI_dup_info_string(UI *ui, const char *text) | ||
368 | { | ||
369 | char *text_copy=NULL; | ||
370 | |||
371 | if (text) | ||
372 | { | ||
373 | text_copy=BUF_strdup(text); | ||
374 | if (text_copy == NULL) | ||
375 | { | ||
376 | UIerr(UI_F_UI_DUP_INFO_STRING,ERR_R_MALLOC_FAILURE); | ||
377 | return -1; | ||
378 | } | ||
379 | } | ||
380 | |||
381 | return general_allocate_string(ui, text_copy, 1, UIT_INFO, 0, NULL, | ||
382 | 0, 0, NULL); | ||
383 | } | ||
384 | |||
385 | int UI_add_error_string(UI *ui, const char *text) | ||
386 | { | ||
387 | return general_allocate_string(ui, text, 0, UIT_ERROR, 0, NULL, 0, 0, | ||
388 | NULL); | ||
389 | } | ||
390 | |||
391 | int UI_dup_error_string(UI *ui, const char *text) | ||
392 | { | ||
393 | char *text_copy=NULL; | ||
394 | |||
395 | if (text) | ||
396 | { | ||
397 | text_copy=BUF_strdup(text); | ||
398 | if (text_copy == NULL) | ||
399 | { | ||
400 | UIerr(UI_F_UI_DUP_ERROR_STRING,ERR_R_MALLOC_FAILURE); | ||
401 | return -1; | ||
402 | } | ||
403 | } | ||
404 | return general_allocate_string(ui, text_copy, 1, UIT_ERROR, 0, NULL, | ||
405 | 0, 0, NULL); | ||
406 | } | ||
407 | |||
408 | char *UI_construct_prompt(UI *ui, const char *object_desc, | ||
409 | const char *object_name) | ||
410 | { | ||
411 | char *prompt = NULL; | ||
412 | |||
413 | if (ui->meth->ui_construct_prompt) | ||
414 | prompt = ui->meth->ui_construct_prompt(ui, | ||
415 | object_desc, object_name); | ||
416 | else | ||
417 | { | ||
418 | char prompt1[] = "Enter "; | ||
419 | char prompt2[] = " for "; | ||
420 | char prompt3[] = ":"; | ||
421 | int len = 0; | ||
422 | |||
423 | if (object_desc == NULL) | ||
424 | return NULL; | ||
425 | len = sizeof(prompt1) - 1 + strlen(object_desc); | ||
426 | if (object_name) | ||
427 | len += sizeof(prompt2) - 1 + strlen(object_name); | ||
428 | len += sizeof(prompt3) - 1; | ||
429 | |||
430 | prompt = (char *)OPENSSL_malloc(len + 1); | ||
431 | strcpy(prompt, prompt1); | ||
432 | strcat(prompt, object_desc); | ||
433 | if (object_name) | ||
434 | { | ||
435 | strcat(prompt, prompt2); | ||
436 | strcat(prompt, object_name); | ||
437 | } | ||
438 | strcat(prompt, prompt3); | ||
439 | } | ||
440 | return prompt; | ||
441 | } | ||
442 | |||
443 | void *UI_add_user_data(UI *ui, void *user_data) | ||
444 | { | ||
445 | void *old_data = ui->user_data; | ||
446 | ui->user_data = user_data; | ||
447 | return old_data; | ||
448 | } | ||
449 | |||
450 | void *UI_get0_user_data(UI *ui) | ||
451 | { | ||
452 | return ui->user_data; | ||
453 | } | ||
454 | |||
455 | const char *UI_get0_result(UI *ui, int i) | ||
456 | { | ||
457 | if (i < 0) | ||
458 | { | ||
459 | UIerr(UI_F_UI_GET0_RESULT,UI_R_INDEX_TOO_SMALL); | ||
460 | return NULL; | ||
461 | } | ||
462 | if (i >= sk_UI_STRING_num(ui->strings)) | ||
463 | { | ||
464 | UIerr(UI_F_UI_GET0_RESULT,UI_R_INDEX_TOO_LARGE); | ||
465 | return NULL; | ||
466 | } | ||
467 | return UI_get0_result_string(sk_UI_STRING_value(ui->strings, i)); | ||
468 | } | ||
469 | |||
470 | static int print_error(const char *str, size_t len, UI *ui) | ||
471 | { | ||
472 | UI_STRING uis; | ||
473 | |||
474 | memset(&uis, 0, sizeof(uis)); | ||
475 | uis.type = UIT_ERROR; | ||
476 | uis.out_string = str; | ||
477 | |||
478 | if (ui->meth->ui_write_string | ||
479 | && !ui->meth->ui_write_string(ui, &uis)) | ||
480 | return -1; | ||
481 | return 0; | ||
482 | } | ||
483 | |||
484 | int UI_process(UI *ui) | ||
485 | { | ||
486 | int i, ok=0; | ||
487 | |||
488 | if (ui->meth->ui_open_session && !ui->meth->ui_open_session(ui)) | ||
489 | return -1; | ||
490 | |||
491 | if (ui->flags & UI_FLAG_PRINT_ERRORS) | ||
492 | ERR_print_errors_cb( | ||
493 | (int (*)(const char *, size_t, void *))print_error, | ||
494 | (void *)ui); | ||
495 | |||
496 | for(i=0; i<sk_UI_STRING_num(ui->strings); i++) | ||
497 | { | ||
498 | if (ui->meth->ui_write_string | ||
499 | && !ui->meth->ui_write_string(ui, | ||
500 | sk_UI_STRING_value(ui->strings, i))) | ||
501 | { | ||
502 | ok=-1; | ||
503 | goto err; | ||
504 | } | ||
505 | } | ||
506 | |||
507 | if (ui->meth->ui_flush) | ||
508 | switch(ui->meth->ui_flush(ui)) | ||
509 | { | ||
510 | case -1: /* Interrupt/Cancel/something... */ | ||
511 | ok = -2; | ||
512 | goto err; | ||
513 | case 0: /* Errors */ | ||
514 | ok = -1; | ||
515 | goto err; | ||
516 | default: /* Success */ | ||
517 | ok = 0; | ||
518 | break; | ||
519 | } | ||
520 | |||
521 | for(i=0; i<sk_UI_STRING_num(ui->strings); i++) | ||
522 | { | ||
523 | if (ui->meth->ui_read_string) | ||
524 | { | ||
525 | switch(ui->meth->ui_read_string(ui, | ||
526 | sk_UI_STRING_value(ui->strings, i))) | ||
527 | { | ||
528 | case -1: /* Interrupt/Cancel/something... */ | ||
529 | ok = -2; | ||
530 | goto err; | ||
531 | case 0: /* Errors */ | ||
532 | ok = -1; | ||
533 | goto err; | ||
534 | default: /* Success */ | ||
535 | ok = 0; | ||
536 | break; | ||
537 | } | ||
538 | } | ||
539 | } | ||
540 | err: | ||
541 | if (ui->meth->ui_close_session && !ui->meth->ui_close_session(ui)) | ||
542 | return -1; | ||
543 | return ok; | ||
544 | } | ||
545 | |||
546 | int UI_ctrl(UI *ui, int cmd, long i, void *p, void (*f)()) | ||
547 | { | ||
548 | if (ui == NULL) | ||
549 | { | ||
550 | UIerr(UI_F_UI_CTRL,ERR_R_PASSED_NULL_PARAMETER); | ||
551 | return -1; | ||
552 | } | ||
553 | switch(cmd) | ||
554 | { | ||
555 | case UI_CTRL_PRINT_ERRORS: | ||
556 | { | ||
557 | int save_flag = !!(ui->flags & UI_FLAG_PRINT_ERRORS); | ||
558 | if (i) | ||
559 | ui->flags |= UI_FLAG_PRINT_ERRORS; | ||
560 | else | ||
561 | ui->flags &= ~UI_FLAG_PRINT_ERRORS; | ||
562 | return save_flag; | ||
563 | } | ||
564 | case UI_CTRL_IS_REDOABLE: | ||
565 | return !!(ui->flags & UI_FLAG_REDOABLE); | ||
566 | default: | ||
567 | break; | ||
568 | } | ||
569 | UIerr(UI_F_UI_CTRL,UI_R_UNKNOWN_CONTROL_COMMAND); | ||
570 | return -1; | ||
571 | } | ||
572 | |||
573 | int UI_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, | ||
574 | CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func) | ||
575 | { | ||
576 | return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_UI, argl, argp, | ||
577 | new_func, dup_func, free_func); | ||
578 | } | ||
579 | |||
580 | int UI_set_ex_data(UI *r, int idx, void *arg) | ||
581 | { | ||
582 | return(CRYPTO_set_ex_data(&r->ex_data,idx,arg)); | ||
583 | } | ||
584 | |||
585 | void *UI_get_ex_data(UI *r, int idx) | ||
586 | { | ||
587 | return(CRYPTO_get_ex_data(&r->ex_data,idx)); | ||
588 | } | ||
589 | |||
590 | void UI_set_default_method(const UI_METHOD *meth) | ||
591 | { | ||
592 | default_UI_meth=meth; | ||
593 | } | ||
594 | |||
595 | const UI_METHOD *UI_get_default_method(void) | ||
596 | { | ||
597 | if (default_UI_meth == NULL) | ||
598 | { | ||
599 | default_UI_meth=UI_OpenSSL(); | ||
600 | } | ||
601 | return default_UI_meth; | ||
602 | } | ||
603 | |||
604 | const UI_METHOD *UI_get_method(UI *ui) | ||
605 | { | ||
606 | return ui->meth; | ||
607 | } | ||
608 | |||
609 | const UI_METHOD *UI_set_method(UI *ui, const UI_METHOD *meth) | ||
610 | { | ||
611 | ui->meth=meth; | ||
612 | return ui->meth; | ||
613 | } | ||
614 | |||
615 | |||
616 | UI_METHOD *UI_create_method(char *name) | ||
617 | { | ||
618 | UI_METHOD *ui_method = (UI_METHOD *)OPENSSL_malloc(sizeof(UI_METHOD)); | ||
619 | |||
620 | if (ui_method) | ||
621 | memset(ui_method, 0, sizeof(*ui_method)); | ||
622 | ui_method->name = BUF_strdup(name); | ||
623 | return ui_method; | ||
624 | } | ||
625 | |||
626 | /* BIG FSCKING WARNING!!!! If you use this on a statically allocated method | ||
627 | (that is, it hasn't been allocated using UI_create_method(), you deserve | ||
628 | anything Murphy can throw at you and more! You have been warned. */ | ||
629 | void UI_destroy_method(UI_METHOD *ui_method) | ||
630 | { | ||
631 | OPENSSL_free(ui_method->name); | ||
632 | ui_method->name = NULL; | ||
633 | OPENSSL_free(ui_method); | ||
634 | } | ||
635 | |||
636 | int UI_method_set_opener(UI_METHOD *method, int (*opener)(UI *ui)) | ||
637 | { | ||
638 | if (method) | ||
639 | { | ||
640 | method->ui_open_session = opener; | ||
641 | return 0; | ||
642 | } | ||
643 | else | ||
644 | return -1; | ||
645 | } | ||
646 | |||
647 | int UI_method_set_writer(UI_METHOD *method, int (*writer)(UI *ui, UI_STRING *uis)) | ||
648 | { | ||
649 | if (method) | ||
650 | { | ||
651 | method->ui_write_string = writer; | ||
652 | return 0; | ||
653 | } | ||
654 | else | ||
655 | return -1; | ||
656 | } | ||
657 | |||
658 | int UI_method_set_flusher(UI_METHOD *method, int (*flusher)(UI *ui)) | ||
659 | { | ||
660 | if (method) | ||
661 | { | ||
662 | method->ui_flush = flusher; | ||
663 | return 0; | ||
664 | } | ||
665 | else | ||
666 | return -1; | ||
667 | } | ||
668 | |||
669 | int UI_method_set_reader(UI_METHOD *method, int (*reader)(UI *ui, UI_STRING *uis)) | ||
670 | { | ||
671 | if (method) | ||
672 | { | ||
673 | method->ui_read_string = reader; | ||
674 | return 0; | ||
675 | } | ||
676 | else | ||
677 | return -1; | ||
678 | } | ||
679 | |||
680 | int UI_method_set_closer(UI_METHOD *method, int (*closer)(UI *ui)) | ||
681 | { | ||
682 | if (method) | ||
683 | { | ||
684 | method->ui_close_session = closer; | ||
685 | return 0; | ||
686 | } | ||
687 | else | ||
688 | return -1; | ||
689 | } | ||
690 | |||
691 | int (*UI_method_get_opener(UI_METHOD *method))(UI*) | ||
692 | { | ||
693 | if (method) | ||
694 | return method->ui_open_session; | ||
695 | else | ||
696 | return NULL; | ||
697 | } | ||
698 | |||
699 | int (*UI_method_get_writer(UI_METHOD *method))(UI*,UI_STRING*) | ||
700 | { | ||
701 | if (method) | ||
702 | return method->ui_write_string; | ||
703 | else | ||
704 | return NULL; | ||
705 | } | ||
706 | |||
707 | int (*UI_method_get_flusher(UI_METHOD *method))(UI*) | ||
708 | { | ||
709 | if (method) | ||
710 | return method->ui_flush; | ||
711 | else | ||
712 | return NULL; | ||
713 | } | ||
714 | |||
715 | int (*UI_method_get_reader(UI_METHOD *method))(UI*,UI_STRING*) | ||
716 | { | ||
717 | if (method) | ||
718 | return method->ui_read_string; | ||
719 | else | ||
720 | return NULL; | ||
721 | } | ||
722 | |||
723 | int (*UI_method_get_closer(UI_METHOD *method))(UI*) | ||
724 | { | ||
725 | if (method) | ||
726 | return method->ui_close_session; | ||
727 | else | ||
728 | return NULL; | ||
729 | } | ||
730 | |||
731 | enum UI_string_types UI_get_string_type(UI_STRING *uis) | ||
732 | { | ||
733 | if (!uis) | ||
734 | return UIT_NONE; | ||
735 | return uis->type; | ||
736 | } | ||
737 | |||
738 | int UI_get_input_flags(UI_STRING *uis) | ||
739 | { | ||
740 | if (!uis) | ||
741 | return 0; | ||
742 | return uis->input_flags; | ||
743 | } | ||
744 | |||
745 | const char *UI_get0_output_string(UI_STRING *uis) | ||
746 | { | ||
747 | if (!uis) | ||
748 | return NULL; | ||
749 | return uis->out_string; | ||
750 | } | ||
751 | |||
752 | const char *UI_get0_action_string(UI_STRING *uis) | ||
753 | { | ||
754 | if (!uis) | ||
755 | return NULL; | ||
756 | switch(uis->type) | ||
757 | { | ||
758 | case UIT_PROMPT: | ||
759 | case UIT_BOOLEAN: | ||
760 | return uis->_.boolean_data.action_desc; | ||
761 | default: | ||
762 | return NULL; | ||
763 | } | ||
764 | } | ||
765 | |||
766 | const char *UI_get0_result_string(UI_STRING *uis) | ||
767 | { | ||
768 | if (!uis) | ||
769 | return NULL; | ||
770 | switch(uis->type) | ||
771 | { | ||
772 | case UIT_PROMPT: | ||
773 | case UIT_VERIFY: | ||
774 | return uis->result_buf; | ||
775 | default: | ||
776 | return NULL; | ||
777 | } | ||
778 | } | ||
779 | |||
780 | const char *UI_get0_test_string(UI_STRING *uis) | ||
781 | { | ||
782 | if (!uis) | ||
783 | return NULL; | ||
784 | switch(uis->type) | ||
785 | { | ||
786 | case UIT_VERIFY: | ||
787 | return uis->_.string_data.test_buf; | ||
788 | default: | ||
789 | return NULL; | ||
790 | } | ||
791 | } | ||
792 | |||
793 | int UI_get_result_minsize(UI_STRING *uis) | ||
794 | { | ||
795 | if (!uis) | ||
796 | return -1; | ||
797 | switch(uis->type) | ||
798 | { | ||
799 | case UIT_PROMPT: | ||
800 | case UIT_VERIFY: | ||
801 | return uis->_.string_data.result_minsize; | ||
802 | default: | ||
803 | return -1; | ||
804 | } | ||
805 | } | ||
806 | |||
807 | int UI_get_result_maxsize(UI_STRING *uis) | ||
808 | { | ||
809 | if (!uis) | ||
810 | return -1; | ||
811 | switch(uis->type) | ||
812 | { | ||
813 | case UIT_PROMPT: | ||
814 | case UIT_VERIFY: | ||
815 | return uis->_.string_data.result_maxsize; | ||
816 | default: | ||
817 | return -1; | ||
818 | } | ||
819 | } | ||
820 | |||
821 | int UI_set_result(UI *ui, UI_STRING *uis, const char *result) | ||
822 | { | ||
823 | int l = strlen(result); | ||
824 | |||
825 | ui->flags &= ~UI_FLAG_REDOABLE; | ||
826 | |||
827 | if (!uis) | ||
828 | return -1; | ||
829 | switch (uis->type) | ||
830 | { | ||
831 | case UIT_PROMPT: | ||
832 | case UIT_VERIFY: | ||
833 | { | ||
834 | char number1[20]; | ||
835 | char number2[20]; | ||
836 | |||
837 | BIO_snprintf(number1, sizeof(number1), "%d", | ||
838 | uis->_.string_data.result_minsize); | ||
839 | BIO_snprintf(number2, sizeof(number2), "%d", | ||
840 | uis->_.string_data.result_maxsize); | ||
841 | |||
842 | if (l < uis->_.string_data.result_minsize) | ||
843 | { | ||
844 | ui->flags |= UI_FLAG_REDOABLE; | ||
845 | UIerr(UI_F_UI_SET_RESULT,UI_R_RESULT_TOO_SMALL); | ||
846 | ERR_add_error_data(5,"You must type in ", | ||
847 | number1," to ",number2," characters"); | ||
848 | return -1; | ||
849 | } | ||
850 | if (l > uis->_.string_data.result_maxsize) | ||
851 | { | ||
852 | ui->flags |= UI_FLAG_REDOABLE; | ||
853 | UIerr(UI_F_UI_SET_RESULT,UI_R_RESULT_TOO_LARGE); | ||
854 | ERR_add_error_data(5,"You must type in ", | ||
855 | number1," to ",number2," characters"); | ||
856 | return -1; | ||
857 | } | ||
858 | } | ||
859 | |||
860 | if (!uis->result_buf) | ||
861 | { | ||
862 | UIerr(UI_F_UI_SET_RESULT,UI_R_NO_RESULT_BUFFER); | ||
863 | return -1; | ||
864 | } | ||
865 | |||
866 | strcpy(uis->result_buf, result); | ||
867 | break; | ||
868 | case UIT_BOOLEAN: | ||
869 | { | ||
870 | const char *p; | ||
871 | |||
872 | if (!uis->result_buf) | ||
873 | { | ||
874 | UIerr(UI_F_UI_SET_RESULT,UI_R_NO_RESULT_BUFFER); | ||
875 | return -1; | ||
876 | } | ||
877 | |||
878 | uis->result_buf[0] = '\0'; | ||
879 | for(p = result; *p; p++) | ||
880 | { | ||
881 | if (strchr(uis->_.boolean_data.ok_chars, *p)) | ||
882 | { | ||
883 | uis->result_buf[0] = | ||
884 | uis->_.boolean_data.ok_chars[0]; | ||
885 | break; | ||
886 | } | ||
887 | if (strchr(uis->_.boolean_data.cancel_chars, *p)) | ||
888 | { | ||
889 | uis->result_buf[0] = | ||
890 | uis->_.boolean_data.cancel_chars[0]; | ||
891 | break; | ||
892 | } | ||
893 | } | ||
894 | default: | ||
895 | break; | ||
896 | } | ||
897 | } | ||
898 | return 0; | ||
899 | } | ||
diff --git a/src/lib/libcrypto/ui/ui_locl.h b/src/lib/libcrypto/ui/ui_locl.h new file mode 100644 index 0000000000..7d3a75a619 --- /dev/null +++ b/src/lib/libcrypto/ui/ui_locl.h | |||
@@ -0,0 +1,148 @@ | |||
1 | /* crypto/ui/ui.h -*- mode:C; c-file-style: "eay" -*- */ | ||
2 | /* Written by Richard Levitte (richard@levitte.org) for the OpenSSL | ||
3 | * project 2001. | ||
4 | */ | ||
5 | /* ==================================================================== | ||
6 | * Copyright (c) 2001 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 | #ifndef HEADER_UI_LOCL_H | ||
60 | #define HEADER_UI_LOCL_H | ||
61 | |||
62 | #include <openssl/ui.h> | ||
63 | |||
64 | struct ui_method_st | ||
65 | { | ||
66 | char *name; | ||
67 | |||
68 | /* All the functions return 1 or non-NULL for success and 0 or NULL | ||
69 | for failure */ | ||
70 | |||
71 | /* Open whatever channel for this, be it the console, an X window | ||
72 | or whatever. | ||
73 | This function should use the ex_data structure to save | ||
74 | intermediate data. */ | ||
75 | int (*ui_open_session)(UI *ui); | ||
76 | |||
77 | int (*ui_write_string)(UI *ui, UI_STRING *uis); | ||
78 | |||
79 | /* Flush the output. If a GUI dialog box is used, this function can | ||
80 | be used to actually display it. */ | ||
81 | int (*ui_flush)(UI *ui); | ||
82 | |||
83 | int (*ui_read_string)(UI *ui, UI_STRING *uis); | ||
84 | |||
85 | int (*ui_close_session)(UI *ui); | ||
86 | |||
87 | /* Construct a prompt in a user-defined manner. object_desc is a | ||
88 | textual short description of the object, for example "pass phrase", | ||
89 | and object_name is the name of the object (might be a card name or | ||
90 | a file name. | ||
91 | The returned string shall always be allocated on the heap with | ||
92 | OPENSSL_malloc(), and need to be free'd with OPENSSL_free(). */ | ||
93 | char *(*ui_construct_prompt)(UI *ui, const char *object_desc, | ||
94 | const char *object_name); | ||
95 | }; | ||
96 | |||
97 | struct ui_string_st | ||
98 | { | ||
99 | enum UI_string_types type; /* Input */ | ||
100 | const char *out_string; /* Input */ | ||
101 | int input_flags; /* Flags from the user */ | ||
102 | |||
103 | /* The following parameters are completely irrelevant for UIT_INFO, | ||
104 | and can therefore be set to 0 or NULL */ | ||
105 | char *result_buf; /* Input and Output: If not NULL, user-defined | ||
106 | with size in result_maxsize. Otherwise, it | ||
107 | may be allocated by the UI routine, meaning | ||
108 | result_minsize is going to be overwritten.*/ | ||
109 | union | ||
110 | { | ||
111 | struct | ||
112 | { | ||
113 | int result_minsize; /* Input: minimum required | ||
114 | size of the result. | ||
115 | */ | ||
116 | int result_maxsize; /* Input: maximum permitted | ||
117 | size of the result */ | ||
118 | |||
119 | const char *test_buf; /* Input: test string to verify | ||
120 | against */ | ||
121 | } string_data; | ||
122 | struct | ||
123 | { | ||
124 | const char *action_desc; /* Input */ | ||
125 | const char *ok_chars; /* Input */ | ||
126 | const char *cancel_chars; /* Input */ | ||
127 | } boolean_data; | ||
128 | } _; | ||
129 | |||
130 | #define OUT_STRING_FREEABLE 0x01 | ||
131 | int flags; /* flags for internal use */ | ||
132 | }; | ||
133 | |||
134 | struct ui_st | ||
135 | { | ||
136 | const UI_METHOD *meth; | ||
137 | STACK_OF(UI_STRING) *strings; /* We might want to prompt for more | ||
138 | than one thing at a time, and | ||
139 | with different echoing status. */ | ||
140 | void *user_data; | ||
141 | CRYPTO_EX_DATA ex_data; | ||
142 | |||
143 | #define UI_FLAG_REDOABLE 0x0001 | ||
144 | #define UI_FLAG_PRINT_ERRORS 0x0100 | ||
145 | int flags; | ||
146 | }; | ||
147 | |||
148 | #endif | ||
diff --git a/src/lib/libcrypto/ui/ui_openssl.c b/src/lib/libcrypto/ui/ui_openssl.c new file mode 100644 index 0000000000..3aa03f74aa --- /dev/null +++ b/src/lib/libcrypto/ui/ui_openssl.c | |||
@@ -0,0 +1,661 @@ | |||
1 | /* crypto/ui/ui_openssl.c -*- mode:C; c-file-style: "eay" -*- */ | ||
2 | /* Written by Richard Levitte (richard@levitte.org) and others | ||
3 | * for the OpenSSL project 2001. | ||
4 | */ | ||
5 | /* ==================================================================== | ||
6 | * Copyright (c) 2001 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 | /* The lowest level part of this file was previously in crypto/des/read_pwd.c, | ||
60 | * Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) | ||
61 | * All rights reserved. | ||
62 | * | ||
63 | * This package is an SSL implementation written | ||
64 | * by Eric Young (eay@cryptsoft.com). | ||
65 | * The implementation was written so as to conform with Netscapes SSL. | ||
66 | * | ||
67 | * This library is free for commercial and non-commercial use as long as | ||
68 | * the following conditions are aheared to. The following conditions | ||
69 | * apply to all code found in this distribution, be it the RC4, RSA, | ||
70 | * lhash, DES, etc., code; not just the SSL code. The SSL documentation | ||
71 | * included with this distribution is covered by the same copyright terms | ||
72 | * except that the holder is Tim Hudson (tjh@cryptsoft.com). | ||
73 | * | ||
74 | * Copyright remains Eric Young's, and as such any Copyright notices in | ||
75 | * the code are not to be removed. | ||
76 | * If this package is used in a product, Eric Young should be given attribution | ||
77 | * as the author of the parts of the library used. | ||
78 | * This can be in the form of a textual message at program startup or | ||
79 | * in documentation (online or textual) provided with the package. | ||
80 | * | ||
81 | * Redistribution and use in source and binary forms, with or without | ||
82 | * modification, are permitted provided that the following conditions | ||
83 | * are met: | ||
84 | * 1. Redistributions of source code must retain the copyright | ||
85 | * notice, this list of conditions and the following disclaimer. | ||
86 | * 2. Redistributions in binary form must reproduce the above copyright | ||
87 | * notice, this list of conditions and the following disclaimer in the | ||
88 | * documentation and/or other materials provided with the distribution. | ||
89 | * 3. All advertising materials mentioning features or use of this software | ||
90 | * must display the following acknowledgement: | ||
91 | * "This product includes cryptographic software written by | ||
92 | * Eric Young (eay@cryptsoft.com)" | ||
93 | * The word 'cryptographic' can be left out if the rouines from the library | ||
94 | * being used are not cryptographic related :-). | ||
95 | * 4. If you include any Windows specific code (or a derivative thereof) from | ||
96 | * the apps directory (application code) you must include an acknowledgement: | ||
97 | * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" | ||
98 | * | ||
99 | * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND | ||
100 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
101 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
102 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | ||
103 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
104 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
105 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
106 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
107 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
108 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
109 | * SUCH DAMAGE. | ||
110 | * | ||
111 | * The licence and distribution terms for any publically available version or | ||
112 | * derivative of this code cannot be changed. i.e. this code cannot simply be | ||
113 | * copied and put under another distribution licence | ||
114 | * [including the GNU Public Licence.] | ||
115 | */ | ||
116 | |||
117 | |||
118 | #include <openssl/e_os2.h> | ||
119 | |||
120 | #if !defined(OPENSSL_SYS_MSDOS) && !defined(OPENSSL_SYS_VMS) | ||
121 | # ifdef OPENSSL_UNISTD | ||
122 | # include OPENSSL_UNISTD | ||
123 | # else | ||
124 | # include <unistd.h> | ||
125 | # endif | ||
126 | /* If unistd.h defines _POSIX_VERSION, we conclude that we | ||
127 | * are on a POSIX system and have sigaction and termios. */ | ||
128 | # if defined(_POSIX_VERSION) | ||
129 | |||
130 | # define SIGACTION | ||
131 | # if !defined(TERMIOS) && !defined(TERMIO) && !defined(SGTTY) | ||
132 | # define TERMIOS | ||
133 | # endif | ||
134 | |||
135 | # endif | ||
136 | #endif | ||
137 | |||
138 | #ifdef WIN16TTY | ||
139 | # undef OPENSSL_SYS_WIN16 | ||
140 | # undef WIN16 | ||
141 | # undef _WINDOWS | ||
142 | # include <graph.h> | ||
143 | #endif | ||
144 | |||
145 | /* 06-Apr-92 Luke Brennan Support for VMS */ | ||
146 | #include "ui_locl.h" | ||
147 | #include "cryptlib.h" | ||
148 | #include <signal.h> | ||
149 | #include <stdio.h> | ||
150 | #include <string.h> | ||
151 | #include <errno.h> | ||
152 | |||
153 | #ifdef OPENSSL_SYS_VMS /* prototypes for sys$whatever */ | ||
154 | # include <starlet.h> | ||
155 | # ifdef __DECC | ||
156 | # pragma message disable DOLLARID | ||
157 | # endif | ||
158 | #endif | ||
159 | |||
160 | #ifdef WIN_CONSOLE_BUG | ||
161 | # include <windows.h> | ||
162 | # include <wincon.h> | ||
163 | #endif | ||
164 | |||
165 | |||
166 | /* There are 5 types of terminal interface supported, | ||
167 | * TERMIO, TERMIOS, VMS, MSDOS and SGTTY | ||
168 | */ | ||
169 | |||
170 | #if defined(__sgi) && !defined(TERMIOS) | ||
171 | # define TERMIOS | ||
172 | # undef TERMIO | ||
173 | # undef SGTTY | ||
174 | #endif | ||
175 | |||
176 | #if defined(linux) && !defined(TERMIO) | ||
177 | # undef TERMIOS | ||
178 | # define TERMIO | ||
179 | # undef SGTTY | ||
180 | #endif | ||
181 | |||
182 | #ifdef _LIBC | ||
183 | # undef TERMIOS | ||
184 | # define TERMIO | ||
185 | # undef SGTTY | ||
186 | #endif | ||
187 | |||
188 | #if !defined(TERMIO) && !defined(TERMIOS) && !defined(OPENSSL_SYS_VMS) && !defined(OPENSSL_SYS_MSDOS) && !defined(OPENSSL_SYS_MACINTOSH_CLASSIC) && !defined(MAC_OS_GUSI_SOURCE) | ||
189 | # undef TERMIOS | ||
190 | # undef TERMIO | ||
191 | # define SGTTY | ||
192 | #endif | ||
193 | |||
194 | #if defined(OPENSSL_SYS_VSWORKS) | ||
195 | #undef TERMIOS | ||
196 | #undef TERMIO | ||
197 | #undef SGTTY | ||
198 | #endif | ||
199 | |||
200 | #ifdef TERMIOS | ||
201 | # include <termios.h> | ||
202 | # define TTY_STRUCT struct termios | ||
203 | # define TTY_FLAGS c_lflag | ||
204 | # define TTY_get(tty,data) tcgetattr(tty,data) | ||
205 | # define TTY_set(tty,data) tcsetattr(tty,TCSANOW,data) | ||
206 | #endif | ||
207 | |||
208 | #ifdef TERMIO | ||
209 | # include <termio.h> | ||
210 | # define TTY_STRUCT struct termio | ||
211 | # define TTY_FLAGS c_lflag | ||
212 | # define TTY_get(tty,data) ioctl(tty,TCGETA,data) | ||
213 | # define TTY_set(tty,data) ioctl(tty,TCSETA,data) | ||
214 | #endif | ||
215 | |||
216 | #ifdef SGTTY | ||
217 | # include <sgtty.h> | ||
218 | # define TTY_STRUCT struct sgttyb | ||
219 | # define TTY_FLAGS sg_flags | ||
220 | # define TTY_get(tty,data) ioctl(tty,TIOCGETP,data) | ||
221 | # define TTY_set(tty,data) ioctl(tty,TIOCSETP,data) | ||
222 | #endif | ||
223 | |||
224 | #if !defined(_LIBC) && !defined(OPENSSL_SYS_MSDOS) && !defined(OPENSSL_SYS_VMS) && !defined(OPENSSL_SYS_MACINTOSH_CLASSIC) | ||
225 | # include <sys/ioctl.h> | ||
226 | #endif | ||
227 | |||
228 | #ifdef OPENSSL_SYS_MSDOS | ||
229 | # include <conio.h> | ||
230 | #endif | ||
231 | |||
232 | #ifdef OPENSSL_SYS_VMS | ||
233 | # include <ssdef.h> | ||
234 | # include <iodef.h> | ||
235 | # include <ttdef.h> | ||
236 | # include <descrip.h> | ||
237 | struct IOSB { | ||
238 | short iosb$w_value; | ||
239 | short iosb$w_count; | ||
240 | long iosb$l_info; | ||
241 | }; | ||
242 | #endif | ||
243 | |||
244 | #if defined(OPENSSL_SYS_MACINTOSH_CLASSIC) || defined(MAC_OS_GUSI_SOURCE) | ||
245 | /* | ||
246 | * This one needs work. As a matter of fact the code is unoperational | ||
247 | * and this is only a trick to get it compiled. | ||
248 | * <appro@fy.chalmers.se> | ||
249 | */ | ||
250 | # define TTY_STRUCT int | ||
251 | #endif | ||
252 | |||
253 | #ifndef NX509_SIG | ||
254 | # define NX509_SIG 32 | ||
255 | #endif | ||
256 | |||
257 | |||
258 | /* Define globals. They are protected by a lock */ | ||
259 | #ifdef SIGACTION | ||
260 | static struct sigaction savsig[NX509_SIG]; | ||
261 | #else | ||
262 | static void (*savsig[NX509_SIG])(int ); | ||
263 | #endif | ||
264 | |||
265 | #ifdef OPENSSL_SYS_VMS | ||
266 | static struct IOSB iosb; | ||
267 | static $DESCRIPTOR(terminal,"TT"); | ||
268 | static long tty_orig[3], tty_new[3]; /* XXX Is there any guarantee that this will always suffice for the actual structures? */ | ||
269 | static long status; | ||
270 | static unsigned short channel = 0; | ||
271 | #else | ||
272 | #ifndef OPENSSL_SYS_MSDOS | ||
273 | static TTY_STRUCT tty_orig,tty_new; | ||
274 | #endif | ||
275 | #endif | ||
276 | static FILE *tty_in, *tty_out; | ||
277 | static int is_a_tty; | ||
278 | |||
279 | /* Declare static functions */ | ||
280 | static void read_till_nl(FILE *); | ||
281 | static void recsig(int); | ||
282 | static void pushsig(void); | ||
283 | static void popsig(void); | ||
284 | #if defined(OPENSSL_SYS_MSDOS) && !defined(OPENSSL_SYS_WIN16) | ||
285 | static int noecho_fgets(char *buf, int size, FILE *tty); | ||
286 | #endif | ||
287 | static int read_string_inner(UI *ui, UI_STRING *uis, int echo, int strip_nl); | ||
288 | |||
289 | static int read_string(UI *ui, UI_STRING *uis); | ||
290 | static int write_string(UI *ui, UI_STRING *uis); | ||
291 | |||
292 | static int open_console(UI *ui); | ||
293 | static int echo_console(UI *ui); | ||
294 | static int noecho_console(UI *ui); | ||
295 | static int close_console(UI *ui); | ||
296 | |||
297 | static UI_METHOD ui_openssl = | ||
298 | { | ||
299 | "OpenSSL default user interface", | ||
300 | open_console, | ||
301 | write_string, | ||
302 | NULL, /* No flusher is needed for command lines */ | ||
303 | read_string, | ||
304 | close_console, | ||
305 | NULL | ||
306 | }; | ||
307 | |||
308 | /* The method with all the built-in thingies */ | ||
309 | UI_METHOD *UI_OpenSSL(void) | ||
310 | { | ||
311 | return &ui_openssl; | ||
312 | } | ||
313 | |||
314 | /* The following function makes sure that info and error strings are printed | ||
315 | before any prompt. */ | ||
316 | static int write_string(UI *ui, UI_STRING *uis) | ||
317 | { | ||
318 | switch (UI_get_string_type(uis)) | ||
319 | { | ||
320 | case UIT_ERROR: | ||
321 | case UIT_INFO: | ||
322 | fputs(UI_get0_output_string(uis), tty_out); | ||
323 | fflush(tty_out); | ||
324 | break; | ||
325 | default: | ||
326 | break; | ||
327 | } | ||
328 | return 1; | ||
329 | } | ||
330 | |||
331 | static int read_string(UI *ui, UI_STRING *uis) | ||
332 | { | ||
333 | int ok = 0; | ||
334 | |||
335 | switch (UI_get_string_type(uis)) | ||
336 | { | ||
337 | case UIT_BOOLEAN: | ||
338 | fputs(UI_get0_output_string(uis), tty_out); | ||
339 | fputs(UI_get0_action_string(uis), tty_out); | ||
340 | fflush(tty_out); | ||
341 | return read_string_inner(ui, uis, | ||
342 | UI_get_input_flags(uis) & UI_INPUT_FLAG_ECHO, 0); | ||
343 | case UIT_PROMPT: | ||
344 | fputs(UI_get0_output_string(uis), tty_out); | ||
345 | fflush(tty_out); | ||
346 | return read_string_inner(ui, uis, | ||
347 | UI_get_input_flags(uis) & UI_INPUT_FLAG_ECHO, 1); | ||
348 | case UIT_VERIFY: | ||
349 | fprintf(tty_out,"Verifying - %s", | ||
350 | UI_get0_output_string(uis)); | ||
351 | fflush(tty_out); | ||
352 | if ((ok = read_string_inner(ui, uis, | ||
353 | UI_get_input_flags(uis) & UI_INPUT_FLAG_ECHO, 1)) <= 0) | ||
354 | return ok; | ||
355 | if (strcmp(UI_get0_result_string(uis), | ||
356 | UI_get0_test_string(uis)) != 0) | ||
357 | { | ||
358 | fprintf(tty_out,"Verify failure\n"); | ||
359 | fflush(tty_out); | ||
360 | return 0; | ||
361 | } | ||
362 | break; | ||
363 | default: | ||
364 | break; | ||
365 | } | ||
366 | return 1; | ||
367 | } | ||
368 | |||
369 | |||
370 | /* Internal functions to read a string without echoing */ | ||
371 | static void read_till_nl(FILE *in) | ||
372 | { | ||
373 | #define SIZE 4 | ||
374 | char buf[SIZE+1]; | ||
375 | |||
376 | do { | ||
377 | fgets(buf,SIZE,in); | ||
378 | } while (strchr(buf,'\n') == NULL); | ||
379 | } | ||
380 | |||
381 | static sig_atomic_t intr_signal; | ||
382 | |||
383 | static int read_string_inner(UI *ui, UI_STRING *uis, int echo, int strip_nl) | ||
384 | { | ||
385 | static int ps; | ||
386 | int ok; | ||
387 | char result[BUFSIZ]; | ||
388 | int maxsize = BUFSIZ-1; | ||
389 | char *p; | ||
390 | |||
391 | #ifndef OPENSSL_SYS_WIN16 | ||
392 | intr_signal=0; | ||
393 | ok=0; | ||
394 | ps=0; | ||
395 | |||
396 | pushsig(); | ||
397 | ps=1; | ||
398 | |||
399 | if (!echo && !noecho_console(ui)) | ||
400 | goto error; | ||
401 | ps=2; | ||
402 | |||
403 | result[0]='\0'; | ||
404 | #ifdef OPENSSL_SYS_MSDOS | ||
405 | if (!echo) | ||
406 | { | ||
407 | noecho_fgets(result,maxsize,tty_in); | ||
408 | p=result; /* FIXME: noecho_fgets doesn't return errors */ | ||
409 | } | ||
410 | else | ||
411 | p=fgets(result,maxsize,tty_in); | ||
412 | #else | ||
413 | p=fgets(result,maxsize,tty_in); | ||
414 | #endif | ||
415 | if(!p) | ||
416 | goto error; | ||
417 | if (feof(tty_in)) goto error; | ||
418 | if (ferror(tty_in)) goto error; | ||
419 | if ((p=(char *)strchr(result,'\n')) != NULL) | ||
420 | { | ||
421 | if (strip_nl) | ||
422 | *p='\0'; | ||
423 | } | ||
424 | else | ||
425 | read_till_nl(tty_in); | ||
426 | if (UI_set_result(ui, uis, result) >= 0) | ||
427 | ok=1; | ||
428 | |||
429 | error: | ||
430 | if (intr_signal == SIGINT) | ||
431 | ok=-1; | ||
432 | if (!echo) fprintf(tty_out,"\n"); | ||
433 | if (ps >= 2 && !echo && !echo_console(ui)) | ||
434 | ok=0; | ||
435 | |||
436 | if (ps >= 1) | ||
437 | popsig(); | ||
438 | #else | ||
439 | ok=1; | ||
440 | #endif | ||
441 | |||
442 | memset(result,0,BUFSIZ); | ||
443 | return ok; | ||
444 | } | ||
445 | |||
446 | |||
447 | /* Internal functions to open, handle and close a channel to the console. */ | ||
448 | static int open_console(UI *ui) | ||
449 | { | ||
450 | CRYPTO_w_lock(CRYPTO_LOCK_UI); | ||
451 | is_a_tty = 1; | ||
452 | |||
453 | #if defined(OPENSSL_SYS_MACINTOSH_CLASSIC) || defined(OPENSSL_SYS_VSWORKS) | ||
454 | tty_in=stdin; | ||
455 | tty_out=stderr; | ||
456 | #else | ||
457 | # ifdef OPENSSL_SYS_MSDOS | ||
458 | # define DEV_TTY "con" | ||
459 | # else | ||
460 | # define DEV_TTY "/dev/tty" | ||
461 | # endif | ||
462 | if ((tty_in=fopen(DEV_TTY,"r")) == NULL) | ||
463 | tty_in=stdin; | ||
464 | if ((tty_out=fopen(DEV_TTY,"w")) == NULL) | ||
465 | tty_out=stderr; | ||
466 | #endif | ||
467 | |||
468 | #if defined(TTY_get) && !defined(VMS) | ||
469 | if (TTY_get(fileno(tty_in),&tty_orig) == -1) | ||
470 | { | ||
471 | #ifdef ENOTTY | ||
472 | if (errno == ENOTTY) | ||
473 | is_a_tty=0; | ||
474 | else | ||
475 | #endif | ||
476 | #ifdef EINVAL | ||
477 | /* Ariel Glenn ariel@columbia.edu reports that solaris | ||
478 | * can return EINVAL instead. This should be ok */ | ||
479 | if (errno == EINVAL) | ||
480 | is_a_tty=0; | ||
481 | else | ||
482 | #endif | ||
483 | return 0; | ||
484 | } | ||
485 | #endif | ||
486 | #ifdef OPENSSL_SYS_VMS | ||
487 | status = sys$assign(&terminal,&channel,0,0); | ||
488 | if (status != SS$_NORMAL) | ||
489 | return 0; | ||
490 | status=sys$qiow(0,channel,IO$_SENSEMODE,&iosb,0,0,tty_orig,12,0,0,0,0); | ||
491 | if ((status != SS$_NORMAL) || (iosb.iosb$w_value != SS$_NORMAL)) | ||
492 | return 0; | ||
493 | #endif | ||
494 | return 1; | ||
495 | } | ||
496 | |||
497 | static int noecho_console(UI *ui) | ||
498 | { | ||
499 | #ifdef TTY_FLAGS | ||
500 | memcpy(&(tty_new),&(tty_orig),sizeof(tty_orig)); | ||
501 | tty_new.TTY_FLAGS &= ~ECHO; | ||
502 | #endif | ||
503 | |||
504 | #if defined(TTY_set) && !defined(OPENSSL_SYS_VMS) | ||
505 | if (is_a_tty && (TTY_set(fileno(tty_in),&tty_new) == -1)) | ||
506 | return 0; | ||
507 | #endif | ||
508 | #ifdef OPENSSL_SYS_VMS | ||
509 | tty_new[0] = tty_orig[0]; | ||
510 | tty_new[1] = tty_orig[1] | TT$M_NOECHO; | ||
511 | tty_new[2] = tty_orig[2]; | ||
512 | status = sys$qiow(0,channel,IO$_SETMODE,&iosb,0,0,tty_new,12,0,0,0,0); | ||
513 | if ((status != SS$_NORMAL) || (iosb.iosb$w_value != SS$_NORMAL)) | ||
514 | return 0; | ||
515 | #endif | ||
516 | return 1; | ||
517 | } | ||
518 | |||
519 | static int echo_console(UI *ui) | ||
520 | { | ||
521 | #if defined(TTY_set) && !defined(OPENSSL_SYS_VMS) | ||
522 | memcpy(&(tty_new),&(tty_orig),sizeof(tty_orig)); | ||
523 | tty_new.TTY_FLAGS |= ECHO; | ||
524 | #endif | ||
525 | |||
526 | #if defined(TTY_set) && !defined(OPENSSL_SYS_VMS) | ||
527 | if (is_a_tty && (TTY_set(fileno(tty_in),&tty_new) == -1)) | ||
528 | return 0; | ||
529 | #endif | ||
530 | #ifdef OPENSSL_SYS_VMS | ||
531 | tty_new[0] = tty_orig[0]; | ||
532 | tty_new[1] = tty_orig[1] & ~TT$M_NOECHO; | ||
533 | tty_new[2] = tty_orig[2]; | ||
534 | status = sys$qiow(0,channel,IO$_SETMODE,&iosb,0,0,tty_new,12,0,0,0,0); | ||
535 | if ((status != SS$_NORMAL) || (iosb.iosb$w_value != SS$_NORMAL)) | ||
536 | return 0; | ||
537 | #endif | ||
538 | return 1; | ||
539 | } | ||
540 | |||
541 | static int close_console(UI *ui) | ||
542 | { | ||
543 | if (tty_in != stderr) fclose(tty_in); | ||
544 | if (tty_out != stderr) fclose(tty_out); | ||
545 | #ifdef OPENSSL_SYS_VMS | ||
546 | status = sys$dassgn(channel); | ||
547 | #endif | ||
548 | CRYPTO_w_unlock(CRYPTO_LOCK_UI); | ||
549 | |||
550 | return 1; | ||
551 | } | ||
552 | |||
553 | |||
554 | /* Internal functions to handle signals and act on them */ | ||
555 | static void pushsig(void) | ||
556 | { | ||
557 | int i; | ||
558 | #ifdef SIGACTION | ||
559 | struct sigaction sa; | ||
560 | |||
561 | memset(&sa,0,sizeof sa); | ||
562 | sa.sa_handler=recsig; | ||
563 | #endif | ||
564 | |||
565 | for (i=1; i<NX509_SIG; i++) | ||
566 | { | ||
567 | #ifdef SIGUSR1 | ||
568 | if (i == SIGUSR1) | ||
569 | continue; | ||
570 | #endif | ||
571 | #ifdef SIGUSR2 | ||
572 | if (i == SIGUSR2) | ||
573 | continue; | ||
574 | #endif | ||
575 | #ifdef SIGKILL | ||
576 | if (i == SIGKILL) /* We can't make any action on that. */ | ||
577 | continue; | ||
578 | #endif | ||
579 | #ifdef SIGACTION | ||
580 | sigaction(i,&sa,&savsig[i]); | ||
581 | #else | ||
582 | savsig[i]=signal(i,recsig); | ||
583 | #endif | ||
584 | } | ||
585 | |||
586 | #ifdef SIGWINCH | ||
587 | signal(SIGWINCH,SIG_DFL); | ||
588 | #endif | ||
589 | } | ||
590 | |||
591 | static void popsig(void) | ||
592 | { | ||
593 | int i; | ||
594 | |||
595 | for (i=1; i<NX509_SIG; i++) | ||
596 | { | ||
597 | #ifdef SIGUSR1 | ||
598 | if (i == SIGUSR1) | ||
599 | continue; | ||
600 | #endif | ||
601 | #ifdef SIGUSR2 | ||
602 | if (i == SIGUSR2) | ||
603 | continue; | ||
604 | #endif | ||
605 | #ifdef SIGACTION | ||
606 | sigaction(i,&savsig[i],NULL); | ||
607 | #else | ||
608 | signal(i,savsig[i]); | ||
609 | #endif | ||
610 | } | ||
611 | } | ||
612 | |||
613 | static void recsig(int i) | ||
614 | { | ||
615 | intr_signal=i; | ||
616 | } | ||
617 | |||
618 | /* Internal functions specific for Windows */ | ||
619 | #if defined(OPENSSL_SYS_MSDOS) && !defined(OPENSSL_SYS_WIN16) | ||
620 | static int noecho_fgets(char *buf, int size, FILE *tty) | ||
621 | { | ||
622 | int i; | ||
623 | char *p; | ||
624 | |||
625 | p=buf; | ||
626 | for (;;) | ||
627 | { | ||
628 | if (size == 0) | ||
629 | { | ||
630 | *p='\0'; | ||
631 | break; | ||
632 | } | ||
633 | size--; | ||
634 | #ifdef WIN16TTY | ||
635 | i=_inchar(); | ||
636 | #else | ||
637 | i=getch(); | ||
638 | #endif | ||
639 | if (i == '\r') i='\n'; | ||
640 | *(p++)=i; | ||
641 | if (i == '\n') | ||
642 | { | ||
643 | *p='\0'; | ||
644 | break; | ||
645 | } | ||
646 | } | ||
647 | #ifdef WIN_CONSOLE_BUG | ||
648 | /* Win95 has several evil console bugs: one of these is that the | ||
649 | * last character read using getch() is passed to the next read: this is | ||
650 | * usually a CR so this can be trouble. No STDIO fix seems to work but | ||
651 | * flushing the console appears to do the trick. | ||
652 | */ | ||
653 | { | ||
654 | HANDLE inh; | ||
655 | inh = GetStdHandle(STD_INPUT_HANDLE); | ||
656 | FlushConsoleInputBuffer(inh); | ||
657 | } | ||
658 | #endif | ||
659 | return(strlen(buf)); | ||
660 | } | ||
661 | #endif | ||
diff --git a/src/lib/libcrypto/ui/ui_util.c b/src/lib/libcrypto/ui/ui_util.c new file mode 100644 index 0000000000..7c6f7d3a73 --- /dev/null +++ b/src/lib/libcrypto/ui/ui_util.c | |||
@@ -0,0 +1,86 @@ | |||
1 | /* crypto/ui/ui_util.c -*- mode:C; c-file-style: "eay" -*- */ | ||
2 | /* ==================================================================== | ||
3 | * Copyright (c) 2001-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 <string.h> | ||
57 | #include <openssl/ui.h> | ||
58 | |||
59 | int UI_UTIL_read_pw_string(char *buf,int length,const char *prompt,int verify) | ||
60 | { | ||
61 | char buff[BUFSIZ]; | ||
62 | int ret; | ||
63 | |||
64 | ret=UI_UTIL_read_pw(buf,buff,(length>BUFSIZ)?BUFSIZ:length,prompt,verify); | ||
65 | memset(buff,0,BUFSIZ); | ||
66 | return(ret); | ||
67 | } | ||
68 | |||
69 | int UI_UTIL_read_pw(char *buf,char *buff,int size,const char *prompt,int verify) | ||
70 | { | ||
71 | int ok = 0; | ||
72 | UI *ui; | ||
73 | |||
74 | ui = UI_new(); | ||
75 | if (ui) | ||
76 | { | ||
77 | ok = UI_add_input_string(ui,prompt,0,buf,0,BUFSIZ-1); | ||
78 | if (ok == 0 && verify) | ||
79 | ok = UI_add_verify_string(ui,prompt,0,buff,0,BUFSIZ-1, | ||
80 | buf); | ||
81 | if (ok == 0) | ||
82 | ok=UI_process(ui); | ||
83 | UI_free(ui); | ||
84 | } | ||
85 | return(ok); | ||
86 | } | ||
diff --git a/src/lib/libcrypto/util/mkerr.pl b/src/lib/libcrypto/util/mkerr.pl new file mode 100644 index 0000000000..4b3bccb13e --- /dev/null +++ b/src/lib/libcrypto/util/mkerr.pl | |||
@@ -0,0 +1,503 @@ | |||
1 | #!/usr/local/bin/perl -w | ||
2 | |||
3 | my $config = "crypto/err/openssl.ec"; | ||
4 | my $debug = 0; | ||
5 | my $rebuild = 0; | ||
6 | my $static = 1; | ||
7 | my $recurse = 0; | ||
8 | my $reindex = 0; | ||
9 | my $dowrite = 0; | ||
10 | |||
11 | |||
12 | while (@ARGV) { | ||
13 | my $arg = $ARGV[0]; | ||
14 | if($arg eq "-conf") { | ||
15 | shift @ARGV; | ||
16 | $config = shift @ARGV; | ||
17 | } elsif($arg eq "-debug") { | ||
18 | $debug = 1; | ||
19 | shift @ARGV; | ||
20 | } elsif($arg eq "-rebuild") { | ||
21 | $rebuild = 1; | ||
22 | shift @ARGV; | ||
23 | } elsif($arg eq "-recurse") { | ||
24 | $recurse = 1; | ||
25 | shift @ARGV; | ||
26 | } elsif($arg eq "-reindex") { | ||
27 | $reindex = 1; | ||
28 | shift @ARGV; | ||
29 | } elsif($arg eq "-nostatic") { | ||
30 | $static = 0; | ||
31 | shift @ARGV; | ||
32 | } elsif($arg eq "-write") { | ||
33 | $dowrite = 1; | ||
34 | shift @ARGV; | ||
35 | } else { | ||
36 | last; | ||
37 | } | ||
38 | } | ||
39 | |||
40 | if($recurse) { | ||
41 | @source = (<crypto/*.c>, <crypto/*/*.c>, ,<rsaref/*.c>, <ssl/*.c>); | ||
42 | } else { | ||
43 | @source = @ARGV; | ||
44 | } | ||
45 | |||
46 | # Read in the config file | ||
47 | |||
48 | open(IN, "<$config") || die "Can't open config file $config"; | ||
49 | |||
50 | # Parse config file | ||
51 | |||
52 | while(<IN>) | ||
53 | { | ||
54 | if(/^L\s+(\S+)\s+(\S+)\s+(\S+)/) { | ||
55 | $hinc{$1} = $2; | ||
56 | $cskip{$3} = $1; | ||
57 | if($3 ne "NONE") { | ||
58 | $csrc{$1} = $3; | ||
59 | $fmax{$1} = 99; | ||
60 | $rmax{$1} = 99; | ||
61 | $fnew{$1} = 0; | ||
62 | $rnew{$1} = 0; | ||
63 | } | ||
64 | } elsif (/^F\s+(\S+)/) { | ||
65 | # Add extra function with $1 | ||
66 | } elsif (/^R\s+(\S+)\s+(\S+)/) { | ||
67 | $rextra{$1} = $2; | ||
68 | $rcodes{$1} = $2; | ||
69 | } | ||
70 | } | ||
71 | |||
72 | close IN; | ||
73 | |||
74 | # Scan each header file in turn and make a list of error codes | ||
75 | # and function names | ||
76 | |||
77 | while (($lib, $hdr) = each %hinc) | ||
78 | { | ||
79 | next if($hdr eq "NONE"); | ||
80 | print STDERR "Scanning header file $hdr\n" if $debug; | ||
81 | open(IN, "<$hdr") || die "Can't open Header file $hdr\n"; | ||
82 | my $line = "", $def= ""; | ||
83 | while(<IN>) { | ||
84 | last if(/BEGIN\s+ERROR\s+CODES/); | ||
85 | if ($line ne '') { | ||
86 | $_ = $line . $_; | ||
87 | $line = ''; | ||
88 | } | ||
89 | |||
90 | if (/\\$/) { | ||
91 | $line = $_; | ||
92 | next; | ||
93 | } | ||
94 | |||
95 | $cpp = 1 if /^#.*ifdef.*cplusplus/; # skip "C" declaration | ||
96 | if ($cpp) { | ||
97 | $cpp = 0 if /^#.*endif/; | ||
98 | next; | ||
99 | } | ||
100 | |||
101 | next if (/^#/); # skip preprocessor directives | ||
102 | |||
103 | s/\/\*.*?\*\///gs; # ignore comments | ||
104 | s/{[^{}]*}//gs; # ignore {} blocks | ||
105 | |||
106 | if (/{|\/\*/) { # Add a } so editor works... | ||
107 | $line = $_; | ||
108 | } else { | ||
109 | $def .= $_; | ||
110 | } | ||
111 | } | ||
112 | |||
113 | foreach (split /;/, $def) { | ||
114 | s/^[\n\s]*//g; | ||
115 | s/[\n\s]*$//g; | ||
116 | next if(/typedef\W/); | ||
117 | if (/\(\*(\w*)\([^\)]+/) { | ||
118 | my $name = $1; | ||
119 | $name =~ tr/[a-z]/[A-Z]/; | ||
120 | $ftrans{$name} = $1; | ||
121 | } elsif (/\w+\W+(\w+)\W*\(\s*\)$/s){ | ||
122 | # K&R C | ||
123 | next ; | ||
124 | } elsif (/\w+\W+\w+\W*\(.*\)$/s) { | ||
125 | while (not /\(\)$/s) { | ||
126 | s/[^\(\)]*\)$/\)/s; | ||
127 | s/\([^\(\)]*\)\)$/\)/s; | ||
128 | } | ||
129 | s/\(void\)//; | ||
130 | /(\w+)\W*\(\)/s; | ||
131 | my $name = $1; | ||
132 | $name =~ tr/[a-z]/[A-Z]/; | ||
133 | $ftrans{$name} = $1; | ||
134 | } elsif (/\(/ and not (/=/ or /DECLARE_STACK/)) { | ||
135 | print STDERR "Header $hdr: cannot parse: $_;\n"; | ||
136 | } | ||
137 | } | ||
138 | |||
139 | next if $reindex; | ||
140 | |||
141 | # Scan function and reason codes and store them: keep a note of the | ||
142 | # maximum code used. | ||
143 | |||
144 | while(<IN>) { | ||
145 | if(/^#define\s+(\S+)\s+(\S+)/) { | ||
146 | $name = $1; | ||
147 | $code = $2; | ||
148 | unless($name =~ /^${lib}_([RF])_(\w+)$/) { | ||
149 | print STDERR "Invalid error code $name\n"; | ||
150 | next; | ||
151 | } | ||
152 | if($1 eq "R") { | ||
153 | $rcodes{$name} = $code; | ||
154 | if(!(exists $rextra{$name}) && | ||
155 | ($code > $rmax{$lib}) ) { | ||
156 | $rmax{$lib} = $code; | ||
157 | } | ||
158 | } else { | ||
159 | if($code > $fmax{$lib}) { | ||
160 | $fmax{$lib} = $code; | ||
161 | } | ||
162 | $fcodes{$name} = $code; | ||
163 | } | ||
164 | } | ||
165 | } | ||
166 | close IN; | ||
167 | } | ||
168 | |||
169 | # Scan each C source file and look for function and reason codes | ||
170 | # This is done by looking for strings that "look like" function or | ||
171 | # reason codes: basically anything consisting of all upper case and | ||
172 | # numerics which has _F_ or _R_ in it and which has the name of an | ||
173 | # error library at the start. This seems to work fine except for the | ||
174 | # oddly named structure BIO_F_CTX which needs to be ignored. | ||
175 | # If a code doesn't exist in list compiled from headers then mark it | ||
176 | # with the value "X" as a place holder to give it a value later. | ||
177 | # Store all function and reason codes found in %ufcodes and %urcodes | ||
178 | # so all those unreferenced can be printed out. | ||
179 | |||
180 | |||
181 | foreach $file (@source) { | ||
182 | # Don't parse the error source file. | ||
183 | next if exists $cskip{$file}; | ||
184 | open(IN, "<$file") || die "Can't open source file $file\n"; | ||
185 | while(<IN>) { | ||
186 | if(/(([A-Z0-9]+)_F_([A-Z0-9_]+))/) { | ||
187 | next unless exists $csrc{$2}; | ||
188 | next if($1 eq "BIO_F_BUFFER_CTX"); | ||
189 | $ufcodes{$1} = 1; | ||
190 | if(!exists $fcodes{$1}) { | ||
191 | $fcodes{$1} = "X"; | ||
192 | $fnew{$2}++; | ||
193 | } | ||
194 | $notrans{$1} = 1 unless exists $ftrans{$3}; | ||
195 | } | ||
196 | if(/(([A-Z0-9]+)_R_[A-Z0-9_]+)/) { | ||
197 | next unless exists $csrc{$2}; | ||
198 | $urcodes{$1} = 1; | ||
199 | if(!exists $rcodes{$1}) { | ||
200 | $rcodes{$1} = "X"; | ||
201 | $rnew{$2}++; | ||
202 | } | ||
203 | } | ||
204 | } | ||
205 | close IN; | ||
206 | } | ||
207 | |||
208 | # Now process each library in turn. | ||
209 | |||
210 | foreach $lib (keys %csrc) | ||
211 | { | ||
212 | my $hfile = $hinc{$lib}; | ||
213 | my $cfile = $csrc{$lib}; | ||
214 | if(!$fnew{$lib} && !$rnew{$lib}) { | ||
215 | print STDERR "$lib:\t\tNo new error codes\n"; | ||
216 | next unless $rebuild; | ||
217 | } else { | ||
218 | print STDERR "$lib:\t\t$fnew{$lib} New Functions,"; | ||
219 | print STDERR " $rnew{$lib} New Reasons.\n"; | ||
220 | next unless $dowrite; | ||
221 | } | ||
222 | |||
223 | # If we get here then we have some new error codes so we | ||
224 | # need to rebuild the header file and C file. | ||
225 | |||
226 | # Make a sorted list of error and reason codes for later use. | ||
227 | |||
228 | my @function = sort grep(/^${lib}_/,keys %fcodes); | ||
229 | my @reasons = sort grep(/^${lib}_/,keys %rcodes); | ||
230 | |||
231 | # Rewrite the header file | ||
232 | |||
233 | open(IN, "<$hfile") || die "Can't Open Header File $hfile\n"; | ||
234 | |||
235 | # Copy across the old file | ||
236 | while(<IN>) { | ||
237 | push @out, $_; | ||
238 | last if (/BEGIN ERROR CODES/); | ||
239 | } | ||
240 | close IN; | ||
241 | |||
242 | open (OUT, ">$hfile") || die "Can't Open File $hfile for writing\n"; | ||
243 | |||
244 | print OUT @out; | ||
245 | undef @out; | ||
246 | print OUT <<"EOF"; | ||
247 | /* The following lines are auto generated by the script mkerr.pl. Any changes | ||
248 | * made after this point may be overwritten when the script is next run. | ||
249 | */ | ||
250 | |||
251 | /* Error codes for the $lib functions. */ | ||
252 | |||
253 | /* Function codes. */ | ||
254 | EOF | ||
255 | |||
256 | foreach $i (@function) { | ||
257 | $z=6-int(length($i)/8); | ||
258 | if($fcodes{$i} eq "X") { | ||
259 | $fcodes{$i} = ++$fmax{$lib}; | ||
260 | print STDERR "New Function code $i\n" if $debug; | ||
261 | } | ||
262 | printf OUT "#define $i%s $fcodes{$i}\n","\t" x $z; | ||
263 | } | ||
264 | |||
265 | print OUT "\n/* Reason codes. */\n"; | ||
266 | |||
267 | foreach $i (@reasons) { | ||
268 | $z=6-int(length($i)/8); | ||
269 | if($rcodes{$i} eq "X") { | ||
270 | $rcodes{$i} = ++$rmax{$lib}; | ||
271 | print STDERR "New Reason code $i\n" if $debug; | ||
272 | } | ||
273 | printf OUT "#define $i%s $rcodes{$i}\n","\t" x $z; | ||
274 | } | ||
275 | print OUT <<"EOF"; | ||
276 | |||
277 | #ifdef __cplusplus | ||
278 | } | ||
279 | #endif | ||
280 | #endif | ||
281 | |||
282 | EOF | ||
283 | close OUT; | ||
284 | |||
285 | # Rewrite the C source file containing the error details. | ||
286 | |||
287 | my $hincf; | ||
288 | if($static) { | ||
289 | $hfile =~ /([^\/]+)$/; | ||
290 | $hincf = "<openssl/$1>"; | ||
291 | } else { | ||
292 | $hincf = "\"$hfile\""; | ||
293 | } | ||
294 | |||
295 | |||
296 | open (OUT,">$cfile") || die "Can't open $cfile for writing"; | ||
297 | |||
298 | print OUT <<"EOF"; | ||
299 | /* $cfile */ | ||
300 | /* ==================================================================== | ||
301 | * Copyright (c) 1999 The OpenSSL Project. All rights reserved. | ||
302 | * | ||
303 | * Redistribution and use in source and binary forms, with or without | ||
304 | * modification, are permitted provided that the following conditions | ||
305 | * are met: | ||
306 | * | ||
307 | * 1. Redistributions of source code must retain the above copyright | ||
308 | * notice, this list of conditions and the following disclaimer. | ||
309 | * | ||
310 | * 2. Redistributions in binary form must reproduce the above copyright | ||
311 | * notice, this list of conditions and the following disclaimer in | ||
312 | * the documentation and/or other materials provided with the | ||
313 | * distribution. | ||
314 | * | ||
315 | * 3. All advertising materials mentioning features or use of this | ||
316 | * software must display the following acknowledgment: | ||
317 | * "This product includes software developed by the OpenSSL Project | ||
318 | * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" | ||
319 | * | ||
320 | * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to | ||
321 | * endorse or promote products derived from this software without | ||
322 | * prior written permission. For written permission, please contact | ||
323 | * openssl-core\@OpenSSL.org. | ||
324 | * | ||
325 | * 5. Products derived from this software may not be called "OpenSSL" | ||
326 | * nor may "OpenSSL" appear in their names without prior written | ||
327 | * permission of the OpenSSL Project. | ||
328 | * | ||
329 | * 6. Redistributions of any form whatsoever must retain the following | ||
330 | * acknowledgment: | ||
331 | * "This product includes software developed by the OpenSSL Project | ||
332 | * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" | ||
333 | * | ||
334 | * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY | ||
335 | * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
336 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | ||
337 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR | ||
338 | * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
339 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
340 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
341 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
342 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
343 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
344 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED | ||
345 | * OF THE POSSIBILITY OF SUCH DAMAGE. | ||
346 | * ==================================================================== | ||
347 | * | ||
348 | * This product includes cryptographic software written by Eric Young | ||
349 | * (eay\@cryptsoft.com). This product includes software written by Tim | ||
350 | * Hudson (tjh\@cryptsoft.com). | ||
351 | * | ||
352 | */ | ||
353 | |||
354 | /* NOTE: this file was auto generated by the mkerr.pl script: any changes | ||
355 | * made to it will be overwritten when the script next updates this file. | ||
356 | */ | ||
357 | |||
358 | #include <stdio.h> | ||
359 | #include <openssl/err.h> | ||
360 | #include $hincf | ||
361 | |||
362 | /* BEGIN ERROR CODES */ | ||
363 | #ifndef NO_ERR | ||
364 | static ERR_STRING_DATA ${lib}_str_functs[]= | ||
365 | { | ||
366 | EOF | ||
367 | # Add each function code: if a function name is found then use it. | ||
368 | foreach $i (@function) { | ||
369 | my $fn; | ||
370 | $i =~ /^${lib}_F_(\S+)$/; | ||
371 | $fn = $1; | ||
372 | if(exists $ftrans{$fn}) { | ||
373 | $fn = $ftrans{$fn}; | ||
374 | } | ||
375 | print OUT "{ERR_PACK(0,$i,0),\t\"$fn\"},\n"; | ||
376 | } | ||
377 | print OUT <<"EOF"; | ||
378 | {0,NULL} | ||
379 | }; | ||
380 | |||
381 | static ERR_STRING_DATA ${lib}_str_reasons[]= | ||
382 | { | ||
383 | EOF | ||
384 | # Add each reason code. | ||
385 | foreach $i (@reasons) { | ||
386 | my $rn; | ||
387 | my $nspc = 0; | ||
388 | $i =~ /^${lib}_R_(\S+)$/; | ||
389 | $rn = $1; | ||
390 | $rn =~ tr/_[A-Z]/ [a-z]/; | ||
391 | $nspc = 40 - length($i) unless length($i) > 40; | ||
392 | $nspc = " " x $nspc; | ||
393 | print OUT "{${i}${nspc},\"$rn\"},\n"; | ||
394 | } | ||
395 | if($static) { | ||
396 | print OUT <<"EOF"; | ||
397 | {0,NULL} | ||
398 | }; | ||
399 | |||
400 | #endif | ||
401 | |||
402 | void ERR_load_${lib}_strings(void) | ||
403 | { | ||
404 | static int init=1; | ||
405 | |||
406 | if (init) | ||
407 | { | ||
408 | init=0; | ||
409 | #ifndef NO_ERR | ||
410 | ERR_load_strings(ERR_LIB_${lib},${lib}_str_functs); | ||
411 | ERR_load_strings(ERR_LIB_${lib},${lib}_str_reasons); | ||
412 | #endif | ||
413 | |||
414 | } | ||
415 | } | ||
416 | EOF | ||
417 | } else { | ||
418 | print OUT <<"EOF"; | ||
419 | {0,NULL} | ||
420 | }; | ||
421 | |||
422 | #endif | ||
423 | |||
424 | #ifdef ${lib}_LIB_NAME | ||
425 | static ERR_STRING_DATA ${lib}_lib_name[]= | ||
426 | { | ||
427 | {0 ,${lib}_LIB_NAME}, | ||
428 | {0,NULL} | ||
429 | }; | ||
430 | #endif | ||
431 | |||
432 | |||
433 | int ${lib}_lib_error_code=0; | ||
434 | |||
435 | void ERR_load_${lib}_strings(void) | ||
436 | { | ||
437 | static int init=1; | ||
438 | |||
439 | if (${lib}_lib_error_code == 0) | ||
440 | ${lib}_lib_error_code=ERR_get_next_error_library(); | ||
441 | |||
442 | if (init) | ||
443 | { | ||
444 | init=0; | ||
445 | #ifndef NO_ERR | ||
446 | ERR_load_strings(${lib}_lib_error_code,${lib}_str_functs); | ||
447 | ERR_load_strings(${lib}_lib_error_code,${lib}_str_reasons); | ||
448 | #endif | ||
449 | |||
450 | #ifdef ${lib}_LIB_NAME | ||
451 | ${lib}_lib_name->error = ERR_PACK(${lib}_lib_error_code,0,0); | ||
452 | ERR_load_strings(0,${lib}_lib_name); | ||
453 | #endif; | ||
454 | } | ||
455 | } | ||
456 | |||
457 | void ERR_${lib}_error(int function, int reason, char *file, int line) | ||
458 | { | ||
459 | if (${lib}_lib_error_code == 0) | ||
460 | ${lib}_lib_error_code=ERR_get_next_error_library(); | ||
461 | ERR_PUT_error(${lib}_lib_error_code,function,reason,file,line); | ||
462 | } | ||
463 | EOF | ||
464 | |||
465 | } | ||
466 | |||
467 | close OUT; | ||
468 | |||
469 | } | ||
470 | |||
471 | if($debug && defined(%notrans)) { | ||
472 | print STDERR "The following function codes were not translated:\n"; | ||
473 | foreach(sort keys %notrans) | ||
474 | { | ||
475 | print STDERR "$_\n"; | ||
476 | } | ||
477 | } | ||
478 | |||
479 | # Make a list of unreferenced function and reason codes | ||
480 | |||
481 | foreach (keys %fcodes) { | ||
482 | push (@funref, $_) unless exists $ufcodes{$_}; | ||
483 | } | ||
484 | |||
485 | foreach (keys %rcodes) { | ||
486 | push (@runref, $_) unless exists $urcodes{$_}; | ||
487 | } | ||
488 | |||
489 | if($debug && defined(@funref) ) { | ||
490 | print STDERR "The following function codes were not referenced:\n"; | ||
491 | foreach(sort @funref) | ||
492 | { | ||
493 | print STDERR "$_\n"; | ||
494 | } | ||
495 | } | ||
496 | |||
497 | if($debug && defined(@runref) ) { | ||
498 | print STDERR "The following reason codes were not referenced:\n"; | ||
499 | foreach(sort @runref) | ||
500 | { | ||
501 | print STDERR "$_\n"; | ||
502 | } | ||
503 | } | ||
diff --git a/src/lib/libcrypto/util/mkstack.pl b/src/lib/libcrypto/util/mkstack.pl new file mode 100644 index 0000000000..3ee13fe7c9 --- /dev/null +++ b/src/lib/libcrypto/util/mkstack.pl | |||
@@ -0,0 +1,124 @@ | |||
1 | #!/usr/local/bin/perl -w | ||
2 | |||
3 | # This is a utility that searches out "DECLARE_STACK_OF()" | ||
4 | # declarations in .h and .c files, and updates/creates/replaces | ||
5 | # the corresponding macro declarations in crypto/stack/safestack.h. | ||
6 | # As it's not generally possible to have macros that generate macros, | ||
7 | # we need to control this from the "outside", here in this script. | ||
8 | # | ||
9 | # Geoff Thorpe, June, 2000 (with massive Perl-hacking | ||
10 | # help from Steve Robb) | ||
11 | |||
12 | my $safestack = "crypto/stack/safestack"; | ||
13 | |||
14 | my $do_write; | ||
15 | while (@ARGV) { | ||
16 | my $arg = $ARGV[0]; | ||
17 | if($arg eq "-write") { | ||
18 | $do_write = 1; | ||
19 | } | ||
20 | shift @ARGV; | ||
21 | } | ||
22 | |||
23 | |||
24 | @source = (<crypto/*.[ch]>, <crypto/*/*.[ch]>, <rsaref/*.[ch]>, <ssl/*.[ch]>); | ||
25 | foreach $file (@source) { | ||
26 | next if -l $file; | ||
27 | |||
28 | # Open the .c/.h file for reading | ||
29 | open(IN, "< $file") || die "Can't open $file for reading: $!"; | ||
30 | |||
31 | while(<IN>) { | ||
32 | if (/^DECLARE_STACK_OF\(([^)]+)\)/) { | ||
33 | push @stacklst, $1; | ||
34 | } if (/^DECLARE_ASN1_SET_OF\(([^)]+)\)/) { | ||
35 | push @asn1setlst, $1; | ||
36 | } if (/^DECLARE_PKCS12_STACK_OF\(([^)]+)\)/) { | ||
37 | push @p12stklst, $1; | ||
38 | } | ||
39 | } | ||
40 | close(IN); | ||
41 | } | ||
42 | |||
43 | |||
44 | |||
45 | my $old_stackfile = ""; | ||
46 | my $new_stackfile = ""; | ||
47 | my $inside_block = 0; | ||
48 | my $type_thing; | ||
49 | |||
50 | open(IN, "< $safestack.h") || die "Can't open input file: $!"; | ||
51 | while(<IN>) { | ||
52 | $old_stackfile .= $_; | ||
53 | |||
54 | if (m|^/\* This block of defines is updated by util/mkstack.pl, please do not touch! \*/|) { | ||
55 | $inside_block = 1; | ||
56 | } | ||
57 | if (m|^/\* End of util/mkstack.pl block, you may now edit :-\) \*/|) { | ||
58 | $inside_block = 0; | ||
59 | } elsif ($inside_block == 0) { | ||
60 | $new_stackfile .= $_; | ||
61 | } | ||
62 | next if($inside_block != 1); | ||
63 | $new_stackfile .= "/* This block of defines is updated by util/mkstack.pl, please do not touch! */"; | ||
64 | |||
65 | foreach $type_thing (sort @stacklst) { | ||
66 | $new_stackfile .= <<EOF; | ||
67 | |||
68 | #define sk_${type_thing}_new(st) SKM_sk_new($type_thing, (st)) | ||
69 | #define sk_${type_thing}_new_null() SKM_sk_new_null($type_thing) | ||
70 | #define sk_${type_thing}_free(st) SKM_sk_free($type_thing, (st)) | ||
71 | #define sk_${type_thing}_num(st) SKM_sk_num($type_thing, (st)) | ||
72 | #define sk_${type_thing}_value(st, i) SKM_sk_value($type_thing, (st), (i)) | ||
73 | #define sk_${type_thing}_set(st, i, val) SKM_sk_set($type_thing, (st), (i), (val)) | ||
74 | #define sk_${type_thing}_zero(st) SKM_sk_zero($type_thing, (st)) | ||
75 | #define sk_${type_thing}_push(st, val) SKM_sk_push($type_thing, (st), (val)) | ||
76 | #define sk_${type_thing}_unshift(st, val) SKM_sk_unshift($type_thing, (st), (val)) | ||
77 | #define sk_${type_thing}_find(st, val) SKM_sk_find($type_thing, (st), (val)) | ||
78 | #define sk_${type_thing}_delete(st, i) SKM_sk_delete($type_thing, (st), (i)) | ||
79 | #define sk_${type_thing}_delete_ptr(st, ptr) SKM_sk_delete_ptr($type_thing, (st), (ptr)) | ||
80 | #define sk_${type_thing}_insert(st, val, i) SKM_sk_insert($type_thing, (st), (val), (i)) | ||
81 | #define sk_${type_thing}_set_cmp_func(st, cmp) SKM_sk_set_cmp_func($type_thing, (st), (cmp)) | ||
82 | #define sk_${type_thing}_dup(st) SKM_sk_dup($type_thing, st) | ||
83 | #define sk_${type_thing}_pop_free(st, free_func) SKM_sk_pop_free($type_thing, (st), (free_func)) | ||
84 | #define sk_${type_thing}_shift(st) SKM_sk_shift($type_thing, (st)) | ||
85 | #define sk_${type_thing}_pop(st) SKM_sk_pop($type_thing, (st)) | ||
86 | #define sk_${type_thing}_sort(st) SKM_sk_sort($type_thing, (st)) | ||
87 | EOF | ||
88 | } | ||
89 | foreach $type_thing (sort @asn1setlst) { | ||
90 | $new_stackfile .= <<EOF; | ||
91 | |||
92 | #define d2i_ASN1_SET_OF_${type_thing}(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \\ | ||
93 | SKM_ASN1_SET_OF_d2i($type_thing, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) | ||
94 | #define i2d_ASN1_SET_OF_${type_thing}(st, pp, i2d_func, ex_tag, ex_class, is_set) \\ | ||
95 | SKM_ASN1_SET_OF_i2d($type_thing, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set)) | ||
96 | #define ASN1_seq_pack_${type_thing}(st, i2d_func, buf, len) \\ | ||
97 | SKM_ASN1_seq_pack($type_thing, (st), (i2d_func), (buf), (len)) | ||
98 | #define ASN1_seq_unpack_${type_thing}(buf, len, d2i_func, free_func) \\ | ||
99 | SKM_ASN1_seq_unpack($type_thing, (buf), (len), (d2i_func), (free_func)) | ||
100 | EOF | ||
101 | } | ||
102 | foreach $type_thing (sort @p12stklst) { | ||
103 | $new_stackfile .= <<EOF; | ||
104 | |||
105 | #define PKCS12_decrypt_d2i_${type_thing}(algor, d2i_func, free_func, pass, passlen, oct, seq) \\ | ||
106 | SKM_PKCS12_decrypt_d2i($type_thing, (algor), (d2i_func), (free_func), (pass), (passlen), (oct), (seq)) | ||
107 | EOF | ||
108 | } | ||
109 | $new_stackfile .= "/* End of util/mkstack.pl block, you may now edit :-) */\n"; | ||
110 | $inside_block = 2; | ||
111 | } | ||
112 | |||
113 | |||
114 | if ($new_stackfile eq $old_stackfile) { | ||
115 | print "No changes to $safestack.h.\n"; | ||
116 | exit 0; # avoid unnecessary rebuild | ||
117 | } | ||
118 | |||
119 | if ($do_write) { | ||
120 | print "Writing new $safestack.h.\n"; | ||
121 | open OUT, ">$safestack.h" || die "Can't open output file"; | ||
122 | print OUT $new_stackfile; | ||
123 | close OUT; | ||
124 | } | ||
diff --git a/src/lib/libcrypto/x509/x509_att.c b/src/lib/libcrypto/x509/x509_att.c new file mode 100644 index 0000000000..caafde658f --- /dev/null +++ b/src/lib/libcrypto/x509/x509_att.c | |||
@@ -0,0 +1,326 @@ | |||
1 | /* crypto/x509/x509_att.c */ | ||
2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) | ||
3 | * All rights reserved. | ||
4 | * | ||
5 | * This package is an SSL implementation written | ||
6 | * by Eric Young (eay@cryptsoft.com). | ||
7 | * The implementation was written so as to conform with Netscapes SSL. | ||
8 | * | ||
9 | * This library is free for commercial and non-commercial use as long as | ||
10 | * the following conditions are aheared to. The following conditions | ||
11 | * apply to all code found in this distribution, be it the RC4, RSA, | ||
12 | * lhash, DES, etc., code; not just the SSL code. The SSL documentation | ||
13 | * included with this distribution is covered by the same copyright terms | ||
14 | * except that the holder is Tim Hudson (tjh@cryptsoft.com). | ||
15 | * | ||
16 | * Copyright remains Eric Young's, and as such any Copyright notices in | ||
17 | * the code are not to be removed. | ||
18 | * If this package is used in a product, Eric Young should be given attribution | ||
19 | * as the author of the parts of the library used. | ||
20 | * This can be in the form of a textual message at program startup or | ||
21 | * in documentation (online or textual) provided with the package. | ||
22 | * | ||
23 | * Redistribution and use in source and binary forms, with or without | ||
24 | * modification, are permitted provided that the following conditions | ||
25 | * are met: | ||
26 | * 1. Redistributions of source code must retain the copyright | ||
27 | * notice, this list of conditions and the following disclaimer. | ||
28 | * 2. Redistributions in binary form must reproduce the above copyright | ||
29 | * notice, this list of conditions and the following disclaimer in the | ||
30 | * documentation and/or other materials provided with the distribution. | ||
31 | * 3. All advertising materials mentioning features or use of this software | ||
32 | * must display the following acknowledgement: | ||
33 | * "This product includes cryptographic software written by | ||
34 | * Eric Young (eay@cryptsoft.com)" | ||
35 | * The word 'cryptographic' can be left out if the rouines from the library | ||
36 | * being used are not cryptographic related :-). | ||
37 | * 4. If you include any Windows specific code (or a derivative thereof) from | ||
38 | * the apps directory (application code) you must include an acknowledgement: | ||
39 | * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" | ||
40 | * | ||
41 | * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND | ||
42 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
43 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
44 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | ||
45 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
46 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
47 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
48 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
49 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
50 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
51 | * SUCH DAMAGE. | ||
52 | * | ||
53 | * The licence and distribution terms for any publically available version or | ||
54 | * derivative of this code cannot be changed. i.e. this code cannot simply be | ||
55 | * copied and put under another distribution licence | ||
56 | * [including the GNU Public Licence.] | ||
57 | */ | ||
58 | |||
59 | #include <stdio.h> | ||
60 | #include <openssl/stack.h> | ||
61 | #include "cryptlib.h" | ||
62 | #include <openssl/asn1.h> | ||
63 | #include <openssl/objects.h> | ||
64 | #include <openssl/evp.h> | ||
65 | #include <openssl/x509.h> | ||
66 | #include <openssl/x509v3.h> | ||
67 | |||
68 | int X509at_get_attr_count(const STACK_OF(X509_ATTRIBUTE) *x) | ||
69 | { | ||
70 | if (!x) return 0; | ||
71 | return(sk_X509_ATTRIBUTE_num(x)); | ||
72 | } | ||
73 | |||
74 | int X509at_get_attr_by_NID(const STACK_OF(X509_ATTRIBUTE) *x, int nid, | ||
75 | int lastpos) | ||
76 | { | ||
77 | ASN1_OBJECT *obj; | ||
78 | |||
79 | obj=OBJ_nid2obj(nid); | ||
80 | if (obj == NULL) return(-2); | ||
81 | return(X509at_get_attr_by_OBJ(x,obj,lastpos)); | ||
82 | } | ||
83 | |||
84 | int X509at_get_attr_by_OBJ(const STACK_OF(X509_ATTRIBUTE) *sk, ASN1_OBJECT *obj, | ||
85 | int lastpos) | ||
86 | { | ||
87 | int n; | ||
88 | X509_ATTRIBUTE *ex; | ||
89 | |||
90 | if (sk == NULL) return(-1); | ||
91 | lastpos++; | ||
92 | if (lastpos < 0) | ||
93 | lastpos=0; | ||
94 | n=sk_X509_ATTRIBUTE_num(sk); | ||
95 | for ( ; lastpos < n; lastpos++) | ||
96 | { | ||
97 | ex=sk_X509_ATTRIBUTE_value(sk,lastpos); | ||
98 | if (OBJ_cmp(ex->object,obj) == 0) | ||
99 | return(lastpos); | ||
100 | } | ||
101 | return(-1); | ||
102 | } | ||
103 | |||
104 | X509_ATTRIBUTE *X509at_get_attr(const STACK_OF(X509_ATTRIBUTE) *x, int loc) | ||
105 | { | ||
106 | if (x == NULL || sk_X509_ATTRIBUTE_num(x) <= loc || loc < 0) | ||
107 | return NULL; | ||
108 | else | ||
109 | return sk_X509_ATTRIBUTE_value(x,loc); | ||
110 | } | ||
111 | |||
112 | X509_ATTRIBUTE *X509at_delete_attr(STACK_OF(X509_ATTRIBUTE) *x, int loc) | ||
113 | { | ||
114 | X509_ATTRIBUTE *ret; | ||
115 | |||
116 | if (x == NULL || sk_X509_ATTRIBUTE_num(x) <= loc || loc < 0) | ||
117 | return(NULL); | ||
118 | ret=sk_X509_ATTRIBUTE_delete(x,loc); | ||
119 | return(ret); | ||
120 | } | ||
121 | |||
122 | STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr(STACK_OF(X509_ATTRIBUTE) **x, | ||
123 | X509_ATTRIBUTE *attr) | ||
124 | { | ||
125 | X509_ATTRIBUTE *new_attr=NULL; | ||
126 | STACK_OF(X509_ATTRIBUTE) *sk=NULL; | ||
127 | |||
128 | if ((x != NULL) && (*x == NULL)) | ||
129 | { | ||
130 | if ((sk=sk_X509_ATTRIBUTE_new_null()) == NULL) | ||
131 | goto err; | ||
132 | } | ||
133 | else | ||
134 | sk= *x; | ||
135 | |||
136 | if ((new_attr=X509_ATTRIBUTE_dup(attr)) == NULL) | ||
137 | goto err2; | ||
138 | if (!sk_X509_ATTRIBUTE_push(sk,new_attr)) | ||
139 | goto err; | ||
140 | if ((x != NULL) && (*x == NULL)) | ||
141 | *x=sk; | ||
142 | return(sk); | ||
143 | err: | ||
144 | X509err(X509_F_X509_ADD_ATTR,ERR_R_MALLOC_FAILURE); | ||
145 | err2: | ||
146 | if (new_attr != NULL) X509_ATTRIBUTE_free(new_attr); | ||
147 | if (sk != NULL) sk_X509_ATTRIBUTE_free(sk); | ||
148 | return(NULL); | ||
149 | } | ||
150 | |||
151 | STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_OBJ(STACK_OF(X509_ATTRIBUTE) **x, | ||
152 | ASN1_OBJECT *obj, int type, | ||
153 | unsigned char *bytes, int len) | ||
154 | { | ||
155 | X509_ATTRIBUTE *attr; | ||
156 | STACK_OF(X509_ATTRIBUTE) *ret; | ||
157 | attr = X509_ATTRIBUTE_create_by_OBJ(NULL, obj, type, bytes, len); | ||
158 | if(!attr) return 0; | ||
159 | ret = X509at_add1_attr(x, attr); | ||
160 | X509_ATTRIBUTE_free(attr); | ||
161 | return ret; | ||
162 | } | ||
163 | |||
164 | STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_NID(STACK_OF(X509_ATTRIBUTE) **x, | ||
165 | int nid, int type, | ||
166 | unsigned char *bytes, int len) | ||
167 | { | ||
168 | X509_ATTRIBUTE *attr; | ||
169 | STACK_OF(X509_ATTRIBUTE) *ret; | ||
170 | attr = X509_ATTRIBUTE_create_by_NID(NULL, nid, type, bytes, len); | ||
171 | if(!attr) return 0; | ||
172 | ret = X509at_add1_attr(x, attr); | ||
173 | X509_ATTRIBUTE_free(attr); | ||
174 | return ret; | ||
175 | } | ||
176 | |||
177 | STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_txt(STACK_OF(X509_ATTRIBUTE) **x, | ||
178 | char *attrname, int type, | ||
179 | unsigned char *bytes, int len) | ||
180 | { | ||
181 | X509_ATTRIBUTE *attr; | ||
182 | STACK_OF(X509_ATTRIBUTE) *ret; | ||
183 | attr = X509_ATTRIBUTE_create_by_txt(NULL, attrname, type, bytes, len); | ||
184 | if(!attr) return 0; | ||
185 | ret = X509at_add1_attr(x, attr); | ||
186 | X509_ATTRIBUTE_free(attr); | ||
187 | return ret; | ||
188 | } | ||
189 | |||
190 | X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_NID(X509_ATTRIBUTE **attr, int nid, | ||
191 | int atrtype, void *data, int len) | ||
192 | { | ||
193 | ASN1_OBJECT *obj; | ||
194 | X509_ATTRIBUTE *ret; | ||
195 | |||
196 | obj=OBJ_nid2obj(nid); | ||
197 | if (obj == NULL) | ||
198 | { | ||
199 | X509err(X509_F_X509_ATTRIBUTE_CREATE_BY_NID,X509_R_UNKNOWN_NID); | ||
200 | return(NULL); | ||
201 | } | ||
202 | ret=X509_ATTRIBUTE_create_by_OBJ(attr,obj,atrtype,data,len); | ||
203 | if (ret == NULL) ASN1_OBJECT_free(obj); | ||
204 | return(ret); | ||
205 | } | ||
206 | |||
207 | X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_OBJ(X509_ATTRIBUTE **attr, | ||
208 | ASN1_OBJECT *obj, int atrtype, void *data, int len) | ||
209 | { | ||
210 | X509_ATTRIBUTE *ret; | ||
211 | |||
212 | if ((attr == NULL) || (*attr == NULL)) | ||
213 | { | ||
214 | if ((ret=X509_ATTRIBUTE_new()) == NULL) | ||
215 | { | ||
216 | X509err(X509_F_X509_ATTRIBUTE_CREATE_BY_OBJ,ERR_R_MALLOC_FAILURE); | ||
217 | return(NULL); | ||
218 | } | ||
219 | } | ||
220 | else | ||
221 | ret= *attr; | ||
222 | |||
223 | if (!X509_ATTRIBUTE_set1_object(ret,obj)) | ||
224 | goto err; | ||
225 | if (!X509_ATTRIBUTE_set1_data(ret,atrtype,data,len)) | ||
226 | goto err; | ||
227 | |||
228 | if ((attr != NULL) && (*attr == NULL)) *attr=ret; | ||
229 | return(ret); | ||
230 | err: | ||
231 | if ((attr == NULL) || (ret != *attr)) | ||
232 | X509_ATTRIBUTE_free(ret); | ||
233 | return(NULL); | ||
234 | } | ||
235 | |||
236 | X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_txt(X509_ATTRIBUTE **attr, | ||
237 | char *atrname, int type, unsigned char *bytes, int len) | ||
238 | { | ||
239 | ASN1_OBJECT *obj; | ||
240 | X509_ATTRIBUTE *nattr; | ||
241 | |||
242 | obj=OBJ_txt2obj(atrname, 0); | ||
243 | if (obj == NULL) | ||
244 | { | ||
245 | X509err(X509_F_X509_ATTRIBUTE_CREATE_BY_TXT, | ||
246 | X509_R_INVALID_FIELD_NAME); | ||
247 | ERR_add_error_data(2, "name=", atrname); | ||
248 | return(NULL); | ||
249 | } | ||
250 | nattr = X509_ATTRIBUTE_create_by_OBJ(attr,obj,type,bytes,len); | ||
251 | ASN1_OBJECT_free(obj); | ||
252 | return nattr; | ||
253 | } | ||
254 | |||
255 | int X509_ATTRIBUTE_set1_object(X509_ATTRIBUTE *attr, ASN1_OBJECT *obj) | ||
256 | { | ||
257 | if ((attr == NULL) || (obj == NULL)) | ||
258 | return(0); | ||
259 | ASN1_OBJECT_free(attr->object); | ||
260 | attr->object=OBJ_dup(obj); | ||
261 | return(1); | ||
262 | } | ||
263 | |||
264 | int X509_ATTRIBUTE_set1_data(X509_ATTRIBUTE *attr, int attrtype, void *data, int len) | ||
265 | { | ||
266 | ASN1_TYPE *ttmp; | ||
267 | ASN1_STRING *stmp; | ||
268 | int atype; | ||
269 | if (!attr) return 0; | ||
270 | if(attrtype & MBSTRING_FLAG) { | ||
271 | stmp = ASN1_STRING_set_by_NID(NULL, data, len, attrtype, | ||
272 | OBJ_obj2nid(attr->object)); | ||
273 | if(!stmp) { | ||
274 | X509err(X509_F_X509_ATTRIBUTE_SET1_DATA, ERR_R_ASN1_LIB); | ||
275 | return 0; | ||
276 | } | ||
277 | atype = stmp->type; | ||
278 | } else { | ||
279 | if(!(stmp = ASN1_STRING_type_new(attrtype))) goto err; | ||
280 | if(!ASN1_STRING_set(stmp, data, len)) goto err; | ||
281 | atype = attrtype; | ||
282 | } | ||
283 | if(!(attr->value.set = sk_ASN1_TYPE_new_null())) goto err; | ||
284 | if(!(ttmp = ASN1_TYPE_new())) goto err; | ||
285 | if(!sk_ASN1_TYPE_push(attr->value.set, ttmp)) goto err; | ||
286 | attr->set = 1; | ||
287 | ASN1_TYPE_set(ttmp, atype, stmp); | ||
288 | return 1; | ||
289 | err: | ||
290 | X509err(X509_F_X509_ATTRIBUTE_SET1_DATA, ERR_R_MALLOC_FAILURE); | ||
291 | return 0; | ||
292 | } | ||
293 | |||
294 | int X509_ATTRIBUTE_count(X509_ATTRIBUTE *attr) | ||
295 | { | ||
296 | if(attr->set) return sk_ASN1_TYPE_num(attr->value.set); | ||
297 | if(attr->value.single) return 1; | ||
298 | return 0; | ||
299 | } | ||
300 | |||
301 | ASN1_OBJECT *X509_ATTRIBUTE_get0_object(X509_ATTRIBUTE *attr) | ||
302 | { | ||
303 | if (attr == NULL) return(NULL); | ||
304 | return(attr->object); | ||
305 | } | ||
306 | |||
307 | void *X509_ATTRIBUTE_get0_data(X509_ATTRIBUTE *attr, int idx, | ||
308 | int atrtype, void *data) | ||
309 | { | ||
310 | ASN1_TYPE *ttmp; | ||
311 | ttmp = X509_ATTRIBUTE_get0_type(attr, idx); | ||
312 | if(!ttmp) return NULL; | ||
313 | if(atrtype != ASN1_TYPE_get(ttmp)){ | ||
314 | X509err(X509_F_X509_ATTRIBUTE_GET0_DATA, X509_R_WRONG_TYPE); | ||
315 | return NULL; | ||
316 | } | ||
317 | return ttmp->value.ptr; | ||
318 | } | ||
319 | |||
320 | ASN1_TYPE *X509_ATTRIBUTE_get0_type(X509_ATTRIBUTE *attr, int idx) | ||
321 | { | ||
322 | if (attr == NULL) return(NULL); | ||
323 | if(idx >= X509_ATTRIBUTE_count(attr)) return NULL; | ||
324 | if(attr->set) return sk_ASN1_TYPE_value(attr->value.set, idx); | ||
325 | else return attr->value.single; | ||
326 | } | ||
diff --git a/src/lib/libcrypto/x509/x509_trs.c b/src/lib/libcrypto/x509/x509_trs.c new file mode 100644 index 0000000000..9f7d67952d --- /dev/null +++ b/src/lib/libcrypto/x509/x509_trs.c | |||
@@ -0,0 +1,263 @@ | |||
1 | /* x509_trs.c */ | ||
2 | /* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL | ||
3 | * project 1999. | ||
4 | */ | ||
5 | /* ==================================================================== | ||
6 | * Copyright (c) 1999 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 | #include "cryptlib.h" | ||
61 | #include <openssl/x509v3.h> | ||
62 | |||
63 | |||
64 | static int tr_cmp(X509_TRUST **a, X509_TRUST **b); | ||
65 | static void trtable_free(X509_TRUST *p); | ||
66 | |||
67 | static int trust_1oidany(X509_TRUST *trust, X509 *x, int flags); | ||
68 | static int trust_any(X509_TRUST *trust, X509 *x, int flags); | ||
69 | |||
70 | static int obj_trust(int id, X509 *x, int flags); | ||
71 | static int (*default_trust)(int id, X509 *x, int flags) = obj_trust; | ||
72 | |||
73 | /* WARNING: the following table should be kept in order of trust | ||
74 | * and without any gaps so we can just subtract the minimum trust | ||
75 | * value to get an index into the table | ||
76 | */ | ||
77 | |||
78 | static X509_TRUST trstandard[] = { | ||
79 | {X509_TRUST_ANY, 0, trust_any, "Any", 0, NULL}, | ||
80 | {X509_TRUST_SSL_CLIENT, 0, trust_1oidany, "SSL Client", NID_client_auth, NULL}, | ||
81 | {X509_TRUST_SSL_SERVER, 0, trust_1oidany, "SSL Client", NID_server_auth, NULL}, | ||
82 | {X509_TRUST_EMAIL, 0, trust_1oidany, "S/MIME email", NID_email_protect, NULL}, | ||
83 | }; | ||
84 | |||
85 | #define X509_TRUST_COUNT (sizeof(trstandard)/sizeof(X509_TRUST)) | ||
86 | |||
87 | IMPLEMENT_STACK_OF(X509_TRUST) | ||
88 | |||
89 | static STACK_OF(X509_TRUST) *trtable = NULL; | ||
90 | |||
91 | static int tr_cmp(X509_TRUST **a, X509_TRUST **b) | ||
92 | { | ||
93 | return (*a)->trust - (*b)->trust; | ||
94 | } | ||
95 | |||
96 | int (*X509_TRUST_set_default(int (*trust)(int , X509 *, int)))(int, X509 *, int) | ||
97 | { | ||
98 | int (*oldtrust)(int , X509 *, int); | ||
99 | oldtrust = default_trust; | ||
100 | default_trust = trust; | ||
101 | return oldtrust; | ||
102 | } | ||
103 | |||
104 | |||
105 | int X509_check_trust(X509 *x, int id, int flags) | ||
106 | { | ||
107 | X509_TRUST *pt; | ||
108 | int idx; | ||
109 | if(id == -1) return 1; | ||
110 | if(!(idx = X509_TRUST_get_by_id(id))) | ||
111 | return default_trust(id, x, flags); | ||
112 | pt = X509_TRUST_get0(idx); | ||
113 | return pt->check_trust(pt, x, flags); | ||
114 | } | ||
115 | |||
116 | int X509_TRUST_get_count(void) | ||
117 | { | ||
118 | if(!trtable) return X509_TRUST_COUNT; | ||
119 | return sk_X509_TRUST_num(trtable) + X509_TRUST_COUNT; | ||
120 | } | ||
121 | |||
122 | X509_TRUST * X509_TRUST_get0(int idx) | ||
123 | { | ||
124 | if(idx < 0) return NULL; | ||
125 | if(idx < X509_TRUST_COUNT) return trstandard + idx; | ||
126 | return sk_X509_TRUST_value(trtable, idx - X509_TRUST_COUNT); | ||
127 | } | ||
128 | |||
129 | int X509_TRUST_get_by_id(int id) | ||
130 | { | ||
131 | X509_TRUST tmp; | ||
132 | int idx; | ||
133 | if((id >= X509_TRUST_MIN) && (id <= X509_TRUST_MAX)) | ||
134 | return id - X509_TRUST_MIN; | ||
135 | tmp.trust = id; | ||
136 | if(!trtable) return -1; | ||
137 | idx = sk_X509_TRUST_find(trtable, &tmp); | ||
138 | if(idx == -1) return -1; | ||
139 | return idx + X509_TRUST_COUNT; | ||
140 | } | ||
141 | |||
142 | int X509_TRUST_add(int id, int flags, int (*ck)(X509_TRUST *, X509 *, int), | ||
143 | char *name, int arg1, void *arg2) | ||
144 | { | ||
145 | int idx; | ||
146 | X509_TRUST *trtmp; | ||
147 | /* This is set according to what we change: application can't set it */ | ||
148 | flags &= ~X509_TRUST_DYNAMIC; | ||
149 | /* This will always be set for application modified trust entries */ | ||
150 | flags |= X509_TRUST_DYNAMIC_NAME; | ||
151 | /* Get existing entry if any */ | ||
152 | idx = X509_TRUST_get_by_id(id); | ||
153 | /* Need a new entry */ | ||
154 | if(idx == -1) { | ||
155 | if(!(trtmp = Malloc(sizeof(X509_TRUST)))) { | ||
156 | X509err(X509_F_X509_TRUST_ADD,ERR_R_MALLOC_FAILURE); | ||
157 | return 0; | ||
158 | } | ||
159 | trtmp->flags = X509_TRUST_DYNAMIC; | ||
160 | } else trtmp = X509_TRUST_get0(idx); | ||
161 | |||
162 | /* Free existing name if dynamic */ | ||
163 | if(trtmp->flags & X509_TRUST_DYNAMIC_NAME) Free(trtmp->name); | ||
164 | /* dup supplied name */ | ||
165 | if(!(trtmp->name = BUF_strdup(name))) { | ||
166 | X509err(X509_F_X509_TRUST_ADD,ERR_R_MALLOC_FAILURE); | ||
167 | return 0; | ||
168 | } | ||
169 | /* Keep the dynamic flag of existing entry */ | ||
170 | trtmp->flags &= X509_TRUST_DYNAMIC; | ||
171 | /* Set all other flags */ | ||
172 | trtmp->flags |= flags; | ||
173 | |||
174 | trtmp->trust = id; | ||
175 | trtmp->check_trust = ck; | ||
176 | trtmp->arg1 = arg1; | ||
177 | trtmp->arg2 = arg2; | ||
178 | |||
179 | /* If its a new entry manage the dynamic table */ | ||
180 | if(idx == -1) { | ||
181 | if(!trtable && !(trtable = sk_X509_TRUST_new(tr_cmp))) { | ||
182 | X509err(X509_F_X509_TRUST_ADD,ERR_R_MALLOC_FAILURE); | ||
183 | return 0; | ||
184 | } | ||
185 | if (!sk_X509_TRUST_push(trtable, trtmp)) { | ||
186 | X509err(X509_F_X509_TRUST_ADD,ERR_R_MALLOC_FAILURE); | ||
187 | return 0; | ||
188 | } | ||
189 | } | ||
190 | return 1; | ||
191 | } | ||
192 | |||
193 | static void trtable_free(X509_TRUST *p) | ||
194 | { | ||
195 | if(!p) return; | ||
196 | if (p->flags & X509_TRUST_DYNAMIC) | ||
197 | { | ||
198 | if (p->flags & X509_TRUST_DYNAMIC_NAME) | ||
199 | Free(p->name); | ||
200 | Free(p); | ||
201 | } | ||
202 | } | ||
203 | |||
204 | void X509_TRUST_cleanup(void) | ||
205 | { | ||
206 | int i; | ||
207 | for(i = 0; i < X509_TRUST_COUNT; i++) trtable_free(trstandard + i); | ||
208 | sk_X509_TRUST_pop_free(trtable, trtable_free); | ||
209 | trtable = NULL; | ||
210 | } | ||
211 | |||
212 | int X509_TRUST_get_flags(X509_TRUST *xp) | ||
213 | { | ||
214 | return xp->flags; | ||
215 | } | ||
216 | |||
217 | char *X509_TRUST_get0_name(X509_TRUST *xp) | ||
218 | { | ||
219 | return xp->name; | ||
220 | } | ||
221 | |||
222 | int X509_TRUST_get_trust(X509_TRUST *xp) | ||
223 | { | ||
224 | return xp->trust; | ||
225 | } | ||
226 | |||
227 | static int trust_1oidany(X509_TRUST *trust, X509 *x, int flags) | ||
228 | { | ||
229 | if(x->aux) return obj_trust(trust->arg1, x, flags); | ||
230 | /* we don't have any trust settings: for compatibility | ||
231 | * we return trusted if it is self signed | ||
232 | */ | ||
233 | X509_check_purpose(x, -1, 0); | ||
234 | if(x->ex_flags & EXFLAG_SS) return X509_TRUST_TRUSTED; | ||
235 | else return X509_TRUST_UNTRUSTED; | ||
236 | } | ||
237 | |||
238 | static int obj_trust(int id, X509 *x, int flags) | ||
239 | { | ||
240 | ASN1_OBJECT *obj; | ||
241 | int i; | ||
242 | X509_CERT_AUX *ax; | ||
243 | ax = x->aux; | ||
244 | if(!ax) return X509_TRUST_UNTRUSTED; | ||
245 | if(ax->reject) { | ||
246 | for(i = 0; i < sk_ASN1_OBJECT_num(ax->reject); i++) { | ||
247 | obj = sk_ASN1_OBJECT_value(ax->reject, i); | ||
248 | if(OBJ_obj2nid(obj) == id) return X509_TRUST_REJECTED; | ||
249 | } | ||
250 | } | ||
251 | if(ax->trust) { | ||
252 | for(i = 0; i < sk_ASN1_OBJECT_num(ax->trust); i++) { | ||
253 | obj = sk_ASN1_OBJECT_value(ax->trust, i); | ||
254 | if(OBJ_obj2nid(obj) == id) return X509_TRUST_TRUSTED; | ||
255 | } | ||
256 | } | ||
257 | return X509_TRUST_UNTRUSTED; | ||
258 | } | ||
259 | |||
260 | static int trust_any(X509_TRUST *trust, X509 *x, int flags) | ||
261 | { | ||
262 | return X509_TRUST_TRUSTED; | ||
263 | } | ||
diff --git a/src/lib/libcrypto/x509/x509cset.c b/src/lib/libcrypto/x509/x509cset.c new file mode 100644 index 0000000000..6cac440ea9 --- /dev/null +++ b/src/lib/libcrypto/x509/x509cset.c | |||
@@ -0,0 +1,169 @@ | |||
1 | /* crypto/x509/x509cset.c */ | ||
2 | /* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL | ||
3 | * project 2001. | ||
4 | */ | ||
5 | /* ==================================================================== | ||
6 | * Copyright (c) 2001 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 | #include "cryptlib.h" | ||
61 | #include <openssl/asn1.h> | ||
62 | #include <openssl/objects.h> | ||
63 | #include <openssl/evp.h> | ||
64 | #include <openssl/x509.h> | ||
65 | |||
66 | int X509_CRL_set_version(X509_CRL *x, long version) | ||
67 | { | ||
68 | if (x == NULL) return(0); | ||
69 | if (x->crl->version == NULL) | ||
70 | { | ||
71 | if ((x->crl->version=M_ASN1_INTEGER_new()) == NULL) | ||
72 | return(0); | ||
73 | } | ||
74 | return(ASN1_INTEGER_set(x->crl->version,version)); | ||
75 | } | ||
76 | |||
77 | int X509_CRL_set_issuer_name(X509_CRL *x, X509_NAME *name) | ||
78 | { | ||
79 | if ((x == NULL) || (x->crl == NULL)) return(0); | ||
80 | return(X509_NAME_set(&x->crl->issuer,name)); | ||
81 | } | ||
82 | |||
83 | |||
84 | int X509_CRL_set_lastUpdate(X509_CRL *x, ASN1_TIME *tm) | ||
85 | { | ||
86 | ASN1_TIME *in; | ||
87 | |||
88 | if (x == NULL) return(0); | ||
89 | in=x->crl->lastUpdate; | ||
90 | if (in != tm) | ||
91 | { | ||
92 | in=M_ASN1_TIME_dup(tm); | ||
93 | if (in != NULL) | ||
94 | { | ||
95 | M_ASN1_TIME_free(x->crl->lastUpdate); | ||
96 | x->crl->lastUpdate=in; | ||
97 | } | ||
98 | } | ||
99 | return(in != NULL); | ||
100 | } | ||
101 | |||
102 | int X509_CRL_set_nextUpdate(X509_CRL *x, ASN1_TIME *tm) | ||
103 | { | ||
104 | ASN1_TIME *in; | ||
105 | |||
106 | if (x == NULL) return(0); | ||
107 | in=x->crl->nextUpdate; | ||
108 | if (in != tm) | ||
109 | { | ||
110 | in=M_ASN1_TIME_dup(tm); | ||
111 | if (in != NULL) | ||
112 | { | ||
113 | M_ASN1_TIME_free(x->crl->nextUpdate); | ||
114 | x->crl->nextUpdate=in; | ||
115 | } | ||
116 | } | ||
117 | return(in != NULL); | ||
118 | } | ||
119 | |||
120 | int X509_CRL_sort(X509_CRL *c) | ||
121 | { | ||
122 | int i; | ||
123 | X509_REVOKED *r; | ||
124 | /* sort the data so it will be written in serial | ||
125 | * number order */ | ||
126 | sk_X509_REVOKED_sort(c->crl->revoked); | ||
127 | for (i=0; i<sk_X509_REVOKED_num(c->crl->revoked); i++) | ||
128 | { | ||
129 | r=sk_X509_REVOKED_value(c->crl->revoked,i); | ||
130 | r->sequence=i; | ||
131 | } | ||
132 | return 1; | ||
133 | } | ||
134 | |||
135 | int X509_REVOKED_set_revocationDate(X509_REVOKED *x, ASN1_TIME *tm) | ||
136 | { | ||
137 | ASN1_TIME *in; | ||
138 | |||
139 | if (x == NULL) return(0); | ||
140 | in=x->revocationDate; | ||
141 | if (in != tm) | ||
142 | { | ||
143 | in=M_ASN1_TIME_dup(tm); | ||
144 | if (in != NULL) | ||
145 | { | ||
146 | M_ASN1_TIME_free(x->revocationDate); | ||
147 | x->revocationDate=in; | ||
148 | } | ||
149 | } | ||
150 | return(in != NULL); | ||
151 | } | ||
152 | |||
153 | int X509_REVOKED_set_serialNumber(X509_REVOKED *x, ASN1_INTEGER *serial) | ||
154 | { | ||
155 | ASN1_INTEGER *in; | ||
156 | |||
157 | if (x == NULL) return(0); | ||
158 | in=x->serialNumber; | ||
159 | if (in != serial) | ||
160 | { | ||
161 | in=M_ASN1_INTEGER_dup(serial); | ||
162 | if (in != NULL) | ||
163 | { | ||
164 | M_ASN1_INTEGER_free(x->serialNumber); | ||
165 | x->serialNumber=in; | ||
166 | } | ||
167 | } | ||
168 | return(in != NULL); | ||
169 | } | ||
diff --git a/src/lib/libcrypto/x509/x509spki.c b/src/lib/libcrypto/x509/x509spki.c new file mode 100644 index 0000000000..b35c3f92e7 --- /dev/null +++ b/src/lib/libcrypto/x509/x509spki.c | |||
@@ -0,0 +1,121 @@ | |||
1 | /* x509spki.c */ | ||
2 | /* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL | ||
3 | * project 1999. | ||
4 | */ | ||
5 | /* ==================================================================== | ||
6 | * Copyright (c) 1999 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 | #include "cryptlib.h" | ||
61 | #include <openssl/x509.h> | ||
62 | #include <openssl/asn1_mac.h> | ||
63 | |||
64 | int NETSCAPE_SPKI_set_pubkey(NETSCAPE_SPKI *x, EVP_PKEY *pkey) | ||
65 | { | ||
66 | if ((x == NULL) || (x->spkac == NULL)) return(0); | ||
67 | return(X509_PUBKEY_set(&(x->spkac->pubkey),pkey)); | ||
68 | } | ||
69 | |||
70 | EVP_PKEY *NETSCAPE_SPKI_get_pubkey(NETSCAPE_SPKI *x) | ||
71 | { | ||
72 | if ((x == NULL) || (x->spkac == NULL)) | ||
73 | return(NULL); | ||
74 | return(X509_PUBKEY_get(x->spkac->pubkey)); | ||
75 | } | ||
76 | |||
77 | /* Load a Netscape SPKI from a base64 encoded string */ | ||
78 | |||
79 | NETSCAPE_SPKI * NETSCAPE_SPKI_b64_decode(const char *str, int len) | ||
80 | { | ||
81 | unsigned char *spki_der, *p; | ||
82 | int spki_len; | ||
83 | NETSCAPE_SPKI *spki; | ||
84 | if(len <= 0) len = strlen(str); | ||
85 | if (!(spki_der = Malloc(len + 1))) { | ||
86 | X509err(X509_F_NETSCAPE_SPKI_B64_DECODE, ERR_R_MALLOC_FAILURE); | ||
87 | return NULL; | ||
88 | } | ||
89 | spki_len = EVP_DecodeBlock(spki_der, (const unsigned char *)str, len); | ||
90 | if(spki_len < 0) { | ||
91 | X509err(X509_F_NETSCAPE_SPKI_B64_DECODE, | ||
92 | X509_R_BASE64_DECODE_ERROR); | ||
93 | Free(spki_der); | ||
94 | return NULL; | ||
95 | } | ||
96 | p = spki_der; | ||
97 | spki = d2i_NETSCAPE_SPKI(NULL, &p, spki_len); | ||
98 | Free(spki_der); | ||
99 | return spki; | ||
100 | } | ||
101 | |||
102 | /* Generate a base64 encoded string from an SPKI */ | ||
103 | |||
104 | char * NETSCAPE_SPKI_b64_encode(NETSCAPE_SPKI *spki) | ||
105 | { | ||
106 | unsigned char *der_spki, *p; | ||
107 | char *b64_str; | ||
108 | int der_len; | ||
109 | der_len = i2d_NETSCAPE_SPKI(spki, NULL); | ||
110 | der_spki = Malloc(der_len); | ||
111 | b64_str = Malloc(der_len * 2); | ||
112 | if(!der_spki || !b64_str) { | ||
113 | X509err(X509_F_NETSCAPE_SPKI_B64_ENCODE, ERR_R_MALLOC_FAILURE); | ||
114 | return NULL; | ||
115 | } | ||
116 | p = der_spki; | ||
117 | i2d_NETSCAPE_SPKI(spki, &p); | ||
118 | EVP_EncodeBlock((unsigned char *)b64_str, der_spki, der_len); | ||
119 | Free(der_spki); | ||
120 | return b64_str; | ||
121 | } | ||
diff --git a/src/lib/libcrypto/x509v3/ext_dat.h b/src/lib/libcrypto/x509v3/ext_dat.h new file mode 100644 index 0000000000..801a585a52 --- /dev/null +++ b/src/lib/libcrypto/x509v3/ext_dat.h | |||
@@ -0,0 +1,97 @@ | |||
1 | /* ext_dat.h */ | ||
2 | /* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL | ||
3 | * project 1999. | ||
4 | */ | ||
5 | /* ==================================================================== | ||
6 | * Copyright (c) 1999 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 | /* This file contains a table of "standard" extensions */ | ||
59 | |||
60 | extern X509V3_EXT_METHOD v3_bcons, v3_nscert, v3_key_usage, v3_ext_ku; | ||
61 | extern X509V3_EXT_METHOD v3_pkey_usage_period, v3_sxnet, v3_info; | ||
62 | extern X509V3_EXT_METHOD v3_ns_ia5_list[], v3_alt[], v3_skey_id, v3_akey_id; | ||
63 | extern X509V3_EXT_METHOD v3_crl_num, v3_crl_reason, v3_cpols, v3_crld; | ||
64 | |||
65 | /* This table will be searched using OBJ_bsearch so it *must* kept in | ||
66 | * order of the ext_nid values. | ||
67 | */ | ||
68 | |||
69 | static X509V3_EXT_METHOD *standard_exts[] = { | ||
70 | &v3_nscert, | ||
71 | &v3_ns_ia5_list[0], | ||
72 | &v3_ns_ia5_list[1], | ||
73 | &v3_ns_ia5_list[2], | ||
74 | &v3_ns_ia5_list[3], | ||
75 | &v3_ns_ia5_list[4], | ||
76 | &v3_ns_ia5_list[5], | ||
77 | &v3_ns_ia5_list[6], | ||
78 | &v3_skey_id, | ||
79 | &v3_key_usage, | ||
80 | &v3_pkey_usage_period, | ||
81 | &v3_alt[0], | ||
82 | &v3_alt[1], | ||
83 | &v3_bcons, | ||
84 | &v3_crl_num, | ||
85 | &v3_cpols, | ||
86 | &v3_akey_id, | ||
87 | &v3_crld, | ||
88 | &v3_ext_ku, | ||
89 | &v3_crl_reason, | ||
90 | &v3_sxnet, | ||
91 | &v3_info, | ||
92 | }; | ||
93 | |||
94 | /* Number of standard extensions */ | ||
95 | |||
96 | #define STANDARD_EXTENSION_COUNT (sizeof(standard_exts)/sizeof(X509V3_EXT_METHOD *)) | ||
97 | |||
diff --git a/src/lib/libcrypto/x509v3/v3_akey.c b/src/lib/libcrypto/x509v3/v3_akey.c new file mode 100644 index 0000000000..4099e6019e --- /dev/null +++ b/src/lib/libcrypto/x509v3/v3_akey.c | |||
@@ -0,0 +1,249 @@ | |||
1 | /* v3_akey.c */ | ||
2 | /* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL | ||
3 | * project 1999. | ||
4 | */ | ||
5 | /* ==================================================================== | ||
6 | * Copyright (c) 1999 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 | #include "cryptlib.h" | ||
61 | #include <openssl/conf.h> | ||
62 | #include <openssl/asn1.h> | ||
63 | #include <openssl/asn1_mac.h> | ||
64 | #include <openssl/x509v3.h> | ||
65 | |||
66 | static STACK_OF(CONF_VALUE) *i2v_AUTHORITY_KEYID(X509V3_EXT_METHOD *method, | ||
67 | AUTHORITY_KEYID *akeyid, STACK_OF(CONF_VALUE) *extlist); | ||
68 | static AUTHORITY_KEYID *v2i_AUTHORITY_KEYID(X509V3_EXT_METHOD *method, | ||
69 | X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *values); | ||
70 | |||
71 | X509V3_EXT_METHOD v3_akey_id = { | ||
72 | NID_authority_key_identifier, X509V3_EXT_MULTILINE, | ||
73 | (X509V3_EXT_NEW)AUTHORITY_KEYID_new, | ||
74 | (X509V3_EXT_FREE)AUTHORITY_KEYID_free, | ||
75 | (X509V3_EXT_D2I)d2i_AUTHORITY_KEYID, | ||
76 | (X509V3_EXT_I2D)i2d_AUTHORITY_KEYID, | ||
77 | NULL, NULL, | ||
78 | (X509V3_EXT_I2V)i2v_AUTHORITY_KEYID, | ||
79 | (X509V3_EXT_V2I)v2i_AUTHORITY_KEYID, | ||
80 | NULL,NULL, | ||
81 | NULL | ||
82 | }; | ||
83 | |||
84 | |||
85 | int i2d_AUTHORITY_KEYID(AUTHORITY_KEYID *a, unsigned char **pp) | ||
86 | { | ||
87 | M_ASN1_I2D_vars(a); | ||
88 | |||
89 | M_ASN1_I2D_len_IMP_opt (a->keyid, i2d_ASN1_OCTET_STRING); | ||
90 | M_ASN1_I2D_len_IMP_opt (a->issuer, i2d_GENERAL_NAMES); | ||
91 | M_ASN1_I2D_len_IMP_opt (a->serial, i2d_ASN1_INTEGER); | ||
92 | |||
93 | M_ASN1_I2D_seq_total(); | ||
94 | |||
95 | M_ASN1_I2D_put_IMP_opt (a->keyid, i2d_ASN1_OCTET_STRING, 0); | ||
96 | M_ASN1_I2D_put_IMP_opt (a->issuer, i2d_GENERAL_NAMES, 1); | ||
97 | M_ASN1_I2D_put_IMP_opt (a->serial, i2d_ASN1_INTEGER, 2); | ||
98 | |||
99 | M_ASN1_I2D_finish(); | ||
100 | } | ||
101 | |||
102 | AUTHORITY_KEYID *AUTHORITY_KEYID_new(void) | ||
103 | { | ||
104 | AUTHORITY_KEYID *ret=NULL; | ||
105 | ASN1_CTX c; | ||
106 | M_ASN1_New_Malloc(ret, AUTHORITY_KEYID); | ||
107 | ret->keyid = NULL; | ||
108 | ret->issuer = NULL; | ||
109 | ret->serial = NULL; | ||
110 | return (ret); | ||
111 | M_ASN1_New_Error(ASN1_F_AUTHORITY_KEYID_NEW); | ||
112 | } | ||
113 | |||
114 | AUTHORITY_KEYID *d2i_AUTHORITY_KEYID(AUTHORITY_KEYID **a, unsigned char **pp, | ||
115 | long length) | ||
116 | { | ||
117 | M_ASN1_D2I_vars(a,AUTHORITY_KEYID *,AUTHORITY_KEYID_new); | ||
118 | M_ASN1_D2I_Init(); | ||
119 | M_ASN1_D2I_start_sequence(); | ||
120 | M_ASN1_D2I_get_IMP_opt (ret->keyid, d2i_ASN1_OCTET_STRING, 0, | ||
121 | V_ASN1_OCTET_STRING); | ||
122 | M_ASN1_D2I_get_IMP_opt (ret->issuer, d2i_GENERAL_NAMES, 1, | ||
123 | V_ASN1_SEQUENCE); | ||
124 | M_ASN1_D2I_get_IMP_opt (ret->serial, d2i_ASN1_INTEGER, 2, | ||
125 | V_ASN1_INTEGER); | ||
126 | M_ASN1_D2I_Finish(a, AUTHORITY_KEYID_free, ASN1_F_D2I_AUTHORITY_KEYID); | ||
127 | } | ||
128 | |||
129 | void AUTHORITY_KEYID_free(AUTHORITY_KEYID *a) | ||
130 | { | ||
131 | if (a == NULL) return; | ||
132 | ASN1_OCTET_STRING_free(a->keyid); | ||
133 | sk_GENERAL_NAME_pop_free(a->issuer, GENERAL_NAME_free); | ||
134 | ASN1_INTEGER_free (a->serial); | ||
135 | Free ((char *)a); | ||
136 | } | ||
137 | |||
138 | static STACK_OF(CONF_VALUE) *i2v_AUTHORITY_KEYID(X509V3_EXT_METHOD *method, | ||
139 | AUTHORITY_KEYID *akeyid, STACK_OF(CONF_VALUE) *extlist) | ||
140 | { | ||
141 | char *tmp; | ||
142 | if(akeyid->keyid) { | ||
143 | tmp = hex_to_string(akeyid->keyid->data, akeyid->keyid->length); | ||
144 | X509V3_add_value("keyid", tmp, &extlist); | ||
145 | Free(tmp); | ||
146 | } | ||
147 | if(akeyid->issuer) | ||
148 | extlist = i2v_GENERAL_NAMES(NULL, akeyid->issuer, extlist); | ||
149 | if(akeyid->serial) { | ||
150 | tmp = hex_to_string(akeyid->serial->data, | ||
151 | akeyid->serial->length); | ||
152 | X509V3_add_value("serial", tmp, &extlist); | ||
153 | Free(tmp); | ||
154 | } | ||
155 | return extlist; | ||
156 | } | ||
157 | |||
158 | /* Currently two options: | ||
159 | * keyid: use the issuers subject keyid, the value 'always' means its is | ||
160 | * an error if the issuer certificate doesn't have a key id. | ||
161 | * issuer: use the issuers cert issuer and serial number. The default is | ||
162 | * to only use this if keyid is not present. With the option 'always' | ||
163 | * this is always included. | ||
164 | */ | ||
165 | |||
166 | static AUTHORITY_KEYID *v2i_AUTHORITY_KEYID(X509V3_EXT_METHOD *method, | ||
167 | X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *values) | ||
168 | { | ||
169 | char keyid=0, issuer=0; | ||
170 | int i; | ||
171 | CONF_VALUE *cnf; | ||
172 | ASN1_OCTET_STRING *ikeyid = NULL; | ||
173 | X509_NAME *isname = NULL; | ||
174 | STACK_OF(GENERAL_NAME) * gens = NULL; | ||
175 | GENERAL_NAME *gen = NULL; | ||
176 | ASN1_INTEGER *serial = NULL; | ||
177 | X509_EXTENSION *ext; | ||
178 | X509 *cert; | ||
179 | AUTHORITY_KEYID *akeyid; | ||
180 | for(i = 0; i < sk_CONF_VALUE_num(values); i++) { | ||
181 | cnf = sk_CONF_VALUE_value(values, i); | ||
182 | if(!strcmp(cnf->name, "keyid")) { | ||
183 | keyid = 1; | ||
184 | if(cnf->value && !strcmp(cnf->value, "always")) keyid = 2; | ||
185 | } else if(!strcmp(cnf->name, "issuer")) { | ||
186 | issuer = 1; | ||
187 | if(cnf->value && !strcmp(cnf->value, "always")) issuer = 2; | ||
188 | } else { | ||
189 | X509V3err(X509V3_F_V2I_AUTHORITY_KEYID,X509V3_R_UNKNOWN_OPTION); | ||
190 | ERR_add_error_data(2, "name=", cnf->name); | ||
191 | return NULL; | ||
192 | } | ||
193 | } | ||
194 | |||
195 | |||
196 | |||
197 | if(!ctx || !ctx->issuer_cert) { | ||
198 | if(ctx && (ctx->flags==CTX_TEST)) return AUTHORITY_KEYID_new(); | ||
199 | X509V3err(X509V3_F_V2I_AUTHORITY_KEYID,X509V3_R_NO_ISSUER_CERTIFICATE); | ||
200 | return NULL; | ||
201 | } | ||
202 | |||
203 | cert = ctx->issuer_cert; | ||
204 | |||
205 | if(keyid) { | ||
206 | i = X509_get_ext_by_NID(cert, NID_subject_key_identifier, -1); | ||
207 | if((i >= 0) && (ext = X509_get_ext(cert, i))) | ||
208 | ikeyid = X509V3_EXT_d2i(ext); | ||
209 | if(keyid==2 && !ikeyid) { | ||
210 | X509V3err(X509V3_F_V2I_AUTHORITY_KEYID,X509V3_R_UNABLE_TO_GET_ISSUER_KEYID); | ||
211 | return NULL; | ||
212 | } | ||
213 | } | ||
214 | |||
215 | if((issuer && !ikeyid) || (issuer == 2)) { | ||
216 | isname = X509_NAME_dup(X509_get_issuer_name(cert)); | ||
217 | serial = ASN1_INTEGER_dup(X509_get_serialNumber(cert)); | ||
218 | if(!isname || !serial) { | ||
219 | X509V3err(X509V3_F_V2I_AUTHORITY_KEYID,X509V3_R_UNABLE_TO_GET_ISSUER_DETAILS); | ||
220 | goto err; | ||
221 | } | ||
222 | } | ||
223 | |||
224 | if(!(akeyid = AUTHORITY_KEYID_new())) goto err; | ||
225 | |||
226 | if(isname) { | ||
227 | if(!(gens = sk_GENERAL_NAME_new(NULL)) || !(gen = GENERAL_NAME_new()) | ||
228 | || !sk_GENERAL_NAME_push(gens, gen)) { | ||
229 | X509V3err(X509V3_F_V2I_AUTHORITY_KEYID,ERR_R_MALLOC_FAILURE); | ||
230 | goto err; | ||
231 | } | ||
232 | gen->type = GEN_DIRNAME; | ||
233 | gen->d.dirn = isname; | ||
234 | } | ||
235 | |||
236 | akeyid->issuer = gens; | ||
237 | akeyid->serial = serial; | ||
238 | akeyid->keyid = ikeyid; | ||
239 | |||
240 | return akeyid; | ||
241 | |||
242 | err: | ||
243 | X509_NAME_free(isname); | ||
244 | ASN1_INTEGER_free(serial); | ||
245 | ASN1_OCTET_STRING_free(ikeyid); | ||
246 | return NULL; | ||
247 | |||
248 | } | ||
249 | |||
diff --git a/src/lib/libcrypto/x509v3/v3_akeya.c b/src/lib/libcrypto/x509v3/v3_akeya.c new file mode 100644 index 0000000000..2aafa26ba7 --- /dev/null +++ b/src/lib/libcrypto/x509v3/v3_akeya.c | |||
@@ -0,0 +1,72 @@ | |||
1 | /* v3_akey_asn1.c */ | ||
2 | /* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL | ||
3 | * project 1999. | ||
4 | */ | ||
5 | /* ==================================================================== | ||
6 | * Copyright (c) 1999 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 | #include "cryptlib.h" | ||
61 | #include <openssl/conf.h> | ||
62 | #include <openssl/asn1.h> | ||
63 | #include <openssl/asn1t.h> | ||
64 | #include <openssl/x509v3.h> | ||
65 | |||
66 | ASN1_SEQUENCE(AUTHORITY_KEYID) = { | ||
67 | ASN1_IMP_OPT(AUTHORITY_KEYID, keyid, ASN1_OCTET_STRING, 0), | ||
68 | ASN1_IMP_SEQUENCE_OF_OPT(AUTHORITY_KEYID, issuer, GENERAL_NAME, 1), | ||
69 | ASN1_IMP_OPT(AUTHORITY_KEYID, serial, ASN1_INTEGER, 2) | ||
70 | } ASN1_SEQUENCE_END(AUTHORITY_KEYID) | ||
71 | |||
72 | IMPLEMENT_ASN1_FUNCTIONS(AUTHORITY_KEYID) | ||
diff --git a/src/lib/libcrypto/x509v3/v3_alt.c b/src/lib/libcrypto/x509v3/v3_alt.c new file mode 100644 index 0000000000..b5e1f8af96 --- /dev/null +++ b/src/lib/libcrypto/x509v3/v3_alt.c | |||
@@ -0,0 +1,402 @@ | |||
1 | /* v3_alt.c */ | ||
2 | /* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL | ||
3 | * project 1999. | ||
4 | */ | ||
5 | /* ==================================================================== | ||
6 | * Copyright (c) 1999 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 | #include "cryptlib.h" | ||
61 | #include <openssl/conf.h> | ||
62 | #include <openssl/x509v3.h> | ||
63 | |||
64 | static STACK_OF(GENERAL_NAME) *v2i_subject_alt(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval); | ||
65 | static STACK_OF(GENERAL_NAME) *v2i_issuer_alt(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval); | ||
66 | static int copy_email(X509V3_CTX *ctx, STACK_OF(GENERAL_NAME) *gens); | ||
67 | static int copy_issuer(X509V3_CTX *ctx, STACK_OF(GENERAL_NAME) *gens); | ||
68 | X509V3_EXT_METHOD v3_alt[] = { | ||
69 | { NID_subject_alt_name, 0, | ||
70 | (X509V3_EXT_NEW)GENERAL_NAMES_new, | ||
71 | (X509V3_EXT_FREE)GENERAL_NAMES_free, | ||
72 | (X509V3_EXT_D2I)d2i_GENERAL_NAMES, | ||
73 | (X509V3_EXT_I2D)i2d_GENERAL_NAMES, | ||
74 | NULL, NULL, | ||
75 | (X509V3_EXT_I2V)i2v_GENERAL_NAMES, | ||
76 | (X509V3_EXT_V2I)v2i_subject_alt, | ||
77 | NULL, NULL, NULL}, | ||
78 | { NID_issuer_alt_name, 0, | ||
79 | (X509V3_EXT_NEW)GENERAL_NAMES_new, | ||
80 | (X509V3_EXT_FREE)GENERAL_NAMES_free, | ||
81 | (X509V3_EXT_D2I)d2i_GENERAL_NAMES, | ||
82 | (X509V3_EXT_I2D)i2d_GENERAL_NAMES, | ||
83 | NULL, NULL, | ||
84 | (X509V3_EXT_I2V)i2v_GENERAL_NAMES, | ||
85 | (X509V3_EXT_V2I)v2i_issuer_alt, | ||
86 | NULL, NULL, NULL}, | ||
87 | EXT_END | ||
88 | }; | ||
89 | |||
90 | STACK_OF(CONF_VALUE) *i2v_GENERAL_NAMES(X509V3_EXT_METHOD *method, | ||
91 | STACK_OF(GENERAL_NAME) *gens, STACK_OF(CONF_VALUE) *ret) | ||
92 | { | ||
93 | int i; | ||
94 | GENERAL_NAME *gen; | ||
95 | for(i = 0; i < sk_GENERAL_NAME_num(gens); i++) { | ||
96 | gen = sk_GENERAL_NAME_value(gens, i); | ||
97 | ret = i2v_GENERAL_NAME(method, gen, ret); | ||
98 | } | ||
99 | if(!ret) return sk_CONF_VALUE_new_null(); | ||
100 | return ret; | ||
101 | } | ||
102 | |||
103 | STACK_OF(CONF_VALUE) *i2v_GENERAL_NAME(X509V3_EXT_METHOD *method, | ||
104 | GENERAL_NAME *gen, STACK_OF(CONF_VALUE) *ret) | ||
105 | { | ||
106 | char oline[256]; | ||
107 | unsigned char *p; | ||
108 | switch (gen->type) | ||
109 | { | ||
110 | case GEN_OTHERNAME: | ||
111 | X509V3_add_value("othername","<unsupported>", &ret); | ||
112 | break; | ||
113 | |||
114 | case GEN_X400: | ||
115 | X509V3_add_value("X400Name","<unsupported>", &ret); | ||
116 | break; | ||
117 | |||
118 | case GEN_EDIPARTY: | ||
119 | X509V3_add_value("EdiPartyName","<unsupported>", &ret); | ||
120 | break; | ||
121 | |||
122 | case GEN_EMAIL: | ||
123 | X509V3_add_value_uchar("email",gen->d.ia5->data, &ret); | ||
124 | break; | ||
125 | |||
126 | case GEN_DNS: | ||
127 | X509V3_add_value_uchar("DNS",gen->d.ia5->data, &ret); | ||
128 | break; | ||
129 | |||
130 | case GEN_URI: | ||
131 | X509V3_add_value_uchar("URI",gen->d.ia5->data, &ret); | ||
132 | break; | ||
133 | |||
134 | case GEN_DIRNAME: | ||
135 | X509_NAME_oneline(gen->d.dirn, oline, 256); | ||
136 | X509V3_add_value("DirName",oline, &ret); | ||
137 | break; | ||
138 | |||
139 | case GEN_IPADD: | ||
140 | p = gen->d.ip->data; | ||
141 | /* BUG: doesn't support IPV6 */ | ||
142 | if(gen->d.ip->length != 4) { | ||
143 | X509V3_add_value("IP Address","<invalid>", &ret); | ||
144 | break; | ||
145 | } | ||
146 | sprintf(oline, "%d.%d.%d.%d", p[0], p[1], p[2], p[3]); | ||
147 | X509V3_add_value("IP Address",oline, &ret); | ||
148 | break; | ||
149 | |||
150 | case GEN_RID: | ||
151 | i2t_ASN1_OBJECT(oline, 256, gen->d.rid); | ||
152 | X509V3_add_value("Registered ID",oline, &ret); | ||
153 | break; | ||
154 | } | ||
155 | return ret; | ||
156 | } | ||
157 | |||
158 | static STACK_OF(GENERAL_NAME) *v2i_issuer_alt(X509V3_EXT_METHOD *method, | ||
159 | X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval) | ||
160 | { | ||
161 | STACK_OF(GENERAL_NAME) *gens = NULL; | ||
162 | CONF_VALUE *cnf; | ||
163 | int i; | ||
164 | if(!(gens = sk_GENERAL_NAME_new(NULL))) { | ||
165 | X509V3err(X509V3_F_V2I_GENERAL_NAMES,ERR_R_MALLOC_FAILURE); | ||
166 | return NULL; | ||
167 | } | ||
168 | for(i = 0; i < sk_CONF_VALUE_num(nval); i++) { | ||
169 | cnf = sk_CONF_VALUE_value(nval, i); | ||
170 | if(!name_cmp(cnf->name, "issuer") && cnf->value && | ||
171 | !strcmp(cnf->value, "copy")) { | ||
172 | if(!copy_issuer(ctx, gens)) goto err; | ||
173 | } else { | ||
174 | GENERAL_NAME *gen; | ||
175 | if(!(gen = v2i_GENERAL_NAME(method, ctx, cnf))) | ||
176 | goto err; | ||
177 | sk_GENERAL_NAME_push(gens, gen); | ||
178 | } | ||
179 | } | ||
180 | return gens; | ||
181 | err: | ||
182 | sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free); | ||
183 | return NULL; | ||
184 | } | ||
185 | |||
186 | /* Append subject altname of issuer to issuer alt name of subject */ | ||
187 | |||
188 | static int copy_issuer(X509V3_CTX *ctx, STACK_OF(GENERAL_NAME) *gens) | ||
189 | { | ||
190 | STACK_OF(GENERAL_NAME) *ialt; | ||
191 | GENERAL_NAME *gen; | ||
192 | X509_EXTENSION *ext; | ||
193 | int i; | ||
194 | if(ctx && (ctx->flags == CTX_TEST)) return 1; | ||
195 | if(!ctx || !ctx->issuer_cert) { | ||
196 | X509V3err(X509V3_F_COPY_ISSUER,X509V3_R_NO_ISSUER_DETAILS); | ||
197 | goto err; | ||
198 | } | ||
199 | i = X509_get_ext_by_NID(ctx->issuer_cert, NID_subject_alt_name, -1); | ||
200 | if(i < 0) return 1; | ||
201 | if(!(ext = X509_get_ext(ctx->issuer_cert, i)) || | ||
202 | !(ialt = X509V3_EXT_d2i(ext)) ) { | ||
203 | X509V3err(X509V3_F_COPY_ISSUER,X509V3_R_ISSUER_DECODE_ERROR); | ||
204 | goto err; | ||
205 | } | ||
206 | |||
207 | for(i = 0; i < sk_GENERAL_NAME_num(ialt); i++) { | ||
208 | gen = sk_GENERAL_NAME_value(ialt, i); | ||
209 | if(!sk_GENERAL_NAME_push(gens, gen)) { | ||
210 | X509V3err(X509V3_F_COPY_ISSUER,ERR_R_MALLOC_FAILURE); | ||
211 | goto err; | ||
212 | } | ||
213 | } | ||
214 | sk_GENERAL_NAME_free(ialt); | ||
215 | |||
216 | return 1; | ||
217 | |||
218 | err: | ||
219 | return 0; | ||
220 | |||
221 | } | ||
222 | |||
223 | static STACK_OF(GENERAL_NAME) *v2i_subject_alt(X509V3_EXT_METHOD *method, | ||
224 | X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval) | ||
225 | { | ||
226 | STACK_OF(GENERAL_NAME) *gens = NULL; | ||
227 | CONF_VALUE *cnf; | ||
228 | int i; | ||
229 | if(!(gens = sk_GENERAL_NAME_new(NULL))) { | ||
230 | X509V3err(X509V3_F_V2I_GENERAL_NAMES,ERR_R_MALLOC_FAILURE); | ||
231 | return NULL; | ||
232 | } | ||
233 | for(i = 0; i < sk_CONF_VALUE_num(nval); i++) { | ||
234 | cnf = sk_CONF_VALUE_value(nval, i); | ||
235 | if(!name_cmp(cnf->name, "email") && cnf->value && | ||
236 | !strcmp(cnf->value, "copy")) { | ||
237 | if(!copy_email(ctx, gens)) goto err; | ||
238 | } else { | ||
239 | GENERAL_NAME *gen; | ||
240 | if(!(gen = v2i_GENERAL_NAME(method, ctx, cnf))) | ||
241 | goto err; | ||
242 | sk_GENERAL_NAME_push(gens, gen); | ||
243 | } | ||
244 | } | ||
245 | return gens; | ||
246 | err: | ||
247 | sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free); | ||
248 | return NULL; | ||
249 | } | ||
250 | |||
251 | /* Copy any email addresses in a certificate or request to | ||
252 | * GENERAL_NAMES | ||
253 | */ | ||
254 | |||
255 | static int copy_email(X509V3_CTX *ctx, STACK_OF(GENERAL_NAME) *gens) | ||
256 | { | ||
257 | X509_NAME *nm; | ||
258 | ASN1_IA5STRING *email = NULL; | ||
259 | X509_NAME_ENTRY *ne; | ||
260 | GENERAL_NAME *gen = NULL; | ||
261 | int i; | ||
262 | if(ctx->flags == CTX_TEST) return 1; | ||
263 | if(!ctx || (!ctx->subject_cert && !ctx->subject_req)) { | ||
264 | X509V3err(X509V3_F_COPY_EMAIL,X509V3_R_NO_SUBJECT_DETAILS); | ||
265 | goto err; | ||
266 | } | ||
267 | /* Find the subject name */ | ||
268 | if(ctx->subject_cert) nm = X509_get_subject_name(ctx->subject_cert); | ||
269 | else nm = X509_REQ_get_subject_name(ctx->subject_req); | ||
270 | |||
271 | /* Now add any email address(es) to STACK */ | ||
272 | i = -1; | ||
273 | while((i = X509_NAME_get_index_by_NID(nm, | ||
274 | NID_pkcs9_emailAddress, i)) > 0) { | ||
275 | ne = X509_NAME_get_entry(nm, i); | ||
276 | email = ASN1_IA5STRING_dup(X509_NAME_ENTRY_get_data(ne)); | ||
277 | if(!email || !(gen = GENERAL_NAME_new())) { | ||
278 | X509V3err(X509V3_F_COPY_EMAIL,ERR_R_MALLOC_FAILURE); | ||
279 | goto err; | ||
280 | } | ||
281 | gen->d.ia5 = email; | ||
282 | email = NULL; | ||
283 | gen->type = GEN_EMAIL; | ||
284 | if(!sk_GENERAL_NAME_push(gens, gen)) { | ||
285 | X509V3err(X509V3_F_COPY_EMAIL,ERR_R_MALLOC_FAILURE); | ||
286 | goto err; | ||
287 | } | ||
288 | gen = NULL; | ||
289 | } | ||
290 | |||
291 | |||
292 | return 1; | ||
293 | |||
294 | err: | ||
295 | GENERAL_NAME_free(gen); | ||
296 | ASN1_IA5STRING_free(email); | ||
297 | return 0; | ||
298 | |||
299 | } | ||
300 | |||
301 | STACK_OF(GENERAL_NAME) *v2i_GENERAL_NAMES(X509V3_EXT_METHOD *method, | ||
302 | X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval) | ||
303 | { | ||
304 | GENERAL_NAME *gen; | ||
305 | STACK_OF(GENERAL_NAME) *gens = NULL; | ||
306 | CONF_VALUE *cnf; | ||
307 | int i; | ||
308 | if(!(gens = sk_GENERAL_NAME_new(NULL))) { | ||
309 | X509V3err(X509V3_F_V2I_GENERAL_NAMES,ERR_R_MALLOC_FAILURE); | ||
310 | return NULL; | ||
311 | } | ||
312 | for(i = 0; i < sk_CONF_VALUE_num(nval); i++) { | ||
313 | cnf = sk_CONF_VALUE_value(nval, i); | ||
314 | if(!(gen = v2i_GENERAL_NAME(method, ctx, cnf))) goto err; | ||
315 | sk_GENERAL_NAME_push(gens, gen); | ||
316 | } | ||
317 | return gens; | ||
318 | err: | ||
319 | sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free); | ||
320 | return NULL; | ||
321 | } | ||
322 | |||
323 | GENERAL_NAME *v2i_GENERAL_NAME(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, | ||
324 | CONF_VALUE *cnf) | ||
325 | { | ||
326 | char is_string = 0; | ||
327 | int type; | ||
328 | GENERAL_NAME *gen = NULL; | ||
329 | |||
330 | char *name, *value; | ||
331 | |||
332 | name = cnf->name; | ||
333 | value = cnf->value; | ||
334 | |||
335 | if(!value) { | ||
336 | X509V3err(X509V3_F_V2I_GENERAL_NAME,X509V3_R_MISSING_VALUE); | ||
337 | return NULL; | ||
338 | } | ||
339 | |||
340 | if(!(gen = GENERAL_NAME_new())) { | ||
341 | X509V3err(X509V3_F_V2I_GENERAL_NAME,ERR_R_MALLOC_FAILURE); | ||
342 | return NULL; | ||
343 | } | ||
344 | |||
345 | if(!name_cmp(name, "email")) { | ||
346 | is_string = 1; | ||
347 | type = GEN_EMAIL; | ||
348 | } else if(!name_cmp(name, "URI")) { | ||
349 | is_string = 1; | ||
350 | type = GEN_URI; | ||
351 | } else if(!name_cmp(name, "DNS")) { | ||
352 | is_string = 1; | ||
353 | type = GEN_DNS; | ||
354 | } else if(!name_cmp(name, "RID")) { | ||
355 | ASN1_OBJECT *obj; | ||
356 | if(!(obj = OBJ_txt2obj(value,0))) { | ||
357 | X509V3err(X509V3_F_V2I_GENERAL_NAME,X509V3_R_BAD_OBJECT); | ||
358 | ERR_add_error_data(2, "value=", value); | ||
359 | goto err; | ||
360 | } | ||
361 | gen->d.rid = obj; | ||
362 | type = GEN_RID; | ||
363 | } else if(!name_cmp(name, "IP")) { | ||
364 | int i1,i2,i3,i4; | ||
365 | unsigned char ip[4]; | ||
366 | if((sscanf(value, "%d.%d.%d.%d",&i1,&i2,&i3,&i4) != 4) || | ||
367 | (i1 < 0) || (i1 > 255) || (i2 < 0) || (i2 > 255) || | ||
368 | (i3 < 0) || (i3 > 255) || (i4 < 0) || (i4 > 255) ) { | ||
369 | X509V3err(X509V3_F_V2I_GENERAL_NAME,X509V3_R_BAD_IP_ADDRESS); | ||
370 | ERR_add_error_data(2, "value=", value); | ||
371 | goto err; | ||
372 | } | ||
373 | ip[0] = i1; ip[1] = i2 ; ip[2] = i3 ; ip[3] = i4; | ||
374 | if(!(gen->d.ip = ASN1_OCTET_STRING_new()) || | ||
375 | !ASN1_STRING_set(gen->d.ip, ip, 4)) { | ||
376 | X509V3err(X509V3_F_V2I_GENERAL_NAME,ERR_R_MALLOC_FAILURE); | ||
377 | goto err; | ||
378 | } | ||
379 | type = GEN_IPADD; | ||
380 | } else { | ||
381 | X509V3err(X509V3_F_V2I_GENERAL_NAME,X509V3_R_UNSUPPORTED_OPTION); | ||
382 | ERR_add_error_data(2, "name=", name); | ||
383 | goto err; | ||
384 | } | ||
385 | |||
386 | if(is_string) { | ||
387 | if(!(gen->d.ia5 = ASN1_IA5STRING_new()) || | ||
388 | !ASN1_STRING_set(gen->d.ia5, (unsigned char*)value, | ||
389 | strlen(value))) { | ||
390 | X509V3err(X509V3_F_V2I_GENERAL_NAME,ERR_R_MALLOC_FAILURE); | ||
391 | goto err; | ||
392 | } | ||
393 | } | ||
394 | |||
395 | gen->type = type; | ||
396 | |||
397 | return gen; | ||
398 | |||
399 | err: | ||
400 | GENERAL_NAME_free(gen); | ||
401 | return NULL; | ||
402 | } | ||
diff --git a/src/lib/libcrypto/x509v3/v3_bcons.c b/src/lib/libcrypto/x509v3/v3_bcons.c new file mode 100644 index 0000000000..de2f855c35 --- /dev/null +++ b/src/lib/libcrypto/x509v3/v3_bcons.c | |||
@@ -0,0 +1,164 @@ | |||
1 | /* v3_bcons.c */ | ||
2 | /* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL | ||
3 | * project 1999. | ||
4 | */ | ||
5 | /* ==================================================================== | ||
6 | * Copyright (c) 1999 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/asn1_mac.h> | ||
64 | #include <openssl/conf.h> | ||
65 | #include <openssl/x509v3.h> | ||
66 | |||
67 | static STACK_OF(CONF_VALUE) *i2v_BASIC_CONSTRAINTS(X509V3_EXT_METHOD *method, BASIC_CONSTRAINTS *bcons, STACK_OF(CONF_VALUE) *extlist); | ||
68 | static BASIC_CONSTRAINTS *v2i_BASIC_CONSTRAINTS(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *values); | ||
69 | |||
70 | X509V3_EXT_METHOD v3_bcons = { | ||
71 | NID_basic_constraints, 0, | ||
72 | (X509V3_EXT_NEW)BASIC_CONSTRAINTS_new, | ||
73 | (X509V3_EXT_FREE)BASIC_CONSTRAINTS_free, | ||
74 | (X509V3_EXT_D2I)d2i_BASIC_CONSTRAINTS, | ||
75 | (X509V3_EXT_I2D)i2d_BASIC_CONSTRAINTS, | ||
76 | NULL, NULL, | ||
77 | (X509V3_EXT_I2V)i2v_BASIC_CONSTRAINTS, | ||
78 | (X509V3_EXT_V2I)v2i_BASIC_CONSTRAINTS, | ||
79 | NULL,NULL, | ||
80 | NULL | ||
81 | }; | ||
82 | |||
83 | |||
84 | int i2d_BASIC_CONSTRAINTS(BASIC_CONSTRAINTS *a, unsigned char **pp) | ||
85 | { | ||
86 | M_ASN1_I2D_vars(a); | ||
87 | if(a->ca) M_ASN1_I2D_len (a->ca, i2d_ASN1_BOOLEAN); | ||
88 | M_ASN1_I2D_len (a->pathlen, i2d_ASN1_INTEGER); | ||
89 | |||
90 | M_ASN1_I2D_seq_total(); | ||
91 | |||
92 | if (a->ca) M_ASN1_I2D_put (a->ca, i2d_ASN1_BOOLEAN); | ||
93 | M_ASN1_I2D_put (a->pathlen, i2d_ASN1_INTEGER); | ||
94 | M_ASN1_I2D_finish(); | ||
95 | } | ||
96 | |||
97 | BASIC_CONSTRAINTS *BASIC_CONSTRAINTS_new(void) | ||
98 | { | ||
99 | BASIC_CONSTRAINTS *ret=NULL; | ||
100 | ASN1_CTX c; | ||
101 | M_ASN1_New_Malloc(ret, BASIC_CONSTRAINTS); | ||
102 | ret->ca = 0; | ||
103 | ret->pathlen = NULL; | ||
104 | return (ret); | ||
105 | M_ASN1_New_Error(ASN1_F_BASIC_CONSTRAINTS_NEW); | ||
106 | } | ||
107 | |||
108 | BASIC_CONSTRAINTS *d2i_BASIC_CONSTRAINTS(BASIC_CONSTRAINTS **a, | ||
109 | unsigned char **pp, long length) | ||
110 | { | ||
111 | M_ASN1_D2I_vars(a,BASIC_CONSTRAINTS *,BASIC_CONSTRAINTS_new); | ||
112 | M_ASN1_D2I_Init(); | ||
113 | M_ASN1_D2I_start_sequence(); | ||
114 | if((M_ASN1_next & (~V_ASN1_CONSTRUCTED)) == | ||
115 | (V_ASN1_UNIVERSAL|V_ASN1_BOOLEAN) ) { | ||
116 | M_ASN1_D2I_get_int (ret->ca, d2i_ASN1_BOOLEAN); | ||
117 | } | ||
118 | M_ASN1_D2I_get_opt (ret->pathlen, d2i_ASN1_INTEGER, V_ASN1_INTEGER); | ||
119 | M_ASN1_D2I_Finish(a, BASIC_CONSTRAINTS_free, ASN1_F_D2I_BASIC_CONSTRAINTS); | ||
120 | } | ||
121 | |||
122 | void BASIC_CONSTRAINTS_free(BASIC_CONSTRAINTS *a) | ||
123 | { | ||
124 | if (a == NULL) return; | ||
125 | ASN1_INTEGER_free (a->pathlen); | ||
126 | Free ((char *)a); | ||
127 | } | ||
128 | |||
129 | static STACK_OF(CONF_VALUE) *i2v_BASIC_CONSTRAINTS(X509V3_EXT_METHOD *method, | ||
130 | BASIC_CONSTRAINTS *bcons, STACK_OF(CONF_VALUE) *extlist) | ||
131 | { | ||
132 | X509V3_add_value_bool("CA", bcons->ca, &extlist); | ||
133 | X509V3_add_value_int("pathlen", bcons->pathlen, &extlist); | ||
134 | return extlist; | ||
135 | } | ||
136 | |||
137 | static BASIC_CONSTRAINTS *v2i_BASIC_CONSTRAINTS(X509V3_EXT_METHOD *method, | ||
138 | X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *values) | ||
139 | { | ||
140 | BASIC_CONSTRAINTS *bcons=NULL; | ||
141 | CONF_VALUE *val; | ||
142 | int i; | ||
143 | if(!(bcons = BASIC_CONSTRAINTS_new())) { | ||
144 | X509V3err(X509V3_F_V2I_BASIC_CONSTRAINTS, ERR_R_MALLOC_FAILURE); | ||
145 | return NULL; | ||
146 | } | ||
147 | for(i = 0; i < sk_CONF_VALUE_num(values); i++) { | ||
148 | val = sk_CONF_VALUE_value(values, i); | ||
149 | if(!strcmp(val->name, "CA")) { | ||
150 | if(!X509V3_get_value_bool(val, &bcons->ca)) goto err; | ||
151 | } else if(!strcmp(val->name, "pathlen")) { | ||
152 | if(!X509V3_get_value_int(val, &bcons->pathlen)) goto err; | ||
153 | } else { | ||
154 | X509V3err(X509V3_F_V2I_BASIC_CONSTRAINTS, X509V3_R_INVALID_NAME); | ||
155 | X509V3_conf_err(val); | ||
156 | goto err; | ||
157 | } | ||
158 | } | ||
159 | return bcons; | ||
160 | err: | ||
161 | BASIC_CONSTRAINTS_free(bcons); | ||
162 | return NULL; | ||
163 | } | ||
164 | |||
diff --git a/src/lib/libcrypto/x509v3/v3_bitst.c b/src/lib/libcrypto/x509v3/v3_bitst.c new file mode 100644 index 0000000000..9828ba15b3 --- /dev/null +++ b/src/lib/libcrypto/x509v3/v3_bitst.c | |||
@@ -0,0 +1,147 @@ | |||
1 | /* v3_bitst.c */ | ||
2 | /* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL | ||
3 | * project 1999. | ||
4 | */ | ||
5 | /* ==================================================================== | ||
6 | * Copyright (c) 1999 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 | #include "cryptlib.h" | ||
61 | #include <openssl/conf.h> | ||
62 | #include <openssl/x509v3.h> | ||
63 | |||
64 | static ASN1_BIT_STRING *asn1_bit_string_new(void); | ||
65 | static ASN1_BIT_STRING *v2i_ASN1_BIT_STRING(X509V3_EXT_METHOD *method, | ||
66 | X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval); | ||
67 | static STACK_OF(CONF_VALUE) *i2v_ASN1_BIT_STRING(X509V3_EXT_METHOD *method, | ||
68 | ASN1_BIT_STRING *bits, | ||
69 | STACK_OF(CONF_VALUE) *extlist); | ||
70 | static BIT_STRING_BITNAME ns_cert_type_table[] = { | ||
71 | {0, "SSL Client", "client"}, | ||
72 | {1, "SSL Server", "server"}, | ||
73 | {2, "S/MIME", "email"}, | ||
74 | {3, "Object Signing", "objsign"}, | ||
75 | {4, "Unused", "reserved"}, | ||
76 | {5, "SSL CA", "sslCA"}, | ||
77 | {6, "S/MIME CA", "emailCA"}, | ||
78 | {7, "Object Signing CA", "objCA"}, | ||
79 | {-1, NULL, NULL} | ||
80 | }; | ||
81 | |||
82 | static BIT_STRING_BITNAME key_usage_type_table[] = { | ||
83 | {0, "Digital Signature", "digitalSignature"}, | ||
84 | {1, "Non Repudiation", "nonRepudiation"}, | ||
85 | {2, "Key Encipherment", "keyEncipherment"}, | ||
86 | {3, "Data Encipherment", "dataEncipherment"}, | ||
87 | {4, "Key Agreement", "keyAgreement"}, | ||
88 | {5, "Certificate Sign", "keyCertSign"}, | ||
89 | {6, "CRL Sign", "cRLSign"}, | ||
90 | {7, "Encipher Only", "encipherOnly"}, | ||
91 | {8, "Decipher Only", "decipherOnly"}, | ||
92 | {-1, NULL, NULL} | ||
93 | }; | ||
94 | |||
95 | |||
96 | |||
97 | X509V3_EXT_METHOD v3_nscert = EXT_BITSTRING(NID_netscape_cert_type, ns_cert_type_table); | ||
98 | X509V3_EXT_METHOD v3_key_usage = EXT_BITSTRING(NID_key_usage, key_usage_type_table); | ||
99 | |||
100 | static ASN1_BIT_STRING *asn1_bit_string_new(void) | ||
101 | { | ||
102 | return ASN1_BIT_STRING_new(); | ||
103 | } | ||
104 | |||
105 | static STACK_OF(CONF_VALUE) *i2v_ASN1_BIT_STRING(X509V3_EXT_METHOD *method, | ||
106 | ASN1_BIT_STRING *bits, STACK_OF(CONF_VALUE) *ret) | ||
107 | { | ||
108 | BIT_STRING_BITNAME *bnam; | ||
109 | for(bnam =method->usr_data; bnam->lname; bnam++) { | ||
110 | if(ASN1_BIT_STRING_get_bit(bits, bnam->bitnum)) | ||
111 | X509V3_add_value(bnam->lname, NULL, &ret); | ||
112 | } | ||
113 | return ret; | ||
114 | } | ||
115 | |||
116 | static ASN1_BIT_STRING *v2i_ASN1_BIT_STRING(X509V3_EXT_METHOD *method, | ||
117 | X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval) | ||
118 | { | ||
119 | CONF_VALUE *val; | ||
120 | ASN1_BIT_STRING *bs; | ||
121 | int i; | ||
122 | BIT_STRING_BITNAME *bnam; | ||
123 | if(!(bs = ASN1_BIT_STRING_new())) { | ||
124 | X509V3err(X509V3_F_V2I_ASN1_BIT_STRING,ERR_R_MALLOC_FAILURE); | ||
125 | return NULL; | ||
126 | } | ||
127 | for(i = 0; i < sk_CONF_VALUE_num(nval); i++) { | ||
128 | val = sk_CONF_VALUE_value(nval, i); | ||
129 | for(bnam = method->usr_data; bnam->lname; bnam++) { | ||
130 | if(!strcmp(bnam->sname, val->name) || | ||
131 | !strcmp(bnam->lname, val->name) ) { | ||
132 | ASN1_BIT_STRING_set_bit(bs, bnam->bitnum, 1); | ||
133 | break; | ||
134 | } | ||
135 | } | ||
136 | if(!bnam->lname) { | ||
137 | X509V3err(X509V3_F_V2I_ASN1_BIT_STRING, | ||
138 | X509V3_R_UNKNOWN_BIT_STRING_ARGUMENT); | ||
139 | X509V3_conf_err(val); | ||
140 | ASN1_BIT_STRING_free(bs); | ||
141 | return NULL; | ||
142 | } | ||
143 | } | ||
144 | return bs; | ||
145 | } | ||
146 | |||
147 | |||
diff --git a/src/lib/libcrypto/x509v3/v3_conf.c b/src/lib/libcrypto/x509v3/v3_conf.c new file mode 100644 index 0000000000..f19bb3ad84 --- /dev/null +++ b/src/lib/libcrypto/x509v3/v3_conf.c | |||
@@ -0,0 +1,366 @@ | |||
1 | /* v3_conf.c */ | ||
2 | /* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL | ||
3 | * project 1999. | ||
4 | */ | ||
5 | /* ==================================================================== | ||
6 | * Copyright (c) 1999 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 | /* extension creation utilities */ | ||
59 | |||
60 | |||
61 | |||
62 | #include <stdio.h> | ||
63 | #include <ctype.h> | ||
64 | #include "cryptlib.h" | ||
65 | #include <openssl/conf.h> | ||
66 | #include <openssl/x509.h> | ||
67 | #include <openssl/x509v3.h> | ||
68 | |||
69 | static int v3_check_critical(char **value); | ||
70 | static int v3_check_generic(char **value); | ||
71 | static X509_EXTENSION *do_ext_conf(LHASH *conf, X509V3_CTX *ctx, int ext_nid, int crit, char *value); | ||
72 | static X509_EXTENSION *v3_generic_extension(const char *ext, char *value, int crit, int type); | ||
73 | static char *conf_lhash_get_string(void *db, char *section, char *value); | ||
74 | static STACK_OF(CONF_VALUE) *conf_lhash_get_section(void *db, char *section); | ||
75 | static X509_EXTENSION *do_ext_i2d(X509V3_EXT_METHOD *method, int ext_nid, | ||
76 | int crit, void *ext_struc); | ||
77 | /* LHASH *conf: Config file */ | ||
78 | /* char *name: Name */ | ||
79 | /* char *value: Value */ | ||
80 | X509_EXTENSION *X509V3_EXT_conf(LHASH *conf, X509V3_CTX *ctx, char *name, | ||
81 | char *value) | ||
82 | { | ||
83 | int crit; | ||
84 | int ext_type; | ||
85 | X509_EXTENSION *ret; | ||
86 | crit = v3_check_critical(&value); | ||
87 | if((ext_type = v3_check_generic(&value))) | ||
88 | return v3_generic_extension(name, value, crit, ext_type); | ||
89 | ret = do_ext_conf(conf, ctx, OBJ_sn2nid(name), crit, value); | ||
90 | if(!ret) { | ||
91 | X509V3err(X509V3_F_X509V3_EXT_CONF,X509V3_R_ERROR_IN_EXTENSION); | ||
92 | ERR_add_error_data(4,"name=", name, ", value=", value); | ||
93 | } | ||
94 | return ret; | ||
95 | } | ||
96 | |||
97 | /* LHASH *conf: Config file */ | ||
98 | /* char *value: Value */ | ||
99 | X509_EXTENSION *X509V3_EXT_conf_nid(LHASH *conf, X509V3_CTX *ctx, int ext_nid, | ||
100 | char *value) | ||
101 | { | ||
102 | int crit; | ||
103 | int ext_type; | ||
104 | crit = v3_check_critical(&value); | ||
105 | if((ext_type = v3_check_generic(&value))) | ||
106 | return v3_generic_extension(OBJ_nid2sn(ext_nid), | ||
107 | value, crit, ext_type); | ||
108 | return do_ext_conf(conf, ctx, ext_nid, crit, value); | ||
109 | } | ||
110 | |||
111 | /* LHASH *conf: Config file */ | ||
112 | /* char *value: Value */ | ||
113 | static X509_EXTENSION *do_ext_conf(LHASH *conf, X509V3_CTX *ctx, int ext_nid, | ||
114 | int crit, char *value) | ||
115 | { | ||
116 | X509V3_EXT_METHOD *method; | ||
117 | X509_EXTENSION *ext; | ||
118 | STACK_OF(CONF_VALUE) *nval; | ||
119 | void *ext_struc; | ||
120 | if(ext_nid == NID_undef) { | ||
121 | X509V3err(X509V3_F_DO_EXT_CONF,X509V3_R_UNKNOWN_EXTENSION_NAME); | ||
122 | return NULL; | ||
123 | } | ||
124 | if(!(method = X509V3_EXT_get_nid(ext_nid))) { | ||
125 | X509V3err(X509V3_F_DO_EXT_CONF,X509V3_R_UNKNOWN_EXTENSION); | ||
126 | return NULL; | ||
127 | } | ||
128 | /* Now get internal extension representation based on type */ | ||
129 | if(method->v2i) { | ||
130 | if(*value == '@') nval = CONF_get_section(conf, value + 1); | ||
131 | else nval = X509V3_parse_list(value); | ||
132 | if(!nval) { | ||
133 | X509V3err(X509V3_F_X509V3_EXT_CONF,X509V3_R_INVALID_EXTENSION_STRING); | ||
134 | ERR_add_error_data(4, "name=", OBJ_nid2sn(ext_nid), ",section=", value); | ||
135 | return NULL; | ||
136 | } | ||
137 | ext_struc = method->v2i(method, ctx, nval); | ||
138 | if(*value != '@') sk_CONF_VALUE_pop_free(nval, | ||
139 | X509V3_conf_free); | ||
140 | if(!ext_struc) return NULL; | ||
141 | } else if(method->s2i) { | ||
142 | if(!(ext_struc = method->s2i(method, ctx, value))) return NULL; | ||
143 | } else if(method->r2i) { | ||
144 | if(!ctx->db) { | ||
145 | X509V3err(X509V3_F_X509V3_EXT_CONF,X509V3_R_NO_CONFIG_DATABASE); | ||
146 | return NULL; | ||
147 | } | ||
148 | if(!(ext_struc = method->r2i(method, ctx, value))) return NULL; | ||
149 | } else { | ||
150 | X509V3err(X509V3_F_X509V3_EXT_CONF,X509V3_R_EXTENSION_SETTING_NOT_SUPPORTED); | ||
151 | ERR_add_error_data(2, "name=", OBJ_nid2sn(ext_nid)); | ||
152 | return NULL; | ||
153 | } | ||
154 | |||
155 | ext = do_ext_i2d(method, ext_nid, crit, ext_struc); | ||
156 | method->ext_free(ext_struc); | ||
157 | return ext; | ||
158 | |||
159 | } | ||
160 | |||
161 | static X509_EXTENSION *do_ext_i2d(X509V3_EXT_METHOD *method, int ext_nid, | ||
162 | int crit, void *ext_struc) | ||
163 | { | ||
164 | unsigned char *ext_der, *p; | ||
165 | int ext_len; | ||
166 | ASN1_OCTET_STRING *ext_oct; | ||
167 | X509_EXTENSION *ext; | ||
168 | /* Convert internal representation to DER */ | ||
169 | ext_len = method->i2d(ext_struc, NULL); | ||
170 | if(!(ext_der = Malloc(ext_len))) goto merr; | ||
171 | p = ext_der; | ||
172 | method->i2d(ext_struc, &p); | ||
173 | if(!(ext_oct = ASN1_OCTET_STRING_new())) goto merr; | ||
174 | ext_oct->data = ext_der; | ||
175 | ext_oct->length = ext_len; | ||
176 | |||
177 | ext = X509_EXTENSION_create_by_NID(NULL, ext_nid, crit, ext_oct); | ||
178 | if(!ext) goto merr; | ||
179 | ASN1_OCTET_STRING_free(ext_oct); | ||
180 | |||
181 | return ext; | ||
182 | |||
183 | merr: | ||
184 | X509V3err(X509V3_F_DO_EXT_I2D,ERR_R_MALLOC_FAILURE); | ||
185 | return NULL; | ||
186 | |||
187 | } | ||
188 | |||
189 | /* Given an internal structure, nid and critical flag create an extension */ | ||
190 | |||
191 | X509_EXTENSION *X509V3_EXT_i2d(int ext_nid, int crit, void *ext_struc) | ||
192 | { | ||
193 | X509V3_EXT_METHOD *method; | ||
194 | if(!(method = X509V3_EXT_get_nid(ext_nid))) { | ||
195 | X509V3err(X509V3_F_X509V3_EXT_I2D,X509V3_R_UNKNOWN_EXTENSION); | ||
196 | return NULL; | ||
197 | } | ||
198 | return do_ext_i2d(method, ext_nid, crit, ext_struc); | ||
199 | } | ||
200 | |||
201 | /* Check the extension string for critical flag */ | ||
202 | static int v3_check_critical(char **value) | ||
203 | { | ||
204 | char *p = *value; | ||
205 | if((strlen(p) < 9) || strncmp(p, "critical,", 9)) return 0; | ||
206 | p+=9; | ||
207 | while(isspace((unsigned char)*p)) p++; | ||
208 | *value = p; | ||
209 | return 1; | ||
210 | } | ||
211 | |||
212 | /* Check extension string for generic extension and return the type */ | ||
213 | static int v3_check_generic(char **value) | ||
214 | { | ||
215 | char *p = *value; | ||
216 | if((strlen(p) < 4) || strncmp(p, "DER:,", 4)) return 0; | ||
217 | p+=4; | ||
218 | while(isspace((unsigned char)*p)) p++; | ||
219 | *value = p; | ||
220 | return 1; | ||
221 | } | ||
222 | |||
223 | /* Create a generic extension: for now just handle RAW type */ | ||
224 | static X509_EXTENSION *v3_generic_extension(const char *ext, char *value, | ||
225 | int crit, int type) | ||
226 | { | ||
227 | unsigned char *ext_der=NULL; | ||
228 | long ext_len; | ||
229 | ASN1_OBJECT *obj=NULL; | ||
230 | ASN1_OCTET_STRING *oct=NULL; | ||
231 | X509_EXTENSION *extension=NULL; | ||
232 | if(!(obj = OBJ_txt2obj(ext, 0))) { | ||
233 | X509V3err(X509V3_F_V3_GENERIC_EXTENSION,X509V3_R_EXTENSION_NAME_ERROR); | ||
234 | ERR_add_error_data(2, "name=", ext); | ||
235 | goto err; | ||
236 | } | ||
237 | |||
238 | if(!(ext_der = string_to_hex(value, &ext_len))) { | ||
239 | X509V3err(X509V3_F_V3_GENERIC_EXTENSION,X509V3_R_EXTENSION_VALUE_ERROR); | ||
240 | ERR_add_error_data(2, "value=", value); | ||
241 | goto err; | ||
242 | } | ||
243 | |||
244 | if(!(oct = ASN1_OCTET_STRING_new())) { | ||
245 | X509V3err(X509V3_F_V3_GENERIC_EXTENSION,ERR_R_MALLOC_FAILURE); | ||
246 | goto err; | ||
247 | } | ||
248 | |||
249 | oct->data = ext_der; | ||
250 | oct->length = ext_len; | ||
251 | ext_der = NULL; | ||
252 | |||
253 | extension = X509_EXTENSION_create_by_OBJ(NULL, obj, crit, oct); | ||
254 | |||
255 | err: | ||
256 | ASN1_OBJECT_free(obj); | ||
257 | ASN1_OCTET_STRING_free(oct); | ||
258 | if(ext_der) Free(ext_der); | ||
259 | return extension; | ||
260 | } | ||
261 | |||
262 | |||
263 | /* This is the main function: add a bunch of extensions based on a config file | ||
264 | * section | ||
265 | */ | ||
266 | |||
267 | int X509V3_EXT_add_conf(LHASH *conf, X509V3_CTX *ctx, char *section, | ||
268 | X509 *cert) | ||
269 | { | ||
270 | X509_EXTENSION *ext; | ||
271 | STACK_OF(CONF_VALUE) *nval; | ||
272 | CONF_VALUE *val; | ||
273 | int i; | ||
274 | if(!(nval = CONF_get_section(conf, section))) return 0; | ||
275 | for(i = 0; i < sk_CONF_VALUE_num(nval); i++) { | ||
276 | val = sk_CONF_VALUE_value(nval, i); | ||
277 | if(!(ext = X509V3_EXT_conf(conf, ctx, val->name, val->value))) | ||
278 | return 0; | ||
279 | if(cert) X509_add_ext(cert, ext, -1); | ||
280 | X509_EXTENSION_free(ext); | ||
281 | } | ||
282 | return 1; | ||
283 | } | ||
284 | |||
285 | /* Same as above but for a CRL */ | ||
286 | |||
287 | int X509V3_EXT_CRL_add_conf(LHASH *conf, X509V3_CTX *ctx, char *section, | ||
288 | X509_CRL *crl) | ||
289 | { | ||
290 | X509_EXTENSION *ext; | ||
291 | STACK_OF(CONF_VALUE) *nval; | ||
292 | CONF_VALUE *val; | ||
293 | int i; | ||
294 | if(!(nval = CONF_get_section(conf, section))) return 0; | ||
295 | for(i = 0; i < sk_CONF_VALUE_num(nval); i++) { | ||
296 | val = sk_CONF_VALUE_value(nval, i); | ||
297 | if(!(ext = X509V3_EXT_conf(conf, ctx, val->name, val->value))) | ||
298 | return 0; | ||
299 | if(crl) X509_CRL_add_ext(crl, ext, -1); | ||
300 | X509_EXTENSION_free(ext); | ||
301 | } | ||
302 | return 1; | ||
303 | } | ||
304 | |||
305 | /* Config database functions */ | ||
306 | |||
307 | char * X509V3_get_string(X509V3_CTX *ctx, char *name, char *section) | ||
308 | { | ||
309 | if(ctx->db_meth->get_string) | ||
310 | return ctx->db_meth->get_string(ctx->db, name, section); | ||
311 | return NULL; | ||
312 | } | ||
313 | |||
314 | STACK_OF(CONF_VALUE) * X509V3_get_section(X509V3_CTX *ctx, char *section) | ||
315 | { | ||
316 | if(ctx->db_meth->get_section) | ||
317 | return ctx->db_meth->get_section(ctx->db, section); | ||
318 | return NULL; | ||
319 | } | ||
320 | |||
321 | void X509V3_string_free(X509V3_CTX *ctx, char *str) | ||
322 | { | ||
323 | if(!str) return; | ||
324 | if(ctx->db_meth->free_string) | ||
325 | ctx->db_meth->free_string(ctx->db, str); | ||
326 | } | ||
327 | |||
328 | void X509V3_section_free(X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *section) | ||
329 | { | ||
330 | if(!section) return; | ||
331 | if(ctx->db_meth->free_section) | ||
332 | ctx->db_meth->free_section(ctx->db, section); | ||
333 | } | ||
334 | |||
335 | static char *conf_lhash_get_string(void *db, char *section, char *value) | ||
336 | { | ||
337 | return CONF_get_string(db, section, value); | ||
338 | } | ||
339 | |||
340 | static STACK_OF(CONF_VALUE) *conf_lhash_get_section(void *db, char *section) | ||
341 | { | ||
342 | return CONF_get_section(db, section); | ||
343 | } | ||
344 | |||
345 | static X509V3_CONF_METHOD conf_lhash_method = { | ||
346 | conf_lhash_get_string, | ||
347 | conf_lhash_get_section, | ||
348 | NULL, | ||
349 | NULL | ||
350 | }; | ||
351 | |||
352 | void X509V3_set_conf_lhash(X509V3_CTX *ctx, LHASH *lhash) | ||
353 | { | ||
354 | ctx->db_meth = &conf_lhash_method; | ||
355 | ctx->db = lhash; | ||
356 | } | ||
357 | |||
358 | void X509V3_set_ctx(X509V3_CTX *ctx, X509 *issuer, X509 *subj, X509_REQ *req, | ||
359 | X509_CRL *crl, int flags) | ||
360 | { | ||
361 | ctx->issuer_cert = issuer; | ||
362 | ctx->subject_cert = subj; | ||
363 | ctx->crl = crl; | ||
364 | ctx->subject_req = req; | ||
365 | ctx->flags = flags; | ||
366 | } | ||
diff --git a/src/lib/libcrypto/x509v3/v3_cpols.c b/src/lib/libcrypto/x509v3/v3_cpols.c new file mode 100644 index 0000000000..b4d4883545 --- /dev/null +++ b/src/lib/libcrypto/x509v3/v3_cpols.c | |||
@@ -0,0 +1,655 @@ | |||
1 | /* v3_cpols.c */ | ||
2 | /* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL | ||
3 | * project 1999. | ||
4 | */ | ||
5 | /* ==================================================================== | ||
6 | * Copyright (c) 1999 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 | #include "cryptlib.h" | ||
61 | #include <openssl/conf.h> | ||
62 | #include <openssl/asn1.h> | ||
63 | #include <openssl/asn1_mac.h> | ||
64 | #include <openssl/x509v3.h> | ||
65 | |||
66 | /* Certificate policies extension support: this one is a bit complex... */ | ||
67 | |||
68 | static int i2r_certpol(X509V3_EXT_METHOD *method, STACK_OF(POLICYINFO) *pol, BIO *out, int indent); | ||
69 | static STACK_OF(POLICYINFO) *r2i_certpol(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, char *value); | ||
70 | static void print_qualifiers(BIO *out, STACK_OF(POLICYQUALINFO) *quals, int indent); | ||
71 | static void print_notice(BIO *out, USERNOTICE *notice, int indent); | ||
72 | static POLICYINFO *policy_section(X509V3_CTX *ctx, | ||
73 | STACK_OF(CONF_VALUE) *polstrs, int ia5org); | ||
74 | static POLICYQUALINFO *notice_section(X509V3_CTX *ctx, | ||
75 | STACK_OF(CONF_VALUE) *unot, int ia5org); | ||
76 | static STACK *nref_nos(STACK_OF(CONF_VALUE) *nos); | ||
77 | |||
78 | X509V3_EXT_METHOD v3_cpols = { | ||
79 | NID_certificate_policies, 0, | ||
80 | (X509V3_EXT_NEW)CERTIFICATEPOLICIES_new, | ||
81 | (X509V3_EXT_FREE)CERTIFICATEPOLICIES_free, | ||
82 | (X509V3_EXT_D2I)d2i_CERTIFICATEPOLICIES, | ||
83 | (X509V3_EXT_I2D)i2d_CERTIFICATEPOLICIES, | ||
84 | NULL, NULL, | ||
85 | NULL, NULL, | ||
86 | (X509V3_EXT_I2R)i2r_certpol, | ||
87 | (X509V3_EXT_R2I)r2i_certpol, | ||
88 | NULL | ||
89 | }; | ||
90 | |||
91 | |||
92 | static STACK_OF(POLICYINFO) *r2i_certpol(X509V3_EXT_METHOD *method, | ||
93 | X509V3_CTX *ctx, char *value) | ||
94 | { | ||
95 | STACK_OF(POLICYINFO) *pols = NULL; | ||
96 | char *pstr; | ||
97 | POLICYINFO *pol; | ||
98 | ASN1_OBJECT *pobj; | ||
99 | STACK_OF(CONF_VALUE) *vals; | ||
100 | CONF_VALUE *cnf; | ||
101 | int i, ia5org; | ||
102 | pols = sk_POLICYINFO_new_null(); | ||
103 | vals = X509V3_parse_list(value); | ||
104 | ia5org = 0; | ||
105 | for(i = 0; i < sk_CONF_VALUE_num(vals); i++) { | ||
106 | cnf = sk_CONF_VALUE_value(vals, i); | ||
107 | if(cnf->value || !cnf->name ) { | ||
108 | X509V3err(X509V3_F_R2I_CERTPOL,X509V3_R_INVALID_POLICY_IDENTIFIER); | ||
109 | X509V3_conf_err(cnf); | ||
110 | goto err; | ||
111 | } | ||
112 | pstr = cnf->name; | ||
113 | if(!strcmp(pstr,"ia5org")) { | ||
114 | ia5org = 1; | ||
115 | continue; | ||
116 | } else if(*pstr == '@') { | ||
117 | STACK_OF(CONF_VALUE) *polsect; | ||
118 | polsect = X509V3_get_section(ctx, pstr + 1); | ||
119 | if(!polsect) { | ||
120 | X509V3err(X509V3_F_R2I_CERTPOL,X509V3_R_INVALID_SECTION); | ||
121 | |||
122 | X509V3_conf_err(cnf); | ||
123 | goto err; | ||
124 | } | ||
125 | pol = policy_section(ctx, polsect, ia5org); | ||
126 | X509V3_section_free(ctx, polsect); | ||
127 | if(!pol) goto err; | ||
128 | } else { | ||
129 | if(!(pobj = OBJ_txt2obj(cnf->name, 0))) { | ||
130 | X509V3err(X509V3_F_R2I_CERTPOL,X509V3_R_INVALID_OBJECT_IDENTIFIER); | ||
131 | X509V3_conf_err(cnf); | ||
132 | goto err; | ||
133 | } | ||
134 | pol = POLICYINFO_new(); | ||
135 | pol->policyid = pobj; | ||
136 | } | ||
137 | sk_POLICYINFO_push(pols, pol); | ||
138 | } | ||
139 | sk_CONF_VALUE_pop_free(vals, X509V3_conf_free); | ||
140 | return pols; | ||
141 | err: | ||
142 | sk_POLICYINFO_pop_free(pols, POLICYINFO_free); | ||
143 | return NULL; | ||
144 | } | ||
145 | |||
146 | static POLICYINFO *policy_section(X509V3_CTX *ctx, | ||
147 | STACK_OF(CONF_VALUE) *polstrs, int ia5org) | ||
148 | { | ||
149 | int i; | ||
150 | CONF_VALUE *cnf; | ||
151 | POLICYINFO *pol; | ||
152 | POLICYQUALINFO *qual; | ||
153 | if(!(pol = POLICYINFO_new())) goto merr; | ||
154 | for(i = 0; i < sk_CONF_VALUE_num(polstrs); i++) { | ||
155 | cnf = sk_CONF_VALUE_value(polstrs, i); | ||
156 | if(!strcmp(cnf->name, "policyIdentifier")) { | ||
157 | ASN1_OBJECT *pobj; | ||
158 | if(!(pobj = OBJ_txt2obj(cnf->value, 0))) { | ||
159 | X509V3err(X509V3_F_POLICY_SECTION,X509V3_R_INVALID_OBJECT_IDENTIFIER); | ||
160 | X509V3_conf_err(cnf); | ||
161 | goto err; | ||
162 | } | ||
163 | pol->policyid = pobj; | ||
164 | |||
165 | } else if(!name_cmp(cnf->name, "CPS")) { | ||
166 | if(!pol->qualifiers) pol->qualifiers = | ||
167 | sk_POLICYQUALINFO_new_null(); | ||
168 | if(!(qual = POLICYQUALINFO_new())) goto merr; | ||
169 | if(!sk_POLICYQUALINFO_push(pol->qualifiers, qual)) | ||
170 | goto merr; | ||
171 | qual->pqualid = OBJ_nid2obj(NID_id_qt_cps); | ||
172 | qual->d.cpsuri = ASN1_IA5STRING_new(); | ||
173 | if(!ASN1_STRING_set(qual->d.cpsuri, cnf->value, | ||
174 | strlen(cnf->value))) goto merr; | ||
175 | } else if(!name_cmp(cnf->name, "userNotice")) { | ||
176 | STACK_OF(CONF_VALUE) *unot; | ||
177 | if(*cnf->value != '@') { | ||
178 | X509V3err(X509V3_F_POLICY_SECTION,X509V3_R_EXPECTED_A_SECTION_NAME); | ||
179 | X509V3_conf_err(cnf); | ||
180 | goto err; | ||
181 | } | ||
182 | unot = X509V3_get_section(ctx, cnf->value + 1); | ||
183 | if(!unot) { | ||
184 | X509V3err(X509V3_F_POLICY_SECTION,X509V3_R_INVALID_SECTION); | ||
185 | |||
186 | X509V3_conf_err(cnf); | ||
187 | goto err; | ||
188 | } | ||
189 | qual = notice_section(ctx, unot, ia5org); | ||
190 | X509V3_section_free(ctx, unot); | ||
191 | if(!qual) goto err; | ||
192 | if(!sk_POLICYQUALINFO_push(pol->qualifiers, qual)) | ||
193 | goto merr; | ||
194 | } else { | ||
195 | X509V3err(X509V3_F_POLICY_SECTION,X509V3_R_INVALID_OPTION); | ||
196 | |||
197 | X509V3_conf_err(cnf); | ||
198 | goto err; | ||
199 | } | ||
200 | } | ||
201 | if(!pol->policyid) { | ||
202 | X509V3err(X509V3_F_POLICY_SECTION,X509V3_R_NO_POLICY_IDENTIFIER); | ||
203 | goto err; | ||
204 | } | ||
205 | |||
206 | return pol; | ||
207 | |||
208 | merr: | ||
209 | X509V3err(X509V3_F_POLICY_SECTION,ERR_R_MALLOC_FAILURE); | ||
210 | |||
211 | err: | ||
212 | POLICYINFO_free(pol); | ||
213 | return NULL; | ||
214 | |||
215 | |||
216 | } | ||
217 | |||
218 | static POLICYQUALINFO *notice_section(X509V3_CTX *ctx, | ||
219 | STACK_OF(CONF_VALUE) *unot, int ia5org) | ||
220 | { | ||
221 | int i; | ||
222 | CONF_VALUE *cnf; | ||
223 | USERNOTICE *not; | ||
224 | POLICYQUALINFO *qual; | ||
225 | if(!(qual = POLICYQUALINFO_new())) goto merr; | ||
226 | qual->pqualid = OBJ_nid2obj(NID_id_qt_unotice); | ||
227 | if(!(not = USERNOTICE_new())) goto merr; | ||
228 | qual->d.usernotice = not; | ||
229 | for(i = 0; i < sk_CONF_VALUE_num(unot); i++) { | ||
230 | cnf = sk_CONF_VALUE_value(unot, i); | ||
231 | if(!strcmp(cnf->name, "explicitText")) { | ||
232 | not->exptext = ASN1_VISIBLESTRING_new(); | ||
233 | if(!ASN1_STRING_set(not->exptext, cnf->value, | ||
234 | strlen(cnf->value))) goto merr; | ||
235 | } else if(!strcmp(cnf->name, "organization")) { | ||
236 | NOTICEREF *nref; | ||
237 | if(!not->noticeref) { | ||
238 | if(!(nref = NOTICEREF_new())) goto merr; | ||
239 | not->noticeref = nref; | ||
240 | } else nref = not->noticeref; | ||
241 | if(ia5org) nref->organization = ASN1_IA5STRING_new(); | ||
242 | else nref->organization = ASN1_VISIBLESTRING_new(); | ||
243 | if(!ASN1_STRING_set(nref->organization, cnf->value, | ||
244 | strlen(cnf->value))) goto merr; | ||
245 | } else if(!strcmp(cnf->name, "noticeNumbers")) { | ||
246 | NOTICEREF *nref; | ||
247 | STACK_OF(CONF_VALUE) *nos; | ||
248 | if(!not->noticeref) { | ||
249 | if(!(nref = NOTICEREF_new())) goto merr; | ||
250 | not->noticeref = nref; | ||
251 | } else nref = not->noticeref; | ||
252 | nos = X509V3_parse_list(cnf->value); | ||
253 | if(!nos || !sk_CONF_VALUE_num(nos)) { | ||
254 | X509V3err(X509V3_F_NOTICE_SECTION,X509V3_R_INVALID_NUMBERS); | ||
255 | X509V3_conf_err(cnf); | ||
256 | goto err; | ||
257 | } | ||
258 | nref->noticenos = nref_nos(nos); | ||
259 | sk_CONF_VALUE_pop_free(nos, X509V3_conf_free); | ||
260 | if(!nref->noticenos) goto err; | ||
261 | } else { | ||
262 | X509V3err(X509V3_F_NOTICE_SECTION,X509V3_R_INVALID_OPTION); | ||
263 | |||
264 | X509V3_conf_err(cnf); | ||
265 | goto err; | ||
266 | } | ||
267 | } | ||
268 | |||
269 | if(not->noticeref && | ||
270 | (!not->noticeref->noticenos || !not->noticeref->organization)) { | ||
271 | X509V3err(X509V3_F_NOTICE_SECTION,X509V3_R_NEED_ORGANIZATION_AND_NUMBERS); | ||
272 | goto err; | ||
273 | } | ||
274 | |||
275 | return qual; | ||
276 | |||
277 | merr: | ||
278 | X509V3err(X509V3_F_NOTICE_SECTION,ERR_R_MALLOC_FAILURE); | ||
279 | |||
280 | err: | ||
281 | POLICYQUALINFO_free(qual); | ||
282 | return NULL; | ||
283 | } | ||
284 | |||
285 | static STACK *nref_nos(STACK_OF(CONF_VALUE) *nos) | ||
286 | { | ||
287 | STACK *nnums; | ||
288 | CONF_VALUE *cnf; | ||
289 | ASN1_INTEGER *aint; | ||
290 | int i; | ||
291 | if(!(nnums = sk_new_null())) goto merr; | ||
292 | for(i = 0; i < sk_CONF_VALUE_num(nos); i++) { | ||
293 | cnf = sk_CONF_VALUE_value(nos, i); | ||
294 | if(!(aint = s2i_ASN1_INTEGER(NULL, cnf->name))) { | ||
295 | X509V3err(X509V3_F_NREF_NOS,X509V3_R_INVALID_NUMBER); | ||
296 | goto err; | ||
297 | } | ||
298 | if(!sk_push(nnums, (char *)aint)) goto merr; | ||
299 | } | ||
300 | return nnums; | ||
301 | |||
302 | merr: | ||
303 | X509V3err(X509V3_F_NOTICE_SECTION,ERR_R_MALLOC_FAILURE); | ||
304 | |||
305 | err: | ||
306 | sk_pop_free(nnums, ASN1_STRING_free); | ||
307 | return NULL; | ||
308 | } | ||
309 | |||
310 | |||
311 | static int i2r_certpol(X509V3_EXT_METHOD *method, STACK_OF(POLICYINFO) *pol, | ||
312 | BIO *out, int indent) | ||
313 | { | ||
314 | int i; | ||
315 | POLICYINFO *pinfo; | ||
316 | /* First print out the policy OIDs */ | ||
317 | for(i = 0; i < sk_POLICYINFO_num(pol); i++) { | ||
318 | pinfo = sk_POLICYINFO_value(pol, i); | ||
319 | BIO_printf(out, "%*sPolicy: ", indent, ""); | ||
320 | i2a_ASN1_OBJECT(out, pinfo->policyid); | ||
321 | BIO_puts(out, "\n"); | ||
322 | if(pinfo->qualifiers) | ||
323 | print_qualifiers(out, pinfo->qualifiers, indent + 2); | ||
324 | } | ||
325 | return 1; | ||
326 | } | ||
327 | |||
328 | |||
329 | int i2d_CERTIFICATEPOLICIES(STACK_OF(POLICYINFO) *a, unsigned char **pp) | ||
330 | { | ||
331 | |||
332 | return i2d_ASN1_SET_OF_POLICYINFO(a, pp, i2d_POLICYINFO, V_ASN1_SEQUENCE, | ||
333 | V_ASN1_UNIVERSAL, IS_SEQUENCE);} | ||
334 | |||
335 | STACK_OF(POLICYINFO) *CERTIFICATEPOLICIES_new(void) | ||
336 | { | ||
337 | return sk_POLICYINFO_new_null(); | ||
338 | } | ||
339 | |||
340 | void CERTIFICATEPOLICIES_free(STACK_OF(POLICYINFO) *a) | ||
341 | { | ||
342 | sk_POLICYINFO_pop_free(a, POLICYINFO_free); | ||
343 | } | ||
344 | |||
345 | STACK_OF(POLICYINFO) *d2i_CERTIFICATEPOLICIES(STACK_OF(POLICYINFO) **a, | ||
346 | unsigned char **pp,long length) | ||
347 | { | ||
348 | return d2i_ASN1_SET_OF_POLICYINFO(a, pp, length, d2i_POLICYINFO, | ||
349 | POLICYINFO_free, V_ASN1_SEQUENCE, V_ASN1_UNIVERSAL); | ||
350 | |||
351 | } | ||
352 | |||
353 | IMPLEMENT_STACK_OF(POLICYINFO) | ||
354 | IMPLEMENT_ASN1_SET_OF(POLICYINFO) | ||
355 | |||
356 | int i2d_POLICYINFO(POLICYINFO *a, unsigned char **pp) | ||
357 | { | ||
358 | M_ASN1_I2D_vars(a); | ||
359 | |||
360 | M_ASN1_I2D_len (a->policyid, i2d_ASN1_OBJECT); | ||
361 | M_ASN1_I2D_len_SEQUENCE_type(POLICYQUALINFO, a->qualifiers, | ||
362 | i2d_POLICYQUALINFO); | ||
363 | |||
364 | M_ASN1_I2D_seq_total(); | ||
365 | |||
366 | M_ASN1_I2D_put (a->policyid, i2d_ASN1_OBJECT); | ||
367 | M_ASN1_I2D_put_SEQUENCE_type(POLICYQUALINFO, a->qualifiers, | ||
368 | i2d_POLICYQUALINFO); | ||
369 | |||
370 | M_ASN1_I2D_finish(); | ||
371 | } | ||
372 | |||
373 | POLICYINFO *POLICYINFO_new(void) | ||
374 | { | ||
375 | POLICYINFO *ret=NULL; | ||
376 | ASN1_CTX c; | ||
377 | M_ASN1_New_Malloc(ret, POLICYINFO); | ||
378 | ret->policyid = NULL; | ||
379 | ret->qualifiers = NULL; | ||
380 | return (ret); | ||
381 | M_ASN1_New_Error(ASN1_F_POLICYINFO_NEW); | ||
382 | } | ||
383 | |||
384 | POLICYINFO *d2i_POLICYINFO(POLICYINFO **a, unsigned char **pp,long length) | ||
385 | { | ||
386 | M_ASN1_D2I_vars(a,POLICYINFO *,POLICYINFO_new); | ||
387 | M_ASN1_D2I_Init(); | ||
388 | M_ASN1_D2I_start_sequence(); | ||
389 | M_ASN1_D2I_get(ret->policyid, d2i_ASN1_OBJECT); | ||
390 | if(!M_ASN1_D2I_end_sequence()) { | ||
391 | M_ASN1_D2I_get_seq_type (POLICYQUALINFO, ret->qualifiers, | ||
392 | d2i_POLICYQUALINFO, POLICYQUALINFO_free); | ||
393 | } | ||
394 | M_ASN1_D2I_Finish(a, POLICYINFO_free, ASN1_F_D2I_POLICYINFO); | ||
395 | } | ||
396 | |||
397 | void POLICYINFO_free(POLICYINFO *a) | ||
398 | { | ||
399 | if (a == NULL) return; | ||
400 | ASN1_OBJECT_free(a->policyid); | ||
401 | sk_POLICYQUALINFO_pop_free(a->qualifiers, POLICYQUALINFO_free); | ||
402 | Free (a); | ||
403 | } | ||
404 | |||
405 | static void print_qualifiers(BIO *out, STACK_OF(POLICYQUALINFO) *quals, | ||
406 | int indent) | ||
407 | { | ||
408 | POLICYQUALINFO *qualinfo; | ||
409 | int i; | ||
410 | for(i = 0; i < sk_POLICYQUALINFO_num(quals); i++) { | ||
411 | qualinfo = sk_POLICYQUALINFO_value(quals, i); | ||
412 | switch(OBJ_obj2nid(qualinfo->pqualid)) | ||
413 | { | ||
414 | case NID_id_qt_cps: | ||
415 | BIO_printf(out, "%*sCPS: %s\n", indent, "", | ||
416 | qualinfo->d.cpsuri->data); | ||
417 | break; | ||
418 | |||
419 | case NID_id_qt_unotice: | ||
420 | BIO_printf(out, "%*sUser Notice:\n", indent, ""); | ||
421 | print_notice(out, qualinfo->d.usernotice, indent + 2); | ||
422 | break; | ||
423 | |||
424 | default: | ||
425 | BIO_printf(out, "%*sUnknown Qualifier: ", | ||
426 | indent + 2, ""); | ||
427 | |||
428 | i2a_ASN1_OBJECT(out, qualinfo->pqualid); | ||
429 | BIO_puts(out, "\n"); | ||
430 | break; | ||
431 | } | ||
432 | } | ||
433 | } | ||
434 | |||
435 | static void print_notice(BIO *out, USERNOTICE *notice, int indent) | ||
436 | { | ||
437 | int i; | ||
438 | if(notice->noticeref) { | ||
439 | NOTICEREF *ref; | ||
440 | ref = notice->noticeref; | ||
441 | BIO_printf(out, "%*sOrganization: %s\n", indent, "", | ||
442 | ref->organization->data); | ||
443 | BIO_printf(out, "%*sNumber%s: ", indent, "", | ||
444 | (sk_num(ref->noticenos) > 1) ? "s" : ""); | ||
445 | for(i = 0; i < sk_num(ref->noticenos); i++) { | ||
446 | ASN1_INTEGER *num; | ||
447 | char *tmp; | ||
448 | num = (ASN1_INTEGER *)sk_value(ref->noticenos, i); | ||
449 | if(i) BIO_puts(out, ", "); | ||
450 | tmp = i2s_ASN1_INTEGER(NULL, num); | ||
451 | BIO_puts(out, tmp); | ||
452 | Free(tmp); | ||
453 | } | ||
454 | BIO_puts(out, "\n"); | ||
455 | } | ||
456 | if(notice->exptext) | ||
457 | BIO_printf(out, "%*sExplicit Text: %s\n", indent, "", | ||
458 | notice->exptext->data); | ||
459 | } | ||
460 | |||
461 | |||
462 | |||
463 | int i2d_POLICYQUALINFO(POLICYQUALINFO *a, unsigned char **pp) | ||
464 | { | ||
465 | M_ASN1_I2D_vars(a); | ||
466 | |||
467 | M_ASN1_I2D_len (a->pqualid, i2d_ASN1_OBJECT); | ||
468 | switch(OBJ_obj2nid(a->pqualid)) { | ||
469 | case NID_id_qt_cps: | ||
470 | M_ASN1_I2D_len(a->d.cpsuri, i2d_ASN1_IA5STRING); | ||
471 | break; | ||
472 | |||
473 | case NID_id_qt_unotice: | ||
474 | M_ASN1_I2D_len(a->d.usernotice, i2d_USERNOTICE); | ||
475 | break; | ||
476 | |||
477 | default: | ||
478 | M_ASN1_I2D_len(a->d.other, i2d_ASN1_TYPE); | ||
479 | break; | ||
480 | } | ||
481 | |||
482 | M_ASN1_I2D_seq_total(); | ||
483 | |||
484 | M_ASN1_I2D_put (a->pqualid, i2d_ASN1_OBJECT); | ||
485 | switch(OBJ_obj2nid(a->pqualid)) { | ||
486 | case NID_id_qt_cps: | ||
487 | M_ASN1_I2D_put(a->d.cpsuri, i2d_ASN1_IA5STRING); | ||
488 | break; | ||
489 | |||
490 | case NID_id_qt_unotice: | ||
491 | M_ASN1_I2D_put(a->d.usernotice, i2d_USERNOTICE); | ||
492 | break; | ||
493 | |||
494 | default: | ||
495 | M_ASN1_I2D_put(a->d.other, i2d_ASN1_TYPE); | ||
496 | break; | ||
497 | } | ||
498 | |||
499 | M_ASN1_I2D_finish(); | ||
500 | } | ||
501 | |||
502 | POLICYQUALINFO *POLICYQUALINFO_new(void) | ||
503 | { | ||
504 | POLICYQUALINFO *ret=NULL; | ||
505 | ASN1_CTX c; | ||
506 | M_ASN1_New_Malloc(ret, POLICYQUALINFO); | ||
507 | ret->pqualid = NULL; | ||
508 | ret->d.other = NULL; | ||
509 | return (ret); | ||
510 | M_ASN1_New_Error(ASN1_F_POLICYQUALINFO_NEW); | ||
511 | } | ||
512 | |||
513 | POLICYQUALINFO *d2i_POLICYQUALINFO(POLICYQUALINFO **a, unsigned char **pp, | ||
514 | long length) | ||
515 | { | ||
516 | M_ASN1_D2I_vars(a,POLICYQUALINFO *,POLICYQUALINFO_new); | ||
517 | M_ASN1_D2I_Init(); | ||
518 | M_ASN1_D2I_start_sequence(); | ||
519 | M_ASN1_D2I_get (ret->pqualid, d2i_ASN1_OBJECT); | ||
520 | switch(OBJ_obj2nid(ret->pqualid)) { | ||
521 | case NID_id_qt_cps: | ||
522 | M_ASN1_D2I_get(ret->d.cpsuri, d2i_ASN1_IA5STRING); | ||
523 | break; | ||
524 | |||
525 | case NID_id_qt_unotice: | ||
526 | M_ASN1_D2I_get(ret->d.usernotice, d2i_USERNOTICE); | ||
527 | break; | ||
528 | |||
529 | default: | ||
530 | M_ASN1_D2I_get(ret->d.other, d2i_ASN1_TYPE); | ||
531 | break; | ||
532 | } | ||
533 | M_ASN1_D2I_Finish(a, POLICYQUALINFO_free, ASN1_F_D2I_POLICYQUALINFO); | ||
534 | } | ||
535 | |||
536 | void POLICYQUALINFO_free(POLICYQUALINFO *a) | ||
537 | { | ||
538 | if (a == NULL) return; | ||
539 | switch(OBJ_obj2nid(a->pqualid)) { | ||
540 | case NID_id_qt_cps: | ||
541 | ASN1_IA5STRING_free(a->d.cpsuri); | ||
542 | break; | ||
543 | |||
544 | case NID_id_qt_unotice: | ||
545 | USERNOTICE_free(a->d.usernotice); | ||
546 | break; | ||
547 | |||
548 | default: | ||
549 | ASN1_TYPE_free(a->d.other); | ||
550 | break; | ||
551 | } | ||
552 | |||
553 | ASN1_OBJECT_free(a->pqualid); | ||
554 | Free (a); | ||
555 | } | ||
556 | |||
557 | int i2d_USERNOTICE(USERNOTICE *a, unsigned char **pp) | ||
558 | { | ||
559 | M_ASN1_I2D_vars(a); | ||
560 | |||
561 | M_ASN1_I2D_len (a->noticeref, i2d_NOTICEREF); | ||
562 | M_ASN1_I2D_len (a->exptext, i2d_DISPLAYTEXT); | ||
563 | |||
564 | M_ASN1_I2D_seq_total(); | ||
565 | |||
566 | M_ASN1_I2D_put (a->noticeref, i2d_NOTICEREF); | ||
567 | M_ASN1_I2D_put (a->exptext, i2d_DISPLAYTEXT); | ||
568 | |||
569 | M_ASN1_I2D_finish(); | ||
570 | } | ||
571 | |||
572 | USERNOTICE *USERNOTICE_new(void) | ||
573 | { | ||
574 | USERNOTICE *ret=NULL; | ||
575 | ASN1_CTX c; | ||
576 | M_ASN1_New_Malloc(ret, USERNOTICE); | ||
577 | ret->noticeref = NULL; | ||
578 | ret->exptext = NULL; | ||
579 | return (ret); | ||
580 | M_ASN1_New_Error(ASN1_F_USERNOTICE_NEW); | ||
581 | } | ||
582 | |||
583 | USERNOTICE *d2i_USERNOTICE(USERNOTICE **a, unsigned char **pp,long length) | ||
584 | { | ||
585 | M_ASN1_D2I_vars(a,USERNOTICE *,USERNOTICE_new); | ||
586 | M_ASN1_D2I_Init(); | ||
587 | M_ASN1_D2I_start_sequence(); | ||
588 | M_ASN1_D2I_get_opt(ret->noticeref, d2i_NOTICEREF, V_ASN1_SEQUENCE); | ||
589 | if (!M_ASN1_D2I_end_sequence()) { | ||
590 | M_ASN1_D2I_get(ret->exptext, d2i_DISPLAYTEXT); | ||
591 | } | ||
592 | M_ASN1_D2I_Finish(a, USERNOTICE_free, ASN1_F_D2I_USERNOTICE); | ||
593 | } | ||
594 | |||
595 | void USERNOTICE_free(USERNOTICE *a) | ||
596 | { | ||
597 | if (a == NULL) return; | ||
598 | NOTICEREF_free(a->noticeref); | ||
599 | DISPLAYTEXT_free(a->exptext); | ||
600 | Free (a); | ||
601 | } | ||
602 | |||
603 | int i2d_NOTICEREF(NOTICEREF *a, unsigned char **pp) | ||
604 | { | ||
605 | M_ASN1_I2D_vars(a); | ||
606 | |||
607 | M_ASN1_I2D_len (a->organization, i2d_DISPLAYTEXT); | ||
608 | M_ASN1_I2D_len_SEQUENCE(a->noticenos, i2d_ASN1_INTEGER); | ||
609 | |||
610 | M_ASN1_I2D_seq_total(); | ||
611 | |||
612 | M_ASN1_I2D_put (a->organization, i2d_DISPLAYTEXT); | ||
613 | M_ASN1_I2D_put_SEQUENCE(a->noticenos, i2d_ASN1_INTEGER); | ||
614 | |||
615 | M_ASN1_I2D_finish(); | ||
616 | } | ||
617 | |||
618 | NOTICEREF *NOTICEREF_new(void) | ||
619 | { | ||
620 | NOTICEREF *ret=NULL; | ||
621 | ASN1_CTX c; | ||
622 | M_ASN1_New_Malloc(ret, NOTICEREF); | ||
623 | ret->organization = NULL; | ||
624 | ret->noticenos = NULL; | ||
625 | return (ret); | ||
626 | M_ASN1_New_Error(ASN1_F_NOTICEREF_NEW); | ||
627 | } | ||
628 | |||
629 | NOTICEREF *d2i_NOTICEREF(NOTICEREF **a, unsigned char **pp,long length) | ||
630 | { | ||
631 | M_ASN1_D2I_vars(a,NOTICEREF *,NOTICEREF_new); | ||
632 | M_ASN1_D2I_Init(); | ||
633 | M_ASN1_D2I_start_sequence(); | ||
634 | /* This is to cope with some broken encodings that use IA5STRING for | ||
635 | * the organization field | ||
636 | */ | ||
637 | M_ASN1_D2I_get_opt(ret->organization, d2i_ASN1_IA5STRING, | ||
638 | V_ASN1_IA5STRING); | ||
639 | if(!ret->organization) { | ||
640 | M_ASN1_D2I_get(ret->organization, d2i_DISPLAYTEXT); | ||
641 | } | ||
642 | M_ASN1_D2I_get_seq(ret->noticenos, d2i_ASN1_INTEGER, ASN1_STRING_free); | ||
643 | M_ASN1_D2I_Finish(a, NOTICEREF_free, ASN1_F_D2I_NOTICEREF); | ||
644 | } | ||
645 | |||
646 | void NOTICEREF_free(NOTICEREF *a) | ||
647 | { | ||
648 | if (a == NULL) return; | ||
649 | DISPLAYTEXT_free(a->organization); | ||
650 | sk_pop_free(a->noticenos, ASN1_STRING_free); | ||
651 | Free (a); | ||
652 | } | ||
653 | |||
654 | IMPLEMENT_STACK_OF(POLICYQUALINFO) | ||
655 | IMPLEMENT_ASN1_SET_OF(POLICYQUALINFO) | ||
diff --git a/src/lib/libcrypto/x509v3/v3_crld.c b/src/lib/libcrypto/x509v3/v3_crld.c new file mode 100644 index 0000000000..897ffb63e4 --- /dev/null +++ b/src/lib/libcrypto/x509v3/v3_crld.c | |||
@@ -0,0 +1,283 @@ | |||
1 | /* v3_crld.c */ | ||
2 | /* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL | ||
3 | * project 1999. | ||
4 | */ | ||
5 | /* ==================================================================== | ||
6 | * Copyright (c) 1999 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 | #include "cryptlib.h" | ||
61 | #include <openssl/conf.h> | ||
62 | #include <openssl/asn1.h> | ||
63 | #include <openssl/asn1_mac.h> | ||
64 | #include <openssl/x509v3.h> | ||
65 | |||
66 | static STACK_OF(CONF_VALUE) *i2v_crld(X509V3_EXT_METHOD *method, | ||
67 | STACK_OF(DIST_POINT) *crld, STACK_OF(CONF_VALUE) *extlist); | ||
68 | static STACK_OF(DIST_POINT) *v2i_crld(X509V3_EXT_METHOD *method, | ||
69 | X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval); | ||
70 | |||
71 | X509V3_EXT_METHOD v3_crld = { | ||
72 | NID_crl_distribution_points, X509V3_EXT_MULTILINE, | ||
73 | (X509V3_EXT_NEW)CRL_DIST_POINTS_new, | ||
74 | (X509V3_EXT_FREE)CRL_DIST_POINTS_free, | ||
75 | (X509V3_EXT_D2I)d2i_CRL_DIST_POINTS, | ||
76 | (X509V3_EXT_I2D)i2d_CRL_DIST_POINTS, | ||
77 | NULL, NULL, | ||
78 | (X509V3_EXT_I2V)i2v_crld, | ||
79 | (X509V3_EXT_V2I)v2i_crld, | ||
80 | NULL, NULL, NULL | ||
81 | }; | ||
82 | |||
83 | static STACK_OF(CONF_VALUE) *i2v_crld(X509V3_EXT_METHOD *method, | ||
84 | STACK_OF(DIST_POINT) *crld, STACK_OF(CONF_VALUE) *exts) | ||
85 | { | ||
86 | DIST_POINT *point; | ||
87 | int i; | ||
88 | for(i = 0; i < sk_DIST_POINT_num(crld); i++) { | ||
89 | point = sk_DIST_POINT_value(crld, i); | ||
90 | if(point->distpoint->fullname) { | ||
91 | exts = i2v_GENERAL_NAMES(NULL, | ||
92 | point->distpoint->fullname, exts); | ||
93 | } | ||
94 | if(point->reasons) | ||
95 | X509V3_add_value("reasons","<UNSUPPORTED>", &exts); | ||
96 | if(point->CRLissuer) | ||
97 | X509V3_add_value("CRLissuer","<UNSUPPORTED>", &exts); | ||
98 | if(point->distpoint->relativename) | ||
99 | X509V3_add_value("RelativeName","<UNSUPPORTED>", &exts); | ||
100 | } | ||
101 | return exts; | ||
102 | } | ||
103 | |||
104 | static STACK_OF(DIST_POINT) *v2i_crld(X509V3_EXT_METHOD *method, | ||
105 | X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval) | ||
106 | { | ||
107 | STACK_OF(DIST_POINT) *crld = NULL; | ||
108 | STACK_OF(GENERAL_NAME) *gens = NULL; | ||
109 | GENERAL_NAME *gen = NULL; | ||
110 | CONF_VALUE *cnf; | ||
111 | int i; | ||
112 | if(!(crld = sk_DIST_POINT_new(NULL))) goto merr; | ||
113 | for(i = 0; i < sk_CONF_VALUE_num(nval); i++) { | ||
114 | DIST_POINT *point; | ||
115 | cnf = sk_CONF_VALUE_value(nval, i); | ||
116 | if(!(gen = v2i_GENERAL_NAME(method, ctx, cnf))) goto err; | ||
117 | if(!(gens = GENERAL_NAMES_new())) goto merr; | ||
118 | if(!sk_GENERAL_NAME_push(gens, gen)) goto merr; | ||
119 | gen = NULL; | ||
120 | if(!(point = DIST_POINT_new())) goto merr; | ||
121 | if(!sk_DIST_POINT_push(crld, point)) { | ||
122 | DIST_POINT_free(point); | ||
123 | goto merr; | ||
124 | } | ||
125 | if(!(point->distpoint = DIST_POINT_NAME_new())) goto merr; | ||
126 | point->distpoint->fullname = gens; | ||
127 | gens = NULL; | ||
128 | } | ||
129 | return crld; | ||
130 | |||
131 | merr: | ||
132 | X509V3err(X509V3_F_V2I_CRLD,ERR_R_MALLOC_FAILURE); | ||
133 | err: | ||
134 | GENERAL_NAME_free(gen); | ||
135 | GENERAL_NAMES_free(gens); | ||
136 | sk_DIST_POINT_pop_free(crld, DIST_POINT_free); | ||
137 | return NULL; | ||
138 | } | ||
139 | |||
140 | int i2d_CRL_DIST_POINTS(STACK_OF(DIST_POINT) *a, unsigned char **pp) | ||
141 | { | ||
142 | |||
143 | return i2d_ASN1_SET_OF_DIST_POINT(a, pp, i2d_DIST_POINT, V_ASN1_SEQUENCE, | ||
144 | V_ASN1_UNIVERSAL, IS_SEQUENCE);} | ||
145 | |||
146 | STACK_OF(DIST_POINT) *CRL_DIST_POINTS_new(void) | ||
147 | { | ||
148 | return sk_DIST_POINT_new_null(); | ||
149 | } | ||
150 | |||
151 | void CRL_DIST_POINTS_free(STACK_OF(DIST_POINT) *a) | ||
152 | { | ||
153 | sk_DIST_POINT_pop_free(a, DIST_POINT_free); | ||
154 | } | ||
155 | |||
156 | STACK_OF(DIST_POINT) *d2i_CRL_DIST_POINTS(STACK_OF(DIST_POINT) **a, | ||
157 | unsigned char **pp,long length) | ||
158 | { | ||
159 | return d2i_ASN1_SET_OF_DIST_POINT(a, pp, length, d2i_DIST_POINT, | ||
160 | DIST_POINT_free, V_ASN1_SEQUENCE, V_ASN1_UNIVERSAL); | ||
161 | |||
162 | } | ||
163 | |||
164 | IMPLEMENT_STACK_OF(DIST_POINT) | ||
165 | IMPLEMENT_ASN1_SET_OF(DIST_POINT) | ||
166 | |||
167 | int i2d_DIST_POINT(DIST_POINT *a, unsigned char **pp) | ||
168 | { | ||
169 | int v = 0; | ||
170 | M_ASN1_I2D_vars(a); | ||
171 | /* NB: underlying type is a CHOICE so need EXPLICIT tagging */ | ||
172 | M_ASN1_I2D_len_EXP_opt (a->distpoint, i2d_DIST_POINT_NAME, 0, v); | ||
173 | M_ASN1_I2D_len_IMP_opt (a->reasons, i2d_ASN1_BIT_STRING); | ||
174 | M_ASN1_I2D_len_IMP_opt (a->CRLissuer, i2d_GENERAL_NAMES); | ||
175 | |||
176 | M_ASN1_I2D_seq_total(); | ||
177 | |||
178 | M_ASN1_I2D_put_EXP_opt (a->distpoint, i2d_DIST_POINT_NAME, 0, v); | ||
179 | M_ASN1_I2D_put_IMP_opt (a->reasons, i2d_ASN1_BIT_STRING, 1); | ||
180 | M_ASN1_I2D_put_IMP_opt (a->CRLissuer, i2d_GENERAL_NAMES, 2); | ||
181 | |||
182 | M_ASN1_I2D_finish(); | ||
183 | } | ||
184 | |||
185 | DIST_POINT *DIST_POINT_new(void) | ||
186 | { | ||
187 | DIST_POINT *ret=NULL; | ||
188 | ASN1_CTX c; | ||
189 | M_ASN1_New_Malloc(ret, DIST_POINT); | ||
190 | ret->distpoint = NULL; | ||
191 | ret->reasons = NULL; | ||
192 | ret->CRLissuer = NULL; | ||
193 | return (ret); | ||
194 | M_ASN1_New_Error(ASN1_F_DIST_POINT_NEW); | ||
195 | } | ||
196 | |||
197 | DIST_POINT *d2i_DIST_POINT(DIST_POINT **a, unsigned char **pp, long length) | ||
198 | { | ||
199 | M_ASN1_D2I_vars(a,DIST_POINT *,DIST_POINT_new); | ||
200 | M_ASN1_D2I_Init(); | ||
201 | M_ASN1_D2I_start_sequence(); | ||
202 | M_ASN1_D2I_get_EXP_opt (ret->distpoint, d2i_DIST_POINT_NAME, 0); | ||
203 | M_ASN1_D2I_get_IMP_opt (ret->reasons, d2i_ASN1_BIT_STRING, 1, | ||
204 | V_ASN1_BIT_STRING); | ||
205 | M_ASN1_D2I_get_IMP_opt (ret->CRLissuer, d2i_GENERAL_NAMES, 2, | ||
206 | V_ASN1_SEQUENCE); | ||
207 | M_ASN1_D2I_Finish(a, DIST_POINT_free, ASN1_F_D2I_DIST_POINT); | ||
208 | } | ||
209 | |||
210 | void DIST_POINT_free(DIST_POINT *a) | ||
211 | { | ||
212 | if (a == NULL) return; | ||
213 | DIST_POINT_NAME_free(a->distpoint); | ||
214 | ASN1_BIT_STRING_free(a->reasons); | ||
215 | sk_GENERAL_NAME_pop_free(a->CRLissuer, GENERAL_NAME_free); | ||
216 | Free ((char *)a); | ||
217 | } | ||
218 | |||
219 | int i2d_DIST_POINT_NAME(DIST_POINT_NAME *a, unsigned char **pp) | ||
220 | { | ||
221 | int v = 0; | ||
222 | M_ASN1_I2D_vars(a); | ||
223 | |||
224 | if(a->fullname) { | ||
225 | M_ASN1_I2D_len_IMP_opt (a->fullname, i2d_GENERAL_NAMES); | ||
226 | } else { | ||
227 | M_ASN1_I2D_len_EXP_opt (a->relativename, i2d_X509_NAME, 1, v); | ||
228 | } | ||
229 | |||
230 | /* Don't want a SEQUENCE so... */ | ||
231 | if(pp == NULL) return ret; | ||
232 | p = *pp; | ||
233 | |||
234 | if(a->fullname) { | ||
235 | M_ASN1_I2D_put_IMP_opt (a->fullname, i2d_GENERAL_NAMES, 0); | ||
236 | } else { | ||
237 | M_ASN1_I2D_put_EXP_opt (a->relativename, i2d_X509_NAME, 1, v); | ||
238 | } | ||
239 | M_ASN1_I2D_finish(); | ||
240 | } | ||
241 | |||
242 | DIST_POINT_NAME *DIST_POINT_NAME_new(void) | ||
243 | { | ||
244 | DIST_POINT_NAME *ret=NULL; | ||
245 | ASN1_CTX c; | ||
246 | M_ASN1_New_Malloc(ret, DIST_POINT_NAME); | ||
247 | ret->fullname = NULL; | ||
248 | ret->relativename = NULL; | ||
249 | return (ret); | ||
250 | M_ASN1_New_Error(ASN1_F_DIST_POINT_NAME_NEW); | ||
251 | } | ||
252 | |||
253 | void DIST_POINT_NAME_free(DIST_POINT_NAME *a) | ||
254 | { | ||
255 | if (a == NULL) return; | ||
256 | X509_NAME_free(a->relativename); | ||
257 | sk_GENERAL_NAME_pop_free(a->fullname, GENERAL_NAME_free); | ||
258 | Free ((char *)a); | ||
259 | } | ||
260 | |||
261 | DIST_POINT_NAME *d2i_DIST_POINT_NAME(DIST_POINT_NAME **a, unsigned char **pp, | ||
262 | long length) | ||
263 | { | ||
264 | unsigned char _tmp, tag; | ||
265 | M_ASN1_D2I_vars(a,DIST_POINT_NAME *,DIST_POINT_NAME_new); | ||
266 | M_ASN1_D2I_Init(); | ||
267 | c.slen = length; | ||
268 | |||
269 | _tmp = M_ASN1_next; | ||
270 | tag = _tmp & ~V_ASN1_CONSTRUCTED; | ||
271 | |||
272 | if(tag == (0|V_ASN1_CONTEXT_SPECIFIC)) { | ||
273 | M_ASN1_D2I_get_imp(ret->fullname, d2i_GENERAL_NAMES, | ||
274 | V_ASN1_SEQUENCE); | ||
275 | } else if (tag == (1|V_ASN1_CONTEXT_SPECIFIC)) { | ||
276 | M_ASN1_D2I_get_EXP_opt (ret->relativename, d2i_X509_NAME, 1); | ||
277 | } else { | ||
278 | c.error = ASN1_R_BAD_TAG; | ||
279 | goto err; | ||
280 | } | ||
281 | |||
282 | M_ASN1_D2I_Finish(a, DIST_POINT_NAME_free, ASN1_F_D2I_DIST_POINT_NAME); | ||
283 | } | ||
diff --git a/src/lib/libcrypto/x509v3/v3_enum.c b/src/lib/libcrypto/x509v3/v3_enum.c new file mode 100644 index 0000000000..db423548ff --- /dev/null +++ b/src/lib/libcrypto/x509v3/v3_enum.c | |||
@@ -0,0 +1,103 @@ | |||
1 | /* v3_enum.c */ | ||
2 | /* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL | ||
3 | * project 1999. | ||
4 | */ | ||
5 | /* ==================================================================== | ||
6 | * Copyright (c) 1999 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 | #include "cryptlib.h" | ||
61 | #include <openssl/x509v3.h> | ||
62 | |||
63 | static ASN1_ENUMERATED *asn1_enumerated_new(void); | ||
64 | |||
65 | static ENUMERATED_NAMES crl_reasons[] = { | ||
66 | {0, "Unspecified", "unspecified"}, | ||
67 | {1, "Key Compromise", "keyCompromise"}, | ||
68 | {2, "CA Compromise", "CACompromise"}, | ||
69 | {3, "Affiliation Changed", "affiliationChanged"}, | ||
70 | {4, "Superseded", "superseded"}, | ||
71 | {5, "Cessation Of Operation", "cessationOfOperation"}, | ||
72 | {6, "Certificate Hold", "certificateHold"}, | ||
73 | {8, "Remove From CRL", "removeFromCRL"}, | ||
74 | {-1, NULL, NULL} | ||
75 | }; | ||
76 | |||
77 | X509V3_EXT_METHOD v3_crl_reason = { | ||
78 | NID_crl_reason, 0, | ||
79 | (X509V3_EXT_NEW)asn1_enumerated_new, | ||
80 | (X509V3_EXT_FREE)ASN1_STRING_free, | ||
81 | (X509V3_EXT_D2I)d2i_ASN1_ENUMERATED, | ||
82 | (X509V3_EXT_I2D)i2d_ASN1_ENUMERATED, | ||
83 | (X509V3_EXT_I2S)i2s_ASN1_ENUMERATED_TABLE, | ||
84 | (X509V3_EXT_S2I)NULL, | ||
85 | NULL, NULL, NULL, NULL, crl_reasons}; | ||
86 | |||
87 | |||
88 | static ASN1_ENUMERATED *asn1_enumerated_new(void) | ||
89 | { | ||
90 | return ASN1_ENUMERATED_new(); | ||
91 | } | ||
92 | |||
93 | char *i2s_ASN1_ENUMERATED_TABLE(X509V3_EXT_METHOD *method, | ||
94 | ASN1_ENUMERATED *e) | ||
95 | { | ||
96 | ENUMERATED_NAMES *enam; | ||
97 | long strval; | ||
98 | strval = ASN1_ENUMERATED_get(e); | ||
99 | for(enam = method->usr_data; enam->lname; enam++) { | ||
100 | if(strval == enam->bitnum) return BUF_strdup(enam->lname); | ||
101 | } | ||
102 | return i2s_ASN1_ENUMERATED(method, e); | ||
103 | } | ||
diff --git a/src/lib/libcrypto/x509v3/v3_extku.c b/src/lib/libcrypto/x509v3/v3_extku.c new file mode 100644 index 0000000000..e039d21cbf --- /dev/null +++ b/src/lib/libcrypto/x509v3/v3_extku.c | |||
@@ -0,0 +1,150 @@ | |||
1 | /* v3_extku.c */ | ||
2 | /* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL | ||
3 | * project 1999. | ||
4 | */ | ||
5 | /* ==================================================================== | ||
6 | * Copyright (c) 1999 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/conf.h> | ||
64 | #include <openssl/x509v3.h> | ||
65 | |||
66 | static STACK_OF(ASN1_OBJECT) *v2i_ext_ku(X509V3_EXT_METHOD *method, | ||
67 | X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval); | ||
68 | static STACK_OF(CONF_VALUE) *i2v_ext_ku(X509V3_EXT_METHOD *method, | ||
69 | STACK_OF(ASN1_OBJECT) *eku, STACK_OF(CONF_VALUE) *extlist); | ||
70 | X509V3_EXT_METHOD v3_ext_ku = { | ||
71 | NID_ext_key_usage, 0, | ||
72 | (X509V3_EXT_NEW)ext_ku_new, | ||
73 | (X509V3_EXT_FREE)ext_ku_free, | ||
74 | (X509V3_EXT_D2I)d2i_ext_ku, | ||
75 | (X509V3_EXT_I2D)i2d_ext_ku, | ||
76 | NULL, NULL, | ||
77 | (X509V3_EXT_I2V)i2v_ext_ku, | ||
78 | (X509V3_EXT_V2I)v2i_ext_ku, | ||
79 | NULL,NULL, | ||
80 | NULL | ||
81 | }; | ||
82 | |||
83 | STACK_OF(ASN1_OBJECT) *ext_ku_new(void) | ||
84 | { | ||
85 | return sk_ASN1_OBJECT_new_null(); | ||
86 | } | ||
87 | |||
88 | void ext_ku_free(STACK_OF(ASN1_OBJECT) *eku) | ||
89 | { | ||
90 | sk_ASN1_OBJECT_pop_free(eku, ASN1_OBJECT_free); | ||
91 | return; | ||
92 | } | ||
93 | |||
94 | int i2d_ext_ku(STACK_OF(ASN1_OBJECT) *a, unsigned char **pp) | ||
95 | { | ||
96 | return i2d_ASN1_SET_OF_ASN1_OBJECT(a, pp, i2d_ASN1_OBJECT, | ||
97 | V_ASN1_SEQUENCE, V_ASN1_UNIVERSAL, IS_SEQUENCE); | ||
98 | } | ||
99 | |||
100 | STACK_OF(ASN1_OBJECT) *d2i_ext_ku(STACK_OF(ASN1_OBJECT) **a, | ||
101 | unsigned char **pp, long length) | ||
102 | { | ||
103 | return d2i_ASN1_SET_OF_ASN1_OBJECT(a, pp, length, d2i_ASN1_OBJECT, | ||
104 | ASN1_OBJECT_free, V_ASN1_SEQUENCE, V_ASN1_UNIVERSAL); | ||
105 | } | ||
106 | |||
107 | |||
108 | |||
109 | static STACK_OF(CONF_VALUE) *i2v_ext_ku(X509V3_EXT_METHOD *method, | ||
110 | STACK_OF(ASN1_OBJECT) *eku, STACK_OF(CONF_VALUE) *ext_list) | ||
111 | { | ||
112 | int i; | ||
113 | ASN1_OBJECT *obj; | ||
114 | char obj_tmp[80]; | ||
115 | for(i = 0; i < sk_ASN1_OBJECT_num(eku); i++) { | ||
116 | obj = sk_ASN1_OBJECT_value(eku, i); | ||
117 | i2t_ASN1_OBJECT(obj_tmp, 80, obj); | ||
118 | X509V3_add_value(NULL, obj_tmp, &ext_list); | ||
119 | } | ||
120 | return ext_list; | ||
121 | } | ||
122 | |||
123 | static STACK_OF(ASN1_OBJECT) *v2i_ext_ku(X509V3_EXT_METHOD *method, | ||
124 | X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval) | ||
125 | { | ||
126 | STACK_OF(ASN1_OBJECT) *extku; | ||
127 | char *extval; | ||
128 | ASN1_OBJECT *objtmp; | ||
129 | CONF_VALUE *val; | ||
130 | int i; | ||
131 | |||
132 | if(!(extku = sk_ASN1_OBJECT_new(NULL))) { | ||
133 | X509V3err(X509V3_F_V2I_EXT_KU,ERR_R_MALLOC_FAILURE); | ||
134 | return NULL; | ||
135 | } | ||
136 | |||
137 | for(i = 0; i < sk_CONF_VALUE_num(nval); i++) { | ||
138 | val = sk_CONF_VALUE_value(nval, i); | ||
139 | if(val->value) extval = val->value; | ||
140 | else extval = val->name; | ||
141 | if(!(objtmp = OBJ_txt2obj(extval, 0))) { | ||
142 | sk_ASN1_OBJECT_pop_free(extku, ASN1_OBJECT_free); | ||
143 | X509V3err(X509V3_F_V2I_EXT_KU,X509V3_R_INVALID_OBJECT_IDENTIFIER); | ||
144 | X509V3_conf_err(val); | ||
145 | return NULL; | ||
146 | } | ||
147 | sk_ASN1_OBJECT_push(extku, objtmp); | ||
148 | } | ||
149 | return extku; | ||
150 | } | ||
diff --git a/src/lib/libcrypto/x509v3/v3_genn.c b/src/lib/libcrypto/x509v3/v3_genn.c new file mode 100644 index 0000000000..af716232f8 --- /dev/null +++ b/src/lib/libcrypto/x509v3/v3_genn.c | |||
@@ -0,0 +1,237 @@ | |||
1 | /* v3_genn.c */ | ||
2 | /* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL | ||
3 | * project 1999. | ||
4 | */ | ||
5 | /* ==================================================================== | ||
6 | * Copyright (c) 1999 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/asn1_mac.h> | ||
64 | #include <openssl/conf.h> | ||
65 | #include <openssl/x509v3.h> | ||
66 | |||
67 | int i2d_GENERAL_NAME(GENERAL_NAME *a, unsigned char **pp) | ||
68 | { | ||
69 | unsigned char *p; | ||
70 | int ret; | ||
71 | |||
72 | ret = 0; | ||
73 | |||
74 | /* Save the location of initial TAG */ | ||
75 | if(pp) p = *pp; | ||
76 | else p = NULL; | ||
77 | |||
78 | /* GEN_DNAME needs special treatment because of EXPLICIT tag */ | ||
79 | |||
80 | if(a->type == GEN_DIRNAME) { | ||
81 | int v = 0; | ||
82 | M_ASN1_I2D_len_EXP_opt(a->d.dirn, i2d_X509_NAME, 4, v); | ||
83 | if(!p) return ret; | ||
84 | M_ASN1_I2D_put_EXP_opt(a->d.dirn, i2d_X509_NAME, 4, v); | ||
85 | *pp = p; | ||
86 | return ret; | ||
87 | } | ||
88 | |||
89 | switch(a->type) { | ||
90 | |||
91 | case GEN_OTHERNAME: | ||
92 | case GEN_X400: | ||
93 | case GEN_EDIPARTY: | ||
94 | ret = i2d_ASN1_TYPE(a->d.other, pp); | ||
95 | break; | ||
96 | |||
97 | case GEN_EMAIL: | ||
98 | case GEN_DNS: | ||
99 | case GEN_URI: | ||
100 | ret = i2d_ASN1_IA5STRING(a->d.ia5, pp); | ||
101 | break; | ||
102 | |||
103 | case GEN_IPADD: | ||
104 | ret = i2d_ASN1_OCTET_STRING(a->d.ip, pp); | ||
105 | break; | ||
106 | |||
107 | case GEN_RID: | ||
108 | ret = i2d_ASN1_OBJECT(a->d.rid, pp); | ||
109 | break; | ||
110 | } | ||
111 | /* Replace TAG with IMPLICIT value */ | ||
112 | if(p) *p = (*p & V_ASN1_CONSTRUCTED) | a->type; | ||
113 | return ret; | ||
114 | } | ||
115 | |||
116 | GENERAL_NAME *GENERAL_NAME_new() | ||
117 | { | ||
118 | GENERAL_NAME *ret=NULL; | ||
119 | ASN1_CTX c; | ||
120 | M_ASN1_New_Malloc(ret, GENERAL_NAME); | ||
121 | ret->type = -1; | ||
122 | ret->d.ptr = NULL; | ||
123 | return (ret); | ||
124 | M_ASN1_New_Error(ASN1_F_GENERAL_NAME_NEW); | ||
125 | } | ||
126 | |||
127 | GENERAL_NAME *d2i_GENERAL_NAME(GENERAL_NAME **a, unsigned char **pp, | ||
128 | long length) | ||
129 | { | ||
130 | unsigned char _tmp; | ||
131 | M_ASN1_D2I_vars(a,GENERAL_NAME *,GENERAL_NAME_new); | ||
132 | M_ASN1_D2I_Init(); | ||
133 | c.slen = length; | ||
134 | |||
135 | _tmp = M_ASN1_next; | ||
136 | ret->type = _tmp & ~V_ASN1_CONSTRUCTED; | ||
137 | |||
138 | switch(ret->type) { | ||
139 | /* Just put these in a "blob" for now */ | ||
140 | case GEN_OTHERNAME: | ||
141 | case GEN_X400: | ||
142 | case GEN_EDIPARTY: | ||
143 | M_ASN1_D2I_get_imp(ret->d.other, d2i_ASN1_TYPE,V_ASN1_SEQUENCE); | ||
144 | break; | ||
145 | |||
146 | case GEN_EMAIL: | ||
147 | case GEN_DNS: | ||
148 | case GEN_URI: | ||
149 | M_ASN1_D2I_get_imp(ret->d.ia5, d2i_ASN1_IA5STRING, | ||
150 | V_ASN1_IA5STRING); | ||
151 | break; | ||
152 | |||
153 | case GEN_DIRNAME: | ||
154 | M_ASN1_D2I_get_EXP_opt(ret->d.dirn, d2i_X509_NAME, 4); | ||
155 | break; | ||
156 | |||
157 | case GEN_IPADD: | ||
158 | M_ASN1_D2I_get_imp(ret->d.ip, d2i_ASN1_OCTET_STRING, | ||
159 | V_ASN1_OCTET_STRING); | ||
160 | break; | ||
161 | |||
162 | case GEN_RID: | ||
163 | M_ASN1_D2I_get_imp(ret->d.rid, d2i_ASN1_OBJECT,V_ASN1_OBJECT); | ||
164 | break; | ||
165 | |||
166 | default: | ||
167 | c.error = ASN1_R_BAD_TAG; | ||
168 | goto err; | ||
169 | } | ||
170 | |||
171 | c.slen = 0; | ||
172 | M_ASN1_D2I_Finish(a, GENERAL_NAME_free, ASN1_F_D2I_GENERAL_NAME); | ||
173 | } | ||
174 | |||
175 | void GENERAL_NAME_free(GENERAL_NAME *a) | ||
176 | { | ||
177 | if (a == NULL) return; | ||
178 | switch(a->type) { | ||
179 | case GEN_OTHERNAME: | ||
180 | case GEN_X400: | ||
181 | case GEN_EDIPARTY: | ||
182 | ASN1_TYPE_free(a->d.other); | ||
183 | break; | ||
184 | |||
185 | case GEN_EMAIL: | ||
186 | case GEN_DNS: | ||
187 | case GEN_URI: | ||
188 | |||
189 | ASN1_IA5STRING_free(a->d.ia5); | ||
190 | break; | ||
191 | |||
192 | case GEN_DIRNAME: | ||
193 | X509_NAME_free(a->d.dirn); | ||
194 | break; | ||
195 | |||
196 | case GEN_IPADD: | ||
197 | ASN1_OCTET_STRING_free(a->d.ip); | ||
198 | break; | ||
199 | |||
200 | case GEN_RID: | ||
201 | ASN1_OBJECT_free(a->d.rid); | ||
202 | break; | ||
203 | |||
204 | } | ||
205 | Free ((char *)a); | ||
206 | } | ||
207 | |||
208 | /* Now the GeneralNames versions: a SEQUENCE OF GeneralName These are needed as | ||
209 | * an explicit functions. | ||
210 | */ | ||
211 | |||
212 | STACK_OF(GENERAL_NAME) *GENERAL_NAMES_new() | ||
213 | { | ||
214 | return sk_GENERAL_NAME_new(NULL); | ||
215 | } | ||
216 | |||
217 | void GENERAL_NAMES_free(STACK_OF(GENERAL_NAME) *a) | ||
218 | { | ||
219 | sk_GENERAL_NAME_pop_free(a, GENERAL_NAME_free); | ||
220 | } | ||
221 | |||
222 | STACK_OF(GENERAL_NAME) *d2i_GENERAL_NAMES(STACK_OF(GENERAL_NAME) **a, | ||
223 | unsigned char **pp, long length) | ||
224 | { | ||
225 | return d2i_ASN1_SET_OF_GENERAL_NAME(a, pp, length, d2i_GENERAL_NAME, | ||
226 | GENERAL_NAME_free, V_ASN1_SEQUENCE, V_ASN1_UNIVERSAL); | ||
227 | } | ||
228 | |||
229 | int i2d_GENERAL_NAMES(STACK_OF(GENERAL_NAME) *a, unsigned char **pp) | ||
230 | { | ||
231 | return i2d_ASN1_SET_OF_GENERAL_NAME(a, pp, i2d_GENERAL_NAME, V_ASN1_SEQUENCE, | ||
232 | V_ASN1_UNIVERSAL, IS_SEQUENCE); | ||
233 | } | ||
234 | |||
235 | IMPLEMENT_STACK_OF(GENERAL_NAME) | ||
236 | IMPLEMENT_ASN1_SET_OF(GENERAL_NAME) | ||
237 | |||
diff --git a/src/lib/libcrypto/x509v3/v3_ia5.c b/src/lib/libcrypto/x509v3/v3_ia5.c new file mode 100644 index 0000000000..3446c5cd6a --- /dev/null +++ b/src/lib/libcrypto/x509v3/v3_ia5.c | |||
@@ -0,0 +1,116 @@ | |||
1 | /* v3_ia5.c */ | ||
2 | /* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL | ||
3 | * project 1999. | ||
4 | */ | ||
5 | /* ==================================================================== | ||
6 | * Copyright (c) 1999 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/conf.h> | ||
64 | #include <openssl/x509v3.h> | ||
65 | |||
66 | static ASN1_IA5STRING *ia5string_new(void); | ||
67 | static char *i2s_ASN1_IA5STRING(X509V3_EXT_METHOD *method, ASN1_IA5STRING *ia5); | ||
68 | static ASN1_IA5STRING *s2i_ASN1_IA5STRING(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, char *str); | ||
69 | X509V3_EXT_METHOD v3_ns_ia5_list[] = { | ||
70 | EXT_IA5STRING(NID_netscape_base_url), | ||
71 | EXT_IA5STRING(NID_netscape_revocation_url), | ||
72 | EXT_IA5STRING(NID_netscape_ca_revocation_url), | ||
73 | EXT_IA5STRING(NID_netscape_renewal_url), | ||
74 | EXT_IA5STRING(NID_netscape_ca_policy_url), | ||
75 | EXT_IA5STRING(NID_netscape_ssl_server_name), | ||
76 | EXT_IA5STRING(NID_netscape_comment), | ||
77 | EXT_END | ||
78 | }; | ||
79 | |||
80 | |||
81 | static ASN1_IA5STRING *ia5string_new(void) | ||
82 | { | ||
83 | return ASN1_IA5STRING_new(); | ||
84 | } | ||
85 | |||
86 | static char *i2s_ASN1_IA5STRING(X509V3_EXT_METHOD *method, | ||
87 | ASN1_IA5STRING *ia5) | ||
88 | { | ||
89 | char *tmp; | ||
90 | if(!ia5 || !ia5->length) return NULL; | ||
91 | tmp = Malloc(ia5->length + 1); | ||
92 | memcpy(tmp, ia5->data, ia5->length); | ||
93 | tmp[ia5->length] = 0; | ||
94 | return tmp; | ||
95 | } | ||
96 | |||
97 | static ASN1_IA5STRING *s2i_ASN1_IA5STRING(X509V3_EXT_METHOD *method, | ||
98 | X509V3_CTX *ctx, char *str) | ||
99 | { | ||
100 | ASN1_IA5STRING *ia5; | ||
101 | if(!str) { | ||
102 | X509V3err(X509V3_F_S2I_ASN1_IA5STRING,X509V3_R_INVALID_NULL_ARGUMENT); | ||
103 | return NULL; | ||
104 | } | ||
105 | if(!(ia5 = ASN1_IA5STRING_new())) goto err; | ||
106 | if(!ASN1_STRING_set((ASN1_STRING *)ia5, (unsigned char*)str, | ||
107 | strlen(str))) { | ||
108 | ASN1_IA5STRING_free(ia5); | ||
109 | goto err; | ||
110 | } | ||
111 | return ia5; | ||
112 | err: | ||
113 | X509V3err(X509V3_F_S2I_ASN1_IA5STRING,ERR_R_MALLOC_FAILURE); | ||
114 | return NULL; | ||
115 | } | ||
116 | |||
diff --git a/src/lib/libcrypto/x509v3/v3_info.c b/src/lib/libcrypto/x509v3/v3_info.c new file mode 100644 index 0000000000..78d2135046 --- /dev/null +++ b/src/lib/libcrypto/x509v3/v3_info.c | |||
@@ -0,0 +1,236 @@ | |||
1 | /* v3_info.c */ | ||
2 | /* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL | ||
3 | * project 1999. | ||
4 | */ | ||
5 | /* ==================================================================== | ||
6 | * Copyright (c) 1999 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 | #include "cryptlib.h" | ||
61 | #include <openssl/conf.h> | ||
62 | #include <openssl/asn1.h> | ||
63 | #include <openssl/asn1_mac.h> | ||
64 | #include <openssl/x509v3.h> | ||
65 | |||
66 | static STACK_OF(CONF_VALUE) *i2v_AUTHORITY_INFO_ACCESS(X509V3_EXT_METHOD *method, | ||
67 | STACK_OF(ACCESS_DESCRIPTION) *ainfo, | ||
68 | STACK_OF(CONF_VALUE) *ret); | ||
69 | static STACK_OF(ACCESS_DESCRIPTION) *v2i_AUTHORITY_INFO_ACCESS(X509V3_EXT_METHOD *method, | ||
70 | X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval); | ||
71 | |||
72 | X509V3_EXT_METHOD v3_info = | ||
73 | { NID_info_access, X509V3_EXT_MULTILINE, | ||
74 | (X509V3_EXT_NEW)AUTHORITY_INFO_ACCESS_new, | ||
75 | (X509V3_EXT_FREE)AUTHORITY_INFO_ACCESS_free, | ||
76 | (X509V3_EXT_D2I)d2i_AUTHORITY_INFO_ACCESS, | ||
77 | (X509V3_EXT_I2D)i2d_AUTHORITY_INFO_ACCESS, | ||
78 | NULL, NULL, | ||
79 | (X509V3_EXT_I2V)i2v_AUTHORITY_INFO_ACCESS, | ||
80 | (X509V3_EXT_V2I)v2i_AUTHORITY_INFO_ACCESS, | ||
81 | NULL, NULL, NULL}; | ||
82 | |||
83 | static STACK_OF(CONF_VALUE) *i2v_AUTHORITY_INFO_ACCESS(X509V3_EXT_METHOD *method, | ||
84 | STACK_OF(ACCESS_DESCRIPTION) *ainfo, | ||
85 | STACK_OF(CONF_VALUE) *ret) | ||
86 | { | ||
87 | ACCESS_DESCRIPTION *desc; | ||
88 | int i; | ||
89 | char objtmp[80], *ntmp; | ||
90 | CONF_VALUE *vtmp; | ||
91 | for(i = 0; i < sk_ACCESS_DESCRIPTION_num(ainfo); i++) { | ||
92 | desc = sk_ACCESS_DESCRIPTION_value(ainfo, i); | ||
93 | ret = i2v_GENERAL_NAME(method, desc->location, ret); | ||
94 | if(!ret) break; | ||
95 | vtmp = sk_CONF_VALUE_value(ret, i); | ||
96 | i2t_ASN1_OBJECT(objtmp, 80, desc->method); | ||
97 | ntmp = Malloc(strlen(objtmp) + strlen(vtmp->name) + 5); | ||
98 | if(!ntmp) { | ||
99 | X509V3err(X509V3_F_I2V_AUTHORITY_INFO_ACCESS, | ||
100 | ERR_R_MALLOC_FAILURE); | ||
101 | return NULL; | ||
102 | } | ||
103 | strcpy(ntmp, objtmp); | ||
104 | strcat(ntmp, " - "); | ||
105 | strcat(ntmp, vtmp->name); | ||
106 | Free(vtmp->name); | ||
107 | vtmp->name = ntmp; | ||
108 | |||
109 | } | ||
110 | if(!ret) return sk_CONF_VALUE_new_null(); | ||
111 | return ret; | ||
112 | } | ||
113 | |||
114 | static STACK_OF(ACCESS_DESCRIPTION) *v2i_AUTHORITY_INFO_ACCESS(X509V3_EXT_METHOD *method, | ||
115 | X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval) | ||
116 | { | ||
117 | STACK_OF(ACCESS_DESCRIPTION) *ainfo = NULL; | ||
118 | CONF_VALUE *cnf, ctmp; | ||
119 | ACCESS_DESCRIPTION *acc; | ||
120 | int i, objlen; | ||
121 | char *objtmp, *ptmp; | ||
122 | if(!(ainfo = sk_ACCESS_DESCRIPTION_new(NULL))) { | ||
123 | X509V3err(X509V3_F_V2I_ACCESS_DESCRIPTION,ERR_R_MALLOC_FAILURE); | ||
124 | return NULL; | ||
125 | } | ||
126 | for(i = 0; i < sk_CONF_VALUE_num(nval); i++) { | ||
127 | cnf = sk_CONF_VALUE_value(nval, i); | ||
128 | if(!(acc = ACCESS_DESCRIPTION_new()) | ||
129 | || !sk_ACCESS_DESCRIPTION_push(ainfo, acc)) { | ||
130 | X509V3err(X509V3_F_V2I_ACCESS_DESCRIPTION,ERR_R_MALLOC_FAILURE); | ||
131 | goto err; | ||
132 | } | ||
133 | ptmp = strchr(cnf->name, ';'); | ||
134 | if(!ptmp) { | ||
135 | X509V3err(X509V3_F_V2I_ACCESS_DESCRIPTION,X509V3_R_INVALID_SYNTAX); | ||
136 | goto err; | ||
137 | } | ||
138 | objlen = ptmp - cnf->name; | ||
139 | ctmp.name = ptmp + 1; | ||
140 | ctmp.value = cnf->value; | ||
141 | if(!(acc->location = v2i_GENERAL_NAME(method, ctx, &ctmp))) | ||
142 | goto err; | ||
143 | if(!(objtmp = Malloc(objlen + 1))) { | ||
144 | X509V3err(X509V3_F_V2I_ACCESS_DESCRIPTION,ERR_R_MALLOC_FAILURE); | ||
145 | goto err; | ||
146 | } | ||
147 | strncpy(objtmp, cnf->name, objlen); | ||
148 | objtmp[objlen] = 0; | ||
149 | acc->method = OBJ_txt2obj(objtmp, 0); | ||
150 | if(!acc->method) { | ||
151 | X509V3err(X509V3_F_V2I_ACCESS_DESCRIPTION,X509V3_R_BAD_OBJECT); | ||
152 | ERR_add_error_data(2, "value=", objtmp); | ||
153 | Free(objtmp); | ||
154 | goto err; | ||
155 | } | ||
156 | Free(objtmp); | ||
157 | |||
158 | } | ||
159 | return ainfo; | ||
160 | err: | ||
161 | sk_ACCESS_DESCRIPTION_pop_free(ainfo, ACCESS_DESCRIPTION_free); | ||
162 | return NULL; | ||
163 | } | ||
164 | |||
165 | int i2d_ACCESS_DESCRIPTION(ACCESS_DESCRIPTION *a, unsigned char **pp) | ||
166 | { | ||
167 | M_ASN1_I2D_vars(a); | ||
168 | |||
169 | M_ASN1_I2D_len(a->method, i2d_ASN1_OBJECT); | ||
170 | M_ASN1_I2D_len(a->location, i2d_GENERAL_NAME); | ||
171 | |||
172 | M_ASN1_I2D_seq_total(); | ||
173 | |||
174 | M_ASN1_I2D_put(a->method, i2d_ASN1_OBJECT); | ||
175 | M_ASN1_I2D_put(a->location, i2d_GENERAL_NAME); | ||
176 | |||
177 | M_ASN1_I2D_finish(); | ||
178 | } | ||
179 | |||
180 | ACCESS_DESCRIPTION *ACCESS_DESCRIPTION_new(void) | ||
181 | { | ||
182 | ACCESS_DESCRIPTION *ret=NULL; | ||
183 | ASN1_CTX c; | ||
184 | M_ASN1_New_Malloc(ret, ACCESS_DESCRIPTION); | ||
185 | ret->method = OBJ_nid2obj(NID_undef); | ||
186 | ret->location = NULL; | ||
187 | return (ret); | ||
188 | M_ASN1_New_Error(ASN1_F_ACCESS_DESCRIPTION_NEW); | ||
189 | } | ||
190 | |||
191 | ACCESS_DESCRIPTION *d2i_ACCESS_DESCRIPTION(ACCESS_DESCRIPTION **a, unsigned char **pp, | ||
192 | long length) | ||
193 | { | ||
194 | M_ASN1_D2I_vars(a,ACCESS_DESCRIPTION *,ACCESS_DESCRIPTION_new); | ||
195 | M_ASN1_D2I_Init(); | ||
196 | M_ASN1_D2I_start_sequence(); | ||
197 | M_ASN1_D2I_get(ret->method, d2i_ASN1_OBJECT); | ||
198 | M_ASN1_D2I_get(ret->location, d2i_GENERAL_NAME); | ||
199 | M_ASN1_D2I_Finish(a, ACCESS_DESCRIPTION_free, ASN1_F_D2I_ACCESS_DESCRIPTION); | ||
200 | } | ||
201 | |||
202 | void ACCESS_DESCRIPTION_free(ACCESS_DESCRIPTION *a) | ||
203 | { | ||
204 | if (a == NULL) return; | ||
205 | ASN1_OBJECT_free(a->method); | ||
206 | GENERAL_NAME_free(a->location); | ||
207 | Free (a); | ||
208 | } | ||
209 | |||
210 | STACK_OF(ACCESS_DESCRIPTION) *AUTHORITY_INFO_ACCESS_new(void) | ||
211 | { | ||
212 | return sk_ACCESS_DESCRIPTION_new(NULL); | ||
213 | } | ||
214 | |||
215 | void AUTHORITY_INFO_ACCESS_free(STACK_OF(ACCESS_DESCRIPTION) *a) | ||
216 | { | ||
217 | sk_ACCESS_DESCRIPTION_pop_free(a, ACCESS_DESCRIPTION_free); | ||
218 | } | ||
219 | |||
220 | STACK_OF(ACCESS_DESCRIPTION) *d2i_AUTHORITY_INFO_ACCESS(STACK_OF(ACCESS_DESCRIPTION) **a, | ||
221 | unsigned char **pp, long length) | ||
222 | { | ||
223 | return d2i_ASN1_SET_OF_ACCESS_DESCRIPTION(a, pp, length, d2i_ACCESS_DESCRIPTION, | ||
224 | ACCESS_DESCRIPTION_free, V_ASN1_SEQUENCE, V_ASN1_UNIVERSAL); | ||
225 | } | ||
226 | |||
227 | int i2d_AUTHORITY_INFO_ACCESS(STACK_OF(ACCESS_DESCRIPTION) *a, unsigned char **pp) | ||
228 | { | ||
229 | return i2d_ASN1_SET_OF_ACCESS_DESCRIPTION(a, pp, i2d_ACCESS_DESCRIPTION, V_ASN1_SEQUENCE, | ||
230 | V_ASN1_UNIVERSAL, IS_SEQUENCE); | ||
231 | } | ||
232 | |||
233 | IMPLEMENT_STACK_OF(ACCESS_DESCRIPTION) | ||
234 | IMPLEMENT_ASN1_SET_OF(ACCESS_DESCRIPTION) | ||
235 | |||
236 | |||
diff --git a/src/lib/libcrypto/x509v3/v3_int.c b/src/lib/libcrypto/x509v3/v3_int.c new file mode 100644 index 0000000000..637dd5e128 --- /dev/null +++ b/src/lib/libcrypto/x509v3/v3_int.c | |||
@@ -0,0 +1,79 @@ | |||
1 | /* v3_int.c */ | ||
2 | /* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL | ||
3 | * project 1999. | ||
4 | */ | ||
5 | /* ==================================================================== | ||
6 | * Copyright (c) 1999 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 | #include "cryptlib.h" | ||
61 | #include <openssl/x509v3.h> | ||
62 | |||
63 | static ASN1_INTEGER *asn1_integer_new(void); | ||
64 | |||
65 | X509V3_EXT_METHOD v3_crl_num = { | ||
66 | NID_crl_number, 0, | ||
67 | (X509V3_EXT_NEW)asn1_integer_new, | ||
68 | (X509V3_EXT_FREE)ASN1_STRING_free, | ||
69 | (X509V3_EXT_D2I)d2i_ASN1_INTEGER, | ||
70 | (X509V3_EXT_I2D)i2d_ASN1_INTEGER, | ||
71 | (X509V3_EXT_I2S)i2s_ASN1_INTEGER, | ||
72 | (X509V3_EXT_S2I)NULL, | ||
73 | NULL, NULL, NULL, NULL, NULL}; | ||
74 | |||
75 | |||
76 | static ASN1_INTEGER *asn1_integer_new(void) | ||
77 | { | ||
78 | return ASN1_INTEGER_new(); | ||
79 | } | ||
diff --git a/src/lib/libcrypto/x509v3/v3_lib.c b/src/lib/libcrypto/x509v3/v3_lib.c new file mode 100644 index 0000000000..a0aa5de794 --- /dev/null +++ b/src/lib/libcrypto/x509v3/v3_lib.c | |||
@@ -0,0 +1,177 @@ | |||
1 | /* v3_lib.c */ | ||
2 | /* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL | ||
3 | * project 1999. | ||
4 | */ | ||
5 | /* ==================================================================== | ||
6 | * Copyright (c) 1999 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 | /* X509 v3 extension utilities */ | ||
59 | |||
60 | #include <stdio.h> | ||
61 | #include "cryptlib.h" | ||
62 | #include <openssl/conf.h> | ||
63 | #include <openssl/x509v3.h> | ||
64 | |||
65 | static STACK *ext_list = NULL; | ||
66 | |||
67 | static int ext_cmp(X509V3_EXT_METHOD **a, X509V3_EXT_METHOD **b); | ||
68 | static void ext_list_free(X509V3_EXT_METHOD *ext); | ||
69 | |||
70 | int X509V3_EXT_add(X509V3_EXT_METHOD *ext) | ||
71 | { | ||
72 | if(!ext_list && !(ext_list = sk_new(ext_cmp))) { | ||
73 | X509V3err(X509V3_F_X509V3_EXT_ADD,ERR_R_MALLOC_FAILURE); | ||
74 | return 0; | ||
75 | } | ||
76 | if(!sk_push(ext_list, (char *)ext)) { | ||
77 | X509V3err(X509V3_F_X509V3_EXT_ADD,ERR_R_MALLOC_FAILURE); | ||
78 | return 0; | ||
79 | } | ||
80 | return 1; | ||
81 | } | ||
82 | |||
83 | static int ext_cmp(X509V3_EXT_METHOD **a, X509V3_EXT_METHOD **b) | ||
84 | { | ||
85 | return ((*a)->ext_nid - (*b)->ext_nid); | ||
86 | } | ||
87 | |||
88 | X509V3_EXT_METHOD *X509V3_EXT_get_nid(int nid) | ||
89 | { | ||
90 | X509V3_EXT_METHOD tmp; | ||
91 | int idx; | ||
92 | tmp.ext_nid = nid; | ||
93 | if(!ext_list || (tmp.ext_nid < 0) ) return NULL; | ||
94 | idx = sk_find(ext_list, (char *)&tmp); | ||
95 | if(idx == -1) return NULL; | ||
96 | return (X509V3_EXT_METHOD *)sk_value(ext_list, idx); | ||
97 | } | ||
98 | |||
99 | X509V3_EXT_METHOD *X509V3_EXT_get(X509_EXTENSION *ext) | ||
100 | { | ||
101 | int nid; | ||
102 | if((nid = OBJ_obj2nid(ext->object)) == NID_undef) return NULL; | ||
103 | return X509V3_EXT_get_nid(nid); | ||
104 | } | ||
105 | |||
106 | |||
107 | int X509V3_EXT_add_list(X509V3_EXT_METHOD *extlist) | ||
108 | { | ||
109 | for(;extlist->ext_nid!=-1;extlist++) | ||
110 | if(!X509V3_EXT_add(extlist)) return 0; | ||
111 | return 1; | ||
112 | } | ||
113 | |||
114 | int X509V3_EXT_add_alias(int nid_to, int nid_from) | ||
115 | { | ||
116 | X509V3_EXT_METHOD *ext, *tmpext; | ||
117 | if(!(ext = X509V3_EXT_get_nid(nid_from))) { | ||
118 | X509V3err(X509V3_F_X509V3_EXT_ADD_ALIAS,X509V3_R_EXTENSION_NOT_FOUND); | ||
119 | return 0; | ||
120 | } | ||
121 | if(!(tmpext = (X509V3_EXT_METHOD *)Malloc(sizeof(X509V3_EXT_METHOD)))) { | ||
122 | X509V3err(X509V3_F_X509V3_EXT_ADD_ALIAS,ERR_R_MALLOC_FAILURE); | ||
123 | return 0; | ||
124 | } | ||
125 | *tmpext = *ext; | ||
126 | tmpext->ext_nid = nid_to; | ||
127 | tmpext->ext_flags |= X509V3_EXT_DYNAMIC; | ||
128 | return 1; | ||
129 | } | ||
130 | |||
131 | void X509V3_EXT_cleanup(void) | ||
132 | { | ||
133 | sk_pop_free(ext_list, ext_list_free); | ||
134 | ext_list = NULL; | ||
135 | } | ||
136 | |||
137 | static void ext_list_free(X509V3_EXT_METHOD *ext) | ||
138 | { | ||
139 | if(ext->ext_flags & X509V3_EXT_DYNAMIC) Free(ext); | ||
140 | } | ||
141 | |||
142 | extern X509V3_EXT_METHOD v3_bcons, v3_nscert, v3_key_usage, v3_ext_ku; | ||
143 | extern X509V3_EXT_METHOD v3_pkey_usage_period, v3_sxnet; | ||
144 | extern X509V3_EXT_METHOD v3_ns_ia5_list[], v3_alt[], v3_skey_id, v3_akey_id; | ||
145 | |||
146 | extern X509V3_EXT_METHOD v3_crl_num, v3_crl_reason, v3_cpols, v3_crld; | ||
147 | |||
148 | int X509V3_add_standard_extensions(void) | ||
149 | { | ||
150 | X509V3_EXT_add_list(v3_ns_ia5_list); | ||
151 | X509V3_EXT_add_list(v3_alt); | ||
152 | X509V3_EXT_add(&v3_bcons); | ||
153 | X509V3_EXT_add(&v3_nscert); | ||
154 | X509V3_EXT_add(&v3_key_usage); | ||
155 | X509V3_EXT_add(&v3_ext_ku); | ||
156 | X509V3_EXT_add(&v3_skey_id); | ||
157 | X509V3_EXT_add(&v3_akey_id); | ||
158 | X509V3_EXT_add(&v3_pkey_usage_period); | ||
159 | X509V3_EXT_add(&v3_crl_num); | ||
160 | X509V3_EXT_add(&v3_sxnet); | ||
161 | X509V3_EXT_add(&v3_crl_reason); | ||
162 | X509V3_EXT_add(&v3_cpols); | ||
163 | X509V3_EXT_add(&v3_crld); | ||
164 | return 1; | ||
165 | } | ||
166 | |||
167 | /* Return an extension internal structure */ | ||
168 | |||
169 | void *X509V3_EXT_d2i(X509_EXTENSION *ext) | ||
170 | { | ||
171 | X509V3_EXT_METHOD *method; | ||
172 | unsigned char *p; | ||
173 | if(!(method = X509V3_EXT_get(ext)) || !method->d2i) return NULL; | ||
174 | p = ext->value->data; | ||
175 | return method->d2i(NULL, &p, ext->value->length); | ||
176 | } | ||
177 | |||
diff --git a/src/lib/libcrypto/x509v3/v3_ocsp.c b/src/lib/libcrypto/x509v3/v3_ocsp.c new file mode 100644 index 0000000000..083112314e --- /dev/null +++ b/src/lib/libcrypto/x509v3/v3_ocsp.c | |||
@@ -0,0 +1,272 @@ | |||
1 | /* v3_ocsp.c */ | ||
2 | /* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL | ||
3 | * project 1999. | ||
4 | */ | ||
5 | /* ==================================================================== | ||
6 | * Copyright (c) 1999 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 | #include "cryptlib.h" | ||
61 | #include <openssl/conf.h> | ||
62 | #include <openssl/asn1.h> | ||
63 | #include <openssl/ocsp.h> | ||
64 | #include <openssl/x509v3.h> | ||
65 | |||
66 | /* OCSP extensions and a couple of CRL entry extensions | ||
67 | */ | ||
68 | |||
69 | static int i2r_ocsp_crlid(X509V3_EXT_METHOD *method, void *nonce, BIO *out, int indent); | ||
70 | static int i2r_ocsp_acutoff(X509V3_EXT_METHOD *method, void *nonce, BIO *out, int indent); | ||
71 | static int i2r_object(X509V3_EXT_METHOD *method, void *obj, BIO *out, int indent); | ||
72 | |||
73 | static void *ocsp_nonce_new(void); | ||
74 | static int i2d_ocsp_nonce(void *a, unsigned char **pp); | ||
75 | static void *d2i_ocsp_nonce(void *a, unsigned char **pp, long length); | ||
76 | static void ocsp_nonce_free(void *a); | ||
77 | static int i2r_ocsp_nonce(X509V3_EXT_METHOD *method, void *nonce, BIO *out, int indent); | ||
78 | |||
79 | static int i2r_ocsp_nocheck(X509V3_EXT_METHOD *method, void *nocheck, BIO *out, int indent); | ||
80 | static void *s2i_ocsp_nocheck(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, char *str); | ||
81 | static int i2r_ocsp_serviceloc(X509V3_EXT_METHOD *method, void *in, BIO *bp, int ind); | ||
82 | |||
83 | X509V3_EXT_METHOD v3_ocsp_crlid = { | ||
84 | NID_id_pkix_OCSP_CrlID, 0, ASN1_ITEM_ref(OCSP_CRLID), | ||
85 | 0,0,0,0, | ||
86 | 0,0, | ||
87 | 0,0, | ||
88 | i2r_ocsp_crlid,0, | ||
89 | NULL | ||
90 | }; | ||
91 | |||
92 | X509V3_EXT_METHOD v3_ocsp_acutoff = { | ||
93 | NID_id_pkix_OCSP_archiveCutoff, 0, ASN1_ITEM_ref(ASN1_GENERALIZEDTIME), | ||
94 | 0,0,0,0, | ||
95 | 0,0, | ||
96 | 0,0, | ||
97 | i2r_ocsp_acutoff,0, | ||
98 | NULL | ||
99 | }; | ||
100 | |||
101 | X509V3_EXT_METHOD v3_crl_invdate = { | ||
102 | NID_invalidity_date, 0, ASN1_ITEM_ref(ASN1_GENERALIZEDTIME), | ||
103 | 0,0,0,0, | ||
104 | 0,0, | ||
105 | 0,0, | ||
106 | i2r_ocsp_acutoff,0, | ||
107 | NULL | ||
108 | }; | ||
109 | |||
110 | X509V3_EXT_METHOD v3_crl_hold = { | ||
111 | NID_hold_instruction_code, 0, ASN1_ITEM_ref(ASN1_OBJECT), | ||
112 | 0,0,0,0, | ||
113 | 0,0, | ||
114 | 0,0, | ||
115 | i2r_object,0, | ||
116 | NULL | ||
117 | }; | ||
118 | |||
119 | X509V3_EXT_METHOD v3_ocsp_nonce = { | ||
120 | NID_id_pkix_OCSP_Nonce, 0, NULL, | ||
121 | ocsp_nonce_new, | ||
122 | ocsp_nonce_free, | ||
123 | d2i_ocsp_nonce, | ||
124 | i2d_ocsp_nonce, | ||
125 | 0,0, | ||
126 | 0,0, | ||
127 | i2r_ocsp_nonce,0, | ||
128 | NULL | ||
129 | }; | ||
130 | |||
131 | X509V3_EXT_METHOD v3_ocsp_nocheck = { | ||
132 | NID_id_pkix_OCSP_noCheck, 0, ASN1_ITEM_ref(ASN1_NULL), | ||
133 | 0,0,0,0, | ||
134 | 0,s2i_ocsp_nocheck, | ||
135 | 0,0, | ||
136 | i2r_ocsp_nocheck,0, | ||
137 | NULL | ||
138 | }; | ||
139 | |||
140 | X509V3_EXT_METHOD v3_ocsp_serviceloc = { | ||
141 | NID_id_pkix_OCSP_serviceLocator, 0, ASN1_ITEM_ref(OCSP_SERVICELOC), | ||
142 | 0,0,0,0, | ||
143 | 0,0, | ||
144 | 0,0, | ||
145 | i2r_ocsp_serviceloc,0, | ||
146 | NULL | ||
147 | }; | ||
148 | |||
149 | static int i2r_ocsp_crlid(X509V3_EXT_METHOD *method, void *in, BIO *bp, int ind) | ||
150 | { | ||
151 | OCSP_CRLID *a = in; | ||
152 | if (a->crlUrl) | ||
153 | { | ||
154 | if (!BIO_printf(bp, "%*scrlUrl: ", ind, "")) goto err; | ||
155 | if (!ASN1_STRING_print(bp, (ASN1_STRING*)a->crlUrl)) goto err; | ||
156 | if (!BIO_write(bp, "\n", 1)) goto err; | ||
157 | } | ||
158 | if (a->crlNum) | ||
159 | { | ||
160 | if (!BIO_printf(bp, "%*scrlNum: ", ind, "")) goto err; | ||
161 | if (!i2a_ASN1_INTEGER(bp, a->crlNum)) goto err; | ||
162 | if (!BIO_write(bp, "\n", 1)) goto err; | ||
163 | } | ||
164 | if (a->crlTime) | ||
165 | { | ||
166 | if (!BIO_printf(bp, "%*scrlTime: ", ind, "")) goto err; | ||
167 | if (!ASN1_GENERALIZEDTIME_print(bp, a->crlTime)) goto err; | ||
168 | if (!BIO_write(bp, "\n", 1)) goto err; | ||
169 | } | ||
170 | return 1; | ||
171 | err: | ||
172 | return 0; | ||
173 | } | ||
174 | |||
175 | static int i2r_ocsp_acutoff(X509V3_EXT_METHOD *method, void *cutoff, BIO *bp, int ind) | ||
176 | { | ||
177 | if (!BIO_printf(bp, "%*s", ind, "")) return 0; | ||
178 | if(!ASN1_GENERALIZEDTIME_print(bp, cutoff)) return 0; | ||
179 | return 1; | ||
180 | } | ||
181 | |||
182 | |||
183 | static int i2r_object(X509V3_EXT_METHOD *method, void *oid, BIO *bp, int ind) | ||
184 | { | ||
185 | if (!BIO_printf(bp, "%*s", ind, "")) return 0; | ||
186 | if(!i2a_ASN1_OBJECT(bp, oid)) return 0; | ||
187 | return 1; | ||
188 | } | ||
189 | |||
190 | /* OCSP nonce. This is needs special treatment because it doesn't have | ||
191 | * an ASN1 encoding at all: it just contains arbitrary data. | ||
192 | */ | ||
193 | |||
194 | static void *ocsp_nonce_new(void) | ||
195 | { | ||
196 | return ASN1_OCTET_STRING_new(); | ||
197 | } | ||
198 | |||
199 | static int i2d_ocsp_nonce(void *a, unsigned char **pp) | ||
200 | { | ||
201 | ASN1_OCTET_STRING *os = a; | ||
202 | if(pp) { | ||
203 | memcpy(*pp, os->data, os->length); | ||
204 | *pp += os->length; | ||
205 | } | ||
206 | return os->length; | ||
207 | } | ||
208 | |||
209 | static void *d2i_ocsp_nonce(void *a, unsigned char **pp, long length) | ||
210 | { | ||
211 | ASN1_OCTET_STRING *os, **pos; | ||
212 | pos = a; | ||
213 | if(!pos || !*pos) os = ASN1_OCTET_STRING_new(); | ||
214 | else os = *pos; | ||
215 | if(!ASN1_OCTET_STRING_set(os, *pp, length)) goto err; | ||
216 | |||
217 | *pp += length; | ||
218 | |||
219 | if(pos) *pos = os; | ||
220 | return os; | ||
221 | |||
222 | err: | ||
223 | if(os && (!pos || (*pos != os))) M_ASN1_OCTET_STRING_free(os); | ||
224 | OCSPerr(OCSP_F_D2I_OCSP_NONCE, ERR_R_MALLOC_FAILURE); | ||
225 | return NULL; | ||
226 | } | ||
227 | |||
228 | static void ocsp_nonce_free(void *a) | ||
229 | { | ||
230 | M_ASN1_OCTET_STRING_free(a); | ||
231 | } | ||
232 | |||
233 | static int i2r_ocsp_nonce(X509V3_EXT_METHOD *method, void *nonce, BIO *out, int indent) | ||
234 | { | ||
235 | if(BIO_printf(out, "%*s", indent, "") <= 0) return 0; | ||
236 | if(i2a_ASN1_STRING(out, nonce, V_ASN1_OCTET_STRING) <= 0) return 0; | ||
237 | return 1; | ||
238 | } | ||
239 | |||
240 | /* Nocheck is just a single NULL. Don't print anything and always set it */ | ||
241 | |||
242 | static int i2r_ocsp_nocheck(X509V3_EXT_METHOD *method, void *nocheck, BIO *out, int indent) | ||
243 | { | ||
244 | return 1; | ||
245 | } | ||
246 | |||
247 | static void *s2i_ocsp_nocheck(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, char *str) | ||
248 | { | ||
249 | return ASN1_NULL_new(); | ||
250 | } | ||
251 | |||
252 | static int i2r_ocsp_serviceloc(X509V3_EXT_METHOD *method, void *in, BIO *bp, int ind) | ||
253 | { | ||
254 | int i; | ||
255 | OCSP_SERVICELOC *a = in; | ||
256 | ACCESS_DESCRIPTION *ad; | ||
257 | |||
258 | if (BIO_printf(bp, "%*sIssuer: ", ind, "") <= 0) goto err; | ||
259 | if (X509_NAME_print_ex(bp, a->issuer, 0, XN_FLAG_ONELINE) <= 0) goto err; | ||
260 | for (i = 0; i < sk_ACCESS_DESCRIPTION_num(a->locator); i++) | ||
261 | { | ||
262 | ad = sk_ACCESS_DESCRIPTION_value(a->locator,i); | ||
263 | if (BIO_printf(bp, "\n%*s", (2*ind), "") <= 0) | ||
264 | goto err; | ||
265 | if(i2a_ASN1_OBJECT(bp, ad->method) <= 0) goto err; | ||
266 | if(BIO_puts(bp, " - ") <= 0) goto err; | ||
267 | if(GENERAL_NAME_print(bp, ad->location) <= 0) goto err; | ||
268 | } | ||
269 | return 1; | ||
270 | err: | ||
271 | return 0; | ||
272 | } | ||
diff --git a/src/lib/libcrypto/x509v3/v3_pku.c b/src/lib/libcrypto/x509v3/v3_pku.c new file mode 100644 index 0000000000..c13e7d8f45 --- /dev/null +++ b/src/lib/libcrypto/x509v3/v3_pku.c | |||
@@ -0,0 +1,151 @@ | |||
1 | /* v3_pku.c */ | ||
2 | /* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL | ||
3 | * project 1999. | ||
4 | */ | ||
5 | /* ==================================================================== | ||
6 | * Copyright (c) 1999 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 | #include "cryptlib.h" | ||
61 | #include <openssl/asn1.h> | ||
62 | #include <openssl/asn1_mac.h> | ||
63 | #include <openssl/x509v3.h> | ||
64 | |||
65 | static int i2r_PKEY_USAGE_PERIOD(X509V3_EXT_METHOD *method, PKEY_USAGE_PERIOD *usage, BIO *out, int indent); | ||
66 | /* | ||
67 | static PKEY_USAGE_PERIOD *v2i_PKEY_USAGE_PERIOD(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *values); | ||
68 | */ | ||
69 | X509V3_EXT_METHOD v3_pkey_usage_period = { | ||
70 | NID_private_key_usage_period, 0, | ||
71 | (X509V3_EXT_NEW)PKEY_USAGE_PERIOD_new, | ||
72 | (X509V3_EXT_FREE)PKEY_USAGE_PERIOD_free, | ||
73 | (X509V3_EXT_D2I)d2i_PKEY_USAGE_PERIOD, | ||
74 | (X509V3_EXT_I2D)i2d_PKEY_USAGE_PERIOD, | ||
75 | NULL, NULL, NULL, NULL, | ||
76 | (X509V3_EXT_I2R)i2r_PKEY_USAGE_PERIOD, NULL, | ||
77 | NULL | ||
78 | }; | ||
79 | |||
80 | int i2d_PKEY_USAGE_PERIOD(PKEY_USAGE_PERIOD *a, unsigned char **pp) | ||
81 | { | ||
82 | M_ASN1_I2D_vars(a); | ||
83 | |||
84 | M_ASN1_I2D_len_IMP_opt (a->notBefore, i2d_ASN1_GENERALIZEDTIME); | ||
85 | M_ASN1_I2D_len_IMP_opt (a->notAfter, i2d_ASN1_GENERALIZEDTIME); | ||
86 | |||
87 | M_ASN1_I2D_seq_total(); | ||
88 | |||
89 | M_ASN1_I2D_put_IMP_opt (a->notBefore, i2d_ASN1_GENERALIZEDTIME, 0); | ||
90 | M_ASN1_I2D_put_IMP_opt (a->notAfter, i2d_ASN1_GENERALIZEDTIME, 1); | ||
91 | |||
92 | M_ASN1_I2D_finish(); | ||
93 | } | ||
94 | |||
95 | PKEY_USAGE_PERIOD *PKEY_USAGE_PERIOD_new(void) | ||
96 | { | ||
97 | PKEY_USAGE_PERIOD *ret=NULL; | ||
98 | ASN1_CTX c; | ||
99 | M_ASN1_New_Malloc(ret, PKEY_USAGE_PERIOD); | ||
100 | ret->notBefore = NULL; | ||
101 | ret->notAfter = NULL; | ||
102 | return (ret); | ||
103 | M_ASN1_New_Error(ASN1_F_PKEY_USAGE_PERIOD_NEW); | ||
104 | } | ||
105 | |||
106 | PKEY_USAGE_PERIOD *d2i_PKEY_USAGE_PERIOD(PKEY_USAGE_PERIOD **a, | ||
107 | unsigned char **pp, long length) | ||
108 | { | ||
109 | M_ASN1_D2I_vars(a,PKEY_USAGE_PERIOD *,PKEY_USAGE_PERIOD_new); | ||
110 | M_ASN1_D2I_Init(); | ||
111 | M_ASN1_D2I_start_sequence(); | ||
112 | M_ASN1_D2I_get_IMP_opt (ret->notBefore, d2i_ASN1_GENERALIZEDTIME, 0, | ||
113 | V_ASN1_GENERALIZEDTIME); | ||
114 | M_ASN1_D2I_get_IMP_opt (ret->notAfter, d2i_ASN1_GENERALIZEDTIME, 1, | ||
115 | V_ASN1_GENERALIZEDTIME); | ||
116 | M_ASN1_D2I_Finish(a, PKEY_USAGE_PERIOD_free, ASN1_F_D2I_PKEY_USAGE_PERIOD); | ||
117 | } | ||
118 | |||
119 | void PKEY_USAGE_PERIOD_free(PKEY_USAGE_PERIOD *a) | ||
120 | { | ||
121 | if (a == NULL) return; | ||
122 | ASN1_GENERALIZEDTIME_free(a->notBefore); | ||
123 | ASN1_GENERALIZEDTIME_free(a->notAfter); | ||
124 | Free ((char *)a); | ||
125 | } | ||
126 | |||
127 | static int i2r_PKEY_USAGE_PERIOD(X509V3_EXT_METHOD *method, | ||
128 | PKEY_USAGE_PERIOD *usage, BIO *out, int indent) | ||
129 | { | ||
130 | BIO_printf(out, "%*s", indent, ""); | ||
131 | if(usage->notBefore) { | ||
132 | BIO_write(out, "Not Before: ", 12); | ||
133 | ASN1_GENERALIZEDTIME_print(out, usage->notBefore); | ||
134 | if(usage->notAfter) BIO_write(out, ", ", 2); | ||
135 | } | ||
136 | if(usage->notAfter) { | ||
137 | BIO_write(out, "Not After: ", 11); | ||
138 | ASN1_GENERALIZEDTIME_print(out, usage->notAfter); | ||
139 | } | ||
140 | return 1; | ||
141 | } | ||
142 | |||
143 | /* | ||
144 | static PKEY_USAGE_PERIOD *v2i_PKEY_USAGE_PERIOD(method, ctx, values) | ||
145 | X509V3_EXT_METHOD *method; | ||
146 | X509V3_CTX *ctx; | ||
147 | STACK_OF(CONF_VALUE) *values; | ||
148 | { | ||
149 | return NULL; | ||
150 | } | ||
151 | */ | ||
diff --git a/src/lib/libcrypto/x509v3/v3_prn.c b/src/lib/libcrypto/x509v3/v3_prn.c new file mode 100644 index 0000000000..dc20c6bdba --- /dev/null +++ b/src/lib/libcrypto/x509v3/v3_prn.c | |||
@@ -0,0 +1,135 @@ | |||
1 | /* v3_prn.c */ | ||
2 | /* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL | ||
3 | * project 1999. | ||
4 | */ | ||
5 | /* ==================================================================== | ||
6 | * Copyright (c) 1999 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 | /* X509 v3 extension utilities */ | ||
59 | |||
60 | #include <stdio.h> | ||
61 | #include "cryptlib.h" | ||
62 | #include <openssl/conf.h> | ||
63 | #include <openssl/x509v3.h> | ||
64 | |||
65 | /* Extension printing routines */ | ||
66 | |||
67 | /* Print out a name+value stack */ | ||
68 | |||
69 | void X509V3_EXT_val_prn(BIO *out, STACK_OF(CONF_VALUE) *val, int indent, int ml) | ||
70 | { | ||
71 | int i; | ||
72 | CONF_VALUE *nval; | ||
73 | if(!val) return; | ||
74 | if(!ml || !sk_CONF_VALUE_num(val)) { | ||
75 | BIO_printf(out, "%*s", indent, ""); | ||
76 | if(!sk_CONF_VALUE_num(val)) BIO_puts(out, "<EMPTY>\n"); | ||
77 | } | ||
78 | for(i = 0; i < sk_CONF_VALUE_num(val); i++) { | ||
79 | if(ml) BIO_printf(out, "%*s", indent, ""); | ||
80 | else if(i > 0) BIO_printf(out, ", "); | ||
81 | nval = sk_CONF_VALUE_value(val, i); | ||
82 | if(!nval->name) BIO_puts(out, nval->value); | ||
83 | else if(!nval->value) BIO_puts(out, nval->name); | ||
84 | else BIO_printf(out, "%s:%s", nval->name, nval->value); | ||
85 | if(ml) BIO_puts(out, "\n"); | ||
86 | } | ||
87 | } | ||
88 | |||
89 | /* Main routine: print out a general extension */ | ||
90 | |||
91 | int X509V3_EXT_print(BIO *out, X509_EXTENSION *ext, int flag, int indent) | ||
92 | { | ||
93 | char *ext_str = NULL, *value = NULL; | ||
94 | unsigned char *p; | ||
95 | X509V3_EXT_METHOD *method; | ||
96 | STACK_OF(CONF_VALUE) *nval = NULL; | ||
97 | int ok = 1; | ||
98 | if(!(method = X509V3_EXT_get(ext))) return 0; | ||
99 | p = ext->value->data; | ||
100 | if(!(ext_str = method->d2i(NULL, &p, ext->value->length))) return 0; | ||
101 | if(method->i2s) { | ||
102 | if(!(value = method->i2s(method, ext_str))) { | ||
103 | ok = 0; | ||
104 | goto err; | ||
105 | } | ||
106 | BIO_printf(out, "%*s%s", indent, "", value); | ||
107 | } else if(method->i2v) { | ||
108 | if(!(nval = method->i2v(method, ext_str, NULL))) { | ||
109 | ok = 0; | ||
110 | goto err; | ||
111 | } | ||
112 | X509V3_EXT_val_prn(out, nval, indent, | ||
113 | method->ext_flags & X509V3_EXT_MULTILINE); | ||
114 | } else if(method->i2r) { | ||
115 | if(!method->i2r(method, ext_str, out, indent)) ok = 0; | ||
116 | } else ok = 0; | ||
117 | |||
118 | err: | ||
119 | sk_CONF_VALUE_pop_free(nval, X509V3_conf_free); | ||
120 | if(value) Free(value); | ||
121 | method->ext_free(ext_str); | ||
122 | return ok; | ||
123 | } | ||
124 | |||
125 | #ifndef NO_FP_API | ||
126 | int X509V3_EXT_print_fp(FILE *fp, X509_EXTENSION *ext, int flag, int indent) | ||
127 | { | ||
128 | BIO *bio_tmp; | ||
129 | int ret; | ||
130 | if(!(bio_tmp = BIO_new_fp(fp, BIO_NOCLOSE))) return 0; | ||
131 | ret = X509V3_EXT_print(bio_tmp, ext, flag, indent); | ||
132 | BIO_free(bio_tmp); | ||
133 | return ret; | ||
134 | } | ||
135 | #endif | ||
diff --git a/src/lib/libcrypto/x509v3/v3_purp.c b/src/lib/libcrypto/x509v3/v3_purp.c new file mode 100644 index 0000000000..b7494ebcd5 --- /dev/null +++ b/src/lib/libcrypto/x509v3/v3_purp.c | |||
@@ -0,0 +1,456 @@ | |||
1 | /* v3_purp.c */ | ||
2 | /* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL | ||
3 | * project 1999. | ||
4 | */ | ||
5 | /* ==================================================================== | ||
6 | * Copyright (c) 1999 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 | #include "cryptlib.h" | ||
61 | #include <openssl/x509v3.h> | ||
62 | |||
63 | |||
64 | static void x509v3_cache_extensions(X509 *x); | ||
65 | |||
66 | static int ca_check(X509 *x); | ||
67 | static int check_purpose_ssl_client(X509_PURPOSE *xp, X509 *x, int ca); | ||
68 | static int check_purpose_ssl_server(X509_PURPOSE *xp, X509 *x, int ca); | ||
69 | static int check_purpose_ns_ssl_server(X509_PURPOSE *xp, X509 *x, int ca); | ||
70 | static int purpose_smime(X509 *x, int ca); | ||
71 | static int check_purpose_smime_sign(X509_PURPOSE *xp, X509 *x, int ca); | ||
72 | static int check_purpose_smime_encrypt(X509_PURPOSE *xp, X509 *x, int ca); | ||
73 | static int check_purpose_crl_sign(X509_PURPOSE *xp, X509 *x, int ca); | ||
74 | |||
75 | static int xp_cmp(X509_PURPOSE **a, X509_PURPOSE **b); | ||
76 | static void xptable_free(X509_PURPOSE *p); | ||
77 | |||
78 | static X509_PURPOSE xstandard[] = { | ||
79 | {X509_PURPOSE_SSL_CLIENT, X509_TRUST_SSL_CLIENT, 0, check_purpose_ssl_client, "SSL client", "sslclient", NULL}, | ||
80 | {X509_PURPOSE_SSL_SERVER, X509_TRUST_SSL_SERVER, 0, check_purpose_ssl_server, "SSL server", "sslserver", NULL}, | ||
81 | {X509_PURPOSE_NS_SSL_SERVER, X509_TRUST_SSL_SERVER, 0, check_purpose_ns_ssl_server, "Netscape SSL server", "nssslserver", NULL}, | ||
82 | {X509_PURPOSE_SMIME_SIGN, X509_TRUST_EMAIL, 0, check_purpose_smime_sign, "S/MIME signing", "smimesign", NULL}, | ||
83 | {X509_PURPOSE_SMIME_ENCRYPT, X509_TRUST_EMAIL, 0, check_purpose_smime_encrypt, "S/MIME encryption", "smimeencrypt", NULL}, | ||
84 | {X509_PURPOSE_CRL_SIGN, X509_TRUST_ANY, 0, check_purpose_crl_sign, "CRL signing", "crlsign", NULL}, | ||
85 | }; | ||
86 | |||
87 | #define X509_PURPOSE_COUNT (sizeof(xstandard)/sizeof(X509_PURPOSE)) | ||
88 | |||
89 | IMPLEMENT_STACK_OF(X509_PURPOSE) | ||
90 | |||
91 | static STACK_OF(X509_PURPOSE) *xptable = NULL; | ||
92 | |||
93 | static int xp_cmp(X509_PURPOSE **a, X509_PURPOSE **b) | ||
94 | { | ||
95 | return (*a)->purpose - (*b)->purpose; | ||
96 | } | ||
97 | |||
98 | int X509_check_purpose(X509 *x, int id, int ca) | ||
99 | { | ||
100 | int idx; | ||
101 | X509_PURPOSE *pt; | ||
102 | if(!(x->ex_flags & EXFLAG_SET)) { | ||
103 | CRYPTO_w_lock(CRYPTO_LOCK_X509); | ||
104 | x509v3_cache_extensions(x); | ||
105 | CRYPTO_w_unlock(CRYPTO_LOCK_X509); | ||
106 | } | ||
107 | if(id == -1) return 1; | ||
108 | idx = X509_PURPOSE_get_by_id(id); | ||
109 | if(idx == -1) return -1; | ||
110 | pt = X509_PURPOSE_get0(idx); | ||
111 | return pt->check_purpose(pt, x, ca); | ||
112 | } | ||
113 | |||
114 | int X509_PURPOSE_get_count(void) | ||
115 | { | ||
116 | if(!xptable) return X509_PURPOSE_COUNT; | ||
117 | return sk_X509_PURPOSE_num(xptable) + X509_PURPOSE_COUNT; | ||
118 | } | ||
119 | |||
120 | X509_PURPOSE * X509_PURPOSE_get0(int idx) | ||
121 | { | ||
122 | if(idx < 0) return NULL; | ||
123 | if(idx < X509_PURPOSE_COUNT) return xstandard + idx; | ||
124 | return sk_X509_PURPOSE_value(xptable, idx - X509_PURPOSE_COUNT); | ||
125 | } | ||
126 | |||
127 | int X509_PURPOSE_get_by_sname(char *sname) | ||
128 | { | ||
129 | int i; | ||
130 | X509_PURPOSE *xptmp; | ||
131 | for(i = 0; i < X509_PURPOSE_get_count(); i++) { | ||
132 | xptmp = X509_PURPOSE_get0(i); | ||
133 | if(!strcmp(xptmp->sname, sname)) return i; | ||
134 | } | ||
135 | return -1; | ||
136 | } | ||
137 | |||
138 | |||
139 | int X509_PURPOSE_get_by_id(int purpose) | ||
140 | { | ||
141 | X509_PURPOSE tmp; | ||
142 | int idx; | ||
143 | if((purpose >= X509_PURPOSE_MIN) && (purpose <= X509_PURPOSE_MAX)) | ||
144 | return purpose - X509_PURPOSE_MIN; | ||
145 | tmp.purpose = purpose; | ||
146 | if(!xptable) return -1; | ||
147 | idx = sk_X509_PURPOSE_find(xptable, &tmp); | ||
148 | if(idx == -1) return -1; | ||
149 | return idx + X509_PURPOSE_COUNT; | ||
150 | } | ||
151 | |||
152 | int X509_PURPOSE_add(int id, int trust, int flags, | ||
153 | int (*ck)(X509_PURPOSE *, X509 *, int), | ||
154 | char *name, char *sname, void *arg) | ||
155 | { | ||
156 | int idx; | ||
157 | X509_PURPOSE *ptmp; | ||
158 | /* This is set according to what we change: application can't set it */ | ||
159 | flags &= ~X509_PURPOSE_DYNAMIC; | ||
160 | /* This will always be set for application modified trust entries */ | ||
161 | flags |= X509_PURPOSE_DYNAMIC_NAME; | ||
162 | /* Get existing entry if any */ | ||
163 | idx = X509_PURPOSE_get_by_id(id); | ||
164 | /* Need a new entry */ | ||
165 | if(idx == -1) { | ||
166 | if(!(ptmp = Malloc(sizeof(X509_PURPOSE)))) { | ||
167 | X509V3err(X509V3_F_X509_PURPOSE_ADD,ERR_R_MALLOC_FAILURE); | ||
168 | return 0; | ||
169 | } | ||
170 | ptmp->flags = X509_PURPOSE_DYNAMIC; | ||
171 | } else ptmp = X509_PURPOSE_get0(idx); | ||
172 | |||
173 | /* Free existing name if dynamic */ | ||
174 | if(ptmp->flags & X509_PURPOSE_DYNAMIC_NAME) { | ||
175 | Free(ptmp->name); | ||
176 | Free(ptmp->sname); | ||
177 | } | ||
178 | /* dup supplied name */ | ||
179 | ptmp->name = BUF_strdup(name); | ||
180 | ptmp->sname = BUF_strdup(sname); | ||
181 | if(!ptmp->name || !ptmp->sname) { | ||
182 | X509V3err(X509V3_F_X509_PURPOSE_ADD,ERR_R_MALLOC_FAILURE); | ||
183 | return 0; | ||
184 | } | ||
185 | /* Keep the dynamic flag of existing entry */ | ||
186 | ptmp->flags &= X509_PURPOSE_DYNAMIC; | ||
187 | /* Set all other flags */ | ||
188 | ptmp->flags |= flags; | ||
189 | |||
190 | ptmp->purpose = id; | ||
191 | ptmp->trust = trust; | ||
192 | ptmp->check_purpose = ck; | ||
193 | ptmp->usr_data = arg; | ||
194 | |||
195 | /* If its a new entry manage the dynamic table */ | ||
196 | if(idx == -1) { | ||
197 | if(!xptable && !(xptable = sk_X509_PURPOSE_new(xp_cmp))) { | ||
198 | X509V3err(X509V3_F_X509_PURPOSE_ADD,ERR_R_MALLOC_FAILURE); | ||
199 | return 0; | ||
200 | } | ||
201 | if (!sk_X509_PURPOSE_push(xptable, ptmp)) { | ||
202 | X509V3err(X509V3_F_X509_PURPOSE_ADD,ERR_R_MALLOC_FAILURE); | ||
203 | return 0; | ||
204 | } | ||
205 | } | ||
206 | return 1; | ||
207 | } | ||
208 | |||
209 | static void xptable_free(X509_PURPOSE *p) | ||
210 | { | ||
211 | if(!p) return; | ||
212 | if (p->flags & X509_PURPOSE_DYNAMIC) | ||
213 | { | ||
214 | if (p->flags & X509_PURPOSE_DYNAMIC_NAME) { | ||
215 | Free(p->name); | ||
216 | Free(p->sname); | ||
217 | } | ||
218 | Free(p); | ||
219 | } | ||
220 | } | ||
221 | |||
222 | void X509_PURPOSE_cleanup(void) | ||
223 | { | ||
224 | int i; | ||
225 | sk_X509_PURPOSE_pop_free(xptable, xptable_free); | ||
226 | for(i = 0; i < X509_PURPOSE_COUNT; i++) xptable_free(xstandard + i); | ||
227 | xptable = NULL; | ||
228 | } | ||
229 | |||
230 | int X509_PURPOSE_get_id(X509_PURPOSE *xp) | ||
231 | { | ||
232 | return xp->purpose; | ||
233 | } | ||
234 | |||
235 | char *X509_PURPOSE_get0_name(X509_PURPOSE *xp) | ||
236 | { | ||
237 | return xp->name; | ||
238 | } | ||
239 | |||
240 | char *X509_PURPOSE_get0_sname(X509_PURPOSE *xp) | ||
241 | { | ||
242 | return xp->sname; | ||
243 | } | ||
244 | |||
245 | int X509_PURPOSE_get_trust(X509_PURPOSE *xp) | ||
246 | { | ||
247 | return xp->trust; | ||
248 | } | ||
249 | |||
250 | #ifndef NO_SHA | ||
251 | static void x509v3_cache_extensions(X509 *x) | ||
252 | { | ||
253 | BASIC_CONSTRAINTS *bs; | ||
254 | ASN1_BIT_STRING *usage; | ||
255 | ASN1_BIT_STRING *ns; | ||
256 | STACK_OF(ASN1_OBJECT) *extusage; | ||
257 | int i; | ||
258 | if(x->ex_flags & EXFLAG_SET) return; | ||
259 | X509_digest(x, EVP_sha1(), x->sha1_hash, NULL); | ||
260 | /* Does subject name match issuer ? */ | ||
261 | if(!X509_NAME_cmp(X509_get_subject_name(x), X509_get_issuer_name(x))) | ||
262 | x->ex_flags |= EXFLAG_SS; | ||
263 | /* V1 should mean no extensions ... */ | ||
264 | if(!X509_get_version(x)) x->ex_flags |= EXFLAG_V1; | ||
265 | /* Handle basic constraints */ | ||
266 | if((bs=X509_get_ext_d2i(x, NID_basic_constraints, NULL, NULL))) { | ||
267 | if(bs->ca) x->ex_flags |= EXFLAG_CA; | ||
268 | if(bs->pathlen) { | ||
269 | if((bs->pathlen->type == V_ASN1_NEG_INTEGER) | ||
270 | || !bs->ca) { | ||
271 | x->ex_flags |= EXFLAG_INVALID; | ||
272 | x->ex_pathlen = 0; | ||
273 | } else x->ex_pathlen = ASN1_INTEGER_get(bs->pathlen); | ||
274 | } else x->ex_pathlen = -1; | ||
275 | BASIC_CONSTRAINTS_free(bs); | ||
276 | x->ex_flags |= EXFLAG_BCONS; | ||
277 | } | ||
278 | /* Handle key usage */ | ||
279 | if((usage=X509_get_ext_d2i(x, NID_key_usage, NULL, NULL))) { | ||
280 | if(usage->length > 0) { | ||
281 | x->ex_kusage = usage->data[0]; | ||
282 | if(usage->length > 1) | ||
283 | x->ex_kusage |= usage->data[1] << 8; | ||
284 | } else x->ex_kusage = 0; | ||
285 | x->ex_flags |= EXFLAG_KUSAGE; | ||
286 | ASN1_BIT_STRING_free(usage); | ||
287 | } | ||
288 | x->ex_xkusage = 0; | ||
289 | if((extusage=X509_get_ext_d2i(x, NID_ext_key_usage, NULL, NULL))) { | ||
290 | x->ex_flags |= EXFLAG_XKUSAGE; | ||
291 | for(i = 0; i < sk_ASN1_OBJECT_num(extusage); i++) { | ||
292 | switch(OBJ_obj2nid(sk_ASN1_OBJECT_value(extusage,i))) { | ||
293 | case NID_server_auth: | ||
294 | x->ex_xkusage |= XKU_SSL_SERVER; | ||
295 | break; | ||
296 | |||
297 | case NID_client_auth: | ||
298 | x->ex_xkusage |= XKU_SSL_CLIENT; | ||
299 | break; | ||
300 | |||
301 | case NID_email_protect: | ||
302 | x->ex_xkusage |= XKU_SMIME; | ||
303 | break; | ||
304 | |||
305 | case NID_code_sign: | ||
306 | x->ex_xkusage |= XKU_CODE_SIGN; | ||
307 | break; | ||
308 | |||
309 | case NID_ms_sgc: | ||
310 | case NID_ns_sgc: | ||
311 | x->ex_xkusage |= XKU_SGC; | ||
312 | } | ||
313 | } | ||
314 | sk_ASN1_OBJECT_pop_free(extusage, ASN1_OBJECT_free); | ||
315 | } | ||
316 | |||
317 | if((ns=X509_get_ext_d2i(x, NID_netscape_cert_type, NULL, NULL))) { | ||
318 | if(ns->length > 0) x->ex_nscert = ns->data[0]; | ||
319 | else x->ex_nscert = 0; | ||
320 | x->ex_flags |= EXFLAG_NSCERT; | ||
321 | ASN1_BIT_STRING_free(ns); | ||
322 | } | ||
323 | x->ex_flags |= EXFLAG_SET; | ||
324 | } | ||
325 | #endif | ||
326 | |||
327 | /* CA checks common to all purposes | ||
328 | * return codes: | ||
329 | * 0 not a CA | ||
330 | * 1 is a CA | ||
331 | * 2 basicConstraints absent so "maybe" a CA | ||
332 | * 3 basicConstraints absent but self signed V1. | ||
333 | */ | ||
334 | |||
335 | #define V1_ROOT (EXFLAG_V1|EXFLAG_SS) | ||
336 | #define ku_reject(x, usage) \ | ||
337 | (((x)->ex_flags & EXFLAG_KUSAGE) && !((x)->ex_kusage & (usage))) | ||
338 | #define xku_reject(x, usage) \ | ||
339 | (((x)->ex_flags & EXFLAG_XKUSAGE) && !((x)->ex_xkusage & (usage))) | ||
340 | #define ns_reject(x, usage) \ | ||
341 | (((x)->ex_flags & EXFLAG_NSCERT) && !((x)->ex_nscert & (usage))) | ||
342 | |||
343 | static int ca_check(X509 *x) | ||
344 | { | ||
345 | /* keyUsage if present should allow cert signing */ | ||
346 | if(ku_reject(x, KU_KEY_CERT_SIGN)) return 0; | ||
347 | if(x->ex_flags & EXFLAG_BCONS) { | ||
348 | if(x->ex_flags & EXFLAG_CA) return 1; | ||
349 | /* If basicConstraints says not a CA then say so */ | ||
350 | else return 0; | ||
351 | } else { | ||
352 | if((x->ex_flags & V1_ROOT) == V1_ROOT) return 3; | ||
353 | else return 2; | ||
354 | } | ||
355 | } | ||
356 | |||
357 | |||
358 | static int check_purpose_ssl_client(X509_PURPOSE *xp, X509 *x, int ca) | ||
359 | { | ||
360 | if(xku_reject(x,XKU_SSL_CLIENT)) return 0; | ||
361 | if(ca) { | ||
362 | int ca_ret; | ||
363 | ca_ret = ca_check(x); | ||
364 | if(!ca_ret) return 0; | ||
365 | /* check nsCertType if present */ | ||
366 | if(x->ex_flags & EXFLAG_NSCERT) { | ||
367 | if(x->ex_nscert & NS_SSL_CA) return ca_ret; | ||
368 | return 0; | ||
369 | } | ||
370 | if(ca_ret != 2) return ca_ret; | ||
371 | else return 0; | ||
372 | } | ||
373 | /* We need to do digital signatures with it */ | ||
374 | if(ku_reject(x,KU_DIGITAL_SIGNATURE)) return 0; | ||
375 | /* nsCertType if present should allow SSL client use */ | ||
376 | if(ns_reject(x, NS_SSL_CLIENT)) return 0; | ||
377 | return 1; | ||
378 | } | ||
379 | |||
380 | static int check_purpose_ssl_server(X509_PURPOSE *xp, X509 *x, int ca) | ||
381 | { | ||
382 | if(xku_reject(x,XKU_SSL_SERVER|XKU_SGC)) return 0; | ||
383 | /* Otherwise same as SSL client for a CA */ | ||
384 | if(ca) return check_purpose_ssl_client(xp, x, 1); | ||
385 | |||
386 | if(ns_reject(x, NS_SSL_SERVER)) return 0; | ||
387 | /* Now as for keyUsage: we'll at least need to sign OR encipher */ | ||
388 | if(ku_reject(x, KU_DIGITAL_SIGNATURE|KU_KEY_ENCIPHERMENT)) return 0; | ||
389 | |||
390 | return 1; | ||
391 | |||
392 | } | ||
393 | |||
394 | static int check_purpose_ns_ssl_server(X509_PURPOSE *xp, X509 *x, int ca) | ||
395 | { | ||
396 | int ret; | ||
397 | ret = check_purpose_ssl_server(xp, x, ca); | ||
398 | if(!ret || ca) return ret; | ||
399 | /* We need to encipher or Netscape complains */ | ||
400 | if(ku_reject(x, KU_KEY_ENCIPHERMENT)) return 0; | ||
401 | return ret; | ||
402 | } | ||
403 | |||
404 | /* common S/MIME checks */ | ||
405 | static int purpose_smime(X509 *x, int ca) | ||
406 | { | ||
407 | if(xku_reject(x,XKU_SMIME)) return 0; | ||
408 | if(ca) { | ||
409 | int ca_ret; | ||
410 | ca_ret = ca_check(x); | ||
411 | if(!ca_ret) return 0; | ||
412 | /* check nsCertType if present */ | ||
413 | if(x->ex_flags & EXFLAG_NSCERT) { | ||
414 | if(x->ex_nscert & NS_SMIME_CA) return ca_ret; | ||
415 | return 0; | ||
416 | } | ||
417 | if(ca_ret != 2) return ca_ret; | ||
418 | else return 0; | ||
419 | } | ||
420 | if(x->ex_flags & EXFLAG_NSCERT) { | ||
421 | if(x->ex_nscert & NS_SMIME) return 1; | ||
422 | /* Workaround for some buggy certificates */ | ||
423 | if(x->ex_nscert & NS_SSL_CLIENT) return 2; | ||
424 | return 0; | ||
425 | } | ||
426 | return 1; | ||
427 | } | ||
428 | |||
429 | static int check_purpose_smime_sign(X509_PURPOSE *xp, X509 *x, int ca) | ||
430 | { | ||
431 | int ret; | ||
432 | ret = purpose_smime(x, ca); | ||
433 | if(!ret || ca) return ret; | ||
434 | if(ku_reject(x, KU_DIGITAL_SIGNATURE)) return 0; | ||
435 | return ret; | ||
436 | } | ||
437 | |||
438 | static int check_purpose_smime_encrypt(X509_PURPOSE *xp, X509 *x, int ca) | ||
439 | { | ||
440 | int ret; | ||
441 | ret = purpose_smime(x, ca); | ||
442 | if(!ret || ca) return ret; | ||
443 | if(ku_reject(x, KU_KEY_ENCIPHERMENT)) return 0; | ||
444 | return ret; | ||
445 | } | ||
446 | |||
447 | static int check_purpose_crl_sign(X509_PURPOSE *xp, X509 *x, int ca) | ||
448 | { | ||
449 | if(ca) { | ||
450 | int ca_ret; | ||
451 | if((ca_ret = ca_check(x)) != 2) return ca_ret; | ||
452 | else return 0; | ||
453 | } | ||
454 | if(ku_reject(x, KU_CRL_SIGN)) return 0; | ||
455 | return 1; | ||
456 | } | ||
diff --git a/src/lib/libcrypto/x509v3/v3_skey.c b/src/lib/libcrypto/x509v3/v3_skey.c new file mode 100644 index 0000000000..fb3e36014d --- /dev/null +++ b/src/lib/libcrypto/x509v3/v3_skey.c | |||
@@ -0,0 +1,156 @@ | |||
1 | /* v3_skey.c */ | ||
2 | /* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL | ||
3 | * project 1999. | ||
4 | */ | ||
5 | /* ==================================================================== | ||
6 | * Copyright (c) 1999 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/x509v3.h> | ||
63 | |||
64 | static ASN1_OCTET_STRING *octet_string_new(void); | ||
65 | static ASN1_OCTET_STRING *s2i_skey_id(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, char *str); | ||
66 | X509V3_EXT_METHOD v3_skey_id = { | ||
67 | NID_subject_key_identifier, 0, | ||
68 | (X509V3_EXT_NEW)octet_string_new, | ||
69 | (X509V3_EXT_FREE)ASN1_STRING_free, | ||
70 | (X509V3_EXT_D2I)d2i_ASN1_OCTET_STRING, | ||
71 | (X509V3_EXT_I2D)i2d_ASN1_OCTET_STRING, | ||
72 | (X509V3_EXT_I2S)i2s_ASN1_OCTET_STRING, | ||
73 | (X509V3_EXT_S2I)s2i_skey_id, | ||
74 | NULL, NULL, NULL, NULL, NULL}; | ||
75 | |||
76 | |||
77 | static ASN1_OCTET_STRING *octet_string_new(void) | ||
78 | { | ||
79 | return ASN1_OCTET_STRING_new(); | ||
80 | } | ||
81 | |||
82 | char *i2s_ASN1_OCTET_STRING(X509V3_EXT_METHOD *method, | ||
83 | ASN1_OCTET_STRING *oct) | ||
84 | { | ||
85 | return hex_to_string(oct->data, oct->length); | ||
86 | } | ||
87 | |||
88 | ASN1_OCTET_STRING *s2i_ASN1_OCTET_STRING(X509V3_EXT_METHOD *method, | ||
89 | X509V3_CTX *ctx, char *str) | ||
90 | { | ||
91 | ASN1_OCTET_STRING *oct; | ||
92 | long length; | ||
93 | |||
94 | if(!(oct = ASN1_OCTET_STRING_new())) { | ||
95 | X509V3err(X509V3_F_S2I_ASN1_OCTET_STRING,ERR_R_MALLOC_FAILURE); | ||
96 | return NULL; | ||
97 | } | ||
98 | |||
99 | if(!(oct->data = string_to_hex(str, &length))) { | ||
100 | ASN1_OCTET_STRING_free(oct); | ||
101 | return NULL; | ||
102 | } | ||
103 | |||
104 | oct->length = length; | ||
105 | |||
106 | return oct; | ||
107 | |||
108 | } | ||
109 | |||
110 | static ASN1_OCTET_STRING *s2i_skey_id(X509V3_EXT_METHOD *method, | ||
111 | X509V3_CTX *ctx, char *str) | ||
112 | { | ||
113 | ASN1_OCTET_STRING *oct; | ||
114 | ASN1_BIT_STRING *pk; | ||
115 | unsigned char pkey_dig[EVP_MAX_MD_SIZE]; | ||
116 | EVP_MD_CTX md; | ||
117 | unsigned int diglen; | ||
118 | |||
119 | if(strcmp(str, "hash")) return s2i_ASN1_OCTET_STRING(method, ctx, str); | ||
120 | |||
121 | if(!(oct = ASN1_OCTET_STRING_new())) { | ||
122 | X509V3err(X509V3_F_S2I_S2I_SKEY_ID,ERR_R_MALLOC_FAILURE); | ||
123 | return NULL; | ||
124 | } | ||
125 | |||
126 | if(ctx && (ctx->flags == CTX_TEST)) return oct; | ||
127 | |||
128 | if(!ctx || (!ctx->subject_req && !ctx->subject_cert)) { | ||
129 | X509V3err(X509V3_F_S2I_ASN1_SKEY_ID,X509V3_R_NO_PUBLIC_KEY); | ||
130 | goto err; | ||
131 | } | ||
132 | |||
133 | if(ctx->subject_req) | ||
134 | pk = ctx->subject_req->req_info->pubkey->public_key; | ||
135 | else pk = ctx->subject_cert->cert_info->key->public_key; | ||
136 | |||
137 | if(!pk) { | ||
138 | X509V3err(X509V3_F_S2I_ASN1_SKEY_ID,X509V3_R_NO_PUBLIC_KEY); | ||
139 | goto err; | ||
140 | } | ||
141 | |||
142 | EVP_DigestInit(&md, EVP_sha1()); | ||
143 | EVP_DigestUpdate(&md, pk->data, pk->length); | ||
144 | EVP_DigestFinal(&md, pkey_dig, &diglen); | ||
145 | |||
146 | if(!ASN1_OCTET_STRING_set(oct, pkey_dig, diglen)) { | ||
147 | X509V3err(X509V3_F_S2I_S2I_SKEY_ID,ERR_R_MALLOC_FAILURE); | ||
148 | goto err; | ||
149 | } | ||
150 | |||
151 | return oct; | ||
152 | |||
153 | err: | ||
154 | ASN1_OCTET_STRING_free(oct); | ||
155 | return NULL; | ||
156 | } | ||
diff --git a/src/lib/libcrypto/x509v3/v3_sxnet.c b/src/lib/libcrypto/x509v3/v3_sxnet.c new file mode 100644 index 0000000000..0687bb4e3d --- /dev/null +++ b/src/lib/libcrypto/x509v3/v3_sxnet.c | |||
@@ -0,0 +1,340 @@ | |||
1 | /* v3_sxnet.c */ | ||
2 | /* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL | ||
3 | * project 1999. | ||
4 | */ | ||
5 | /* ==================================================================== | ||
6 | * Copyright (c) 1999 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 | #include "cryptlib.h" | ||
61 | #include <openssl/conf.h> | ||
62 | #include <openssl/asn1.h> | ||
63 | #include <openssl/asn1_mac.h> | ||
64 | #include <openssl/x509v3.h> | ||
65 | |||
66 | /* Support for Thawte strong extranet extension */ | ||
67 | |||
68 | #define SXNET_TEST | ||
69 | |||
70 | static int sxnet_i2r(X509V3_EXT_METHOD *method, SXNET *sx, BIO *out, int indent); | ||
71 | #ifdef SXNET_TEST | ||
72 | static SXNET * sxnet_v2i(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, | ||
73 | STACK_OF(CONF_VALUE) *nval); | ||
74 | #endif | ||
75 | X509V3_EXT_METHOD v3_sxnet = { | ||
76 | NID_sxnet, X509V3_EXT_MULTILINE, | ||
77 | (X509V3_EXT_NEW)SXNET_new, | ||
78 | (X509V3_EXT_FREE)SXNET_free, | ||
79 | (X509V3_EXT_D2I)d2i_SXNET, | ||
80 | (X509V3_EXT_I2D)i2d_SXNET, | ||
81 | NULL, NULL, | ||
82 | NULL, | ||
83 | #ifdef SXNET_TEST | ||
84 | (X509V3_EXT_V2I)sxnet_v2i, | ||
85 | #else | ||
86 | NULL, | ||
87 | #endif | ||
88 | (X509V3_EXT_I2R)sxnet_i2r, | ||
89 | NULL, | ||
90 | NULL | ||
91 | }; | ||
92 | |||
93 | |||
94 | int i2d_SXNET(SXNET *a, unsigned char **pp) | ||
95 | { | ||
96 | M_ASN1_I2D_vars(a); | ||
97 | |||
98 | M_ASN1_I2D_len (a->version, i2d_ASN1_INTEGER); | ||
99 | M_ASN1_I2D_len_SEQUENCE_type (SXNETID, a->ids, i2d_SXNETID); | ||
100 | |||
101 | M_ASN1_I2D_seq_total(); | ||
102 | |||
103 | M_ASN1_I2D_put (a->version, i2d_ASN1_INTEGER); | ||
104 | M_ASN1_I2D_put_SEQUENCE_type (SXNETID, a->ids, i2d_SXNETID); | ||
105 | |||
106 | M_ASN1_I2D_finish(); | ||
107 | } | ||
108 | |||
109 | SXNET *SXNET_new(void) | ||
110 | { | ||
111 | SXNET *ret=NULL; | ||
112 | ASN1_CTX c; | ||
113 | M_ASN1_New_Malloc(ret, SXNET); | ||
114 | M_ASN1_New(ret->version,ASN1_INTEGER_new); | ||
115 | M_ASN1_New(ret->ids,sk_SXNETID_new_null); | ||
116 | return (ret); | ||
117 | M_ASN1_New_Error(ASN1_F_SXNET_NEW); | ||
118 | } | ||
119 | |||
120 | SXNET *d2i_SXNET(SXNET **a, unsigned char **pp, long length) | ||
121 | { | ||
122 | M_ASN1_D2I_vars(a,SXNET *,SXNET_new); | ||
123 | M_ASN1_D2I_Init(); | ||
124 | M_ASN1_D2I_start_sequence(); | ||
125 | M_ASN1_D2I_get (ret->version, d2i_ASN1_INTEGER); | ||
126 | M_ASN1_D2I_get_seq_type (SXNETID, ret->ids, d2i_SXNETID, SXNETID_free); | ||
127 | M_ASN1_D2I_Finish(a, SXNET_free, ASN1_F_D2I_SXNET); | ||
128 | } | ||
129 | |||
130 | void SXNET_free(SXNET *a) | ||
131 | { | ||
132 | if (a == NULL) return; | ||
133 | ASN1_INTEGER_free(a->version); | ||
134 | sk_SXNETID_pop_free(a->ids, SXNETID_free); | ||
135 | Free (a); | ||
136 | } | ||
137 | |||
138 | int i2d_SXNETID(SXNETID *a, unsigned char **pp) | ||
139 | { | ||
140 | M_ASN1_I2D_vars(a); | ||
141 | |||
142 | M_ASN1_I2D_len (a->zone, i2d_ASN1_INTEGER); | ||
143 | M_ASN1_I2D_len (a->user, i2d_ASN1_OCTET_STRING); | ||
144 | |||
145 | M_ASN1_I2D_seq_total(); | ||
146 | |||
147 | M_ASN1_I2D_put (a->zone, i2d_ASN1_INTEGER); | ||
148 | M_ASN1_I2D_put (a->user, i2d_ASN1_OCTET_STRING); | ||
149 | |||
150 | M_ASN1_I2D_finish(); | ||
151 | } | ||
152 | |||
153 | SXNETID *SXNETID_new(void) | ||
154 | { | ||
155 | SXNETID *ret=NULL; | ||
156 | ASN1_CTX c; | ||
157 | M_ASN1_New_Malloc(ret, SXNETID); | ||
158 | ret->zone = NULL; | ||
159 | M_ASN1_New(ret->user,ASN1_OCTET_STRING_new); | ||
160 | return (ret); | ||
161 | M_ASN1_New_Error(ASN1_F_SXNETID_NEW); | ||
162 | } | ||
163 | |||
164 | SXNETID *d2i_SXNETID(SXNETID **a, unsigned char **pp, long length) | ||
165 | { | ||
166 | M_ASN1_D2I_vars(a,SXNETID *,SXNETID_new); | ||
167 | M_ASN1_D2I_Init(); | ||
168 | M_ASN1_D2I_start_sequence(); | ||
169 | M_ASN1_D2I_get(ret->zone, d2i_ASN1_INTEGER); | ||
170 | M_ASN1_D2I_get(ret->user, d2i_ASN1_OCTET_STRING); | ||
171 | M_ASN1_D2I_Finish(a, SXNETID_free, ASN1_F_D2I_SXNETID); | ||
172 | } | ||
173 | |||
174 | void SXNETID_free(SXNETID *a) | ||
175 | { | ||
176 | if (a == NULL) return; | ||
177 | ASN1_INTEGER_free(a->zone); | ||
178 | ASN1_OCTET_STRING_free(a->user); | ||
179 | Free (a); | ||
180 | } | ||
181 | |||
182 | static int sxnet_i2r(X509V3_EXT_METHOD *method, SXNET *sx, BIO *out, | ||
183 | int indent) | ||
184 | { | ||
185 | long v; | ||
186 | char *tmp; | ||
187 | SXNETID *id; | ||
188 | int i; | ||
189 | v = ASN1_INTEGER_get(sx->version); | ||
190 | BIO_printf(out, "%*sVersion: %d (0x%X)", indent, "", v + 1, v); | ||
191 | for(i = 0; i < sk_SXNETID_num(sx->ids); i++) { | ||
192 | id = sk_SXNETID_value(sx->ids, i); | ||
193 | tmp = i2s_ASN1_INTEGER(NULL, id->zone); | ||
194 | BIO_printf(out, "\n%*sZone: %s, User: ", indent, "", tmp); | ||
195 | Free(tmp); | ||
196 | ASN1_OCTET_STRING_print(out, id->user); | ||
197 | } | ||
198 | return 1; | ||
199 | } | ||
200 | |||
201 | #ifdef SXNET_TEST | ||
202 | |||
203 | /* NBB: this is used for testing only. It should *not* be used for anything | ||
204 | * else because it will just take static IDs from the configuration file and | ||
205 | * they should really be separate values for each user. | ||
206 | */ | ||
207 | |||
208 | |||
209 | static SXNET * sxnet_v2i(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, | ||
210 | STACK_OF(CONF_VALUE) *nval) | ||
211 | { | ||
212 | CONF_VALUE *cnf; | ||
213 | SXNET *sx = NULL; | ||
214 | int i; | ||
215 | for(i = 0; i < sk_CONF_VALUE_num(nval); i++) { | ||
216 | cnf = sk_CONF_VALUE_value(nval, i); | ||
217 | if(!SXNET_add_id_asc(&sx, cnf->name, cnf->value, -1)) | ||
218 | return NULL; | ||
219 | } | ||
220 | return sx; | ||
221 | } | ||
222 | |||
223 | |||
224 | #endif | ||
225 | |||
226 | /* Strong Extranet utility functions */ | ||
227 | |||
228 | /* Add an id given the zone as an ASCII number */ | ||
229 | |||
230 | int SXNET_add_id_asc(SXNET **psx, char *zone, char *user, | ||
231 | int userlen) | ||
232 | { | ||
233 | ASN1_INTEGER *izone = NULL; | ||
234 | if(!(izone = s2i_ASN1_INTEGER(NULL, zone))) { | ||
235 | X509V3err(X509V3_F_SXNET_ADD_ASC,X509V3_R_ERROR_CONVERTING_ZONE); | ||
236 | return 0; | ||
237 | } | ||
238 | return SXNET_add_id_INTEGER(psx, izone, user, userlen); | ||
239 | } | ||
240 | |||
241 | /* Add an id given the zone as an unsigned long */ | ||
242 | |||
243 | int SXNET_add_id_ulong(SXNET **psx, unsigned long lzone, char *user, | ||
244 | int userlen) | ||
245 | { | ||
246 | ASN1_INTEGER *izone = NULL; | ||
247 | if(!(izone = ASN1_INTEGER_new()) || !ASN1_INTEGER_set(izone, lzone)) { | ||
248 | X509V3err(X509V3_F_SXNET_ADD_ID_ULONG,ERR_R_MALLOC_FAILURE); | ||
249 | ASN1_INTEGER_free(izone); | ||
250 | return 0; | ||
251 | } | ||
252 | return SXNET_add_id_INTEGER(psx, izone, user, userlen); | ||
253 | |||
254 | } | ||
255 | |||
256 | /* Add an id given the zone as an ASN1_INTEGER. | ||
257 | * Note this version uses the passed integer and doesn't make a copy so don't | ||
258 | * free it up afterwards. | ||
259 | */ | ||
260 | |||
261 | int SXNET_add_id_INTEGER(SXNET **psx, ASN1_INTEGER *zone, char *user, | ||
262 | int userlen) | ||
263 | { | ||
264 | SXNET *sx = NULL; | ||
265 | SXNETID *id = NULL; | ||
266 | if(!psx || !zone || !user) { | ||
267 | X509V3err(X509V3_F_SXNET_ADD_ID_INTEGER,X509V3_R_INVALID_NULL_ARGUMENT); | ||
268 | return 0; | ||
269 | } | ||
270 | if(userlen == -1) userlen = strlen(user); | ||
271 | if(userlen > 64) { | ||
272 | X509V3err(X509V3_F_SXNET_ADD_ID_INTEGER,X509V3_R_USER_TOO_LONG); | ||
273 | return 0; | ||
274 | } | ||
275 | if(!*psx) { | ||
276 | if(!(sx = SXNET_new())) goto err; | ||
277 | if(!ASN1_INTEGER_set(sx->version, 0)) goto err; | ||
278 | *psx = sx; | ||
279 | } else sx = *psx; | ||
280 | if(SXNET_get_id_INTEGER(sx, zone)) { | ||
281 | X509V3err(X509V3_F_SXNET_ADD_ID_INTEGER,X509V3_R_DUPLICATE_ZONE_ID); | ||
282 | return 0; | ||
283 | } | ||
284 | |||
285 | if(!(id = SXNETID_new())) goto err; | ||
286 | if(userlen == -1) userlen = strlen(user); | ||
287 | |||
288 | if(!ASN1_OCTET_STRING_set(id->user, user, userlen)) goto err; | ||
289 | if(!sk_SXNETID_push(sx->ids, id)) goto err; | ||
290 | id->zone = zone; | ||
291 | return 1; | ||
292 | |||
293 | err: | ||
294 | X509V3err(X509V3_F_SXNET_ADD_ID_INTEGER,ERR_R_MALLOC_FAILURE); | ||
295 | SXNETID_free(id); | ||
296 | SXNET_free(sx); | ||
297 | *psx = NULL; | ||
298 | return 0; | ||
299 | } | ||
300 | |||
301 | ASN1_OCTET_STRING *SXNET_get_id_asc(SXNET *sx, char *zone) | ||
302 | { | ||
303 | ASN1_INTEGER *izone = NULL; | ||
304 | ASN1_OCTET_STRING *oct; | ||
305 | if(!(izone = s2i_ASN1_INTEGER(NULL, zone))) { | ||
306 | X509V3err(X509V3_F_SXNET_GET_ID_ASC,X509V3_R_ERROR_CONVERTING_ZONE); | ||
307 | return NULL; | ||
308 | } | ||
309 | oct = SXNET_get_id_INTEGER(sx, izone); | ||
310 | ASN1_INTEGER_free(izone); | ||
311 | return oct; | ||
312 | } | ||
313 | |||
314 | ASN1_OCTET_STRING *SXNET_get_id_ulong(SXNET *sx, unsigned long lzone) | ||
315 | { | ||
316 | ASN1_INTEGER *izone = NULL; | ||
317 | ASN1_OCTET_STRING *oct; | ||
318 | if(!(izone = ASN1_INTEGER_new()) || !ASN1_INTEGER_set(izone, lzone)) { | ||
319 | X509V3err(X509V3_F_SXNET_GET_ID_ULONG,ERR_R_MALLOC_FAILURE); | ||
320 | ASN1_INTEGER_free(izone); | ||
321 | return NULL; | ||
322 | } | ||
323 | oct = SXNET_get_id_INTEGER(sx, izone); | ||
324 | ASN1_INTEGER_free(izone); | ||
325 | return oct; | ||
326 | } | ||
327 | |||
328 | ASN1_OCTET_STRING *SXNET_get_id_INTEGER(SXNET *sx, ASN1_INTEGER *zone) | ||
329 | { | ||
330 | SXNETID *id; | ||
331 | int i; | ||
332 | for(i = 0; i < sk_SXNETID_num(sx->ids); i++) { | ||
333 | id = sk_SXNETID_value(sx->ids, i); | ||
334 | if(!ASN1_INTEGER_cmp(id->zone, zone)) return id->user; | ||
335 | } | ||
336 | return NULL; | ||
337 | } | ||
338 | |||
339 | IMPLEMENT_STACK_OF(SXNETID) | ||
340 | IMPLEMENT_ASN1_SET_OF(SXNETID) | ||
diff --git a/src/lib/libcrypto/x509v3/v3_utl.c b/src/lib/libcrypto/x509v3/v3_utl.c new file mode 100644 index 0000000000..40f71c71b4 --- /dev/null +++ b/src/lib/libcrypto/x509v3/v3_utl.c | |||
@@ -0,0 +1,418 @@ | |||
1 | /* v3_utl.c */ | ||
2 | /* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL | ||
3 | * project 1999. | ||
4 | */ | ||
5 | /* ==================================================================== | ||
6 | * Copyright (c) 1999 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 | /* X509 v3 extension utilities */ | ||
59 | |||
60 | |||
61 | #include <stdio.h> | ||
62 | #include <ctype.h> | ||
63 | #include "cryptlib.h" | ||
64 | #include <openssl/conf.h> | ||
65 | #include <openssl/x509v3.h> | ||
66 | |||
67 | static char *strip_spaces(char *name); | ||
68 | |||
69 | /* Add a CONF_VALUE name value pair to stack */ | ||
70 | |||
71 | int X509V3_add_value(const char *name, const char *value, | ||
72 | STACK_OF(CONF_VALUE) **extlist) | ||
73 | { | ||
74 | CONF_VALUE *vtmp = NULL; | ||
75 | char *tname = NULL, *tvalue = NULL; | ||
76 | if(name && !(tname = BUF_strdup(name))) goto err; | ||
77 | if(value && !(tvalue = BUF_strdup(value))) goto err;; | ||
78 | if(!(vtmp = (CONF_VALUE *)Malloc(sizeof(CONF_VALUE)))) goto err; | ||
79 | if(!*extlist && !(*extlist = sk_CONF_VALUE_new(NULL))) goto err; | ||
80 | vtmp->section = NULL; | ||
81 | vtmp->name = tname; | ||
82 | vtmp->value = tvalue; | ||
83 | if(!sk_CONF_VALUE_push(*extlist, vtmp)) goto err; | ||
84 | return 1; | ||
85 | err: | ||
86 | X509V3err(X509V3_F_X509V3_ADD_VALUE,ERR_R_MALLOC_FAILURE); | ||
87 | if(vtmp) Free(vtmp); | ||
88 | if(tname) Free(tname); | ||
89 | if(tvalue) Free(tvalue); | ||
90 | return 0; | ||
91 | } | ||
92 | |||
93 | int X509V3_add_value_uchar(const char *name, const unsigned char *value, | ||
94 | STACK_OF(CONF_VALUE) **extlist) | ||
95 | { | ||
96 | return X509V3_add_value(name,(const char *)value,extlist); | ||
97 | } | ||
98 | |||
99 | /* Free function for STACK_OF(CONF_VALUE) */ | ||
100 | |||
101 | void X509V3_conf_free(CONF_VALUE *conf) | ||
102 | { | ||
103 | if(!conf) return; | ||
104 | if(conf->name) Free(conf->name); | ||
105 | if(conf->value) Free(conf->value); | ||
106 | if(conf->section) Free(conf->section); | ||
107 | Free((char *)conf); | ||
108 | } | ||
109 | |||
110 | int X509V3_add_value_bool(const char *name, int asn1_bool, | ||
111 | STACK_OF(CONF_VALUE) **extlist) | ||
112 | { | ||
113 | if(asn1_bool) return X509V3_add_value(name, "TRUE", extlist); | ||
114 | return X509V3_add_value(name, "FALSE", extlist); | ||
115 | } | ||
116 | |||
117 | int X509V3_add_value_bool_nf(char *name, int asn1_bool, | ||
118 | STACK_OF(CONF_VALUE) **extlist) | ||
119 | { | ||
120 | if(asn1_bool) return X509V3_add_value(name, "TRUE", extlist); | ||
121 | return 1; | ||
122 | } | ||
123 | |||
124 | |||
125 | char *i2s_ASN1_ENUMERATED(X509V3_EXT_METHOD *method, ASN1_ENUMERATED *a) | ||
126 | { | ||
127 | BIGNUM *bntmp = NULL; | ||
128 | char *strtmp = NULL; | ||
129 | if(!a) return NULL; | ||
130 | if(!(bntmp = ASN1_ENUMERATED_to_BN(a, NULL)) || | ||
131 | !(strtmp = BN_bn2dec(bntmp)) ) | ||
132 | X509V3err(X509V3_F_I2S_ASN1_ENUMERATED,ERR_R_MALLOC_FAILURE); | ||
133 | BN_free(bntmp); | ||
134 | return strtmp; | ||
135 | } | ||
136 | |||
137 | char *i2s_ASN1_INTEGER(X509V3_EXT_METHOD *method, ASN1_INTEGER *a) | ||
138 | { | ||
139 | BIGNUM *bntmp = NULL; | ||
140 | char *strtmp = NULL; | ||
141 | if(!a) return NULL; | ||
142 | if(!(bntmp = ASN1_INTEGER_to_BN(a, NULL)) || | ||
143 | !(strtmp = BN_bn2dec(bntmp)) ) | ||
144 | X509V3err(X509V3_F_I2S_ASN1_INTEGER,ERR_R_MALLOC_FAILURE); | ||
145 | BN_free(bntmp); | ||
146 | return strtmp; | ||
147 | } | ||
148 | |||
149 | ASN1_INTEGER *s2i_ASN1_INTEGER(X509V3_EXT_METHOD *method, char *value) | ||
150 | { | ||
151 | BIGNUM *bn = NULL; | ||
152 | ASN1_INTEGER *aint; | ||
153 | bn = BN_new(); | ||
154 | if(!value) { | ||
155 | X509V3err(X509V3_F_S2I_ASN1_INTEGER,X509V3_R_INVALID_NULL_VALUE); | ||
156 | return 0; | ||
157 | } | ||
158 | if(!BN_dec2bn(&bn, value)) { | ||
159 | X509V3err(X509V3_F_S2I_ASN1_INTEGER,X509V3_R_BN_DEC2BN_ERROR); | ||
160 | return 0; | ||
161 | } | ||
162 | |||
163 | if(!(aint = BN_to_ASN1_INTEGER(bn, NULL))) { | ||
164 | X509V3err(X509V3_F_S2I_ASN1_INTEGER,X509V3_R_BN_TO_ASN1_INTEGER_ERROR); | ||
165 | return 0; | ||
166 | } | ||
167 | BN_free(bn); | ||
168 | return aint; | ||
169 | } | ||
170 | |||
171 | int X509V3_add_value_int(const char *name, ASN1_INTEGER *aint, | ||
172 | STACK_OF(CONF_VALUE) **extlist) | ||
173 | { | ||
174 | char *strtmp; | ||
175 | int ret; | ||
176 | if(!aint) return 1; | ||
177 | if(!(strtmp = i2s_ASN1_INTEGER(NULL, aint))) return 0; | ||
178 | ret = X509V3_add_value(name, strtmp, extlist); | ||
179 | Free(strtmp); | ||
180 | return ret; | ||
181 | } | ||
182 | |||
183 | int X509V3_get_value_bool(CONF_VALUE *value, int *asn1_bool) | ||
184 | { | ||
185 | char *btmp; | ||
186 | if(!(btmp = value->value)) goto err; | ||
187 | if(!strcmp(btmp, "TRUE") || !strcmp(btmp, "true") | ||
188 | || !strcmp(btmp, "Y") || !strcmp(btmp, "y") | ||
189 | || !strcmp(btmp, "YES") || !strcmp(btmp, "yes")) { | ||
190 | *asn1_bool = 0xff; | ||
191 | return 1; | ||
192 | } else if(!strcmp(btmp, "FALSE") || !strcmp(btmp, "false") | ||
193 | || !strcmp(btmp, "N") || !strcmp(btmp, "n") | ||
194 | || !strcmp(btmp, "NO") || !strcmp(btmp, "no")) { | ||
195 | *asn1_bool = 0; | ||
196 | return 1; | ||
197 | } | ||
198 | err: | ||
199 | X509V3err(X509V3_F_X509V3_GET_VALUE_BOOL,X509V3_R_INVALID_BOOLEAN_STRING); | ||
200 | X509V3_conf_err(value); | ||
201 | return 0; | ||
202 | } | ||
203 | |||
204 | int X509V3_get_value_int(CONF_VALUE *value, ASN1_INTEGER **aint) | ||
205 | { | ||
206 | ASN1_INTEGER *itmp; | ||
207 | if(!(itmp = s2i_ASN1_INTEGER(NULL, value->value))) { | ||
208 | X509V3_conf_err(value); | ||
209 | return 0; | ||
210 | } | ||
211 | *aint = itmp; | ||
212 | return 1; | ||
213 | } | ||
214 | |||
215 | #define HDR_NAME 1 | ||
216 | #define HDR_VALUE 2 | ||
217 | |||
218 | /*#define DEBUG*/ | ||
219 | |||
220 | STACK_OF(CONF_VALUE) *X509V3_parse_list(char *line) | ||
221 | { | ||
222 | char *p, *q, c; | ||
223 | char *ntmp, *vtmp; | ||
224 | STACK_OF(CONF_VALUE) *values = NULL; | ||
225 | char *linebuf; | ||
226 | int state; | ||
227 | /* We are going to modify the line so copy it first */ | ||
228 | linebuf = BUF_strdup(line); | ||
229 | state = HDR_NAME; | ||
230 | ntmp = NULL; | ||
231 | /* Go through all characters */ | ||
232 | for(p = linebuf, q = linebuf; (c = *p) && (c!='\r') && (c!='\n'); p++) { | ||
233 | |||
234 | switch(state) { | ||
235 | case HDR_NAME: | ||
236 | if(c == ':') { | ||
237 | state = HDR_VALUE; | ||
238 | *p = 0; | ||
239 | ntmp = strip_spaces(q); | ||
240 | if(!ntmp) { | ||
241 | X509V3err(X509V3_F_X509V3_PARSE_LIST, X509V3_R_INVALID_NULL_NAME); | ||
242 | goto err; | ||
243 | } | ||
244 | q = p + 1; | ||
245 | } else if(c == ',') { | ||
246 | *p = 0; | ||
247 | ntmp = strip_spaces(q); | ||
248 | q = p + 1; | ||
249 | #ifdef DEBUG | ||
250 | printf("%s\n", ntmp); | ||
251 | #endif | ||
252 | if(!ntmp) { | ||
253 | X509V3err(X509V3_F_X509V3_PARSE_LIST, X509V3_R_INVALID_NULL_NAME); | ||
254 | goto err; | ||
255 | } | ||
256 | X509V3_add_value(ntmp, NULL, &values); | ||
257 | } | ||
258 | break ; | ||
259 | |||
260 | case HDR_VALUE: | ||
261 | if(c == ',') { | ||
262 | state = HDR_NAME; | ||
263 | *p = 0; | ||
264 | vtmp = strip_spaces(q); | ||
265 | #ifdef DEBUG | ||
266 | printf("%s\n", ntmp); | ||
267 | #endif | ||
268 | if(!vtmp) { | ||
269 | X509V3err(X509V3_F_X509V3_PARSE_LIST, X509V3_R_INVALID_NULL_VALUE); | ||
270 | goto err; | ||
271 | } | ||
272 | X509V3_add_value(ntmp, vtmp, &values); | ||
273 | ntmp = NULL; | ||
274 | q = p + 1; | ||
275 | } | ||
276 | |||
277 | } | ||
278 | } | ||
279 | |||
280 | if(state == HDR_VALUE) { | ||
281 | vtmp = strip_spaces(q); | ||
282 | #ifdef DEBUG | ||
283 | printf("%s=%s\n", ntmp, vtmp); | ||
284 | #endif | ||
285 | if(!vtmp) { | ||
286 | X509V3err(X509V3_F_X509V3_PARSE_LIST, X509V3_R_INVALID_NULL_VALUE); | ||
287 | goto err; | ||
288 | } | ||
289 | X509V3_add_value(ntmp, vtmp, &values); | ||
290 | } else { | ||
291 | ntmp = strip_spaces(q); | ||
292 | #ifdef DEBUG | ||
293 | printf("%s\n", ntmp); | ||
294 | #endif | ||
295 | if(!ntmp) { | ||
296 | X509V3err(X509V3_F_X509V3_PARSE_LIST, X509V3_R_INVALID_NULL_NAME); | ||
297 | goto err; | ||
298 | } | ||
299 | X509V3_add_value(ntmp, NULL, &values); | ||
300 | } | ||
301 | Free(linebuf); | ||
302 | return values; | ||
303 | |||
304 | err: | ||
305 | Free(linebuf); | ||
306 | sk_CONF_VALUE_pop_free(values, X509V3_conf_free); | ||
307 | return NULL; | ||
308 | |||
309 | } | ||
310 | |||
311 | /* Delete leading and trailing spaces from a string */ | ||
312 | static char *strip_spaces(char *name) | ||
313 | { | ||
314 | char *p, *q; | ||
315 | /* Skip over leading spaces */ | ||
316 | p = name; | ||
317 | while(*p && isspace((unsigned char)*p)) p++; | ||
318 | if(!*p) return NULL; | ||
319 | q = p + strlen(p) - 1; | ||
320 | while((q != p) && isspace((unsigned char)*q)) q--; | ||
321 | if(p != q) q[1] = 0; | ||
322 | if(!*p) return NULL; | ||
323 | return p; | ||
324 | } | ||
325 | |||
326 | /* hex string utilities */ | ||
327 | |||
328 | /* Given a buffer of length 'len' return a Malloc'ed string with its | ||
329 | * hex representation | ||
330 | */ | ||
331 | |||
332 | char *hex_to_string(unsigned char *buffer, long len) | ||
333 | { | ||
334 | char *tmp, *q; | ||
335 | unsigned char *p; | ||
336 | int i; | ||
337 | static char hexdig[] = "0123456789ABCDEF"; | ||
338 | if(!buffer || !len) return NULL; | ||
339 | if(!(tmp = Malloc(len * 3 + 1))) { | ||
340 | X509V3err(X509V3_F_HEX_TO_STRING,ERR_R_MALLOC_FAILURE); | ||
341 | return NULL; | ||
342 | } | ||
343 | q = tmp; | ||
344 | for(i = 0, p = buffer; i < len; i++,p++) { | ||
345 | *q++ = hexdig[(*p >> 4) & 0xf]; | ||
346 | *q++ = hexdig[*p & 0xf]; | ||
347 | *q++ = ':'; | ||
348 | } | ||
349 | q[-1] = 0; | ||
350 | return tmp; | ||
351 | } | ||
352 | |||
353 | /* Give a string of hex digits convert to | ||
354 | * a buffer | ||
355 | */ | ||
356 | |||
357 | unsigned char *string_to_hex(char *str, long *len) | ||
358 | { | ||
359 | unsigned char *hexbuf, *q; | ||
360 | unsigned char ch, cl, *p; | ||
361 | if(!str) { | ||
362 | X509V3err(X509V3_F_STRING_TO_HEX,X509V3_R_INVALID_NULL_ARGUMENT); | ||
363 | return NULL; | ||
364 | } | ||
365 | if(!(hexbuf = Malloc(strlen(str) >> 1))) goto err; | ||
366 | for(p = (unsigned char *)str, q = hexbuf; *p;) { | ||
367 | ch = *p++; | ||
368 | if(ch == ':') continue; | ||
369 | cl = *p++; | ||
370 | if(!cl) { | ||
371 | X509V3err(X509V3_F_STRING_TO_HEX,X509V3_R_ODD_NUMBER_OF_DIGITS); | ||
372 | Free(hexbuf); | ||
373 | return NULL; | ||
374 | } | ||
375 | if(isupper(ch)) ch = tolower(ch); | ||
376 | if(isupper(cl)) cl = tolower(cl); | ||
377 | |||
378 | if((ch >= '0') && (ch <= '9')) ch -= '0'; | ||
379 | else if ((ch >= 'a') && (ch <= 'f')) ch -= 'a' - 10; | ||
380 | else goto badhex; | ||
381 | |||
382 | if((cl >= '0') && (cl <= '9')) cl -= '0'; | ||
383 | else if ((cl >= 'a') && (cl <= 'f')) cl -= 'a' - 10; | ||
384 | else goto badhex; | ||
385 | |||
386 | *q++ = (ch << 4) | cl; | ||
387 | } | ||
388 | |||
389 | if(len) *len = q - hexbuf; | ||
390 | |||
391 | return hexbuf; | ||
392 | |||
393 | err: | ||
394 | if(hexbuf) Free(hexbuf); | ||
395 | X509V3err(X509V3_F_STRING_TO_HEX,ERR_R_MALLOC_FAILURE); | ||
396 | return NULL; | ||
397 | |||
398 | badhex: | ||
399 | Free(hexbuf); | ||
400 | X509V3err(X509V3_F_STRING_TO_HEX,X509V3_R_ILLEGAL_HEX_DIGIT); | ||
401 | return NULL; | ||
402 | |||
403 | } | ||
404 | |||
405 | /* V2I name comparison function: returns zero if 'name' matches | ||
406 | * cmp or cmp.* | ||
407 | */ | ||
408 | |||
409 | int name_cmp(const char *name, const char *cmp) | ||
410 | { | ||
411 | int len, ret; | ||
412 | char c; | ||
413 | len = strlen(cmp); | ||
414 | if((ret = strncmp(name, cmp, len))) return ret; | ||
415 | c = name[len]; | ||
416 | if(!c || (c=='.')) return 0; | ||
417 | return 1; | ||
418 | } | ||
diff --git a/src/lib/libcrypto/x509v3/v3err.c b/src/lib/libcrypto/x509v3/v3err.c new file mode 100644 index 0000000000..50efa8d99d --- /dev/null +++ b/src/lib/libcrypto/x509v3/v3err.c | |||
@@ -0,0 +1,171 @@ | |||
1 | /* crypto/x509v3/v3err.c */ | ||
2 | /* ==================================================================== | ||
3 | * Copyright (c) 1999 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 | */ | ||
59 | |||
60 | #include <stdio.h> | ||
61 | #include <openssl/err.h> | ||
62 | #include <openssl/x509v3.h> | ||
63 | |||
64 | /* BEGIN ERROR CODES */ | ||
65 | #ifndef NO_ERR | ||
66 | static ERR_STRING_DATA X509V3_str_functs[]= | ||
67 | { | ||
68 | {ERR_PACK(0,X509V3_F_COPY_EMAIL,0), "COPY_EMAIL"}, | ||
69 | {ERR_PACK(0,X509V3_F_COPY_ISSUER,0), "COPY_ISSUER"}, | ||
70 | {ERR_PACK(0,X509V3_F_DO_EXT_CONF,0), "DO_EXT_CONF"}, | ||
71 | {ERR_PACK(0,X509V3_F_DO_EXT_I2D,0), "DO_EXT_I2D"}, | ||
72 | {ERR_PACK(0,X509V3_F_HEX_TO_STRING,0), "hex_to_string"}, | ||
73 | {ERR_PACK(0,X509V3_F_I2S_ASN1_ENUMERATED,0), "i2s_ASN1_ENUMERATED"}, | ||
74 | {ERR_PACK(0,X509V3_F_I2S_ASN1_INTEGER,0), "i2s_ASN1_INTEGER"}, | ||
75 | {ERR_PACK(0,X509V3_F_NOTICE_SECTION,0), "NOTICE_SECTION"}, | ||
76 | {ERR_PACK(0,X509V3_F_NREF_NOS,0), "NREF_NOS"}, | ||
77 | {ERR_PACK(0,X509V3_F_POLICY_SECTION,0), "POLICY_SECTION"}, | ||
78 | {ERR_PACK(0,X509V3_F_R2I_CERTPOL,0), "R2I_CERTPOL"}, | ||
79 | {ERR_PACK(0,X509V3_F_S2I_ASN1_IA5STRING,0), "S2I_ASN1_IA5STRING"}, | ||
80 | {ERR_PACK(0,X509V3_F_S2I_ASN1_INTEGER,0), "s2i_ASN1_INTEGER"}, | ||
81 | {ERR_PACK(0,X509V3_F_S2I_ASN1_OCTET_STRING,0), "s2i_ASN1_OCTET_STRING"}, | ||
82 | {ERR_PACK(0,X509V3_F_S2I_ASN1_SKEY_ID,0), "S2I_ASN1_SKEY_ID"}, | ||
83 | {ERR_PACK(0,X509V3_F_S2I_S2I_SKEY_ID,0), "S2I_S2I_SKEY_ID"}, | ||
84 | {ERR_PACK(0,X509V3_F_STRING_TO_HEX,0), "string_to_hex"}, | ||
85 | {ERR_PACK(0,X509V3_F_SXNET_ADD_ASC,0), "SXNET_ADD_ASC"}, | ||
86 | {ERR_PACK(0,X509V3_F_SXNET_ADD_ID_INTEGER,0), "SXNET_add_id_INTEGER"}, | ||
87 | {ERR_PACK(0,X509V3_F_SXNET_ADD_ID_ULONG,0), "SXNET_add_id_ulong"}, | ||
88 | {ERR_PACK(0,X509V3_F_SXNET_GET_ID_ASC,0), "SXNET_get_id_asc"}, | ||
89 | {ERR_PACK(0,X509V3_F_SXNET_GET_ID_ULONG,0), "SXNET_get_id_ulong"}, | ||
90 | {ERR_PACK(0,X509V3_F_V2I_ASN1_BIT_STRING,0), "V2I_ASN1_BIT_STRING"}, | ||
91 | {ERR_PACK(0,X509V3_F_V2I_AUTHORITY_KEYID,0), "V2I_AUTHORITY_KEYID"}, | ||
92 | {ERR_PACK(0,X509V3_F_V2I_BASIC_CONSTRAINTS,0), "V2I_BASIC_CONSTRAINTS"}, | ||
93 | {ERR_PACK(0,X509V3_F_V2I_CRLD,0), "V2I_CRLD"}, | ||
94 | {ERR_PACK(0,X509V3_F_V2I_EXT_KU,0), "V2I_EXT_KU"}, | ||
95 | {ERR_PACK(0,X509V3_F_V2I_GENERAL_NAME,0), "v2i_GENERAL_NAME"}, | ||
96 | {ERR_PACK(0,X509V3_F_V2I_GENERAL_NAMES,0), "v2i_GENERAL_NAMES"}, | ||
97 | {ERR_PACK(0,X509V3_F_V3_GENERIC_EXTENSION,0), "V3_GENERIC_EXTENSION"}, | ||
98 | {ERR_PACK(0,X509V3_F_X509V3_ADD_VALUE,0), "X509V3_add_value"}, | ||
99 | {ERR_PACK(0,X509V3_F_X509V3_EXT_ADD,0), "X509V3_EXT_add"}, | ||
100 | {ERR_PACK(0,X509V3_F_X509V3_EXT_ADD_ALIAS,0), "X509V3_EXT_add_alias"}, | ||
101 | {ERR_PACK(0,X509V3_F_X509V3_EXT_CONF,0), "X509V3_EXT_conf"}, | ||
102 | {ERR_PACK(0,X509V3_F_X509V3_EXT_I2D,0), "X509V3_EXT_i2d"}, | ||
103 | {ERR_PACK(0,X509V3_F_X509V3_GET_VALUE_BOOL,0), "X509V3_get_value_bool"}, | ||
104 | {ERR_PACK(0,X509V3_F_X509V3_PARSE_LIST,0), "X509V3_parse_list"}, | ||
105 | {0,NULL} | ||
106 | }; | ||
107 | |||
108 | static ERR_STRING_DATA X509V3_str_reasons[]= | ||
109 | { | ||
110 | {X509V3_R_BAD_IP_ADDRESS ,"bad ip address"}, | ||
111 | {X509V3_R_BAD_OBJECT ,"bad object"}, | ||
112 | {X509V3_R_BN_DEC2BN_ERROR ,"bn dec2bn error"}, | ||
113 | {X509V3_R_BN_TO_ASN1_INTEGER_ERROR ,"bn to asn1 integer error"}, | ||
114 | {X509V3_R_DUPLICATE_ZONE_ID ,"duplicate zone id"}, | ||
115 | {X509V3_R_ERROR_CONVERTING_ZONE ,"error converting zone"}, | ||
116 | {X509V3_R_ERROR_IN_EXTENSION ,"error in extension"}, | ||
117 | {X509V3_R_EXPECTED_A_SECTION_NAME ,"expected a section name"}, | ||
118 | {X509V3_R_EXTENSION_NAME_ERROR ,"extension name error"}, | ||
119 | {X509V3_R_EXTENSION_NOT_FOUND ,"extension not found"}, | ||
120 | {X509V3_R_EXTENSION_SETTING_NOT_SUPPORTED,"extension setting not supported"}, | ||
121 | {X509V3_R_EXTENSION_VALUE_ERROR ,"extension value error"}, | ||
122 | {X509V3_R_ILLEGAL_HEX_DIGIT ,"illegal hex digit"}, | ||
123 | {X509V3_R_INVALID_BOOLEAN_STRING ,"invalid boolean string"}, | ||
124 | {X509V3_R_INVALID_EXTENSION_STRING ,"invalid extension string"}, | ||
125 | {X509V3_R_INVALID_NAME ,"invalid name"}, | ||
126 | {X509V3_R_INVALID_NULL_ARGUMENT ,"invalid null argument"}, | ||
127 | {X509V3_R_INVALID_NULL_NAME ,"invalid null name"}, | ||
128 | {X509V3_R_INVALID_NULL_VALUE ,"invalid null value"}, | ||
129 | {X509V3_R_INVALID_NUMBER ,"invalid number"}, | ||
130 | {X509V3_R_INVALID_NUMBERS ,"invalid numbers"}, | ||
131 | {X509V3_R_INVALID_OBJECT_IDENTIFIER ,"invalid object identifier"}, | ||
132 | {X509V3_R_INVALID_OPTION ,"invalid option"}, | ||
133 | {X509V3_R_INVALID_POLICY_IDENTIFIER ,"invalid policy identifier"}, | ||
134 | {X509V3_R_INVALID_SECTION ,"invalid section"}, | ||
135 | {X509V3_R_ISSUER_DECODE_ERROR ,"issuer decode error"}, | ||
136 | {X509V3_R_MISSING_VALUE ,"missing value"}, | ||
137 | {X509V3_R_NEED_ORGANIZATION_AND_NUMBERS ,"need organization and numbers"}, | ||
138 | {X509V3_R_NO_CONFIG_DATABASE ,"no config database"}, | ||
139 | {X509V3_R_NO_ISSUER_CERTIFICATE ,"no issuer certificate"}, | ||
140 | {X509V3_R_NO_ISSUER_DETAILS ,"no issuer details"}, | ||
141 | {X509V3_R_NO_POLICY_IDENTIFIER ,"no policy identifier"}, | ||
142 | {X509V3_R_NO_PUBLIC_KEY ,"no public key"}, | ||
143 | {X509V3_R_NO_SUBJECT_DETAILS ,"no subject details"}, | ||
144 | {X509V3_R_ODD_NUMBER_OF_DIGITS ,"odd number of digits"}, | ||
145 | {X509V3_R_UNABLE_TO_GET_ISSUER_DETAILS ,"unable to get issuer details"}, | ||
146 | {X509V3_R_UNABLE_TO_GET_ISSUER_KEYID ,"unable to get issuer keyid"}, | ||
147 | {X509V3_R_UNKNOWN_BIT_STRING_ARGUMENT ,"unknown bit string argument"}, | ||
148 | {X509V3_R_UNKNOWN_EXTENSION ,"unknown extension"}, | ||
149 | {X509V3_R_UNKNOWN_EXTENSION_NAME ,"unknown extension name"}, | ||
150 | {X509V3_R_UNKNOWN_OPTION ,"unknown option"}, | ||
151 | {X509V3_R_UNSUPPORTED_OPTION ,"unsupported option"}, | ||
152 | {X509V3_R_USER_TOO_LONG ,"user too long"}, | ||
153 | {0,NULL} | ||
154 | }; | ||
155 | |||
156 | #endif | ||
157 | |||
158 | void ERR_load_X509V3_strings(void) | ||
159 | { | ||
160 | static int init=1; | ||
161 | |||
162 | if (init) | ||
163 | { | ||
164 | init=0; | ||
165 | #ifndef NO_ERR | ||
166 | ERR_load_strings(ERR_LIB_X509V3,X509V3_str_functs); | ||
167 | ERR_load_strings(ERR_LIB_X509V3,X509V3_str_reasons); | ||
168 | #endif | ||
169 | |||
170 | } | ||
171 | } | ||
diff --git a/src/lib/libssl/LICENSE b/src/lib/libssl/LICENSE new file mode 100644 index 0000000000..b9e18d5e7b --- /dev/null +++ b/src/lib/libssl/LICENSE | |||
@@ -0,0 +1,127 @@ | |||
1 | |||
2 | LICENSE ISSUES | ||
3 | ============== | ||
4 | |||
5 | The OpenSSL toolkit stays under a dual license, i.e. both the conditions of | ||
6 | the OpenSSL License and the original SSLeay license apply to the toolkit. | ||
7 | See below for the actual license texts. Actually both licenses are BSD-style | ||
8 | Open Source licenses. In case of any license issues related to OpenSSL | ||
9 | please contact openssl-core@openssl.org. | ||
10 | |||
11 | OpenSSL License | ||
12 | --------------- | ||
13 | |||
14 | /* ==================================================================== | ||
15 | * Copyright (c) 1998-1999 The OpenSSL Project. All rights reserved. | ||
16 | * | ||
17 | * Redistribution and use in source and binary forms, with or without | ||
18 | * modification, are permitted provided that the following conditions | ||
19 | * are met: | ||
20 | * | ||
21 | * 1. Redistributions of source code must retain the above copyright | ||
22 | * notice, this list of conditions and the following disclaimer. | ||
23 | * | ||
24 | * 2. Redistributions in binary form must reproduce the above copyright | ||
25 | * notice, this list of conditions and the following disclaimer in | ||
26 | * the documentation and/or other materials provided with the | ||
27 | * distribution. | ||
28 | * | ||
29 | * 3. All advertising materials mentioning features or use of this | ||
30 | * software must display the following acknowledgment: | ||
31 | * "This product includes software developed by the OpenSSL Project | ||
32 | * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" | ||
33 | * | ||
34 | * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to | ||
35 | * endorse or promote products derived from this software without | ||
36 | * prior written permission. For written permission, please contact | ||
37 | * openssl-core@openssl.org. | ||
38 | * | ||
39 | * 5. Products derived from this software may not be called "OpenSSL" | ||
40 | * nor may "OpenSSL" appear in their names without prior written | ||
41 | * permission of the OpenSSL Project. | ||
42 | * | ||
43 | * 6. Redistributions of any form whatsoever must retain the following | ||
44 | * acknowledgment: | ||
45 | * "This product includes software developed by the OpenSSL Project | ||
46 | * for use in the OpenSSL Toolkit (http://www.openssl.org/)" | ||
47 | * | ||
48 | * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY | ||
49 | * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
50 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | ||
51 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR | ||
52 | * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
53 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
54 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
55 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
56 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
57 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
58 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED | ||
59 | * OF THE POSSIBILITY OF SUCH DAMAGE. | ||
60 | * ==================================================================== | ||
61 | * | ||
62 | * This product includes cryptographic software written by Eric Young | ||
63 | * (eay@cryptsoft.com). This product includes software written by Tim | ||
64 | * Hudson (tjh@cryptsoft.com). | ||
65 | * | ||
66 | */ | ||
67 | |||
68 | Original SSLeay License | ||
69 | ----------------------- | ||
70 | |||
71 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) | ||
72 | * All rights reserved. | ||
73 | * | ||
74 | * This package is an SSL implementation written | ||
75 | * by Eric Young (eay@cryptsoft.com). | ||
76 | * The implementation was written so as to conform with Netscapes SSL. | ||
77 | * | ||
78 | * This library is free for commercial and non-commercial use as long as | ||
79 | * the following conditions are aheared to. The following conditions | ||
80 | * apply to all code found in this distribution, be it the RC4, RSA, | ||
81 | * lhash, DES, etc., code; not just the SSL code. The SSL documentation | ||
82 | * included with this distribution is covered by the same copyright terms | ||
83 | * except that the holder is Tim Hudson (tjh@cryptsoft.com). | ||
84 | * | ||
85 | * Copyright remains Eric Young's, and as such any Copyright notices in | ||
86 | * the code are not to be removed. | ||
87 | * If this package is used in a product, Eric Young should be given attribution | ||
88 | * as the author of the parts of the library used. | ||
89 | * This can be in the form of a textual message at program startup or | ||
90 | * in documentation (online or textual) provided with the package. | ||
91 | * | ||
92 | * Redistribution and use in source and binary forms, with or without | ||
93 | * modification, are permitted provided that the following conditions | ||
94 | * are met: | ||
95 | * 1. Redistributions of source code must retain the copyright | ||
96 | * notice, this list of conditions and the following disclaimer. | ||
97 | * 2. Redistributions in binary form must reproduce the above copyright | ||
98 | * notice, this list of conditions and the following disclaimer in the | ||
99 | * documentation and/or other materials provided with the distribution. | ||
100 | * 3. All advertising materials mentioning features or use of this software | ||
101 | * must display the following acknowledgement: | ||
102 | * "This product includes cryptographic software written by | ||
103 | * Eric Young (eay@cryptsoft.com)" | ||
104 | * The word 'cryptographic' can be left out if the rouines from the library | ||
105 | * being used are not cryptographic related :-). | ||
106 | * 4. If you include any Windows specific code (or a derivative thereof) from | ||
107 | * the apps directory (application code) you must include an acknowledgement: | ||
108 | * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" | ||
109 | * | ||
110 | * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND | ||
111 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
112 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
113 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | ||
114 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
115 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
116 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
117 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
118 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
119 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
120 | * SUCH DAMAGE. | ||
121 | * | ||
122 | * The licence and distribution terms for any publically available version or | ||
123 | * derivative of this code cannot be changed. i.e. this code cannot simply be | ||
124 | * copied and put under another distribution licence | ||
125 | * [including the GNU Public Licence.] | ||
126 | */ | ||
127 | |||
diff --git a/src/lib/libssl/doc/openssl.cnf b/src/lib/libssl/doc/openssl.cnf new file mode 100644 index 0000000000..d70dd25622 --- /dev/null +++ b/src/lib/libssl/doc/openssl.cnf | |||
@@ -0,0 +1,214 @@ | |||
1 | # | ||
2 | # OpenSSL example configuration file. | ||
3 | # This is mostly being used for generation of certificate requests. | ||
4 | # | ||
5 | |||
6 | RANDFILE = $ENV::HOME/.rnd | ||
7 | oid_file = $ENV::HOME/.oid | ||
8 | oid_section = new_oids | ||
9 | |||
10 | # To use this configuration file with the "-extfile" option of the | ||
11 | # "openssl x509" utility, name here the section containing the | ||
12 | # X.509v3 extensions to use: | ||
13 | # extensions = | ||
14 | # (Alternatively, use a configuration file that has only | ||
15 | # X.509v3 extensions in its main [= default] section.) | ||
16 | |||
17 | [ new_oids ] | ||
18 | |||
19 | # We can add new OIDs in here for use by 'ca' and 'req'. | ||
20 | # Add a simple OID like this: | ||
21 | # testoid1=1.2.3.4 | ||
22 | # Or use config file substitution like this: | ||
23 | # testoid2=${testoid1}.5.6 | ||
24 | |||
25 | #################################################################### | ||
26 | [ ca ] | ||
27 | default_ca = CA_default # The default ca section | ||
28 | |||
29 | #################################################################### | ||
30 | [ CA_default ] | ||
31 | |||
32 | dir = ./demoCA # Where everything is kept | ||
33 | certs = $dir/certs # Where the issued certs are kept | ||
34 | crl_dir = $dir/crl # Where the issued crl are kept | ||
35 | database = $dir/index.txt # database index file. | ||
36 | new_certs_dir = $dir/newcerts # default place for new certs. | ||
37 | |||
38 | certificate = $dir/cacert.pem # The CA certificate | ||
39 | serial = $dir/serial # The current serial number | ||
40 | crl = $dir/crl.pem # The current CRL | ||
41 | private_key = $dir/private/cakey.pem# The private key | ||
42 | RANDFILE = $dir/private/.rand # private random number file | ||
43 | |||
44 | x509_extensions = usr_cert # The extentions to add to the cert | ||
45 | |||
46 | # Extensions to add to a CRL. Note: Netscape communicator chokes on V2 CRLs | ||
47 | # so this is commented out by default to leave a V1 CRL. | ||
48 | # crl_extensions = crl_ext | ||
49 | |||
50 | default_days = 365 # how long to certify for | ||
51 | default_crl_days= 30 # how long before next CRL | ||
52 | default_md = md5 # which md to use. | ||
53 | preserve = no # keep passed DN ordering | ||
54 | |||
55 | # A few difference way of specifying how similar the request should look | ||
56 | # For type CA, the listed attributes must be the same, and the optional | ||
57 | # and supplied fields are just that :-) | ||
58 | policy = policy_match | ||
59 | |||
60 | # For the CA policy | ||
61 | [ policy_match ] | ||
62 | countryName = match | ||
63 | stateOrProvinceName = match | ||
64 | organizationName = match | ||
65 | organizationalUnitName = optional | ||
66 | commonName = supplied | ||
67 | emailAddress = optional | ||
68 | |||
69 | # For the 'anything' policy | ||
70 | # At this point in time, you must list all acceptable 'object' | ||
71 | # types. | ||
72 | [ policy_anything ] | ||
73 | countryName = optional | ||
74 | stateOrProvinceName = optional | ||
75 | localityName = optional | ||
76 | organizationName = optional | ||
77 | organizationalUnitName = optional | ||
78 | commonName = supplied | ||
79 | emailAddress = optional | ||
80 | |||
81 | #################################################################### | ||
82 | [ req ] | ||
83 | default_bits = 1024 | ||
84 | default_keyfile = privkey.pem | ||
85 | distinguished_name = req_distinguished_name | ||
86 | attributes = req_attributes | ||
87 | x509_extensions = v3_ca # The extentions to add to the self signed cert | ||
88 | |||
89 | [ req_distinguished_name ] | ||
90 | countryName = Country Name (2 letter code) | ||
91 | countryName_default = AU | ||
92 | countryName_min = 2 | ||
93 | countryName_max = 2 | ||
94 | |||
95 | stateOrProvinceName = State or Province Name (full name) | ||
96 | stateOrProvinceName_default = Some-State | ||
97 | |||
98 | localityName = Locality Name (eg, city) | ||
99 | |||
100 | 0.organizationName = Organization Name (eg, company) | ||
101 | 0.organizationName_default = Internet Widgits Pty Ltd | ||
102 | |||
103 | # we can do this but it is not needed normally :-) | ||
104 | #1.organizationName = Second Organization Name (eg, company) | ||
105 | #1.organizationName_default = World Wide Web Pty Ltd | ||
106 | |||
107 | organizationalUnitName = Organizational Unit Name (eg, section) | ||
108 | #organizationalUnitName_default = | ||
109 | |||
110 | commonName = Common Name (eg, YOUR name) | ||
111 | commonName_max = 64 | ||
112 | |||
113 | emailAddress = Email Address | ||
114 | emailAddress_max = 40 | ||
115 | |||
116 | # SET-ex3 = SET extension number 3 | ||
117 | |||
118 | [ req_attributes ] | ||
119 | challengePassword = A challenge password | ||
120 | challengePassword_min = 4 | ||
121 | challengePassword_max = 20 | ||
122 | |||
123 | unstructuredName = An optional company name | ||
124 | |||
125 | [ usr_cert ] | ||
126 | |||
127 | # These extensions are added when 'ca' signs a request. | ||
128 | |||
129 | # This goes against PKIX guidelines but some CAs do it and some software | ||
130 | # requires this to avoid interpreting an end user certificate as a CA. | ||
131 | |||
132 | basicConstraints=CA:FALSE | ||
133 | |||
134 | # Here are some examples of the usage of nsCertType. If it is omitted | ||
135 | # the certificate can be used for anything *except* object signing. | ||
136 | |||
137 | # This is OK for an SSL server. | ||
138 | # nsCertType = server | ||
139 | |||
140 | # For an object signing certificate this would be used. | ||
141 | # nsCertType = objsign | ||
142 | |||
143 | # For normal client use this is typical | ||
144 | # nsCertType = client, email | ||
145 | |||
146 | # and for everything including object signing: | ||
147 | # nsCertType = client, email, objsign | ||
148 | |||
149 | # This is typical in keyUsage for a client certificate. | ||
150 | # keyUsage = nonRepudiation, digitalSignature, keyEncipherment | ||
151 | |||
152 | # This will be displayed in Netscape's comment listbox. | ||
153 | nsComment = "OpenSSL Generated Certificate" | ||
154 | |||
155 | # PKIX recommendations harmless if included in all certificates. | ||
156 | subjectKeyIdentifier=hash | ||
157 | authorityKeyIdentifier=keyid,issuer:always | ||
158 | |||
159 | # This stuff is for subjectAltName and issuerAltname. | ||
160 | # Import the email address. | ||
161 | # subjectAltName=email:copy | ||
162 | |||
163 | # Copy subject details | ||
164 | # issuerAltName=issuer:copy | ||
165 | |||
166 | #nsCaRevocationUrl = http://www.domain.dom/ca-crl.pem | ||
167 | #nsBaseUrl | ||
168 | #nsRevocationUrl | ||
169 | #nsRenewalUrl | ||
170 | #nsCaPolicyUrl | ||
171 | #nsSslServerName | ||
172 | |||
173 | [ v3_ca ] | ||
174 | |||
175 | # Extensions for a typical CA | ||
176 | |||
177 | |||
178 | # PKIX recommendation. | ||
179 | |||
180 | subjectKeyIdentifier=hash | ||
181 | |||
182 | authorityKeyIdentifier=keyid:always,issuer:always | ||
183 | |||
184 | # This is what PKIX recommends but some broken software chokes on critical | ||
185 | # extensions. | ||
186 | #basicConstraints = critical,CA:true | ||
187 | # So we do this instead. | ||
188 | basicConstraints = CA:true | ||
189 | |||
190 | # Key usage: this is typical for a CA certificate. However since it will | ||
191 | # prevent it being used as an test self-signed certificate it is best | ||
192 | # left out by default. | ||
193 | # keyUsage = cRLSign, keyCertSign | ||
194 | |||
195 | # Some might want this also | ||
196 | # nsCertType = sslCA, emailCA | ||
197 | |||
198 | # Include email address in subject alt name: another PKIX recommendation | ||
199 | # subjectAltName=email:copy | ||
200 | # Copy issuer details | ||
201 | # issuerAltName=issuer:copy | ||
202 | |||
203 | # RAW DER hex encoding of an extension: beware experts only! | ||
204 | # 1.2.3.5=RAW:02:03 | ||
205 | # You can even override a supported extension: | ||
206 | # basicConstraints= critical, RAW:30:03:01:01:FF | ||
207 | |||
208 | [ crl_ext ] | ||
209 | |||
210 | # CRL extensions. | ||
211 | # Only issuerAltName and authorityKeyIdentifier make any sense in a CRL. | ||
212 | |||
213 | # issuerAltName=issuer:copy | ||
214 | authorityKeyIdentifier=keyid:always,issuer:always | ||
diff --git a/src/lib/libssl/doc/openssl.txt b/src/lib/libssl/doc/openssl.txt new file mode 100644 index 0000000000..91b85e5f14 --- /dev/null +++ b/src/lib/libssl/doc/openssl.txt | |||
@@ -0,0 +1,1174 @@ | |||
1 | |||
2 | This is some preliminary documentation for OpenSSL. | ||
3 | |||
4 | ============================================================================== | ||
5 | BUFFER Library | ||
6 | ============================================================================== | ||
7 | |||
8 | The buffer library handles simple character arrays. Buffers are used for | ||
9 | various purposes in the library, most notably memory BIOs. | ||
10 | |||
11 | The library uses the BUF_MEM structure defined in buffer.h: | ||
12 | |||
13 | typedef struct buf_mem_st | ||
14 | { | ||
15 | int length; /* current number of bytes */ | ||
16 | char *data; | ||
17 | int max; /* size of buffer */ | ||
18 | } BUF_MEM; | ||
19 | |||
20 | 'length' is the current size of the buffer in bytes, 'max' is the amount of | ||
21 | memory allocated to the buffer. There are three functions which handle these | ||
22 | and one "miscellaneous" function. | ||
23 | |||
24 | BUF_MEM *BUF_MEM_new() | ||
25 | |||
26 | This allocates a new buffer of zero size. Returns the buffer or NULL on error. | ||
27 | |||
28 | void BUF_MEM_free(BUF_MEM *a) | ||
29 | |||
30 | This frees up an already existing buffer. The data is zeroed before freeing | ||
31 | up in case the buffer contains sensitive data. | ||
32 | |||
33 | int BUF_MEM_grow(BUF_MEM *str, int len) | ||
34 | |||
35 | This changes the size of an already existing buffer. It returns zero on error | ||
36 | or the new size (i.e. 'len'). Any data already in the buffer is preserved if | ||
37 | it increases in size. | ||
38 | |||
39 | char * BUF_strdup(char *str) | ||
40 | |||
41 | This is the previously mentioned strdup function: like the standard library | ||
42 | strdup() it copies a null terminated string into a block of allocated memory | ||
43 | and returns a pointer to the allocated block. | ||
44 | |||
45 | Unlike the standard C library strdup() this function uses Malloc() and so | ||
46 | should be used in preference to the standard library strdup() because it can | ||
47 | be used for memory leak checking or replacing the malloc() function. | ||
48 | |||
49 | The memory allocated from BUF_strdup() should be freed up using the Free() | ||
50 | function. | ||
51 | |||
52 | ============================================================================== | ||
53 | OpenSSL X509V3 extension configuration | ||
54 | ============================================================================== | ||
55 | |||
56 | OpenSSL X509V3 extension configuration: preliminary documentation. | ||
57 | |||
58 | INTRODUCTION. | ||
59 | |||
60 | For OpenSSL 0.9.2 the extension code has be considerably enhanced. It is now | ||
61 | possible to add and print out common X509 V3 certificate and CRL extensions. | ||
62 | |||
63 | BEGINNERS NOTE | ||
64 | |||
65 | For most simple applications you don't need to know too much about extensions: | ||
66 | the default openssl.cnf values will usually do sensible things. | ||
67 | |||
68 | If you want to know more you can initially quickly look through the sections | ||
69 | describing how the standard OpenSSL utilities display and add extensions and | ||
70 | then the list of supported extensions. | ||
71 | |||
72 | For more technical information about the meaning of extensions see: | ||
73 | |||
74 | http://www.imc.org/ietf-pkix/ | ||
75 | http://home.netscape.com/eng/security/certs.html | ||
76 | |||
77 | PRINTING EXTENSIONS. | ||
78 | |||
79 | Extension values are automatically printed out for supported extensions. | ||
80 | |||
81 | openssl x509 -in cert.pem -text | ||
82 | openssl crl -in crl.pem -text | ||
83 | |||
84 | will give information in the extension printout, for example: | ||
85 | |||
86 | X509v3 extensions: | ||
87 | X509v3 Basic Constraints: | ||
88 | CA:TRUE | ||
89 | X509v3 Subject Key Identifier: | ||
90 | 73:FE:F7:59:A7:E1:26:84:44:D6:44:36:EE:79:1A:95:7C:B1:4B:15 | ||
91 | X509v3 Authority Key Identifier: | ||
92 | keyid:73:FE:F7:59:A7:E1:26:84:44:D6:44:36:EE:79:1A:95:7C:B1:4B:15, DirName:/C=AU/ST=Some-State/O=Internet Widgits Pty Ltd/Email=email@1.address/Email=email@2.address, serial:00 | ||
93 | X509v3 Key Usage: | ||
94 | Certificate Sign, CRL Sign | ||
95 | X509v3 Subject Alternative Name: | ||
96 | email:email@1.address, email:email@2.address | ||
97 | |||
98 | CONFIGURATION FILES. | ||
99 | |||
100 | The OpenSSL utilities 'ca' and 'req' can now have extension sections listing | ||
101 | which certificate extensions to include. In each case a line: | ||
102 | |||
103 | x509_extensions = extension_section | ||
104 | |||
105 | indicates which section contains the extensions. In the case of 'req' the | ||
106 | extension section is used when the -x509 option is present to create a | ||
107 | self signed root certificate. | ||
108 | |||
109 | The 'x509' utility also supports extensions when it signs a certificate. | ||
110 | The -extfile option is used to set the configuration file containing the | ||
111 | extensions. In this case a line with: | ||
112 | |||
113 | extensions = extension_section | ||
114 | |||
115 | in the nameless (default) section is used. If no such line is included then | ||
116 | it uses the default section. | ||
117 | |||
118 | You can also add extensions to CRLs: a line | ||
119 | |||
120 | crl_extensions = crl_extension_section | ||
121 | |||
122 | will include extensions when the -gencrl option is used with the 'ca' utility. | ||
123 | You can add any extension to a CRL but of the supported extensions only | ||
124 | issuerAltName and authorityKeyIdentifier make any real sense. Note: these are | ||
125 | CRL extensions NOT CRL *entry* extensions which cannot currently be generated. | ||
126 | CRL entry extensions can be displayed. | ||
127 | |||
128 | NB. At this time Netscape Communicator rejects V2 CRLs: to get an old V1 CRL | ||
129 | you should not include a crl_extensions line in the configuration file. | ||
130 | |||
131 | As with all configuration files you can use the inbuilt environment expansion | ||
132 | to allow the values to be passed in the environment. Therefore if you have | ||
133 | several extension sections used for different purposes you can have a line: | ||
134 | |||
135 | x509_extensions = $ENV::ENV_EXT | ||
136 | |||
137 | and set the ENV_EXT environment variable before calling the relevant utility. | ||
138 | |||
139 | EXTENSION SYNTAX. | ||
140 | |||
141 | Extensions have the basic form: | ||
142 | |||
143 | extension_name=[critical,] extension_options | ||
144 | |||
145 | the use of the critical option makes the extension critical. Extreme caution | ||
146 | should be made when using the critical flag. If an extension is marked | ||
147 | as critical then any client that does not understand the extension should | ||
148 | reject it as invalid. Some broken software will reject certificates which | ||
149 | have *any* critical extensions (these violates PKIX but we have to live | ||
150 | with it). | ||
151 | |||
152 | There are three main types of extension: string extensions, multi-valued | ||
153 | extensions, and raw extensions. | ||
154 | |||
155 | String extensions simply have a string which contains either the value itself | ||
156 | or how it is obtained. | ||
157 | |||
158 | For example: | ||
159 | |||
160 | nsComment="This is a Comment" | ||
161 | |||
162 | Multi-valued extensions have a short form and a long form. The short form | ||
163 | is a list of names and values: | ||
164 | |||
165 | basicConstraints=critical,CA:true,pathlen:1 | ||
166 | |||
167 | The long form allows the values to be placed in a separate section: | ||
168 | |||
169 | basicConstraints=critical,@bs_section | ||
170 | |||
171 | [bs_section] | ||
172 | |||
173 | CA=true | ||
174 | pathlen=1 | ||
175 | |||
176 | Both forms are equivalent. However it should be noted that in some cases the | ||
177 | same name can appear multiple times, for example, | ||
178 | |||
179 | subjectAltName=email:steve@here,email:steve@there | ||
180 | |||
181 | in this case an equivalent long form is: | ||
182 | |||
183 | subjectAltName=@alt_section | ||
184 | |||
185 | [alt_section] | ||
186 | |||
187 | email.1=steve@here | ||
188 | email.2=steve@there | ||
189 | |||
190 | This is because the configuration file code cannot handle the same name | ||
191 | occurring twice in the same extension. | ||
192 | |||
193 | The syntax of raw extensions is governed by the extension code: it can | ||
194 | for example contain data in multiple sections. The correct syntax to | ||
195 | use is defined by the extension code itself: check out the certificate | ||
196 | policies extension for an example. | ||
197 | |||
198 | In addition it is also possible to use the word DER to include arbitrary | ||
199 | data in any extension. | ||
200 | |||
201 | 1.2.3.4=critical,DER:01:02:03:04 | ||
202 | 1.2.3.4=DER:01020304 | ||
203 | |||
204 | The value following DER is a hex dump of the DER encoding of the extension | ||
205 | Any extension can be placed in this form to override the default behaviour. | ||
206 | For example: | ||
207 | |||
208 | basicConstraints=critical,DER:00:01:02:03 | ||
209 | |||
210 | WARNING: DER should be used with caution. It is possible to create totally | ||
211 | invalid extensions unless care is taken. | ||
212 | |||
213 | CURRENTLY SUPPORTED EXTENSIONS. | ||
214 | |||
215 | If you aren't sure about extensions then they can be largely ignored: its only | ||
216 | when you want to do things like restrict certificate usage when you need to | ||
217 | worry about them. | ||
218 | |||
219 | The only extension that a beginner might want to look at is Basic Constraints. | ||
220 | If in addition you want to try Netscape object signing the you should also | ||
221 | look at Netscape Certificate Type. | ||
222 | |||
223 | Literal String extensions. | ||
224 | |||
225 | In each case the 'value' of the extension is placed directly in the | ||
226 | extension. Currently supported extensions in this category are: nsBaseUrl, | ||
227 | nsRevocationUrl, nsCaRevocationUrl, nsRenewalUrl, nsCaPolicyUrl, | ||
228 | nsSslServerName and nsComment. | ||
229 | |||
230 | For example: | ||
231 | |||
232 | nsComment="This is a test comment" | ||
233 | |||
234 | Bit Strings. | ||
235 | |||
236 | Bit string extensions just consist of a list of supported bits, currently | ||
237 | two extensions are in this category: PKIX keyUsage and the Netscape specific | ||
238 | nsCertType. | ||
239 | |||
240 | nsCertType (netscape certificate type) takes the flags: client, server, email, | ||
241 | objsign, reserved, sslCA, emailCA, objCA. | ||
242 | |||
243 | keyUsage (PKIX key usage) takes the flags: digitalSignature, nonRepudiation, | ||
244 | keyEncipherment, dataEncipherment, keyAgreement, keyCertSign, cRLSign, | ||
245 | encipherOnly, decipherOnly. | ||
246 | |||
247 | For example: | ||
248 | |||
249 | nsCertType=server | ||
250 | |||
251 | keyUsage=digitalSignature, nonRepudiation | ||
252 | |||
253 | Hints on Netscape Certificate Type. | ||
254 | |||
255 | Other than Basic Constraints this is the only extension a beginner might | ||
256 | want to use, if you want to try Netscape object signing, otherwise it can | ||
257 | be ignored. | ||
258 | |||
259 | If you want a certificate that can be used just for object signing then: | ||
260 | |||
261 | nsCertType=objsign | ||
262 | |||
263 | will do the job. If you want to use it as a normal end user and server | ||
264 | certificate as well then | ||
265 | |||
266 | nsCertType=objsign,email,server | ||
267 | |||
268 | is more appropriate. You cannot use a self signed certificate for object | ||
269 | signing (well Netscape signtool can but it cheats!) so you need to create | ||
270 | a CA certificate and sign an end user certificate with it. | ||
271 | |||
272 | Side note: If you want to conform to the Netscape specifications then you | ||
273 | should really also set: | ||
274 | |||
275 | nsCertType=objCA | ||
276 | |||
277 | in the *CA* certificate for just an object signing CA and | ||
278 | |||
279 | nsCertType=objCA,emailCA,sslCA | ||
280 | |||
281 | for everything. Current Netscape software doesn't enforce this so it can | ||
282 | be omitted. | ||
283 | |||
284 | Basic Constraints. | ||
285 | |||
286 | This is generally the only extension you need to worry about for simple | ||
287 | applications. If you want your certificate to be usable as a CA certificate | ||
288 | (in addition to an end user certificate) then you set this to: | ||
289 | |||
290 | basicConstraints=CA:TRUE | ||
291 | |||
292 | if you want to be certain the certificate cannot be used as a CA then do: | ||
293 | |||
294 | basicConstraints=CA:FALSE | ||
295 | |||
296 | The rest of this section describes more advanced usage. | ||
297 | |||
298 | Basic constraints is a multi-valued extension that supports a CA and an | ||
299 | optional pathlen option. The CA option takes the values true and false and | ||
300 | pathlen takes an integer. Note if the CA option is false the pathlen option | ||
301 | should be omitted. | ||
302 | |||
303 | The pathlen parameter indicates the maximum number of CAs that can appear | ||
304 | below this one in a chain. So if you have a CA with a pathlen of zero it can | ||
305 | only be used to sign end user certificates and not further CAs. This all | ||
306 | assumes that the software correctly interprets this extension of course. | ||
307 | |||
308 | Examples: | ||
309 | |||
310 | basicConstraints=CA:TRUE | ||
311 | basicConstraints=critical,CA:TRUE, pathlen:0 | ||
312 | |||
313 | NOTE: for a CA to be considered valid it must have the CA option set to | ||
314 | TRUE. An end user certificate MUST NOT have the CA value set to true. | ||
315 | According to PKIX recommendations it should exclude the extension entirely, | ||
316 | however some software may require CA set to FALSE for end entity certificates. | ||
317 | |||
318 | Subject Key Identifier. | ||
319 | |||
320 | This is really a string extension and can take two possible values. Either | ||
321 | a hex string giving details of the extension value to include or the word | ||
322 | 'hash' which then automatically follow PKIX guidelines in selecting and | ||
323 | appropriate key identifier. The use of the hex string is strongly discouraged. | ||
324 | |||
325 | Example: subjectKeyIdentifier=hash | ||
326 | |||
327 | Authority Key Identifier. | ||
328 | |||
329 | The authority key identifier extension permits two options. keyid and issuer: | ||
330 | both can take the optional value "always". | ||
331 | |||
332 | If the keyid option is present an attempt is made to copy the subject key | ||
333 | identifier from the parent certificate. If the value "always" is present | ||
334 | then an error is returned if the option fails. | ||
335 | |||
336 | The issuer option copies the issuer and serial number from the issuer | ||
337 | certificate. Normally this will only be done if the keyid option fails or | ||
338 | is not included: the "always" flag will always include the value. | ||
339 | |||
340 | Subject Alternative Name. | ||
341 | |||
342 | The subject alternative name extension allows various literal values to be | ||
343 | included in the configuration file. These include "email" (an email address) | ||
344 | "URI" a uniform resource indicator, "DNS" (a DNS domain name), RID (a | ||
345 | registered ID: OBJECT IDENTIFIER) and IP (and IP address). | ||
346 | |||
347 | Also the email option include a special 'copy' value. This will automatically | ||
348 | include and email addresses contained in the certificate subject name in | ||
349 | the extension. | ||
350 | |||
351 | Examples: | ||
352 | |||
353 | subjectAltName=email:copy,email:my@other.address,URL:http://my.url.here/ | ||
354 | subjectAltName=email:my@other.address,RID:1.2.3.4 | ||
355 | |||
356 | Issuer Alternative Name. | ||
357 | |||
358 | The issuer alternative name option supports all the literal options of | ||
359 | subject alternative name. It does *not* support the email:copy option because | ||
360 | that would not make sense. It does support an additional issuer:copy option | ||
361 | that will copy all the subject alternative name values from the issuer | ||
362 | certificate (if possible). | ||
363 | |||
364 | CRL distribution points. | ||
365 | |||
366 | This is a multi-valued extension that supports all the literal options of | ||
367 | subject alternative name. Of the few software packages that currently interpret | ||
368 | this extension most only interpret the URI option. | ||
369 | |||
370 | Currently each option will set a new DistributionPoint with the fullName | ||
371 | field set to the given value. | ||
372 | |||
373 | Other fields like cRLissuer and reasons cannot currently be set or displayed: | ||
374 | at this time no examples were available that used these fields. | ||
375 | |||
376 | If you see this extension with <UNSUPPORTED> when you attempt to print it out | ||
377 | or it doesn't appear to display correctly then let me know, including the | ||
378 | certificate (mail me at steve@openssl.org) . | ||
379 | |||
380 | Examples: | ||
381 | |||
382 | crlDistributionPoints=URI:http://www.myhost.com/myca.crl | ||
383 | crlDistributionPoints=URI:http://www.my.com/my.crl,URI:http://www.oth.com/my.crl | ||
384 | |||
385 | Certificate Policies. | ||
386 | |||
387 | This is a RAW extension. It attempts to display the contents of this extension: | ||
388 | unfortunately this extension is often improperly encoded. | ||
389 | |||
390 | The certificate policies extension will rarely be used in practice: few | ||
391 | software packages interpret it correctly or at all. IE5 does partially | ||
392 | support this extension: but it needs the 'ia5org' option because it will | ||
393 | only correctly support a broken encoding. Of the options below only the | ||
394 | policy OID, explicitText and CPS options are displayed with IE5. | ||
395 | |||
396 | All the fields of this extension can be set by using the appropriate syntax. | ||
397 | |||
398 | If you follow the PKIX recommendations of not including any qualifiers and just | ||
399 | using only one OID then you just include the value of that OID. Multiple OIDs | ||
400 | can be set separated by commas, for example: | ||
401 | |||
402 | certificatePolicies= 1.2.4.5, 1.1.3.4 | ||
403 | |||
404 | If you wish to include qualifiers then the policy OID and qualifiers need to | ||
405 | be specified in a separate section: this is done by using the @section syntax | ||
406 | instead of a literal OID value. | ||
407 | |||
408 | The section referred to must include the policy OID using the name | ||
409 | policyIdentifier, cPSuri qualifiers can be included using the syntax: | ||
410 | |||
411 | CPS.nnn=value | ||
412 | |||
413 | userNotice qualifiers can be set using the syntax: | ||
414 | |||
415 | userNotice.nnn=@notice | ||
416 | |||
417 | The value of the userNotice qualifier is specified in the relevant section. | ||
418 | This section can include explicitText, organization and noticeNumbers | ||
419 | options. explicitText and organization are text strings, noticeNumbers is a | ||
420 | comma separated list of numbers. The organization and noticeNumbers options | ||
421 | (if included) must BOTH be present. If you use the userNotice option with IE5 | ||
422 | then you need the 'ia5org' option at the top level to modify the encoding: | ||
423 | otherwise it will not be interpreted properly. | ||
424 | |||
425 | Example: | ||
426 | |||
427 | certificatePolicies=ia5org,1.2.3.4,1.5.6.7.8,@polsect | ||
428 | |||
429 | [polsect] | ||
430 | |||
431 | policyIdentifier = 1.3.5.8 | ||
432 | CPS.1="http://my.host.name/" | ||
433 | CPS.2="http://my.your.name/" | ||
434 | userNotice.1=@notice | ||
435 | |||
436 | [notice] | ||
437 | |||
438 | explicitText="Explicit Text Here" | ||
439 | organization="Organisation Name" | ||
440 | noticeNumbers=1,2,3,4 | ||
441 | |||
442 | TECHNICAL NOTE: the ia5org option changes the type of the 'organization' field, | ||
443 | according to PKIX it should be of type DisplayText but Verisign uses an | ||
444 | IA5STRING and IE5 needs this too. | ||
445 | |||
446 | Display only extensions. | ||
447 | |||
448 | Some extensions are only partially supported and currently are only displayed | ||
449 | but cannot be set. These include private key usage period, CRL number, and | ||
450 | CRL reason. | ||
451 | |||
452 | ============================================================================== | ||
453 | X509V3 Extension code: programmers guide | ||
454 | ============================================================================== | ||
455 | |||
456 | The purpose of the extension code is twofold. It allows an extension to be | ||
457 | created from a string or structure describing its contents and it prints out an | ||
458 | extension in a human or machine readable form. | ||
459 | |||
460 | 1. Initialisation and cleanup. | ||
461 | |||
462 | X509V3_add_standard_extensions(); | ||
463 | |||
464 | This function should be called before any other extension code. It adds support | ||
465 | for some common PKIX and Netscape extensions. Additional custom extensions can | ||
466 | be added as well (see later). | ||
467 | |||
468 | void X509V3_EXT_cleanup(void); | ||
469 | |||
470 | This function should be called last to cleanup the extension code. After this | ||
471 | call no other extension calls should be made. | ||
472 | |||
473 | 2. Printing and parsing extensions. | ||
474 | |||
475 | The simplest way to print out extensions is via the standard X509 printing | ||
476 | routines: if you use the standard X509_print() function, the supported | ||
477 | extensions will be printed out automatically. | ||
478 | |||
479 | The following functions allow finer control over extension display: | ||
480 | |||
481 | int X509V3_EXT_print(BIO *out, X509_EXTENSION *ext, int flag, int indent); | ||
482 | int X509V3_EXT_print_fp(FILE *out, X509_EXTENSION *ext, int flag, int indent); | ||
483 | |||
484 | These two functions print out an individual extension to a BIO or FILE pointer. | ||
485 | Currently the flag argument is unused and should be set to 0. The 'indent' | ||
486 | argument is the number of spaces to indent each line. | ||
487 | |||
488 | void *X509V3_EXT_d2i(X509_EXTENSION *ext); | ||
489 | |||
490 | This function parses an extension and returns its internal structure. The | ||
491 | precise structure you get back depends on the extension being parsed. If the | ||
492 | extension if basicConstraints you will get back a pointer to a | ||
493 | BASIC_CONSTRAINTS structure. Check out the source in crypto/x509v3 for more | ||
494 | details about the structures returned. The returned structure should be freed | ||
495 | after use using the relevant free function, BASIC_CONSTRAINTS_free() for | ||
496 | example. | ||
497 | |||
498 | 3. Generating extensions. | ||
499 | |||
500 | An extension will typically be generated from a configuration file, or some | ||
501 | other kind of configuration database. | ||
502 | |||
503 | int X509V3_EXT_add_conf(LHASH *conf, X509V3_CTX *ctx, char *section, | ||
504 | X509 *cert); | ||
505 | int X509V3_EXT_CRL_add_conf(LHASH *conf, X509V3_CTX *ctx, char *section, | ||
506 | X509_CRL *crl); | ||
507 | |||
508 | These functions add all the extensions in the given section to the given | ||
509 | certificate or CRL. They will normally be called just before the certificate | ||
510 | or CRL is due to be signed. Both return 0 on error on non zero for success. | ||
511 | |||
512 | In each case 'conf' is the LHASH pointer of the configuration file to use | ||
513 | and 'section' is the section containing the extension details. | ||
514 | |||
515 | See the 'context functions' section for a description of the ctx paramater. | ||
516 | |||
517 | |||
518 | X509_EXTENSION *X509V3_EXT_conf(LHASH *conf, X509V3_CTX *ctx, char *name, | ||
519 | char *value); | ||
520 | |||
521 | This function returns an extension based on a name and value pair, if the | ||
522 | pair will not need to access other sections in a config file (or there is no | ||
523 | config file) then the 'conf' parameter can be set to NULL. | ||
524 | |||
525 | X509_EXTENSION *X509V3_EXT_conf_nid(char *conf, X509V3_CTX *ctx, int nid, | ||
526 | char *value); | ||
527 | |||
528 | This function creates an extension in the same way as X509V3_EXT_conf() but | ||
529 | takes the NID of the extension rather than its name. | ||
530 | |||
531 | For example to produce basicConstraints with the CA flag and a path length of | ||
532 | 10: | ||
533 | |||
534 | x = X509V3_EXT_conf_nid(NULL, NULL, NID_basicConstraints, "CA:TRUE,pathlen:10"); | ||
535 | |||
536 | |||
537 | X509_EXTENSION *X509V3_EXT_i2d(int ext_nid, int crit, void *ext_struc); | ||
538 | |||
539 | This function sets up an extension from its internal structure. The ext_nid | ||
540 | parameter is the NID of the extension and 'crit' is the critical flag. | ||
541 | |||
542 | 4. Context functions. | ||
543 | |||
544 | The following functions set and manipulate an extension context structure. | ||
545 | The purpose of the extension context is to allow the extension code to | ||
546 | access various structures relating to the "environment" of the certificate: | ||
547 | for example the issuers certificate or the certificate request. | ||
548 | |||
549 | void X509V3_set_ctx(X509V3_CTX *ctx, X509 *issuer, X509 *subject, | ||
550 | X509_REQ *req, X509_CRL *crl, int flags); | ||
551 | |||
552 | This function sets up an X509V3_CTX structure with details of the certificate | ||
553 | environment: specifically the issuers certificate, the subject certificate, | ||
554 | the certificate request and the CRL: if these are not relevant or not | ||
555 | available then they can be set to NULL. The 'flags' parameter should be set | ||
556 | to zero. | ||
557 | |||
558 | X509V3_set_ctx_test(ctx) | ||
559 | |||
560 | This macro is used to set the 'ctx' structure to a 'test' value: this is to | ||
561 | allow the syntax of an extension (or configuration file) to be tested. | ||
562 | |||
563 | X509V3_set_ctx_nodb(ctx) | ||
564 | |||
565 | This macro is used when no configuration database is present. | ||
566 | |||
567 | void X509V3_set_conf_lhash(X509V3_CTX *ctx, LHASH *lhash); | ||
568 | |||
569 | This function is used to set the configuration database when it is an LHASH | ||
570 | structure: typically a configuration file. | ||
571 | |||
572 | The following functions are used to access a configuration database: they | ||
573 | should only be used in RAW extensions. | ||
574 | |||
575 | char * X509V3_get_string(X509V3_CTX *ctx, char *name, char *section); | ||
576 | |||
577 | This function returns the value of the parameter "name" in "section", or NULL | ||
578 | if there has been an error. | ||
579 | |||
580 | void X509V3_string_free(X509V3_CTX *ctx, char *str); | ||
581 | |||
582 | This function frees up the string returned by the above function. | ||
583 | |||
584 | STACK_OF(CONF_VALUE) * X509V3_get_section(X509V3_CTX *ctx, char *section); | ||
585 | |||
586 | This function returns a whole section as a STACK_OF(CONF_VALUE) . | ||
587 | |||
588 | void X509V3_section_free( X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *section); | ||
589 | |||
590 | This function frees up the STACK returned by the above function. | ||
591 | |||
592 | Note: it is possible to use the extension code with a custom configuration | ||
593 | database. To do this the "db_meth" element of the X509V3_CTX structure should | ||
594 | be set to an X509V3_CTX_METHOD structure. This structure contains the following | ||
595 | function pointers: | ||
596 | |||
597 | char * (*get_string)(void *db, char *section, char *value); | ||
598 | STACK_OF(CONF_VALUE) * (*get_section)(void *db, char *section); | ||
599 | void (*free_string)(void *db, char * string); | ||
600 | void (*free_section)(void *db, STACK_OF(CONF_VALUE) *section); | ||
601 | |||
602 | these will be called and passed the 'db' element in the X509V3_CTX structure | ||
603 | to access the database. If a given function is not implemented or not required | ||
604 | it can be set to NULL. | ||
605 | |||
606 | 5. String helper functions. | ||
607 | |||
608 | There are several "i2s" and "s2i" functions that convert structures to and | ||
609 | from ASCII strings. In all the "i2s" cases the returned string should be | ||
610 | freed using Free() after use. Since some of these are part of other extension | ||
611 | code they may take a 'method' parameter. Unless otherwise stated it can be | ||
612 | safely set to NULL. | ||
613 | |||
614 | char *i2s_ASN1_OCTET_STRING(X509V3_EXT_METHOD *method, ASN1_OCTET_STRING *oct); | ||
615 | |||
616 | This returns a hex string from an ASN1_OCTET_STRING. | ||
617 | |||
618 | char * i2s_ASN1_INTEGER(X509V3_EXT_METHOD *meth, ASN1_INTEGER *aint); | ||
619 | char * i2s_ASN1_ENUMERATED(X509V3_EXT_METHOD *meth, ASN1_ENUMERATED *aint); | ||
620 | |||
621 | These return a string decimal representations of an ASN1_INTEGER and an | ||
622 | ASN1_ENUMERATED type, respectively. | ||
623 | |||
624 | ASN1_OCTET_STRING *s2i_ASN1_OCTET_STRING(X509V3_EXT_METHOD *method, | ||
625 | X509V3_CTX *ctx, char *str); | ||
626 | |||
627 | This converts an ASCII hex string to an ASN1_OCTET_STRING. | ||
628 | |||
629 | ASN1_INTEGER * s2i_ASN1_INTEGER(X509V3_EXT_METHOD *meth, char *value); | ||
630 | |||
631 | This converts a decimal ASCII string into an ASN1_INTEGER. | ||
632 | |||
633 | 6. Multi valued extension helper functions. | ||
634 | |||
635 | The following functions can be used to manipulate STACKs of CONF_VALUE | ||
636 | structures, as used by multi valued extensions. | ||
637 | |||
638 | int X509V3_get_value_bool(CONF_VALUE *value, int *asn1_bool); | ||
639 | |||
640 | This function expects a boolean value in 'value' and sets 'asn1_bool' to | ||
641 | it. That is it sets it to 0 for FALSE or 0xff for TRUE. The following | ||
642 | strings are acceptable: "TRUE", "true", "Y", "y", "YES", "yes", "FALSE" | ||
643 | "false", "N", "n", "NO" or "no". | ||
644 | |||
645 | int X509V3_get_value_int(CONF_VALUE *value, ASN1_INTEGER **aint); | ||
646 | |||
647 | This accepts a decimal integer of arbitrary length and sets an ASN1_INTEGER. | ||
648 | |||
649 | int X509V3_add_value(const char *name, const char *value, | ||
650 | STACK_OF(CONF_VALUE) **extlist); | ||
651 | |||
652 | This simply adds a string name and value pair. | ||
653 | |||
654 | int X509V3_add_value_uchar(const char *name, const unsigned char *value, | ||
655 | STACK_OF(CONF_VALUE) **extlist); | ||
656 | |||
657 | The same as above but for an unsigned character value. | ||
658 | |||
659 | int X509V3_add_value_bool(const char *name, int asn1_bool, | ||
660 | STACK_OF(CONF_VALUE) **extlist); | ||
661 | |||
662 | This adds either "TRUE" or "FALSE" depending on the value of 'ans1_bool' | ||
663 | |||
664 | int X509V3_add_value_bool_nf(char *name, int asn1_bool, | ||
665 | STACK_OF(CONF_VALUE) **extlist); | ||
666 | |||
667 | This is the same as above except it adds nothing if asn1_bool is FALSE. | ||
668 | |||
669 | int X509V3_add_value_int(const char *name, ASN1_INTEGER *aint, | ||
670 | STACK_OF(CONF_VALUE) **extlist); | ||
671 | |||
672 | This function adds the value of the ASN1_INTEGER in decimal form. | ||
673 | |||
674 | 7. Other helper functions. | ||
675 | |||
676 | <to be added> | ||
677 | |||
678 | ADDING CUSTOM EXTENSIONS. | ||
679 | |||
680 | Currently there are three types of supported extensions. | ||
681 | |||
682 | String extensions are simple strings where the value is placed directly in the | ||
683 | extensions, and the string returned is printed out. | ||
684 | |||
685 | Multi value extensions are passed a STACK_OF(CONF_VALUE) name and value pairs | ||
686 | or return a STACK_OF(CONF_VALUE). | ||
687 | |||
688 | Raw extensions are just passed a BIO or a value and it is the extensions | ||
689 | responsiblity to handle all the necessary printing. | ||
690 | |||
691 | There are two ways to add an extension. One is simply as an alias to an already | ||
692 | existing extension. An alias is an extension that is identical in ASN1 structure | ||
693 | to an existing extension but has a different OBJECT IDENTIFIER. This can be | ||
694 | done by calling: | ||
695 | |||
696 | int X509V3_EXT_add_alias(int nid_to, int nid_from); | ||
697 | |||
698 | 'nid_to' is the new extension NID and 'nid_from' is the already existing | ||
699 | extension NID. | ||
700 | |||
701 | Alternatively an extension can be written from scratch. This involves writing | ||
702 | the ASN1 code to encode and decode the extension and functions to print out and | ||
703 | generate the extension from strings. The relevant functions are then placed in | ||
704 | a X509V3_EXT_METHOD structure and int X509V3_EXT_add(X509V3_EXT_METHOD *ext); | ||
705 | called. | ||
706 | |||
707 | The X509V3_EXT_METHOD structure is described below. | ||
708 | |||
709 | strut { | ||
710 | int ext_nid; | ||
711 | int ext_flags; | ||
712 | X509V3_EXT_NEW ext_new; | ||
713 | X509V3_EXT_FREE ext_free; | ||
714 | X509V3_EXT_D2I d2i; | ||
715 | X509V3_EXT_I2D i2d; | ||
716 | X509V3_EXT_I2S i2s; | ||
717 | X509V3_EXT_S2I s2i; | ||
718 | X509V3_EXT_I2V i2v; | ||
719 | X509V3_EXT_V2I v2i; | ||
720 | X509V3_EXT_R2I r2i; | ||
721 | X509V3_EXT_I2R i2r; | ||
722 | |||
723 | void *usr_data; | ||
724 | }; | ||
725 | |||
726 | The elements have the following meanings. | ||
727 | |||
728 | ext_nid is the NID of the object identifier of the extension. | ||
729 | |||
730 | ext_flags is set of flags. Currently the only external flag is | ||
731 | X509V3_EXT_MULTILINE which means a multi valued extensions | ||
732 | should be printed on separate lines. | ||
733 | |||
734 | usr_data is an extension specific pointer to any relevant data. This | ||
735 | allows extensions to share identical code but have different | ||
736 | uses. An example of this is the bit string extension which uses | ||
737 | usr_data to contain a list of the bit names. | ||
738 | |||
739 | All the remaining elements are function pointers. | ||
740 | |||
741 | ext_new is a pointer to a function that allocates memory for the | ||
742 | extension ASN1 structure: for example ASN1_OBJECT_new(). | ||
743 | |||
744 | ext_free is a pointer to a function that free up memory of the extension | ||
745 | ASN1 structure: for example ASN1_OBJECT_free(). | ||
746 | |||
747 | d2i is the standard ASN1 function that converts a DER buffer into | ||
748 | the internal ASN1 structure: for example d2i_ASN1_IA5STRING(). | ||
749 | |||
750 | i2d is the standard ASN1 function that converts the internal | ||
751 | structure into the DER representation: for example | ||
752 | i2d_ASN1_IA5STRING(). | ||
753 | |||
754 | The remaining functions are depend on the type of extension. One i2X and | ||
755 | one X2i should be set and the rest set to NULL. The types set do not need | ||
756 | to match up, for example the extension could be set using the multi valued | ||
757 | v2i function and printed out using the raw i2r. | ||
758 | |||
759 | All functions have the X509V3_EXT_METHOD passed to them in the 'method' | ||
760 | parameter and an X509V3_CTX structure. Extension code can then access the | ||
761 | parent structure via the 'method' parameter to for example make use of the value | ||
762 | of usr_data. If the code needs to use detail relating to the request it can | ||
763 | use the 'ctx' parameter. | ||
764 | |||
765 | A note should be given here about the 'flags' member of the 'ctx' parameter. | ||
766 | If it has the value CTX_TEST then the configuration syntax is being checked | ||
767 | and no actual certificate or CRL exists. Therefore any attempt in the config | ||
768 | file to access such information should silently succeed. If the syntax is OK | ||
769 | then it should simply return a (possibly bogus) extension, otherwise it | ||
770 | should return NULL. | ||
771 | |||
772 | char *i2s(struct v3_ext_method *method, void *ext); | ||
773 | |||
774 | This function takes the internal structure in the ext parameter and returns | ||
775 | a Malloc'ed string representing its value. | ||
776 | |||
777 | void * s2i(struct v3_ext_method *method, struct v3_ext_ctx *ctx, char *str); | ||
778 | |||
779 | This function takes the string representation in the ext parameter and returns | ||
780 | an allocated internal structure: ext_free() will be used on this internal | ||
781 | structure after use. | ||
782 | |||
783 | i2v and v2i handle a STACK_OF(CONF_VALUE): | ||
784 | |||
785 | typedef struct | ||
786 | { | ||
787 | char *section; | ||
788 | char *name; | ||
789 | char *value; | ||
790 | } CONF_VALUE; | ||
791 | |||
792 | Only the name and value members are currently used. | ||
793 | |||
794 | STACK_OF(CONF_VALUE) * i2v(struct v3_ext_method *method, void *ext); | ||
795 | |||
796 | This function is passed the internal structure in the ext parameter and | ||
797 | returns a STACK of CONF_VALUE structures. The values of name, value, | ||
798 | section and the structure itself will be freed up with Free after use. | ||
799 | Several helper functions are available to add values to this STACK. | ||
800 | |||
801 | void * v2i(struct v3_ext_method *method, struct v3_ext_ctx *ctx, | ||
802 | STACK_OF(CONF_VALUE) *values); | ||
803 | |||
804 | This function takes a STACK_OF(CONF_VALUE) structures and should set the | ||
805 | values of the external structure. This typically uses the name element to | ||
806 | determine which structure element to set and the value element to determine | ||
807 | what to set it to. Several helper functions are available for this | ||
808 | purpose (see above). | ||
809 | |||
810 | int i2r(struct v3_ext_method *method, void *ext, BIO *out, int indent); | ||
811 | |||
812 | This function is passed the internal extension structure in the ext parameter | ||
813 | and sends out a human readable version of the extension to out. The 'indent' | ||
814 | paremeter should be noted to determine the necessary amount of indentation | ||
815 | needed on the output. | ||
816 | |||
817 | void * r2i(struct v3_ext_method *method, struct v3_ext_ctx *ctx, char *str); | ||
818 | |||
819 | This is just passed the string representation of the extension. It is intended | ||
820 | to be used for more elaborate extensions where the standard single and multi | ||
821 | valued options are insufficient. They can use the 'ctx' parameter to parse the | ||
822 | configuration database themselves. See the context functions section for details | ||
823 | of how to do this. | ||
824 | |||
825 | Note: although this type takes the same parameters as the "r2s" function there | ||
826 | is a subtle difference. Whereas an "r2i" function can access a configuration | ||
827 | database an "s2i" function MUST NOT. This is so the internal code can safely | ||
828 | assume that an "s2i" function will work without a configuration database. | ||
829 | |||
830 | ============================================================================== | ||
831 | PKCS#12 Library | ||
832 | ============================================================================== | ||
833 | |||
834 | This section describes the internal PKCS#12 support. There are very few | ||
835 | differences between the old external library and the new internal code at | ||
836 | present. This may well change because the external library will not be updated | ||
837 | much in future. | ||
838 | |||
839 | This version now includes a couple of high level PKCS#12 functions which | ||
840 | generally "do the right thing" and should make it much easier to handle PKCS#12 | ||
841 | structures. | ||
842 | |||
843 | HIGH LEVEL FUNCTIONS. | ||
844 | |||
845 | For most applications you only need concern yourself with the high level | ||
846 | functions. They can parse and generate simple PKCS#12 files as produced by | ||
847 | Netscape and MSIE or indeed any compliant PKCS#12 file containing a single | ||
848 | private key and certificate pair. | ||
849 | |||
850 | 1. Initialisation and cleanup. | ||
851 | |||
852 | No special initialisation is needed for the internal PKCS#12 library: the | ||
853 | standard SSLeay_add_all_algorithms() is sufficient. If you do not wish to | ||
854 | add all algorithms (you should at least add SHA1 though) then you can manually | ||
855 | initialise the PKCS#12 library with: | ||
856 | |||
857 | PKCS12_PBE_add(); | ||
858 | |||
859 | The memory allocated by the PKCS#12 library is freed up when EVP_cleanup() is | ||
860 | called or it can be directly freed with: | ||
861 | |||
862 | EVP_PBE_cleanup(); | ||
863 | |||
864 | after this call (or EVP_cleanup() ) no more PKCS#12 library functions should | ||
865 | be called. | ||
866 | |||
867 | 2. I/O functions. | ||
868 | |||
869 | i2d_PKCS12_bio(bp, p12) | ||
870 | |||
871 | This writes out a PKCS12 structure to a BIO. | ||
872 | |||
873 | i2d_PKCS12_fp(fp, p12) | ||
874 | |||
875 | This is the same but for a FILE pointer. | ||
876 | |||
877 | d2i_PKCS12_bio(bp, p12) | ||
878 | |||
879 | This reads in a PKCS12 structure from a BIO. | ||
880 | |||
881 | d2i_PKCS12_fp(fp, p12) | ||
882 | |||
883 | This is the same but for a FILE pointer. | ||
884 | |||
885 | 3. Parsing and creation functions. | ||
886 | |||
887 | 3.1 Parsing with PKCS12_parse(). | ||
888 | |||
889 | int PKCS12_parse(PKCS12 *p12, char *pass, EVP_PKEY **pkey, X509 **cert, | ||
890 | STACK **ca); | ||
891 | |||
892 | This function takes a PKCS12 structure and a password (ASCII, null terminated) | ||
893 | and returns the private key, the corresponding certificate and any CA | ||
894 | certificates. If any of these is not required it can be passed as a NULL. | ||
895 | The 'ca' parameter should be either NULL, a pointer to NULL or a valid STACK | ||
896 | structure. Typically to read in a PKCS#12 file you might do: | ||
897 | |||
898 | p12 = d2i_PKCS12_fp(fp, NULL); | ||
899 | PKCS12_parse(p12, password, &pkey, &cert, NULL); /* CAs not wanted */ | ||
900 | PKCS12_free(p12); | ||
901 | |||
902 | 3.2 PKCS#12 creation with PKCS12_create(). | ||
903 | |||
904 | PKCS12 *PKCS12_create(char *pass, char *name, EVP_PKEY *pkey, X509 *cert, | ||
905 | STACK *ca, int nid_key, int nid_cert, int iter, | ||
906 | int mac_iter, int keytype); | ||
907 | |||
908 | This function will create a PKCS12 structure from a given password, name, | ||
909 | private key, certificate and optional STACK of CA certificates. The remaining | ||
910 | 5 parameters can be set to 0 and sensible defaults will be used. | ||
911 | |||
912 | The parameters nid_key and nid_cert are the key and certificate encryption | ||
913 | algorithms, iter is the encryption iteration count, mac_iter is the MAC | ||
914 | iteration count and keytype is the type of private key. If you really want | ||
915 | to know what these last 5 parameters do then read the low level section. | ||
916 | |||
917 | Typically to create a PKCS#12 file the following could be used: | ||
918 | |||
919 | p12 = PKCS12_create(pass, "My Certificate", pkey, cert, NULL, 0,0,0,0,0); | ||
920 | i2d_PKCS12_fp(fp, p12); | ||
921 | PKCS12_free(p12); | ||
922 | |||
923 | LOW LEVEL FUNCTIONS. | ||
924 | |||
925 | In some cases the high level functions do not provide the necessary | ||
926 | functionality. For example if you want to generate or parse more complex | ||
927 | PKCS#12 files. The sample pkcs12 application uses the low level functions | ||
928 | to display details about the internal structure of a PKCS#12 file. | ||
929 | |||
930 | Introduction. | ||
931 | |||
932 | This is a brief description of how a PKCS#12 file is represented internally: | ||
933 | some knowledge of PKCS#12 is assumed. | ||
934 | |||
935 | A PKCS#12 object contains several levels. | ||
936 | |||
937 | At the lowest level is a PKCS12_SAFEBAG. This can contain a certificate, a | ||
938 | CRL, a private key, encrypted or unencrypted, a set of safebags (so the | ||
939 | structure can be nested) or other secrets (not documented at present). | ||
940 | A safebag can optionally have attributes, currently these are: a unicode | ||
941 | friendlyName (a Unicode string) or a localKeyID (a string of bytes). | ||
942 | |||
943 | At the next level is an authSafe which is a set of safebags collected into | ||
944 | a PKCS#7 ContentInfo. This can be just plain data, or encrypted itself. | ||
945 | |||
946 | At the top level is the PKCS12 structure itself which contains a set of | ||
947 | authSafes in an embedded PKCS#7 Contentinfo of type data. In addition it | ||
948 | contains a MAC which is a kind of password protected digest to preserve | ||
949 | integrity (so any unencrypted stuff below can't be tampered with). | ||
950 | |||
951 | The reason for these levels is so various objects can be encrypted in various | ||
952 | ways. For example you might want to encrypt a set of private keys with | ||
953 | triple-DES and then include the related certificates either unencrypted or | ||
954 | with lower encryption. Yes it's the dreaded crypto laws at work again which | ||
955 | allow strong encryption on private keys and only weak encryption on other | ||
956 | stuff. | ||
957 | |||
958 | To build one of these things you turn all certificates and keys into safebags | ||
959 | (with optional attributes). You collect the safebags into (one or more) STACKS | ||
960 | and convert these into authsafes (encrypted or unencrypted). The authsafes | ||
961 | are collected into a STACK and added to a PKCS12 structure. Finally a MAC | ||
962 | inserted. | ||
963 | |||
964 | Pulling one apart is basically the reverse process. The MAC is verified against | ||
965 | the given password. The authsafes are extracted and each authsafe split into | ||
966 | a set of safebags (possibly involving decryption). Finally the safebags are | ||
967 | decomposed into the original keys and certificates and the attributes used to | ||
968 | match up private key and certificate pairs. | ||
969 | |||
970 | Anyway here are the functions that do the dirty work. | ||
971 | |||
972 | 1. Construction functions. | ||
973 | |||
974 | 1.1 Safebag functions. | ||
975 | |||
976 | M_PKCS12_x5092certbag(x509) | ||
977 | |||
978 | This macro takes an X509 structure and returns a certificate bag. The | ||
979 | X509 structure can be freed up after calling this function. | ||
980 | |||
981 | M_PKCS12_x509crl2certbag(crl) | ||
982 | |||
983 | As above but for a CRL. | ||
984 | |||
985 | PKCS8_PRIV_KEY_INFO *PKEY2PKCS8(EVP_PKEY *pkey) | ||
986 | |||
987 | Take a private key and convert it into a PKCS#8 PrivateKeyInfo structure. | ||
988 | Works for both RSA and DSA private keys. NB since the PKCS#8 PrivateKeyInfo | ||
989 | structure contains a private key data in plain text form it should be free'd | ||
990 | up as soon as it has been encrypted for security reasons (freeing up the | ||
991 | structure zeros out the sensitive data). This can be done with | ||
992 | PKCS8_PRIV_KEY_INFO_free(). | ||
993 | |||
994 | PKCS8_add_keyusage(PKCS8_PRIV_KEY_INFO *p8, int usage) | ||
995 | |||
996 | This sets the key type when a key is imported into MSIE or Outlook 98. Two | ||
997 | values are currently supported: KEY_EX and KEY_SIG. KEY_EX is an exchange type | ||
998 | key that can also be used for signing but its size is limited in the export | ||
999 | versions of MS software to 512 bits, it is also the default. KEY_SIG is a | ||
1000 | signing only key but the keysize is unlimited (well 16K is supposed to work). | ||
1001 | If you are using the domestic version of MSIE then you can ignore this because | ||
1002 | KEY_EX is not limited and can be used for both. | ||
1003 | |||
1004 | PKCS12_SAFEBAG *PKCS12_MAKE_KEYBAG(PKCS8_PRIV_KEY_INFO *p8) | ||
1005 | |||
1006 | Convert a PKCS8 private key structure into a keybag. This routine embeds the | ||
1007 | p8 structure in the keybag so p8 should not be freed up or used after it is | ||
1008 | called. The p8 structure will be freed up when the safebag is freed. | ||
1009 | |||
1010 | PKCS12_SAFEBAG *PKCS12_MAKE_SHKEYBAG(int pbe_nid, unsigned char *pass, int passlen, unsigned char *salt, int saltlen, int iter, PKCS8_PRIV_KEY_INFO *p8) | ||
1011 | |||
1012 | Convert a PKCS#8 structure into a shrouded key bag (encrypted). p8 is not | ||
1013 | embedded and can be freed up after use. | ||
1014 | |||
1015 | int PKCS12_add_localkeyid(PKCS12_SAFEBAG *bag, unsigned char *name, int namelen) | ||
1016 | int PKCS12_add_friendlyname(PKCS12_SAFEBAG *bag, unsigned char *name, int namelen) | ||
1017 | |||
1018 | Add a local key id or a friendlyname to a safebag. | ||
1019 | |||
1020 | 1.2 Authsafe functions. | ||
1021 | |||
1022 | PKCS7 *PKCS12_pack_p7data(STACK *sk) | ||
1023 | Take a stack of safebags and convert them into an unencrypted authsafe. The | ||
1024 | stack of safebags can be freed up after calling this function. | ||
1025 | |||
1026 | PKCS7 *PKCS12_pack_p7encdata(int pbe_nid, unsigned char *pass, int passlen, unsigned char *salt, int saltlen, int iter, STACK *bags); | ||
1027 | |||
1028 | As above but encrypted. | ||
1029 | |||
1030 | 1.3 PKCS12 functions. | ||
1031 | |||
1032 | PKCS12 *PKCS12_init(int mode) | ||
1033 | |||
1034 | Initialise a PKCS12 structure (currently mode should be NID_pkcs7_data). | ||
1035 | |||
1036 | M_PKCS12_pack_authsafes(p12, safes) | ||
1037 | |||
1038 | This macro takes a STACK of authsafes and adds them to a PKCS#12 structure. | ||
1039 | |||
1040 | int PKCS12_set_mac(PKCS12 *p12, unsigned char *pass, int passlen, unsigned char *salt, int saltlen, int iter, EVP_MD *md_type); | ||
1041 | |||
1042 | Add a MAC to a PKCS12 structure. If EVP_MD is NULL use SHA-1, the spec suggests | ||
1043 | that SHA-1 should be used. | ||
1044 | |||
1045 | 2. Extraction Functions. | ||
1046 | |||
1047 | 2.1 Safebags. | ||
1048 | |||
1049 | M_PKCS12_bag_type(bag) | ||
1050 | |||
1051 | Return the type of "bag". Returns one of the following | ||
1052 | |||
1053 | NID_keyBag | ||
1054 | NID_pkcs8ShroudedKeyBag 7 | ||
1055 | NID_certBag 8 | ||
1056 | NID_crlBag 9 | ||
1057 | NID_secretBag 10 | ||
1058 | NID_safeContentsBag 11 | ||
1059 | |||
1060 | M_PKCS12_cert_bag_type(bag) | ||
1061 | |||
1062 | Returns type of certificate bag, following are understood. | ||
1063 | |||
1064 | NID_x509Certificate 14 | ||
1065 | NID_sdsiCertificate 15 | ||
1066 | |||
1067 | M_PKCS12_crl_bag_type(bag) | ||
1068 | |||
1069 | Returns crl bag type, currently only NID_crlBag is recognised. | ||
1070 | |||
1071 | M_PKCS12_certbag2x509(bag) | ||
1072 | |||
1073 | This macro extracts an X509 certificate from a certificate bag. | ||
1074 | |||
1075 | M_PKCS12_certbag2x509crl(bag) | ||
1076 | |||
1077 | As above but for a CRL. | ||
1078 | |||
1079 | EVP_PKEY * PKCS82PKEY(PKCS8_PRIV_KEY_INFO *p8) | ||
1080 | |||
1081 | Extract a private key from a PKCS8 private key info structure. | ||
1082 | |||
1083 | M_PKCS12_decrypt_skey(bag, pass, passlen) | ||
1084 | |||
1085 | Decrypt a shrouded key bag and return a PKCS8 private key info structure. | ||
1086 | Works with both RSA and DSA keys | ||
1087 | |||
1088 | char *PKCS12_get_friendlyname(bag) | ||
1089 | |||
1090 | Returns the friendlyName of a bag if present or NULL if none. The returned | ||
1091 | string is a null terminated ASCII string allocated with Malloc(). It should | ||
1092 | thus be freed up with Free() after use. | ||
1093 | |||
1094 | 2.2 AuthSafe functions. | ||
1095 | |||
1096 | M_PKCS12_unpack_p7data(p7) | ||
1097 | |||
1098 | Extract a STACK of safe bags from a PKCS#7 data ContentInfo. | ||
1099 | |||
1100 | #define M_PKCS12_unpack_p7encdata(p7, pass, passlen) | ||
1101 | |||
1102 | As above but for an encrypted content info. | ||
1103 | |||
1104 | 2.3 PKCS12 functions. | ||
1105 | |||
1106 | M_PKCS12_unpack_authsafes(p12) | ||
1107 | |||
1108 | Extract a STACK of authsafes from a PKCS12 structure. | ||
1109 | |||
1110 | M_PKCS12_mac_present(p12) | ||
1111 | |||
1112 | Check to see if a MAC is present. | ||
1113 | |||
1114 | int PKCS12_verify_mac(PKCS12 *p12, unsigned char *pass, int passlen) | ||
1115 | |||
1116 | Verify a MAC on a PKCS12 structure. Returns an error if MAC not present. | ||
1117 | |||
1118 | |||
1119 | Notes. | ||
1120 | |||
1121 | 1. All the function return 0 or NULL on error. | ||
1122 | 2. Encryption based functions take a common set of parameters. These are | ||
1123 | described below. | ||
1124 | |||
1125 | pass, passlen | ||
1126 | ASCII password and length. The password on the MAC is called the "integrity | ||
1127 | password" the encryption password is called the "privacy password" in the | ||
1128 | PKCS#12 documentation. The passwords do not have to be the same. If -1 is | ||
1129 | passed for the length it is worked out by the function itself (currently | ||
1130 | this is sometimes done whatever is passed as the length but that may change). | ||
1131 | |||
1132 | salt, saltlen | ||
1133 | A 'salt' if salt is NULL a random salt is used. If saltlen is also zero a | ||
1134 | default length is used. | ||
1135 | |||
1136 | iter | ||
1137 | Iteration count. This is a measure of how many times an internal function is | ||
1138 | called to encrypt the data. The larger this value is the longer it takes, it | ||
1139 | makes dictionary attacks on passwords harder. NOTE: Some implementations do | ||
1140 | not support an iteration count on the MAC. If the password for the MAC and | ||
1141 | encryption is the same then there is no point in having a high iteration | ||
1142 | count for encryption if the MAC has no count. The MAC could be attacked | ||
1143 | and the password used for the main decryption. | ||
1144 | |||
1145 | pbe_nid | ||
1146 | This is the NID of the password based encryption method used. The following are | ||
1147 | supported. | ||
1148 | NID_pbe_WithSHA1And128BitRC4 | ||
1149 | NID_pbe_WithSHA1And40BitRC4 | ||
1150 | NID_pbe_WithSHA1And3_Key_TripleDES_CBC | ||
1151 | NID_pbe_WithSHA1And2_Key_TripleDES_CBC | ||
1152 | NID_pbe_WithSHA1And128BitRC2_CBC | ||
1153 | NID_pbe_WithSHA1And40BitRC2_CBC | ||
1154 | |||
1155 | Which you use depends on the implementation you are exporting to. "Export | ||
1156 | grade" (i.e. cryptographically challenged) products cannot support all | ||
1157 | algorithms. Typically you may be able to use any encryption on shrouded key | ||
1158 | bags but they must then be placed in an unencrypted authsafe. Other authsafes | ||
1159 | may only support 40bit encryption. Of course if you are using SSLeay | ||
1160 | throughout you can strongly encrypt everything and have high iteration counts | ||
1161 | on everything. | ||
1162 | |||
1163 | 3. For decryption routines only the password and length are needed. | ||
1164 | |||
1165 | 4. Unlike the external version the nid's of objects are the values of the | ||
1166 | constants: that is NID_certBag is the real nid, therefore there is no | ||
1167 | PKCS12_obj_offset() function. Note the object constants are not the same as | ||
1168 | those of the external version. If you use these constants then you will need | ||
1169 | to recompile your code. | ||
1170 | |||
1171 | 5. With the exception of PKCS12_MAKE_KEYBAG(), after calling any function or | ||
1172 | macro of the form PKCS12_MAKE_SOMETHING(other) the "other" structure can be | ||
1173 | reused or freed up safely. | ||
1174 | |||
diff --git a/src/lib/libssl/doc/standards.txt b/src/lib/libssl/doc/standards.txt new file mode 100644 index 0000000000..61ccc5d7e0 --- /dev/null +++ b/src/lib/libssl/doc/standards.txt | |||
@@ -0,0 +1,121 @@ | |||
1 | Standards related to OpenSSL | ||
2 | ============================ | ||
3 | |||
4 | [Please, this is currently a draft. I made a first try at finding | ||
5 | documents that describe parts of what OpenSSL implements. There are | ||
6 | big gaps, and I've most certainly done something wrong. Please | ||
7 | correct whatever is... Also, this note should be removed when this | ||
8 | file is reaching a somewhat correct state. -- Richard Levitte] | ||
9 | |||
10 | |||
11 | All pointers in here will be either URL's or blobs of text borrowed | ||
12 | from miscellaneous indexes, like rfc-index.txt (index of RFCs), | ||
13 | 1id-index.txt (index of Internet drafts) and the like. | ||
14 | |||
15 | To find the latest possible RFCs, it's recommended to either browse | ||
16 | ftp://ftp.isi.edu/in-notes/ or go to http://www.rfc-editor.org/ and | ||
17 | use the search mechanism found there. | ||
18 | To find the latest possible Internet drafts, it's recommended to | ||
19 | browse ftp://ftp.isi.edu/internet-drafts/. | ||
20 | To find the latest possible PKCS, it's recommended to browse | ||
21 | http://www.rsasecurity.com/rsalabs/pkcs/. | ||
22 | |||
23 | |||
24 | Implemented: | ||
25 | ------------ | ||
26 | |||
27 | These are documents that describe things that are implemented in OpenSSL. | ||
28 | |||
29 | 1319 The MD2 Message-Digest Algorithm. B. Kaliski. April 1992. | ||
30 | (Format: TXT=25661 bytes) (Status: INFORMATIONAL) | ||
31 | |||
32 | 1320 The MD4 Message-Digest Algorithm. R. Rivest. April 1992. (Format: | ||
33 | TXT=32407 bytes) (Status: INFORMATIONAL) | ||
34 | |||
35 | 1321 The MD5 Message-Digest Algorithm. R. Rivest. April 1992. (Format: | ||
36 | TXT=35222 bytes) (Status: INFORMATIONAL) | ||
37 | |||
38 | 2246 The TLS Protocol Version 1.0. T. Dierks, C. Allen. January 1999. | ||
39 | (Format: TXT=170401 bytes) (Status: PROPOSED STANDARD) | ||
40 | |||
41 | 2268 A Description of the RC2(r) Encryption Algorithm. R. Rivest. | ||
42 | January 1998. (Format: TXT=19048 bytes) (Status: INFORMATIONAL) | ||
43 | |||
44 | 2314 PKCS 10: Certification Request Syntax Version 1.5. B. Kaliski. | ||
45 | March 1998. (Format: TXT=15814 bytes) (Status: INFORMATIONAL) | ||
46 | |||
47 | 2315 PKCS 7: Cryptographic Message Syntax Version 1.5. B. Kaliski. | ||
48 | March 1998. (Format: TXT=69679 bytes) (Status: INFORMATIONAL) | ||
49 | |||
50 | 2437 PKCS #1: RSA Cryptography Specifications Version 2.0. B. Kaliski, | ||
51 | J. Staddon. October 1998. (Format: TXT=73529 bytes) (Obsoletes | ||
52 | RFC2313) (Status: INFORMATIONAL) | ||
53 | |||
54 | 2459 Internet X.509 Public Key Infrastructure Certificate and CRL | ||
55 | Profile. R. Housley, W. Ford, W. Polk, D. Solo. January 1999. | ||
56 | (Format: TXT=278438 bytes) (Status: PROPOSED STANDARD) | ||
57 | |||
58 | PKCS#8: Private-Key Information Syntax Standard | ||
59 | |||
60 | PKCS#12: Personal Information Exchange Syntax Standard, version 1.0. | ||
61 | |||
62 | |||
63 | Related: | ||
64 | -------- | ||
65 | |||
66 | These are documents that are close to OpenSSL, for example the | ||
67 | STARTTLS documents. | ||
68 | |||
69 | 1421 Privacy Enhancement for Internet Electronic Mail: Part I: Message | ||
70 | Encryption and Authentication Procedures. J. Linn. February 1993. | ||
71 | (Format: TXT=103894 bytes) (Obsoletes RFC1113) (Status: PROPOSED | ||
72 | STANDARD) | ||
73 | |||
74 | 1422 Privacy Enhancement for Internet Electronic Mail: Part II: | ||
75 | Certificate-Based Key Management. S. Kent. February 1993. (Format: | ||
76 | TXT=86085 bytes) (Obsoletes RFC1114) (Status: PROPOSED STANDARD) | ||
77 | |||
78 | 1423 Privacy Enhancement for Internet Electronic Mail: Part III: | ||
79 | Algorithms, Modes, and Identifiers. D. Balenson. February 1993. | ||
80 | (Format: TXT=33277 bytes) (Obsoletes RFC1115) (Status: PROPOSED | ||
81 | STANDARD) | ||
82 | |||
83 | 1424 Privacy Enhancement for Internet Electronic Mail: Part IV: Key | ||
84 | Certification and Related Services. B. Kaliski. February 1993. | ||
85 | (Format: TXT=17537 bytes) (Status: PROPOSED STANDARD) | ||
86 | |||
87 | 2487 SMTP Service Extension for Secure SMTP over TLS. P. Hoffman. | ||
88 | January 1999. (Format: TXT=15120 bytes) (Status: PROPOSED STANDARD) | ||
89 | |||
90 | 2585 Internet X.509 Public Key Infrastructure Operational Protocols: | ||
91 | FTP and HTTP. R. Housley, P. Hoffman. May 1999. (Format: TXT=14813 | ||
92 | bytes) (Status: PROPOSED STANDARD) | ||
93 | |||
94 | 2595 Using TLS with IMAP, POP3 and ACAP. C. Newman. June 1999. | ||
95 | (Format: TXT=32440 bytes) (Status: PROPOSED STANDARD) | ||
96 | |||
97 | 2712 Addition of Kerberos Cipher Suites to Transport Layer Security | ||
98 | (TLS). A. Medvinsky, M. Hur. October 1999. (Format: TXT=13763 bytes) | ||
99 | (Status: PROPOSED STANDARD) | ||
100 | |||
101 | 2817 Upgrading to TLS Within HTTP/1.1. R. Khare, S. Lawrence. May | ||
102 | 2000. (Format: TXT=27598 bytes) (Updates RFC2616) (Status: PROPOSED | ||
103 | STANDARD) | ||
104 | |||
105 | 2818 HTTP Over TLS. E. Rescorla. May 2000. (Format: TXT=15170 bytes) | ||
106 | (Status: INFORMATIONAL) | ||
107 | |||
108 | "Securing FTP with TLS", 01/27/2000, <draft-murray-auth-ftp-ssl-05.txt> | ||
109 | |||
110 | |||
111 | To be implemented: | ||
112 | ------------------ | ||
113 | |||
114 | These are documents that describe things that are planed to be | ||
115 | implemented in the hopefully short future. | ||
116 | |||
117 | 2560 X.509 Internet Public Key Infrastructure Online Certificate | ||
118 | Status Protocol - OCSP. M. Myers, R. Ankney, A. Malpani, S. Galperin, | ||
119 | C. Adams. June 1999. (Format: TXT=43243 bytes) (Status: PROPOSED | ||
120 | STANDARD) | ||
121 | |||
diff --git a/src/lib/libssl/test/VMSca-response.1 b/src/lib/libssl/test/VMSca-response.1 new file mode 100644 index 0000000000..8b13789179 --- /dev/null +++ b/src/lib/libssl/test/VMSca-response.1 | |||
@@ -0,0 +1 @@ | |||
diff --git a/src/lib/libssl/test/VMSca-response.2 b/src/lib/libssl/test/VMSca-response.2 new file mode 100644 index 0000000000..9b48ee4cf9 --- /dev/null +++ b/src/lib/libssl/test/VMSca-response.2 | |||
@@ -0,0 +1,2 @@ | |||
1 | y | ||
2 | y | ||
diff --git a/src/lib/libssl/test/bctest b/src/lib/libssl/test/bctest new file mode 100644 index 0000000000..bdb3218f7a --- /dev/null +++ b/src/lib/libssl/test/bctest | |||
@@ -0,0 +1,111 @@ | |||
1 | #!/bin/sh | ||
2 | |||
3 | # This script is used by test/Makefile.ssl to check whether a sane 'bc' | ||
4 | # is installed. | ||
5 | # ('make test_bn' should not try to run 'bc' if it does not exist or if | ||
6 | # it is a broken 'bc' version that is known to cause trouble.) | ||
7 | # | ||
8 | # If 'bc' works, we also test if it knows the 'print' command. | ||
9 | # | ||
10 | # In any case, output an appropriate command line for running (or not | ||
11 | # running) bc. | ||
12 | |||
13 | |||
14 | IFS=: | ||
15 | try_without_dir=true | ||
16 | # First we try "bc", then "$dir/bc" for each item in $PATH. | ||
17 | for dir in dummy:$PATH; do | ||
18 | if [ "$try_without_dir" = true ]; then | ||
19 | # first iteration | ||
20 | bc=bc | ||
21 | try_without_dir=false | ||
22 | else | ||
23 | # second and later iterations | ||
24 | bc="$dir/bc" | ||
25 | if [ ! -f "$bc" ]; then # '-x' is not available on Ultrix | ||
26 | bc='' | ||
27 | fi | ||
28 | fi | ||
29 | |||
30 | if [ ! "$bc" = '' ]; then | ||
31 | failure=none | ||
32 | |||
33 | |||
34 | # Test for SunOS 5.[78] bc bug | ||
35 | "$bc" >tmp.bctest <<\EOF | ||
36 | obase=16 | ||
37 | ibase=16 | ||
38 | a=AD88C418F31B3FC712D0425001D522B3AE9134FF3A98C13C1FCC1682211195406C1A6C66C6A\ | ||
39 | CEEC1A0EC16950233F77F1C2F2363D56DD71A36C57E0B2511FC4BA8F22D261FE2E9356D99AF57\ | ||
40 | 10F3817C0E05BF79C423C3F66FDF321BE8D3F18F625D91B670931C1EF25F28E489BDA1C5422D1\ | ||
41 | C3F6F7A1AD21585746ECC4F10A14A778AF56F08898E965E9909E965E0CB6F85B514150C644759\ | ||
42 | 3BE731877B16EA07B552088FF2EA728AC5E0FF3A23EB939304519AB8B60F2C33D6BA0945B66F0\ | ||
43 | 4FC3CADF855448B24A9D7640BCF473E | ||
44 | b=DCE91E7D120B983EA9A104B5A96D634DD644C37657B1C7860B45E6838999B3DCE5A555583C6\ | ||
45 | 9209E41F413422954175A06E67FFEF6746DD652F0F48AEFECC3D8CAC13523BDAAD3F5AF4212BD\ | ||
46 | 8B3CD64126E1A82E190228020C05B91C8B141F1110086FC2A4C6ED631EBA129D04BB9A19FC53D\ | ||
47 | 3ED0E2017D60A68775B75481449 | ||
48 | (a/b)*b + (a%b) - a | ||
49 | EOF | ||
50 | if [ 0 != "`cat tmp.bctest`" ]; then | ||
51 | failure=SunOStest | ||
52 | fi | ||
53 | |||
54 | |||
55 | if [ "$failure" = none ]; then | ||
56 | # Test for SCO bc bug. | ||
57 | "$bc" >tmp.bctest <<\EOF | ||
58 | obase=16 | ||
59 | ibase=16 | ||
60 | -FFDD63BA1A4648F0D804F8A1C66C53F0D2110590E8A3907EC73B4AEC6F15AC177F176F2274D2\ | ||
61 | 9DC8022EA0D7DD3ABE9746D2D46DD3EA5B5F6F69DF12877E0AC5E7F5ADFACEE54573F5D256A06\ | ||
62 | 11B5D2BC24947724E22AE4EC3FB0C39D9B4694A01AFE5E43B4D99FB9812A0E4A5773D8B254117\ | ||
63 | 1239157EC6E3D8D50199 * -FFDD63BA1A4648F0D804F8A1C66C53F0D2110590E8A3907EC73B4\ | ||
64 | AEC6F15AC177F176F2274D29DC8022EA0D7DD3ABE9746D2D46DD3EA5B5F6F69DF12877E0AC5E7\ | ||
65 | F5ADFACEE54573F5D256A0611B5D2BC24947724E22AE4EC3FB0C39D9B4694A01AFE5E43B4D99F\ | ||
66 | B9812A0E4A5773D8B2541171239157EC6E3D8D50199 - FFBACC221682DA464B6D7F123482522\ | ||
67 | 02EDAEDCA38C3B69E9B7BBCD6165A9CD8716C4903417F23C09A85B851961F92C217258CEEB866\ | ||
68 | 85EFCC5DD131853A02C07A873B8E2AF2E40C6D5ED598CD0E8F35AD49F3C3A17FDB7653E4E2DC4\ | ||
69 | A8D23CC34686EE4AD01F7407A7CD74429AC6D36DBF0CB6A3E302D0E5BDFCD048A3B90C1BE5AA8\ | ||
70 | E16C3D5884F9136B43FF7BB443764153D4AEC176C681B078F4CC53D6EB6AB76285537DDEE7C18\ | ||
71 | 8C72441B52EDBDDBC77E02D34E513F2AABF92F44109CAFE8242BD0ECBAC5604A94B02EA44D43C\ | ||
72 | 04E9476E6FBC48043916BFA1485C6093603600273C9C33F13114D78064AE42F3DC466C7DA543D\ | ||
73 | 89C8D71 | ||
74 | AD534AFBED2FA39EE9F40E20FCF9E2C861024DB98DDCBA1CD118C49CA55EEBC20D6BA51B2271C\ | ||
75 | 928B693D6A73F67FEB1B4571448588B46194617D25D910C6A9A130CC963155CF34079CB218A44\ | ||
76 | 8A1F57E276D92A33386DDCA3D241DB78C8974ABD71DD05B0FA555709C9910D745185E6FE108E3\ | ||
77 | 37F1907D0C56F8BFBF52B9704 % -E557905B56B13441574CAFCE2BD257A750B1A8B2C88D0E36\ | ||
78 | E18EF7C38DAC80D3948E17ED63AFF3B3467866E3B89D09A81B3D16B52F6A3C7134D3C6F5123E9\ | ||
79 | F617E3145BBFBE9AFD0D6E437EA4FF6F04BC67C4F1458B4F0F47B64 - 1C2BBBB19B74E86FD32\ | ||
80 | 9E8DB6A8C3B1B9986D57ED5419C2E855F7D5469E35E76334BB42F4C43E3F3A31B9697C171DAC4\ | ||
81 | D97935A7E1A14AD209D6CF811F55C6DB83AA9E6DFECFCD6669DED7171EE22A40C6181615CAF3F\ | ||
82 | 5296964 | ||
83 | EOF | ||
84 | if [ "0 | ||
85 | 0" != "`cat tmp.bctest`" ]; then | ||
86 | failure=SCOtest | ||
87 | fi | ||
88 | fi | ||
89 | |||
90 | |||
91 | if [ "$failure" = none ]; then | ||
92 | # bc works; now check if it knows the 'print' command. | ||
93 | if [ "OK" = "`echo 'print \"OK\"' | $bc 2>/dev/null`" ] | ||
94 | then | ||
95 | echo "$bc" | ||
96 | else | ||
97 | echo "sed 's/print.*//' | $bc" | ||
98 | fi | ||
99 | exit 0 | ||
100 | fi | ||
101 | |||
102 | echo "$bc does not work properly ('$failure' failed). Looking for another bc ..." >&2 | ||
103 | fi | ||
104 | done | ||
105 | |||
106 | echo "No working bc found. Consider installing GNU bc." >&2 | ||
107 | if [ "$1" = ignore ]; then | ||
108 | echo "cat >/dev/null" | ||
109 | exit 0 | ||
110 | fi | ||
111 | exit 1 | ||