summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/evp
diff options
context:
space:
mode:
authordjm <>2010-10-01 22:54:21 +0000
committerdjm <>2010-10-01 22:54:21 +0000
commit2ea67f4aa254b09ded62e6e14fc893bbe6381579 (patch)
treebb3923b81f2ce34b1ad62684afdf1a94d904c185 /src/lib/libcrypto/evp
parent6ddfb710ab14b10183ff3a6a32f643554c80065e (diff)
parent829fd51d4f8dde4a7f3bf54754f3c1d1a502f5e2 (diff)
downloadopenbsd-2ea67f4aa254b09ded62e6e14fc893bbe6381579.tar.gz
openbsd-2ea67f4aa254b09ded62e6e14fc893bbe6381579.tar.bz2
openbsd-2ea67f4aa254b09ded62e6e14fc893bbe6381579.zip
This commit was generated by cvs2git to track changes on a CVS vendor
branch.
Diffstat (limited to 'src/lib/libcrypto/evp')
-rw-r--r--src/lib/libcrypto/evp/e_camellia.c2
-rw-r--r--src/lib/libcrypto/evp/m_ecdsa.c2
-rw-r--r--src/lib/libcrypto/evp/m_sigver.c200
-rw-r--r--src/lib/libcrypto/evp/m_wp.c42
-rw-r--r--src/lib/libcrypto/evp/pmeth_fn.c368
-rw-r--r--src/lib/libcrypto/evp/pmeth_gn.c220
-rw-r--r--src/lib/libcrypto/evp/pmeth_lib.c538
7 files changed, 1370 insertions, 2 deletions
diff --git a/src/lib/libcrypto/evp/e_camellia.c b/src/lib/libcrypto/evp/e_camellia.c
index 365d397164..a7b40d1c60 100644
--- a/src/lib/libcrypto/evp/e_camellia.c
+++ b/src/lib/libcrypto/evp/e_camellia.c
@@ -93,7 +93,7 @@ IMPLEMENT_BLOCK_CIPHER(camellia_256, ks, Camellia, EVP_CAMELLIA_KEY,
93 EVP_CIPHER_get_asn1_iv, 93 EVP_CIPHER_get_asn1_iv,
94 NULL) 94 NULL)
95 95
96#define IMPLEMENT_CAMELLIA_CFBR(ksize,cbits) IMPLEMENT_CFBR(camellia,Camellia,EVP_CAMELLIA_KEY,ks,ksize,cbits,16,0) 96#define IMPLEMENT_CAMELLIA_CFBR(ksize,cbits) IMPLEMENT_CFBR(camellia,Camellia,EVP_CAMELLIA_KEY,ks,ksize,cbits,16)
97 97
98IMPLEMENT_CAMELLIA_CFBR(128,1) 98IMPLEMENT_CAMELLIA_CFBR(128,1)
99IMPLEMENT_CAMELLIA_CFBR(192,1) 99IMPLEMENT_CAMELLIA_CFBR(192,1)
diff --git a/src/lib/libcrypto/evp/m_ecdsa.c b/src/lib/libcrypto/evp/m_ecdsa.c
index fad270faca..8d87a49ebe 100644
--- a/src/lib/libcrypto/evp/m_ecdsa.c
+++ b/src/lib/libcrypto/evp/m_ecdsa.c
@@ -130,7 +130,7 @@ static const EVP_MD ecdsa_md=
130 NID_ecdsa_with_SHA1, 130 NID_ecdsa_with_SHA1,
131 NID_ecdsa_with_SHA1, 131 NID_ecdsa_with_SHA1,
132 SHA_DIGEST_LENGTH, 132 SHA_DIGEST_LENGTH,
133 0, 133 EVP_MD_FLAG_PKEY_DIGEST,
134 init, 134 init,
135 update, 135 update,
136 final, 136 final,
diff --git a/src/lib/libcrypto/evp/m_sigver.c b/src/lib/libcrypto/evp/m_sigver.c
new file mode 100644
index 0000000000..f0b7f95059
--- /dev/null
+++ b/src/lib/libcrypto/evp/m_sigver.c
@@ -0,0 +1,200 @@
1/* m_sigver.c */
2/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
3 * project 2006.
4 */
5/* ====================================================================
6 * Copyright (c) 2006,2007 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/objects.h>
63#include <openssl/x509.h>
64#include "evp_locl.h"
65
66static int do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
67 const EVP_MD *type, ENGINE *e, EVP_PKEY *pkey,
68 int ver)
69 {
70 if (ctx->pctx == NULL)
71 ctx->pctx = EVP_PKEY_CTX_new(pkey, e);
72 if (ctx->pctx == NULL)
73 return 0;
74
75 if (type == NULL)
76 {
77 int def_nid;
78 if (EVP_PKEY_get_default_digest_nid(pkey, &def_nid) > 0)
79 type = EVP_get_digestbynid(def_nid);
80 }
81
82 if (type == NULL)
83 {
84 EVPerr(EVP_F_DO_SIGVER_INIT, EVP_R_NO_DEFAULT_DIGEST);
85 return 0;
86 }
87
88 if (ver)
89 {
90 if (ctx->pctx->pmeth->verifyctx_init)
91 {
92 if (ctx->pctx->pmeth->verifyctx_init(ctx->pctx, ctx) <=0)
93 return 0;
94 ctx->pctx->operation = EVP_PKEY_OP_VERIFYCTX;
95 }
96 else if (EVP_PKEY_verify_init(ctx->pctx) <= 0)
97 return 0;
98 }
99 else
100 {
101 if (ctx->pctx->pmeth->signctx_init)
102 {
103 if (ctx->pctx->pmeth->signctx_init(ctx->pctx, ctx) <= 0)
104 return 0;
105 ctx->pctx->operation = EVP_PKEY_OP_SIGNCTX;
106 }
107 else if (EVP_PKEY_sign_init(ctx->pctx) <= 0)
108 return 0;
109 }
110 if (EVP_PKEY_CTX_set_signature_md(ctx->pctx, type) <= 0)
111 return 0;
112 if (pctx)
113 *pctx = ctx->pctx;
114 if (!EVP_DigestInit_ex(ctx, type, e))
115 return 0;
116 return 1;
117 }
118
119int EVP_DigestSignInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
120 const EVP_MD *type, ENGINE *e, EVP_PKEY *pkey)
121 {
122 return do_sigver_init(ctx, pctx, type, e, pkey, 0);
123 }
124
125int EVP_DigestVerifyInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
126 const EVP_MD *type, ENGINE *e, EVP_PKEY *pkey)
127 {
128 return do_sigver_init(ctx, pctx, type, e, pkey, 1);
129 }
130
131int EVP_DigestSignFinal(EVP_MD_CTX *ctx, unsigned char *sigret, size_t *siglen)
132 {
133 int sctx, r = 0;
134 if (ctx->pctx->pmeth->signctx)
135 sctx = 1;
136 else
137 sctx = 0;
138 if (sigret)
139 {
140 MS_STATIC EVP_MD_CTX tmp_ctx;
141 unsigned char md[EVP_MAX_MD_SIZE];
142 unsigned int mdlen;
143 EVP_MD_CTX_init(&tmp_ctx);
144 if (!EVP_MD_CTX_copy_ex(&tmp_ctx,ctx))
145 return 0;
146 if (sctx)
147 r = tmp_ctx.pctx->pmeth->signctx(tmp_ctx.pctx,
148 sigret, siglen, &tmp_ctx);
149 else
150 r = EVP_DigestFinal_ex(&tmp_ctx,md,&mdlen);
151 EVP_MD_CTX_cleanup(&tmp_ctx);
152 if (sctx || !r)
153 return r;
154 if (EVP_PKEY_sign(ctx->pctx, sigret, siglen, md, mdlen) <= 0)
155 return 0;
156 }
157 else
158 {
159 if (sctx)
160 {
161 if (ctx->pctx->pmeth->signctx(ctx->pctx, sigret, siglen, ctx) <= 0)
162 return 0;
163 }
164 else
165 {
166 int s = EVP_MD_size(ctx->digest);
167 if (s < 0 || EVP_PKEY_sign(ctx->pctx, sigret, siglen, NULL, s) <= 0)
168 return 0;
169 }
170 }
171 return 1;
172 }
173
174int EVP_DigestVerifyFinal(EVP_MD_CTX *ctx, unsigned char *sig, size_t siglen)
175 {
176 MS_STATIC EVP_MD_CTX tmp_ctx;
177 unsigned char md[EVP_MAX_MD_SIZE];
178 int r;
179 unsigned int mdlen;
180 int vctx;
181
182 if (ctx->pctx->pmeth->verifyctx)
183 vctx = 1;
184 else
185 vctx = 0;
186 EVP_MD_CTX_init(&tmp_ctx);
187 if (!EVP_MD_CTX_copy_ex(&tmp_ctx,ctx))
188 return -1;
189 if (vctx)
190 {
191 r = tmp_ctx.pctx->pmeth->verifyctx(tmp_ctx.pctx,
192 sig, siglen, &tmp_ctx);
193 }
194 else
195 r = EVP_DigestFinal_ex(&tmp_ctx,md,&mdlen);
196 EVP_MD_CTX_cleanup(&tmp_ctx);
197 if (vctx || !r)
198 return r;
199 return EVP_PKEY_verify(ctx->pctx, sig, siglen, md, mdlen);
200 }
diff --git a/src/lib/libcrypto/evp/m_wp.c b/src/lib/libcrypto/evp/m_wp.c
new file mode 100644
index 0000000000..1ce47c040b
--- /dev/null
+++ b/src/lib/libcrypto/evp/m_wp.c
@@ -0,0 +1,42 @@
1/* crypto/evp/m_wp.c */
2
3#include <stdio.h>
4#include "cryptlib.h"
5
6#ifndef OPENSSL_NO_WHIRLPOOL
7
8#include <openssl/evp.h>
9#include <openssl/objects.h>
10#include <openssl/x509.h>
11#include <openssl/whrlpool.h>
12
13static int init(EVP_MD_CTX *ctx)
14 { return WHIRLPOOL_Init(ctx->md_data); }
15
16static int update(EVP_MD_CTX *ctx,const void *data,size_t count)
17 { return WHIRLPOOL_Update(ctx->md_data,data,count); }
18
19static int final(EVP_MD_CTX *ctx,unsigned char *md)
20 { return WHIRLPOOL_Final(md,ctx->md_data); }
21
22static const EVP_MD whirlpool_md=
23 {
24 NID_whirlpool,
25 0,
26 WHIRLPOOL_DIGEST_LENGTH,
27 0,
28 init,
29 update,
30 final,
31 NULL,
32 NULL,
33 EVP_PKEY_NULL_method,
34 WHIRLPOOL_BBLOCK/8,
35 sizeof(EVP_MD *)+sizeof(WHIRLPOOL_CTX),
36 };
37
38const EVP_MD *EVP_whirlpool(void)
39 {
40 return(&whirlpool_md);
41 }
42#endif
diff --git a/src/lib/libcrypto/evp/pmeth_fn.c b/src/lib/libcrypto/evp/pmeth_fn.c
new file mode 100644
index 0000000000..c4676f2f8d
--- /dev/null
+++ b/src/lib/libcrypto/evp/pmeth_fn.c
@@ -0,0 +1,368 @@
1/* pmeth_fn.c */
2/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
3 * project 2006.
4 */
5/* ====================================================================
6 * Copyright (c) 2006 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/objects.h>
63#include <openssl/evp.h>
64#include "evp_locl.h"
65
66#define M_check_autoarg(ctx, arg, arglen, err) \
67 if (ctx->pmeth->flags & EVP_PKEY_FLAG_AUTOARGLEN) \
68 { \
69 size_t pksize = (size_t)EVP_PKEY_size(ctx->pkey); \
70 if (!arg) \
71 { \
72 *arglen = pksize; \
73 return 1; \
74 } \
75 else if (*arglen < pksize) \
76 { \
77 EVPerr(err, EVP_R_BUFFER_TOO_SMALL); /*ckerr_ignore*/\
78 return 0; \
79 } \
80 }
81
82int EVP_PKEY_sign_init(EVP_PKEY_CTX *ctx)
83 {
84 int ret;
85 if (!ctx || !ctx->pmeth || !ctx->pmeth->sign)
86 {
87 EVPerr(EVP_F_EVP_PKEY_SIGN_INIT,
88 EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
89 return -2;
90 }
91 ctx->operation = EVP_PKEY_OP_SIGN;
92 if (!ctx->pmeth->sign_init)
93 return 1;
94 ret = ctx->pmeth->sign_init(ctx);
95 if (ret <= 0)
96 ctx->operation = EVP_PKEY_OP_UNDEFINED;
97 return ret;
98 }
99
100int EVP_PKEY_sign(EVP_PKEY_CTX *ctx,
101 unsigned char *sig, size_t *siglen,
102 const unsigned char *tbs, size_t tbslen)
103 {
104 if (!ctx || !ctx->pmeth || !ctx->pmeth->sign)
105 {
106 EVPerr(EVP_F_EVP_PKEY_SIGN,
107 EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
108 return -2;
109 }
110 if (ctx->operation != EVP_PKEY_OP_SIGN)
111 {
112 EVPerr(EVP_F_EVP_PKEY_SIGN, EVP_R_OPERATON_NOT_INITIALIZED);
113 return -1;
114 }
115 M_check_autoarg(ctx, sig, siglen, EVP_F_EVP_PKEY_SIGN)
116 return ctx->pmeth->sign(ctx, sig, siglen, tbs, tbslen);
117 }
118
119int EVP_PKEY_verify_init(EVP_PKEY_CTX *ctx)
120 {
121 int ret;
122 if (!ctx || !ctx->pmeth || !ctx->pmeth->verify)
123 {
124 EVPerr(EVP_F_EVP_PKEY_VERIFY_INIT,
125 EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
126 return -2;
127 }
128 ctx->operation = EVP_PKEY_OP_VERIFY;
129 if (!ctx->pmeth->verify_init)
130 return 1;
131 ret = ctx->pmeth->verify_init(ctx);
132 if (ret <= 0)
133 ctx->operation = EVP_PKEY_OP_UNDEFINED;
134 return ret;
135 }
136
137int EVP_PKEY_verify(EVP_PKEY_CTX *ctx,
138 const unsigned char *sig, size_t siglen,
139 const unsigned char *tbs, size_t tbslen)
140 {
141 if (!ctx || !ctx->pmeth || !ctx->pmeth->verify)
142 {
143 EVPerr(EVP_F_EVP_PKEY_VERIFY,
144 EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
145 return -2;
146 }
147 if (ctx->operation != EVP_PKEY_OP_VERIFY)
148 {
149 EVPerr(EVP_F_EVP_PKEY_VERIFY, EVP_R_OPERATON_NOT_INITIALIZED);
150 return -1;
151 }
152 return ctx->pmeth->verify(ctx, sig, siglen, tbs, tbslen);
153 }
154
155int EVP_PKEY_verify_recover_init(EVP_PKEY_CTX *ctx)
156 {
157 int ret;
158 if (!ctx || !ctx->pmeth || !ctx->pmeth->verify_recover)
159 {
160 EVPerr(EVP_F_EVP_PKEY_VERIFY_RECOVER_INIT,
161 EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
162 return -2;
163 }
164 ctx->operation = EVP_PKEY_OP_VERIFYRECOVER;
165 if (!ctx->pmeth->verify_recover_init)
166 return 1;
167 ret = ctx->pmeth->verify_recover_init(ctx);
168 if (ret <= 0)
169 ctx->operation = EVP_PKEY_OP_UNDEFINED;
170 return ret;
171 }
172
173int EVP_PKEY_verify_recover(EVP_PKEY_CTX *ctx,
174 unsigned char *rout, size_t *routlen,
175 const unsigned char *sig, size_t siglen)
176 {
177 if (!ctx || !ctx->pmeth || !ctx->pmeth->verify_recover)
178 {
179 EVPerr(EVP_F_EVP_PKEY_VERIFY_RECOVER,
180 EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
181 return -2;
182 }
183 if (ctx->operation != EVP_PKEY_OP_VERIFYRECOVER)
184 {
185 EVPerr(EVP_F_EVP_PKEY_VERIFY_RECOVER, EVP_R_OPERATON_NOT_INITIALIZED);
186 return -1;
187 }
188 M_check_autoarg(ctx, rout, routlen, EVP_F_EVP_PKEY_VERIFY_RECOVER)
189 return ctx->pmeth->verify_recover(ctx, rout, routlen, sig, siglen);
190 }
191
192int EVP_PKEY_encrypt_init(EVP_PKEY_CTX *ctx)
193 {
194 int ret;
195 if (!ctx || !ctx->pmeth || !ctx->pmeth->encrypt)
196 {
197 EVPerr(EVP_F_EVP_PKEY_ENCRYPT_INIT,
198 EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
199 return -2;
200 }
201 ctx->operation = EVP_PKEY_OP_ENCRYPT;
202 if (!ctx->pmeth->encrypt_init)
203 return 1;
204 ret = ctx->pmeth->encrypt_init(ctx);
205 if (ret <= 0)
206 ctx->operation = EVP_PKEY_OP_UNDEFINED;
207 return ret;
208 }
209
210int EVP_PKEY_encrypt(EVP_PKEY_CTX *ctx,
211 unsigned char *out, size_t *outlen,
212 const unsigned char *in, size_t inlen)
213 {
214 if (!ctx || !ctx->pmeth || !ctx->pmeth->encrypt)
215 {
216 EVPerr(EVP_F_EVP_PKEY_ENCRYPT,
217 EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
218 return -2;
219 }
220 if (ctx->operation != EVP_PKEY_OP_ENCRYPT)
221 {
222 EVPerr(EVP_F_EVP_PKEY_ENCRYPT, EVP_R_OPERATON_NOT_INITIALIZED);
223 return -1;
224 }
225 M_check_autoarg(ctx, out, outlen, EVP_F_EVP_PKEY_ENCRYPT)
226 return ctx->pmeth->encrypt(ctx, out, outlen, in, inlen);
227 }
228
229int EVP_PKEY_decrypt_init(EVP_PKEY_CTX *ctx)
230 {
231 int ret;
232 if (!ctx || !ctx->pmeth || !ctx->pmeth->decrypt)
233 {
234 EVPerr(EVP_F_EVP_PKEY_DECRYPT_INIT,
235 EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
236 return -2;
237 }
238 ctx->operation = EVP_PKEY_OP_DECRYPT;
239 if (!ctx->pmeth->decrypt_init)
240 return 1;
241 ret = ctx->pmeth->decrypt_init(ctx);
242 if (ret <= 0)
243 ctx->operation = EVP_PKEY_OP_UNDEFINED;
244 return ret;
245 }
246
247int EVP_PKEY_decrypt(EVP_PKEY_CTX *ctx,
248 unsigned char *out, size_t *outlen,
249 const unsigned char *in, size_t inlen)
250 {
251 if (!ctx || !ctx->pmeth || !ctx->pmeth->decrypt)
252 {
253 EVPerr(EVP_F_EVP_PKEY_DECRYPT,
254 EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
255 return -2;
256 }
257 if (ctx->operation != EVP_PKEY_OP_DECRYPT)
258 {
259 EVPerr(EVP_F_EVP_PKEY_DECRYPT, EVP_R_OPERATON_NOT_INITIALIZED);
260 return -1;
261 }
262 M_check_autoarg(ctx, out, outlen, EVP_F_EVP_PKEY_DECRYPT)
263 return ctx->pmeth->decrypt(ctx, out, outlen, in, inlen);
264 }
265
266
267int EVP_PKEY_derive_init(EVP_PKEY_CTX *ctx)
268 {
269 int ret;
270 if (!ctx || !ctx->pmeth || !ctx->pmeth->derive)
271 {
272 EVPerr(EVP_F_EVP_PKEY_DERIVE_INIT,
273 EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
274 return -2;
275 }
276 ctx->operation = EVP_PKEY_OP_DERIVE;
277 if (!ctx->pmeth->derive_init)
278 return 1;
279 ret = ctx->pmeth->derive_init(ctx);
280 if (ret <= 0)
281 ctx->operation = EVP_PKEY_OP_UNDEFINED;
282 return ret;
283 }
284
285int EVP_PKEY_derive_set_peer(EVP_PKEY_CTX *ctx, EVP_PKEY *peer)
286 {
287 int ret;
288 if (!ctx || !ctx->pmeth || !(ctx->pmeth->derive||ctx->pmeth->encrypt||ctx->pmeth->decrypt) || !ctx->pmeth->ctrl)
289 {
290 EVPerr(EVP_F_EVP_PKEY_DERIVE_SET_PEER,
291 EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
292 return -2;
293 }
294 if (ctx->operation != EVP_PKEY_OP_DERIVE && ctx->operation != EVP_PKEY_OP_ENCRYPT && ctx->operation != EVP_PKEY_OP_DECRYPT)
295 {
296 EVPerr(EVP_F_EVP_PKEY_DERIVE_SET_PEER,
297 EVP_R_OPERATON_NOT_INITIALIZED);
298 return -1;
299 }
300
301 ret = ctx->pmeth->ctrl(ctx, EVP_PKEY_CTRL_PEER_KEY, 0, peer);
302
303 if (ret <= 0)
304 return ret;
305
306 if (ret == 2)
307 return 1;
308
309 if (!ctx->pkey)
310 {
311 EVPerr(EVP_F_EVP_PKEY_DERIVE_SET_PEER, EVP_R_NO_KEY_SET);
312 return -1;
313 }
314
315 if (ctx->pkey->type != peer->type)
316 {
317 EVPerr(EVP_F_EVP_PKEY_DERIVE_SET_PEER,
318 EVP_R_DIFFERENT_KEY_TYPES);
319 return -1;
320 }
321
322 /* ran@cryptocom.ru: For clarity. The error is if parameters in peer are
323 * present (!missing) but don't match. EVP_PKEY_cmp_parameters may return
324 * 1 (match), 0 (don't match) and -2 (comparison is not defined). -1
325 * (different key types) is impossible here because it is checked earlier.
326 * -2 is OK for us here, as well as 1, so we can check for 0 only. */
327 if (!EVP_PKEY_missing_parameters(peer) &&
328 !EVP_PKEY_cmp_parameters(ctx->pkey, peer))
329 {
330 EVPerr(EVP_F_EVP_PKEY_DERIVE_SET_PEER,
331 EVP_R_DIFFERENT_PARAMETERS);
332 return -1;
333 }
334
335 if (ctx->peerkey)
336 EVP_PKEY_free(ctx->peerkey);
337 ctx->peerkey = peer;
338
339 ret = ctx->pmeth->ctrl(ctx, EVP_PKEY_CTRL_PEER_KEY, 1, peer);
340
341 if (ret <= 0)
342 {
343 ctx->peerkey = NULL;
344 return ret;
345 }
346
347 CRYPTO_add(&peer->references,1,CRYPTO_LOCK_EVP_PKEY);
348 return 1;
349 }
350
351
352int EVP_PKEY_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *pkeylen)
353 {
354 if (!ctx || !ctx->pmeth || !ctx->pmeth->derive)
355 {
356 EVPerr(EVP_F_EVP_PKEY_DERIVE,
357 EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
358 return -2;
359 }
360 if (ctx->operation != EVP_PKEY_OP_DERIVE)
361 {
362 EVPerr(EVP_F_EVP_PKEY_DERIVE, EVP_R_OPERATON_NOT_INITIALIZED);
363 return -1;
364 }
365 M_check_autoarg(ctx, key, pkeylen, EVP_F_EVP_PKEY_DERIVE)
366 return ctx->pmeth->derive(ctx, key, pkeylen);
367 }
368
diff --git a/src/lib/libcrypto/evp/pmeth_gn.c b/src/lib/libcrypto/evp/pmeth_gn.c
new file mode 100644
index 0000000000..5d74161a09
--- /dev/null
+++ b/src/lib/libcrypto/evp/pmeth_gn.c
@@ -0,0 +1,220 @@
1/* pmeth_gn.c */
2/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
3 * project 2006.
4 */
5/* ====================================================================
6 * Copyright (c) 2006 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/objects.h>
63#include <openssl/evp.h>
64#include <openssl/bn.h>
65#include "evp_locl.h"
66
67int EVP_PKEY_paramgen_init(EVP_PKEY_CTX *ctx)
68 {
69 int ret;
70 if (!ctx || !ctx->pmeth || !ctx->pmeth->paramgen)
71 {
72 EVPerr(EVP_F_EVP_PKEY_PARAMGEN_INIT,
73 EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
74 return -2;
75 }
76 ctx->operation = EVP_PKEY_OP_PARAMGEN;
77 if (!ctx->pmeth->paramgen_init)
78 return 1;
79 ret = ctx->pmeth->paramgen_init(ctx);
80 if (ret <= 0)
81 ctx->operation = EVP_PKEY_OP_UNDEFINED;
82 return ret;
83 }
84
85int EVP_PKEY_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey)
86 {
87 int ret;
88 if (!ctx || !ctx->pmeth || !ctx->pmeth->paramgen)
89 {
90 EVPerr(EVP_F_EVP_PKEY_PARAMGEN,
91 EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
92 return -2;
93 }
94
95 if (ctx->operation != EVP_PKEY_OP_PARAMGEN)
96 {
97 EVPerr(EVP_F_EVP_PKEY_PARAMGEN, EVP_R_OPERATON_NOT_INITIALIZED);
98 return -1;
99 }
100
101 if (!ppkey)
102 return -1;
103
104 if (!*ppkey)
105 *ppkey = EVP_PKEY_new();
106
107 ret = ctx->pmeth->paramgen(ctx, *ppkey);
108 if (ret <= 0)
109 {
110 EVP_PKEY_free(*ppkey);
111 *ppkey = NULL;
112 }
113 return ret;
114 }
115
116int EVP_PKEY_keygen_init(EVP_PKEY_CTX *ctx)
117 {
118 int ret;
119 if (!ctx || !ctx->pmeth || !ctx->pmeth->keygen)
120 {
121 EVPerr(EVP_F_EVP_PKEY_KEYGEN_INIT,
122 EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
123 return -2;
124 }
125 ctx->operation = EVP_PKEY_OP_KEYGEN;
126 if (!ctx->pmeth->keygen_init)
127 return 1;
128 ret = ctx->pmeth->keygen_init(ctx);
129 if (ret <= 0)
130 ctx->operation = EVP_PKEY_OP_UNDEFINED;
131 return ret;
132 }
133
134int EVP_PKEY_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey)
135 {
136 int ret;
137
138 if (!ctx || !ctx->pmeth || !ctx->pmeth->keygen)
139 {
140 EVPerr(EVP_F_EVP_PKEY_KEYGEN,
141 EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
142 return -2;
143 }
144 if (ctx->operation != EVP_PKEY_OP_KEYGEN)
145 {
146 EVPerr(EVP_F_EVP_PKEY_KEYGEN, EVP_R_OPERATON_NOT_INITIALIZED);
147 return -1;
148 }
149
150 if (!ppkey)
151 return -1;
152
153 if (!*ppkey)
154 *ppkey = EVP_PKEY_new();
155
156 ret = ctx->pmeth->keygen(ctx, *ppkey);
157 if (ret <= 0)
158 {
159 EVP_PKEY_free(*ppkey);
160 *ppkey = NULL;
161 }
162 return ret;
163 }
164
165void EVP_PKEY_CTX_set_cb(EVP_PKEY_CTX *ctx, EVP_PKEY_gen_cb *cb)
166 {
167 ctx->pkey_gencb = cb;
168 }
169
170EVP_PKEY_gen_cb *EVP_PKEY_CTX_get_cb(EVP_PKEY_CTX *ctx)
171 {
172 return ctx->pkey_gencb;
173 }
174
175/* "translation callback" to call EVP_PKEY_CTX callbacks using BN_GENCB
176 * style callbacks.
177 */
178
179static int trans_cb(int a, int b, BN_GENCB *gcb)
180 {
181 EVP_PKEY_CTX *ctx = gcb->arg;
182 ctx->keygen_info[0] = a;
183 ctx->keygen_info[1] = b;
184 return ctx->pkey_gencb(ctx);
185 }
186
187void evp_pkey_set_cb_translate(BN_GENCB *cb, EVP_PKEY_CTX *ctx)
188 {
189 BN_GENCB_set(cb, trans_cb, ctx)
190 }
191
192int EVP_PKEY_CTX_get_keygen_info(EVP_PKEY_CTX *ctx, int idx)
193 {
194 if (idx == -1)
195 return ctx->keygen_info_count;
196 if (idx < 0 || idx > ctx->keygen_info_count)
197 return 0;
198 return ctx->keygen_info[idx];
199 }
200
201EVP_PKEY *EVP_PKEY_new_mac_key(int type, ENGINE *e,
202 unsigned char *key, int keylen)
203 {
204 EVP_PKEY_CTX *mac_ctx = NULL;
205 EVP_PKEY *mac_key = NULL;
206 mac_ctx = EVP_PKEY_CTX_new_id(type, e);
207 if (!mac_ctx)
208 return NULL;
209 if (EVP_PKEY_keygen_init(mac_ctx) <= 0)
210 goto merr;
211 if (EVP_PKEY_CTX_ctrl(mac_ctx, -1, EVP_PKEY_OP_KEYGEN,
212 EVP_PKEY_CTRL_SET_MAC_KEY, keylen, key) <= 0)
213 goto merr;
214 if (EVP_PKEY_keygen(mac_ctx, &mac_key) <= 0)
215 goto merr;
216 merr:
217 if (mac_ctx)
218 EVP_PKEY_CTX_free(mac_ctx);
219 return mac_key;
220 }
diff --git a/src/lib/libcrypto/evp/pmeth_lib.c b/src/lib/libcrypto/evp/pmeth_lib.c
new file mode 100644
index 0000000000..b2d8de3a8d
--- /dev/null
+++ b/src/lib/libcrypto/evp/pmeth_lib.c
@@ -0,0 +1,538 @@
1/* pmeth_lib.c */
2/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
3 * project 2006.
4 */
5/* ====================================================================
6 * Copyright (c) 2006 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/objects.h>
63#include <openssl/evp.h>
64#ifndef OPENSSL_NO_ENGINE
65#include <openssl/engine.h>
66#endif
67#include "asn1_locl.h"
68#include "evp_locl.h"
69
70typedef int sk_cmp_fn_type(const char * const *a, const char * const *b);
71
72DECLARE_STACK_OF(EVP_PKEY_METHOD)
73STACK_OF(EVP_PKEY_METHOD) *app_pkey_methods = NULL;
74
75extern const EVP_PKEY_METHOD rsa_pkey_meth, dh_pkey_meth, dsa_pkey_meth;
76extern const EVP_PKEY_METHOD ec_pkey_meth, hmac_pkey_meth;
77
78static const EVP_PKEY_METHOD *standard_methods[] =
79 {
80#ifndef OPENSSL_NO_RSA
81 &rsa_pkey_meth,
82#endif
83#ifndef OPENSSL_NO_DH
84 &dh_pkey_meth,
85#endif
86#ifndef OPENSSL_NO_DSA
87 &dsa_pkey_meth,
88#endif
89#ifndef OPENSSL_NO_EC
90 &ec_pkey_meth,
91#endif
92 &hmac_pkey_meth,
93 };
94
95DECLARE_OBJ_BSEARCH_CMP_FN(const EVP_PKEY_METHOD *, const EVP_PKEY_METHOD *,
96 pmeth);
97
98static int pmeth_cmp(const EVP_PKEY_METHOD * const *a,
99 const EVP_PKEY_METHOD * const *b)
100 {
101 return ((*a)->pkey_id - (*b)->pkey_id);
102 }
103
104IMPLEMENT_OBJ_BSEARCH_CMP_FN(const EVP_PKEY_METHOD *, const EVP_PKEY_METHOD *,
105 pmeth);
106
107const EVP_PKEY_METHOD *EVP_PKEY_meth_find(int type)
108 {
109 EVP_PKEY_METHOD tmp;
110 const EVP_PKEY_METHOD *t = &tmp, **ret;
111 tmp.pkey_id = type;
112 if (app_pkey_methods)
113 {
114 int idx;
115 idx = sk_EVP_PKEY_METHOD_find(app_pkey_methods, &tmp);
116 if (idx >= 0)
117 return sk_EVP_PKEY_METHOD_value(app_pkey_methods, idx);
118 }
119 ret = OBJ_bsearch_pmeth(&t, standard_methods,
120 sizeof(standard_methods)/sizeof(EVP_PKEY_METHOD *));
121 if (!ret || !*ret)
122 return NULL;
123 return *ret;
124 }
125
126static EVP_PKEY_CTX *int_ctx_new(EVP_PKEY *pkey, ENGINE *e, int id)
127 {
128 EVP_PKEY_CTX *ret;
129 const EVP_PKEY_METHOD *pmeth;
130 if (id == -1)
131 {
132 if (!pkey || !pkey->ameth)
133 return NULL;
134 id = pkey->ameth->pkey_id;
135 }
136#ifndef OPENSSL_NO_ENGINE
137 /* Try to find an ENGINE which implements this method */
138 if (e)
139 {
140 if (!ENGINE_init(e))
141 {
142 EVPerr(EVP_F_INT_CTX_NEW,ERR_R_ENGINE_LIB);
143 return NULL;
144 }
145 }
146 else
147 e = ENGINE_get_pkey_meth_engine(id);
148
149 /* If an ENGINE handled this method look it up. Othewise
150 * use internal tables.
151 */
152
153 if (e)
154 pmeth = ENGINE_get_pkey_meth(e, id);
155 else
156#endif
157 pmeth = EVP_PKEY_meth_find(id);
158
159 if (pmeth == NULL)
160 {
161 EVPerr(EVP_F_INT_CTX_NEW,EVP_R_UNSUPPORTED_ALGORITHM);
162 return NULL;
163 }
164
165 ret = OPENSSL_malloc(sizeof(EVP_PKEY_CTX));
166 if (!ret)
167 {
168#ifndef OPENSSL_NO_ENGINE
169 if (e)
170 ENGINE_finish(e);
171#endif
172 EVPerr(EVP_F_INT_CTX_NEW,ERR_R_MALLOC_FAILURE);
173 return NULL;
174 }
175 ret->engine = e;
176 ret->pmeth = pmeth;
177 ret->operation = EVP_PKEY_OP_UNDEFINED;
178 ret->pkey = pkey;
179 ret->peerkey = NULL;
180 ret->pkey_gencb = 0;
181 if (pkey)
182 CRYPTO_add(&pkey->references,1,CRYPTO_LOCK_EVP_PKEY);
183 ret->data = NULL;
184
185 if (pmeth->init)
186 {
187 if (pmeth->init(ret) <= 0)
188 {
189 EVP_PKEY_CTX_free(ret);
190 return NULL;
191 }
192 }
193
194 return ret;
195 }
196
197EVP_PKEY_METHOD* EVP_PKEY_meth_new(int id, int flags)
198 {
199 EVP_PKEY_METHOD *pmeth;
200 pmeth = OPENSSL_malloc(sizeof(EVP_PKEY_METHOD));
201 if (!pmeth)
202 return NULL;
203
204 pmeth->pkey_id = id;
205 pmeth->flags = flags | EVP_PKEY_FLAG_DYNAMIC;
206
207 pmeth->init = 0;
208 pmeth->copy = 0;
209 pmeth->cleanup = 0;
210 pmeth->paramgen_init = 0;
211 pmeth->paramgen = 0;
212 pmeth->keygen_init = 0;
213 pmeth->keygen = 0;
214 pmeth->sign_init = 0;
215 pmeth->sign = 0;
216 pmeth->verify_init = 0;
217 pmeth->verify = 0;
218 pmeth->verify_recover_init = 0;
219 pmeth->verify_recover = 0;
220 pmeth->signctx_init = 0;
221 pmeth->signctx = 0;
222 pmeth->verifyctx_init = 0;
223 pmeth->verifyctx = 0;
224 pmeth->encrypt_init = 0;
225 pmeth->encrypt = 0;
226 pmeth->decrypt_init = 0;
227 pmeth->decrypt = 0;
228 pmeth->derive_init = 0;
229 pmeth->derive = 0;
230 pmeth->ctrl = 0;
231 pmeth->ctrl_str = 0;
232
233 return pmeth;
234 }
235
236void EVP_PKEY_meth_free(EVP_PKEY_METHOD *pmeth)
237 {
238 if (pmeth && (pmeth->flags & EVP_PKEY_FLAG_DYNAMIC))
239 OPENSSL_free(pmeth);
240 }
241
242EVP_PKEY_CTX *EVP_PKEY_CTX_new(EVP_PKEY *pkey, ENGINE *e)
243 {
244 return int_ctx_new(pkey, e, -1);
245 }
246
247EVP_PKEY_CTX *EVP_PKEY_CTX_new_id(int id, ENGINE *e)
248 {
249 return int_ctx_new(NULL, e, id);
250 }
251
252EVP_PKEY_CTX *EVP_PKEY_CTX_dup(EVP_PKEY_CTX *pctx)
253 {
254 EVP_PKEY_CTX *rctx;
255 if (!pctx->pmeth || !pctx->pmeth->copy)
256 return NULL;
257#ifndef OPENSSL_NO_ENGINE
258 /* Make sure it's safe to copy a pkey context using an ENGINE */
259 if (pctx->engine && !ENGINE_init(pctx->engine))
260 {
261 EVPerr(EVP_F_EVP_PKEY_CTX_DUP,ERR_R_ENGINE_LIB);
262 return 0;
263 }
264#endif
265 rctx = OPENSSL_malloc(sizeof(EVP_PKEY_CTX));
266 if (!rctx)
267 return NULL;
268
269 rctx->pmeth = pctx->pmeth;
270#ifndef OPENSSL_NO_ENGINE
271 rctx->engine = pctx->engine;
272#endif
273
274 if (pctx->pkey)
275 CRYPTO_add(&pctx->pkey->references,1,CRYPTO_LOCK_EVP_PKEY);
276
277 rctx->pkey = pctx->pkey;
278
279 if (pctx->peerkey)
280 CRYPTO_add(&pctx->peerkey->references,1,CRYPTO_LOCK_EVP_PKEY);
281
282 rctx->peerkey = pctx->peerkey;
283
284 rctx->data = NULL;
285 rctx->app_data = NULL;
286 rctx->operation = pctx->operation;
287
288 if (pctx->pmeth->copy(rctx, pctx) > 0)
289 return rctx;
290
291 EVP_PKEY_CTX_free(rctx);
292 return NULL;
293
294 }
295
296int EVP_PKEY_meth_add0(const EVP_PKEY_METHOD *pmeth)
297 {
298 if (app_pkey_methods == NULL)
299 {
300 app_pkey_methods = sk_EVP_PKEY_METHOD_new(pmeth_cmp);
301 if (!app_pkey_methods)
302 return 0;
303 }
304 if (!sk_EVP_PKEY_METHOD_push(app_pkey_methods, pmeth))
305 return 0;
306 sk_EVP_PKEY_METHOD_sort(app_pkey_methods);
307 return 1;
308 }
309
310void EVP_PKEY_CTX_free(EVP_PKEY_CTX *ctx)
311 {
312 if (ctx == NULL)
313 return;
314 if (ctx->pmeth && ctx->pmeth->cleanup)
315 ctx->pmeth->cleanup(ctx);
316 if (ctx->pkey)
317 EVP_PKEY_free(ctx->pkey);
318 if (ctx->peerkey)
319 EVP_PKEY_free(ctx->peerkey);
320#ifndef OPENSSL_NO_ENGINE
321 if(ctx->engine)
322 /* The EVP_PKEY_CTX we used belongs to an ENGINE, release the
323 * functional reference we held for this reason. */
324 ENGINE_finish(ctx->engine);
325#endif
326 OPENSSL_free(ctx);
327 }
328
329int EVP_PKEY_CTX_ctrl(EVP_PKEY_CTX *ctx, int keytype, int optype,
330 int cmd, int p1, void *p2)
331 {
332 int ret;
333 if (!ctx || !ctx->pmeth || !ctx->pmeth->ctrl)
334 {
335 EVPerr(EVP_F_EVP_PKEY_CTX_CTRL, EVP_R_COMMAND_NOT_SUPPORTED);
336 return -2;
337 }
338 if ((keytype != -1) && (ctx->pmeth->pkey_id != keytype))
339 return -1;
340
341 if (ctx->operation == EVP_PKEY_OP_UNDEFINED)
342 {
343 EVPerr(EVP_F_EVP_PKEY_CTX_CTRL, EVP_R_NO_OPERATION_SET);
344 return -1;
345 }
346
347 if ((optype != -1) && !(ctx->operation & optype))
348 {
349 EVPerr(EVP_F_EVP_PKEY_CTX_CTRL, EVP_R_INVALID_OPERATION);
350 return -1;
351 }
352
353 ret = ctx->pmeth->ctrl(ctx, cmd, p1, p2);
354
355 if (ret == -2)
356 EVPerr(EVP_F_EVP_PKEY_CTX_CTRL, EVP_R_COMMAND_NOT_SUPPORTED);
357
358 return ret;
359
360 }
361
362int EVP_PKEY_CTX_ctrl_str(EVP_PKEY_CTX *ctx,
363 const char *name, const char *value)
364 {
365 if (!ctx || !ctx->pmeth || !ctx->pmeth->ctrl_str)
366 {
367 EVPerr(EVP_F_EVP_PKEY_CTX_CTRL_STR,
368 EVP_R_COMMAND_NOT_SUPPORTED);
369 return -2;
370 }
371 if (!strcmp(name, "digest"))
372 {
373 const EVP_MD *md;
374 if (!value || !(md = EVP_get_digestbyname(value)))
375 {
376 EVPerr(EVP_F_EVP_PKEY_CTX_CTRL_STR,
377 EVP_R_INVALID_DIGEST);
378 return 0;
379 }
380 return EVP_PKEY_CTX_set_signature_md(ctx, md);
381 }
382 return ctx->pmeth->ctrl_str(ctx, name, value);
383 }
384
385int EVP_PKEY_CTX_get_operation(EVP_PKEY_CTX *ctx)
386 {
387 return ctx->operation;
388 }
389
390void EVP_PKEY_CTX_set0_keygen_info(EVP_PKEY_CTX *ctx, int *dat, int datlen)
391 {
392 ctx->keygen_info = dat;
393 ctx->keygen_info_count = datlen;
394 }
395
396void EVP_PKEY_CTX_set_data(EVP_PKEY_CTX *ctx, void *data)
397 {
398 ctx->data = data;
399 }
400
401void *EVP_PKEY_CTX_get_data(EVP_PKEY_CTX *ctx)
402 {
403 return ctx->data;
404 }
405
406EVP_PKEY *EVP_PKEY_CTX_get0_pkey(EVP_PKEY_CTX *ctx)
407 {
408 return ctx->pkey;
409 }
410
411EVP_PKEY *EVP_PKEY_CTX_get0_peerkey(EVP_PKEY_CTX *ctx)
412 {
413 return ctx->peerkey;
414 }
415
416void EVP_PKEY_CTX_set_app_data(EVP_PKEY_CTX *ctx, void *data)
417 {
418 ctx->app_data = data;
419 }
420
421void *EVP_PKEY_CTX_get_app_data(EVP_PKEY_CTX *ctx)
422 {
423 return ctx->app_data;
424 }
425
426void EVP_PKEY_meth_set_init(EVP_PKEY_METHOD *pmeth,
427 int (*init)(EVP_PKEY_CTX *ctx))
428 {
429 pmeth->init = init;
430 }
431
432void EVP_PKEY_meth_set_copy(EVP_PKEY_METHOD *pmeth,
433 int (*copy)(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src))
434 {
435 pmeth->copy = copy;
436 }
437
438void EVP_PKEY_meth_set_cleanup(EVP_PKEY_METHOD *pmeth,
439 void (*cleanup)(EVP_PKEY_CTX *ctx))
440 {
441 pmeth->cleanup = cleanup;
442 }
443
444void EVP_PKEY_meth_set_paramgen(EVP_PKEY_METHOD *pmeth,
445 int (*paramgen_init)(EVP_PKEY_CTX *ctx),
446 int (*paramgen)(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey))
447 {
448 pmeth->paramgen_init = paramgen_init;
449 pmeth->paramgen = paramgen;
450 }
451
452void EVP_PKEY_meth_set_keygen(EVP_PKEY_METHOD *pmeth,
453 int (*keygen_init)(EVP_PKEY_CTX *ctx),
454 int (*keygen)(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey))
455 {
456 pmeth->keygen_init = keygen_init;
457 pmeth->keygen = keygen;
458 }
459
460void EVP_PKEY_meth_set_sign(EVP_PKEY_METHOD *pmeth,
461 int (*sign_init)(EVP_PKEY_CTX *ctx),
462 int (*sign)(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen,
463 const unsigned char *tbs, size_t tbslen))
464 {
465 pmeth->sign_init = sign_init;
466 pmeth->sign = sign;
467 }
468
469void EVP_PKEY_meth_set_verify(EVP_PKEY_METHOD *pmeth,
470 int (*verify_init)(EVP_PKEY_CTX *ctx),
471 int (*verify)(EVP_PKEY_CTX *ctx, const unsigned char *sig, size_t siglen,
472 const unsigned char *tbs, size_t tbslen))
473 {
474 pmeth->verify_init = verify_init;
475 pmeth->verify = verify;
476 }
477
478void EVP_PKEY_meth_set_verify_recover(EVP_PKEY_METHOD *pmeth,
479 int (*verify_recover_init)(EVP_PKEY_CTX *ctx),
480 int (*verify_recover)(EVP_PKEY_CTX *ctx,
481 unsigned char *sig, size_t *siglen,
482 const unsigned char *tbs, size_t tbslen))
483 {
484 pmeth->verify_recover_init = verify_recover_init;
485 pmeth->verify_recover = verify_recover;
486 }
487
488void EVP_PKEY_meth_set_signctx(EVP_PKEY_METHOD *pmeth,
489 int (*signctx_init)(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx),
490 int (*signctx)(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen,
491 EVP_MD_CTX *mctx))
492 {
493 pmeth->signctx_init = signctx_init;
494 pmeth->signctx = signctx;
495 }
496
497void EVP_PKEY_meth_set_verifyctx(EVP_PKEY_METHOD *pmeth,
498 int (*verifyctx_init)(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx),
499 int (*verifyctx)(EVP_PKEY_CTX *ctx, const unsigned char *sig,int siglen,
500 EVP_MD_CTX *mctx))
501 {
502 pmeth->verifyctx_init = verifyctx_init;
503 pmeth->verifyctx = verifyctx;
504 }
505
506void EVP_PKEY_meth_set_encrypt(EVP_PKEY_METHOD *pmeth,
507 int (*encrypt_init)(EVP_PKEY_CTX *ctx),
508 int (*encryptfn)(EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen,
509 const unsigned char *in, size_t inlen))
510 {
511 pmeth->encrypt_init = encrypt_init;
512 pmeth->encrypt = encryptfn;
513 }
514
515void EVP_PKEY_meth_set_decrypt(EVP_PKEY_METHOD *pmeth,
516 int (*decrypt_init)(EVP_PKEY_CTX *ctx),
517 int (*decrypt)(EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen,
518 const unsigned char *in, size_t inlen))
519 {
520 pmeth->decrypt_init = decrypt_init;
521 pmeth->decrypt = decrypt;
522 }
523
524void EVP_PKEY_meth_set_derive(EVP_PKEY_METHOD *pmeth,
525 int (*derive_init)(EVP_PKEY_CTX *ctx),
526 int (*derive)(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen))
527 {
528 pmeth->derive_init = derive_init;
529 pmeth->derive = derive;
530 }
531
532void EVP_PKEY_meth_set_ctrl(EVP_PKEY_METHOD *pmeth,
533 int (*ctrl)(EVP_PKEY_CTX *ctx, int type, int p1, void *p2),
534 int (*ctrl_str)(EVP_PKEY_CTX *ctx, const char *type, const char *value))
535 {
536 pmeth->ctrl = ctrl;
537 pmeth->ctrl_str = ctrl_str;
538 }