示例#1
0
int BN_generate_dsa_nonce(BIGNUM *out, const BIGNUM *range, const BIGNUM *priv,
                          const uint8_t *message, size_t message_len,
                          BN_CTX *ctx) {
  /* We copy |priv| into a local buffer to avoid furthur exposing its
   * length. */
  uint8_t private_bytes[96];
  size_t todo = sizeof(priv->d[0]) * priv->top;
  if (todo > sizeof(private_bytes)) {
    /* No reasonable DSA or ECDSA key should have a private key
     * this large and we don't handle this case in order to avoid
     * leaking the length of the private key. */
    OPENSSL_PUT_ERROR(BN, BN_R_PRIVATE_KEY_TOO_LARGE);
    return 0;
  }
  OPENSSL_memcpy(private_bytes, priv->d, todo);
  OPENSSL_memset(private_bytes + todo, 0, sizeof(private_bytes) - todo);

  /* Pass a SHA512 hash of the private key and message as additional data into
   * the RBG. This is a hardening measure against entropy failure. */
  OPENSSL_COMPILE_ASSERT(SHA512_DIGEST_LENGTH >= 32,
                         additional_data_is_too_large_for_sha512);
  SHA512_CTX sha;
  uint8_t digest[SHA512_DIGEST_LENGTH];
  SHA512_Init(&sha);
  SHA512_Update(&sha, private_bytes, sizeof(private_bytes));
  SHA512_Update(&sha, message, message_len);
  SHA512_Final(digest, &sha);

  /* Select a value k from [1, range-1], following FIPS 186-4 appendix B.5.2. */
  return bn_rand_range_with_additional_data(out, 1, range, digest);
}
示例#2
0
static int bn_cmp_words_consttime(const BN_ULONG *a, size_t a_len,
                                  const BN_ULONG *b, size_t b_len) {
  OPENSSL_COMPILE_ASSERT(sizeof(BN_ULONG) <= sizeof(crypto_word_t),
                         crypto_word_t_too_small);
  int ret = 0;
  // Process the common words in little-endian order.
  size_t min = a_len < b_len ? a_len : b_len;
  for (size_t i = 0; i < min; i++) {
    crypto_word_t eq = constant_time_eq_w(a[i], b[i]);
    crypto_word_t lt = constant_time_lt_w(a[i], b[i]);
    ret =
        constant_time_select_int(eq, ret, constant_time_select_int(lt, -1, 1));
  }

  // If |a| or |b| has non-zero words beyond |min|, they take precedence.
  if (a_len < b_len) {
    crypto_word_t mask = 0;
    for (size_t i = a_len; i < b_len; i++) {
      mask |= b[i];
    }
    ret = constant_time_select_int(constant_time_is_zero_w(mask), ret, -1);
  } else if (b_len < a_len) {
    crypto_word_t mask = 0;
    for (size_t i = b_len; i < a_len; i++) {
      mask |= a[i];
    }
    ret = constant_time_select_int(constant_time_is_zero_w(mask), ret, 1);
  }

  return ret;
}
示例#3
0
int SSL_set_private_key_digest_prefs(SSL *ssl, const int *digest_nids,
                                     size_t num_digests) {
  OPENSSL_free(ssl->cert->sigalgs);

  OPENSSL_COMPILE_ASSERT(sizeof(int) >= 2 * sizeof(uint16_t),
                         digest_list_conversion_cannot_overflow);

  ssl->cert->num_sigalgs = 0;
  ssl->cert->sigalgs = OPENSSL_malloc(sizeof(uint16_t) * 2 * num_digests);
  if (ssl->cert->sigalgs == NULL) {
    OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
    return 0;
  }

  /* Convert the digest list to a signature algorithms list.
   *
   * TODO(davidben): Replace this API with one that can express RSA-PSS, etc. */
  for (size_t i = 0; i < num_digests; i++) {
    switch (digest_nids[i]) {
      case NID_sha1:
        ssl->cert->sigalgs[ssl->cert->num_sigalgs] = SSL_SIGN_RSA_PKCS1_SHA1;
        ssl->cert->sigalgs[ssl->cert->num_sigalgs + 1] = SSL_SIGN_ECDSA_SHA1;
        ssl->cert->num_sigalgs += 2;
        break;
      case NID_sha256:
        ssl->cert->sigalgs[ssl->cert->num_sigalgs] = SSL_SIGN_RSA_PKCS1_SHA256;
        ssl->cert->sigalgs[ssl->cert->num_sigalgs + 1] =
            SSL_SIGN_ECDSA_SECP256R1_SHA256;
        ssl->cert->num_sigalgs += 2;
        break;
      case NID_sha384:
        ssl->cert->sigalgs[ssl->cert->num_sigalgs] = SSL_SIGN_RSA_PKCS1_SHA384;
        ssl->cert->sigalgs[ssl->cert->num_sigalgs + 1] =
            SSL_SIGN_ECDSA_SECP384R1_SHA384;
        ssl->cert->num_sigalgs += 2;
        break;
      case NID_sha512:
        ssl->cert->sigalgs[ssl->cert->num_sigalgs] = SSL_SIGN_RSA_PKCS1_SHA512;
        ssl->cert->sigalgs[ssl->cert->num_sigalgs + 1] =
            SSL_SIGN_ECDSA_SECP521R1_SHA512;
        ssl->cert->num_sigalgs += 2;
        break;
    }
  }

  return 1;
}
示例#4
0
long ASN1_INTEGER_get(const ASN1_INTEGER *a)
{
    int neg = 0, i;

    if (a == NULL)
        return (0L);
    i = a->type;
    if (i == V_ASN1_NEG_INTEGER)
        neg = 1;
    else if (i != V_ASN1_INTEGER)
        return -1;

    OPENSSL_COMPILE_ASSERT(sizeof(uint64_t) >= sizeof(long),
                           long_larger_than_uint64_t);

    if (a->length > (int)sizeof(uint64_t)) {
        /* hmm... a bit ugly, return all ones */
        return -1;
    }

    uint64_t r64 = 0;
    if (a->data != NULL) {
      for (i = 0; i < a->length; i++) {
          r64 <<= 8;
          r64 |= (unsigned char)a->data[i];
      }

      if (r64 > LONG_MAX) {
          return -1;
      }
    }

    long r = (long) r64;
    if (neg)
        r = -r;

    return r;
}
示例#5
0
文件: random.c 项目: frewsxcv/ring
int BN_generate_dsa_nonce(BIGNUM *out, const BIGNUM *range, const BIGNUM *priv,
                          const uint8_t *message, size_t message_len) {
    /* We use 512 bits of random data per iteration to
     * ensure that we have at least |range| bits of randomness. */
    uint8_t random_bytes[64];
    uint8_t digest[SHA512_DIGEST_LENGTH];
    const unsigned num_k_bytes = BN_num_bytes(range);
    const unsigned bits_to_mask = (8 - (BN_num_bits(range) % 8)) % 8;
    uint8_t private_bytes[SHA512_DIGEST_LENGTH];
    uint8_t *k_bytes = NULL;
    int ret = 0;

    if (out == NULL) {
        return 0;
    }

    if (BN_is_zero(range)) {
        OPENSSL_PUT_ERROR(BN, BN_R_DIV_BY_ZERO);
        goto err;
    }

    k_bytes = OPENSSL_malloc(num_k_bytes);
    if (!k_bytes) {
        OPENSSL_PUT_ERROR(BN, ERR_R_MALLOC_FAILURE);
        goto err;
    }

    /* We copy |priv| into a local buffer to avoid furthur exposing its
     * length. */
    size_t todo = sizeof(priv->d[0]) * priv->top;
    if (todo > sizeof(private_bytes)) {
        /* No ECDSA key for a curve we support has a private key this large and we
         * don't handle this case in order to avoid leaking the length of the
         * private key and so we can generate the nonce with just one call to
         * |BN_generate_dsa_nonce_digest|. */
        OPENSSL_PUT_ERROR(BN, BN_R_PRIVATE_KEY_TOO_LARGE);
        goto err;
    }
    memcpy(private_bytes, priv->d, todo);
    memset(private_bytes + todo, 0, sizeof(private_bytes) - todo);

    OPENSSL_COMPILE_ASSERT(sizeof(digest) == sizeof(private_bytes),
                           BN_generate_dsa_nonce_digest_may_not_generate_enough);

    for (uint32_t attempt = 0;; attempt++) {
        uint8_t attempt_be[4];
        to_be_u32_ptr(attempt_be, attempt);
        if (!RAND_bytes(random_bytes, sizeof(random_bytes)) ||
                !BN_generate_dsa_nonce_digest(digest, sizeof(digest), attempt_be,
                                              sizeof(attempt_be), private_bytes,
                                              sizeof(private_bytes), message,
                                              message_len, random_bytes,
                                              sizeof(random_bytes))) {
            goto err;
        }

        memcpy(k_bytes, digest, num_k_bytes);

        k_bytes[0] &= 0xff >> bits_to_mask;

        if (!BN_bin2bn(k_bytes, num_k_bytes, out)) {
            goto err;
        }
        if (BN_cmp(out, range) < 0) {
            break;
        }

        if (attempt == 255) {
            /* This should never happen in practice. If it were to happen then it is
             * very likely that the something is very wrong. Note that 255 is
             * arbitrary; the limit should be |UINT32_MAX| or less in order for
             * |attempt| to avoid wrapping around; */
            OPENSSL_PUT_ERROR(BN, BN_R_TOO_MANY_ITERATIONS);
            goto err;
        }
    }

    ret = 1;

err:
    OPENSSL_free(k_bytes);
    return ret;
}
示例#6
0
// bn_mul_part_recursive sets |r| to |a| * |b|, using |t| as scratch space. |r|
// has length 4*|n|, |a| has length |n| + |tna|, |b| has length |n| + |tnb|, and
// |t| has length 8*|n|. |n| must be a power of two. Additionally, we must have
// 0 <= tna < n and 0 <= tnb < n, and |tna| and |tnb| must differ by at most
// one.
//
// TODO(davidben): Make this take |size_t| and perhaps the actual lengths of |a|
// and |b|.
static void bn_mul_part_recursive(BN_ULONG *r, const BN_ULONG *a,
                                  const BN_ULONG *b, int n, int tna, int tnb,
                                  BN_ULONG *t) {
  // |n| is a power of two.
  assert(n != 0 && (n & (n - 1)) == 0);
  // Check |tna| and |tnb| are in range.
  assert(0 <= tna && tna < n);
  assert(0 <= tnb && tnb < n);
  assert(-1 <= tna - tnb && tna - tnb <= 1);

  int n2 = n * 2;
  if (n < 8) {
    bn_mul_normal(r, a, n + tna, b, n + tnb);
    OPENSSL_memset(r + n2 + tna + tnb, 0, n2 - tna - tnb);
    return;
  }

  // Split |a| and |b| into a0,a1 and b0,b1, where a0 and b0 have size |n|. |a1|
  // and |b1| have size |tna| and |tnb|, respectively.
  // Split |t| into t0,t1,t2,t3, each of size |n|, with the remaining 4*|n| used
  // for recursive calls.
  // Split |r| into r0,r1,r2,r3. We must contribute a0*b0 to r0,r1, a0*a1+b0*b1
  // to r1,r2, and a1*b1 to r2,r3. The middle term we will compute as:
  //
  //   a0*a1 + b0*b1 = (a0 - a1)*(b1 - b0) + a1*b1 + a0*b0

  // t0 = a0 - a1 and t1 = b1 - b0. The result will be multiplied, so we XOR
  // their sign masks, giving the sign of (a0 - a1)*(b1 - b0). t0 and t1
  // themselves store the absolute value.
  BN_ULONG neg = bn_abs_sub_part_words(t, a, &a[n], tna, n - tna, &t[n2]);
  neg ^= bn_abs_sub_part_words(&t[n], &b[n], b, tnb, tnb - n, &t[n2]);

  // Compute:
  // t2,t3 = t0 * t1 = |(a0 - a1)*(b1 - b0)|
  // r0,r1 = a0 * b0
  // r2,r3 = a1 * b1
  if (n == 8) {
    bn_mul_comba8(&t[n2], t, &t[n]);
    bn_mul_comba8(r, a, b);

    bn_mul_normal(&r[n2], &a[n], tna, &b[n], tnb);
    // |bn_mul_normal| only writes |tna| + |tna| words. Zero the rest.
    OPENSSL_memset(&r[n2 + tna + tnb], 0, sizeof(BN_ULONG) * (n2 - tna - tnb));
  } else {
    BN_ULONG *p = &t[n2 * 2];
    bn_mul_recursive(&t[n2], t, &t[n], n, 0, 0, p);
    bn_mul_recursive(r, a, b, n, 0, 0, p);

    OPENSSL_memset(&r[n2], 0, sizeof(BN_ULONG) * n2);
    if (tna < BN_MUL_RECURSIVE_SIZE_NORMAL &&
        tnb < BN_MUL_RECURSIVE_SIZE_NORMAL) {
      bn_mul_normal(&r[n2], &a[n], tna, &b[n], tnb);
    } else {
      int i = n;
      for (;;) {
        i /= 2;
        if (i < tna || i < tnb) {
          // E.g., n == 16, i == 8 and tna == 11. |tna| and |tnb| are within one
          // of each other, so if |tna| is larger and tna > i, then we know
          // tnb >= i, and this call is valid.
          bn_mul_part_recursive(&r[n2], &a[n], &b[n], i, tna - i, tnb - i, p);
          break;
        }
        if (i == tna || i == tnb) {
          // If there is only a bottom half to the number, just do it. We know
          // the larger of |tna - i| and |tnb - i| is zero. The other is zero or
          // -1 by because of |tna| and |tnb| differ by at most one.
          bn_mul_recursive(&r[n2], &a[n], &b[n], i, tna - i, tnb - i, p);
          break;
        }

        // This loop will eventually terminate when |i| falls below
        // |BN_MUL_RECURSIVE_SIZE_NORMAL| because we know one of |tna| and |tnb|
        // exceeds that.
      }
    }
  }

  // t0,t1,c = r0,r1 + r2,r3 = a0*b0 + a1*b1
  BN_ULONG c = bn_add_words(t, r, &r[n2], n2);

  // t2,t3,c = t0,t1,c + neg*t2,t3 = (a0 - a1)*(b1 - b0) + a1*b1 + a0*b0.
  // The second term is stored as the absolute value, so we do this with a
  // constant-time select.
  BN_ULONG c_neg = c - bn_sub_words(&t[n2 * 2], t, &t[n2], n2);
  BN_ULONG c_pos = c + bn_add_words(&t[n2], t, &t[n2], n2);
  bn_select_words(&t[n2], neg, &t[n2 * 2], &t[n2], n2);
  OPENSSL_COMPILE_ASSERT(sizeof(BN_ULONG) <= sizeof(crypto_word_t),
                         crypto_word_t_too_small);
  c = constant_time_select_w(neg, c_neg, c_pos);

  // We now have our three components. Add them together.
  // r1,r2,c = r1,r2 + t2,t3,c
  c += bn_add_words(&r[n], &r[n], &t[n2], n2);

  // Propagate the carry bit to the end.
  for (int i = n + n2; i < n2 + n2; i++) {
    BN_ULONG old = r[i];
    r[i] = old + c;
    c = r[i] < old;
  }

  // The product should fit without carries.
  assert(c == 0);
}
示例#7
0
// bn_mul_recursive sets |r| to |a| * |b|, using |t| as scratch space. |r| has
// length 2*|n2|, |a| has length |n2| + |dna|, |b| has length |n2| + |dnb|, and
// |t| has length 4*|n2|. |n2| must be a power of two. Finally, we must have
// -|BN_MUL_RECURSIVE_SIZE_NORMAL|/2 <= |dna| <= 0 and
// -|BN_MUL_RECURSIVE_SIZE_NORMAL|/2 <= |dnb| <= 0.
//
// TODO(davidben): Simplify and |size_t| the calling convention around lengths
// here.
static void bn_mul_recursive(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b,
                             int n2, int dna, int dnb, BN_ULONG *t) {
  // |n2| is a power of two.
  assert(n2 != 0 && (n2 & (n2 - 1)) == 0);
  // Check |dna| and |dnb| are in range.
  assert(-BN_MUL_RECURSIVE_SIZE_NORMAL/2 <= dna && dna <= 0);
  assert(-BN_MUL_RECURSIVE_SIZE_NORMAL/2 <= dnb && dnb <= 0);

  // Only call bn_mul_comba 8 if n2 == 8 and the
  // two arrays are complete [steve]
  if (n2 == 8 && dna == 0 && dnb == 0) {
    bn_mul_comba8(r, a, b);
    return;
  }

  // Else do normal multiply
  if (n2 < BN_MUL_RECURSIVE_SIZE_NORMAL) {
    bn_mul_normal(r, a, n2 + dna, b, n2 + dnb);
    if (dna + dnb < 0) {
      OPENSSL_memset(&r[2 * n2 + dna + dnb], 0,
                     sizeof(BN_ULONG) * -(dna + dnb));
    }
    return;
  }

  // Split |a| and |b| into a0,a1 and b0,b1, where a0 and b0 have size |n|.
  // Split |t| into t0,t1,t2,t3, each of size |n|, with the remaining 4*|n| used
  // for recursive calls.
  // Split |r| into r0,r1,r2,r3. We must contribute a0*b0 to r0,r1, a0*a1+b0*b1
  // to r1,r2, and a1*b1 to r2,r3. The middle term we will compute as:
  //
  //   a0*a1 + b0*b1 = (a0 - a1)*(b1 - b0) + a1*b1 + a0*b0
  //
  // Note that we know |n| >= |BN_MUL_RECURSIVE_SIZE_NORMAL|/2 above, so
  // |tna| and |tnb| are non-negative.
  int n = n2 / 2, tna = n + dna, tnb = n + dnb;

  // t0 = a0 - a1 and t1 = b1 - b0. The result will be multiplied, so we XOR
  // their sign masks, giving the sign of (a0 - a1)*(b1 - b0). t0 and t1
  // themselves store the absolute value.
  BN_ULONG neg = bn_abs_sub_part_words(t, a, &a[n], tna, n - tna, &t[n2]);
  neg ^= bn_abs_sub_part_words(&t[n], &b[n], b, tnb, tnb - n, &t[n2]);

  // Compute:
  // t2,t3 = t0 * t1 = |(a0 - a1)*(b1 - b0)|
  // r0,r1 = a0 * b0
  // r2,r3 = a1 * b1
  if (n == 4 && dna == 0 && dnb == 0) {
    bn_mul_comba4(&t[n2], t, &t[n]);

    bn_mul_comba4(r, a, b);
    bn_mul_comba4(&r[n2], &a[n], &b[n]);
  } else if (n == 8 && dna == 0 && dnb == 0) {
    bn_mul_comba8(&t[n2], t, &t[n]);

    bn_mul_comba8(r, a, b);
    bn_mul_comba8(&r[n2], &a[n], &b[n]);
  } else {
    BN_ULONG *p = &t[n2 * 2];
    bn_mul_recursive(&t[n2], t, &t[n], n, 0, 0, p);
    bn_mul_recursive(r, a, b, n, 0, 0, p);
    bn_mul_recursive(&r[n2], &a[n], &b[n], n, dna, dnb, p);
  }

  // t0,t1,c = r0,r1 + r2,r3 = a0*b0 + a1*b1
  BN_ULONG c = bn_add_words(t, r, &r[n2], n2);

  // t2,t3,c = t0,t1,c + neg*t2,t3 = (a0 - a1)*(b1 - b0) + a1*b1 + a0*b0.
  // The second term is stored as the absolute value, so we do this with a
  // constant-time select.
  BN_ULONG c_neg = c - bn_sub_words(&t[n2 * 2], t, &t[n2], n2);
  BN_ULONG c_pos = c + bn_add_words(&t[n2], t, &t[n2], n2);
  bn_select_words(&t[n2], neg, &t[n2 * 2], &t[n2], n2);
  OPENSSL_COMPILE_ASSERT(sizeof(BN_ULONG) <= sizeof(crypto_word_t),
                         crypto_word_t_too_small);
  c = constant_time_select_w(neg, c_neg, c_pos);

  // We now have our three components. Add them together.
  // r1,r2,c = r1,r2 + t2,t3,c
  c += bn_add_words(&r[n], &r[n], &t[n2], n2);

  // Propagate the carry bit to the end.
  for (int i = n + n2; i < n2 + n2; i++) {
    BN_ULONG old = r[i];
    r[i] = old + c;
    c = r[i] < old;
  }

  // The product should fit without carries.
  assert(c == 0);
}