Coverage Report

Created: 2026-04-02 07:09

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/boringssl/crypto/rsa/rsa_crypt.cc
Line
Count
Source
1
// Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
2
//
3
// Licensed under the Apache License, Version 2.0 (the "License");
4
// you may not use this file except in compliance with the License.
5
// You may obtain a copy of the License at
6
//
7
//     https://www.apache.org/licenses/LICENSE-2.0
8
//
9
// Unless required by applicable law or agreed to in writing, software
10
// distributed under the License is distributed on an "AS IS" BASIS,
11
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
// See the License for the specific language governing permissions and
13
// limitations under the License.
14
15
#include <openssl/base.h>
16
17
#include <limits.h>
18
19
#include <openssl/bn.h>
20
#include <openssl/err.h>
21
#include <openssl/evp.h>
22
#include <openssl/mem.h>
23
#include <openssl/rand.h>
24
#include <openssl/rsa.h>
25
26
#include "../fipsmodule/bn/internal.h"
27
#include "../fipsmodule/rsa/internal.h"
28
#include "../internal.h"
29
#include "internal.h"
30
31
32
using namespace bssl;
33
34
2.67k
static void rand_nonzero(uint8_t *out, size_t len) {
35
2.67k
  RAND_bytes(out, len);
36
37
526k
  for (size_t i = 0; i < len; i++) {
38
    // Zero values are replaced, and the distribution of zero and non-zero bytes
39
    // is public, so leaking this is safe.
40
526k
    while (constant_time_declassify_int(out[i] == 0)) {
41
2.04k
      RAND_bytes(out + i, 1);
42
2.04k
    }
43
524k
  }
44
2.67k
}
45
46
int RSA_padding_add_PKCS1_OAEP_mgf1(uint8_t *to, size_t to_len,
47
                                    const uint8_t *from, size_t from_len,
48
                                    const uint8_t *param, size_t param_len,
49
0
                                    const EVP_MD *md, const EVP_MD *mgf1md) {
50
0
  if (md == nullptr) {
51
0
    md = EVP_sha1();
52
0
  }
53
0
  if (mgf1md == nullptr) {
54
0
    mgf1md = md;
55
0
  }
56
57
0
  size_t mdlen = EVP_MD_size(md);
58
59
0
  if (to_len < 2 * mdlen + 2) {
60
0
    OPENSSL_PUT_ERROR(RSA, RSA_R_KEY_SIZE_TOO_SMALL);
61
0
    return 0;
62
0
  }
63
64
0
  size_t emlen = to_len - 1;
65
0
  if (from_len > emlen - 2 * mdlen - 1) {
66
0
    OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
67
0
    return 0;
68
0
  }
69
70
0
  if (emlen < 2 * mdlen + 1) {
71
0
    OPENSSL_PUT_ERROR(RSA, RSA_R_KEY_SIZE_TOO_SMALL);
72
0
    return 0;
73
0
  }
74
75
0
  to[0] = 0;
76
0
  uint8_t *seed = to + 1;
77
0
  uint8_t *db = to + mdlen + 1;
78
79
0
  uint8_t *dbmask = nullptr;
80
0
  int ret = 0;
81
0
  if (!EVP_Digest(param, param_len, db, nullptr, md, nullptr)) {
82
0
    goto out;
83
0
  }
84
0
  OPENSSL_memset(db + mdlen, 0, emlen - from_len - 2 * mdlen - 1);
85
0
  db[emlen - from_len - mdlen - 1] = 0x01;
86
0
  OPENSSL_memcpy(db + emlen - from_len - mdlen, from, from_len);
87
0
  if (!RAND_bytes(seed, mdlen)) {
88
0
    goto out;
89
0
  }
90
91
0
  dbmask = reinterpret_cast<uint8_t *>(OPENSSL_malloc(emlen - mdlen));
92
0
  if (dbmask == nullptr) {
93
0
    goto out;
94
0
  }
95
96
0
  if (!PKCS1_MGF1(dbmask, emlen - mdlen, seed, mdlen, mgf1md)) {
97
0
    goto out;
98
0
  }
99
0
  for (size_t i = 0; i < emlen - mdlen; i++) {
100
0
    db[i] ^= dbmask[i];
101
0
  }
102
103
0
  uint8_t seedmask[EVP_MAX_MD_SIZE];
104
0
  if (!PKCS1_MGF1(seedmask, mdlen, db, emlen - mdlen, mgf1md)) {
105
0
    goto out;
106
0
  }
107
0
  for (size_t i = 0; i < mdlen; i++) {
108
0
    seed[i] ^= seedmask[i];
109
0
  }
110
0
  ret = 1;
111
112
0
out:
113
0
  OPENSSL_free(dbmask);
114
0
  return ret;
115
0
}
116
117
int bssl::RSA_padding_check_PKCS1_OAEP_mgf1(uint8_t *out, size_t *out_len,
118
                                            size_t max_out, const uint8_t *from,
119
                                            size_t from_len,
120
                                            const uint8_t *param,
121
                                            size_t param_len, const EVP_MD *md,
122
0
                                            const EVP_MD *mgf1md) {
123
0
  uint8_t *db = nullptr;
124
125
0
  {
126
0
    if (md == nullptr) {
127
0
      md = EVP_sha1();
128
0
    }
129
0
    if (mgf1md == nullptr) {
130
0
      mgf1md = md;
131
0
    }
132
133
0
    size_t mdlen = EVP_MD_size(md);
134
135
    // The encoded message is one byte smaller than the modulus to ensure that
136
    // it doesn't end up greater than the modulus. Thus there's an extra "+1"
137
    // here compared to https://tools.ietf.org/html/rfc2437#section-9.1.1.2.
138
0
    if (from_len < 1 + 2 * mdlen + 1) {
139
      // 'from_len' is the length of the modulus, i.e. does not depend on the
140
      // particular ciphertext.
141
0
      goto decoding_err;
142
0
    }
143
144
0
    size_t dblen = from_len - mdlen - 1;
145
0
    db = reinterpret_cast<uint8_t *>(OPENSSL_malloc(dblen));
146
0
    if (db == nullptr) {
147
0
      goto err;
148
0
    }
149
150
0
    const uint8_t *maskedseed = from + 1;
151
0
    const uint8_t *maskeddb = from + 1 + mdlen;
152
153
0
    uint8_t seed[EVP_MAX_MD_SIZE];
154
0
    if (!PKCS1_MGF1(seed, mdlen, maskeddb, dblen, mgf1md)) {
155
0
      goto err;
156
0
    }
157
0
    for (size_t i = 0; i < mdlen; i++) {
158
0
      seed[i] ^= maskedseed[i];
159
0
    }
160
161
0
    if (!PKCS1_MGF1(db, dblen, seed, mdlen, mgf1md)) {
162
0
      goto err;
163
0
    }
164
0
    for (size_t i = 0; i < dblen; i++) {
165
0
      db[i] ^= maskeddb[i];
166
0
    }
167
168
0
    uint8_t phash[EVP_MAX_MD_SIZE];
169
0
    if (!EVP_Digest(param, param_len, phash, nullptr, md, nullptr)) {
170
0
      goto err;
171
0
    }
172
173
0
    crypto_word_t bad =
174
0
        ~constant_time_is_zero_w(CRYPTO_memcmp(db, phash, mdlen));
175
0
    bad |= ~constant_time_is_zero_w(from[0]);
176
177
0
    crypto_word_t looking_for_one_byte = CONSTTIME_TRUE_W;
178
0
    size_t one_index = 0;
179
0
    for (size_t i = mdlen; i < dblen; i++) {
180
0
      crypto_word_t equals1 = constant_time_eq_w(db[i], 1);
181
0
      crypto_word_t equals0 = constant_time_eq_w(db[i], 0);
182
0
      one_index =
183
0
          constant_time_select_w(looking_for_one_byte & equals1, i, one_index);
184
0
      looking_for_one_byte =
185
0
          constant_time_select_w(equals1, 0, looking_for_one_byte);
186
0
      bad |= looking_for_one_byte & ~equals0;
187
0
    }
188
189
0
    bad |= looking_for_one_byte;
190
191
    // Whether the overall padding was valid or not in OAEP is public.
192
0
    if (constant_time_declassify_w(bad)) {
193
0
      goto decoding_err;
194
0
    }
195
196
    // Once the padding is known to be valid, the output length is also public.
197
0
    static_assert(sizeof(size_t) <= sizeof(crypto_word_t),
198
0
                  "size_t does not fit in crypto_word_t");
199
0
    one_index = constant_time_declassify_w(one_index);
200
201
0
    one_index++;
202
0
    size_t mlen = dblen - one_index;
203
0
    if (max_out < mlen) {
204
0
      OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_TOO_LARGE);
205
0
      goto err;
206
0
    }
207
208
0
    OPENSSL_memcpy(out, db + one_index, mlen);
209
0
    *out_len = mlen;
210
0
    OPENSSL_free(db);
211
0
    return 1;
212
0
  }
213
214
0
decoding_err:
215
  // To avoid chosen ciphertext attacks, the error message should not reveal
216
  // which kind of decoding error happened.
217
0
  OPENSSL_PUT_ERROR(RSA, RSA_R_OAEP_DECODING_ERROR);
218
0
err:
219
0
  OPENSSL_free(db);
220
0
  return 0;
221
0
}
222
223
static int rsa_padding_add_PKCS1_type_2(uint8_t *to, size_t to_len,
224
2.67k
                                        const uint8_t *from, size_t from_len) {
225
  // See RFC 8017, section 7.2.1.
226
2.67k
  if (to_len < RSA_PKCS1_PADDING_SIZE) {
227
0
    OPENSSL_PUT_ERROR(RSA, RSA_R_KEY_SIZE_TOO_SMALL);
228
0
    return 0;
229
0
  }
230
231
2.67k
  if (from_len > to_len - RSA_PKCS1_PADDING_SIZE) {
232
0
    OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
233
0
    return 0;
234
0
  }
235
236
2.67k
  to[0] = 0;
237
2.67k
  to[1] = 2;
238
239
2.67k
  size_t padding_len = to_len - 3 - from_len;
240
2.67k
  rand_nonzero(to + 2, padding_len);
241
2.67k
  to[2 + padding_len] = 0;
242
2.67k
  OPENSSL_memcpy(to + to_len - from_len, from, from_len);
243
2.67k
  return 1;
244
2.67k
}
245
246
static int rsa_padding_check_PKCS1_type_2(uint8_t *out, size_t *out_len,
247
                                          size_t max_out, const uint8_t *from,
248
0
                                          size_t from_len) {
249
0
  if (from_len == 0) {
250
0
    OPENSSL_PUT_ERROR(RSA, RSA_R_EMPTY_PUBLIC_KEY);
251
0
    return 0;
252
0
  }
253
254
  // PKCS#1 v1.5 decryption. See "PKCS #1 v2.2: RSA Cryptography
255
  // Standard", section 7.2.2.
256
0
  if (from_len < RSA_PKCS1_PADDING_SIZE) {
257
    // |from| is zero-padded to the size of the RSA modulus, a public value, so
258
    // this can be rejected in non-constant time.
259
0
    OPENSSL_PUT_ERROR(RSA, RSA_R_KEY_SIZE_TOO_SMALL);
260
0
    return 0;
261
0
  }
262
263
0
  crypto_word_t first_byte_is_zero = constant_time_eq_w(from[0], 0);
264
0
  crypto_word_t second_byte_is_two = constant_time_eq_w(from[1], 2);
265
266
0
  crypto_word_t zero_index = 0, looking_for_index = CONSTTIME_TRUE_W;
267
0
  for (size_t i = 2; i < from_len; i++) {
268
0
    crypto_word_t equals0 = constant_time_is_zero_w(from[i]);
269
0
    zero_index =
270
0
        constant_time_select_w(looking_for_index & equals0, i, zero_index);
271
0
    looking_for_index = constant_time_select_w(equals0, 0, looking_for_index);
272
0
  }
273
274
  // The input must begin with 00 02.
275
0
  crypto_word_t valid_index = first_byte_is_zero;
276
0
  valid_index &= second_byte_is_two;
277
278
  // We must have found the end of PS.
279
0
  valid_index &= ~looking_for_index;
280
281
  // PS must be at least 8 bytes long, and it starts two bytes into |from|.
282
0
  valid_index &= constant_time_ge_w(zero_index, 2 + 8);
283
284
  // Skip the zero byte.
285
0
  zero_index++;
286
287
  // NOTE: Although this logic attempts to be constant time, the API contracts
288
  // of this function and |RSA_decrypt| with |RSA_PKCS1_PADDING| make it
289
  // impossible to completely avoid Bleichenbacher's attack. Consumers should
290
  // use |RSA_PADDING_NONE| and perform the padding check in constant-time
291
  // combined with a swap to a random session key or other mitigation.
292
0
  CONSTTIME_DECLASSIFY(&valid_index, sizeof(valid_index));
293
0
  CONSTTIME_DECLASSIFY(&zero_index, sizeof(zero_index));
294
295
0
  if (!valid_index) {
296
0
    OPENSSL_PUT_ERROR(RSA, RSA_R_PKCS_DECODING_ERROR);
297
0
    return 0;
298
0
  }
299
300
0
  const size_t msg_len = from_len - zero_index;
301
0
  if (msg_len > max_out) {
302
    // This shouldn't happen because this function is always called with
303
    // |max_out| as the key size and |from_len| is bounded by the key size.
304
0
    OPENSSL_PUT_ERROR(RSA, RSA_R_PKCS_DECODING_ERROR);
305
0
    return 0;
306
0
  }
307
308
0
  OPENSSL_memcpy(out, &from[zero_index], msg_len);
309
0
  *out_len = msg_len;
310
0
  return 1;
311
0
}
312
313
int RSA_public_encrypt(size_t flen, const uint8_t *from, uint8_t *to, RSA *rsa,
314
0
                       int padding) {
315
0
  size_t out_len;
316
317
0
  if (!RSA_encrypt(rsa, &out_len, to, RSA_size(rsa), from, flen, padding)) {
318
0
    return -1;
319
0
  }
320
321
0
  if (out_len > INT_MAX) {
322
0
    OPENSSL_PUT_ERROR(RSA, ERR_R_OVERFLOW);
323
0
    return -1;
324
0
  }
325
0
  return (int)out_len;
326
0
}
327
328
int RSA_private_encrypt(size_t flen, const uint8_t *from, uint8_t *to, RSA *rsa,
329
0
                        int padding) {
330
0
  size_t out_len;
331
332
0
  if (!RSA_sign_raw(rsa, &out_len, to, RSA_size(rsa), from, flen, padding)) {
333
0
    return -1;
334
0
  }
335
336
0
  if (out_len > INT_MAX) {
337
0
    OPENSSL_PUT_ERROR(RSA, ERR_R_OVERFLOW);
338
0
    return -1;
339
0
  }
340
0
  return (int)out_len;
341
0
}
342
343
int RSA_encrypt(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out,
344
2.67k
                const uint8_t *in, size_t in_len, int padding) {
345
2.67k
  auto *impl = FromOpaque(rsa);
346
347
2.67k
  if (impl->n == nullptr || impl->e == nullptr) {
348
0
    OPENSSL_PUT_ERROR(RSA, RSA_R_VALUE_MISSING);
349
0
    return 0;
350
0
  }
351
352
2.67k
  if (!rsa_check_public_key(rsa)) {
353
0
    return 0;
354
0
  }
355
356
2.67k
  const unsigned rsa_size = RSA_size(rsa);
357
2.67k
  if (max_out < rsa_size) {
358
0
    OPENSSL_PUT_ERROR(RSA, RSA_R_OUTPUT_BUFFER_TOO_SMALL);
359
0
    return 0;
360
0
  }
361
362
2.67k
  UniquePtr<BN_CTX> ctx(BN_CTX_new());
363
2.67k
  if (ctx == nullptr) {
364
0
    return 0;
365
0
  }
366
367
2.67k
  BN_CTXScope scope(ctx.get());
368
2.67k
  BIGNUM *f = BN_CTX_get(ctx.get());
369
2.67k
  BIGNUM *result = BN_CTX_get(ctx.get());
370
2.67k
  uint8_t *buf = reinterpret_cast<uint8_t *>(OPENSSL_malloc(rsa_size));
371
2.67k
  int i, ret = 0;
372
2.67k
  if (!f || !result || !buf) {
373
0
    goto err;
374
0
  }
375
376
2.67k
  switch (padding) {
377
2.67k
    case RSA_PKCS1_PADDING:
378
2.67k
      i = rsa_padding_add_PKCS1_type_2(buf, rsa_size, in, in_len);
379
2.67k
      break;
380
0
    case RSA_PKCS1_OAEP_PADDING:
381
      // Use the default parameters: SHA-1 for both hashes and no label.
382
0
      i = RSA_padding_add_PKCS1_OAEP_mgf1(buf, rsa_size, in, in_len, nullptr, 0,
383
0
                                          nullptr, nullptr);
384
0
      break;
385
0
    case RSA_NO_PADDING:
386
0
      i = RSA_padding_add_none(buf, rsa_size, in, in_len);
387
0
      break;
388
0
    default:
389
0
      OPENSSL_PUT_ERROR(RSA, RSA_R_UNKNOWN_PADDING_TYPE);
390
0
      goto err;
391
2.67k
  }
392
393
2.67k
  if (i <= 0) {
394
0
    goto err;
395
0
  }
396
397
2.67k
  if (BN_bin2bn(buf, rsa_size, f) == nullptr) {
398
0
    goto err;
399
0
  }
400
401
2.67k
  if (BN_ucmp(f, impl->n.get()) >= 0) {
402
    // usually the padding functions would catch this
403
0
    OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_TOO_LARGE_FOR_MODULUS);
404
0
    goto err;
405
0
  }
406
407
2.67k
  if (!BN_MONT_CTX_set_locked(&impl->mont_n, &impl->lock, impl->n.get(),
408
2.67k
                              ctx.get()) ||
409
2.67k
      !BN_mod_exp_mont(result, f, impl->e.get(), &impl->mont_n->N, ctx.get(),
410
2.67k
                       impl->mont_n.get())) {
411
0
    goto err;
412
0
  }
413
414
  // put in leading 0 bytes if the number is less than the length of the
415
  // modulus
416
2.67k
  if (!BN_bn2bin_padded(out, rsa_size, result)) {
417
0
    OPENSSL_PUT_ERROR(RSA, ERR_R_INTERNAL_ERROR);
418
0
    goto err;
419
0
  }
420
421
2.67k
  *out_len = rsa_size;
422
2.67k
  ret = 1;
423
424
2.67k
err:
425
2.67k
  OPENSSL_free(buf);
426
2.67k
  return ret;
427
2.67k
}
428
429
static int rsa_default_decrypt(RSA *rsa, size_t *out_len, uint8_t *out,
430
                               size_t max_out, const uint8_t *in, size_t in_len,
431
96
                               int padding) {
432
96
  const unsigned rsa_size = RSA_size(rsa);
433
96
  uint8_t *buf = nullptr;
434
96
  int ret = 0;
435
436
96
  if (max_out < rsa_size) {
437
0
    OPENSSL_PUT_ERROR(RSA, RSA_R_OUTPUT_BUFFER_TOO_SMALL);
438
0
    return 0;
439
0
  }
440
441
96
  if (padding == RSA_NO_PADDING) {
442
96
    buf = out;
443
96
  } else {
444
    // Allocate a temporary buffer to hold the padded plaintext.
445
0
    buf = reinterpret_cast<uint8_t *>(OPENSSL_malloc(rsa_size));
446
0
    if (buf == nullptr) {
447
0
      goto err;
448
0
    }
449
0
  }
450
451
96
  if (in_len != rsa_size) {
452
6
    OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_LEN_NOT_EQUAL_TO_MOD_LEN);
453
6
    goto err;
454
6
  }
455
456
90
  if (!rsa_private_transform(rsa, buf, in, rsa_size)) {
457
3
    goto err;
458
3
  }
459
460
87
  switch (padding) {
461
0
    case RSA_PKCS1_PADDING:
462
0
      ret =
463
0
          rsa_padding_check_PKCS1_type_2(out, out_len, rsa_size, buf, rsa_size);
464
0
      break;
465
0
    case RSA_PKCS1_OAEP_PADDING:
466
      // Use the default parameters: SHA-1 for both hashes and no label.
467
0
      ret = RSA_padding_check_PKCS1_OAEP_mgf1(
468
0
          out, out_len, rsa_size, buf, rsa_size, nullptr, 0, nullptr, nullptr);
469
0
      break;
470
87
    case RSA_NO_PADDING:
471
87
      *out_len = rsa_size;
472
87
      ret = 1;
473
87
      break;
474
0
    default:
475
0
      OPENSSL_PUT_ERROR(RSA, RSA_R_UNKNOWN_PADDING_TYPE);
476
0
      goto err;
477
87
  }
478
479
87
  CONSTTIME_DECLASSIFY(&ret, sizeof(ret));
480
87
  if (!ret) {
481
0
    OPENSSL_PUT_ERROR(RSA, RSA_R_PADDING_CHECK_FAILED);
482
87
  } else {
483
87
    CONSTTIME_DECLASSIFY(out, *out_len);
484
87
  }
485
486
96
err:
487
96
  if (padding != RSA_NO_PADDING) {
488
0
    OPENSSL_free(buf);
489
0
  }
490
491
96
  return ret;
492
87
}
493
494
int RSA_decrypt(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out,
495
96
                const uint8_t *in, size_t in_len, int padding) {
496
96
  auto *impl = FromOpaque(rsa);
497
96
  if (impl->meth->decrypt) {
498
0
    return impl->meth->decrypt(rsa, out_len, out, max_out, in, in_len, padding);
499
0
  }
500
501
96
  return rsa_default_decrypt(rsa, out_len, out, max_out, in, in_len, padding);
502
96
}
503
504
int RSA_private_decrypt(size_t flen, const uint8_t *from, uint8_t *to, RSA *rsa,
505
0
                        int padding) {
506
0
  size_t out_len;
507
0
  if (!RSA_decrypt(rsa, &out_len, to, RSA_size(rsa), from, flen, padding)) {
508
0
    return -1;
509
0
  }
510
511
0
  if (out_len > INT_MAX) {
512
0
    OPENSSL_PUT_ERROR(RSA, ERR_R_OVERFLOW);
513
0
    return -1;
514
0
  }
515
0
  return (int)out_len;
516
0
}
517
518
int RSA_public_decrypt(size_t flen, const uint8_t *from, uint8_t *to, RSA *rsa,
519
0
                       int padding) {
520
0
  size_t out_len;
521
0
  if (!RSA_verify_raw(rsa, &out_len, to, RSA_size(rsa), from, flen, padding)) {
522
0
    return -1;
523
0
  }
524
525
0
  if (out_len > INT_MAX) {
526
0
    OPENSSL_PUT_ERROR(RSA, ERR_R_OVERFLOW);
527
0
    return -1;
528
0
  }
529
0
  return (int)out_len;
530
0
}