Exemple #1
0
int RSA_message_index_PKCS1_type_2(const uint8_t *from, size_t from_len,
                                   size_t *out_index) {
  size_t i;
  int first_byte_is_zero, second_byte_is_two, looking_for_index;
  int valid_index, zero_index = 0;

  /* PKCS#1 v1.5 decryption. See "PKCS #1 v2.2: RSA Cryptography
   * Standard", section 7.2.2. */
  if (from_len < RSA_PKCS1_PADDING_SIZE) {
    return 0;
  }

  first_byte_is_zero = constant_time_byte_eq(from[0], 0);
  second_byte_is_two = constant_time_byte_eq(from[1], 2);

  looking_for_index = 1;
  for (i = 2; i < from_len; i++) {
    int equals0 = constant_time_byte_eq(from[i], 0);
    zero_index =
        constant_time_select(looking_for_index & equals0, i, zero_index);
    looking_for_index = constant_time_select(equals0, 0, looking_for_index);
  }

  /* The input must begin with 00 02. */
  valid_index = first_byte_is_zero;
  valid_index &= second_byte_is_two;

  /* We must have found the end of PS. */
  valid_index &= ~looking_for_index;

  /* PS must be at least 8 bytes long, and it starts two bytes into |from|. */
  valid_index &= constant_time_le(2 + 8, zero_index);

  /* Skip the zero byte. */
  *out_index = zero_index + 1;

  return valid_index;
}
Exemple #2
0
int RSA_padding_check_PKCS1_type_2(uint8_t *to, unsigned to_len,
                                   const uint8_t *from, unsigned from_len) {
  if (from_len == 0) {
    OPENSSL_PUT_ERROR(RSA, RSA_R_EMPTY_PUBLIC_KEY);
    return -1;
  }

  /* PKCS#1 v1.5 decryption. See "PKCS #1 v2.2: RSA Cryptography
   * Standard", section 7.2.2. */
  if (from_len < RSA_PKCS1_PADDING_SIZE) {
    /* |from| is zero-padded to the size of the RSA modulus, a public value, so
     * this can be rejected in non-constant time. */
    OPENSSL_PUT_ERROR(RSA, RSA_R_KEY_SIZE_TOO_SMALL);
    return -1;
  }

  unsigned first_byte_is_zero = constant_time_eq(from[0], 0);
  unsigned second_byte_is_two = constant_time_eq(from[1], 2);

  unsigned i, zero_index = 0, looking_for_index = ~0u;
  for (i = 2; i < from_len; i++) {
    unsigned equals0 = constant_time_is_zero(from[i]);
    zero_index = constant_time_select(looking_for_index & equals0, (unsigned)i,
                                      zero_index);
    looking_for_index = constant_time_select(equals0, 0, looking_for_index);
  }

  /* The input must begin with 00 02. */
  unsigned valid_index = first_byte_is_zero;
  valid_index &= second_byte_is_two;

  /* We must have found the end of PS. */
  valid_index &= ~looking_for_index;

  /* PS must be at least 8 bytes long, and it starts two bytes into |from|. */
  valid_index &= constant_time_ge(zero_index, 2 + 8);

  /* Skip the zero byte. */
  zero_index++;

  /* NOTE: Although this logic attempts to be constant time, the API contracts
   * of this function and |RSA_decrypt| with |RSA_PKCS1_PADDING| make it
   * impossible to completely avoid Bleichenbacher's attack. Consumers should
   * use |RSA_unpad_key_pkcs1|. */
  if (!valid_index) {
    OPENSSL_PUT_ERROR(RSA, RSA_R_PKCS_DECODING_ERROR);
    return -1;
  }

  const unsigned msg_len = from_len - zero_index;
  if (msg_len > to_len) {
    /* This shouldn't happen because this function is always called with
     * |to_len| as the key size and |from_len| is bounded by the key size. */
    OPENSSL_PUT_ERROR(RSA, RSA_R_PKCS_DECODING_ERROR);
    return -1;
  }

  if (msg_len > INT_MAX) {
    OPENSSL_PUT_ERROR(RSA, ERR_R_OVERFLOW);
    return -1;
  }

  memcpy(to, &from[zero_index], msg_len);
  return (int)msg_len;
}
Exemple #3
0
int RSA_padding_check_PKCS1_OAEP_mgf1(uint8_t *to, unsigned tlen,
                                      const uint8_t *from, unsigned flen,
                                      const uint8_t *param, unsigned plen,
                                      const EVP_MD *md, const EVP_MD *mgf1md) {
  unsigned i, dblen, mlen = -1, mdlen;
  const uint8_t *maskeddb, *maskedseed;
  uint8_t *db = NULL, seed[EVP_MAX_MD_SIZE], phash[EVP_MAX_MD_SIZE];
  int bad, looking_for_one_byte, one_index = 0;

  if (md == NULL) {
    md = EVP_sha1();
  }
  if (mgf1md == NULL) {
    mgf1md = md;
  }

  mdlen = EVP_MD_size(md);

  /* The encoded message is one byte smaller than the modulus to ensure that it
   * doesn't end up greater than the modulus. Thus there's an extra "+1" here
   * compared to https://tools.ietf.org/html/rfc2437#section-9.1.1.2. */
  if (flen < 1 + 2*mdlen + 1) {
    /* 'flen' is the length of the modulus, i.e. does not depend on the
     * particular ciphertext. */
    goto decoding_err;
  }

  dblen = flen - mdlen - 1;
  db = OPENSSL_malloc(dblen);
  if (db == NULL) {
    OPENSSL_PUT_ERROR(RSA, RSA_padding_check_PKCS1_OAEP_mgf1,
                      ERR_R_MALLOC_FAILURE);
    goto err;
  }

  maskedseed = from + 1;
  maskeddb = from + 1 + mdlen;

  if (PKCS1_MGF1(seed, mdlen, maskeddb, dblen, mgf1md)) {
    goto err;
  }
  for (i = 0; i < mdlen; i++) {
    seed[i] ^= maskedseed[i];
  }

  if (PKCS1_MGF1(db, dblen, seed, mdlen, mgf1md)) {
    goto err;
  }
  for (i = 0; i < dblen; i++) {
    db[i] ^= maskeddb[i];
  }

  if (!EVP_Digest((void *)param, plen, phash, NULL, md, NULL)) {
    goto err;
  }

  bad = CRYPTO_memcmp(db, phash, mdlen);
  bad |= from[0];

  looking_for_one_byte = 1;
  for (i = mdlen; i < dblen; i++) {
    int equals1 = constant_time_byte_eq(db[i], 1);
    int equals0 = constant_time_byte_eq(db[i], 0);
    one_index =
        constant_time_select(looking_for_one_byte & equals1, i, one_index);
    looking_for_one_byte =
        constant_time_select(equals1, 0, looking_for_one_byte);
    bad |= looking_for_one_byte & ~equals0;
  }

  bad |= looking_for_one_byte;

  if (bad) {
    goto decoding_err;
  }

  one_index++;
  mlen = dblen - one_index;
  if (tlen < mlen) {
    OPENSSL_PUT_ERROR(RSA, RSA_padding_check_PKCS1_OAEP_mgf1,
                      RSA_R_DATA_TOO_LARGE);
    mlen = -1;
  } else {
    memcpy(to, db + one_index, mlen);
  }

  OPENSSL_free(db);
  return mlen;

decoding_err:
  /* to avoid chosen ciphertext attacks, the error message should not reveal
   * which kind of decoding error happened */
  OPENSSL_PUT_ERROR(RSA, RSA_padding_check_PKCS1_OAEP_mgf1,
                    RSA_R_OAEP_DECODING_ERROR);
 err:
  if (db != NULL) {
    OPENSSL_free(db);
  }
  return -1;
}
Exemple #4
0
void EVP_tls_cbc_copy_mac(uint8_t *out, unsigned md_size,
                          const uint8_t *in, unsigned in_len,
                          unsigned orig_len) {
#if defined(CBC_MAC_ROTATE_IN_PLACE)
    uint8_t rotated_mac_buf[64 + EVP_MAX_MD_SIZE];
    uint8_t *rotated_mac;
#else
    uint8_t rotated_mac[EVP_MAX_MD_SIZE];
#endif

    /* mac_end is the index of |in| just after the end of the MAC. */
    unsigned mac_end = in_len;
    unsigned mac_start = mac_end - md_size;
    /* scan_start contains the number of bytes that we can ignore because
     * the MAC's position can only vary by 255 bytes. */
    unsigned scan_start = 0;
    unsigned i, j;
    unsigned rotate_offset;

    assert(orig_len >= in_len);
    assert(in_len >= md_size);
    assert(md_size <= EVP_MAX_MD_SIZE);

#if defined(CBC_MAC_ROTATE_IN_PLACE)
    rotated_mac = rotated_mac_buf + ((0 - (size_t)rotated_mac_buf) & 63);
#endif

    /* This information is public so it's safe to branch based on it. */
    if (orig_len > md_size + 255 + 1) {
        scan_start = orig_len - (md_size + 255 + 1);
    }

    /* Ideally the next statement would be:
     *
     *   rotate_offset = (mac_start - scan_start) % md_size;
     *
     * However, division is not a constant-time operation (at least on Intel
     * chips). Thus we enumerate the possible values of md_size and handle each
     * separately. The value of |md_size| is public information (it's determined
     * by the cipher suite in the ServerHello) so our timing can vary based on
     * its value. */

    rotate_offset = mac_start - scan_start;
    /* rotate_offset can be, at most, 255 (bytes of padding) + 1 (padding length)
     * + md_size = 256 + 48 (since SHA-384 is the largest hash) = 304. */
    assert(rotate_offset <= 304);

    /* Below is an SMT-LIB2 verification that the Barrett reductions below are
     * correct within this range:
     *
     * (define-fun barrett (
     *     (x (_ BitVec 32))
     *     (mul (_ BitVec 32))
     *     (shift (_ BitVec 32))
     *     (divisor (_ BitVec 32)) ) (_ BitVec 32)
     *   (let ((q (bvsub x (bvmul divisor (bvlshr (bvmul x mul) shift))) ))
     *     (ite (bvuge q divisor)
     *       (bvsub q divisor)
     *       q)))
     *
     * (declare-fun x () (_ BitVec 32))
     *
     * (assert (or
     *   (let (
     *     (divisor (_ bv20 32))
     *     (mul (_ bv25 32))
     *     (shift (_ bv9 32))
     *     (limit (_ bv853 32)))
     *
     *     (and (bvule x limit) (not (= (bvurem x divisor)
     *                                  (barrett x mul shift divisor)))))
     *
     *   (let (
     *     (divisor (_ bv48 32))
     *     (mul (_ bv10 32))
     *     (shift (_ bv9 32))
     *     (limit (_ bv768 32)))
     *
     *     (and (bvule x limit) (not (= (bvurem x divisor)
     *                                  (barrett x mul shift divisor)))))
     * ))
     *
     * (check-sat)
     * (get-model)
     */

    if (md_size == 16) {
        rotate_offset &= 15;
    } else if (md_size == 20) {
        /* 1/20 is approximated as 25/512 and then Barrett reduction is used.
         * Analytically, this is correct for 0 <= rotate_offset <= 853. */
        unsigned q = (rotate_offset * 25) >> 9;
        rotate_offset -= q * 20;
        rotate_offset -=
            constant_time_select(constant_time_ge(rotate_offset, 20), 20, 0);
    } else if (md_size == 32) {