fips_rsa_sign.c revision 296465
1/* fips_rsa_sign.c */
2/*
3 * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
4 * 2007.
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
14 *    notice, this list of conditions and the following disclaimer.
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
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
72 */
73
74/* Standard encodings including NULL parameter */
75
76static const unsigned char sha1_bin[] = {
77    0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x05,
78    0x00, 0x04, 0x14
79};
80
81static 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
86static 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
91static 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
96static 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/*
102 * Alternate encodings with absent parameters. We don't generate signature
103 * using this format but do tolerate received signatures of this form.
104 */
105
106static unsigned char sha1_nn_bin[] = {
107    0x30, 0x1f, 0x30, 0x07, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x04,
108    0x14
109};
110
111static unsigned char sha224_nn_bin[] = {
112    0x30, 0x2b, 0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03,
113    0x04, 0x02, 0x04, 0x04, 0x1c
114};
115
116static unsigned char sha256_nn_bin[] = {
117    0x30, 0x2f, 0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03,
118    0x04, 0x02, 0x01, 0x04, 0x20
119};
120
121static unsigned char sha384_nn_bin[] = {
122    0x30, 0x3f, 0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03,
123    0x04, 0x02, 0x02, 0x04, 0x30
124};
125
126static unsigned char sha512_nn_bin[] = {
127    0x30, 0x4f, 0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03,
128    0x04, 0x02, 0x03, 0x04, 0x40
129};
130
131static const unsigned char *fips_digestinfo_encoding(int nid,
132                                                     unsigned int *len)
133{
134    switch (nid) {
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
162static const unsigned char *fips_digestinfo_nn_encoding(int nid,
163                                                        unsigned int *len)
164{
165    switch (nid) {
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
193static int fips_rsa_sign(int type, const unsigned char *x, unsigned int y,
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}
286
287static int fips_rsa_verify(int dtype,
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}
399
400static int init(EVP_MD_CTX *ctx)
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};
429
430const EVP_MD *EVP_sha1(void)
431{
432    return (&sha1_md);
433}
434
435static int init224(EVP_MD_CTX *ctx)
436{
437    return SHA224_Init(ctx->md_data);
438}
439
440static int init256(EVP_MD_CTX *ctx)
441{
442    return SHA256_Init(ctx->md_data);
443}
444
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 */
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};
474
475const EVP_MD *EVP_sha224(void)
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};
494
495const EVP_MD *EVP_sha256(void)
496{
497    return (&sha256_md);
498}
499
500static int init384(EVP_MD_CTX *ctx)
501{
502    return SHA384_Init(ctx->md_data);
503}
504
505static int init512(EVP_MD_CTX *ctx)
506{
507    return SHA512_Init(ctx->md_data);
508}
509
510/* See comment in SHA224/256 section */
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};
535
536const EVP_MD *EVP_sha384(void)
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};
555
556const EVP_MD *EVP_sha512(void)
557{
558    return (&sha512_md);
559}
560
561#endif
562