Coverage Report

Created: 2026-08-28 07:25

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/boringssl/crypto/fipsmodule/rsa/padding.cc.inc
Line
Count
Source
1
// Copyright 2005-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/rsa.h>
16
17
#include <assert.h>
18
#include <limits.h>
19
#include <string.h>
20
21
#include <openssl/bn.h>
22
#include <openssl/digest.h>
23
#include <openssl/err.h>
24
#include <openssl/mem.h>
25
26
#include "../../internal.h"
27
#include "../bcm_interface.h"
28
#include "../service_indicator/internal.h"
29
#include "internal.h"
30
31
32
using namespace bssl;
33
34
int bssl::RSA_padding_add_PKCS1_type_1(uint8_t *to, size_t to_len,
35
5.80k
                                       const uint8_t *from, size_t from_len) {
36
  // See RFC 8017, section 9.2.
37
5.80k
  if (to_len < RSA_PKCS1_PADDING_SIZE) {
38
0
    OPENSSL_PUT_ERROR(RSA, RSA_R_KEY_SIZE_TOO_SMALL);
39
0
    return 0;
40
0
  }
41
42
5.80k
  if (from_len > to_len - RSA_PKCS1_PADDING_SIZE) {
43
0
    OPENSSL_PUT_ERROR(RSA, RSA_R_DIGEST_TOO_BIG_FOR_RSA_KEY);
44
0
    return 0;
45
0
  }
46
47
5.80k
  to[0] = 0;
48
5.80k
  to[1] = 1;
49
5.80k
  OPENSSL_memset(to + 2, 0xff, to_len - 3 - from_len);
50
5.80k
  to[to_len - from_len - 1] = 0;
51
5.80k
  OPENSSL_memcpy(to + to_len - from_len, from, from_len);
52
5.80k
  return 1;
53
5.80k
}
54
55
int bssl::RSA_padding_check_PKCS1_type_1(uint8_t *out, size_t *out_len,
56
                                         size_t max_out, const uint8_t *from,
57
8.43k
                                         size_t from_len) {
58
  // See RFC 8017, section 9.2. This is part of signature verification and thus
59
  // does not need to run in constant-time.
60
8.43k
  if (from_len < 2) {
61
0
    OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_TOO_SMALL);
62
0
    return 0;
63
0
  }
64
65
  // Check the header.
66
8.43k
  if (from[0] != 0 || from[1] != 1) {
67
3.99k
    OPENSSL_PUT_ERROR(RSA, RSA_R_BLOCK_TYPE_IS_NOT_01);
68
3.99k
    return 0;
69
3.99k
  }
70
71
  // Scan over padded data, looking for the 00.
72
4.44k
  size_t pad;
73
347k
  for (pad = 2 /* header */; pad < from_len; pad++) {
74
347k
    if (from[pad] == 0x00) {
75
4.41k
      break;
76
4.41k
    }
77
78
342k
    if (from[pad] != 0xff) {
79
29
      OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_FIXED_HEADER_DECRYPT);
80
29
      return 0;
81
29
    }
82
342k
  }
83
84
4.41k
  if (pad == from_len) {
85
0
    OPENSSL_PUT_ERROR(RSA, RSA_R_NULL_BEFORE_BLOCK_MISSING);
86
0
    return 0;
87
0
  }
88
89
4.41k
  if (pad < 2 /* header */ + 8) {
90
6
    OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_PAD_BYTE_COUNT);
91
6
    return 0;
92
6
  }
93
94
  // Skip over the 00.
95
4.41k
  pad++;
96
97
4.41k
  if (from_len - pad > max_out) {
98
0
    OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_TOO_LARGE);
99
0
    return 0;
100
0
  }
101
102
4.41k
  OPENSSL_memcpy(out, from + pad, from_len - pad);
103
4.41k
  *out_len = from_len - pad;
104
4.41k
  return 1;
105
4.41k
}
106
107
int bssl::RSA_padding_add_none(uint8_t *to, size_t to_len, const uint8_t *from,
108
12.9k
                               size_t from_len) {
109
12.9k
  if (from_len > to_len) {
110
0
    OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
111
0
    return 0;
112
0
  }
113
114
12.9k
  if (from_len < to_len) {
115
0
    OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_TOO_SMALL);
116
0
    return 0;
117
0
  }
118
119
12.9k
  OPENSSL_memcpy(to, from, from_len);
120
12.9k
  return 1;
121
12.9k
}
122
123
int bssl::PKCS1_MGF1(uint8_t *out, size_t len, const uint8_t *seed,
124
13.6k
                     size_t seed_len, const EVP_MD *md) {
125
13.6k
  int ret = 0;
126
13.6k
  ScopedEVP_MD_CTX ctx;
127
13.6k
  FIPS_service_indicator_lock_state();
128
129
13.6k
  size_t md_len = EVP_MD_size(md);
130
131
88.0k
  for (uint32_t i = 0; len > 0; i++) {
132
74.4k
    uint8_t counter[4];
133
74.4k
    counter[0] = (uint8_t)(i >> 24);
134
74.4k
    counter[1] = (uint8_t)(i >> 16);
135
74.4k
    counter[2] = (uint8_t)(i >> 8);
136
74.4k
    counter[3] = (uint8_t)i;
137
74.4k
    if (!EVP_DigestInit_ex(ctx.get(), md, nullptr) ||
138
74.4k
        !EVP_DigestUpdate(ctx.get(), seed, seed_len) ||
139
74.4k
        !EVP_DigestUpdate(ctx.get(), counter, sizeof(counter))) {
140
0
      goto err;
141
0
    }
142
143
74.4k
    if (md_len <= len) {
144
60.8k
      if (!EVP_DigestFinal_ex(ctx.get(), out, nullptr)) {
145
0
        goto err;
146
0
      }
147
60.8k
      out += md_len;
148
60.8k
      len -= md_len;
149
60.8k
    } else {
150
13.6k
      uint8_t digest[EVP_MAX_MD_SIZE];
151
13.6k
      if (!EVP_DigestFinal_ex(ctx.get(), digest, nullptr)) {
152
0
        goto err;
153
0
      }
154
13.6k
      OPENSSL_memcpy(out, digest, len);
155
13.6k
      len = 0;
156
13.6k
    }
157
74.4k
  }
158
159
13.6k
  ret = 1;
160
161
13.6k
err:
162
13.6k
  FIPS_service_indicator_unlock_state();
163
13.6k
  return ret;
164
13.6k
}
165
166
static const uint8_t kPSSZeroes[] = {0, 0, 0, 0, 0, 0, 0, 0};
167
168
int RSA_verify_PKCS1_PSS_mgf1(const RSA *rsa, const uint8_t *mHash,
169
                              const EVP_MD *Hash, const EVP_MD *mgf1Hash,
170
2.14k
                              const uint8_t *EM, int sLen) {
171
2.14k
  if (mgf1Hash == nullptr) {
172
2.14k
    mgf1Hash = Hash;
173
2.14k
  }
174
175
2.14k
  int ret = 0;
176
2.14k
  uint8_t *DB = nullptr;
177
2.14k
  const uint8_t *H;
178
2.14k
  ScopedEVP_MD_CTX ctx;
179
2.14k
  unsigned MSBits;
180
2.14k
  size_t emLen, maskedDBLen, salt_start;
181
2.14k
  FIPS_service_indicator_lock_state();
182
183
2.14k
  size_t hLen = EVP_MD_size(Hash);
184
2.14k
  if (sLen == RSA_PSS_SALTLEN_DIGEST) {
185
2.14k
    sLen = (int)hLen;
186
2.14k
  } else if (sLen == RSA_PSS_SALTLEN_AUTO) {
187
    // Leave `sLen` negative, which will trigger the logic below to recover and
188
    // allow any salt length.
189
0
  } else if (sLen < 0) {
190
    // Other negative values are reserved.
191
0
    OPENSSL_PUT_ERROR(RSA, RSA_R_SLEN_CHECK_FAILED);
192
0
    goto err;
193
0
  }
194
195
2.14k
  MSBits = (RSA_bits(rsa) - 1) & 0x7;
196
2.14k
  emLen = RSA_size(rsa);
197
2.14k
  if (EM[0] & (0xFF << MSBits)) {
198
514
    OPENSSL_PUT_ERROR(RSA, RSA_R_FIRST_OCTET_INVALID);
199
514
    goto err;
200
514
  }
201
1.62k
  if (MSBits == 0) {
202
80
    EM++;
203
80
    emLen--;
204
80
  }
205
  // `sLen` may be negative for the non-standard salt length recovery mode.
206
1.62k
  if (emLen < hLen + 2 || (sLen >= 0 && emLen < hLen + (size_t)sLen + 2)) {
207
0
    OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_TOO_LARGE);
208
0
    goto err;
209
0
  }
210
1.62k
  if (EM[emLen - 1] != 0xbc) {
211
988
    OPENSSL_PUT_ERROR(RSA, RSA_R_LAST_OCTET_INVALID);
212
988
    goto err;
213
988
  }
214
638
  maskedDBLen = emLen - hLen - 1;
215
638
  H = EM + maskedDBLen;
216
638
  DB = reinterpret_cast<uint8_t *>(OPENSSL_malloc(maskedDBLen));
217
638
  if (!DB) {
218
0
    goto err;
219
0
  }
220
638
  if (!PKCS1_MGF1(DB, maskedDBLen, H, hLen, mgf1Hash)) {
221
0
    goto err;
222
0
  }
223
132k
  for (size_t i = 0; i < maskedDBLen; i++) {
224
132k
    DB[i] ^= EM[i];
225
132k
  }
226
638
  if (MSBits) {
227
626
    DB[0] &= 0xFF >> (8 - MSBits);
228
626
  }
229
  // This step differs slightly from EMSA-PSS-VERIFY (RFC 8017) step 10 because
230
  // it accepts a non-standard salt recovery flow. DB should be some number of
231
  // zeros, a one, then the salt.
232
56.3k
  for (salt_start = 0; DB[salt_start] == 0 && salt_start < maskedDBLen - 1;
233
55.6k
       salt_start++) {
234
55.6k
    ;
235
55.6k
  }
236
638
  if (DB[salt_start] != 0x1) {
237
317
    OPENSSL_PUT_ERROR(RSA, RSA_R_SLEN_RECOVERY_FAILED);
238
317
    goto err;
239
317
  }
240
321
  salt_start++;
241
  // If a salt length was specified, check it matches.
242
321
  if (sLen >= 0 && maskedDBLen - salt_start != (size_t)sLen) {
243
25
    OPENSSL_PUT_ERROR(RSA, RSA_R_SLEN_CHECK_FAILED);
244
25
    goto err;
245
25
  }
246
296
  uint8_t H_[EVP_MAX_MD_SIZE];
247
296
  if (!EVP_DigestInit_ex(ctx.get(), Hash, nullptr) ||
248
296
      !EVP_DigestUpdate(ctx.get(), kPSSZeroes, sizeof(kPSSZeroes)) ||
249
296
      !EVP_DigestUpdate(ctx.get(), mHash, hLen) ||
250
296
      !EVP_DigestUpdate(ctx.get(), DB + salt_start, maskedDBLen - salt_start) ||
251
296
      !EVP_DigestFinal_ex(ctx.get(), H_, nullptr)) {
252
0
    goto err;
253
0
  }
254
296
  if (OPENSSL_memcmp(H_, H, hLen) != 0) {
255
296
    OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_SIGNATURE);
256
296
    goto err;
257
296
  }
258
259
0
  ret = 1;
260
261
2.14k
err:
262
2.14k
  OPENSSL_free(DB);
263
2.14k
  FIPS_service_indicator_unlock_state();
264
2.14k
  return ret;
265
0
}
266
267
int RSA_padding_add_PKCS1_PSS_mgf1(const RSA *rsa, unsigned char *EM,
268
                                   const unsigned char *mHash,
269
                                   const EVP_MD *Hash, const EVP_MD *mgf1Hash,
270
12.9k
                                   int sLenRequested) {
271
12.9k
  int ret = 0;
272
12.9k
  ScopedEVP_MD_CTX ctx;
273
12.9k
  size_t maskedDBLen, MSBits, emLen;
274
12.9k
  size_t hLen;
275
12.9k
  unsigned char *H, *salt = nullptr, *p;
276
277
12.9k
  if (mgf1Hash == nullptr) {
278
12.9k
    mgf1Hash = Hash;
279
12.9k
  }
280
281
12.9k
  FIPS_service_indicator_lock_state();
282
12.9k
  hLen = EVP_MD_size(Hash);
283
284
12.9k
  unsigned rsa_bits = RSA_bits(rsa);
285
12.9k
  if (rsa_bits == 0) {
286
0
    OPENSSL_PUT_ERROR(RSA, RSA_R_EMPTY_PUBLIC_KEY);
287
0
    goto err;
288
0
  }
289
290
12.9k
  MSBits = (rsa_bits - 1) & 0x7;
291
12.9k
  emLen = RSA_size(rsa);
292
12.9k
  if (MSBits == 0) {
293
0
    assert(emLen >= 1);
294
0
    *EM++ = 0;
295
0
    emLen--;
296
0
  }
297
298
12.9k
  if (emLen < hLen + 2) {
299
0
    OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
300
0
    goto err;
301
0
  }
302
303
12.9k
  size_t sLen;
304
12.9k
  if (sLenRequested == RSA_PSS_SALTLEN_DIGEST) {
305
12.9k
    sLen = hLen;
306
12.9k
  } else if (sLenRequested == RSA_PSS_SALTLEN_AUTO) {
307
    // Use the maximum possible salt length.
308
0
    sLen = emLen - hLen - 2;
309
0
  } else if (sLenRequested < 0) {
310
    // Other negative values are reserved.
311
0
    OPENSSL_PUT_ERROR(RSA, RSA_R_SLEN_CHECK_FAILED);
312
0
    goto err;
313
0
  } else {
314
0
    sLen = (size_t)sLenRequested;
315
0
  }
316
317
12.9k
  if (emLen - hLen - 2 < sLen) {
318
0
    OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
319
0
    goto err;
320
0
  }
321
322
12.9k
  if (sLen > 0) {
323
12.9k
    salt = reinterpret_cast<uint8_t *>(OPENSSL_malloc(sLen));
324
12.9k
    if (!salt) {
325
0
      goto err;
326
0
    }
327
12.9k
    BCM_rand_bytes(salt, sLen);
328
12.9k
  }
329
12.9k
  maskedDBLen = emLen - hLen - 1;
330
12.9k
  H = EM + maskedDBLen;
331
332
12.9k
  if (!EVP_DigestInit_ex(ctx.get(), Hash, nullptr) ||
333
12.9k
      !EVP_DigestUpdate(ctx.get(), kPSSZeroes, sizeof(kPSSZeroes)) ||
334
12.9k
      !EVP_DigestUpdate(ctx.get(), mHash, hLen) ||
335
12.9k
      !EVP_DigestUpdate(ctx.get(), salt, sLen) ||
336
12.9k
      !EVP_DigestFinal_ex(ctx.get(), H, nullptr)) {
337
0
    goto err;
338
0
  }
339
340
  // Generate dbMask in place then perform XOR on it
341
12.9k
  if (!PKCS1_MGF1(EM, maskedDBLen, H, hLen, mgf1Hash)) {
342
0
    goto err;
343
0
  }
344
345
12.9k
  p = EM;
346
  // Initial PS XORs with all zeroes which is a NOP so just update
347
  // pointer. Note from a test above this value is guaranteed to
348
  // be non-negative.
349
12.9k
  p += emLen - sLen - hLen - 2;
350
12.9k
  *p++ ^= 0x1;
351
12.9k
  if (sLen > 0) {
352
586k
    for (size_t i = 0; i < sLen; i++) {
353
573k
      *p++ ^= salt[i];
354
573k
    }
355
12.9k
  }
356
12.9k
  if (MSBits) {
357
12.9k
    EM[0] &= 0xFF >> (8 - MSBits);
358
12.9k
  }
359
360
  // H is already in place so just set final 0xbc
361
362
12.9k
  EM[emLen - 1] = 0xbc;
363
364
12.9k
  ret = 1;
365
366
12.9k
err:
367
12.9k
  OPENSSL_free(salt);
368
12.9k
  FIPS_service_indicator_unlock_state();
369
370
12.9k
  return ret;
371
12.9k
}