]> CyberLeo.Net >> Repos - FreeBSD/releng/9.2.git/blob - crypto/openssl/fips/rsa/fips_rsa_sign.c
- Copy stable/9 to releng/9.2 as part of the 9.2-RELEASE cycle.
[FreeBSD/releng/9.2.git] / crypto / openssl / fips / rsa / fips_rsa_sign.c
1 /* fips_rsa_sign.c */
2 /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
3  * project 2007.
4  */
5 /* ====================================================================
6  * Copyright (c) 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 <string.h>
60 #include <openssl/evp.h>
61 #include <openssl/rsa.h>
62 #include <openssl/err.h>
63 #include <openssl/sha.h>
64
65 #ifdef OPENSSL_FIPS
66
67 /* FIPS versions of RSA_sign() and RSA_verify().
68  * These will only have to deal with SHA* signatures and by including
69  * pregenerated encodings all ASN1 dependencies can be avoided
70  */
71
72 /* Standard encodings including NULL parameter */
73
74 static const unsigned char sha1_bin[] = {
75   0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x05,
76   0x00, 0x04, 0x14
77 };
78
79 static const unsigned char sha224_bin[] = {
80   0x30, 0x2d, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03,
81   0x04, 0x02, 0x04, 0x05, 0x00, 0x04, 0x1c
82 };
83
84 static const unsigned char sha256_bin[] = {
85   0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03,
86   0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20
87 };
88
89 static const unsigned char sha384_bin[] = {
90   0x30, 0x41, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03,
91   0x04, 0x02, 0x02, 0x05, 0x00, 0x04, 0x30
92 };
93
94 static const unsigned char sha512_bin[] = {
95   0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03,
96   0x04, 0x02, 0x03, 0x05, 0x00, 0x04, 0x40
97 };
98
99 /* Alternate encodings with absent parameters. We don't generate signature
100  * using this format but do tolerate received signatures of this form.
101  */
102
103 static unsigned char sha1_nn_bin[] = {
104   0x30, 0x1f, 0x30, 0x07, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x04,
105   0x14
106 };
107
108 static unsigned char sha224_nn_bin[] = {
109   0x30, 0x2b, 0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03,
110   0x04, 0x02, 0x04, 0x04, 0x1c
111 };
112
113 static unsigned char sha256_nn_bin[] = {
114   0x30, 0x2f, 0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03,
115   0x04, 0x02, 0x01, 0x04, 0x20
116 };
117
118 static unsigned char sha384_nn_bin[] = {
119   0x30, 0x3f, 0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03,
120   0x04, 0x02, 0x02, 0x04, 0x30
121 };
122
123 static unsigned char sha512_nn_bin[] = {
124   0x30, 0x4f, 0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03,
125   0x04, 0x02, 0x03, 0x04, 0x40
126 };
127
128
129 static const unsigned char *fips_digestinfo_encoding(int nid, unsigned int *len)
130         {
131         switch (nid)
132                 {
133
134                 case NID_sha1:
135                 *len = sizeof(sha1_bin);
136                 return sha1_bin;
137
138                 case NID_sha224:
139                 *len = sizeof(sha224_bin);
140                 return sha224_bin;
141
142                 case NID_sha256:
143                 *len = sizeof(sha256_bin);
144                 return sha256_bin;
145
146                 case NID_sha384:
147                 *len = sizeof(sha384_bin);
148                 return sha384_bin;
149
150                 case NID_sha512:
151                 *len = sizeof(sha512_bin);
152                 return sha512_bin;
153
154                 default:
155                 return NULL;
156
157                 }
158         }
159
160 static const unsigned char *fips_digestinfo_nn_encoding(int nid, unsigned int *len)
161         {
162         switch (nid)
163                 {
164
165                 case NID_sha1:
166                 *len = sizeof(sha1_nn_bin);
167                 return sha1_nn_bin;
168
169                 case NID_sha224:
170                 *len = sizeof(sha224_nn_bin);
171                 return sha224_nn_bin;
172
173                 case NID_sha256:
174                 *len = sizeof(sha256_nn_bin);
175                 return sha256_nn_bin;
176
177                 case NID_sha384:
178                 *len = sizeof(sha384_nn_bin);
179                 return sha384_nn_bin;
180
181                 case NID_sha512:
182                 *len = sizeof(sha512_nn_bin);
183                 return sha512_nn_bin;
184
185                 default:
186                 return NULL;
187
188                 }
189         }
190
191 static int fips_rsa_sign(int type, const unsigned char *x, unsigned int y,
192              unsigned char *sigret, unsigned int *siglen, EVP_MD_SVCTX *sv)
193         {
194         int i=0,j,ret=0;
195         unsigned int dlen;
196         const unsigned char *der;
197         unsigned int m_len;
198         int pad_mode = sv->mctx->flags & EVP_MD_CTX_FLAG_PAD_MASK;
199         int rsa_pad_mode = 0;
200         RSA *rsa = sv->key;
201         /* Largest DigestInfo: 19 (max encoding) + max MD */
202         unsigned char tmpdinfo[19 + EVP_MAX_MD_SIZE];
203         unsigned char md[EVP_MAX_MD_SIZE + 1];
204
205         EVP_DigestFinal_ex(sv->mctx, md, &m_len);
206
207         if((rsa->flags & RSA_FLAG_SIGN_VER) && rsa->meth->rsa_sign)
208                 {
209                 ret = rsa->meth->rsa_sign(type, md, m_len,
210                         sigret, siglen, rsa);
211                 goto done;
212                 }
213
214         if (pad_mode == EVP_MD_CTX_FLAG_PAD_X931)
215                 {
216                 int hash_id;
217                 memcpy(tmpdinfo, md, m_len);
218                 hash_id = RSA_X931_hash_id(M_EVP_MD_CTX_type(sv->mctx));
219                 if (hash_id == -1)
220                         {
221                         RSAerr(RSA_F_FIPS_RSA_SIGN,RSA_R_UNKNOWN_ALGORITHM_TYPE);
222                         return 0;
223                         }
224                 tmpdinfo[m_len] = (unsigned char)hash_id;
225                 i = m_len + 1;
226                 rsa_pad_mode = RSA_X931_PADDING;
227                 }
228         else if (pad_mode == EVP_MD_CTX_FLAG_PAD_PKCS1)
229                 {
230
231                 der = fips_digestinfo_encoding(type, &dlen);
232                 
233                 if (!der)
234                         {
235                         RSAerr(RSA_F_FIPS_RSA_SIGN,RSA_R_UNKNOWN_ALGORITHM_TYPE);
236                         return 0;
237                         }
238                 memcpy(tmpdinfo, der, dlen);
239                 memcpy(tmpdinfo + dlen, md, m_len);
240
241                 i = dlen + m_len;
242                 rsa_pad_mode = RSA_PKCS1_PADDING;
243
244                 }
245         else if (pad_mode == EVP_MD_CTX_FLAG_PAD_PSS)
246                 {
247                 unsigned char *sbuf;
248                 int saltlen;
249                 i = RSA_size(rsa);
250                 sbuf = OPENSSL_malloc(RSA_size(rsa));
251                 saltlen = M_EVP_MD_CTX_FLAG_PSS_SALT(sv->mctx);
252                 if (saltlen == EVP_MD_CTX_FLAG_PSS_MDLEN)
253                         saltlen = -1;
254                 else if (saltlen == EVP_MD_CTX_FLAG_PSS_MREC)
255                         saltlen = -2;
256                 if (!sbuf)
257                         {
258                         RSAerr(RSA_F_FIPS_RSA_SIGN,ERR_R_MALLOC_FAILURE);
259                         goto psserr;
260                         }
261                 if (!RSA_padding_add_PKCS1_PSS(rsa, sbuf, md,
262                                         M_EVP_MD_CTX_md(sv->mctx), saltlen))
263                         goto psserr;
264                 j=rsa->meth->rsa_priv_enc(i,sbuf,sigret,rsa,RSA_NO_PADDING);
265                 if (j > 0)
266                         {
267                         ret=1;
268                         *siglen=j;
269                         }
270                 psserr:
271                 OPENSSL_cleanse(md,m_len);
272                 OPENSSL_cleanse(sbuf, i);
273                 OPENSSL_free(sbuf);
274                 return ret;
275                 }
276
277         j=RSA_size(rsa);
278         if (i > (j-RSA_PKCS1_PADDING_SIZE))
279                 {
280                 RSAerr(RSA_F_FIPS_RSA_SIGN,RSA_R_DIGEST_TOO_BIG_FOR_RSA_KEY);
281                 goto done;
282                 }
283         /* NB: call underlying method directly to avoid FIPS blocking */
284         j=rsa->meth->rsa_priv_enc(i,tmpdinfo,sigret,rsa,rsa_pad_mode);
285         if (j > 0)
286                 {
287                 ret=1;
288                 *siglen=j;
289                 }
290
291         done:
292         OPENSSL_cleanse(tmpdinfo,i);
293         OPENSSL_cleanse(md,m_len);
294         return ret;
295         }
296
297 static int fips_rsa_verify(int dtype,
298                 const unsigned char *x, unsigned int y,
299                 unsigned char *sigbuf, unsigned int siglen, EVP_MD_SVCTX *sv)
300         {
301         int i,ret=0;
302         unsigned int dlen, diglen;
303         int pad_mode = sv->mctx->flags & EVP_MD_CTX_FLAG_PAD_MASK;
304         int rsa_pad_mode = 0;
305         unsigned char *s;
306         const unsigned char *der;
307         unsigned char dig[EVP_MAX_MD_SIZE];
308         RSA *rsa = sv->key;
309
310         if (siglen != (unsigned int)RSA_size(sv->key))
311                 {
312                 RSAerr(RSA_F_FIPS_RSA_VERIFY,RSA_R_WRONG_SIGNATURE_LENGTH);
313                 return(0);
314                 }
315
316         EVP_DigestFinal_ex(sv->mctx, dig, &diglen);
317
318         if((rsa->flags & RSA_FLAG_SIGN_VER) && rsa->meth->rsa_verify)
319                 {
320                 return rsa->meth->rsa_verify(dtype, dig, diglen,
321                         sigbuf, siglen, rsa);
322                 }
323
324
325         s= OPENSSL_malloc((unsigned int)siglen);
326         if (s == NULL)
327                 {
328                 RSAerr(RSA_F_FIPS_RSA_VERIFY,ERR_R_MALLOC_FAILURE);
329                 goto err;
330                 }
331         if (pad_mode == EVP_MD_CTX_FLAG_PAD_X931)
332                 rsa_pad_mode = RSA_X931_PADDING;
333         else if (pad_mode == EVP_MD_CTX_FLAG_PAD_PKCS1)
334                 rsa_pad_mode = RSA_PKCS1_PADDING;
335         else if (pad_mode == EVP_MD_CTX_FLAG_PAD_PSS)
336                 rsa_pad_mode = RSA_NO_PADDING;
337
338         /* NB: call underlying method directly to avoid FIPS blocking */
339         i=rsa->meth->rsa_pub_dec((int)siglen,sigbuf,s, rsa, rsa_pad_mode);
340
341         if (i <= 0) goto err;
342
343         if (pad_mode == EVP_MD_CTX_FLAG_PAD_X931)
344                 {
345                 int hash_id;
346                 if (i != (int)(diglen + 1))
347                         {
348                         RSAerr(RSA_F_FIPS_RSA_VERIFY,RSA_R_BAD_SIGNATURE);
349                         goto err;
350                         }
351                 hash_id = RSA_X931_hash_id(M_EVP_MD_CTX_type(sv->mctx));
352                 if (hash_id == -1)
353                         {
354                         RSAerr(RSA_F_FIPS_RSA_VERIFY,RSA_R_UNKNOWN_ALGORITHM_TYPE);
355                         goto err;
356                         }
357                 if (s[diglen] != (unsigned char)hash_id)
358                         {
359                         RSAerr(RSA_F_FIPS_RSA_VERIFY,RSA_R_BAD_SIGNATURE);
360                         goto err;
361                         }
362                 if (memcmp(s, dig, diglen))
363                         {
364                         RSAerr(RSA_F_FIPS_RSA_VERIFY,RSA_R_BAD_SIGNATURE);
365                         goto err;
366                         }
367                 ret = 1;
368                 }
369         else if (pad_mode == EVP_MD_CTX_FLAG_PAD_PKCS1)
370                 {
371
372                 der = fips_digestinfo_encoding(dtype, &dlen);
373                 
374                 if (!der)
375                         {
376                         RSAerr(RSA_F_FIPS_RSA_VERIFY,RSA_R_UNKNOWN_ALGORITHM_TYPE);
377                         return(0);
378                         }
379
380                 /* Compare, DigestInfo length, DigestInfo header and finally
381                  * digest value itself
382                  */
383
384                 /* If length mismatch try alternate encoding */
385                 if (i != (int)(dlen + diglen))
386                         der = fips_digestinfo_nn_encoding(dtype, &dlen);
387
388                 if ((i != (int)(dlen + diglen)) || memcmp(der, s, dlen)
389                         || memcmp(s + dlen, dig, diglen))
390                         {
391                         RSAerr(RSA_F_FIPS_RSA_VERIFY,RSA_R_BAD_SIGNATURE);
392                         goto err;
393                         }
394                 ret = 1;
395
396                 }
397         else if (pad_mode == EVP_MD_CTX_FLAG_PAD_PSS)
398                 {
399                 int saltlen;
400                 saltlen = M_EVP_MD_CTX_FLAG_PSS_SALT(sv->mctx);
401                 if (saltlen == EVP_MD_CTX_FLAG_PSS_MDLEN)
402                         saltlen = -1;
403                 else if (saltlen == EVP_MD_CTX_FLAG_PSS_MREC)
404                         saltlen = -2;
405                 ret = RSA_verify_PKCS1_PSS(rsa, dig, M_EVP_MD_CTX_md(sv->mctx),
406                                                 s, saltlen);
407                 if (ret < 0)
408                         ret = 0;
409                 }
410 err:
411         if (s != NULL)
412                 {
413                 OPENSSL_cleanse(s, siglen);
414                 OPENSSL_free(s);
415                 }
416         return(ret);
417         }
418
419 #define EVP_PKEY_RSA_fips_method \
420                                 (evp_sign_method *)fips_rsa_sign, \
421                                 (evp_verify_method *)fips_rsa_verify, \
422                                 {EVP_PKEY_RSA,EVP_PKEY_RSA2,0,0}
423
424 static int init(EVP_MD_CTX *ctx)
425         { return SHA1_Init(ctx->md_data); }
426
427 static int update(EVP_MD_CTX *ctx,const void *data,size_t count)
428         { return SHA1_Update(ctx->md_data,data,count); }
429
430 static int final(EVP_MD_CTX *ctx,unsigned char *md)
431         { return SHA1_Final(md,ctx->md_data); }
432
433 static const EVP_MD sha1_md=
434         {
435         NID_sha1,
436         NID_sha1WithRSAEncryption,
437         SHA_DIGEST_LENGTH,
438         EVP_MD_FLAG_FIPS|EVP_MD_FLAG_SVCTX,
439         init,
440         update,
441         final,
442         NULL,
443         NULL,
444         EVP_PKEY_RSA_fips_method,
445         SHA_CBLOCK,
446         sizeof(EVP_MD *)+sizeof(SHA_CTX),
447         };
448
449 const EVP_MD *EVP_sha1(void)
450         {
451         return(&sha1_md);
452         }
453
454 static int init224(EVP_MD_CTX *ctx)
455         { return SHA224_Init(ctx->md_data); }
456 static int init256(EVP_MD_CTX *ctx)
457         { return SHA256_Init(ctx->md_data); }
458 /*
459  * Even though there're separate SHA224_[Update|Final], we call
460  * SHA256 functions even in SHA224 context. This is what happens
461  * there anyway, so we can spare few CPU cycles:-)
462  */
463 static int update256(EVP_MD_CTX *ctx,const void *data,size_t count)
464         { return SHA256_Update(ctx->md_data,data,count); }
465 static int final256(EVP_MD_CTX *ctx,unsigned char *md)
466         { return SHA256_Final(md,ctx->md_data); }
467
468 static const EVP_MD sha224_md=
469         {
470         NID_sha224,
471         NID_sha224WithRSAEncryption,
472         SHA224_DIGEST_LENGTH,
473         EVP_MD_FLAG_FIPS|EVP_MD_FLAG_SVCTX,
474         init224,
475         update256,
476         final256,
477         NULL,
478         NULL,
479         EVP_PKEY_RSA_fips_method,
480         SHA256_CBLOCK,
481         sizeof(EVP_MD *)+sizeof(SHA256_CTX),
482         };
483
484 const EVP_MD *EVP_sha224(void)
485         { return(&sha224_md); }
486
487 static const EVP_MD sha256_md=
488         {
489         NID_sha256,
490         NID_sha256WithRSAEncryption,
491         SHA256_DIGEST_LENGTH,
492         EVP_MD_FLAG_FIPS|EVP_MD_FLAG_SVCTX,
493         init256,
494         update256,
495         final256,
496         NULL,
497         NULL,
498         EVP_PKEY_RSA_fips_method,
499         SHA256_CBLOCK,
500         sizeof(EVP_MD *)+sizeof(SHA256_CTX),
501         };
502
503 const EVP_MD *EVP_sha256(void)
504         { return(&sha256_md); }
505
506 static int init384(EVP_MD_CTX *ctx)
507         { return SHA384_Init(ctx->md_data); }
508 static int init512(EVP_MD_CTX *ctx)
509         { return SHA512_Init(ctx->md_data); }
510 /* See comment in SHA224/256 section */
511 static int update512(EVP_MD_CTX *ctx,const void *data,size_t count)
512         { return SHA512_Update(ctx->md_data,data,count); }
513 static int final512(EVP_MD_CTX *ctx,unsigned char *md)
514         { return SHA512_Final(md,ctx->md_data); }
515
516 static const EVP_MD sha384_md=
517         {
518         NID_sha384,
519         NID_sha384WithRSAEncryption,
520         SHA384_DIGEST_LENGTH,
521         EVP_MD_FLAG_FIPS|EVP_MD_FLAG_SVCTX,
522         init384,
523         update512,
524         final512,
525         NULL,
526         NULL,
527         EVP_PKEY_RSA_fips_method,
528         SHA512_CBLOCK,
529         sizeof(EVP_MD *)+sizeof(SHA512_CTX),
530         };
531
532 const EVP_MD *EVP_sha384(void)
533         { return(&sha384_md); }
534
535 static const EVP_MD sha512_md=
536         {
537         NID_sha512,
538         NID_sha512WithRSAEncryption,
539         SHA512_DIGEST_LENGTH,
540         EVP_MD_FLAG_FIPS|EVP_MD_FLAG_SVCTX,
541         init512,
542         update512,
543         final512,
544         NULL,
545         NULL,
546         EVP_PKEY_RSA_fips_method,
547         SHA512_CBLOCK,
548         sizeof(EVP_MD *)+sizeof(SHA512_CTX),
549         };
550
551 const EVP_MD *EVP_sha512(void)
552         { return(&sha512_md); }
553
554 #endif