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