/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 | } |