]> git.ipfire.org Git - thirdparty/openssl.git/blame - fips/rsa/fips_rsa_sign.c
Run util/openssl-format-source -v -c .
[thirdparty/openssl.git] / fips / rsa / fips_rsa_sign.c
CommitLineData
59f3477b 1/* fips_rsa_sign.c */
40720ce3
MC
2/*
3 * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
4 * 2007.
59f3477b
DSH
5 */
6/* ====================================================================
7 * Copyright (c) 2007 The OpenSSL Project. All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 *
13 * 1. Redistributions of source code must retain the above copyright
40720ce3 14 * notice, this list of conditions and the following disclaimer.
59f3477b
DSH
15 *
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in
18 * the documentation and/or other materials provided with the
19 * distribution.
20 *
21 * 3. All advertising materials mentioning features or use of this
22 * software must display the following acknowledgment:
23 * "This product includes software developed by the OpenSSL Project
24 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
25 *
26 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
27 * endorse or promote products derived from this software without
28 * prior written permission. For written permission, please contact
29 * licensing@OpenSSL.org.
30 *
31 * 5. Products derived from this software may not be called "OpenSSL"
32 * nor may "OpenSSL" appear in their names without prior written
33 * permission of the OpenSSL Project.
34 *
35 * 6. Redistributions of any form whatsoever must retain the following
36 * acknowledgment:
37 * "This product includes software developed by the OpenSSL Project
38 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
39 *
40 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
41 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
42 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
43 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
44 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
45 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
46 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
47 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
49 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
50 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
51 * OF THE POSSIBILITY OF SUCH DAMAGE.
52 * ====================================================================
53 *
54 * This product includes cryptographic software written by Eric Young
55 * (eay@cryptsoft.com). This product includes software written by Tim
56 * Hudson (tjh@cryptsoft.com).
57 *
58 */
59
60#include <string.h>
61#include <openssl/evp.h>
62#include <openssl/rsa.h>
63#include <openssl/err.h>
64#include <openssl/sha.h>
65
66#ifdef OPENSSL_FIPS
67
40720ce3
MC
68/*
69 * FIPS versions of RSA_sign() and RSA_verify(). These will only have to deal
70 * with SHA* signatures and by including pregenerated encodings all ASN1
71 * dependencies can be avoided
59f3477b
DSH
72 */
73
74/* Standard encodings including NULL parameter */
75
76static const unsigned char sha1_bin[] = {
40720ce3
MC
77 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x05,
78 0x00, 0x04, 0x14
59f3477b
DSH
79};
80
81static const unsigned char sha224_bin[] = {
40720ce3
MC
82 0x30, 0x2d, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03,
83 0x04, 0x02, 0x04, 0x05, 0x00, 0x04, 0x1c
59f3477b
DSH
84};
85
86static const unsigned char sha256_bin[] = {
40720ce3
MC
87 0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03,
88 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20
59f3477b
DSH
89};
90
91static const unsigned char sha384_bin[] = {
40720ce3
MC
92 0x30, 0x41, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03,
93 0x04, 0x02, 0x02, 0x05, 0x00, 0x04, 0x30
59f3477b
DSH
94};
95
96static const unsigned char sha512_bin[] = {
40720ce3
MC
97 0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03,
98 0x04, 0x02, 0x03, 0x05, 0x00, 0x04, 0x40
59f3477b
DSH
99};
100
40720ce3
MC
101/*
102 * Alternate encodings with absent parameters. We don't generate signature
59f3477b
DSH
103 * using this format but do tolerate received signatures of this form.
104 */
105
106static unsigned char sha1_nn_bin[] = {
40720ce3
MC
107 0x30, 0x1f, 0x30, 0x07, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x04,
108 0x14
59f3477b
DSH
109};
110
111static unsigned char sha224_nn_bin[] = {
40720ce3
MC
112 0x30, 0x2b, 0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03,
113 0x04, 0x02, 0x04, 0x04, 0x1c
59f3477b
DSH
114};
115
116static unsigned char sha256_nn_bin[] = {
40720ce3
MC
117 0x30, 0x2f, 0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03,
118 0x04, 0x02, 0x01, 0x04, 0x20
59f3477b
DSH
119};
120
121static unsigned char sha384_nn_bin[] = {
40720ce3
MC
122 0x30, 0x3f, 0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03,
123 0x04, 0x02, 0x02, 0x04, 0x30
59f3477b
DSH
124};
125
126static unsigned char sha512_nn_bin[] = {
40720ce3
MC
127 0x30, 0x4f, 0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03,
128 0x04, 0x02, 0x03, 0x04, 0x40
59f3477b
DSH
129};
130
40720ce3
MC
131static const unsigned char *fips_digestinfo_encoding(int nid,
132 unsigned int *len)
133{
134 switch (nid) {
59f3477b 135
40720ce3
MC
136 case NID_sha1:
137 *len = sizeof(sha1_bin);
138 return sha1_bin;
59f3477b 139
40720ce3
MC
140 case NID_sha224:
141 *len = sizeof(sha224_bin);
142 return sha224_bin;
59f3477b 143
40720ce3
MC
144 case NID_sha256:
145 *len = sizeof(sha256_bin);
146 return sha256_bin;
59f3477b 147
40720ce3
MC
148 case NID_sha384:
149 *len = sizeof(sha384_bin);
150 return sha384_bin;
59f3477b 151
40720ce3
MC
152 case NID_sha512:
153 *len = sizeof(sha512_bin);
154 return sha512_bin;
59f3477b 155
40720ce3
MC
156 default:
157 return NULL;
59f3477b 158
40720ce3
MC
159 }
160}
59f3477b 161
40720ce3
MC
162static const unsigned char *fips_digestinfo_nn_encoding(int nid,
163 unsigned int *len)
164{
165 switch (nid) {
59f3477b 166
40720ce3
MC
167 case NID_sha1:
168 *len = sizeof(sha1_nn_bin);
169 return sha1_nn_bin;
59f3477b 170
40720ce3
MC
171 case NID_sha224:
172 *len = sizeof(sha224_nn_bin);
173 return sha224_nn_bin;
59f3477b 174
40720ce3
MC
175 case NID_sha256:
176 *len = sizeof(sha256_nn_bin);
177 return sha256_nn_bin;
59f3477b 178
40720ce3
MC
179 case NID_sha384:
180 *len = sizeof(sha384_nn_bin);
181 return sha384_nn_bin;
59f3477b 182
40720ce3
MC
183 case NID_sha512:
184 *len = sizeof(sha512_nn_bin);
185 return sha512_nn_bin;
59f3477b 186
40720ce3
MC
187 default:
188 return NULL;
59f3477b 189
40720ce3
MC
190 }
191}
59f3477b
DSH
192
193static int fips_rsa_sign(int type, const unsigned char *x, unsigned int y,
40720ce3
MC
194 unsigned char *sigret, unsigned int *siglen,
195 EVP_MD_SVCTX * sv)
196{
197 int i = 0, j, ret = 0;
198 unsigned int dlen;
199 const unsigned char *der;
200 unsigned int m_len;
201 int pad_mode = sv->mctx->flags & EVP_MD_CTX_FLAG_PAD_MASK;
202 int rsa_pad_mode = 0;
203 RSA *rsa = sv->key;
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(sv->mctx, md, &m_len);
209
210 if ((rsa->flags & RSA_FLAG_SIGN_VER) && rsa->meth->rsa_sign) {
211 ret = rsa->meth->rsa_sign(type, md, m_len, sigret, siglen, rsa);
212 goto done;
213 }
214
215 if (pad_mode == EVP_MD_CTX_FLAG_PAD_X931) {
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 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 rsa_pad_mode = RSA_X931_PADDING;
226 } else if (pad_mode == EVP_MD_CTX_FLAG_PAD_PKCS1) {
227
228 der = fips_digestinfo_encoding(type, &dlen);
229
230 if (!der) {
231 RSAerr(RSA_F_FIPS_RSA_SIGN, RSA_R_UNKNOWN_ALGORITHM_TYPE);
232 return 0;
233 }
234 memcpy(tmpdinfo, der, dlen);
235 memcpy(tmpdinfo + dlen, md, m_len);
236
237 i = dlen + m_len;
238 rsa_pad_mode = RSA_PKCS1_PADDING;
239
240 } else if (pad_mode == EVP_MD_CTX_FLAG_PAD_PSS) {
241 unsigned char *sbuf;
242 int saltlen;
243 i = RSA_size(rsa);
244 sbuf = OPENSSL_malloc(RSA_size(rsa));
245 saltlen = M_EVP_MD_CTX_FLAG_PSS_SALT(sv->mctx);
246 if (saltlen == EVP_MD_CTX_FLAG_PSS_MDLEN)
247 saltlen = -1;
248 else if (saltlen == EVP_MD_CTX_FLAG_PSS_MREC)
249 saltlen = -2;
250 if (!sbuf) {
251 RSAerr(RSA_F_FIPS_RSA_SIGN, ERR_R_MALLOC_FAILURE);
252 goto psserr;
253 }
254 if (!RSA_padding_add_PKCS1_PSS(rsa, sbuf, md,
255 M_EVP_MD_CTX_md(sv->mctx), saltlen))
256 goto psserr;
257 j = rsa->meth->rsa_priv_enc(i, sbuf, sigret, rsa, RSA_NO_PADDING);
258 if (j > 0) {
259 ret = 1;
260 *siglen = j;
261 }
262 psserr:
263 OPENSSL_cleanse(md, m_len);
264 OPENSSL_cleanse(sbuf, i);
265 OPENSSL_free(sbuf);
266 return ret;
267 }
268
269 j = RSA_size(rsa);
270 if (i > (j - RSA_PKCS1_PADDING_SIZE)) {
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 ret = 1;
278 *siglen = j;
279 }
280
281 done:
282 OPENSSL_cleanse(tmpdinfo, i);
283 OPENSSL_cleanse(md, m_len);
284 return ret;
285}
59f3477b
DSH
286
287static int fips_rsa_verify(int dtype,
40720ce3
MC
288 const unsigned char *x, unsigned int y,
289 unsigned char *sigbuf, unsigned int siglen,
290 EVP_MD_SVCTX * sv)
291{
292 int i, ret = 0;
293 unsigned int dlen, diglen;
294 int pad_mode = sv->mctx->flags & EVP_MD_CTX_FLAG_PAD_MASK;
295 int rsa_pad_mode = 0;
296 unsigned char *s;
297 const unsigned char *der;
298 unsigned char dig[EVP_MAX_MD_SIZE];
299 RSA *rsa = sv->key;
300
301 if (siglen != (unsigned int)RSA_size(sv->key)) {
302 RSAerr(RSA_F_FIPS_RSA_VERIFY, RSA_R_WRONG_SIGNATURE_LENGTH);
303 return (0);
304 }
305
306 EVP_DigestFinal_ex(sv->mctx, dig, &diglen);
307
308 if ((rsa->flags & RSA_FLAG_SIGN_VER) && rsa->meth->rsa_verify) {
309 return rsa->meth->rsa_verify(dtype, dig, diglen, sigbuf, siglen, rsa);
310 }
311
312 s = OPENSSL_malloc((unsigned int)siglen);
313 if (s == NULL) {
314 RSAerr(RSA_F_FIPS_RSA_VERIFY, ERR_R_MALLOC_FAILURE);
315 goto err;
316 }
317 if (pad_mode == EVP_MD_CTX_FLAG_PAD_X931)
318 rsa_pad_mode = RSA_X931_PADDING;
319 else if (pad_mode == EVP_MD_CTX_FLAG_PAD_PKCS1)
320 rsa_pad_mode = RSA_PKCS1_PADDING;
321 else if (pad_mode == EVP_MD_CTX_FLAG_PAD_PSS)
322 rsa_pad_mode = RSA_NO_PADDING;
323
324 /* NB: call underlying method directly to avoid FIPS blocking */
325 i = rsa->meth->rsa_pub_dec((int)siglen, sigbuf, s, rsa, rsa_pad_mode);
326
327 if (i <= 0)
328 goto err;
329
330 if (pad_mode == EVP_MD_CTX_FLAG_PAD_X931) {
331 int hash_id;
332 if (i != (int)(diglen + 1)) {
333 RSAerr(RSA_F_FIPS_RSA_VERIFY, RSA_R_BAD_SIGNATURE);
334 goto err;
335 }
336 hash_id = RSA_X931_hash_id(M_EVP_MD_CTX_type(sv->mctx));
337 if (hash_id == -1) {
338 RSAerr(RSA_F_FIPS_RSA_VERIFY, RSA_R_UNKNOWN_ALGORITHM_TYPE);
339 goto err;
340 }
341 if (s[diglen] != (unsigned char)hash_id) {
342 RSAerr(RSA_F_FIPS_RSA_VERIFY, RSA_R_BAD_SIGNATURE);
343 goto err;
344 }
345 if (memcmp(s, dig, diglen)) {
346 RSAerr(RSA_F_FIPS_RSA_VERIFY, RSA_R_BAD_SIGNATURE);
347 goto err;
348 }
349 ret = 1;
350 } else if (pad_mode == EVP_MD_CTX_FLAG_PAD_PKCS1) {
351
352 der = fips_digestinfo_encoding(dtype, &dlen);
353
354 if (!der) {
355 RSAerr(RSA_F_FIPS_RSA_VERIFY, RSA_R_UNKNOWN_ALGORITHM_TYPE);
356 return (0);
357 }
358
359 /*
360 * Compare, DigestInfo length, DigestInfo header and finally digest
361 * value itself
362 */
363
364 /* If length mismatch try alternate encoding */
365 if (i != (int)(dlen + diglen))
366 der = fips_digestinfo_nn_encoding(dtype, &dlen);
367
368 if ((i != (int)(dlen + diglen)) || memcmp(der, s, dlen)
369 || memcmp(s + dlen, dig, diglen)) {
370 RSAerr(RSA_F_FIPS_RSA_VERIFY, RSA_R_BAD_SIGNATURE);
371 goto err;
372 }
373 ret = 1;
374
375 } else if (pad_mode == EVP_MD_CTX_FLAG_PAD_PSS) {
376 int saltlen;
377 saltlen = M_EVP_MD_CTX_FLAG_PSS_SALT(sv->mctx);
378 if (saltlen == EVP_MD_CTX_FLAG_PSS_MDLEN)
379 saltlen = -1;
380 else if (saltlen == EVP_MD_CTX_FLAG_PSS_MREC)
381 saltlen = -2;
382 ret = RSA_verify_PKCS1_PSS(rsa, dig, M_EVP_MD_CTX_md(sv->mctx),
383 s, saltlen);
384 if (ret < 0)
385 ret = 0;
386 }
387 err:
388 if (s != NULL) {
389 OPENSSL_cleanse(s, siglen);
390 OPENSSL_free(s);
391 }
392 return (ret);
393}
394
395# define EVP_PKEY_RSA_fips_method \
396 (evp_sign_method *)fips_rsa_sign, \
397 (evp_verify_method *)fips_rsa_verify, \
398 {EVP_PKEY_RSA,EVP_PKEY_RSA2,0,0}
59f3477b
DSH
399
400static int init(EVP_MD_CTX *ctx)
40720ce3
MC
401{
402 return SHA1_Init(ctx->md_data);
403}
404
405static int update(EVP_MD_CTX *ctx, const void *data, size_t count)
406{
407 return SHA1_Update(ctx->md_data, data, count);
408}
409
410static int final(EVP_MD_CTX *ctx, unsigned char *md)
411{
412 return SHA1_Final(md, ctx->md_data);
413}
414
415static const EVP_MD sha1_md = {
416 NID_sha1,
417 NID_sha1WithRSAEncryption,
418 SHA_DIGEST_LENGTH,
419 EVP_MD_FLAG_FIPS | EVP_MD_FLAG_SVCTX,
420 init,
421 update,
422 final,
423 NULL,
424 NULL,
425 EVP_PKEY_RSA_fips_method,
426 SHA_CBLOCK,
427 sizeof(EVP_MD *) + sizeof(SHA_CTX),
428};
59f3477b
DSH
429
430const EVP_MD *EVP_sha1(void)
40720ce3
MC
431{
432 return (&sha1_md);
433}
59f3477b
DSH
434
435static int init224(EVP_MD_CTX *ctx)
40720ce3
MC
436{
437 return SHA224_Init(ctx->md_data);
438}
439
59f3477b 440static int init256(EVP_MD_CTX *ctx)
40720ce3
MC
441{
442 return SHA256_Init(ctx->md_data);
443}
444
59f3477b
DSH
445/*
446 * Even though there're separate SHA224_[Update|Final], we call
447 * SHA256 functions even in SHA224 context. This is what happens
448 * there anyway, so we can spare few CPU cycles:-)
449 */
40720ce3
MC
450static int update256(EVP_MD_CTX *ctx, const void *data, size_t count)
451{
452 return SHA256_Update(ctx->md_data, data, count);
453}
454
455static int final256(EVP_MD_CTX *ctx, unsigned char *md)
456{
457 return SHA256_Final(md, ctx->md_data);
458}
459
460static const EVP_MD sha224_md = {
461 NID_sha224,
462 NID_sha224WithRSAEncryption,
463 SHA224_DIGEST_LENGTH,
464 EVP_MD_FLAG_FIPS | EVP_MD_FLAG_SVCTX,
465 init224,
466 update256,
467 final256,
468 NULL,
469 NULL,
470 EVP_PKEY_RSA_fips_method,
471 SHA256_CBLOCK,
472 sizeof(EVP_MD *) + sizeof(SHA256_CTX),
473};
59f3477b
DSH
474
475const EVP_MD *EVP_sha224(void)
40720ce3
MC
476{
477 return (&sha224_md);
478}
479
480static const EVP_MD sha256_md = {
481 NID_sha256,
482 NID_sha256WithRSAEncryption,
483 SHA256_DIGEST_LENGTH,
484 EVP_MD_FLAG_FIPS | EVP_MD_FLAG_SVCTX,
485 init256,
486 update256,
487 final256,
488 NULL,
489 NULL,
490 EVP_PKEY_RSA_fips_method,
491 SHA256_CBLOCK,
492 sizeof(EVP_MD *) + sizeof(SHA256_CTX),
493};
59f3477b
DSH
494
495const EVP_MD *EVP_sha256(void)
40720ce3
MC
496{
497 return (&sha256_md);
498}
59f3477b
DSH
499
500static int init384(EVP_MD_CTX *ctx)
40720ce3
MC
501{
502 return SHA384_Init(ctx->md_data);
503}
504
59f3477b 505static int init512(EVP_MD_CTX *ctx)
40720ce3
MC
506{
507 return SHA512_Init(ctx->md_data);
508}
509
59f3477b 510/* See comment in SHA224/256 section */
40720ce3
MC
511static int update512(EVP_MD_CTX *ctx, const void *data, size_t count)
512{
513 return SHA512_Update(ctx->md_data, data, count);
514}
515
516static int final512(EVP_MD_CTX *ctx, unsigned char *md)
517{
518 return SHA512_Final(md, ctx->md_data);
519}
520
521static const EVP_MD sha384_md = {
522 NID_sha384,
523 NID_sha384WithRSAEncryption,
524 SHA384_DIGEST_LENGTH,
525 EVP_MD_FLAG_FIPS | EVP_MD_FLAG_SVCTX,
526 init384,
527 update512,
528 final512,
529 NULL,
530 NULL,
531 EVP_PKEY_RSA_fips_method,
532 SHA512_CBLOCK,
533 sizeof(EVP_MD *) + sizeof(SHA512_CTX),
534};
59f3477b
DSH
535
536const EVP_MD *EVP_sha384(void)
40720ce3
MC
537{
538 return (&sha384_md);
539}
540
541static const EVP_MD sha512_md = {
542 NID_sha512,
543 NID_sha512WithRSAEncryption,
544 SHA512_DIGEST_LENGTH,
545 EVP_MD_FLAG_FIPS | EVP_MD_FLAG_SVCTX,
546 init512,
547 update512,
548 final512,
549 NULL,
550 NULL,
551 EVP_PKEY_RSA_fips_method,
552 SHA512_CBLOCK,
553 sizeof(EVP_MD *) + sizeof(SHA512_CTX),
554};
59f3477b
DSH
555
556const EVP_MD *EVP_sha512(void)
40720ce3
MC
557{
558 return (&sha512_md);
559}
59f3477b
DSH
560
561#endif