예제 #1
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);

  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) {
예제 #2
0
int EVP_tls_cbc_remove_padding(unsigned *out_len,
                               const uint8_t *in, unsigned in_len,
                               unsigned block_size, unsigned mac_size) {
  unsigned padding_length, good, to_check, i;
  const unsigned overhead = 1 /* padding length byte */ + mac_size;

  /* These lengths are all public so we can test them in non-constant time. */
  if (overhead > in_len) {
    return 0;
  }

  padding_length = in[in_len - 1];

  good = constant_time_ge(in_len, overhead + padding_length);
  /* The padding consists of a length byte at the end of the record and
   * then that many bytes of padding, all with the same value as the
   * length byte. Thus, with the length byte included, there are i+1
   * bytes of padding.
   *
   * We can't check just |padding_length+1| bytes because that leaks
   * decrypted information. Therefore we always have to check the maximum
   * amount of padding possible. (Again, the length of the record is
   * public information so we can use it.) */
  to_check = 256; /* maximum amount of padding, inc length byte. */
  if (to_check > in_len) {
    to_check = in_len;
  }

  for (i = 0; i < to_check; i++) {
    uint8_t mask = constant_time_ge_8(padding_length, i);
    uint8_t b = in[in_len - 1 - i];
    /* The final |padding_length+1| bytes should all have the value
     * |padding_length|. Therefore the XOR should be zero. */
    good &= ~(mask & (padding_length ^ b));
  }

  /* If any of the final |padding_length+1| bytes had the wrong value,
   * one or more of the lower eight bits of |good| will be cleared. */
  good = constant_time_eq(0xff, good & 0xff);

  /* Always treat |padding_length| as zero on error. If, assuming block size of
   * 16, a padding of [<15 arbitrary bytes> 15] treated |padding_length| as 16
   * and returned -1, distinguishing good MAC and bad padding from bad MAC and
   * bad padding would give POODLE's padding oracle. */
  padding_length = good & (padding_length + 1);
  *out_len = in_len - padding_length;

  return constant_time_select_int(good, 1, -1);
}
예제 #3
0
파일: padding.c 프로젝트: Ms2ger/ring
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;
}
예제 #4
0
파일: rsa_pk1.c 프로젝트: AndreV84/openssl
int RSA_padding_check_PKCS1_type_2(unsigned char *to, int tlen,
                                   const unsigned char *from, int flen,
                                   int num)
{
    int i;
    /* |em| is the encoded message, zero-padded to exactly |num| bytes */
    unsigned char *em = NULL;
    unsigned int good, found_zero_byte;
    int zero_index = 0, msg_index, mlen = -1;

    if (tlen < 0 || flen < 0)
        return -1;

    /*
     * PKCS#1 v1.5 decryption. See "PKCS #1 v2.2: RSA Cryptography Standard",
     * section 7.2.2.
     */

    if (flen > num)
        goto err;

    if (num < 11)
        goto err;

    em = OPENSSL_zalloc(num);
    if (em == NULL) {
        RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_2, ERR_R_MALLOC_FAILURE);
        return -1;
    }
    /*
     * Always do this zero-padding copy (even when num == flen) to avoid
     * leaking that information. The copy still leaks some side-channel
     * information, but it's impossible to have a fixed  memory access
     * pattern since we can't read out of the bounds of |from|.
     *
     * TODO(emilia): Consider porting BN_bn2bin_padded from BoringSSL.
     */
    memcpy(em + num - flen, from, flen);

    good = constant_time_is_zero(em[0]);
    good &= constant_time_eq(em[1], 2);

    found_zero_byte = 0;
    for (i = 2; i < num; i++) {
        unsigned int equals0 = constant_time_is_zero(em[i]);
        zero_index =
            constant_time_select_int(~found_zero_byte & equals0, i,
                                     zero_index);
        found_zero_byte |= equals0;
    }

    /*
     * PS must be at least 8 bytes long, and it starts two bytes into |em|.
     * If we never found a 0-byte, then |zero_index| is 0 and the check
     * also fails.
     */
    good &= constant_time_ge((unsigned int)(zero_index), 2 + 8);

    /*
     * Skip the zero byte. This is incorrect if we never found a zero-byte
     * but in this case we also do not copy the message out.
     */
    msg_index = zero_index + 1;
    mlen = num - msg_index;

    /*
     * For good measure, do this check in constant time as well; it could
     * leak something if |tlen| was assuming valid padding.
     */
    good &= constant_time_ge((unsigned int)(tlen), (unsigned int)(mlen));

    /*
     * We can't continue in constant-time because we need to copy the result
     * and we cannot fake its length. This unavoidably leaks timing
     * information at the API boundary.
     * TODO(emilia): this could be addressed at the call site,
     * see BoringSSL commit 0aa0767340baf925bda4804882aab0cb974b2d26.
     */
    if (!good) {
        mlen = -1;
        goto err;
    }

    memcpy(to, em + msg_index, mlen);

 err:
    OPENSSL_free(em);
    if (mlen == -1)
        RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_2,
               RSA_R_PKCS_DECODING_ERROR);
    return mlen;
}
예제 #5
0
int RSA_padding_check_PKCS1_type_2(unsigned char *to, int tlen,
                                   const unsigned char *from, int flen,
                                   int num)
{
    int i;
    /* |em| is the encoded message, zero-padded to exactly |num| bytes */
    unsigned char *em = NULL;
    unsigned int good, found_zero_byte, mask;
    int zero_index = 0, msg_index, mlen = -1;

    if (tlen < 0 || flen < 0)
        return -1;

    /*
     * PKCS#1 v1.5 decryption. See "PKCS #1 v2.2: RSA Cryptography Standard",
     * section 7.2.2.
     */

    if (flen > num || num < 11) {
        RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_2,
               RSA_R_PKCS_DECODING_ERROR);
        return -1;
    }

    em = OPENSSL_malloc(num);
    if (em == NULL) {
        RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_2, ERR_R_MALLOC_FAILURE);
        return -1;
    }
    /*
     * Caller is encouraged to pass zero-padded message created with
     * BN_bn2binpad. Trouble is that since we can't read out of |from|'s
     * bounds, it's impossible to have an invariant memory access pattern
     * in case |from| was not zero-padded in advance.
     */
    for (from += flen, em += num, i = 0; i < num; i++) {
        mask = ~constant_time_is_zero(flen);
        flen -= 1 & mask;
        from -= 1 & mask;
        *--em = *from & mask;
    }
    from = em;

    good = constant_time_is_zero(from[0]);
    good &= constant_time_eq(from[1], 2);

    /* scan over padding data */
    found_zero_byte = 0;
    for (i = 2; i < num; i++) {
        unsigned int equals0 = constant_time_is_zero(from[i]);

        zero_index = constant_time_select_int(~found_zero_byte & equals0,
                                              i, zero_index);
        found_zero_byte |= equals0;
    }

    /*
     * PS must be at least 8 bytes long, and it starts two bytes into |from|.
     * If we never found a 0-byte, then |zero_index| is 0 and the check
     * also fails.
     */
    good &= constant_time_ge(zero_index, 2 + 8);

    /*
     * Skip the zero byte. This is incorrect if we never found a zero-byte
     * but in this case we also do not copy the message out.
     */
    msg_index = zero_index + 1;
    mlen = num - msg_index;

    /*
     * For good measure, do this check in constant time as well.
     */
    good &= constant_time_ge(tlen, mlen);

    /*
     * Even though we can't fake result's length, we can pretend copying
     * |tlen| bytes where |mlen| bytes would be real. Last |tlen| of |num|
     * bytes are viewed as circular buffer with start at |tlen|-|mlen'|,
     * where |mlen'| is "saturated" |mlen| value. Deducing information
     * about failure or |mlen| would take attacker's ability to observe
     * memory access pattern with byte granularity *as it occurs*. It
     * should be noted that failure is indistinguishable from normal
     * operation if |tlen| is fixed by protocol.
     */
    tlen = constant_time_select_int(constant_time_lt(num, tlen), num, tlen);
    msg_index = constant_time_select_int(good, msg_index, num - tlen);
    mlen = num - msg_index;
    for (from += msg_index, mask = good, i = 0; i < tlen; i++) {
        unsigned int equals = constant_time_eq(i, mlen);

        from -= tlen & equals;  /* if (i == mlen) rewind   */
        mask &= mask ^ equals;  /* if (i == mlen) mask = 0 */
        to[i] = constant_time_select_8(mask, from[i], to[i]);
    }

    OPENSSL_cleanse(em, num);
    OPENSSL_free(em);
    RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_2, RSA_R_PKCS_DECODING_ERROR);
    err_clear_last_constant_time(1 & good);

    return constant_time_select_int(good, mlen, -1);
}
예제 #6
0
파일: tls_cbc.c 프로젝트: gfxcc/iShareOC
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) {