Beginnings of PSS support.
[oweals/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         /* message digest */
81         const EVP_MD *md;
82         /* PSS seedlength */
83         int pss_seedlen;
84         /* Temp buffer */
85         unsigned char *tbuf;
86         } RSA_PKEY_CTX;
87
88 static 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->pss_seedlen = 0;
101
102         ctx->data = rctx;
103         
104         return 1;
105         }
106
107 static int setup_tbuf(RSA_PKEY_CTX *ctx, EVP_PKEY_CTX *pk)
108         {
109         if (ctx->tbuf)
110                 return 1;
111         ctx->tbuf = OPENSSL_malloc(EVP_PKEY_size(pk->pkey));
112         if (!ctx->tbuf)
113                 return 0;
114         return 1;
115         }
116
117 static void pkey_rsa_cleanup(EVP_PKEY_CTX *ctx)
118         {
119         RSA_PKEY_CTX *rctx = ctx->data;
120         if (rctx)
121                 {
122                 if (rctx->pub_exp)
123                         BN_free(rctx->pub_exp);
124                 if (rctx->tbuf)
125                         OPENSSL_free(rctx->tbuf);
126                 }
127         OPENSSL_free(rctx);
128         }
129
130 static int pkey_rsa_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, int *siglen,
131                                         const unsigned char *tbs, int tbslen)
132         {
133         int ret;
134         RSA_PKEY_CTX *rctx = ctx->data;
135
136         if (rctx->md)
137                 {
138                 if (tbslen != EVP_MD_size(rctx->md))
139                         {
140                         RSAerr(RSA_F_PKEY_RSA_SIGN,
141                                         RSA_R_INVALID_DIGEST_LENGTH);
142                         return -1;
143                         }
144                 if (rctx->pad_mode == RSA_X931_PADDING)
145                         {
146                         if (!setup_tbuf(rctx, ctx))
147                                 return -1;
148                         memcpy(rctx->tbuf, tbs, tbslen);
149                         rctx->tbuf[tbslen] =
150                                 RSA_X931_hash_id(EVP_MD_type(rctx->md));
151                         ret = RSA_private_encrypt(tbslen + 1, rctx->tbuf,
152                                                 sig, ctx->pkey->pkey.rsa,
153                                                 RSA_X931_PADDING);
154                         }
155                 else if (rctx->pad_mode == RSA_PKCS1_PADDING)
156                         {
157                         unsigned int sltmp;
158                         ret = RSA_sign(EVP_MD_type(rctx->md),
159                                                 tbs, tbslen, sig, &sltmp,
160                                                         ctx->pkey->pkey.rsa);
161                         if (ret <= 0)
162                                 return ret;
163                         ret = sltmp;
164                         }
165                 else
166                         return -1;
167                 }
168         else
169                 ret = RSA_private_encrypt(tbslen, tbs, sig, ctx->pkey->pkey.rsa,
170                                                         rctx->pad_mode);
171         if (ret < 0)
172                 return ret;
173         *siglen = ret;
174         return 1;
175         }
176
177
178 static int pkey_rsa_verifyrecover(EVP_PKEY_CTX *ctx,
179                                         unsigned char *rout, int *routlen,
180                                         const unsigned char *sig, int siglen)
181         {
182         int ret;
183         RSA_PKEY_CTX *rctx = ctx->data;
184
185         if (rctx->md)
186                 {
187                 if (rctx->pad_mode == RSA_X931_PADDING)
188                         {
189                         if (!setup_tbuf(rctx, ctx))
190                                 return -1;
191                         ret = RSA_public_decrypt(siglen, sig,
192                                                 rctx->tbuf, ctx->pkey->pkey.rsa,
193                                                 RSA_X931_PADDING);
194                         if (ret < 1)
195                                 return 0;
196                         ret--;
197                         if (rctx->tbuf[ret] !=
198                                 RSA_X931_hash_id(EVP_MD_type(rctx->md)))
199                                 {
200                                 RSAerr(RSA_F_PKEY_RSA_VERIFYRECOVER,
201                                                 RSA_R_ALGORITHM_MISMATCH);
202                                 return 0;
203                                 }
204                         if (ret != EVP_MD_size(rctx->md))
205                                 {
206                                 RSAerr(RSA_F_PKEY_RSA_VERIFYRECOVER,
207                                         RSA_R_INVALID_DIGEST_LENGTH);
208                                 return 0;
209                                 }
210                         if (rout)
211                                 memcpy(rout, rctx->tbuf, ret);
212                         }
213                 else if (rctx->pad_mode == RSA_PKCS1_PADDING)
214                         {
215                         unsigned int sltmp;
216                         ret = int_rsa_verify(EVP_MD_type(rctx->md),
217                                                 NULL, 0, rout, &sltmp,
218                                         sig, siglen, ctx->pkey->pkey.rsa);
219                         ret = sltmp;
220                         }
221                 else
222                         return -1;
223                 }
224         else
225                 ret = RSA_public_decrypt(siglen, sig, rout, ctx->pkey->pkey.rsa,
226                                                         rctx->pad_mode);
227         if (ret < 0)
228                 return ret;
229         *routlen = ret;
230         return 1;
231         }
232
233 static int pkey_rsa_verify(EVP_PKEY_CTX *ctx,
234                                         const unsigned char *sig, int siglen,
235                                         const unsigned char *tbs, int tbslen)
236         {
237         RSA_PKEY_CTX *rctx = ctx->data;
238         int rslen;
239         if (rctx->md)
240                 {
241                 if (rctx->pad_mode == RSA_PKCS1_PADDING)
242                         return RSA_verify(EVP_MD_type(rctx->md), tbs, tbslen,
243                                         sig, siglen, ctx->pkey->pkey.rsa);
244                 if (rctx->pad_mode == RSA_X931_PADDING)
245                         {
246                         if (pkey_rsa_verifyrecover(ctx, NULL, &rslen,
247                                         sig, siglen) <= 0)
248                                 return 0;
249                         }
250                 else
251                         return -1;
252                 }
253         else
254                 {
255                 if (!setup_tbuf(rctx, ctx))
256                         return -1;
257                 rslen = RSA_public_decrypt(siglen, sig, rctx->tbuf,
258                                         ctx->pkey->pkey.rsa, rctx->pad_mode);
259                 if (rslen <= 0)
260                         return 0;
261                 }
262
263         if ((rslen != tbslen) || memcmp(tbs, rctx->tbuf, rslen))
264                 return 0;
265
266         return 1;
267                         
268         }
269         
270
271 static int pkey_rsa_encrypt(EVP_PKEY_CTX *ctx, unsigned char *out, int *outlen,
272                                         const unsigned char *in, int inlen)
273         {
274         int ret;
275         RSA_PKEY_CTX *rctx = ctx->data;
276         ret = RSA_public_encrypt(inlen, in, out, ctx->pkey->pkey.rsa,
277                                                         rctx->pad_mode);
278         if (ret < 0)
279                 return ret;
280         *outlen = ret;
281         return 1;
282         }
283
284 static int pkey_rsa_decrypt(EVP_PKEY_CTX *ctx, unsigned char *out, int *outlen,
285                                         const unsigned char *in, int inlen)
286         {
287         int ret;
288         RSA_PKEY_CTX *rctx = ctx->data;
289         ret = RSA_private_decrypt(inlen, in, out, ctx->pkey->pkey.rsa,
290                                                         rctx->pad_mode);
291         if (ret < 0)
292                 return ret;
293         *outlen = ret;
294         return 1;
295         }
296
297 static int check_padding_md(const EVP_MD *md, int padding)
298         {
299         if (!md)
300                 return 1;
301         if (padding == RSA_NO_PADDING)
302                 {
303                 RSAerr(RSA_F_CHECK_PADDING_NID, RSA_R_INVALID_PADDING_MODE);
304                 return 0;
305                 }
306
307         if (padding == RSA_X931_PADDING)
308                 {
309                 if (RSA_X931_hash_id(EVP_MD_type(md)) == -1)
310                         {
311                         RSAerr(RSA_F_CHECK_PADDING_NID,
312                                                 RSA_R_INVALID_X931_DIGEST);
313                         return 0;
314                         }
315                 return 1;
316                 }
317
318         return 1;
319         }
320                         
321
322 static int pkey_rsa_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
323         {
324         RSA_PKEY_CTX *rctx = ctx->data;
325         switch (type)
326                 {
327                 case EVP_PKEY_CTRL_RSA_PADDING:
328                 if ((p1 >= RSA_PKCS1_PADDING) && (p1 <= RSA_PKCS1_PSS_PADDING))
329                         {
330                         if (ctx->operation & EVP_PKEY_OP_TYPE_GEN)
331                                 return -2;
332                         if (!check_padding_md(rctx->md, p1))
333                                 return 0;
334                         if ((p1 == RSA_PKCS1_PSS_PADDING) 
335                                 && !(ctx->operation & EVP_PKEY_OP_TYPE_SIG))
336                                 return -2;
337                         if ((p1 == RSA_PKCS1_OAEP_PADDING) 
338                                 && !(ctx->operation & EVP_PKEY_OP_TYPE_CRYPT))
339                                 return -2;
340                         rctx->pad_mode = p1;
341                         return 1;
342                         }
343                 return -2;
344
345                 case EVP_PKEY_CTRL_MD:
346                 if (!check_padding_md(p2, rctx->pad_mode))
347                         return 0;
348                 rctx->md = p2;
349                 return 1;
350
351                 default:
352                 return -2;
353
354                 }
355         }
356                         
357 static int pkey_rsa_ctrl_str(EVP_PKEY_CTX *ctx,
358                         const char *type, const char *value)
359         {
360         if (!strcmp(type, "rsa_padding_mode"))
361                 {
362                 int pm;
363                 if (!value)
364                         return 0;
365                 if (!strcmp(value, "pkcs1"))
366                         pm = RSA_PKCS1_PADDING;
367                 else if (!strcmp(value, "sslv23"))
368                         pm = RSA_SSLV23_PADDING;
369                 else if (!strcmp(value, "none"))
370                         pm = RSA_NO_PADDING;
371                 else if (!strcmp(value, "oeap"))
372                         pm = RSA_PKCS1_OAEP_PADDING;
373                 else if (!strcmp(value, "x931"))
374                         pm = RSA_X931_PADDING;
375                 else if (!strcmp(value, "pss"))
376                         pm = RSA_PKCS1_PSS_PADDING;
377                 else
378                         return -2;
379                 return EVP_PKEY_CTX_set_rsa_padding(ctx, pm);
380                 }
381         return -2;
382         }
383
384 const EVP_PKEY_METHOD rsa_pkey_meth = 
385         {
386         EVP_PKEY_RSA,
387         0,
388         pkey_rsa_init,
389         pkey_rsa_cleanup,
390
391         0,0,
392
393         0,0,
394
395         0,
396         pkey_rsa_sign,
397
398         0,
399         pkey_rsa_verify,
400
401         0,
402         pkey_rsa_verifyrecover,
403
404
405         0,0,0,0,
406
407         0,
408         pkey_rsa_encrypt,
409
410         0,
411         pkey_rsa_decrypt,
412
413         pkey_rsa_ctrl,
414         pkey_rsa_ctrl_str
415
416
417         };