/*
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#ifdef FREEBL_NO_DEPEND
#include "stubs.h"
#endif

#include "prerror.h"
#include "secerr.h"

#include "prtypes.h"
#include "prinit.h"
#include "blapi.h"
#include "nssilock.h"
#include "secitem.h"
#include "blapit.h"
#include "mpi.h"
#include "secmpi.h"
#include "pqg.h"

/*
 * FIPS 186-2 requires result from random output to be reduced mod q when
 * generating random numbers for DSA.
 *
 * Input: w, 2*qLen bytes
 *        q, qLen bytes
 * Output: xj, qLen bytes
 */
static SECStatus
fips186Change_ReduceModQForDSA(const PRUint8 *w, const PRUint8 *q,
                               unsigned int qLen, PRUint8 *xj)
{
    mp_int W, Q, Xj;
    mp_err err;
    SECStatus rv = SECSuccess;

    /* Initialize MPI integers. */
    MP_DIGITS(&W) = 0;
    MP_DIGITS(&Q) = 0;
    MP_DIGITS(&Xj) = 0;
    CHECK_MPI_OK(mp_init(&W));
    CHECK_MPI_OK(mp_init(&Q));
    CHECK_MPI_OK(mp_init(&Xj));
    /*
     * Convert input arguments into MPI integers.
     */
    CHECK_MPI_OK(mp_read_unsigned_octets(&W, w, 2 * qLen));
    CHECK_MPI_OK(mp_read_unsigned_octets(&Q, q, qLen));

    /*
     * Algorithm 1 of FIPS 186-2 Change Notice 1, Step 3.3
     *
     * xj = (w0 || w1) mod q
     */
    CHECK_MPI_OK(mp_mod(&W, &Q, &Xj));
    CHECK_MPI_OK(mp_to_fixlen_octets(&Xj, xj, qLen));
cleanup:
    mp_clear(&W);
    mp_clear(&Q);
    mp_clear(&Xj);
    if (err) {
        MP_TO_SEC_ERROR(err);
        rv = SECFailure;
    }
    return rv;
}

/*
 * FIPS 186-2 requires result from random output to be reduced mod q when
 * generating random numbers for DSA.
 */
SECStatus
FIPS186Change_ReduceModQForDSA(const unsigned char *w,
                               const unsigned char *q,
                               unsigned char *xj)
{
    return fips186Change_ReduceModQForDSA(w, q, DSA1_SUBPRIME_LEN, xj);
}

/*
 * The core of Algorithm 1 of FIPS 186-2 Change Notice 1.
 *
 * We no longer support FIPS 186-2 RNG. This function was exported
 * for power-up self tests and FIPS tests. Keep this stub, which fails,
 * to prevent crashes, but also to signal to test code that FIPS 186-2
 * RNG is no longer supported.
 */
SECStatus
FIPS186Change_GenerateX(PRUint8 *XKEY, const PRUint8 *XSEEDj,
                        PRUint8 *x_j)
{
    PORT_SetError(PR_NOT_IMPLEMENTED_ERROR);
    return SECFailure;
}

/*
 * Specialized RNG for DSA
 *
 * As per Algorithm 1 of FIPS 186-2 Change Notice 1, in step 3.3 the value
 * Xj should be reduced mod q, a 160-bit prime number.  Since this parameter
 * is only meaningful in the context of DSA, the above RNG functions
 * were implemented without it.  They are re-implemented below for use
 * with DSA.
 */

/*
** Generate some random bytes, using the global random number generator
** object.  In DSA mode, so there is a q.
*/
static SECStatus
dsa_GenerateGlobalRandomBytes(const SECItem *qItem, PRUint8 *dest,
                              unsigned int *destLen, unsigned int maxDestLen)
{
    SECStatus rv;
    SECItem w;
    const PRUint8 *q = qItem->data;
    unsigned int qLen = qItem->len;

    if (*q == 0) {
        ++q;
        --qLen;
    }
    if (maxDestLen < qLen) {
        /* This condition can occur when DSA_SignDigest is passed a group
           with a subprime that is larger than DSA_MAX_SUBPRIME_LEN. */
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }
    w.data = NULL; /* otherwise SECITEM_AllocItem asserts */
    if (!SECITEM_AllocItem(NULL, &w, 2 * qLen)) {
        return SECFailure;
    }
    *destLen = qLen;

    rv = RNG_GenerateGlobalRandomBytes(w.data, w.len);
    if (rv == SECSuccess) {
        rv = fips186Change_ReduceModQForDSA(w.data, q, qLen, dest);
    }

    SECITEM_FreeItem(&w, PR_FALSE);
    return rv;
}

static void
translate_mpi_error(mp_err err)
{
    MP_TO_SEC_ERROR(err);
}

static SECStatus
dsa_NewKeyExtended(const PQGParams *params, const SECItem *seed,
                   DSAPrivateKey **privKey)
{
    mp_int p, g;
    mp_int x, y;
    mp_err err;
    PLArenaPool *arena;
    DSAPrivateKey *key;
    /* Check args. */
    if (!params || !privKey || !seed || !seed->data) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }
    /* Initialize an arena for the DSA key. */
    arena = PORT_NewArena(NSS_FREEBL_DEFAULT_CHUNKSIZE);
    if (!arena) {
        PORT_SetError(SEC_ERROR_NO_MEMORY);
        return SECFailure;
    }
    key = (DSAPrivateKey *)PORT_ArenaZAlloc(arena, sizeof(DSAPrivateKey));
    if (!key) {
        PORT_SetError(SEC_ERROR_NO_MEMORY);
        PORT_FreeArena(arena, PR_TRUE);
        return SECFailure;
    }
    key->params.arena = arena;
    /* Initialize MPI integers. */
    MP_DIGITS(&p) = 0;
    MP_DIGITS(&g) = 0;
    MP_DIGITS(&x) = 0;
    MP_DIGITS(&y) = 0;
    CHECK_MPI_OK(mp_init(&p));
    CHECK_MPI_OK(mp_init(&g));
    CHECK_MPI_OK(mp_init(&x));
    CHECK_MPI_OK(mp_init(&y));
    /* Copy over the PQG params */
    CHECK_MPI_OK(SECITEM_CopyItem(arena, &key->params.prime,
                                  &params->prime));
    CHECK_MPI_OK(SECITEM_CopyItem(arena, &key->params.subPrime,
                                  &params->subPrime));
    CHECK_MPI_OK(SECITEM_CopyItem(arena, &key->params.base, &params->base));
    /* Convert stored p, g, and received x into MPI integers. */
    SECITEM_TO_MPINT(params->prime, &p);
    SECITEM_TO_MPINT(params->base, &g);
    OCTETS_TO_MPINT(seed->data, &x, seed->len);
    /* Store x in private key */
    SECITEM_AllocItem(arena, &key->privateValue, seed->len);
    PORT_Memcpy(key->privateValue.data, seed->data, seed->len);
    /* Compute public key y = g**x mod p */
    CHECK_MPI_OK(mp_exptmod(&g, &x, &p, &y));
    /* Store y in public key */
    MPINT_TO_SECITEM(&y, &key->publicValue, arena);
    *privKey = key;
    key = NULL;
cleanup:
    mp_clear(&p);
    mp_clear(&g);
    mp_clear(&x);
    mp_clear(&y);
    if (key) {
        PORT_FreeArena(key->params.arena, PR_TRUE);
    }
    if (err) {
        translate_mpi_error(err);
        return SECFailure;
    }
    return SECSuccess;
}

SECStatus
DSA_NewRandom(PLArenaPool *arena, const SECItem *q, SECItem *seed)
{
    int retries = 10;
    unsigned int i;
    PRBool good;

    if (q == NULL || q->data == NULL || q->len == 0 ||
        (q->data[0] == 0 && q->len == 1)) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }

    if (!SECITEM_AllocItem(arena, seed, q->len)) {
        return SECFailure;
    }

    do {
        /* Generate seed bytes for x according to FIPS 186-1 appendix 3 */
        if (dsa_GenerateGlobalRandomBytes(q, seed->data, &seed->len,
                                          seed->len)) {
            goto loser;
        }
        /* Disallow values of 0 and 1 for x. */
        good = PR_FALSE;
        for (i = 0; i < seed->len - 1; i++) {
            if (seed->data[i] != 0) {
                good = PR_TRUE;
                break;
            }
        }
        if (!good && seed->data[i] > 1) {
            good = PR_TRUE;
        }
    } while (!good && --retries > 0);

    if (!good) {
        PORT_SetError(SEC_ERROR_NEED_RANDOM);
    loser:
        if (arena != NULL) {
            SECITEM_ZfreeItem(seed, PR_FALSE);
        }
        return SECFailure;
    }

    return SECSuccess;
}

/*
** Generate and return a new DSA public and private key pair,
**  both of which are encoded into a single DSAPrivateKey struct.
**  "params" is a pointer to the PQG parameters for the domain
**  Uses a random seed.
*/
SECStatus
DSA_NewKey(const PQGParams *params, DSAPrivateKey **privKey)
{
    SECItem seed;
    SECStatus rv;

    rv = PQG_Check(params);
    if (rv != SECSuccess) {
        return rv;
    }
    seed.data = NULL;

    rv = DSA_NewRandom(NULL, &params->subPrime, &seed);
    if (rv == SECSuccess) {
        if (seed.len != PQG_GetLength(&params->subPrime)) {
            PORT_SetError(SEC_ERROR_INVALID_ARGS);
            rv = SECFailure;
        } else {
            rv = dsa_NewKeyExtended(params, &seed, privKey);
        }
    }
    SECITEM_ZfreeItem(&seed, PR_FALSE);
    return rv;
}

/* For FIPS compliance testing. Seed must be exactly the size of subPrime  */
SECStatus
DSA_NewKeyFromSeed(const PQGParams *params,
                   const unsigned char *seed,
                   DSAPrivateKey **privKey)
{
    SECItem seedItem;
    seedItem.data = (unsigned char *)seed;
    seedItem.len = PQG_GetLength(&params->subPrime);
    return dsa_NewKeyExtended(params, &seedItem, privKey);
}

static SECStatus
dsa_SignDigest(DSAPrivateKey *key, SECItem *signature, const SECItem *digest,
               const unsigned char *kbytes)
{
    mp_int p, q, g; /* PQG parameters */
    mp_int x, k;    /* private key & pseudo-random integer */
    mp_int r, s;    /* tuple (r, s) is signature) */
    mp_int t;       /* holding tmp values */
    mp_int ar;      /* holding blinding values */
    mp_digit fuzz;  /* blinding multiplier for q */
    mp_err err = MP_OKAY;
    SECStatus rv = SECSuccess;
    unsigned int dsa_subprime_len, dsa_signature_len, offset;
    SECItem localDigest;
    unsigned char localDigestData[DSA_MAX_SUBPRIME_LEN];
    SECItem t2 = { siBuffer, NULL, 0 };

    /* FIPS-compliance dictates that digest is a SHA hash. */
    /* Check args. */
    if (!key || !signature || !digest) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }

    dsa_subprime_len = PQG_GetLength(&key->params.subPrime);
    dsa_signature_len = dsa_subprime_len * 2;
    if ((signature->len < dsa_signature_len) ||
        (digest->len > HASH_LENGTH_MAX) ||
        (digest->len < SHA1_LENGTH)) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }

    /* DSA accepts digests not equal to dsa_subprime_len, if the
     * digests are greater, then they are truncated to the size of
     * dsa_subprime_len, using the left most bits. If they are less
     * then they are padded on the left.*/
    PORT_Memset(localDigestData, 0, dsa_subprime_len);
    offset = (digest->len < dsa_subprime_len) ? (dsa_subprime_len - digest->len) : 0;
    PORT_Memcpy(localDigestData + offset, digest->data,
                dsa_subprime_len - offset);
    localDigest.data = localDigestData;
    localDigest.len = dsa_subprime_len;

    /* Initialize MPI integers. */
    MP_DIGITS(&p) = 0;
    MP_DIGITS(&q) = 0;
    MP_DIGITS(&g) = 0;
    MP_DIGITS(&x) = 0;
    MP_DIGITS(&k) = 0;
    MP_DIGITS(&r) = 0;
    MP_DIGITS(&s) = 0;
    MP_DIGITS(&t) = 0;
    MP_DIGITS(&ar) = 0;
    CHECK_MPI_OK(mp_init(&p));
    CHECK_MPI_OK(mp_init(&q));
    CHECK_MPI_OK(mp_init(&g));
    CHECK_MPI_OK(mp_init(&x));
    CHECK_MPI_OK(mp_init(&k));
    CHECK_MPI_OK(mp_init(&r));
    CHECK_MPI_OK(mp_init(&s));
    CHECK_MPI_OK(mp_init(&t));
    CHECK_MPI_OK(mp_init(&ar));

    /*
    ** Convert stored PQG and private key into MPI integers.
    */
    SECITEM_TO_MPINT(key->params.prime, &p);
    SECITEM_TO_MPINT(key->params.subPrime, &q);
    SECITEM_TO_MPINT(key->params.base, &g);
    SECITEM_TO_MPINT(key->privateValue, &x);
    OCTETS_TO_MPINT(kbytes, &k, dsa_subprime_len);

    /* k blinding  create a single value that has the high bit set in
     * the mp_digit*/
    if (RNG_GenerateGlobalRandomBytes(&fuzz, sizeof(mp_digit)) != SECSuccess) {
        PORT_SetError(SEC_ERROR_NEED_RANDOM);
        rv = SECFailure;
        goto cleanup;
    }
    fuzz |= 1ULL << ((sizeof(mp_digit) * PR_BITS_PER_BYTE - 1));
    /*
    ** FIPS 186-1, Section 5, Step 1
    **
    ** r = (g**k mod p) mod q
    */
    CHECK_MPI_OK(mp_mul_d(&q, fuzz, &t)); /* t = q*fuzz */
    CHECK_MPI_OK(mp_add(&k, &t, &t));     /* t = k+q*fuzz */
    /* length of t is now fixed, bits in k have been blinded */
    CHECK_MPI_OK(mp_exptmod(&g, &t, &p, &r)); /* r = g**t mod p */
    /* r is now g**(k+q*fuzz) == g**k mod p */
    CHECK_MPI_OK(mp_mod(&r, &q, &r)); /* r = r mod q    */
    /* make sure fuzz is cleared off the stack and not optimized away */
    *(volatile mp_digit *)&fuzz = 0;

    /*
    ** FIPS 186-1, Section 5, Step 2
    **
    ** s = (k**-1 * (HASH(M) + x*r)) mod q
    */
    if (DSA_NewRandom(NULL, &key->params.subPrime, &t2) != SECSuccess) {
        PORT_SetError(SEC_ERROR_NEED_RANDOM);
        rv = SECFailure;
        goto cleanup;
    }
    SECITEM_TO_MPINT(t2, &t); /* t <-$ Zq */
    SECITEM_ZfreeItem(&t2, PR_FALSE);
    if (DSA_NewRandom(NULL, &key->params.subPrime, &t2) != SECSuccess) {
        PORT_SetError(SEC_ERROR_NEED_RANDOM);
        rv = SECFailure;
        goto cleanup;
    }
    SECITEM_TO_MPINT(t2, &ar); /* ar <-$ Zq */
    SECITEM_ZfreeItem(&t2, PR_FALSE);

    /* Using mp_invmod on k directly would leak bits from k. */
    CHECK_MPI_OK(mp_mul(&k, &ar, &k));       /* k = k * ar */
    CHECK_MPI_OK(mp_mulmod(&k, &t, &q, &k)); /* k = k * t mod q */
    /* k is now k*t*ar */
    CHECK_MPI_OK(mp_invmod(&k, &q, &k)); /* k = k**-1 mod q */
    /* k is now (k*t*ar)**-1 */
    CHECK_MPI_OK(mp_mulmod(&k, &t, &q, &k)); /* k = k * t mod q */
    /* k is now (k*ar)**-1 */
    SECITEM_TO_MPINT(localDigest, &s); /* s = HASH(M)     */
    /* To avoid leaking secret bits here the addition is blinded. */
    CHECK_MPI_OK(mp_mul(&x, &ar, &x)); /* x = x * ar */
    /* x is now x*ar */
    CHECK_MPI_OK(mp_mulmod(&x, &r, &q, &x)); /* x = x * r mod q */
    /* x is now x*r*ar */
    CHECK_MPI_OK(mp_mulmod(&s, &ar, &q, &t)); /* t = s * ar mod q */
    /* t is now hash(M)*ar */
    CHECK_MPI_OK(mp_add(&t, &x, &s)); /* s = t + x */
    /* s is now (HASH(M)+x*r)*ar */
    CHECK_MPI_OK(mp_mulmod(&s, &k, &q, &s)); /* s = s * k mod q */
    /* s is now (HASH(M)+x*r)*ar*(k*ar)**-1 = (k**-1)*(HASH(M)+x*r) */

    /*
    ** verify r != 0 and s != 0
    ** mentioned as optional in FIPS 186-1.
    */
    if (mp_cmp_z(&r) == 0 || mp_cmp_z(&s) == 0) {
        PORT_SetError(SEC_ERROR_NEED_RANDOM);
        rv = SECFailure;
        goto cleanup;
    }
    /*
    ** Step 4
    **
    ** Signature is tuple (r, s)
    */
    err = mp_to_fixlen_octets(&r, signature->data, dsa_subprime_len);
    if (err < 0)
        goto cleanup;
    err = mp_to_fixlen_octets(&s, signature->data + dsa_subprime_len,
                              dsa_subprime_len);
    if (err < 0)
        goto cleanup;
    err = MP_OKAY;
    signature->len = dsa_signature_len;
cleanup:
    PORT_Memset(localDigestData, 0, DSA_MAX_SUBPRIME_LEN);
    mp_clear(&p);
    mp_clear(&q);
    mp_clear(&g);
    mp_clear(&x);
    mp_clear(&k);
    mp_clear(&r);
    mp_clear(&s);
    mp_clear(&t);
    mp_clear(&ar);
    if (err) {
        translate_mpi_error(err);
        rv = SECFailure;
    }
    return rv;
}

/* signature is caller-supplied buffer of at least 40 bytes.
** On input,  signature->len == size of buffer to hold signature.
**            digest->len    == size of digest.
** On output, signature->len == size of signature in buffer.
** Uses a random seed.
*/
SECStatus
DSA_SignDigest(DSAPrivateKey *key, SECItem *signature, const SECItem *digest)
{
    SECStatus rv;
    int retries = 10;
    unsigned char kSeed[DSA_MAX_SUBPRIME_LEN];
    unsigned int kSeedLen = 0;
    unsigned int i;
    unsigned int dsa_subprime_len = PQG_GetLength(&key->params.subPrime);
    PRBool good;

    PORT_SetError(0);
    do {
        rv = dsa_GenerateGlobalRandomBytes(&key->params.subPrime,
                                           kSeed, &kSeedLen, sizeof kSeed);
        if (rv != SECSuccess)
            break;
        if (kSeedLen != dsa_subprime_len) {
            PORT_SetError(SEC_ERROR_INVALID_ARGS);
            rv = SECFailure;
            break;
        }
        /* Disallow a value of 0 for k. */
        good = PR_FALSE;
        for (i = 0; i < kSeedLen; i++) {
            if (kSeed[i] != 0) {
                good = PR_TRUE;
                break;
            }
        }
        if (!good) {
            PORT_SetError(SEC_ERROR_NEED_RANDOM);
            rv = SECFailure;
            continue;
        }
        rv = dsa_SignDigest(key, signature, digest, kSeed);
    } while (rv != SECSuccess && PORT_GetError() == SEC_ERROR_NEED_RANDOM &&
             --retries > 0);
    PORT_Memset(kSeed, 0, sizeof kSeed);
    return rv;
}

/* For FIPS compliance testing. Seed must be exactly 20 bytes. */
SECStatus
DSA_SignDigestWithSeed(DSAPrivateKey *key,
                       SECItem *signature,
                       const SECItem *digest,
                       const unsigned char *seed)
{
    SECStatus rv;
    rv = dsa_SignDigest(key, signature, digest, seed);
    return rv;
}

/* signature is caller-supplied buffer of at least 20 bytes.
** On input,  signature->len == size of buffer to hold signature.
**            digest->len    == size of digest.
*/
SECStatus
DSA_VerifyDigest(DSAPublicKey *key, const SECItem *signature,
                 const SECItem *digest)
{
    /* FIPS-compliance dictates that digest is a SHA hash. */
    mp_int p, q, g;      /* PQG parameters */
    mp_int r_, s_;       /* tuple (r', s') is received signature) */
    mp_int u1, u2, v, w; /* intermediate values used in verification */
    mp_int y;            /* public key */
    mp_err err;
    unsigned int dsa_subprime_len, dsa_signature_len, offset;
    SECItem localDigest;
    unsigned char localDigestData[DSA_MAX_SUBPRIME_LEN];
    SECStatus verified = SECFailure;

    /* Check args. */
    if (!key || !signature || !digest) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }

    dsa_subprime_len = PQG_GetLength(&key->params.subPrime);
    dsa_signature_len = dsa_subprime_len * 2;
    if ((signature->len != dsa_signature_len) ||
        (digest->len > HASH_LENGTH_MAX) ||
        (digest->len < SHA1_LENGTH)) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }

    /* DSA accepts digests not equal to dsa_subprime_len, if the
     * digests are greater, than they are truncated to the size of
     * dsa_subprime_len, using the left most bits. If they are less
     * then they are padded on the left.*/
    PORT_Memset(localDigestData, 0, dsa_subprime_len);
    offset = (digest->len < dsa_subprime_len) ? (dsa_subprime_len - digest->len) : 0;
    PORT_Memcpy(localDigestData + offset, digest->data,
                dsa_subprime_len - offset);
    localDigest.data = localDigestData;
    localDigest.len = dsa_subprime_len;

    /* Initialize MPI integers. */
    MP_DIGITS(&p) = 0;
    MP_DIGITS(&q) = 0;
    MP_DIGITS(&g) = 0;
    MP_DIGITS(&y) = 0;
    MP_DIGITS(&r_) = 0;
    MP_DIGITS(&s_) = 0;
    MP_DIGITS(&u1) = 0;
    MP_DIGITS(&u2) = 0;
    MP_DIGITS(&v) = 0;
    MP_DIGITS(&w) = 0;
    CHECK_MPI_OK(mp_init(&p));
    CHECK_MPI_OK(mp_init(&q));
    CHECK_MPI_OK(mp_init(&g));
    CHECK_MPI_OK(mp_init(&y));
    CHECK_MPI_OK(mp_init(&r_));
    CHECK_MPI_OK(mp_init(&s_));
    CHECK_MPI_OK(mp_init(&u1));
    CHECK_MPI_OK(mp_init(&u2));
    CHECK_MPI_OK(mp_init(&v));
    CHECK_MPI_OK(mp_init(&w));
    /*
    ** Convert stored PQG and public key into MPI integers.
    */
    SECITEM_TO_MPINT(key->params.prime, &p);
    SECITEM_TO_MPINT(key->params.subPrime, &q);
    SECITEM_TO_MPINT(key->params.base, &g);
    SECITEM_TO_MPINT(key->publicValue, &y);
    /*
    ** Convert received signature (r', s') into MPI integers.
    */
    OCTETS_TO_MPINT(signature->data, &r_, dsa_subprime_len);
    OCTETS_TO_MPINT(signature->data + dsa_subprime_len, &s_, dsa_subprime_len);
    /*
    ** Verify that 0 < r' < q and 0 < s' < q
    */
    if (mp_cmp_z(&r_) <= 0 || mp_cmp_z(&s_) <= 0 ||
        mp_cmp(&r_, &q) >= 0 || mp_cmp(&s_, &q) >= 0) {
        /* err is zero here. */
        PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
        goto cleanup; /* will return verified == SECFailure */
    }
    /*
    ** FIPS 186-1, Section 6, Step 1
    **
    ** w = (s')**-1 mod q
    */
    CHECK_MPI_OK(mp_invmod(&s_, &q, &w)); /* w = (s')**-1 mod q */
    /*
    ** FIPS 186-1, Section 6, Step 2
    **
    ** u1 = ((Hash(M')) * w) mod q
    */
    SECITEM_TO_MPINT(localDigest, &u1);        /* u1 = HASH(M')     */
    CHECK_MPI_OK(mp_mulmod(&u1, &w, &q, &u1)); /* u1 = u1 * w mod q */
    /*
    ** FIPS 186-1, Section 6, Step 3
    **
    ** u2 = ((r') * w) mod q
    */
    CHECK_MPI_OK(mp_mulmod(&r_, &w, &q, &u2));
    /*
    ** FIPS 186-1, Section 6, Step 4
    **
    ** v = ((g**u1 * y**u2) mod p) mod q
    */
    CHECK_MPI_OK(mp_exptmod(&g, &u1, &p, &g)); /* g = g**u1 mod p */
    CHECK_MPI_OK(mp_exptmod(&y, &u2, &p, &y)); /* y = y**u2 mod p */
    CHECK_MPI_OK(mp_mulmod(&g, &y, &p, &v));   /* v = g * y mod p */
    CHECK_MPI_OK(mp_mod(&v, &q, &v));          /* v = v mod q     */
    /*
    ** Verification:  v == r'
    */
    if (mp_cmp(&v, &r_)) {
        PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
        verified = SECFailure; /* Signature failed to verify. */
    } else {
        verified = SECSuccess; /* Signature verified. */
    }
cleanup:
    PORT_Memset(localDigestData, 0, sizeof localDigestData);
    mp_clear(&p);
    mp_clear(&q);
    mp_clear(&g);
    mp_clear(&y);
    mp_clear(&r_);
    mp_clear(&s_);
    mp_clear(&u1);
    mp_clear(&u2);
    mp_clear(&v);
    mp_clear(&w);
    if (err) {
        translate_mpi_error(err);
    }
    return verified;
}
