Coverage Report

Created: 2026-05-11 06:45

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
6.02k
                                       const uint8_t *from, size_t from_len) {
36
  // See RFC 8017, section 9.2.
37
6.02k
  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
6.02k
  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
6.02k
  to[0] = 0;
48
6.02k
  to[1] = 1;
49
6.02k
  OPENSSL_memset(to + 2, 0xff, to_len - 3 - from_len);
50
6.02k
  to[to_len - from_len - 1] = 0;
51
6.02k
  OPENSSL_memcpy(to + to_len - from_len, from, from_len);
52
6.02k
  return 1;
53
6.02k
}
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
7.35k
                                         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
7.35k
  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
7.35k
  if (from[0] != 0 || from[1] != 1) {
67
3.46k
    OPENSSL_PUT_ERROR(RSA, RSA_R_BLOCK_TYPE_IS_NOT_01);
68
3.46k
    return 0;
69
3.46k
  }
70
71
  // Scan over padded data, looking for the 00.
72
3.89k
  size_t pad;
73
309k
  for (pad = 2 /* header */; pad < from_len; pad++) {
74
309k
    if (from[pad] == 0x00) {
75
3.86k
      break;
76
3.86k
    }
77
78
305k
    if (from[pad] != 0xff) {
79
29
      OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_FIXED_HEADER_DECRYPT);
80
29
      return 0;
81
29
    }
82
305k
  }
83
84
3.86k
  if (pad == from_len) {
85
0
    OPENSSL_PUT_ERROR(RSA, RSA_R_NULL_BEFORE_BLOCK_MISSING);
86
0
    return 0;
87
0
  }
88
89
3.86k
  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
3.85k
  pad++;
96
97
3.85k
  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
3.85k
  OPENSSL_memcpy(out, from + pad, from_len - pad);
103
3.85k
  *out_len = from_len - pad;
104
3.85k
  return 1;
105
3.85k
}
106
107
int bssl::RSA_padding_add_none(uint8_t *to, size_t to_len, const uint8_t *from,
108
14.8k
                               size_t from_len) {
109
14.8k
  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
14.8k
  if (from_len < to_len) {
115
0
    OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_TOO_SMALL);
116
0
    return 0;
117
0
  }
118
119
14.8k
  OPENSSL_memcpy(to, from, from_len);
120
14.8k
  return 1;
121
14.8k
}
122
123
int bssl::PKCS1_MGF1(uint8_t *out, size_t len, const uint8_t *seed,
124
15.4k
                     size_t seed_len, const EVP_MD *md) {
125
15.4k
  int ret = 0;
126
15.4k
  ScopedEVP_MD_CTX ctx;
127
15.4k
  FIPS_service_indicator_lock_state();
128
129
15.4k
  size_t md_len = EVP_MD_size(md);
130
131
99.0k
  for (uint32_t i = 0; len > 0; i++) {
132
83.6k
    uint8_t counter[4];
133
83.6k
    counter[0] = (uint8_t)(i >> 24);
134
83.6k
    counter[1] = (uint8_t)(i >> 16);
135
83.6k
    counter[2] = (uint8_t)(i >> 8);
136
83.6k
    counter[3] = (uint8_t)i;
137
83.6k
    if (!EVP_DigestInit_ex(ctx.get(), md, nullptr) ||
138
83.6k
        !EVP_DigestUpdate(ctx.get(), seed, seed_len) ||
139
83.6k
        !EVP_DigestUpdate(ctx.get(), counter, sizeof(counter))) {
140
0
      goto err;
141
0
    }
142
143
83.6k
    if (md_len <= len) {
144
68.1k
      if (!EVP_DigestFinal_ex(ctx.get(), out, nullptr)) {
145
0
        goto err;
146
0
      }
147
68.1k
      out += md_len;
148
68.1k
      len -= md_len;
149
68.1k
    } else {
150
15.4k
      uint8_t digest[EVP_MAX_MD_SIZE];
151
15.4k
      if (!EVP_DigestFinal_ex(ctx.get(), digest, nullptr)) {
152
0
        goto err;
153
0
      }
154
15.4k
      OPENSSL_memcpy(out, digest, len);
155
15.4k
      len = 0;
156
15.4k
    }
157
83.6k
  }
158
159
15.4k
  ret = 1;
160
161
15.4k
err:
162
15.4k
  FIPS_service_indicator_unlock_state();
163
15.4k
  return ret;
164
15.4k
}
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.01k
                              const uint8_t *EM, int sLen) {
171
2.01k
  if (mgf1Hash == nullptr) {
172
2.01k
    mgf1Hash = Hash;
173
2.01k
  }
174
175
2.01k
  int ret = 0;
176
2.01k
  uint8_t *DB = nullptr;
177
2.01k
  const uint8_t *H;
178
2.01k
  ScopedEVP_MD_CTX ctx;
179
2.01k
  unsigned MSBits;
180
2.01k
  size_t emLen, maskedDBLen, salt_start;
181
2.01k
  FIPS_service_indicator_lock_state();
182
183
2.01k
  size_t hLen = EVP_MD_size(Hash);
184
2.01k
  if (sLen == RSA_PSS_SALTLEN_DIGEST) {
185
2.01k
    sLen = (int)hLen;
186
2.01k
  } 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.01k
  MSBits = (RSA_bits(rsa) - 1) & 0x7;
196
2.01k
  emLen = RSA_size(rsa);
197
2.01k
  if (EM[0] & (0xFF << MSBits)) {
198
505
    OPENSSL_PUT_ERROR(RSA, RSA_R_FIRST_OCTET_INVALID);
199
505
    goto err;
200
505
  }
201
1.51k
  if (MSBits == 0) {
202
53
    EM++;
203
53
    emLen--;
204
53
  }
205
  // |sLen| may be negative for the non-standard salt length recovery mode.
206
1.51k
  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.51k
  if (EM[emLen - 1] != 0xbc) {
211
982
    OPENSSL_PUT_ERROR(RSA, RSA_R_LAST_OCTET_INVALID);
212
982
    goto err;
213
982
  }
214
530
  maskedDBLen = emLen - hLen - 1;
215
530
  H = EM + maskedDBLen;
216
530
  DB = reinterpret_cast<uint8_t *>(OPENSSL_malloc(maskedDBLen));
217
530
  if (!DB) {
218
0
    goto err;
219
0
  }
220
530
  if (!PKCS1_MGF1(DB, maskedDBLen, H, hLen, mgf1Hash)) {
221
0
    goto err;
222
0
  }
223
110k
  for (size_t i = 0; i < maskedDBLen; i++) {
224
110k
    DB[i] ^= EM[i];
225
110k
  }
226
530
  if (MSBits) {
227
523
    DB[0] &= 0xFF >> (8 - MSBits);
228
523
  }
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
50.5k
  for (salt_start = 0; DB[salt_start] == 0 && salt_start < maskedDBLen - 1;
233
50.0k
       salt_start++) {
234
50.0k
    ;
235
50.0k
  }
236
530
  if (DB[salt_start] != 0x1) {
237
243
    OPENSSL_PUT_ERROR(RSA, RSA_R_SLEN_RECOVERY_FAILED);
238
243
    goto err;
239
243
  }
240
287
  salt_start++;
241
  // If a salt length was specified, check it matches.
242
287
  if (sLen >= 0 && maskedDBLen - salt_start != (size_t)sLen) {
243
22
    OPENSSL_PUT_ERROR(RSA, RSA_R_SLEN_CHECK_FAILED);
244
22
    goto err;
245
22
  }
246
265
  uint8_t H_[EVP_MAX_MD_SIZE];
247
265
  if (!EVP_DigestInit_ex(ctx.get(), Hash, nullptr) ||
248
265
      !EVP_DigestUpdate(ctx.get(), kPSSZeroes, sizeof(kPSSZeroes)) ||
249
265
      !EVP_DigestUpdate(ctx.get(), mHash, hLen) ||
250
265
      !EVP_DigestUpdate(ctx.get(), DB + salt_start, maskedDBLen - salt_start) ||
251
265
      !EVP_DigestFinal_ex(ctx.get(), H_, nullptr)) {
252
0
    goto err;
253
0
  }
254
265
  if (OPENSSL_memcmp(H_, H, hLen) != 0) {
255
265
    OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_SIGNATURE);
256
265
    goto err;
257
265
  }
258
259
0
  ret = 1;
260
261
2.01k
err:
262
2.01k
  OPENSSL_free(DB);
263
2.01k
  FIPS_service_indicator_unlock_state();
264
2.01k
  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
14.8k
                                   int sLenRequested) {
271
14.8k
  int ret = 0;
272
14.8k
  ScopedEVP_MD_CTX ctx;
273
14.8k
  size_t maskedDBLen, MSBits, emLen;
274
14.8k
  size_t hLen;
275
14.8k
  unsigned char *H, *salt = nullptr, *p;
276
277
14.8k
  if (mgf1Hash == nullptr) {
278
14.8k
    mgf1Hash = Hash;
279
14.8k
  }
280
281
14.8k
  FIPS_service_indicator_lock_state();
282
14.8k
  hLen = EVP_MD_size(Hash);
283
284
14.8k
  unsigned rsa_bits = RSA_bits(rsa);
285
14.8k
  if (rsa_bits == 0) {
286
0
    OPENSSL_PUT_ERROR(RSA, RSA_R_EMPTY_PUBLIC_KEY);
287
0
    goto err;
288
0
  }
289
290
14.8k
  MSBits = (rsa_bits - 1) & 0x7;
291
14.8k
  emLen = RSA_size(rsa);
292
14.8k
  if (MSBits == 0) {
293
0
    assert(emLen >= 1);
294
0
    *EM++ = 0;
295
0
    emLen--;
296
0
  }
297
298
14.8k
  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
14.8k
  size_t sLen;
304
14.8k
  if (sLenRequested == RSA_PSS_SALTLEN_DIGEST) {
305
14.8k
    sLen = hLen;
306
14.8k
  } 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
14.8k
  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
14.8k
  if (sLen > 0) {
323
14.8k
    salt = reinterpret_cast<uint8_t *>(OPENSSL_malloc(sLen));
324
14.8k
    if (!salt) {
325
0
      goto err;
326
0
    }
327
14.8k
    BCM_rand_bytes(salt, sLen);
328
14.8k
  }
329
14.8k
  maskedDBLen = emLen - hLen - 1;
330
14.8k
  H = EM + maskedDBLen;
331
332
14.8k
  if (!EVP_DigestInit_ex(ctx.get(), Hash, nullptr) ||
333
14.8k
      !EVP_DigestUpdate(ctx.get(), kPSSZeroes, sizeof(kPSSZeroes)) ||
334
14.8k
      !EVP_DigestUpdate(ctx.get(), mHash, hLen) ||
335
14.8k
      !EVP_DigestUpdate(ctx.get(), salt, sLen) ||
336
14.8k
      !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
14.8k
  if (!PKCS1_MGF1(EM, maskedDBLen, H, hLen, mgf1Hash)) {
342
0
    goto err;
343
0
  }
344
345
14.8k
  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
14.8k
  p += emLen - sLen - hLen - 2;
350
14.8k
  *p++ ^= 0x1;
351
14.8k
  if (sLen > 0) {
352
679k
    for (size_t i = 0; i < sLen; i++) {
353
664k
      *p++ ^= salt[i];
354
664k
    }
355
14.8k
  }
356
14.8k
  if (MSBits) {
357
14.8k
    EM[0] &= 0xFF >> (8 - MSBits);
358
14.8k
  }
359
360
  // H is already in place so just set final 0xbc
361
362
14.8k
  EM[emLen - 1] = 0xbc;
363
364
14.8k
  ret = 1;
365
366
14.8k
err:
367
14.8k
  OPENSSL_free(salt);
368
14.8k
  FIPS_service_indicator_unlock_state();
369
370
14.8k
  return ret;
371
14.8k
}