Coverage Report

Created: 2026-04-04 06:13

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/nss/lib/freebl/rsapkcs.c
Line
Count
Source
1
/* This Source Code Form is subject to the terms of the Mozilla Public
2
 * License, v. 2.0. If a copy of the MPL was not distributed with this
3
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4
5
/*
6
 * RSA PKCS#1 v2.1 (RFC 3447) operations
7
 */
8
9
#ifdef FREEBL_NO_DEPEND
10
#include "stubs.h"
11
#endif
12
13
#include "secerr.h"
14
15
#include "blapi.h"
16
#include "secitem.h"
17
#include "blapii.h"
18
#include "secmpi.h"
19
20
111k
#define RSA_BLOCK_MIN_PAD_LEN 8
21
76.5k
#define RSA_BLOCK_FIRST_OCTET 0x00
22
48.8k
#define RSA_BLOCK_PRIVATE_PAD_OCTET 0xff
23
1.37M
#define RSA_BLOCK_AFTER_PAD_OCTET 0x00
24
25
/*
26
 * RSA block types
27
 *
28
 * The values of RSA_BlockPrivate and RSA_BlockPublic are fixed.
29
 * The value of RSA_BlockRaw isn't fixed by definition, but we are keeping
30
 * the value that NSS has been using in the past.
31
 */
32
typedef enum {
33
    RSA_BlockPrivate = 1, /* pad for a private-key operation */
34
    RSA_BlockPublic = 2,  /* pad for a public-key operation */
35
    RSA_BlockRaw = 4      /* simply justify the block appropriately */
36
} RSA_BlockType;
37
38
/* Needed for RSA-PSS functions */
39
static const unsigned char eightZeros[] = { 0, 0, 0, 0, 0, 0, 0, 0 };
40
41
/* Constant time comparison of a single byte.
42
 * Returns 1 iff a == b, otherwise returns 0.
43
 * Note: For ranges of bytes, use constantTimeCompare.
44
 */
45
static unsigned char
46
constantTimeEQ8(unsigned char a, unsigned char b)
47
0
{
48
0
    unsigned char c = ~((a - b) | (b - a));
49
0
    c >>= 7;
50
0
    return c;
51
0
}
52
53
/* Constant time comparison of a range of bytes.
54
 * Returns 1 iff len bytes of a are identical to len bytes of b, otherwise
55
 * returns 0.
56
 */
57
static unsigned char
58
constantTimeCompare(const unsigned char *a,
59
                    const unsigned char *b,
60
                    unsigned int len)
61
0
{
62
0
    unsigned char tmp = 0;
63
0
    unsigned int i;
64
0
    for (i = 0; i < len; ++i, ++a, ++b)
65
0
        tmp |= *a ^ *b;
66
0
    return constantTimeEQ8(0x00, tmp);
67
0
}
68
69
/* Constant time conditional.
70
 * Returns a if c is 1, or b if c is 0. The result is undefined if c is
71
 * not 0 or 1.
72
 */
73
static unsigned int
74
constantTimeCondition(unsigned int c,
75
                      unsigned int a,
76
                      unsigned int b)
77
0
{
78
0
    return (~(c - 1) & a) | ((c - 1) & b);
79
0
}
80
81
static unsigned int
82
rsa_modulusLen(SECItem *modulus)
83
152k
{
84
152k
    if (modulus->len == 0) {
85
0
        return 0;
86
0
    }
87
88
152k
    unsigned char byteZero = modulus->data[0];
89
152k
    unsigned int modLen = modulus->len - !byteZero;
90
152k
    return modLen;
91
152k
}
92
93
static unsigned int
94
rsa_modulusBits(SECItem *modulus)
95
5.15k
{
96
5.15k
    if (modulus->len == 0) {
97
0
        return 0;
98
0
    }
99
100
5.15k
    unsigned char byteZero = modulus->data[0];
101
5.15k
    unsigned int numBits = (modulus->len - 1) * 8;
102
103
5.15k
    if (byteZero == 0 && modulus->len == 1) {
104
0
        return 0;
105
0
    }
106
107
5.15k
    if (byteZero == 0) {
108
0
        numBits -= 8;
109
0
        byteZero = modulus->data[1];
110
0
    }
111
112
45.9k
    while (byteZero > 0) {
113
40.7k
        numBits++;
114
40.7k
        byteZero >>= 1;
115
40.7k
    }
116
117
5.15k
    return numBits;
118
5.15k
}
119
120
/*
121
 * Format one block of data for public/private key encryption using
122
 * the rules defined in PKCS #1.
123
 */
124
static unsigned char *
125
rsa_FormatOneBlock(unsigned modulusLen,
126
                   RSA_BlockType blockType,
127
                   SECItem *data)
128
36.6k
{
129
36.6k
    unsigned char *block;
130
36.6k
    unsigned char *bp;
131
36.6k
    unsigned int padLen;
132
36.6k
    unsigned int i, j;
133
36.6k
    SECStatus rv;
134
135
36.6k
    block = (unsigned char *)PORT_Alloc(modulusLen);
136
36.6k
    if (block == NULL)
137
0
        return NULL;
138
139
36.6k
    bp = block;
140
141
    /*
142
     * All RSA blocks start with two octets:
143
     *  0x00 || BlockType
144
     */
145
36.6k
    *bp++ = RSA_BLOCK_FIRST_OCTET;
146
36.6k
    *bp++ = (unsigned char)blockType;
147
148
36.6k
    switch (blockType) {
149
150
        /*
151
         * Blocks intended for private-key operation.
152
         */
153
21.6k
        case RSA_BlockPrivate: /* preferred method */
154
            /*
155
             * 0x00 || BT || Pad || 0x00 || ActualData
156
             *   1      1   padLen    1      data->len
157
             * padLen must be at least RSA_BLOCK_MIN_PAD_LEN (8) bytes.
158
             * Pad is either all 0x00 or all 0xff bytes, depending on blockType.
159
             */
160
21.6k
            padLen = modulusLen - data->len - 3;
161
21.6k
            PORT_Assert(padLen >= RSA_BLOCK_MIN_PAD_LEN);
162
21.6k
            if (padLen < RSA_BLOCK_MIN_PAD_LEN) {
163
0
                PORT_ZFree(block, modulusLen);
164
0
                return NULL;
165
0
            }
166
21.6k
            PORT_Memset(bp, RSA_BLOCK_PRIVATE_PAD_OCTET, padLen);
167
21.6k
            bp += padLen;
168
21.6k
            *bp++ = RSA_BLOCK_AFTER_PAD_OCTET;
169
21.6k
            PORT_Memcpy(bp, data->data, data->len);
170
21.6k
            break;
171
172
        /*
173
         * Blocks intended for public-key operation.
174
         */
175
14.9k
        case RSA_BlockPublic:
176
            /*
177
             * 0x00 || BT || Pad || 0x00 || ActualData
178
             *   1      1   padLen    1      data->len
179
             * Pad is 8 or more non-zero random bytes.
180
             *
181
             * Build the block left to right.
182
             * Fill the entire block from Pad to the end with random bytes.
183
             * Use the bytes after Pad as a supply of extra random bytes from
184
             * which to find replacements for the zero bytes in Pad.
185
             * If we need more than that, refill the bytes after Pad with
186
             * new random bytes as necessary.
187
             */
188
189
14.9k
            padLen = modulusLen - (data->len + 3);
190
14.9k
            PORT_Assert(padLen >= RSA_BLOCK_MIN_PAD_LEN);
191
14.9k
            if (padLen < RSA_BLOCK_MIN_PAD_LEN) {
192
0
                PORT_ZFree(block, modulusLen);
193
0
                return NULL;
194
0
            }
195
14.9k
            j = modulusLen - 2;
196
14.9k
            rv = RNG_GenerateGlobalRandomBytes(bp, j);
197
14.9k
            if (rv == SECSuccess) {
198
1.32M
                for (i = 0; i < padLen;) {
199
1.30M
                    unsigned char repl;
200
                    /* Pad with non-zero random data. */
201
1.30M
                    if (bp[i] != RSA_BLOCK_AFTER_PAD_OCTET) {
202
1.30M
                        ++i;
203
1.30M
                        continue;
204
1.30M
                    }
205
4.60k
                    if (j <= padLen) {
206
0
                        rv = RNG_GenerateGlobalRandomBytes(bp + padLen,
207
0
                                                           modulusLen - (2 + padLen));
208
0
                        if (rv != SECSuccess)
209
0
                            break;
210
0
                        j = modulusLen - 2;
211
0
                    }
212
4.60k
                    do {
213
4.60k
                        repl = bp[--j];
214
4.60k
                    } while (repl == RSA_BLOCK_AFTER_PAD_OCTET && j > padLen);
215
4.60k
                    if (repl != RSA_BLOCK_AFTER_PAD_OCTET) {
216
4.60k
                        bp[i++] = repl;
217
4.60k
                    }
218
4.60k
                }
219
14.9k
            }
220
14.9k
            if (rv != SECSuccess) {
221
0
                PORT_ZFree(block, modulusLen);
222
0
                PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
223
0
                return NULL;
224
0
            }
225
14.9k
            bp += padLen;
226
14.9k
            *bp++ = RSA_BLOCK_AFTER_PAD_OCTET;
227
14.9k
            PORT_Memcpy(bp, data->data, data->len);
228
14.9k
            break;
229
230
0
        default:
231
0
            PORT_Assert(0);
232
0
            PORT_ZFree(block, modulusLen);
233
0
            return NULL;
234
36.6k
    }
235
236
36.6k
    return block;
237
36.6k
}
238
239
/* modulusLen has to be larger than RSA_BLOCK_MIN_PAD_LEN + 3, and data has to be smaller than modulus - (RSA_BLOCK_MIN_PAD_LEN + 3) */
240
static SECStatus
241
rsa_FormatBlock(SECItem *result,
242
                unsigned modulusLen,
243
                RSA_BlockType blockType,
244
                SECItem *data)
245
36.6k
{
246
36.6k
    switch (blockType) {
247
21.6k
        case RSA_BlockPrivate:
248
36.6k
        case RSA_BlockPublic:
249
            /*
250
             * 0x00 || BT || Pad || 0x00 || ActualData
251
             *
252
             * The "3" below is the first octet + the second octet + the 0x00
253
             * octet that always comes just before the ActualData.
254
             */
255
36.6k
            if (modulusLen < (3 + RSA_BLOCK_MIN_PAD_LEN) || data->len > (modulusLen - (3 + RSA_BLOCK_MIN_PAD_LEN))) {
256
0
                return SECFailure;
257
0
            }
258
36.6k
            result->data = rsa_FormatOneBlock(modulusLen, blockType, data);
259
36.6k
            if (result->data == NULL) {
260
0
                result->len = 0;
261
0
                return SECFailure;
262
0
            }
263
36.6k
            result->len = modulusLen;
264
265
36.6k
            break;
266
267
0
        case RSA_BlockRaw:
268
            /*
269
             * Pad || ActualData
270
             * Pad is zeros. The application is responsible for recovering
271
             * the actual data.
272
             */
273
0
            if (data->len > modulusLen) {
274
0
                return SECFailure;
275
0
            }
276
0
            result->data = (unsigned char *)PORT_ZAlloc(modulusLen);
277
0
            result->len = modulusLen;
278
0
            PORT_Memcpy(result->data + (modulusLen - data->len),
279
0
                        data->data, data->len);
280
0
            break;
281
282
0
        default:
283
0
            PORT_Assert(0);
284
0
            result->data = NULL;
285
0
            result->len = 0;
286
0
            return SECFailure;
287
36.6k
    }
288
289
36.6k
    return SECSuccess;
290
36.6k
}
291
292
/*
293
 * Mask generation function MGF1 as defined in PKCS #1 v2.1 / RFC 3447.
294
 */
295
static SECStatus
296
MGF1(HASH_HashType hashAlg,
297
     unsigned char *mask,
298
     unsigned int maskLen,
299
     const unsigned char *mgfSeed,
300
     unsigned int mgfSeedLen)
301
3.00k
{
302
3.00k
    unsigned int digestLen;
303
3.00k
    PRUint32 counter;
304
3.00k
    PRUint32 rounds;
305
3.00k
    unsigned char *tempHash;
306
3.00k
    unsigned char *temp;
307
3.00k
    const SECHashObject *hash;
308
3.00k
    void *hashContext;
309
3.00k
    unsigned char C[4];
310
3.00k
    SECStatus rv = SECSuccess;
311
312
3.00k
    hash = HASH_GetRawHashObject(hashAlg);
313
3.00k
    if (hash == NULL) {
314
0
        return SECFailure;
315
0
    }
316
317
3.00k
    hashContext = (*hash->create)();
318
3.00k
    rounds = (maskLen + hash->length - 1) / hash->length;
319
18.7k
    for (counter = 0; counter < rounds; counter++) {
320
15.7k
        C[0] = (unsigned char)((counter >> 24) & 0xff);
321
15.7k
        C[1] = (unsigned char)((counter >> 16) & 0xff);
322
15.7k
        C[2] = (unsigned char)((counter >> 8) & 0xff);
323
15.7k
        C[3] = (unsigned char)(counter & 0xff);
324
325
        /* This could be optimized when the clone functions in
326
         * rawhash.c are implemented. */
327
15.7k
        (*hash->begin)(hashContext);
328
15.7k
        (*hash->update)(hashContext, mgfSeed, mgfSeedLen);
329
15.7k
        (*hash->update)(hashContext, C, sizeof C);
330
331
15.7k
        tempHash = mask + counter * hash->length;
332
15.7k
        if (counter != (rounds - 1)) {
333
12.7k
            (*hash->end)(hashContext, tempHash, &digestLen, hash->length);
334
12.7k
        } else { /* we're in the last round and need to cut the hash */
335
3.00k
            temp = (unsigned char *)PORT_Alloc(hash->length);
336
3.00k
            if (!temp) {
337
0
                rv = SECFailure;
338
0
                goto done;
339
0
            }
340
3.00k
            (*hash->end)(hashContext, temp, &digestLen, hash->length);
341
3.00k
            PORT_Memcpy(tempHash, temp, maskLen - counter * hash->length);
342
3.00k
            PORT_Free(temp);
343
3.00k
        }
344
15.7k
    }
345
346
3.00k
done:
347
3.00k
    (*hash->destroy)(hashContext, PR_TRUE);
348
3.00k
    return rv;
349
3.00k
}
350
351
/* XXX Doesn't set error code */
352
SECStatus
353
RSA_SignRaw(RSAPrivateKey *key,
354
            unsigned char *output,
355
            unsigned int *outputLen,
356
            unsigned int maxOutputLen,
357
            const unsigned char *data,
358
            unsigned int dataLen)
359
0
{
360
0
    SECStatus rv = SECSuccess;
361
0
    unsigned int modulusLen = rsa_modulusLen(&key->modulus);
362
0
    SECItem formatted;
363
0
    SECItem unformatted;
364
365
0
    if (maxOutputLen < modulusLen)
366
0
        return SECFailure;
367
368
0
    unformatted.len = dataLen;
369
0
    unformatted.data = (unsigned char *)data;
370
0
    formatted.data = NULL;
371
0
    rv = rsa_FormatBlock(&formatted, modulusLen, RSA_BlockRaw, &unformatted);
372
0
    if (rv != SECSuccess)
373
0
        goto done;
374
375
0
    rv = RSA_PrivateKeyOpDoubleChecked(key, output, formatted.data);
376
0
    *outputLen = modulusLen;
377
378
0
done:
379
0
    if (formatted.data != NULL)
380
0
        PORT_ZFree(formatted.data, modulusLen);
381
0
    return rv;
382
0
}
383
384
/* XXX Doesn't set error code */
385
SECStatus
386
RSA_CheckSignRaw(RSAPublicKey *key,
387
                 const unsigned char *sig,
388
                 unsigned int sigLen,
389
                 const unsigned char *hash,
390
                 unsigned int hashLen)
391
0
{
392
0
    SECStatus rv;
393
0
    unsigned int modulusLen = rsa_modulusLen(&key->modulus);
394
0
    unsigned char *buffer;
395
396
0
    if (sigLen != modulusLen)
397
0
        goto failure;
398
0
    if (hashLen > modulusLen)
399
0
        goto failure;
400
401
0
    buffer = (unsigned char *)PORT_Alloc(modulusLen + 1);
402
0
    if (!buffer)
403
0
        goto failure;
404
405
0
    rv = RSA_PublicKeyOp(key, buffer, sig);
406
0
    if (rv != SECSuccess)
407
0
        goto loser;
408
409
    /*
410
     * make sure we get the same results
411
     */
412
    /* XXX(rsleevi): Constant time */
413
    /* NOTE: should we verify the leading zeros? */
414
0
    if (PORT_Memcmp(buffer + (modulusLen - hashLen), hash, hashLen) != 0)
415
0
        goto loser;
416
417
0
    PORT_Free(buffer);
418
0
    return SECSuccess;
419
420
0
loser:
421
0
    PORT_Free(buffer);
422
0
failure:
423
0
    return SECFailure;
424
0
}
425
426
/* XXX Doesn't set error code */
427
SECStatus
428
RSA_CheckSignRecoverRaw(RSAPublicKey *key,
429
                        unsigned char *data,
430
                        unsigned int *dataLen,
431
                        unsigned int maxDataLen,
432
                        const unsigned char *sig,
433
                        unsigned int sigLen)
434
0
{
435
0
    SECStatus rv;
436
0
    unsigned int modulusLen = rsa_modulusLen(&key->modulus);
437
438
0
    if (sigLen != modulusLen)
439
0
        goto failure;
440
0
    if (maxDataLen < modulusLen)
441
0
        goto failure;
442
443
0
    rv = RSA_PublicKeyOp(key, data, sig);
444
0
    if (rv != SECSuccess)
445
0
        goto failure;
446
447
0
    *dataLen = modulusLen;
448
0
    return SECSuccess;
449
450
0
failure:
451
0
    return SECFailure;
452
0
}
453
454
/* XXX Doesn't set error code */
455
SECStatus
456
RSA_EncryptRaw(RSAPublicKey *key,
457
               unsigned char *output,
458
               unsigned int *outputLen,
459
               unsigned int maxOutputLen,
460
               const unsigned char *input,
461
               unsigned int inputLen)
462
0
{
463
0
    SECStatus rv;
464
0
    unsigned int modulusLen = rsa_modulusLen(&key->modulus);
465
0
    SECItem formatted;
466
0
    SECItem unformatted;
467
468
0
    formatted.data = NULL;
469
0
    if (maxOutputLen < modulusLen)
470
0
        goto failure;
471
472
0
    unformatted.len = inputLen;
473
0
    unformatted.data = (unsigned char *)input;
474
0
    formatted.data = NULL;
475
0
    rv = rsa_FormatBlock(&formatted, modulusLen, RSA_BlockRaw, &unformatted);
476
0
    if (rv != SECSuccess)
477
0
        goto failure;
478
479
0
    rv = RSA_PublicKeyOp(key, output, formatted.data);
480
0
    if (rv != SECSuccess)
481
0
        goto failure;
482
483
0
    PORT_ZFree(formatted.data, modulusLen);
484
0
    *outputLen = modulusLen;
485
0
    return SECSuccess;
486
487
0
failure:
488
0
    if (formatted.data != NULL)
489
0
        PORT_ZFree(formatted.data, modulusLen);
490
0
    return SECFailure;
491
0
}
492
493
/* XXX Doesn't set error code */
494
SECStatus
495
RSA_DecryptRaw(RSAPrivateKey *key,
496
               unsigned char *output,
497
               unsigned int *outputLen,
498
               unsigned int maxOutputLen,
499
               const unsigned char *input,
500
               unsigned int inputLen)
501
0
{
502
0
    SECStatus rv;
503
0
    unsigned int modulusLen = rsa_modulusLen(&key->modulus);
504
505
0
    if (modulusLen > maxOutputLen)
506
0
        goto failure;
507
0
    if (inputLen != modulusLen)
508
0
        goto failure;
509
510
0
    rv = RSA_PrivateKeyOp(key, output, input);
511
0
    if (rv != SECSuccess)
512
0
        goto failure;
513
514
0
    *outputLen = modulusLen;
515
0
    return SECSuccess;
516
517
0
failure:
518
0
    return SECFailure;
519
0
}
520
521
/*
522
 * Decodes an EME-OAEP encoded block, validating the encoding in constant
523
 * time.
524
 * Described in RFC 3447, section 7.1.2.
525
 * input contains the encoded block, after decryption.
526
 * label is the optional value L that was associated with the message.
527
 * On success, the original message and message length will be stored in
528
 * output and outputLen.
529
 */
530
static SECStatus
531
eme_oaep_decode(unsigned char *output,
532
                unsigned int *outputLen,
533
                unsigned int maxOutputLen,
534
                const unsigned char *input,
535
                unsigned int inputLen,
536
                HASH_HashType hashAlg,
537
                HASH_HashType maskHashAlg,
538
                const unsigned char *label,
539
                unsigned int labelLen)
540
0
{
541
0
    const SECHashObject *hash;
542
0
    void *hashContext;
543
0
    SECStatus rv = SECFailure;
544
0
    unsigned char labelHash[HASH_LENGTH_MAX];
545
0
    unsigned int i;
546
0
    unsigned int maskLen;
547
0
    unsigned int paddingOffset;
548
0
    unsigned char *mask = NULL;
549
0
    unsigned char *tmpOutput = NULL;
550
0
    unsigned char isGood;
551
0
    unsigned char foundPaddingEnd;
552
553
0
    hash = HASH_GetRawHashObject(hashAlg);
554
555
    /* 1.c */
556
0
    if (inputLen < (hash->length * 2) + 2) {
557
0
        PORT_SetError(SEC_ERROR_INPUT_LEN);
558
0
        return SECFailure;
559
0
    }
560
561
    /* Step 3.a - Generate lHash */
562
0
    hashContext = (*hash->create)();
563
0
    if (hashContext == NULL) {
564
0
        PORT_SetError(SEC_ERROR_NO_MEMORY);
565
0
        return SECFailure;
566
0
    }
567
0
    (*hash->begin)(hashContext);
568
0
    if (labelLen > 0)
569
0
        (*hash->update)(hashContext, label, labelLen);
570
0
    (*hash->end)(hashContext, labelHash, &i, sizeof(labelHash));
571
0
    (*hash->destroy)(hashContext, PR_TRUE);
572
573
0
    tmpOutput = (unsigned char *)PORT_Alloc(inputLen);
574
0
    if (tmpOutput == NULL) {
575
0
        PORT_SetError(SEC_ERROR_NO_MEMORY);
576
0
        goto done;
577
0
    }
578
579
0
    maskLen = inputLen - hash->length - 1;
580
0
    mask = (unsigned char *)PORT_Alloc(maskLen);
581
0
    if (mask == NULL) {
582
0
        PORT_SetError(SEC_ERROR_NO_MEMORY);
583
0
        goto done;
584
0
    }
585
586
0
    PORT_Memcpy(tmpOutput, input, inputLen);
587
588
    /* 3.c - Generate seedMask */
589
0
    MGF1(maskHashAlg, mask, hash->length, &tmpOutput[1 + hash->length],
590
0
         inputLen - hash->length - 1);
591
    /* 3.d - Unmask seed */
592
0
    for (i = 0; i < hash->length; ++i)
593
0
        tmpOutput[1 + i] ^= mask[i];
594
595
    /* 3.e - Generate dbMask */
596
0
    MGF1(maskHashAlg, mask, maskLen, &tmpOutput[1], hash->length);
597
    /* 3.f - Unmask DB */
598
0
    for (i = 0; i < maskLen; ++i)
599
0
        tmpOutput[1 + hash->length + i] ^= mask[i];
600
601
    /* 3.g - Compare Y, lHash, and PS in constant time
602
     * Warning: This code is timing dependent and must not disclose which of
603
     * these were invalid.
604
     */
605
0
    paddingOffset = 0;
606
0
    isGood = 1;
607
0
    foundPaddingEnd = 0;
608
609
    /* Compare Y */
610
0
    isGood &= constantTimeEQ8(0x00, tmpOutput[0]);
611
612
    /* Compare lHash and lHash' */
613
0
    isGood &= constantTimeCompare(&labelHash[0],
614
0
                                  &tmpOutput[1 + hash->length],
615
0
                                  hash->length);
616
617
    /* Compare that the padding is zero or more zero octets, followed by a
618
     * 0x01 octet */
619
0
    for (i = 1 + (hash->length * 2); i < inputLen; ++i) {
620
0
        unsigned char isZero = constantTimeEQ8(0x00, tmpOutput[i]);
621
0
        unsigned char isOne = constantTimeEQ8(0x01, tmpOutput[i]);
622
        /* non-constant time equivalent:
623
         * if (tmpOutput[i] == 0x01 && !foundPaddingEnd)
624
         *     paddingOffset = i;
625
         */
626
0
        paddingOffset = constantTimeCondition(isOne & ~foundPaddingEnd, i,
627
0
                                              paddingOffset);
628
        /* non-constant time equivalent:
629
         * if (tmpOutput[i] == 0x01)
630
         *    foundPaddingEnd = true;
631
         *
632
         * Note: This may yield false positives, as it will be set whenever
633
         * a 0x01 byte is encountered. If there was bad padding (eg:
634
         * 0x03 0x02 0x01), foundPaddingEnd will still be set to true, and
635
         * paddingOffset will still be set to 2.
636
         */
637
0
        foundPaddingEnd = constantTimeCondition(isOne, 1, foundPaddingEnd);
638
        /* non-constant time equivalent:
639
         * if (tmpOutput[i] != 0x00 && tmpOutput[i] != 0x01 &&
640
         *     !foundPaddingEnd) {
641
         *    isGood = false;
642
         * }
643
         *
644
         * Note: This may yield false positives, as a message (and padding)
645
         * that is entirely zeros will result in isGood still being true. Thus
646
         * it's necessary to check foundPaddingEnd is positive below.
647
         */
648
0
        isGood = constantTimeCondition(~foundPaddingEnd & ~isZero, 0, isGood);
649
0
    }
650
651
    /* While both isGood and foundPaddingEnd may have false positives, they
652
     * cannot BOTH have false positives. If both are not true, then an invalid
653
     * message was received. Note, this comparison must still be done in constant
654
     * time so as not to leak either condition.
655
     */
656
0
    if (!(isGood & foundPaddingEnd)) {
657
0
        PORT_SetError(SEC_ERROR_BAD_DATA);
658
0
        goto done;
659
0
    }
660
661
    /* End timing dependent code */
662
663
0
    ++paddingOffset; /* Skip the 0x01 following the end of PS */
664
665
0
    *outputLen = inputLen - paddingOffset;
666
0
    if (*outputLen > maxOutputLen) {
667
0
        PORT_SetError(SEC_ERROR_OUTPUT_LEN);
668
0
        goto done;
669
0
    }
670
671
0
    if (*outputLen)
672
0
        PORT_Memcpy(output, &tmpOutput[paddingOffset], *outputLen);
673
0
    rv = SECSuccess;
674
675
0
done:
676
0
    if (mask)
677
0
        PORT_ZFree(mask, maskLen);
678
0
    if (tmpOutput)
679
0
        PORT_ZFree(tmpOutput, inputLen);
680
0
    return rv;
681
0
}
682
683
/*
684
 * Generate an EME-OAEP encoded block for encryption
685
 * Described in RFC 3447, section 7.1.1
686
 * We use input instead of M for the message to be encrypted
687
 * label is the optional value L to be associated with the message.
688
 */
689
static SECStatus
690
eme_oaep_encode(unsigned char *em,
691
                unsigned int emLen,
692
                const unsigned char *input,
693
                unsigned int inputLen,
694
                HASH_HashType hashAlg,
695
                HASH_HashType maskHashAlg,
696
                const unsigned char *label,
697
                unsigned int labelLen,
698
                const unsigned char *seed,
699
                unsigned int seedLen)
700
0
{
701
0
    const SECHashObject *hash;
702
0
    void *hashContext;
703
0
    SECStatus rv;
704
0
    unsigned char *mask;
705
0
    unsigned int reservedLen;
706
0
    unsigned int dbMaskLen;
707
0
    unsigned int i;
708
709
0
    hash = HASH_GetRawHashObject(hashAlg);
710
0
    PORT_Assert(seed == NULL || seedLen == hash->length);
711
712
    /* Step 1.b */
713
0
    reservedLen = (2 * hash->length) + 2;
714
0
    if (emLen < reservedLen || inputLen > (emLen - reservedLen)) {
715
0
        PORT_SetError(SEC_ERROR_INPUT_LEN);
716
0
        return SECFailure;
717
0
    }
718
719
    /*
720
     * From RFC 3447, Section 7.1
721
     *                      +----------+---------+-------+
722
     *                 DB = |  lHash   |    PS   |   M   |
723
     *                      +----------+---------+-------+
724
     *                                     |
725
     *           +----------+              V
726
     *           |   seed   |--> MGF ---> xor
727
     *           +----------+              |
728
     *                 |                   |
729
     *        +--+     V                   |
730
     *        |00|    xor <----- MGF <-----|
731
     *        +--+     |                   |
732
     *          |      |                   |
733
     *          V      V                   V
734
     *        +--+----------+----------------------------+
735
     *  EM =  |00|maskedSeed|          maskedDB          |
736
     *        +--+----------+----------------------------+
737
     *
738
     * We use mask to hold the result of the MGF functions, and all other
739
     * values are generated in their final resting place.
740
     */
741
0
    *em = 0x00;
742
743
    /* Step 2.a - Generate lHash */
744
0
    hashContext = (*hash->create)();
745
0
    if (hashContext == NULL) {
746
0
        PORT_SetError(SEC_ERROR_NO_MEMORY);
747
0
        return SECFailure;
748
0
    }
749
0
    (*hash->begin)(hashContext);
750
0
    if (labelLen > 0)
751
0
        (*hash->update)(hashContext, label, labelLen);
752
0
    (*hash->end)(hashContext, &em[1 + hash->length], &i, hash->length);
753
0
    (*hash->destroy)(hashContext, PR_TRUE);
754
755
    /* Step 2.b - Generate PS */
756
0
    if (emLen - reservedLen - inputLen > 0) {
757
0
        PORT_Memset(em + 1 + (hash->length * 2), 0x00,
758
0
                    emLen - reservedLen - inputLen);
759
0
    }
760
761
    /* Step 2.c. - Generate DB
762
     * DB = lHash || PS || 0x01 || M
763
     * Note that PS and lHash have already been placed into em at their
764
     * appropriate offsets. This just copies M into place
765
     */
766
0
    em[emLen - inputLen - 1] = 0x01;
767
0
    if (inputLen)
768
0
        PORT_Memcpy(em + emLen - inputLen, input, inputLen);
769
770
0
    if (seed == NULL) {
771
        /* Step 2.d - Generate seed */
772
0
        rv = RNG_GenerateGlobalRandomBytes(em + 1, hash->length);
773
0
        if (rv != SECSuccess) {
774
0
            return rv;
775
0
        }
776
0
    } else {
777
        /* For Known Answer Tests, copy the supplied seed. */
778
0
        PORT_Memcpy(em + 1, seed, seedLen);
779
0
    }
780
781
    /* Step 2.e - Generate dbMask*/
782
0
    dbMaskLen = emLen - hash->length - 1;
783
0
    mask = (unsigned char *)PORT_Alloc(dbMaskLen);
784
0
    if (mask == NULL) {
785
0
        PORT_SetError(SEC_ERROR_NO_MEMORY);
786
0
        return SECFailure;
787
0
    }
788
0
    MGF1(maskHashAlg, mask, dbMaskLen, em + 1, hash->length);
789
    /* Step 2.f - Compute maskedDB*/
790
0
    for (i = 0; i < dbMaskLen; ++i)
791
0
        em[1 + hash->length + i] ^= mask[i];
792
793
    /* Step 2.g - Generate seedMask */
794
0
    MGF1(maskHashAlg, mask, hash->length, &em[1 + hash->length], dbMaskLen);
795
    /* Step 2.h - Compute maskedSeed */
796
0
    for (i = 0; i < hash->length; ++i)
797
0
        em[1 + i] ^= mask[i];
798
799
0
    PORT_ZFree(mask, dbMaskLen);
800
0
    return SECSuccess;
801
0
}
802
803
SECStatus
804
RSA_PartialVerify(RSAPublicKey *key)
805
0
{
806
0
    mp_int n, e, fact;
807
0
    mp_err err;
808
0
    SECStatus rv = SECSuccess;
809
0
    mp_int small_primes_product;
810
    /* this string is the NIST string *751, since the requirement is to detect up to prime 751
811
     * inclusive */
812
0
    const char *primes_product_decimal_string = "1090367704589007566035202161494385722019383400119651874476478760664145697976533387343668263403266024900638505861980470638958322454581550203448421495842767449796261170069732921897400657944793163960886418313690808872680411646815934535605444102983629208422567461571568587963766123806881456648026733413053968363611105";
813
814
    /* we only need to verify public keys once, and only in FIPS mode */
815
0
    if (!key->needVerify) {
816
0
        return SECSuccess;
817
0
    }
818
    /* modulus length is check done by the FIPS indicator code */
819
    /* validate public exponent: this test only succeeds if the exponent e is
820
     * 2^16 <= e < 2^256. e = 2^16 will be rejected below byte the iseven check */
821
0
    if (!key->publicExponent.data[0] || (key->publicExponent.len < 3) || (key->publicExponent.len > 32)) {
822
0
        PORT_SetError(SEC_ERROR_INVALID_KEY);
823
0
        return SECFailure;
824
0
    }
825
    /* convert to mpi for more detailed tests */
826
0
    MP_DIGITS(&n) = 0;
827
0
    MP_DIGITS(&e) = 0;
828
0
    MP_DIGITS(&fact) = 0;
829
0
    MP_DIGITS(&small_primes_product) = 0;
830
0
    CHECK_MPI_OK(mp_init(&n));
831
0
    CHECK_MPI_OK(mp_init(&e));
832
0
    CHECK_MPI_OK(mp_init(&small_primes_product));
833
0
    CHECK_MPI_OK(mp_init(&fact));
834
0
    SECITEM_TO_MPINT(key->modulus, &n);
835
0
    SECITEM_TO_MPINT(key->publicExponent, &e);
836
837
    /* reject even exponents and moduluses */
838
0
    if (mp_iseven(&e) || mp_iseven(&n)) {
839
0
        err = MP_BADARG;
840
0
        goto cleanup;
841
0
    }
842
    /* check for componsite or power */
843
0
    err = mpp_pprime_or_power_secure(&n, NULL, 4);
844
0
    if (err != MP_NOT_POWER) {
845
        /* prime check succeeded, therefore modulus is not composite */
846
        /* or we found a factor, indicating that the modulus is probably
847
         * a power of a prime */
848
0
        err = MP_BADARG;
849
0
        goto cleanup;
850
0
    }
851
    /* check for small factors using gcd */
852
0
    CHECK_MPI_OK(mp_read_radix(&small_primes_product,
853
0
                               primes_product_decimal_string, 10));
854
0
    CHECK_MPI_OK(mp_gcd(&n, &small_primes_product, &fact));
855
0
    if (mp_cmp_d(&fact, 1) != 0) {
856
        /* factor found, not a good modulus */
857
0
        err = MP_BADARG;
858
0
        goto cleanup;
859
0
    }
860
861
0
cleanup:
862
0
    mp_clear(&n);
863
0
    mp_clear(&e);
864
0
    mp_clear(&small_primes_product);
865
0
    mp_clear(&fact);
866
0
    if (err) {
867
0
        PORT_SetError(SEC_ERROR_INVALID_KEY);
868
0
        rv = SECFailure;
869
0
    } else {
870
        /* if we are called again with this key, no need to verify
871
         * again */
872
0
        key->needVerify = PR_FALSE;
873
0
    }
874
0
    return rv;
875
0
}
876
877
SECStatus
878
RSA_EncryptOAEP(RSAPublicKey *key,
879
                HASH_HashType hashAlg,
880
                HASH_HashType maskHashAlg,
881
                const unsigned char *label,
882
                unsigned int labelLen,
883
                const unsigned char *seed,
884
                unsigned int seedLen,
885
                unsigned char *output,
886
                unsigned int *outputLen,
887
                unsigned int maxOutputLen,
888
                const unsigned char *input,
889
                unsigned int inputLen)
890
0
{
891
0
    SECStatus rv = SECFailure;
892
0
    unsigned int modulusLen = rsa_modulusLen(&key->modulus);
893
0
    unsigned char *oaepEncoded = NULL;
894
895
0
    if (maxOutputLen < modulusLen) {
896
0
        PORT_SetError(SEC_ERROR_OUTPUT_LEN);
897
0
        return SECFailure;
898
0
    }
899
900
0
    if ((hashAlg == HASH_AlgNULL) || (maskHashAlg == HASH_AlgNULL)) {
901
0
        PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
902
0
        return SECFailure;
903
0
    }
904
905
0
    if ((labelLen == 0 && label != NULL) ||
906
0
        (labelLen > 0 && label == NULL)) {
907
0
        PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
908
0
        return SECFailure;
909
0
    }
910
911
0
    rv = RSA_PartialVerify(key);
912
0
    if (rv != SECSuccess) {
913
        /* error code set by RSA_PartialVerify() */
914
0
        return rv;
915
0
    }
916
917
0
    oaepEncoded = (unsigned char *)PORT_Alloc(modulusLen);
918
0
    if (oaepEncoded == NULL) {
919
0
        PORT_SetError(SEC_ERROR_NO_MEMORY);
920
0
        return SECFailure;
921
0
    }
922
0
    rv = eme_oaep_encode(oaepEncoded, modulusLen, input, inputLen,
923
0
                         hashAlg, maskHashAlg, label, labelLen, seed, seedLen);
924
0
    if (rv != SECSuccess)
925
0
        goto done;
926
927
0
    rv = RSA_PublicKeyOp(key, output, oaepEncoded);
928
0
    if (rv != SECSuccess)
929
0
        goto done;
930
0
    *outputLen = modulusLen;
931
932
0
done:
933
0
    PORT_Free(oaepEncoded);
934
0
    return rv;
935
0
}
936
937
SECStatus
938
RSA_DecryptOAEP(RSAPrivateKey *key,
939
                HASH_HashType hashAlg,
940
                HASH_HashType maskHashAlg,
941
                const unsigned char *label,
942
                unsigned int labelLen,
943
                unsigned char *output,
944
                unsigned int *outputLen,
945
                unsigned int maxOutputLen,
946
                const unsigned char *input,
947
                unsigned int inputLen)
948
0
{
949
0
    SECStatus rv = SECFailure;
950
0
    unsigned int modulusLen = rsa_modulusLen(&key->modulus);
951
0
    unsigned char *oaepEncoded = NULL;
952
953
0
    if ((hashAlg == HASH_AlgNULL) || (maskHashAlg == HASH_AlgNULL)) {
954
0
        PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
955
0
        return SECFailure;
956
0
    }
957
958
0
    if (inputLen != modulusLen) {
959
0
        PORT_SetError(SEC_ERROR_INPUT_LEN);
960
0
        return SECFailure;
961
0
    }
962
963
0
    if ((labelLen == 0 && label != NULL) ||
964
0
        (labelLen > 0 && label == NULL)) {
965
0
        PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
966
0
        return SECFailure;
967
0
    }
968
969
0
    oaepEncoded = (unsigned char *)PORT_Alloc(modulusLen);
970
0
    if (oaepEncoded == NULL) {
971
0
        PORT_SetError(SEC_ERROR_NO_MEMORY);
972
0
        return SECFailure;
973
0
    }
974
975
0
    rv = RSA_PrivateKeyOpDoubleChecked(key, oaepEncoded, input);
976
0
    if (rv != SECSuccess) {
977
0
        goto done;
978
0
    }
979
0
    rv = eme_oaep_decode(output, outputLen, maxOutputLen, oaepEncoded,
980
0
                         modulusLen, hashAlg, maskHashAlg, label,
981
0
                         labelLen);
982
983
0
done:
984
0
    if (oaepEncoded)
985
0
        PORT_ZFree(oaepEncoded, modulusLen);
986
0
    return rv;
987
0
}
988
989
/* XXX Doesn't set error code */
990
SECStatus
991
RSA_EncryptBlock(RSAPublicKey *key,
992
                 unsigned char *output,
993
                 unsigned int *outputLen,
994
                 unsigned int maxOutputLen,
995
                 const unsigned char *input,
996
                 unsigned int inputLen)
997
14.9k
{
998
14.9k
    SECStatus rv;
999
14.9k
    unsigned int modulusLen = rsa_modulusLen(&key->modulus);
1000
14.9k
    SECItem formatted;
1001
14.9k
    SECItem unformatted;
1002
1003
14.9k
    formatted.data = NULL;
1004
14.9k
    if (maxOutputLen < modulusLen)
1005
0
        goto failure;
1006
1007
14.9k
    unformatted.len = inputLen;
1008
14.9k
    unformatted.data = (unsigned char *)input;
1009
14.9k
    formatted.data = NULL;
1010
14.9k
    rv = rsa_FormatBlock(&formatted, modulusLen, RSA_BlockPublic,
1011
14.9k
                         &unformatted);
1012
14.9k
    if (rv != SECSuccess)
1013
0
        goto failure;
1014
1015
14.9k
    rv = RSA_PublicKeyOp(key, output, formatted.data);
1016
14.9k
    if (rv != SECSuccess)
1017
0
        goto failure;
1018
1019
14.9k
    PORT_ZFree(formatted.data, modulusLen);
1020
14.9k
    *outputLen = modulusLen;
1021
14.9k
    return SECSuccess;
1022
1023
0
failure:
1024
0
    if (formatted.data != NULL)
1025
0
        PORT_ZFree(formatted.data, modulusLen);
1026
0
    return SECFailure;
1027
14.9k
}
1028
1029
static HMACContext *
1030
rsa_GetHMACContext(const SECHashObject *hash, RSAPrivateKey *key,
1031
                   const unsigned char *input, unsigned int inputLen)
1032
4.00k
{
1033
4.00k
    unsigned char keyHash[HASH_LENGTH_MAX];
1034
4.00k
    void *hashContext;
1035
4.00k
    HMACContext *hmac = NULL;
1036
4.00k
    unsigned int privKeyLen = key->privateExponent.len;
1037
4.00k
    unsigned int keyLen;
1038
4.00k
    SECStatus rv;
1039
1040
    /* first get the key hash (should store in the key structure) */
1041
4.00k
    PORT_Memset(keyHash, 0, sizeof(keyHash));
1042
4.00k
    hashContext = (*hash->create)();
1043
4.00k
    if (hashContext == NULL) {
1044
0
        return NULL;
1045
0
    }
1046
4.00k
    (*hash->begin)(hashContext);
1047
4.00k
    if (privKeyLen < inputLen) {
1048
0
        int padLen = inputLen - privKeyLen;
1049
0
        while (padLen > sizeof(keyHash)) {
1050
0
            (*hash->update)(hashContext, keyHash, sizeof(keyHash));
1051
0
            padLen -= sizeof(keyHash);
1052
0
        }
1053
0
        (*hash->update)(hashContext, keyHash, padLen);
1054
0
    }
1055
4.00k
    (*hash->update)(hashContext, key->privateExponent.data, privKeyLen);
1056
4.00k
    (*hash->end)(hashContext, keyHash, &keyLen, sizeof(keyHash));
1057
4.00k
    (*hash->destroy)(hashContext, PR_TRUE);
1058
1059
    /* now create the hmac key */
1060
4.00k
    hmac = HMAC_Create(hash, keyHash, keyLen, PR_TRUE);
1061
4.00k
    if (hmac == NULL) {
1062
0
        PORT_SafeZero(keyHash, sizeof(keyHash));
1063
0
        return NULL;
1064
0
    }
1065
4.00k
    HMAC_Begin(hmac);
1066
4.00k
    HMAC_Update(hmac, input, inputLen);
1067
4.00k
    rv = HMAC_Finish(hmac, keyHash, &keyLen, sizeof(keyHash));
1068
4.00k
    if (rv != SECSuccess) {
1069
0
        PORT_SafeZero(keyHash, sizeof(keyHash));
1070
0
        HMAC_Destroy(hmac, PR_TRUE);
1071
0
        return NULL;
1072
0
    }
1073
    /* Finally set the new key into the hash context. We
1074
     * reuse the original context allocated above so we don't
1075
     * need to allocate and free another one */
1076
4.00k
    rv = HMAC_ReInit(hmac, hash, keyHash, keyLen, PR_TRUE);
1077
4.00k
    PORT_SafeZero(keyHash, sizeof(keyHash));
1078
4.00k
    if (rv != SECSuccess) {
1079
0
        HMAC_Destroy(hmac, PR_TRUE);
1080
0
        return NULL;
1081
0
    }
1082
1083
4.00k
    return hmac;
1084
4.00k
}
1085
1086
static SECStatus
1087
rsa_HMACPrf(HMACContext *hmac, const char *label, int labelLen,
1088
            int hashLength, unsigned char *output, int length)
1089
8.00k
{
1090
8.00k
    unsigned char iterator[2] = { 0, 0 };
1091
8.00k
    unsigned char encodedLen[2] = { 0, 0 };
1092
8.00k
    unsigned char hmacLast[HASH_LENGTH_MAX];
1093
8.00k
    unsigned int left = length;
1094
8.00k
    unsigned int hashReturn;
1095
8.00k
    SECStatus rv = SECSuccess;
1096
1097
    /* encodedLen is in bits, length is in bytes, thus the shifts
1098
     * do an implied multiply by 8 */
1099
8.00k
    encodedLen[0] = (length >> 5) & 0xff;
1100
8.00k
    encodedLen[1] = (length << 3) & 0xff;
1101
1102
64.0k
    while (left > hashLength) {
1103
56.0k
        HMAC_Begin(hmac);
1104
56.0k
        HMAC_Update(hmac, iterator, 2);
1105
56.0k
        HMAC_Update(hmac, (const unsigned char *)label, labelLen);
1106
56.0k
        HMAC_Update(hmac, encodedLen, 2);
1107
56.0k
        rv = HMAC_Finish(hmac, output, &hashReturn, hashLength);
1108
56.0k
        if (rv != SECSuccess) {
1109
0
            return rv;
1110
0
        }
1111
56.0k
        iterator[1]++;
1112
56.0k
        if (iterator[1] == 0)
1113
0
            iterator[0]++;
1114
56.0k
        left -= hashLength;
1115
56.0k
        output += hashLength;
1116
56.0k
    }
1117
8.00k
    if (left) {
1118
8.00k
        HMAC_Begin(hmac);
1119
8.00k
        HMAC_Update(hmac, iterator, 2);
1120
8.00k
        HMAC_Update(hmac, (const unsigned char *)label, labelLen);
1121
8.00k
        HMAC_Update(hmac, encodedLen, 2);
1122
8.00k
        rv = HMAC_Finish(hmac, hmacLast, &hashReturn, sizeof(hmacLast));
1123
8.00k
        if (rv != SECSuccess) {
1124
0
            return rv;
1125
0
        }
1126
8.00k
        PORT_Memcpy(output, hmacLast, left);
1127
8.00k
        PORT_SafeZero(hmacLast, sizeof(hmacLast));
1128
8.00k
    }
1129
8.00k
    return rv;
1130
8.00k
}
1131
1132
/* This function takes a 16-bit input number and
1133
 * creates the smallest mask which covers
1134
 * the whole number. Examples:
1135
 *     0x81 -> 0xff
1136
 *     0x1af -> 0x1ff
1137
 *     0x4d1 -> 0x7ff
1138
 */
1139
static int
1140
makeMask16(int len)
1141
4.00k
{
1142
    // or the high bit in each bit location
1143
4.00k
    len |= (len >> 1);
1144
4.00k
    len |= (len >> 2);
1145
4.00k
    len |= (len >> 4);
1146
4.00k
    len |= (len >> 8);
1147
4.00k
    return len;
1148
4.00k
}
1149
1150
8.00k
#define STRING_AND_LENGTH(s) s, sizeof(s) - 1
1151
static int
1152
rsa_GetErrorLength(HMACContext *hmac, int hashLen, int maxLegalLen)
1153
4.00k
{
1154
4.00k
    unsigned char out[128 * 2];
1155
4.00k
    unsigned char *outp;
1156
4.00k
    int outLength = 0;
1157
4.00k
    int lengthMask;
1158
4.00k
    SECStatus rv;
1159
1160
4.00k
    lengthMask = makeMask16(maxLegalLen);
1161
4.00k
    rv = rsa_HMACPrf(hmac, STRING_AND_LENGTH("length"), hashLen,
1162
4.00k
                     out, sizeof(out));
1163
4.00k
    if (rv != SECSuccess) {
1164
0
        return -1;
1165
0
    }
1166
516k
    for (outp = out; outp < out + sizeof(out); outp += 2) {
1167
512k
        int candidate = outp[0] << 8 | outp[1];
1168
512k
        candidate = candidate & lengthMask;
1169
512k
        outLength = PORT_CT_SEL(PORT_CT_LT(candidate, maxLegalLen),
1170
512k
                                candidate, outLength);
1171
512k
    }
1172
4.00k
    PORT_SafeZero(out, sizeof(out));
1173
4.00k
    return outLength;
1174
4.00k
}
1175
1176
/*
1177
 * This function can only fail in environmental cases: Programming errors
1178
 * and out of memory situations. It can't fail if the keys are valid and
1179
 * the inputs are the proper size. If the actual RSA decryption fails, a
1180
 * fake value and a fake length, both of which have already been generated
1181
 * based on the key and input, are returned.
1182
 * Applications are expected to detect decryption failures based on the fact
1183
 * that the decrypted value (usually a key) doesn't validate. The prevents
1184
 * Blecheinbaucher style attacks against the key. */
1185
SECStatus
1186
RSA_DecryptBlock(RSAPrivateKey *key,
1187
                 unsigned char *output,
1188
                 unsigned int *outputLen,
1189
                 unsigned int maxOutputLen,
1190
                 const unsigned char *input,
1191
                 unsigned int inputLen)
1192
90.0k
{
1193
90.0k
    SECStatus rv;
1194
90.0k
    PRUint32 fail;
1195
90.0k
    unsigned int modulusLen = rsa_modulusLen(&key->modulus);
1196
90.0k
    unsigned int i;
1197
90.0k
    unsigned char *buffer = NULL;
1198
90.0k
    unsigned char *errorBuffer = NULL;
1199
90.0k
    unsigned char *bp = NULL;
1200
90.0k
    unsigned char *ep = NULL;
1201
90.0k
    unsigned int outLen = modulusLen;
1202
90.0k
    unsigned int maxLegalLen = modulusLen - 10;
1203
90.0k
    unsigned int errorLength;
1204
90.0k
    const SECHashObject *hashObj;
1205
90.0k
    HMACContext *hmac = NULL;
1206
1207
    /* failures in the top section indicate failures in the environment
1208
     * (memory) or the library. OK to return errors in these cases because
1209
     * it doesn't provide any oracle information to attackers. */
1210
90.0k
    if (inputLen != modulusLen || modulusLen < 10) {
1211
86.0k
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
1212
86.0k
        return SECFailure;
1213
86.0k
    }
1214
1215
    /* Allocate enough space to decrypt */
1216
4.00k
    buffer = PORT_ZAlloc(modulusLen);
1217
4.00k
    if (!buffer) {
1218
0
        goto loser;
1219
0
    }
1220
4.00k
    errorBuffer = PORT_ZAlloc(modulusLen);
1221
4.00k
    if (!errorBuffer) {
1222
0
        goto loser;
1223
0
    }
1224
4.00k
    hashObj = HASH_GetRawHashObject(HASH_AlgSHA256);
1225
4.00k
    if (hashObj == NULL) {
1226
0
        goto loser;
1227
0
    }
1228
1229
    /* calculate the values to return in the error case rather than
1230
     * the actual returned values. This data is the same for the
1231
     * same input and private key. */
1232
4.00k
    hmac = rsa_GetHMACContext(hashObj, key, input, inputLen);
1233
4.00k
    if (hmac == NULL) {
1234
0
        goto loser;
1235
0
    }
1236
4.00k
    errorLength = rsa_GetErrorLength(hmac, hashObj->length, maxLegalLen);
1237
4.00k
    if (((int)errorLength) < 0) {
1238
0
        goto loser;
1239
0
    }
1240
    /* we always have to generate a full moduluslen error string. Otherwise
1241
     * we create a timing dependency on errorLength, which could be used to
1242
     * determine the difference between errorLength and outputLen and tell
1243
     * us that there was a pkcs1 decryption failure */
1244
4.00k
    rv = rsa_HMACPrf(hmac, STRING_AND_LENGTH("message"),
1245
4.00k
                     hashObj->length, errorBuffer, modulusLen);
1246
4.00k
    if (rv != SECSuccess) {
1247
0
        goto loser;
1248
0
    }
1249
1250
4.00k
    HMAC_Destroy(hmac, PR_TRUE);
1251
4.00k
    hmac = NULL;
1252
1253
    /* From here on out, we will always return success. If there is
1254
     * an error, we will return deterministic output based on the key
1255
     * and the input data. */
1256
4.00k
    rv = RSA_PrivateKeyOp(key, buffer, input);
1257
1258
4.00k
    fail = PORT_CT_NE(rv, SECSuccess);
1259
4.00k
    fail |= PORT_CT_NE(buffer[0], RSA_BLOCK_FIRST_OCTET) | PORT_CT_NE(buffer[1], RSA_BlockPublic);
1260
1261
    /* There have to be at least 8 bytes of padding. */
1262
36.0k
    for (i = 2; i < 10; i++) {
1263
32.0k
        fail |= PORT_CT_EQ(buffer[i], RSA_BLOCK_AFTER_PAD_OCTET);
1264
32.0k
    }
1265
1266
988k
    for (i = 10; i < modulusLen; i++) {
1267
984k
        unsigned int newLen = modulusLen - i - 1;
1268
984k
        PRUint32 condition = PORT_CT_EQ(buffer[i], RSA_BLOCK_AFTER_PAD_OCTET) & PORT_CT_EQ(outLen, modulusLen);
1269
984k
        outLen = PORT_CT_SEL(condition, newLen, outLen);
1270
984k
    }
1271
    // this can only happen if a zero wasn't found above
1272
4.00k
    fail |= PORT_CT_GE(outLen, modulusLen);
1273
1274
4.00k
    outLen = PORT_CT_SEL(fail, errorLength, outLen);
1275
1276
    /* index into the correct buffer. Do it before we truncate outLen if the
1277
     * application was asking for less data than we can return */
1278
4.00k
    bp = buffer + modulusLen - outLen;
1279
4.00k
    ep = errorBuffer + modulusLen - outLen;
1280
1281
    /* at this point, outLen returns no information about decryption failures,
1282
     * no need to hide its value. maxOutputLen is how much data the
1283
     * application is expecting, which is also not sensitive. */
1284
4.00k
    if (outLen > maxOutputLen) {
1285
0
        outLen = maxOutputLen;
1286
0
    }
1287
1288
    /* we can't use PORT_Memcpy because caching could create a time dependency
1289
     * on the status of fail. */
1290
512k
    for (i = 0; i < outLen; i++) {
1291
508k
        output[i] = PORT_CT_SEL(fail, ep[i], bp[i]);
1292
508k
    }
1293
1294
4.00k
    *outputLen = outLen;
1295
1296
4.00k
    PORT_Free(buffer);
1297
4.00k
    PORT_Free(errorBuffer);
1298
1299
4.00k
    return SECSuccess;
1300
1301
0
loser:
1302
0
    if (hmac) {
1303
0
        HMAC_Destroy(hmac, PR_TRUE);
1304
0
    }
1305
0
    PORT_Free(buffer);
1306
0
    PORT_Free(errorBuffer);
1307
1308
0
    return SECFailure;
1309
4.00k
}
1310
1311
/*
1312
 * Encode a RSA-PSS signature.
1313
 * Described in RFC 3447, section 9.1.1.
1314
 * We use mHash instead of M as input.
1315
 * emBits from the RFC is just modBits - 1, see section 8.1.1.
1316
 * We only support MGF1 as the MGF.
1317
 */
1318
SECStatus
1319
RSA_EMSAEncodePSS(unsigned char *em,
1320
                  unsigned int emLen,
1321
                  unsigned int emBits,
1322
                  const unsigned char *mHash,
1323
                  unsigned int mHashLen,
1324
                  HASH_HashType hashAlg,
1325
                  HASH_HashType maskHashAlg,
1326
                  const unsigned char *salt,
1327
                  unsigned int saltLen)
1328
2.72k
{
1329
2.72k
    const SECHashObject *hash;
1330
2.72k
    void *hash_context;
1331
2.72k
    unsigned char *dbMask;
1332
2.72k
    unsigned int dbMaskLen;
1333
2.72k
    unsigned int i;
1334
2.72k
    SECStatus rv;
1335
1336
2.72k
    hash = HASH_GetRawHashObject(hashAlg);
1337
2.72k
    PORT_Assert(hash);
1338
1339
2.72k
    if (mHashLen < hash->length) {
1340
0
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
1341
0
        return SECFailure;
1342
0
    }
1343
1344
2.72k
    dbMaskLen = emLen - hash->length - 1;
1345
1346
    /* Step 3 */
1347
2.72k
    if (emLen < hash->length + saltLen + 2) {
1348
0
        PORT_SetError(SEC_ERROR_OUTPUT_LEN);
1349
0
        return SECFailure;
1350
0
    }
1351
1352
    /* Step 4 */
1353
2.72k
    if (salt == NULL) {
1354
2.72k
        rv = RNG_GenerateGlobalRandomBytes(&em[dbMaskLen - saltLen], saltLen);
1355
2.72k
        if (rv != SECSuccess) {
1356
0
            return rv;
1357
0
        }
1358
2.72k
    } else {
1359
0
        PORT_Memcpy(&em[dbMaskLen - saltLen], salt, saltLen);
1360
0
    }
1361
1362
    /* Step 5 + 6 */
1363
    /* Compute H and store it at its final location &em[dbMaskLen]. */
1364
2.72k
    hash_context = (*hash->create)();
1365
2.72k
    if (hash_context == NULL) {
1366
0
        PORT_SetError(SEC_ERROR_NO_MEMORY);
1367
0
        return SECFailure;
1368
0
    }
1369
2.72k
    (*hash->begin)(hash_context);
1370
2.72k
    (*hash->update)(hash_context, eightZeros, 8);
1371
2.72k
    (*hash->update)(hash_context, mHash, hash->length);
1372
2.72k
    (*hash->update)(hash_context, &em[dbMaskLen - saltLen], saltLen);
1373
2.72k
    (*hash->end)(hash_context, &em[dbMaskLen], &i, hash->length);
1374
2.72k
    (*hash->destroy)(hash_context, PR_TRUE);
1375
1376
    /* Step 7 + 8 */
1377
2.72k
    PORT_Memset(em, 0, dbMaskLen - saltLen - 1);
1378
2.72k
    em[dbMaskLen - saltLen - 1] = 0x01;
1379
1380
    /* Step 9 */
1381
2.72k
    dbMask = (unsigned char *)PORT_Alloc(dbMaskLen);
1382
2.72k
    if (dbMask == NULL) {
1383
0
        PORT_SetError(SEC_ERROR_NO_MEMORY);
1384
0
        return SECFailure;
1385
0
    }
1386
2.72k
    MGF1(maskHashAlg, dbMask, dbMaskLen, &em[dbMaskLen], hash->length);
1387
1388
    /* Step 10 */
1389
572k
    for (i = 0; i < dbMaskLen; i++)
1390
569k
        em[i] ^= dbMask[i];
1391
2.72k
    PORT_Free(dbMask);
1392
1393
    /* Step 11 */
1394
2.72k
    em[0] &= 0xff >> (8 * emLen - emBits);
1395
1396
    /* Step 12 */
1397
2.72k
    em[emLen - 1] = 0xbc;
1398
1399
2.72k
    return SECSuccess;
1400
2.72k
}
1401
1402
/*
1403
 * Verify a RSA-PSS signature.
1404
 * Described in RFC 3447, section 9.1.2.
1405
 * We use mHash instead of M as input.
1406
 * emBits from the RFC is just modBits - 1, see section 8.1.2.
1407
 * We only support MGF1 as the MGF.
1408
 */
1409
static SECStatus
1410
emsa_pss_verify(const unsigned char *mHash,
1411
                const unsigned char *em,
1412
                unsigned int emLen,
1413
                unsigned int emBits,
1414
                HASH_HashType hashAlg,
1415
                HASH_HashType maskHashAlg,
1416
                unsigned int saltLen)
1417
2.36k
{
1418
2.36k
    const SECHashObject *hash;
1419
2.36k
    void *hash_context;
1420
2.36k
    unsigned char *db;
1421
2.36k
    unsigned char *H_; /* H' from the RFC */
1422
2.36k
    unsigned int i;
1423
2.36k
    unsigned int dbMaskLen;
1424
2.36k
    unsigned int zeroBits;
1425
2.36k
    SECStatus rv;
1426
1427
2.36k
    hash = HASH_GetRawHashObject(hashAlg);
1428
2.36k
    dbMaskLen = emLen - hash->length - 1;
1429
1430
    /* Step 3 + 4 */
1431
2.36k
    if ((emLen < (hash->length + saltLen + 2)) ||
1432
2.21k
        (em[emLen - 1] != 0xbc)) {
1433
2.06k
        PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
1434
2.06k
        return SECFailure;
1435
2.06k
    }
1436
1437
    /* Step 6 */
1438
301
    zeroBits = 8 * emLen - emBits;
1439
301
    if (em[0] >> (8 - zeroBits)) {
1440
19
        PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
1441
19
        return SECFailure;
1442
19
    }
1443
1444
    /* Step 7 */
1445
282
    db = (unsigned char *)PORT_Alloc(dbMaskLen);
1446
282
    if (db == NULL) {
1447
0
        PORT_SetError(SEC_ERROR_NO_MEMORY);
1448
0
        return SECFailure;
1449
0
    }
1450
    /* &em[dbMaskLen] points to H, used as mgfSeed */
1451
282
    MGF1(maskHashAlg, db, dbMaskLen, &em[dbMaskLen], hash->length);
1452
1453
    /* Step 8 */
1454
51.6k
    for (i = 0; i < dbMaskLen; i++) {
1455
51.3k
        db[i] ^= em[i];
1456
51.3k
    }
1457
1458
    /* Step 9 */
1459
282
    db[0] &= 0xff >> zeroBits;
1460
1461
    /* Step 10 */
1462
19.6k
    for (i = 0; i < (dbMaskLen - saltLen - 1); i++) {
1463
19.4k
        if (db[i] != 0) {
1464
147
            PORT_Free(db);
1465
147
            PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
1466
147
            return SECFailure;
1467
147
        }
1468
19.4k
    }
1469
135
    if (db[dbMaskLen - saltLen - 1] != 0x01) {
1470
1
        PORT_Free(db);
1471
1
        PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
1472
1
        return SECFailure;
1473
1
    }
1474
1475
    /* Step 12 + 13 */
1476
134
    H_ = (unsigned char *)PORT_Alloc(hash->length);
1477
134
    if (H_ == NULL) {
1478
0
        PORT_Free(db);
1479
0
        PORT_SetError(SEC_ERROR_NO_MEMORY);
1480
0
        return SECFailure;
1481
0
    }
1482
134
    hash_context = (*hash->create)();
1483
134
    if (hash_context == NULL) {
1484
0
        PORT_Free(db);
1485
0
        PORT_Free(H_);
1486
0
        PORT_SetError(SEC_ERROR_NO_MEMORY);
1487
0
        return SECFailure;
1488
0
    }
1489
134
    (*hash->begin)(hash_context);
1490
134
    (*hash->update)(hash_context, eightZeros, 8);
1491
134
    (*hash->update)(hash_context, mHash, hash->length);
1492
134
    (*hash->update)(hash_context, &db[dbMaskLen - saltLen], saltLen);
1493
134
    (*hash->end)(hash_context, H_, &i, hash->length);
1494
134
    (*hash->destroy)(hash_context, PR_TRUE);
1495
1496
134
    PORT_Free(db);
1497
1498
    /* Step 14 */
1499
134
    if (PORT_Memcmp(H_, &em[dbMaskLen], hash->length) != 0) {
1500
92
        PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
1501
92
        rv = SECFailure;
1502
92
    } else {
1503
42
        rv = SECSuccess;
1504
42
    }
1505
1506
134
    PORT_Free(H_);
1507
134
    return rv;
1508
134
}
1509
1510
SECStatus
1511
RSA_SignPSS(RSAPrivateKey *key,
1512
            HASH_HashType hashAlg,
1513
            HASH_HashType maskHashAlg,
1514
            const unsigned char *salt,
1515
            unsigned int saltLength,
1516
            unsigned char *output,
1517
            unsigned int *outputLen,
1518
            unsigned int maxOutputLen,
1519
            const unsigned char *input,
1520
            unsigned int inputLen)
1521
2.72k
{
1522
2.72k
    SECStatus rv = SECSuccess;
1523
2.72k
    unsigned int modulusLen = rsa_modulusLen(&key->modulus);
1524
2.72k
    unsigned int modulusBits = rsa_modulusBits(&key->modulus);
1525
2.72k
    unsigned int emLen = modulusLen;
1526
2.72k
    unsigned char *pssEncoded, *em;
1527
1528
2.72k
    if (maxOutputLen < modulusLen) {
1529
0
        PORT_SetError(SEC_ERROR_OUTPUT_LEN);
1530
0
        return SECFailure;
1531
0
    }
1532
1533
2.72k
    if ((hashAlg == HASH_AlgNULL) || (maskHashAlg == HASH_AlgNULL)) {
1534
0
        PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
1535
0
        return SECFailure;
1536
0
    }
1537
1538
2.72k
    pssEncoded = em = (unsigned char *)PORT_Alloc(modulusLen);
1539
2.72k
    if (pssEncoded == NULL) {
1540
0
        PORT_SetError(SEC_ERROR_NO_MEMORY);
1541
0
        return SECFailure;
1542
0
    }
1543
1544
    /* len(em) == ceil((modulusBits - 1) / 8). */
1545
2.72k
    if (modulusBits % 8 == 1) {
1546
0
        em[0] = 0;
1547
0
        emLen--;
1548
0
        em++;
1549
0
    }
1550
2.72k
    rv = RSA_EMSAEncodePSS(em, emLen, modulusBits - 1, input, inputLen, hashAlg,
1551
2.72k
                           maskHashAlg, salt, saltLength);
1552
2.72k
    if (rv != SECSuccess)
1553
0
        goto done;
1554
1555
    // This sets error codes upon failure.
1556
2.72k
    rv = RSA_PrivateKeyOpDoubleChecked(key, output, pssEncoded);
1557
2.72k
    *outputLen = modulusLen;
1558
1559
2.72k
done:
1560
2.72k
    PORT_Free(pssEncoded);
1561
2.72k
    return rv;
1562
2.72k
}
1563
1564
SECStatus
1565
RSA_CheckSignPSS(RSAPublicKey *key,
1566
                 HASH_HashType hashAlg,
1567
                 HASH_HashType maskHashAlg,
1568
                 unsigned int saltLength,
1569
                 const unsigned char *sig,
1570
                 unsigned int sigLen,
1571
                 const unsigned char *hash,
1572
                 unsigned int hashLen)
1573
2.43k
{
1574
2.43k
    SECStatus rv;
1575
2.43k
    unsigned int modulusLen = rsa_modulusLen(&key->modulus);
1576
2.43k
    unsigned int modulusBits = rsa_modulusBits(&key->modulus);
1577
2.43k
    unsigned int emLen = modulusLen;
1578
2.43k
    unsigned char *buffer, *em;
1579
1580
2.43k
    if (sigLen != modulusLen) {
1581
43
        PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
1582
43
        return SECFailure;
1583
43
    }
1584
1585
2.38k
    if ((hashAlg == HASH_AlgNULL) || (maskHashAlg == HASH_AlgNULL)) {
1586
0
        PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
1587
0
        return SECFailure;
1588
0
    }
1589
1590
2.38k
    buffer = em = (unsigned char *)PORT_Alloc(modulusLen);
1591
2.38k
    if (!buffer) {
1592
0
        PORT_SetError(SEC_ERROR_NO_MEMORY);
1593
0
        return SECFailure;
1594
0
    }
1595
1596
2.38k
    rv = RSA_PublicKeyOp(key, buffer, sig);
1597
2.38k
    if (rv != SECSuccess) {
1598
25
        PORT_Free(buffer);
1599
25
        PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
1600
25
        return SECFailure;
1601
25
    }
1602
1603
    /* len(em) == ceil((modulusBits - 1) / 8). */
1604
2.36k
    if (modulusBits % 8 == 1) {
1605
30
        emLen--;
1606
30
        em++;
1607
30
    }
1608
2.36k
    rv = emsa_pss_verify(hash, em, emLen, modulusBits - 1, hashAlg,
1609
2.36k
                         maskHashAlg, saltLength);
1610
1611
2.36k
    PORT_Free(buffer);
1612
2.36k
    return rv;
1613
2.38k
}
1614
1615
SECStatus
1616
RSA_Sign(RSAPrivateKey *key,
1617
         unsigned char *output,
1618
         unsigned int *outputLen,
1619
         unsigned int maxOutputLen,
1620
         const unsigned char *input,
1621
         unsigned int inputLen)
1622
21.6k
{
1623
21.6k
    SECStatus rv = SECFailure;
1624
21.6k
    unsigned int modulusLen = rsa_modulusLen(&key->modulus);
1625
21.6k
    SECItem formatted = { siBuffer, NULL, 0 };
1626
21.6k
    SECItem unformatted = { siBuffer, (unsigned char *)input, inputLen };
1627
1628
21.6k
    if (maxOutputLen < modulusLen) {
1629
0
        PORT_SetError(SEC_ERROR_OUTPUT_LEN);
1630
0
        goto done;
1631
0
    }
1632
1633
21.6k
    rv = rsa_FormatBlock(&formatted, modulusLen, RSA_BlockPrivate,
1634
21.6k
                         &unformatted);
1635
21.6k
    if (rv != SECSuccess) {
1636
0
        PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
1637
0
        goto done;
1638
0
    }
1639
1640
    // This sets error codes upon failure.
1641
21.6k
    rv = RSA_PrivateKeyOpDoubleChecked(key, output, formatted.data);
1642
21.6k
    *outputLen = modulusLen;
1643
1644
21.6k
done:
1645
21.6k
    if (formatted.data != NULL) {
1646
21.6k
        PORT_ZFree(formatted.data, modulusLen);
1647
21.6k
    }
1648
21.6k
    return rv;
1649
21.6k
}
1650
1651
SECStatus
1652
RSA_CheckSign(RSAPublicKey *key,
1653
              const unsigned char *sig,
1654
              unsigned int sigLen,
1655
              const unsigned char *data,
1656
              unsigned int dataLen)
1657
1.24k
{
1658
1.24k
    SECStatus rv = SECFailure;
1659
1.24k
    unsigned int modulusLen = rsa_modulusLen(&key->modulus);
1660
1.24k
    unsigned int i;
1661
1.24k
    unsigned char *buffer = NULL;
1662
1663
1.24k
    if (sigLen != modulusLen) {
1664
55
        PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
1665
55
        goto done;
1666
55
    }
1667
1668
    /*
1669
     * 0x00 || BT || Pad || 0x00 || ActualData
1670
     *
1671
     * The "3" below is the first octet + the second octet + the 0x00
1672
     * octet that always comes just before the ActualData.
1673
     */
1674
1.19k
    if (dataLen > modulusLen - (3 + RSA_BLOCK_MIN_PAD_LEN)) {
1675
0
        PORT_SetError(SEC_ERROR_BAD_DATA);
1676
0
        goto done;
1677
0
    }
1678
1679
1.19k
    buffer = (unsigned char *)PORT_Alloc(modulusLen + 1);
1680
1.19k
    if (!buffer) {
1681
0
        PORT_SetError(SEC_ERROR_NO_MEMORY);
1682
0
        goto done;
1683
0
    }
1684
1685
1.19k
    if (RSA_PublicKeyOp(key, buffer, sig) != SECSuccess) {
1686
23
        PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
1687
23
        goto done;
1688
23
    }
1689
1690
    /*
1691
     * check the padding that was used
1692
     */
1693
1.16k
    if (buffer[0] != RSA_BLOCK_FIRST_OCTET ||
1694
1.10k
        buffer[1] != (unsigned char)RSA_BlockPrivate) {
1695
1.10k
        PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
1696
1.10k
        goto done;
1697
1.10k
    }
1698
6.00k
    for (i = 2; i < modulusLen - dataLen - 1; i++) {
1699
5.96k
        if (buffer[i] != RSA_BLOCK_PRIVATE_PAD_OCTET) {
1700
27
            PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
1701
27
            goto done;
1702
27
        }
1703
5.96k
    }
1704
36
    if (buffer[i] != RSA_BLOCK_AFTER_PAD_OCTET) {
1705
1
        PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
1706
1
        goto done;
1707
1
    }
1708
1709
    /*
1710
     * make sure we get the same results
1711
     */
1712
35
    if (PORT_Memcmp(buffer + modulusLen - dataLen, data, dataLen) == 0) {
1713
6
        rv = SECSuccess;
1714
6
    }
1715
1716
1.24k
done:
1717
1.24k
    if (buffer) {
1718
1.19k
        PORT_Free(buffer);
1719
1.19k
    }
1720
1.24k
    return rv;
1721
35
}
1722
1723
SECStatus
1724
RSA_CheckSignRecover(RSAPublicKey *key,
1725
                     unsigned char *output,
1726
                     unsigned int *outputLen,
1727
                     unsigned int maxOutputLen,
1728
                     const unsigned char *sig,
1729
                     unsigned int sigLen)
1730
19.7k
{
1731
19.7k
    SECStatus rv = SECFailure;
1732
19.7k
    unsigned int modulusLen = rsa_modulusLen(&key->modulus);
1733
19.7k
    unsigned int i;
1734
19.7k
    unsigned char *buffer = NULL;
1735
19.7k
    unsigned int padLen;
1736
1737
19.7k
    if (sigLen != modulusLen) {
1738
665
        PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
1739
665
        goto done;
1740
665
    }
1741
1742
19.0k
    buffer = (unsigned char *)PORT_Alloc(modulusLen + 1);
1743
19.0k
    if (!buffer) {
1744
0
        PORT_SetError(SEC_ERROR_NO_MEMORY);
1745
0
        goto done;
1746
0
    }
1747
1748
19.0k
    if (RSA_PublicKeyOp(key, buffer, sig) != SECSuccess) {
1749
272
        PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
1750
272
        goto done;
1751
272
    }
1752
1753
18.7k
    *outputLen = 0;
1754
1755
    /*
1756
     * check the padding that was used
1757
     */
1758
18.7k
    if (buffer[0] != RSA_BLOCK_FIRST_OCTET ||
1759
18.5k
        buffer[1] != (unsigned char)RSA_BlockPrivate) {
1760
18.5k
        PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
1761
18.5k
        goto done;
1762
18.5k
    }
1763
21.4k
    for (i = 2; i < modulusLen; i++) {
1764
21.4k
        if (buffer[i] == RSA_BLOCK_AFTER_PAD_OCTET) {
1765
196
            *outputLen = modulusLen - i - 1;
1766
196
            break;
1767
196
        }
1768
21.2k
        if (buffer[i] != RSA_BLOCK_PRIVATE_PAD_OCTET) {
1769
60
            PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
1770
60
            goto done;
1771
60
        }
1772
21.2k
    }
1773
197
    padLen = i - 2;
1774
197
    if (padLen < RSA_BLOCK_MIN_PAD_LEN) {
1775
21
        PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
1776
21
        goto done;
1777
21
    }
1778
176
    if (*outputLen == 0) {
1779
1
        PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
1780
1
        goto done;
1781
1
    }
1782
175
    if (*outputLen > maxOutputLen) {
1783
0
        PORT_SetError(SEC_ERROR_OUTPUT_LEN);
1784
0
        goto done;
1785
0
    }
1786
1787
175
    PORT_Memcpy(output, buffer + modulusLen - *outputLen, *outputLen);
1788
175
    rv = SECSuccess;
1789
1790
19.7k
done:
1791
19.7k
    if (buffer) {
1792
19.0k
        PORT_Free(buffer);
1793
19.0k
    }
1794
19.7k
    return rv;
1795
175
}