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