Coverage Report

Created: 2022-11-30 06:20

/src/openssl/crypto/rsa/rsa_pss.c
Line
Count
Source (jump to first uncovered line)
1
/* rsa_pss.c */
2
/*
3
 * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
4
 * 2005.
5
 */
6
/* ====================================================================
7
 * Copyright (c) 2005 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 <stdio.h>
61
#include "cryptlib.h"
62
#include <openssl/bn.h>
63
#include <openssl/rsa.h>
64
#include <openssl/evp.h>
65
#include <openssl/rand.h>
66
#include <openssl/sha.h>
67
68
static const unsigned char zeroes[] = { 0, 0, 0, 0, 0, 0, 0, 0 };
69
70
#if defined(_MSC_VER) && defined(_ARM_)
71
# pragma optimize("g", off)
72
#endif
73
74
int RSA_verify_PKCS1_PSS(RSA *rsa, const unsigned char *mHash,
75
                         const EVP_MD *Hash, const unsigned char *EM,
76
                         int sLen)
77
0
{
78
0
    return RSA_verify_PKCS1_PSS_mgf1(rsa, mHash, Hash, NULL, EM, sLen);
79
0
}
80
81
int RSA_verify_PKCS1_PSS_mgf1(RSA *rsa, const unsigned char *mHash,
82
                              const EVP_MD *Hash, const EVP_MD *mgf1Hash,
83
                              const unsigned char *EM, int sLen)
84
0
{
85
0
    int i;
86
0
    int ret = 0;
87
0
    int hLen, maskedDBLen, MSBits, emLen;
88
0
    const unsigned char *H;
89
0
    unsigned char *DB = NULL;
90
0
    EVP_MD_CTX ctx;
91
0
    unsigned char H_[EVP_MAX_MD_SIZE];
92
0
    EVP_MD_CTX_init(&ctx);
93
94
0
    if (mgf1Hash == NULL)
95
0
        mgf1Hash = Hash;
96
97
0
    hLen = EVP_MD_size(Hash);
98
0
    if (hLen < 0)
99
0
        goto err;
100
    /*-
101
     * Negative sLen has special meanings:
102
     *      -1      sLen == hLen
103
     *      -2      salt length is autorecovered from signature
104
     *      -N      reserved
105
     */
106
0
    if (sLen == -1)
107
0
        sLen = hLen;
108
0
    else if (sLen == -2)
109
0
        sLen = -2;
110
0
    else if (sLen < -2) {
111
0
        RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, RSA_R_SLEN_CHECK_FAILED);
112
0
        goto err;
113
0
    }
114
115
0
    MSBits = (BN_num_bits(rsa->n) - 1) & 0x7;
116
0
    emLen = RSA_size(rsa);
117
0
    if (EM[0] & (0xFF << MSBits)) {
118
0
        RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, RSA_R_FIRST_OCTET_INVALID);
119
0
        goto err;
120
0
    }
121
0
    if (MSBits == 0) {
122
0
        EM++;
123
0
        emLen--;
124
0
    }
125
0
    if (emLen < hLen + 2) {
126
0
        RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, RSA_R_DATA_TOO_LARGE);
127
0
        goto err;
128
0
    }
129
0
    if (sLen > emLen - hLen - 2) { /* sLen can be small negative */
130
0
        RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, RSA_R_DATA_TOO_LARGE);
131
0
        goto err;
132
0
    }
133
0
    if (EM[emLen - 1] != 0xbc) {
134
0
        RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, RSA_R_LAST_OCTET_INVALID);
135
0
        goto err;
136
0
    }
137
0
    maskedDBLen = emLen - hLen - 1;
138
0
    H = EM + maskedDBLen;
139
0
    DB = OPENSSL_malloc(maskedDBLen);
140
0
    if (!DB) {
141
0
        RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, ERR_R_MALLOC_FAILURE);
142
0
        goto err;
143
0
    }
144
0
    if (PKCS1_MGF1(DB, maskedDBLen, H, hLen, mgf1Hash) < 0)
145
0
        goto err;
146
0
    for (i = 0; i < maskedDBLen; i++)
147
0
        DB[i] ^= EM[i];
148
0
    if (MSBits)
149
0
        DB[0] &= 0xFF >> (8 - MSBits);
150
0
    for (i = 0; DB[i] == 0 && i < (maskedDBLen - 1); i++) ;
151
0
    if (DB[i++] != 0x1) {
152
0
        RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, RSA_R_SLEN_RECOVERY_FAILED);
153
0
        goto err;
154
0
    }
155
0
    if (sLen >= 0 && (maskedDBLen - i) != sLen) {
156
0
        RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, RSA_R_SLEN_CHECK_FAILED);
157
0
        goto err;
158
0
    }
159
0
    if (!EVP_DigestInit_ex(&ctx, Hash, NULL)
160
0
        || !EVP_DigestUpdate(&ctx, zeroes, sizeof zeroes)
161
0
        || !EVP_DigestUpdate(&ctx, mHash, hLen))
162
0
        goto err;
163
0
    if (maskedDBLen - i) {
164
0
        if (!EVP_DigestUpdate(&ctx, DB + i, maskedDBLen - i))
165
0
            goto err;
166
0
    }
167
0
    if (!EVP_DigestFinal_ex(&ctx, H_, NULL))
168
0
        goto err;
169
0
    if (memcmp(H_, H, hLen)) {
170
0
        RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, RSA_R_BAD_SIGNATURE);
171
0
        ret = 0;
172
0
    } else
173
0
        ret = 1;
174
175
0
 err:
176
0
    if (DB)
177
0
        OPENSSL_free(DB);
178
0
    EVP_MD_CTX_cleanup(&ctx);
179
180
0
    return ret;
181
182
0
}
183
184
int RSA_padding_add_PKCS1_PSS(RSA *rsa, unsigned char *EM,
185
                              const unsigned char *mHash,
186
                              const EVP_MD *Hash, int sLen)
187
0
{
188
0
    return RSA_padding_add_PKCS1_PSS_mgf1(rsa, EM, mHash, Hash, NULL, sLen);
189
0
}
190
191
int RSA_padding_add_PKCS1_PSS_mgf1(RSA *rsa, unsigned char *EM,
192
                                   const unsigned char *mHash,
193
                                   const EVP_MD *Hash, const EVP_MD *mgf1Hash,
194
                                   int sLen)
195
0
{
196
0
    int i;
197
0
    int ret = 0;
198
0
    int hLen, maskedDBLen, MSBits, emLen;
199
0
    unsigned char *H, *salt = NULL, *p;
200
0
    EVP_MD_CTX ctx;
201
202
0
    if (mgf1Hash == NULL)
203
0
        mgf1Hash = Hash;
204
205
0
    hLen = EVP_MD_size(Hash);
206
0
    if (hLen < 0)
207
0
        goto err;
208
    /*-
209
     * Negative sLen has special meanings:
210
     *      -1      sLen == hLen
211
     *      -2      salt length is maximized
212
     *      -N      reserved
213
     */
214
0
    if (sLen == -1)
215
0
        sLen = hLen;
216
0
    else if (sLen == -2)
217
0
        sLen = -2;
218
0
    else if (sLen < -2) {
219
0
        RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_PSS_MGF1, RSA_R_SLEN_CHECK_FAILED);
220
0
        goto err;
221
0
    }
222
223
0
    MSBits = (BN_num_bits(rsa->n) - 1) & 0x7;
224
0
    emLen = RSA_size(rsa);
225
0
    if (MSBits == 0) {
226
0
        *EM++ = 0;
227
0
        emLen--;
228
0
    }
229
0
    if (emLen < hLen + 2) {
230
0
        RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_PSS_MGF1,
231
0
               RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
232
0
        goto err;
233
0
    }
234
0
    if (sLen == -2) {
235
0
        sLen = emLen - hLen - 2;
236
0
    } else if (sLen > emLen - hLen - 2) {
237
0
        RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_PSS_MGF1,
238
0
               RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
239
0
        goto err;
240
0
    }
241
0
    if (sLen > 0) {
242
0
        salt = OPENSSL_malloc(sLen);
243
0
        if (!salt) {
244
0
            RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_PSS_MGF1,
245
0
                   ERR_R_MALLOC_FAILURE);
246
0
            goto err;
247
0
        }
248
0
        if (RAND_bytes(salt, sLen) <= 0)
249
0
            goto err;
250
0
    }
251
0
    maskedDBLen = emLen - hLen - 1;
252
0
    H = EM + maskedDBLen;
253
0
    EVP_MD_CTX_init(&ctx);
254
0
    if (!EVP_DigestInit_ex(&ctx, Hash, NULL)
255
0
        || !EVP_DigestUpdate(&ctx, zeroes, sizeof zeroes)
256
0
        || !EVP_DigestUpdate(&ctx, mHash, hLen))
257
0
        goto err;
258
0
    if (sLen && !EVP_DigestUpdate(&ctx, salt, sLen))
259
0
        goto err;
260
0
    if (!EVP_DigestFinal_ex(&ctx, H, NULL))
261
0
        goto err;
262
0
    EVP_MD_CTX_cleanup(&ctx);
263
264
    /* Generate dbMask in place then perform XOR on it */
265
0
    if (PKCS1_MGF1(EM, maskedDBLen, H, hLen, mgf1Hash))
266
0
        goto err;
267
268
0
    p = EM;
269
270
    /*
271
     * Initial PS XORs with all zeroes which is a NOP so just update pointer.
272
     * Note from a test above this value is guaranteed to be non-negative.
273
     */
274
0
    p += emLen - sLen - hLen - 2;
275
0
    *p++ ^= 0x1;
276
0
    if (sLen > 0) {
277
0
        for (i = 0; i < sLen; i++)
278
0
            *p++ ^= salt[i];
279
0
    }
280
0
    if (MSBits)
281
0
        EM[0] &= 0xFF >> (8 - MSBits);
282
283
    /* H is already in place so just set final 0xbc */
284
285
0
    EM[emLen - 1] = 0xbc;
286
287
0
    ret = 1;
288
289
0
 err:
290
0
    if (salt)
291
0
        OPENSSL_free(salt);
292
293
0
    return ret;
294
295
0
}
296
297
#if defined(_MSC_VER)
298
# pragma optimize("",on)
299
#endif