summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/rsa
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/libcrypto/rsa')
-rw-r--r--src/lib/libcrypto/rsa/rsa_ameth.c349
-rw-r--r--src/lib/libcrypto/rsa/rsa_locl.h4
-rw-r--r--src/lib/libcrypto/rsa/rsa_pmeth.c587
-rw-r--r--src/lib/libcrypto/rsa/rsa_prn.c93
-rw-r--r--src/lib/libcrypto/rsa/rsa_pss.c16
5 files changed, 1044 insertions, 5 deletions
diff --git a/src/lib/libcrypto/rsa/rsa_ameth.c b/src/lib/libcrypto/rsa/rsa_ameth.c
new file mode 100644
index 0000000000..8c3209885e
--- /dev/null
+++ b/src/lib/libcrypto/rsa/rsa_ameth.c
@@ -0,0 +1,349 @@
1/* crypto/rsa/rsa_ameth.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 "cryptlib.h"
61#include <openssl/asn1t.h>
62#include <openssl/x509.h>
63#include <openssl/rsa.h>
64#include <openssl/bn.h>
65#ifndef OPENSSL_NO_CMS
66#include <openssl/cms.h>
67#endif
68#include "asn1_locl.h"
69
70static int rsa_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey)
71 {
72 unsigned char *penc = NULL;
73 int penclen;
74 penclen = i2d_RSAPublicKey(pkey->pkey.rsa, &penc);
75 if (penclen <= 0)
76 return 0;
77 if (X509_PUBKEY_set0_param(pk, OBJ_nid2obj(EVP_PKEY_RSA),
78 V_ASN1_NULL, NULL, penc, penclen))
79 return 1;
80
81 OPENSSL_free(penc);
82 return 0;
83 }
84
85static int rsa_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey)
86 {
87 const unsigned char *p;
88 int pklen;
89 RSA *rsa = NULL;
90 if (!X509_PUBKEY_get0_param(NULL, &p, &pklen, NULL, pubkey))
91 return 0;
92 if (!(rsa = d2i_RSAPublicKey(NULL, &p, pklen)))
93 {
94 RSAerr(RSA_F_RSA_PUB_DECODE, ERR_R_RSA_LIB);
95 return 0;
96 }
97 EVP_PKEY_assign_RSA (pkey, rsa);
98 return 1;
99 }
100
101static int rsa_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b)
102 {
103 if (BN_cmp(b->pkey.rsa->n,a->pkey.rsa->n) != 0
104 || BN_cmp(b->pkey.rsa->e,a->pkey.rsa->e) != 0)
105 return 0;
106 return 1;
107 }
108
109static int old_rsa_priv_decode(EVP_PKEY *pkey,
110 const unsigned char **pder, int derlen)
111 {
112 RSA *rsa;
113 if (!(rsa = d2i_RSAPrivateKey (NULL, pder, derlen)))
114 {
115 RSAerr(RSA_F_OLD_RSA_PRIV_DECODE, ERR_R_RSA_LIB);
116 return 0;
117 }
118 EVP_PKEY_assign_RSA(pkey, rsa);
119 return 1;
120 }
121
122static int old_rsa_priv_encode(const EVP_PKEY *pkey, unsigned char **pder)
123 {
124 return i2d_RSAPrivateKey(pkey->pkey.rsa, pder);
125 }
126
127static int rsa_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey)
128 {
129 unsigned char *rk = NULL;
130 int rklen;
131 rklen = i2d_RSAPrivateKey(pkey->pkey.rsa, &rk);
132
133 if (rklen <= 0)
134 {
135 RSAerr(RSA_F_RSA_PRIV_ENCODE,ERR_R_MALLOC_FAILURE);
136 return 0;
137 }
138
139 if (!PKCS8_pkey_set0(p8, OBJ_nid2obj(NID_rsaEncryption), 0,
140 V_ASN1_NULL, NULL, rk, rklen))
141 {
142 RSAerr(RSA_F_RSA_PRIV_ENCODE,ERR_R_MALLOC_FAILURE);
143 return 0;
144 }
145
146 return 1;
147 }
148
149static int rsa_priv_decode(EVP_PKEY *pkey, PKCS8_PRIV_KEY_INFO *p8)
150 {
151 const unsigned char *p;
152 int pklen;
153 if (!PKCS8_pkey_get0(NULL, &p, &pklen, NULL, p8))
154 return 0;
155 return old_rsa_priv_decode(pkey, &p, pklen);
156 }
157
158static int int_rsa_size(const EVP_PKEY *pkey)
159 {
160 return RSA_size(pkey->pkey.rsa);
161 }
162
163static int rsa_bits(const EVP_PKEY *pkey)
164 {
165 return BN_num_bits(pkey->pkey.rsa->n);
166 }
167
168static void int_rsa_free(EVP_PKEY *pkey)
169 {
170 RSA_free(pkey->pkey.rsa);
171 }
172
173
174static void update_buflen(const BIGNUM *b, size_t *pbuflen)
175 {
176 size_t i;
177 if (!b)
178 return;
179 if (*pbuflen < (i = (size_t)BN_num_bytes(b)))
180 *pbuflen = i;
181 }
182
183static int do_rsa_print(BIO *bp, const RSA *x, int off, int priv)
184 {
185 char *str;
186 const char *s;
187 unsigned char *m=NULL;
188 int ret=0, mod_len = 0;
189 size_t buf_len=0;
190
191 update_buflen(x->n, &buf_len);
192 update_buflen(x->e, &buf_len);
193
194 if (priv)
195 {
196 update_buflen(x->d, &buf_len);
197 update_buflen(x->p, &buf_len);
198 update_buflen(x->q, &buf_len);
199 update_buflen(x->dmp1, &buf_len);
200 update_buflen(x->dmq1, &buf_len);
201 update_buflen(x->iqmp, &buf_len);
202 }
203
204 m=(unsigned char *)OPENSSL_malloc(buf_len+10);
205 if (m == NULL)
206 {
207 RSAerr(RSA_F_DO_RSA_PRINT,ERR_R_MALLOC_FAILURE);
208 goto err;
209 }
210
211 if (x->n != NULL)
212 mod_len = BN_num_bits(x->n);
213
214 if(!BIO_indent(bp,off,128))
215 goto err;
216
217 if (priv && x->d)
218 {
219 if (BIO_printf(bp,"Private-Key: (%d bit)\n", mod_len)
220 <= 0) goto err;
221 str = "modulus:";
222 s = "publicExponent:";
223 }
224 else
225 {
226 if (BIO_printf(bp,"Public-Key: (%d bit)\n", mod_len)
227 <= 0) goto err;
228 str = "Modulus:";
229 s= "Exponent:";
230 }
231 if (!ASN1_bn_print(bp,str,x->n,m,off)) goto err;
232 if (!ASN1_bn_print(bp,s,x->e,m,off))
233 goto err;
234 if (priv)
235 {
236 if (!ASN1_bn_print(bp,"privateExponent:",x->d,m,off))
237 goto err;
238 if (!ASN1_bn_print(bp,"prime1:",x->p,m,off))
239 goto err;
240 if (!ASN1_bn_print(bp,"prime2:",x->q,m,off))
241 goto err;
242 if (!ASN1_bn_print(bp,"exponent1:",x->dmp1,m,off))
243 goto err;
244 if (!ASN1_bn_print(bp,"exponent2:",x->dmq1,m,off))
245 goto err;
246 if (!ASN1_bn_print(bp,"coefficient:",x->iqmp,m,off))
247 goto err;
248 }
249 ret=1;
250err:
251 if (m != NULL) OPENSSL_free(m);
252 return(ret);
253 }
254
255static int rsa_pub_print(BIO *bp, const EVP_PKEY *pkey, int indent,
256 ASN1_PCTX *ctx)
257 {
258 return do_rsa_print(bp, pkey->pkey.rsa, indent, 0);
259 }
260
261
262static int rsa_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent,
263 ASN1_PCTX *ctx)
264 {
265 return do_rsa_print(bp, pkey->pkey.rsa, indent, 1);
266 }
267
268
269static int rsa_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2)
270 {
271 X509_ALGOR *alg = NULL;
272 switch (op)
273 {
274
275 case ASN1_PKEY_CTRL_PKCS7_SIGN:
276 if (arg1 == 0)
277 PKCS7_SIGNER_INFO_get0_algs(arg2, NULL, NULL, &alg);
278 break;
279
280 case ASN1_PKEY_CTRL_PKCS7_ENCRYPT:
281 if (arg1 == 0)
282 PKCS7_RECIP_INFO_get0_alg(arg2, &alg);
283 break;
284#ifndef OPENSSL_NO_CMS
285 case ASN1_PKEY_CTRL_CMS_SIGN:
286 if (arg1 == 0)
287 CMS_SignerInfo_get0_algs(arg2, NULL, NULL, NULL, &alg);
288 break;
289
290 case ASN1_PKEY_CTRL_CMS_ENVELOPE:
291 if (arg1 == 0)
292 CMS_RecipientInfo_ktri_get0_algs(arg2, NULL, NULL, &alg);
293 break;
294#endif
295
296 case ASN1_PKEY_CTRL_DEFAULT_MD_NID:
297 *(int *)arg2 = NID_sha1;
298 return 1;
299
300 default:
301 return -2;
302
303 }
304
305 if (alg)
306 X509_ALGOR_set0(alg, OBJ_nid2obj(NID_rsaEncryption),
307 V_ASN1_NULL, 0);
308
309 return 1;
310
311 }
312
313
314const EVP_PKEY_ASN1_METHOD rsa_asn1_meths[] =
315 {
316 {
317 EVP_PKEY_RSA,
318 EVP_PKEY_RSA,
319 ASN1_PKEY_SIGPARAM_NULL,
320
321 "RSA",
322 "OpenSSL RSA method",
323
324 rsa_pub_decode,
325 rsa_pub_encode,
326 rsa_pub_cmp,
327 rsa_pub_print,
328
329 rsa_priv_decode,
330 rsa_priv_encode,
331 rsa_priv_print,
332
333 int_rsa_size,
334 rsa_bits,
335
336 0,0,0,0,0,0,
337
338 int_rsa_free,
339 rsa_pkey_ctrl,
340 old_rsa_priv_decode,
341 old_rsa_priv_encode
342 },
343
344 {
345 EVP_PKEY_RSA2,
346 EVP_PKEY_RSA,
347 ASN1_PKEY_ALIAS
348 }
349 };
diff --git a/src/lib/libcrypto/rsa/rsa_locl.h b/src/lib/libcrypto/rsa/rsa_locl.h
new file mode 100644
index 0000000000..f5d2d56628
--- /dev/null
+++ b/src/lib/libcrypto/rsa/rsa_locl.h
@@ -0,0 +1,4 @@
1extern int int_rsa_verify(int dtype, const unsigned char *m, unsigned int m_len,
2 unsigned char *rm, size_t *prm_len,
3 const unsigned char *sigbuf, size_t siglen,
4 RSA *rsa);
diff --git a/src/lib/libcrypto/rsa/rsa_pmeth.c b/src/lib/libcrypto/rsa/rsa_pmeth.c
new file mode 100644
index 0000000000..c6892ecd09
--- /dev/null
+++ b/src/lib/libcrypto/rsa/rsa_pmeth.c
@@ -0,0 +1,587 @@
1/* crypto/rsa/rsa_pmeth.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 "cryptlib.h"
61#include <openssl/asn1t.h>
62#include <openssl/x509.h>
63#include <openssl/rsa.h>
64#include <openssl/bn.h>
65#include <openssl/evp.h>
66#include "evp_locl.h"
67#include "rsa_locl.h"
68
69/* RSA pkey context structure */
70
71typedef struct
72 {
73 /* Key gen parameters */
74 int nbits;
75 BIGNUM *pub_exp;
76 /* Keygen callback info */
77 int gentmp[2];
78 /* RSA padding mode */
79 int pad_mode;
80 /* message digest */
81 const EVP_MD *md;
82 /* PSS/OAEP salt length */
83 int saltlen;
84 /* Temp buffer */
85 unsigned char *tbuf;
86 } RSA_PKEY_CTX;
87
88static int pkey_rsa_init(EVP_PKEY_CTX *ctx)
89 {
90 RSA_PKEY_CTX *rctx;
91 rctx = OPENSSL_malloc(sizeof(RSA_PKEY_CTX));
92 if (!rctx)
93 return 0;
94 rctx->nbits = 1024;
95 rctx->pub_exp = NULL;
96 rctx->pad_mode = RSA_PKCS1_PADDING;
97 rctx->md = NULL;
98 rctx->tbuf = NULL;
99
100 rctx->saltlen = -2;
101
102 ctx->data = rctx;
103 ctx->keygen_info = rctx->gentmp;
104 ctx->keygen_info_count = 2;
105
106 return 1;
107 }
108
109static int pkey_rsa_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src)
110 {
111 RSA_PKEY_CTX *dctx, *sctx;
112 if (!pkey_rsa_init(dst))
113 return 0;
114 sctx = src->data;
115 dctx = dst->data;
116 dctx->nbits = sctx->nbits;
117 if (sctx->pub_exp)
118 {
119 dctx->pub_exp = BN_dup(sctx->pub_exp);
120 if (!dctx->pub_exp)
121 return 0;
122 }
123 dctx->pad_mode = sctx->pad_mode;
124 dctx->md = sctx->md;
125 return 1;
126 }
127
128static int setup_tbuf(RSA_PKEY_CTX *ctx, EVP_PKEY_CTX *pk)
129 {
130 if (ctx->tbuf)
131 return 1;
132 ctx->tbuf = OPENSSL_malloc(EVP_PKEY_size(pk->pkey));
133 if (!ctx->tbuf)
134 return 0;
135 return 1;
136 }
137
138static void pkey_rsa_cleanup(EVP_PKEY_CTX *ctx)
139 {
140 RSA_PKEY_CTX *rctx = ctx->data;
141 if (rctx)
142 {
143 if (rctx->pub_exp)
144 BN_free(rctx->pub_exp);
145 if (rctx->tbuf)
146 OPENSSL_free(rctx->tbuf);
147 OPENSSL_free(rctx);
148 }
149 }
150
151static int pkey_rsa_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen,
152 const unsigned char *tbs, size_t tbslen)
153 {
154 int ret;
155 RSA_PKEY_CTX *rctx = ctx->data;
156 RSA *rsa = ctx->pkey->pkey.rsa;
157
158 if (rctx->md)
159 {
160 if (tbslen != (size_t)EVP_MD_size(rctx->md))
161 {
162 RSAerr(RSA_F_PKEY_RSA_SIGN,
163 RSA_R_INVALID_DIGEST_LENGTH);
164 return -1;
165 }
166 if (rctx->pad_mode == RSA_X931_PADDING)
167 {
168 if (!setup_tbuf(rctx, ctx))
169 return -1;
170 memcpy(rctx->tbuf, tbs, tbslen);
171 rctx->tbuf[tbslen] =
172 RSA_X931_hash_id(EVP_MD_type(rctx->md));
173 ret = RSA_private_encrypt(tbslen + 1, rctx->tbuf,
174 sig, rsa, RSA_X931_PADDING);
175 }
176 else if (rctx->pad_mode == RSA_PKCS1_PADDING)
177 {
178 unsigned int sltmp;
179 ret = RSA_sign(EVP_MD_type(rctx->md),
180 tbs, tbslen, sig, &sltmp, rsa);
181 if (ret <= 0)
182 return ret;
183 ret = sltmp;
184 }
185 else if (rctx->pad_mode == RSA_PKCS1_PSS_PADDING)
186 {
187 if (!setup_tbuf(rctx, ctx))
188 return -1;
189 if (!RSA_padding_add_PKCS1_PSS(rsa, rctx->tbuf, tbs,
190 rctx->md, rctx->saltlen))
191 return -1;
192 ret = RSA_private_encrypt(RSA_size(rsa), rctx->tbuf,
193 sig, rsa, RSA_NO_PADDING);
194 }
195 else
196 return -1;
197 }
198 else
199 ret = RSA_private_encrypt(tbslen, tbs, sig, ctx->pkey->pkey.rsa,
200 rctx->pad_mode);
201 if (ret < 0)
202 return ret;
203 *siglen = ret;
204 return 1;
205 }
206
207
208static int pkey_rsa_verifyrecover(EVP_PKEY_CTX *ctx,
209 unsigned char *rout, size_t *routlen,
210 const unsigned char *sig, size_t siglen)
211 {
212 int ret;
213 RSA_PKEY_CTX *rctx = ctx->data;
214
215 if (rctx->md)
216 {
217 if (rctx->pad_mode == RSA_X931_PADDING)
218 {
219 if (!setup_tbuf(rctx, ctx))
220 return -1;
221 ret = RSA_public_decrypt(siglen, sig,
222 rctx->tbuf, ctx->pkey->pkey.rsa,
223 RSA_X931_PADDING);
224 if (ret < 1)
225 return 0;
226 ret--;
227 if (rctx->tbuf[ret] !=
228 RSA_X931_hash_id(EVP_MD_type(rctx->md)))
229 {
230 RSAerr(RSA_F_PKEY_RSA_VERIFYRECOVER,
231 RSA_R_ALGORITHM_MISMATCH);
232 return 0;
233 }
234 if (ret != EVP_MD_size(rctx->md))
235 {
236 RSAerr(RSA_F_PKEY_RSA_VERIFYRECOVER,
237 RSA_R_INVALID_DIGEST_LENGTH);
238 return 0;
239 }
240 if (rout)
241 memcpy(rout, rctx->tbuf, ret);
242 }
243 else if (rctx->pad_mode == RSA_PKCS1_PADDING)
244 {
245 size_t sltmp;
246 ret = int_rsa_verify(EVP_MD_type(rctx->md),
247 NULL, 0, rout, &sltmp,
248 sig, siglen, ctx->pkey->pkey.rsa);
249 if (ret <= 0)
250 return 0;
251 ret = sltmp;
252 }
253 else
254 return -1;
255 }
256 else
257 ret = RSA_public_decrypt(siglen, sig, rout, ctx->pkey->pkey.rsa,
258 rctx->pad_mode);
259 if (ret < 0)
260 return ret;
261 *routlen = ret;
262 return 1;
263 }
264
265static int pkey_rsa_verify(EVP_PKEY_CTX *ctx,
266 const unsigned char *sig, size_t siglen,
267 const unsigned char *tbs, size_t tbslen)
268 {
269 RSA_PKEY_CTX *rctx = ctx->data;
270 RSA *rsa = ctx->pkey->pkey.rsa;
271 size_t rslen;
272 if (rctx->md)
273 {
274 if (rctx->pad_mode == RSA_PKCS1_PADDING)
275 return RSA_verify(EVP_MD_type(rctx->md), tbs, tbslen,
276 sig, siglen, rsa);
277 if (rctx->pad_mode == RSA_X931_PADDING)
278 {
279 if (pkey_rsa_verifyrecover(ctx, NULL, &rslen,
280 sig, siglen) <= 0)
281 return 0;
282 }
283 else if (rctx->pad_mode == RSA_PKCS1_PSS_PADDING)
284 {
285 int ret;
286 if (!setup_tbuf(rctx, ctx))
287 return -1;
288 ret = RSA_public_decrypt(siglen, sig, rctx->tbuf,
289 rsa, RSA_NO_PADDING);
290 if (ret <= 0)
291 return 0;
292 ret = RSA_verify_PKCS1_PSS(rsa, tbs, rctx->md,
293 rctx->tbuf, rctx->saltlen);
294 if (ret <= 0)
295 return 0;
296 return 1;
297 }
298 else
299 return -1;
300 }
301 else
302 {
303 if (!setup_tbuf(rctx, ctx))
304 return -1;
305 rslen = RSA_public_decrypt(siglen, sig, rctx->tbuf,
306 rsa, rctx->pad_mode);
307 if (rslen == 0)
308 return 0;
309 }
310
311 if ((rslen != tbslen) || memcmp(tbs, rctx->tbuf, rslen))
312 return 0;
313
314 return 1;
315
316 }
317
318
319static int pkey_rsa_encrypt(EVP_PKEY_CTX *ctx,
320 unsigned char *out, size_t *outlen,
321 const unsigned char *in, size_t inlen)
322 {
323 int ret;
324 RSA_PKEY_CTX *rctx = ctx->data;
325 ret = RSA_public_encrypt(inlen, in, out, ctx->pkey->pkey.rsa,
326 rctx->pad_mode);
327 if (ret < 0)
328 return ret;
329 *outlen = ret;
330 return 1;
331 }
332
333static int pkey_rsa_decrypt(EVP_PKEY_CTX *ctx,
334 unsigned char *out, size_t *outlen,
335 const unsigned char *in, size_t inlen)
336 {
337 int ret;
338 RSA_PKEY_CTX *rctx = ctx->data;
339 ret = RSA_private_decrypt(inlen, in, out, ctx->pkey->pkey.rsa,
340 rctx->pad_mode);
341 if (ret < 0)
342 return ret;
343 *outlen = ret;
344 return 1;
345 }
346
347static int check_padding_md(const EVP_MD *md, int padding)
348 {
349 if (!md)
350 return 1;
351
352 if (padding == RSA_NO_PADDING)
353 {
354 RSAerr(RSA_F_CHECK_PADDING_MD, RSA_R_INVALID_PADDING_MODE);
355 return 0;
356 }
357
358 if (padding == RSA_X931_PADDING)
359 {
360 if (RSA_X931_hash_id(EVP_MD_type(md)) == -1)
361 {
362 RSAerr(RSA_F_CHECK_PADDING_MD,
363 RSA_R_INVALID_X931_DIGEST);
364 return 0;
365 }
366 return 1;
367 }
368
369 return 1;
370 }
371
372
373static int pkey_rsa_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
374 {
375 RSA_PKEY_CTX *rctx = ctx->data;
376 switch (type)
377 {
378 case EVP_PKEY_CTRL_RSA_PADDING:
379 if ((p1 >= RSA_PKCS1_PADDING) && (p1 <= RSA_PKCS1_PSS_PADDING))
380 {
381 if (!check_padding_md(rctx->md, p1))
382 return 0;
383 if (p1 == RSA_PKCS1_PSS_PADDING)
384 {
385 if (!(ctx->operation &
386 (EVP_PKEY_OP_SIGN | EVP_PKEY_OP_VERIFY)))
387 goto bad_pad;
388 if (!rctx->md)
389 rctx->md = EVP_sha1();
390 }
391 if (p1 == RSA_PKCS1_OAEP_PADDING)
392 {
393 if (!(ctx->operation & EVP_PKEY_OP_TYPE_CRYPT))
394 goto bad_pad;
395 if (!rctx->md)
396 rctx->md = EVP_sha1();
397 }
398 rctx->pad_mode = p1;
399 return 1;
400 }
401 bad_pad:
402 RSAerr(RSA_F_PKEY_RSA_CTRL,
403 RSA_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE);
404 return -2;
405
406 case EVP_PKEY_CTRL_RSA_PSS_SALTLEN:
407 if (p1 < -2)
408 return -2;
409 if (rctx->pad_mode != RSA_PKCS1_PSS_PADDING)
410 {
411 RSAerr(RSA_F_PKEY_RSA_CTRL, RSA_R_INVALID_PSS_SALTLEN);
412 return -2;
413 }
414 rctx->saltlen = p1;
415 return 1;
416
417 case EVP_PKEY_CTRL_RSA_KEYGEN_BITS:
418 if (p1 < 256)
419 {
420 RSAerr(RSA_F_PKEY_RSA_CTRL, RSA_R_INVALID_KEYBITS);
421 return -2;
422 }
423 rctx->nbits = p1;
424 return 1;
425
426 case EVP_PKEY_CTRL_RSA_KEYGEN_PUBEXP:
427 if (!p2)
428 return -2;
429 rctx->pub_exp = p2;
430 return 1;
431
432 case EVP_PKEY_CTRL_MD:
433 if (!check_padding_md(p2, rctx->pad_mode))
434 return 0;
435 rctx->md = p2;
436 return 1;
437
438 case EVP_PKEY_CTRL_DIGESTINIT:
439 case EVP_PKEY_CTRL_PKCS7_ENCRYPT:
440 case EVP_PKEY_CTRL_PKCS7_DECRYPT:
441 case EVP_PKEY_CTRL_PKCS7_SIGN:
442#ifndef OPENSSL_NO_CMS
443 case EVP_PKEY_CTRL_CMS_ENCRYPT:
444 case EVP_PKEY_CTRL_CMS_DECRYPT:
445 case EVP_PKEY_CTRL_CMS_SIGN:
446#endif
447 return 1;
448 case EVP_PKEY_CTRL_PEER_KEY:
449 RSAerr(RSA_F_PKEY_RSA_CTRL,
450 RSA_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
451 return -2;
452
453 default:
454 return -2;
455
456 }
457 }
458
459static int pkey_rsa_ctrl_str(EVP_PKEY_CTX *ctx,
460 const char *type, const char *value)
461 {
462 if (!value)
463 {
464 RSAerr(RSA_F_PKEY_RSA_CTRL_STR, RSA_R_VALUE_MISSING);
465 return 0;
466 }
467 if (!strcmp(type, "rsa_padding_mode"))
468 {
469 int pm;
470 if (!strcmp(value, "pkcs1"))
471 pm = RSA_PKCS1_PADDING;
472 else if (!strcmp(value, "sslv23"))
473 pm = RSA_SSLV23_PADDING;
474 else if (!strcmp(value, "none"))
475 pm = RSA_NO_PADDING;
476 else if (!strcmp(value, "oeap"))
477 pm = RSA_PKCS1_OAEP_PADDING;
478 else if (!strcmp(value, "x931"))
479 pm = RSA_X931_PADDING;
480 else if (!strcmp(value, "pss"))
481 pm = RSA_PKCS1_PSS_PADDING;
482 else
483 {
484 RSAerr(RSA_F_PKEY_RSA_CTRL_STR,
485 RSA_R_UNKNOWN_PADDING_TYPE);
486 return -2;
487 }
488 return EVP_PKEY_CTX_set_rsa_padding(ctx, pm);
489 }
490
491 if (!strcmp(type, "rsa_pss_saltlen"))
492 {
493 int saltlen;
494 saltlen = atoi(value);
495 return EVP_PKEY_CTX_set_rsa_pss_saltlen(ctx, saltlen);
496 }
497
498 if (!strcmp(type, "rsa_keygen_bits"))
499 {
500 int nbits;
501 nbits = atoi(value);
502 return EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, nbits);
503 }
504
505 if (!strcmp(type, "rsa_keygen_pubexp"))
506 {
507 int ret;
508 BIGNUM *pubexp = NULL;
509 if (!BN_asc2bn(&pubexp, value))
510 return 0;
511 ret = EVP_PKEY_CTX_set_rsa_keygen_pubexp(ctx, pubexp);
512 if (ret <= 0)
513 BN_free(pubexp);
514 return ret;
515 }
516
517 return -2;
518 }
519
520static int pkey_rsa_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
521 {
522 RSA *rsa = NULL;
523 RSA_PKEY_CTX *rctx = ctx->data;
524 BN_GENCB *pcb, cb;
525 int ret;
526 if (!rctx->pub_exp)
527 {
528 rctx->pub_exp = BN_new();
529 if (!rctx->pub_exp || !BN_set_word(rctx->pub_exp, RSA_F4))
530 return 0;
531 }
532 rsa = RSA_new();
533 if (!rsa)
534 return 0;
535 if (ctx->pkey_gencb)
536 {
537 pcb = &cb;
538 evp_pkey_set_cb_translate(pcb, ctx);
539 }
540 else
541 pcb = NULL;
542 ret = RSA_generate_key_ex(rsa, rctx->nbits, rctx->pub_exp, pcb);
543 if (ret > 0)
544 EVP_PKEY_assign_RSA(pkey, rsa);
545 else
546 RSA_free(rsa);
547 return ret;
548 }
549
550const EVP_PKEY_METHOD rsa_pkey_meth =
551 {
552 EVP_PKEY_RSA,
553 EVP_PKEY_FLAG_AUTOARGLEN,
554 pkey_rsa_init,
555 pkey_rsa_copy,
556 pkey_rsa_cleanup,
557
558 0,0,
559
560 0,
561 pkey_rsa_keygen,
562
563 0,
564 pkey_rsa_sign,
565
566 0,
567 pkey_rsa_verify,
568
569 0,
570 pkey_rsa_verifyrecover,
571
572
573 0,0,0,0,
574
575 0,
576 pkey_rsa_encrypt,
577
578 0,
579 pkey_rsa_decrypt,
580
581 0,0,
582
583 pkey_rsa_ctrl,
584 pkey_rsa_ctrl_str
585
586
587 };
diff --git a/src/lib/libcrypto/rsa/rsa_prn.c b/src/lib/libcrypto/rsa/rsa_prn.c
new file mode 100644
index 0000000000..224db0fae5
--- /dev/null
+++ b/src/lib/libcrypto/rsa/rsa_prn.c
@@ -0,0 +1,93 @@
1/* crypto/rsa/rsa_prn.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 "cryptlib.h"
61#include <openssl/rsa.h>
62#include <openssl/evp.h>
63
64#ifndef OPENSSL_NO_FP_API
65int RSA_print_fp(FILE *fp, const RSA *x, int off)
66 {
67 BIO *b;
68 int ret;
69
70 if ((b=BIO_new(BIO_s_file())) == NULL)
71 {
72 RSAerr(RSA_F_RSA_PRINT_FP,ERR_R_BUF_LIB);
73 return(0);
74 }
75 BIO_set_fp(b,fp,BIO_NOCLOSE);
76 ret=RSA_print(b,x,off);
77 BIO_free(b);
78 return(ret);
79 }
80#endif
81
82int RSA_print(BIO *bp, const RSA *x, int off)
83 {
84 EVP_PKEY *pk;
85 int ret;
86 pk = EVP_PKEY_new();
87 if (!pk || !EVP_PKEY_set1_RSA(pk, (RSA *)x))
88 return 0;
89 ret = EVP_PKEY_print_private(bp, pk, off, NULL);
90 EVP_PKEY_free(pk);
91 return ret;
92 }
93
diff --git a/src/lib/libcrypto/rsa/rsa_pss.c b/src/lib/libcrypto/rsa/rsa_pss.c
index 9b993aca49..ac211e2ffe 100644
--- a/src/lib/libcrypto/rsa/rsa_pss.c
+++ b/src/lib/libcrypto/rsa/rsa_pss.c
@@ -81,7 +81,9 @@ int RSA_verify_PKCS1_PSS(RSA *rsa, const unsigned char *mHash,
81 EVP_MD_CTX ctx; 81 EVP_MD_CTX ctx;
82 unsigned char H_[EVP_MAX_MD_SIZE]; 82 unsigned char H_[EVP_MAX_MD_SIZE];
83 83
84 hLen = M_EVP_MD_size(Hash); 84 hLen = EVP_MD_size(Hash);
85 if (hLen < 0)
86 goto err;
85 /* 87 /*
86 * Negative sLen has special meanings: 88 * Negative sLen has special meanings:
87 * -1 sLen == hLen 89 * -1 sLen == hLen
@@ -126,7 +128,8 @@ int RSA_verify_PKCS1_PSS(RSA *rsa, const unsigned char *mHash,
126 RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS, ERR_R_MALLOC_FAILURE); 128 RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS, ERR_R_MALLOC_FAILURE);
127 goto err; 129 goto err;
128 } 130 }
129 PKCS1_MGF1(DB, maskedDBLen, H, hLen, Hash); 131 if (PKCS1_MGF1(DB, maskedDBLen, H, hLen, Hash) < 0)
132 goto err;
130 for (i = 0; i < maskedDBLen; i++) 133 for (i = 0; i < maskedDBLen; i++)
131 DB[i] ^= EM[i]; 134 DB[i] ^= EM[i];
132 if (MSBits) 135 if (MSBits)
@@ -176,7 +179,9 @@ int RSA_padding_add_PKCS1_PSS(RSA *rsa, unsigned char *EM,
176 unsigned char *H, *salt = NULL, *p; 179 unsigned char *H, *salt = NULL, *p;
177 EVP_MD_CTX ctx; 180 EVP_MD_CTX ctx;
178 181
179 hLen = M_EVP_MD_size(Hash); 182 hLen = EVP_MD_size(Hash);
183 if (hLen < 0)
184 goto err;
180 /* 185 /*
181 * Negative sLen has special meanings: 186 * Negative sLen has special meanings:
182 * -1 sLen == hLen 187 * -1 sLen == hLen
@@ -217,7 +222,7 @@ int RSA_padding_add_PKCS1_PSS(RSA *rsa, unsigned char *EM,
217 ERR_R_MALLOC_FAILURE); 222 ERR_R_MALLOC_FAILURE);
218 goto err; 223 goto err;
219 } 224 }
220 if (!RAND_bytes(salt, sLen)) 225 if (RAND_bytes(salt, sLen) <= 0)
221 goto err; 226 goto err;
222 } 227 }
223 maskedDBLen = emLen - hLen - 1; 228 maskedDBLen = emLen - hLen - 1;
@@ -232,7 +237,8 @@ int RSA_padding_add_PKCS1_PSS(RSA *rsa, unsigned char *EM,
232 EVP_MD_CTX_cleanup(&ctx); 237 EVP_MD_CTX_cleanup(&ctx);
233 238
234 /* Generate dbMask in place then perform XOR on it */ 239 /* Generate dbMask in place then perform XOR on it */
235 PKCS1_MGF1(EM, maskedDBLen, H, hLen, Hash); 240 if (PKCS1_MGF1(EM, maskedDBLen, H, hLen, Hash))
241 goto err;
236 242
237 p = EM; 243 p = EM;
238 244