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