Store digests as EVP_MD instead of a NID.
[openssl.git] / crypto / rsa / rsa_pmeth.c
1 /* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
2  * project 2006.
3  */
4 /* ====================================================================
5  * Copyright (c) 2006 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  *    licensing@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 <stdio.h>
59 #include "cryptlib.h"
60 #include <openssl/asn1t.h>
61 #include <openssl/x509.h>
62 #include <openssl/rsa.h>
63 #include <openssl/evp.h>
64 #include "evp_locl.h"
65
66 extern int int_rsa_verify(int dtype, const unsigned char *m, unsigned int m_len,
67                 unsigned char *rm, unsigned int *prm_len,
68                 const unsigned char *sigbuf, unsigned int siglen,
69                 RSA *rsa);
70
71 /* RSA pkey context structure */
72
73 typedef struct
74         {
75         /* Key gen parameters */
76         int nbits;
77         BIGNUM *pub_exp;
78         /* RSA padding mode */
79         int pad_mode;
80         /* nid for message digest */
81         const EVP_MD *md;
82         /* Temp buffer */
83         unsigned char *tbuf;
84         } RSA_PKEY_CTX;
85
86 static int pkey_rsa_init(EVP_PKEY_CTX *ctx)
87         {
88         RSA_PKEY_CTX *rctx;
89         rctx = OPENSSL_malloc(sizeof(RSA_PKEY_CTX));
90         if (!rctx)
91                 return 0;
92         rctx->nbits = 1024;
93         rctx->pub_exp = NULL;
94         rctx->pad_mode = RSA_PKCS1_PADDING;
95         rctx->md = NULL;
96         rctx->tbuf = NULL;
97
98         ctx->data = rctx;
99         
100         return 1;
101         }
102
103 static int setup_tbuf(RSA_PKEY_CTX *ctx, EVP_PKEY_CTX *pk)
104         {
105         if (ctx->tbuf)
106                 return 1;
107         ctx->tbuf = OPENSSL_malloc(EVP_PKEY_size(pk->pkey));
108         if (!ctx->tbuf)
109                 return 0;
110         return 1;
111         }
112
113 static void pkey_rsa_cleanup(EVP_PKEY_CTX *ctx)
114         {
115         RSA_PKEY_CTX *rctx = ctx->data;
116         if (rctx)
117                 {
118                 if (rctx->pub_exp)
119                         BN_free(rctx->pub_exp);
120                 if (rctx->tbuf)
121                         OPENSSL_free(rctx->tbuf);
122                 }
123         OPENSSL_free(rctx);
124         }
125
126 static int pkey_rsa_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, int *siglen,
127                                         const unsigned char *tbs, int tbslen)
128         {
129         int ret;
130         RSA_PKEY_CTX *rctx = ctx->data;
131
132         if (rctx->md)
133                 {
134                 if (tbslen != EVP_MD_size(rctx->md))
135                         {
136                         RSAerr(RSA_F_PKEY_RSA_SIGN,
137                                         RSA_R_INVALID_DIGEST_LENGTH);
138                         return -1;
139                         }
140                 if (rctx->pad_mode == RSA_X931_PADDING)
141                         {
142                         if (!setup_tbuf(rctx, ctx))
143                                 return -1;
144                         memcpy(rctx->tbuf, tbs, tbslen);
145                         rctx->tbuf[tbslen] =
146                                 RSA_X931_hash_id(EVP_MD_type(rctx->md));
147                         ret = RSA_private_encrypt(tbslen + 1, rctx->tbuf,
148                                                 sig, ctx->pkey->pkey.rsa,
149                                                 RSA_X931_PADDING);
150                         }
151                 else if (rctx->pad_mode == RSA_PKCS1_PADDING)
152                         {
153                         unsigned int sltmp;
154                         ret = RSA_sign(EVP_MD_type(rctx->md),
155                                                 tbs, tbslen, sig, &sltmp,
156                                                         ctx->pkey->pkey.rsa);
157                         }
158                 else
159                         return -1;
160                 }
161         else
162                 ret = RSA_private_encrypt(tbslen, tbs, sig, ctx->pkey->pkey.rsa,
163                                                         rctx->pad_mode);
164         if (ret < 0)
165                 return ret;
166         *siglen = ret;
167         return 1;
168         }
169
170
171 static int pkey_rsa_verifyrecover(EVP_PKEY_CTX *ctx,
172                                         unsigned char *sig, int *siglen,
173                                         const unsigned char *tbs, int tbslen)
174         {
175         int ret;
176         RSA_PKEY_CTX *rctx = ctx->data;
177
178         if (rctx->md)
179                 {
180                 if (rctx->pad_mode == RSA_X931_PADDING)
181                         {
182                         if (!setup_tbuf(rctx, ctx))
183                                 return -1;
184                         ret = RSA_public_decrypt(tbslen, tbs,
185                                                 rctx->tbuf, ctx->pkey->pkey.rsa,
186                                                 RSA_X931_PADDING);
187                         if (ret < 1)
188                                 return 0;
189                         ret--;
190                         if (rctx->tbuf[ret] !=
191                                 RSA_X931_hash_id(EVP_MD_type(rctx->md)))
192                                 {
193                                 RSAerr(RSA_F_PKEY_RSA_VERIFYRECOVER,
194                                                 RSA_R_ALGORITHM_MISMATCH);
195                                 return 0;
196                                 }
197                         if (ret != EVP_MD_size(rctx->md))
198                                 {
199                                 RSAerr(RSA_F_PKEY_RSA_VERIFYRECOVER,
200                                         RSA_R_INVALID_DIGEST_LENGTH);
201                                 return 0;
202                                 }
203                         memcpy(sig, rctx->tbuf, ret);
204                         }
205                 else if (rctx->pad_mode == RSA_PKCS1_PADDING)
206                         {
207                         unsigned int sltmp;
208                         ret = int_rsa_verify(EVP_MD_type(rctx->md),
209                                                 NULL, 0, sig, &sltmp,
210                                         tbs, tbslen, ctx->pkey->pkey.rsa);
211                         }
212                 else
213                         return -1;
214                 }
215         else
216                 ret = RSA_public_decrypt(tbslen, tbs, sig, ctx->pkey->pkey.rsa,
217                                                         rctx->pad_mode);
218         if (ret < 0)
219                 return ret;
220         *siglen = ret;
221         return 1;
222         }
223
224 static int pkey_rsa_encrypt(EVP_PKEY_CTX *ctx, unsigned char *out, int *outlen,
225                                         const unsigned char *in, int inlen)
226         {
227         int ret;
228         RSA_PKEY_CTX *rctx = ctx->data;
229         ret = RSA_public_encrypt(inlen, in, out, ctx->pkey->pkey.rsa,
230                                                         rctx->pad_mode);
231         if (ret < 0)
232                 return ret;
233         *outlen = ret;
234         return 1;
235         }
236
237 static int pkey_rsa_decrypt(EVP_PKEY_CTX *ctx, unsigned char *out, int *outlen,
238                                         const unsigned char *in, int inlen)
239         {
240         int ret;
241         RSA_PKEY_CTX *rctx = ctx->data;
242         ret = RSA_private_decrypt(inlen, in, out, ctx->pkey->pkey.rsa,
243                                                         rctx->pad_mode);
244         if (ret < 0)
245                 return ret;
246         *outlen = ret;
247         return 1;
248         }
249
250 static int check_padding_md(const EVP_MD *md, int padding)
251         {
252         if (!md)
253                 return 1;
254         if (padding == RSA_NO_PADDING)
255                 {
256                 RSAerr(RSA_F_CHECK_PADDING_NID, RSA_R_INVALID_PADDING_MODE);
257                 return 0;
258                 }
259
260         if (padding == RSA_X931_PADDING)
261                 {
262                 if (RSA_X931_hash_id(EVP_MD_type(md)) == -1)
263                         {
264                         RSAerr(RSA_F_CHECK_PADDING_NID,
265                                                 RSA_R_INVALID_X931_DIGEST);
266                         return 0;
267                         }
268                 return 1;
269                 }
270
271         return 1;
272         }
273                         
274
275 static int pkey_rsa_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
276         {
277         RSA_PKEY_CTX *rctx = ctx->data;
278         switch (type)
279                 {
280                 case EVP_PKEY_CTRL_RSA_PADDING:
281                 /* TODO: add PSS support */
282                 if ((p1 >= RSA_PKCS1_PADDING) && (p1 <= RSA_X931_PADDING))
283                         {
284                         if (ctx->operation == EVP_PKEY_OP_KEYGEN)
285                                 return -2;
286                         if (!check_padding_md(rctx->md, p1))
287                                 return 0;
288                         rctx->pad_mode = p1;
289                         return 1;
290                         }
291                 return -2;
292
293                 case EVP_PKEY_CTRL_MD:
294                 if (!check_padding_md(p2, rctx->pad_mode))
295                         return 0;
296                 rctx->md = p2;
297                 return 1;
298
299                 default:
300                 return -2;
301
302                 }
303         }
304                         
305 static int pkey_rsa_ctrl_str(EVP_PKEY_CTX *ctx,
306                         const char *type, const char *value)
307         {
308         if (!strcmp(type, "rsa_padding_mode"))
309                 {
310                 int pm;
311                 if (!value)
312                         return 0;
313                 if (!strcmp(value, "pkcs1"))
314                         pm = RSA_PKCS1_PADDING;
315                 else if (!strcmp(value, "sslv23"))
316                         pm = RSA_SSLV23_PADDING;
317                 else if (!strcmp(value, "none"))
318                         pm = RSA_NO_PADDING;
319                 else if (!strcmp(value, "oeap"))
320                         pm = RSA_PKCS1_OAEP_PADDING;
321                 else if (!strcmp(value, "x931"))
322                         pm = RSA_X931_PADDING;
323                 else
324                         return -2;
325                 return EVP_PKEY_CTX_set_rsa_padding(ctx, pm);
326                 }
327         return -2;
328         }
329
330 const EVP_PKEY_METHOD rsa_pkey_meth = 
331         {
332         EVP_PKEY_RSA,
333         0,
334         pkey_rsa_init,
335         pkey_rsa_cleanup,
336
337         0,0,
338
339         0,0,
340
341         0,
342         pkey_rsa_sign,
343
344         0,0,
345
346         0,
347         pkey_rsa_verifyrecover,
348
349
350         0,0,0,0,
351
352         0,
353         pkey_rsa_encrypt,
354
355         0,
356         pkey_rsa_decrypt,
357
358         pkey_rsa_ctrl,
359         pkey_rsa_ctrl_str
360
361
362         };