// Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include <openssl/dsa.h>

#include <string.h>

#include <openssl/bn.h>
#include <openssl/dh.h>
#include <openssl/digest.h>
#include <openssl/engine.h>
#include <openssl/err.h>
#include <openssl/ex_data.h>
#include <openssl/mem.h>
#include <openssl/rand.h>
#include <openssl/sha.h>

#include "../fipsmodule/bn/internal.h"
#include "../fipsmodule/dh/internal.h"
#include "../internal.h"
#include "internal.h"


static_assert(OPENSSL_DSA_MAX_MODULUS_BITS <=
                  BN_MONTGOMERY_MAX_WORDS * BN_BITS2,
              "Max DSA size too big for Montgomery arithmetic");

// Primality test according to FIPS PUB 186[-1], Appendix 2.1: 50 rounds of
// Miller-Rabin.
#define DSS_prime_checks 50

static int dsa_sign_setup(const DSA *dsa, BN_CTX *ctx_in, BIGNUM **out_kinv,
                          BIGNUM **out_r);

static CRYPTO_EX_DATA_CLASS g_ex_data_class = CRYPTO_EX_DATA_CLASS_INIT;

DSA *DSA_new(void) {
  DSA *dsa = reinterpret_cast<DSA *>(OPENSSL_zalloc(sizeof(DSA)));
  if (dsa == NULL) {
    return NULL;
  }

  dsa->references = 1;
  CRYPTO_MUTEX_init(&dsa->method_mont_lock);
  CRYPTO_new_ex_data(&dsa->ex_data);
  return dsa;
}

void DSA_free(DSA *dsa) {
  if (dsa == NULL) {
    return;
  }

  if (!CRYPTO_refcount_dec_and_test_zero(&dsa->references)) {
    return;
  }

  CRYPTO_free_ex_data(&g_ex_data_class, &dsa->ex_data);

  BN_clear_free(dsa->p);
  BN_clear_free(dsa->q);
  BN_clear_free(dsa->g);
  BN_clear_free(dsa->pub_key);
  BN_clear_free(dsa->priv_key);
  BN_MONT_CTX_free(dsa->method_mont_p);
  BN_MONT_CTX_free(dsa->method_mont_q);
  CRYPTO_MUTEX_cleanup(&dsa->method_mont_lock);
  OPENSSL_free(dsa);
}

int DSA_up_ref(DSA *dsa) {
  CRYPTO_refcount_inc(&dsa->references);
  return 1;
}

unsigned DSA_bits(const DSA *dsa) { return BN_num_bits(dsa->p); }

const BIGNUM *DSA_get0_pub_key(const DSA *dsa) { return dsa->pub_key; }

const BIGNUM *DSA_get0_priv_key(const DSA *dsa) { return dsa->priv_key; }

const BIGNUM *DSA_get0_p(const DSA *dsa) { return dsa->p; }

const BIGNUM *DSA_get0_q(const DSA *dsa) { return dsa->q; }

const BIGNUM *DSA_get0_g(const DSA *dsa) { return dsa->g; }

void DSA_get0_key(const DSA *dsa, const BIGNUM **out_pub_key,
                  const BIGNUM **out_priv_key) {
  if (out_pub_key != NULL) {
    *out_pub_key = dsa->pub_key;
  }
  if (out_priv_key != NULL) {
    *out_priv_key = dsa->priv_key;
  }
}

void DSA_get0_pqg(const DSA *dsa, const BIGNUM **out_p, const BIGNUM **out_q,
                  const BIGNUM **out_g) {
  if (out_p != NULL) {
    *out_p = dsa->p;
  }
  if (out_q != NULL) {
    *out_q = dsa->q;
  }
  if (out_g != NULL) {
    *out_g = dsa->g;
  }
}

int DSA_set0_key(DSA *dsa, BIGNUM *pub_key, BIGNUM *priv_key) {
  if (dsa->pub_key == NULL && pub_key == NULL) {
    return 0;
  }

  if (pub_key != NULL) {
    BN_free(dsa->pub_key);
    dsa->pub_key = pub_key;
  }
  if (priv_key != NULL) {
    BN_free(dsa->priv_key);
    dsa->priv_key = priv_key;
  }

  return 1;
}

int DSA_set0_pqg(DSA *dsa, BIGNUM *p, BIGNUM *q, BIGNUM *g) {
  if ((dsa->p == NULL && p == NULL) || (dsa->q == NULL && q == NULL) ||
      (dsa->g == NULL && g == NULL)) {
    return 0;
  }

  if (p != NULL) {
    BN_free(dsa->p);
    dsa->p = p;
  }
  if (q != NULL) {
    BN_free(dsa->q);
    dsa->q = q;
  }
  if (g != NULL) {
    BN_free(dsa->g);
    dsa->g = g;
  }

  BN_MONT_CTX_free(dsa->method_mont_p);
  dsa->method_mont_p = NULL;
  BN_MONT_CTX_free(dsa->method_mont_q);
  dsa->method_mont_q = NULL;
  return 1;
}

int DSA_generate_parameters_ex(DSA *dsa, unsigned bits, const uint8_t *seed_in,
                               size_t seed_len, int *out_counter,
                               unsigned long *out_h, BN_GENCB *cb) {
  if (bits > OPENSSL_DSA_MAX_MODULUS_BITS) {
    OPENSSL_PUT_ERROR(DSA, DSA_R_INVALID_PARAMETERS);
    return 0;
  }

  unsigned char seed[SHA256_DIGEST_LENGTH];
  unsigned char md[SHA256_DIGEST_LENGTH];
  unsigned char buf[SHA256_DIGEST_LENGTH], buf2[SHA256_DIGEST_LENGTH];
  BIGNUM *r0, *W, *X, *c, *test;
  BIGNUM *g = NULL, *q = NULL, *p = NULL;
  int k, n = 0, m = 0;
  int counter = 0;
  int r = 0;
  unsigned int h = 2;
  const EVP_MD *evpmd;

  evpmd = (bits >= 2048) ? EVP_sha256() : EVP_sha1();
  size_t qsize = EVP_MD_size(evpmd);

  if (bits < 512) {
    bits = 512;
  }

  bits = (bits + 63) / 64 * 64;

  if (seed_in != NULL) {
    if (seed_len < qsize) {
      return 0;
    }
    if (seed_len > qsize) {
      // Only consume as much seed as is expected.
      seed_len = qsize;
    }
    OPENSSL_memcpy(seed, seed_in, seed_len);
  }

  bssl::UniquePtr<BN_CTX> ctx(BN_CTX_new());
  if (ctx == nullptr) {
    return 0;
  }
  bssl::BN_CTXScope scope(ctx.get());

  r0 = BN_CTX_get(ctx.get());
  g = BN_CTX_get(ctx.get());
  W = BN_CTX_get(ctx.get());
  q = BN_CTX_get(ctx.get());
  X = BN_CTX_get(ctx.get());
  c = BN_CTX_get(ctx.get());
  p = BN_CTX_get(ctx.get());
  test = BN_CTX_get(ctx.get());

  if (test == NULL || !BN_lshift(test, BN_value_one(), bits - 1)) {
    return 0;
  }

  for (;;) {
    // Find q.
    for (;;) {
      // step 1
      if (!BN_GENCB_call(cb, BN_GENCB_GENERATED, m++)) {
        return 0;
      }

      int use_random_seed = (seed_in == NULL);
      if (use_random_seed) {
        if (!RAND_bytes(seed, qsize)) {
          return 0;
        }
        // DSA parameters are public.
        CONSTTIME_DECLASSIFY(seed, qsize);
      } else {
        // If we come back through, use random seed next time.
        seed_in = NULL;
      }
      OPENSSL_memcpy(buf, seed, qsize);
      OPENSSL_memcpy(buf2, seed, qsize);
      // precompute "SEED + 1" for step 7:
      for (size_t i = qsize - 1; i < qsize; i--) {
        buf[i]++;
        if (buf[i] != 0) {
          break;
        }
      }

      // step 2
      if (!EVP_Digest(seed, qsize, md, NULL, evpmd, NULL) ||
          !EVP_Digest(buf, qsize, buf2, NULL, evpmd, NULL)) {
        return 0;
      }
      for (size_t i = 0; i < qsize; i++) {
        md[i] ^= buf2[i];
      }

      // step 3
      md[0] |= 0x80;
      md[qsize - 1] |= 0x01;
      if (!BN_bin2bn(md, qsize, q)) {
        return 0;
      }

      // step 4
      r = BN_is_prime_fasttest_ex(q, DSS_prime_checks, ctx.get(),
                                  use_random_seed, cb);
      if (r > 0) {
        break;
      }
      if (r != 0) {
        return 0;
      }

      // do a callback call
      // step 5
    }

    if (!BN_GENCB_call(cb, 2, 0) || !BN_GENCB_call(cb, 3, 0)) {
      return 0;
    }

    // step 6
    counter = 0;
    // "offset = 2"

    n = (bits - 1) / 160;

    for (;;) {
      if ((counter != 0) && !BN_GENCB_call(cb, BN_GENCB_GENERATED, counter)) {
        return 0;
      }

      // step 7
      BN_zero(W);
      // now 'buf' contains "SEED + offset - 1"
      for (k = 0; k <= n; k++) {
        // obtain "SEED + offset + k" by incrementing:
        for (size_t i = qsize - 1; i < qsize; i--) {
          buf[i]++;
          if (buf[i] != 0) {
            break;
          }
        }

        if (!EVP_Digest(buf, qsize, md, NULL, evpmd, NULL)) {
          return 0;
        }

        // step 8
        if (!BN_bin2bn(md, qsize, r0) || !BN_lshift(r0, r0, (qsize << 3) * k) ||
            !BN_add(W, W, r0)) {
          return 0;
        }
      }

      // more of step 8
      if (!BN_mask_bits(W, bits - 1) || !BN_copy(X, W) || !BN_add(X, X, test)) {
        return 0;
      }

      // step 9
      if (!BN_lshift1(r0, q) || !BN_mod(c, X, r0, ctx.get()) ||
          !BN_sub(r0, c, BN_value_one()) || !BN_sub(p, X, r0)) {
        return 0;
      }

      // step 10
      if (BN_cmp(p, test) >= 0) {
        // step 11
        r = BN_is_prime_fasttest_ex(p, DSS_prime_checks, ctx.get(), 1, cb);
        if (r > 0) {
          goto end;  // found it
        }
        if (r != 0) {
          return 0;
        }
      }

      // step 13
      counter++;
      // "offset = offset + n + 1"

      // step 14
      if (counter >= 4096) {
        break;
      }
    }
  }
end:
  if (!BN_GENCB_call(cb, 2, 1)) {
    return 0;
  }

  // We now need to generate g
  // Set r0=(p-1)/q
  if (!BN_sub(test, p, BN_value_one()) ||
      !BN_div(r0, NULL, test, q, ctx.get())) {
    return 0;
  }

  bssl::UniquePtr<BN_MONT_CTX> mont(BN_MONT_CTX_new_for_modulus(p, ctx.get()));
  if (mont == nullptr || !BN_set_word(test, h)) {
    return 0;
  }

  for (;;) {
    // g=test^r0%p
    if (!BN_mod_exp_mont(g, test, r0, p, ctx.get(), mont.get())) {
      return 0;
    }
    if (!BN_is_one(g)) {
      break;
    }
    if (!BN_add(test, test, BN_value_one())) {
      return 0;
    }
    h++;
  }

  if (!BN_GENCB_call(cb, 3, 1)) {
    return 0;
  }

  BN_free(dsa->p);
  BN_free(dsa->q);
  BN_free(dsa->g);
  dsa->p = BN_dup(p);
  dsa->q = BN_dup(q);
  dsa->g = BN_dup(g);
  if (dsa->p == NULL || dsa->q == NULL || dsa->g == NULL) {
    return 0;
  }
  if (out_counter != NULL) {
    *out_counter = counter;
  }
  if (out_h != NULL) {
    *out_h = h;
  }

  return 1;
}

DSA *DSAparams_dup(const DSA *dsa) {
  DSA *ret = DSA_new();
  if (ret == NULL) {
    return NULL;
  }
  ret->p = BN_dup(dsa->p);
  ret->q = BN_dup(dsa->q);
  ret->g = BN_dup(dsa->g);
  if (ret->p == NULL || ret->q == NULL || ret->g == NULL) {
    DSA_free(ret);
    return NULL;
  }
  return ret;
}

int DSA_generate_key(DSA *dsa) {
  if (!dsa_check_key(dsa)) {
    return 0;
  }

  bssl::UniquePtr<BN_CTX> ctx(BN_CTX_new());
  if (ctx == nullptr) {
    return 0;
  }

  int ok = 0;
  BIGNUM *pub_key = nullptr;
  BIGNUM *priv_key = dsa->priv_key;
  if (priv_key == nullptr) {
    priv_key = BN_new();
    if (priv_key == nullptr) {
      goto err;
    }
  }

  if (!BN_rand_range_ex(priv_key, 1, dsa->q)) {
    goto err;
  }

  pub_key = dsa->pub_key;
  if (pub_key == nullptr) {
    pub_key = BN_new();
    if (pub_key == nullptr) {
      goto err;
    }
  }

  if (!BN_MONT_CTX_set_locked(&dsa->method_mont_p, &dsa->method_mont_lock,
                              dsa->p, ctx.get()) ||
      !BN_mod_exp_mont_consttime(pub_key, dsa->g, priv_key, dsa->p, ctx.get(),
                                 dsa->method_mont_p)) {
    goto err;
  }

  // The public key is computed from the private key, but is public.
  bn_declassify(pub_key);

  dsa->priv_key = priv_key;
  dsa->pub_key = pub_key;
  ok = 1;

err:
  if (dsa->pub_key == nullptr) {
    BN_free(pub_key);
  }
  if (dsa->priv_key == nullptr) {
    BN_free(priv_key);
  }

  return ok;
}

DSA_SIG *DSA_SIG_new(void) {
  return reinterpret_cast<DSA_SIG *>(OPENSSL_zalloc(sizeof(DSA_SIG)));
}

void DSA_SIG_free(DSA_SIG *sig) {
  if (!sig) {
    return;
  }

  BN_free(sig->r);
  BN_free(sig->s);
  OPENSSL_free(sig);
}

void DSA_SIG_get0(const DSA_SIG *sig, const BIGNUM **out_r,
                  const BIGNUM **out_s) {
  if (out_r != NULL) {
    *out_r = sig->r;
  }
  if (out_s != NULL) {
    *out_s = sig->s;
  }
}

int DSA_SIG_set0(DSA_SIG *sig, BIGNUM *r, BIGNUM *s) {
  if (r == NULL || s == NULL) {
    return 0;
  }
  BN_free(sig->r);
  BN_free(sig->s);
  sig->r = r;
  sig->s = s;
  return 1;
}

// mod_mul_consttime sets |r| to |a| * |b| modulo |mont->N|, treating |a| and
// |b| as secret. This function internally uses Montgomery reduction, but
// neither inputs nor outputs are in Montgomery form.
static int mod_mul_consttime(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
                             const BN_MONT_CTX *mont, BN_CTX *ctx) {
  bssl::BN_CTXScope scope(ctx);
  BIGNUM *tmp = BN_CTX_get(ctx);
  // |BN_mod_mul_montgomery| removes a factor of R, so we cancel it with a
  // single |BN_to_montgomery| which adds one factor of R.
  return tmp != nullptr &&  //
         BN_to_montgomery(tmp, a, mont, ctx) &&
         BN_mod_mul_montgomery(r, tmp, b, mont, ctx);
}

DSA_SIG *DSA_do_sign(const uint8_t *digest, size_t digest_len, const DSA *dsa) {
  if (!dsa_check_key(dsa)) {
    return NULL;
  }

  if (dsa->priv_key == NULL) {
    OPENSSL_PUT_ERROR(DSA, DSA_R_MISSING_PARAMETERS);
    return NULL;
  }

  BIGNUM *kinv = NULL, *r = NULL, *s = NULL;
  BIGNUM m;
  BIGNUM xr;
  BN_CTX *ctx = NULL;
  DSA_SIG *ret = NULL;

  BN_init(&m);
  BN_init(&xr);
  s = BN_new();
  {
    if (s == NULL) {
      goto err;
    }
    ctx = BN_CTX_new();
    if (ctx == NULL) {
      goto err;
    }

    // Cap iterations so that invalid parameters do not infinite loop. This does
    // not impact valid parameters because the probability of requiring even one
    // retry is negligible, let alone 32. Unfortunately, DSA was mis-specified,
    // so invalid parameters are reachable from most callers handling untrusted
    // private keys. (The |dsa_check_key| call above is not sufficient. Checking
    // whether arbitrary paremeters form a valid DSA group is expensive.)
    static const int kMaxIterations = 32;
    int iters = 0;
  redo:
    if (!dsa_sign_setup(dsa, ctx, &kinv, &r)) {
      goto err;
    }

    if (digest_len > BN_num_bytes(dsa->q)) {
      // If the digest length is greater than the size of |dsa->q| use the
      // BN_num_bits(dsa->q) leftmost bits of the digest, see FIPS 186-3, 4.2.
      // Note the above check that |dsa->q| is a multiple of 8 bits.
      digest_len = BN_num_bytes(dsa->q);
    }

    if (BN_bin2bn(digest, digest_len, &m) == NULL) {
      goto err;
    }

    // |m| is bounded by 2^(num_bits(q)), which is slightly looser than q. This
    // violates |bn_mod_add_consttime| and |mod_mul_consttime|'s preconditions.
    // (The underlying algorithms could accept looser bounds, but we reduce for
    // simplicity.)
    size_t q_width = bn_minimal_width(dsa->q);
    if (!bn_resize_words(&m, q_width) || !bn_resize_words(&xr, q_width)) {
      goto err;
    }
    bn_reduce_once_in_place(m.d, 0 /* no carry word */, dsa->q->d,
                            xr.d /* scratch space */, q_width);

    // Compute s = inv(k) (m + xr) mod q. Note |dsa->method_mont_q| is
    // initialized by |dsa_sign_setup|.
    if (!mod_mul_consttime(&xr, dsa->priv_key, r, dsa->method_mont_q, ctx) ||
        !bn_mod_add_consttime(s, &xr, &m, dsa->q, ctx) ||
        !mod_mul_consttime(s, s, kinv, dsa->method_mont_q, ctx)) {
      goto err;
    }

    // The signature is computed from the private key, but is public.
    bn_declassify(r);
    bn_declassify(s);

    // Redo if r or s is zero as required by FIPS 186-3: this is
    // very unlikely.
    if (BN_is_zero(r) || BN_is_zero(s)) {
      iters++;
      if (iters > kMaxIterations) {
        OPENSSL_PUT_ERROR(DSA, DSA_R_TOO_MANY_ITERATIONS);
        goto err;
      }
      goto redo;
    }

    ret = DSA_SIG_new();
    if (ret == NULL) {
      goto err;
    }
    ret->r = r;
    ret->s = s;
  }

err:
  if (ret == NULL) {
    OPENSSL_PUT_ERROR(DSA, ERR_R_BN_LIB);
    BN_free(r);
    BN_free(s);
  }
  BN_CTX_free(ctx);
  BN_clear_free(&m);
  BN_clear_free(&xr);
  BN_clear_free(kinv);

  return ret;
}

int DSA_do_verify(const uint8_t *digest, size_t digest_len, const DSA_SIG *sig,
                  const DSA *dsa) {
  int valid;
  if (!DSA_do_check_signature(&valid, digest, digest_len, sig, dsa)) {
    return -1;
  }
  return valid;
}

int DSA_do_check_signature(int *out_valid, const uint8_t *digest,
                           size_t digest_len, const DSA_SIG *sig,
                           const DSA *dsa) {
  *out_valid = 0;
  if (!dsa_check_key(dsa)) {
    return 0;
  }

  if (dsa->pub_key == NULL) {
    OPENSSL_PUT_ERROR(DSA, DSA_R_MISSING_PARAMETERS);
    return 0;
  }

  int ret = 0;
  BIGNUM u1, u2, t1;
  BN_init(&u1);
  BN_init(&u2);
  BN_init(&t1);
  BN_CTX *ctx = BN_CTX_new();
  {
    if (ctx == NULL) {
      goto err;
    }

    if (BN_is_zero(sig->r) || BN_is_negative(sig->r) ||
        BN_ucmp(sig->r, dsa->q) >= 0) {
      ret = 1;
      goto err;
    }
    if (BN_is_zero(sig->s) || BN_is_negative(sig->s) ||
        BN_ucmp(sig->s, dsa->q) >= 0) {
      ret = 1;
      goto err;
    }

    if (!BN_MONT_CTX_set_locked((BN_MONT_CTX **)&dsa->method_mont_p,
                                (CRYPTO_MUTEX *)&dsa->method_mont_lock, dsa->p,
                                ctx) ||
        !BN_MONT_CTX_set_locked((BN_MONT_CTX **)&dsa->method_mont_q,
                                (CRYPTO_MUTEX *)&dsa->method_mont_lock, dsa->q,
                                ctx)) {
      goto err;
    }

    // Calculate W = inv(S) mod Q, in the Montgomery domain. This is slightly
    // more efficiently computed as FromMont(s)^-1 = (s * R^-1)^-1 = s^-1 * R,
    // instead of ToMont(s^-1) = s^-1 * R.
    if (!BN_from_montgomery(&u2, sig->s, dsa->method_mont_q, ctx) ||
        !BN_mod_inverse(&u2, &u2, dsa->q, ctx)) {
      goto err;
    }

    // save M in u1
    unsigned q_bits = BN_num_bits(dsa->q);
    if (digest_len > (q_bits >> 3)) {
      // if the digest length is greater than the size of q use the
      // BN_num_bits(dsa->q) leftmost bits of the digest, see
      // fips 186-3, 4.2
      digest_len = (q_bits >> 3);
    }

    if (BN_bin2bn(digest, digest_len, &u1) == NULL) {
      goto err;
    }

    // u1 = M * w mod q. w was stored in the Montgomery domain while M was not,
    // so the result will already be out of the Montgomery domain.
    if (!BN_mod_mul_montgomery(&u1, &u1, &u2, dsa->method_mont_q, ctx)) {
      goto err;
    }

    // u2 = r * w mod q. w was stored in the Montgomery domain while r was not,
    // so the result will already be out of the Montgomery domain.
    if (!BN_mod_mul_montgomery(&u2, sig->r, &u2, dsa->method_mont_q, ctx)) {
      goto err;
    }

    if (!BN_mod_exp2_mont(&t1, dsa->g, &u1, dsa->pub_key, &u2, dsa->p, ctx,
                          dsa->method_mont_p)) {
      goto err;
    }

    // let u1 = u1 mod q
    if (!BN_mod(&u1, &t1, dsa->q, ctx)) {
      goto err;
    }

    // V is now in u1.  If the signature is correct, it will be
    // equal to R.
    *out_valid = BN_ucmp(&u1, sig->r) == 0;
    ret = 1;
  }

err:
  if (ret != 1) {
    OPENSSL_PUT_ERROR(DSA, ERR_R_BN_LIB);
  }
  BN_CTX_free(ctx);
  BN_free(&u1);
  BN_free(&u2);
  BN_free(&t1);

  return ret;
}

int DSA_sign(int type, const uint8_t *digest, size_t digest_len,
             uint8_t *out_sig, unsigned int *out_siglen, const DSA *dsa) {
  DSA_SIG *s;

  s = DSA_do_sign(digest, digest_len, dsa);
  if (s == NULL) {
    *out_siglen = 0;
    return 0;
  }

  *out_siglen = i2d_DSA_SIG(s, &out_sig);
  DSA_SIG_free(s);
  return 1;
}

int DSA_verify(int type, const uint8_t *digest, size_t digest_len,
               const uint8_t *sig, size_t sig_len, const DSA *dsa) {
  int valid;
  if (!DSA_check_signature(&valid, digest, digest_len, sig, sig_len, dsa)) {
    return -1;
  }
  return valid;
}

int DSA_check_signature(int *out_valid, const uint8_t *digest,
                        size_t digest_len, const uint8_t *sig, size_t sig_len,
                        const DSA *dsa) {
  DSA_SIG *s = NULL;
  int ret = 0;
  uint8_t *der = NULL;

  s = DSA_SIG_new();
  {
    if (s == NULL) {
      goto err;
    }

    const uint8_t *sigp = sig;
    if (d2i_DSA_SIG(&s, &sigp, sig_len) == NULL || sigp != sig + sig_len) {
      goto err;
    }

    // Ensure that the signature uses DER and doesn't have trailing garbage.
    int der_len = i2d_DSA_SIG(s, &der);
    if (der_len < 0 || (size_t)der_len != sig_len ||
        OPENSSL_memcmp(sig, der, sig_len)) {
      goto err;
    }

    ret = DSA_do_check_signature(out_valid, digest, digest_len, s, dsa);
  }

err:
  OPENSSL_free(der);
  DSA_SIG_free(s);
  return ret;
}

// der_len_len returns the number of bytes needed to represent a length of |len|
// in DER.
static size_t der_len_len(size_t len) {
  if (len < 0x80) {
    return 1;
  }
  size_t ret = 1;
  while (len > 0) {
    ret++;
    len >>= 8;
  }
  return ret;
}

int DSA_size(const DSA *dsa) {
  if (dsa->q == NULL) {
    return 0;
  }

  size_t order_len = BN_num_bytes(dsa->q);
  // Compute the maximum length of an |order_len| byte integer. Defensively
  // assume that the leading 0x00 is included.
  size_t integer_len = 1 /* tag */ + der_len_len(order_len + 1) + 1 + order_len;
  if (integer_len < order_len) {
    return 0;
  }
  // A DSA signature is two INTEGERs.
  size_t value_len = 2 * integer_len;
  if (value_len < integer_len) {
    return 0;
  }
  // Add the header.
  size_t ret = 1 /* tag */ + der_len_len(value_len) + value_len;
  if (ret < value_len) {
    return 0;
  }
  return ret;
}

static int dsa_sign_setup(const DSA *dsa, BN_CTX *ctx, BIGNUM **out_kinv,
                          BIGNUM **out_r) {
  int ret = 0;
  BIGNUM k;
  BN_init(&k);
  BIGNUM *r = BN_new();
  BIGNUM *kinv = BN_new();
  if (r == NULL || kinv == NULL ||
      // Get random k
      !BN_rand_range_ex(&k, 1, dsa->q) ||
      !BN_MONT_CTX_set_locked((BN_MONT_CTX **)&dsa->method_mont_p,
                              (CRYPTO_MUTEX *)&dsa->method_mont_lock, dsa->p,
                              ctx) ||
      !BN_MONT_CTX_set_locked((BN_MONT_CTX **)&dsa->method_mont_q,
                              (CRYPTO_MUTEX *)&dsa->method_mont_lock, dsa->q,
                              ctx) ||
      // Compute r = (g^k mod p) mod q
      !BN_mod_exp_mont_consttime(r, dsa->g, &k, dsa->p, ctx,
                                 dsa->method_mont_p)) {
    OPENSSL_PUT_ERROR(DSA, ERR_R_BN_LIB);
    goto err;
  }
  // Note |BN_mod| below is not constant-time and may leak information about
  // |r|. |dsa->p| may be significantly larger than |dsa->q|, so this is not
  // easily performed in constant-time with Montgomery reduction.
  //
  // However, |r| at this point is g^k (mod p). It is almost the value of |r|
  // revealed in the signature anyway (g^k (mod p) (mod q)), going from it to
  // |k| would require computing a discrete log.
  bn_declassify(r);
  if (!BN_mod(r, r, dsa->q, ctx) ||
      // Compute part of 's = inv(k) (m + xr) mod q' using Fermat's Little
      // Theorem.
      !bn_mod_inverse_prime(kinv, &k, dsa->q, ctx, dsa->method_mont_q)) {
    OPENSSL_PUT_ERROR(DSA, ERR_R_BN_LIB);
    goto err;
  }

  BN_clear_free(*out_kinv);
  *out_kinv = kinv;
  kinv = NULL;

  BN_clear_free(*out_r);
  *out_r = r;
  r = NULL;

  ret = 1;

err:
  BN_clear_free(&k);
  BN_clear_free(r);
  BN_clear_free(kinv);
  return ret;
}

int DSA_get_ex_new_index(long argl, void *argp, CRYPTO_EX_unused *unused,
                         CRYPTO_EX_dup *dup_unused, CRYPTO_EX_free *free_func) {
  return CRYPTO_get_ex_new_index_ex(&g_ex_data_class, argl, argp, free_func);
}

int DSA_set_ex_data(DSA *dsa, int idx, void *arg) {
  return CRYPTO_set_ex_data(&dsa->ex_data, idx, arg);
}

void *DSA_get_ex_data(const DSA *dsa, int idx) {
  return CRYPTO_get_ex_data(&dsa->ex_data, idx);
}

DH *DSA_dup_DH(const DSA *dsa) {
  if (dsa == nullptr) {
    return nullptr;
  }

  bssl::UniquePtr<DH> ret(DH_new());
  if (ret == nullptr) {
    return nullptr;
  }
  if (dsa->q != nullptr) {
    ret->priv_length = BN_num_bits(dsa->q);
    if ((ret->q = BN_dup(dsa->q)) == nullptr) {
      return nullptr;
    }
  }
  if ((dsa->p != nullptr && (ret->p = BN_dup(dsa->p)) == nullptr) ||
      (dsa->g != nullptr && (ret->g = BN_dup(dsa->g)) == nullptr) ||
      (dsa->pub_key != nullptr &&
       (ret->pub_key = BN_dup(dsa->pub_key)) == nullptr) ||
      (dsa->priv_key != nullptr &&
       (ret->priv_key = BN_dup(dsa->priv_key)) == nullptr)) {
    return nullptr;
  }

  return ret.release();
}
