Check i before r[i].
[openssl.git] / 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 #define OPENSSL_FIPSAPI
60
61 #include <string.h>
62 #include <openssl/evp.h>
63 #include <openssl/rsa.h>
64 #include <openssl/err.h>
65 #include <openssl/sha.h>
66 #include <openssl/fips.h>
67
68 #ifdef OPENSSL_FIPS
69
70 /* FIPS versions of RSA_sign() and RSA_verify().
71  * These will only have to deal with SHA* signatures and by including
72  * pregenerated encodings all ASN1 dependencies can be avoided
73  */
74
75 /* Standard encodings including NULL parameter */
76
77 __fips_constseg
78 static const unsigned char sha1_bin[] = {
79   0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x05,
80   0x00, 0x04, 0x14
81 };
82
83 __fips_constseg
84 static const unsigned char sha224_bin[] = {
85   0x30, 0x2d, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03,
86   0x04, 0x02, 0x04, 0x05, 0x00, 0x04, 0x1c
87 };
88
89 __fips_constseg
90 static const unsigned char sha256_bin[] = {
91   0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03,
92   0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20
93 };
94
95 __fips_constseg
96 static const unsigned char sha384_bin[] = {
97   0x30, 0x41, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03,
98   0x04, 0x02, 0x02, 0x05, 0x00, 0x04, 0x30
99 };
100
101 __fips_constseg
102 static const unsigned char sha512_bin[] = {
103   0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03,
104   0x04, 0x02, 0x03, 0x05, 0x00, 0x04, 0x40
105 };
106
107 /* Alternate encodings with absent parameters. We don't generate signature
108  * using this format but do tolerate received signatures of this form.
109  */
110
111 __fips_constseg
112 static const unsigned char sha1_nn_bin[] = {
113   0x30, 0x1f, 0x30, 0x07, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x04,
114   0x14
115 };
116
117 __fips_constseg
118 static const unsigned char sha224_nn_bin[] = {
119   0x30, 0x2b, 0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03,
120   0x04, 0x02, 0x04, 0x04, 0x1c
121 };
122
123 __fips_constseg
124 static const unsigned char sha256_nn_bin[] = {
125   0x30, 0x2f, 0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03,
126   0x04, 0x02, 0x01, 0x04, 0x20
127 };
128
129 __fips_constseg
130 static const unsigned char sha384_nn_bin[] = {
131   0x30, 0x3f, 0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03,
132   0x04, 0x02, 0x02, 0x04, 0x30
133 };
134
135 __fips_constseg
136 static const unsigned char sha512_nn_bin[] = {
137   0x30, 0x4f, 0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03,
138   0x04, 0x02, 0x03, 0x04, 0x40
139 };
140
141
142 static const unsigned char *fips_digestinfo_encoding(int nid, unsigned int *len)
143         {
144         switch (nid)
145                 {
146
147                 case NID_sha1:
148                 *len = sizeof(sha1_bin);
149                 return sha1_bin;
150
151                 case NID_sha224:
152                 *len = sizeof(sha224_bin);
153                 return sha224_bin;
154
155                 case NID_sha256:
156                 *len = sizeof(sha256_bin);
157                 return sha256_bin;
158
159                 case NID_sha384:
160                 *len = sizeof(sha384_bin);
161                 return sha384_bin;
162
163                 case NID_sha512:
164                 *len = sizeof(sha512_bin);
165                 return sha512_bin;
166
167                 default:
168                 return NULL;
169
170                 }
171         }
172
173 static const unsigned char *fips_digestinfo_nn_encoding(int nid, unsigned int *len)
174         {
175         switch (nid)
176                 {
177
178                 case NID_sha1:
179                 *len = sizeof(sha1_nn_bin);
180                 return sha1_nn_bin;
181
182                 case NID_sha224:
183                 *len = sizeof(sha224_nn_bin);
184                 return sha224_nn_bin;
185
186                 case NID_sha256:
187                 *len = sizeof(sha256_nn_bin);
188                 return sha256_nn_bin;
189
190                 case NID_sha384:
191                 *len = sizeof(sha384_nn_bin);
192                 return sha384_nn_bin;
193
194                 case NID_sha512:
195                 *len = sizeof(sha512_nn_bin);
196                 return sha512_nn_bin;
197
198                 default:
199                 return NULL;
200
201                 }
202         }
203
204 int FIPS_rsa_sign_ctx(RSA *rsa, EVP_MD_CTX *ctx,
205                         int rsa_pad_mode, int saltlen, const EVP_MD *mgf1Hash,
206                         unsigned char *sigret, unsigned int *siglen)
207         {
208         unsigned int md_len, rv;
209         unsigned char md[EVP_MAX_MD_SIZE];
210         FIPS_digestfinal(ctx, md, &md_len);
211         rv = FIPS_rsa_sign_digest(rsa, md, md_len,
212                                         M_EVP_MD_CTX_md(ctx),
213                                         rsa_pad_mode, saltlen,
214                                         mgf1Hash, sigret, siglen);
215         OPENSSL_cleanse(md, md_len);
216         return rv;
217         }
218
219
220 int FIPS_rsa_sign_digest(RSA *rsa, const unsigned char *md, int md_len,
221                         const EVP_MD *mhash, int rsa_pad_mode, int saltlen,
222                         const EVP_MD *mgf1Hash,
223                         unsigned char *sigret, unsigned int *siglen)
224         {
225         int i=0,j,ret=0;
226         unsigned int dlen;
227         const unsigned char *der;
228         int md_type;
229         /* Largest DigestInfo: 19 (max encoding) + max MD */
230         unsigned char tmpdinfo[19 + EVP_MAX_MD_SIZE];
231
232         if (FIPS_selftest_failed())
233                 {
234                 FIPSerr(FIPS_F_FIPS_RSA_SIGN_DIGEST, FIPS_R_SELFTEST_FAILED);
235                 return 0;
236                 }
237         if (!mhash && rsa_pad_mode == RSA_PKCS1_PADDING)
238                 md_type = saltlen;
239         else
240                 md_type = M_EVP_MD_type(mhash);
241
242         if (rsa_pad_mode == RSA_X931_PADDING)
243                 {
244                 int hash_id;
245                 memcpy(tmpdinfo, md, md_len);
246                 hash_id = RSA_X931_hash_id(md_type);
247                 if (hash_id == -1)
248                         {
249                         RSAerr(RSA_F_FIPS_RSA_SIGN_DIGEST,RSA_R_UNKNOWN_ALGORITHM_TYPE);
250                         return 0;
251                         }
252                 tmpdinfo[md_len] = (unsigned char)hash_id;
253                 i = md_len + 1;
254                 }
255         else if (rsa_pad_mode == RSA_PKCS1_PADDING)
256                 {
257
258                 der = fips_digestinfo_encoding(md_type, &dlen);
259                 
260                 if (!der)
261                         {
262                         RSAerr(RSA_F_FIPS_RSA_SIGN_DIGEST,RSA_R_UNKNOWN_ALGORITHM_TYPE);
263                         return 0;
264                         }
265                 memcpy(tmpdinfo, der, dlen);
266                 memcpy(tmpdinfo + dlen, md, md_len);
267
268                 i = dlen + md_len;
269
270                 }
271         else if (rsa_pad_mode == RSA_PKCS1_PSS_PADDING)
272                 {
273                 unsigned char *sbuf;
274                 i = RSA_size(rsa);
275                 sbuf = OPENSSL_malloc(RSA_size(rsa));
276                 if (!sbuf)
277                         {
278                         RSAerr(RSA_F_FIPS_RSA_SIGN_DIGEST,ERR_R_MALLOC_FAILURE);
279                         goto psserr;
280                         }
281                 if (!RSA_padding_add_PKCS1_PSS_mgf1(rsa, sbuf, md, mhash, 
282                                                         mgf1Hash, saltlen))
283                         goto psserr;
284                 j=rsa->meth->rsa_priv_enc(i,sbuf,sigret,rsa,RSA_NO_PADDING);
285                 if (j > 0)
286                         {
287                         ret=1;
288                         *siglen=j;
289                         }
290                 psserr:
291                 OPENSSL_cleanse(sbuf, i);
292                 OPENSSL_free(sbuf);
293                 return ret;
294                 }
295
296         j=RSA_size(rsa);
297         if (i > (j-RSA_PKCS1_PADDING_SIZE))
298                 {
299                 RSAerr(RSA_F_FIPS_RSA_SIGN_DIGEST,RSA_R_DIGEST_TOO_BIG_FOR_RSA_KEY);
300                 goto done;
301                 }
302         /* NB: call underlying method directly to avoid FIPS blocking */
303         j=rsa->meth->rsa_priv_enc(i,tmpdinfo,sigret,rsa,rsa_pad_mode);
304         if (j > 0)
305                 {
306                 ret=1;
307                 *siglen=j;
308                 }
309
310         done:
311         OPENSSL_cleanse(tmpdinfo,i);
312         return ret;
313         }
314
315 int FIPS_rsa_verify_ctx(RSA *rsa, EVP_MD_CTX *ctx,
316                         int rsa_pad_mode, int saltlen, const EVP_MD *mgf1Hash,
317                         const unsigned char *sigbuf, unsigned int siglen)
318         {
319         unsigned int md_len, rv;
320         unsigned char md[EVP_MAX_MD_SIZE];
321         FIPS_digestfinal(ctx, md, &md_len);
322         rv = FIPS_rsa_verify_digest(rsa, md, md_len, M_EVP_MD_CTX_md(ctx),
323                                         rsa_pad_mode, saltlen, mgf1Hash,
324                                         sigbuf, siglen);
325         OPENSSL_cleanse(md, md_len);
326         return rv;
327         }
328         
329 int FIPS_rsa_verify_digest(RSA *rsa, const unsigned char *dig, int diglen,
330                         const EVP_MD *mhash, int rsa_pad_mode, int saltlen,
331                         const EVP_MD *mgf1Hash,
332                         const unsigned char *sigbuf, unsigned int siglen)
333         {
334         int i,ret=0;
335         unsigned int dlen;
336         unsigned char *s;
337         const unsigned char *der;
338         int md_type;
339         int rsa_dec_pad_mode;
340
341         if (FIPS_selftest_failed())
342                 {
343                 FIPSerr(FIPS_F_FIPS_RSA_VERIFY_DIGEST, FIPS_R_SELFTEST_FAILED);
344                 return 0;
345                 }
346
347         if (siglen != (unsigned int)RSA_size(rsa))
348                 {
349                 RSAerr(RSA_F_FIPS_RSA_VERIFY_DIGEST,RSA_R_WRONG_SIGNATURE_LENGTH);
350                 return(0);
351                 }
352
353         if (!mhash && rsa_pad_mode == RSA_PKCS1_PADDING)
354                 md_type = saltlen;
355         else
356                 md_type = M_EVP_MD_type(mhash);
357
358         s= OPENSSL_malloc((unsigned int)siglen);
359         if (s == NULL)
360                 {
361                 RSAerr(RSA_F_FIPS_RSA_VERIFY_DIGEST,ERR_R_MALLOC_FAILURE);
362                 goto err;
363                 }
364
365         if (rsa_pad_mode == RSA_PKCS1_PSS_PADDING)
366                 rsa_dec_pad_mode = RSA_NO_PADDING;
367         else
368                 rsa_dec_pad_mode = rsa_pad_mode;
369
370         /* NB: call underlying method directly to avoid FIPS blocking */
371         i=rsa->meth->rsa_pub_dec((int)siglen,sigbuf,s, rsa, rsa_dec_pad_mode);
372
373         if (i <= 0) goto err;
374
375         if (rsa_pad_mode == RSA_X931_PADDING)
376                 {
377                 int hash_id;
378                 if (i != (int)(diglen + 1))
379                         {
380                         RSAerr(RSA_F_FIPS_RSA_VERIFY_DIGEST,RSA_R_BAD_SIGNATURE);
381                         goto err;
382                         }
383                 hash_id = RSA_X931_hash_id(md_type);
384                 if (hash_id == -1)
385                         {
386                         RSAerr(RSA_F_FIPS_RSA_VERIFY_DIGEST,RSA_R_UNKNOWN_ALGORITHM_TYPE);
387                         goto err;
388                         }
389                 if (s[diglen] != (unsigned char)hash_id)
390                         {
391                         RSAerr(RSA_F_FIPS_RSA_VERIFY_DIGEST,RSA_R_BAD_SIGNATURE);
392                         goto err;
393                         }
394                 if (memcmp(s, dig, diglen))
395                         {
396                         RSAerr(RSA_F_FIPS_RSA_VERIFY_DIGEST,RSA_R_BAD_SIGNATURE);
397                         goto err;
398                         }
399                 ret = 1;
400                 }
401         else if (rsa_pad_mode == RSA_PKCS1_PADDING)
402                 {
403
404                 der = fips_digestinfo_encoding(md_type, &dlen);
405                 
406                 if (!der)
407                         {
408                         RSAerr(RSA_F_FIPS_RSA_VERIFY_DIGEST,RSA_R_UNKNOWN_ALGORITHM_TYPE);
409                         return(0);
410                         }
411
412                 /* Compare, DigestInfo length, DigestInfo header and finally
413                  * digest value itself
414                  */
415
416                 /* If length mismatch try alternate encoding */
417                 if (i != (int)(dlen + diglen))
418                         der = fips_digestinfo_nn_encoding(md_type, &dlen);
419
420                 if ((i != (int)(dlen + diglen)) || memcmp(der, s, dlen)
421                         || memcmp(s + dlen, dig, diglen))
422                         {
423                         RSAerr(RSA_F_FIPS_RSA_VERIFY_DIGEST,RSA_R_BAD_SIGNATURE);
424                         goto err;
425                         }
426                 ret = 1;
427
428                 }
429         else if (rsa_pad_mode == RSA_PKCS1_PSS_PADDING)
430                 {
431                 ret = RSA_verify_PKCS1_PSS_mgf1(rsa, dig, mhash, mgf1Hash,
432                                                 s, saltlen);
433                 if (ret < 0)
434                         ret = 0;
435                 }
436 err:
437         if (s != NULL)
438                 {
439                 OPENSSL_cleanse(s, siglen);
440                 OPENSSL_free(s);
441                 }
442         return(ret);
443         }
444
445 int FIPS_rsa_sign(RSA *rsa, const unsigned char *msg, int msglen,
446                         const EVP_MD *mhash, int rsa_pad_mode, int saltlen,
447                         const EVP_MD *mgf1Hash,
448                         unsigned char *sigret, unsigned int *siglen)
449         {
450         unsigned int md_len, rv;
451         unsigned char md[EVP_MAX_MD_SIZE];
452         FIPS_digest(msg, msglen, md, &md_len, mhash);
453         rv = FIPS_rsa_sign_digest(rsa, md, md_len, mhash, rsa_pad_mode,
454                                         saltlen, mgf1Hash, sigret, siglen);
455         OPENSSL_cleanse(md, md_len);
456         return rv;
457         }
458
459
460 int FIPS_rsa_verify(RSA *rsa, const unsigned char *msg, int msglen,
461                         const EVP_MD *mhash, int rsa_pad_mode, int saltlen,
462                         const EVP_MD *mgf1Hash,
463                         const unsigned char *sigbuf, unsigned int siglen)
464         {
465         unsigned int md_len, rv;
466         unsigned char md[EVP_MAX_MD_SIZE];
467         FIPS_digest(msg, msglen, md, &md_len, mhash);
468         rv = FIPS_rsa_verify_digest(rsa, md, md_len, mhash, rsa_pad_mode,
469                                         saltlen, mgf1Hash, sigbuf, siglen);
470         OPENSSL_cleanse(md, md_len);
471         return rv;
472         }
473
474 #endif