/*
 * Copyright (c) 2007, 2019, Oracle and/or its affiliates. All rights reserved.
 * Use is subject to license terms.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this library; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

/* *********************************************************************
 *
 * The Original Code is the Elliptic Curve Cryptography library.
 *
 * The Initial Developer of the Original Code is
 * Sun Microsystems, Inc.
 * Portions created by the Initial Developer are Copyright (C) 2003
 * the Initial Developer. All Rights Reserved.
 *
 * Contributor(s):
 *   Dr Vipul Gupta <vipul.gupta@sun.com> and
 *   Douglas Stebila <douglas@stebila.ca>, Sun Microsystems Laboratories
 *
 * Last Modified Date from the Original Code: May 2017
 *********************************************************************** */

#include "mplogic.h"
#include "ec.h"
#include "ecl.h"

#include <sys/types.h>
#ifndef _KERNEL
#include <stdlib.h>
#include <string.h>

#ifndef _WIN32
#include <stdio.h>
#include <strings.h>
#endif /* _WIN32 */

#endif
#include "ecl-exp.h"
#include "mpi.h"
#include "ecc_impl.h"

#ifdef _KERNEL
#define PORT_ZFree(p, l)                bzero((p), (l)); kmem_free((p), (l))
#else
#ifndef _WIN32
#define PORT_ZFree(p, l)                bzero((p), (l)); free((p))
#else
#define PORT_ZFree(p, l)                memset((p), 0, (l)); free((p))
#endif /* _WIN32 */
#endif

/*
 * Returns true if pointP is the point at infinity, false otherwise
 */
PRBool
ec_point_at_infinity(SECItem *pointP)
{
    unsigned int i;

    for (i = 1; i < pointP->len; i++) {
        if (pointP->data[i] != 0x00) return PR_FALSE;
    }

    return PR_TRUE;
}

/*
 * Computes scalar point multiplication pointQ = k1 * G + k2 * pointP for
 * the curve whose parameters are encoded in params with base point G.
 */
SECStatus
ec_points_mul(const ECParams *params, const mp_int *k1, const mp_int *k2,
             const SECItem *pointP, SECItem *pointQ, int kmflag, int timing)
{
    mp_int Px, Py, Qx, Qy;
    mp_int Gx, Gy, order, irreducible, a, b;
#if 0 /* currently don't support non-named curves */
    unsigned int irr_arr[5];
#endif
    ECGroup *group = NULL;
    SECStatus rv = SECFailure;
    mp_err err = MP_OKAY;
    unsigned int len;

#if EC_DEBUG
    int i;
    char mpstr[256];

    printf("ec_points_mul: params [len=%d]:", params->DEREncoding.len);
    for (i = 0; i < params->DEREncoding.len; i++)
            printf("%02x:", params->DEREncoding.data[i]);
    printf("\n");

        if (k1 != NULL) {
                mp_tohex(k1, mpstr);
                printf("ec_points_mul: scalar k1: %s\n", mpstr);
                mp_todecimal(k1, mpstr);
                printf("ec_points_mul: scalar k1: %s (dec)\n", mpstr);
        }

        if (k2 != NULL) {
                mp_tohex(k2, mpstr);
                printf("ec_points_mul: scalar k2: %s\n", mpstr);
                mp_todecimal(k2, mpstr);
                printf("ec_points_mul: scalar k2: %s (dec)\n", mpstr);
        }

        if (pointP != NULL) {
                printf("ec_points_mul: pointP [len=%d]:", pointP->len);
                for (i = 0; i < pointP->len; i++)
                        printf("%02x:", pointP->data[i]);
                printf("\n");
        }
#endif

        /* NOTE: We only support uncompressed points for now */
        len = (params->fieldID.size + 7) >> 3;
        if (pointP != NULL) {
                if ((pointP->data[0] != EC_POINT_FORM_UNCOMPRESSED) ||
                        (pointP->len != (2 * len + 1))) {
                        return SECFailure;
                };
        }

        MP_DIGITS(&Px) = 0;
        MP_DIGITS(&Py) = 0;
        MP_DIGITS(&Qx) = 0;
        MP_DIGITS(&Qy) = 0;
        MP_DIGITS(&Gx) = 0;
        MP_DIGITS(&Gy) = 0;
        MP_DIGITS(&order) = 0;
        MP_DIGITS(&irreducible) = 0;
        MP_DIGITS(&a) = 0;
        MP_DIGITS(&b) = 0;
        CHECK_MPI_OK( mp_init(&Px, kmflag) );
        CHECK_MPI_OK( mp_init(&Py, kmflag) );
        CHECK_MPI_OK( mp_init(&Qx, kmflag) );
        CHECK_MPI_OK( mp_init(&Qy, kmflag) );
        CHECK_MPI_OK( mp_init(&Gx, kmflag) );
        CHECK_MPI_OK( mp_init(&Gy, kmflag) );
        CHECK_MPI_OK( mp_init(&order, kmflag) );
        CHECK_MPI_OK( mp_init(&irreducible, kmflag) );
        CHECK_MPI_OK( mp_init(&a, kmflag) );
        CHECK_MPI_OK( mp_init(&b, kmflag) );

        if ((k2 != NULL) && (pointP != NULL)) {
                /* Initialize Px and Py */
                CHECK_MPI_OK( mp_read_unsigned_octets(&Px, pointP->data + 1, (mp_size) len) );
                CHECK_MPI_OK( mp_read_unsigned_octets(&Py, pointP->data + 1 + len, (mp_size) len) );
        }

        /* construct from named params, if possible */
        if (params->name != ECCurve_noName) {
                group = ECGroup_fromName(params->name, kmflag);
        }

#if 0 /* currently don't support non-named curves */
        if (group == NULL) {
                /* Set up mp_ints containing the curve coefficients */
                CHECK_MPI_OK( mp_read_unsigned_octets(&Gx, params->base.data + 1,
                                                                                  (mp_size) len) );
                CHECK_MPI_OK( mp_read_unsigned_octets(&Gy, params->base.data + 1 + len,
                                                                                  (mp_size) len) );
                SECITEM_TO_MPINT( params->order, &order );
                SECITEM_TO_MPINT( params->curve.a, &a );
                SECITEM_TO_MPINT( params->curve.b, &b );
                if (params->fieldID.type == ec_field_GFp) {
                        SECITEM_TO_MPINT( params->fieldID.u.prime, &irreducible );
                        group = ECGroup_consGFp(&irreducible, &a, &b, &Gx, &Gy, &order, params->cofactor);
                } else {
                        SECITEM_TO_MPINT( params->fieldID.u.poly, &irreducible );
                        irr_arr[0] = params->fieldID.size;
                        irr_arr[1] = params->fieldID.k1;
                        irr_arr[2] = params->fieldID.k2;
                        irr_arr[3] = params->fieldID.k3;
                        irr_arr[4] = 0;
                        group = ECGroup_consGF2m(&irreducible, irr_arr, &a, &b, &Gx, &Gy, &order, params->cofactor);
                }
        }
#endif
        if (group == NULL)
                goto cleanup;

        if ((k2 != NULL) && (pointP != NULL)) {
                CHECK_MPI_OK( ECPoints_mul(group, k1, k2, &Px, &Py, &Qx, &Qy, timing) );
        } else {
                CHECK_MPI_OK( ECPoints_mul(group, k1, NULL, NULL, NULL, &Qx, &Qy, timing) );
    }

    /* Construct the SECItem representation of point Q */
    pointQ->data[0] = EC_POINT_FORM_UNCOMPRESSED;
    CHECK_MPI_OK( mp_to_fixlen_octets(&Qx, pointQ->data + 1,
                                      (mp_size) len) );
    CHECK_MPI_OK( mp_to_fixlen_octets(&Qy, pointQ->data + 1 + len,
                                      (mp_size) len) );

    rv = SECSuccess;

#if EC_DEBUG
    printf("ec_points_mul: pointQ [len=%d]:", pointQ->len);
    for (i = 0; i < pointQ->len; i++)
            printf("%02x:", pointQ->data[i]);
    printf("\n");
#endif

cleanup:
    ECGroup_free(group);
    mp_clear(&Px);
    mp_clear(&Py);
    mp_clear(&Qx);
    mp_clear(&Qy);
    mp_clear(&Gx);
    mp_clear(&Gy);
    mp_clear(&order);
    mp_clear(&irreducible);
    mp_clear(&a);
    mp_clear(&b);
    if (err) {
        MP_TO_SEC_ERROR(err);
        rv = SECFailure;
    }

    return rv;
}

/* Generates a new EC key pair. The private key is a supplied
 * value and the public key is the result of performing a scalar
 * point multiplication of that value with the curve's base point.
 */
SECStatus
ec_NewKey(ECParams *ecParams, ECPrivateKey **privKey,
    const unsigned char *privKeyBytes, int privKeyLen, int kmflag)
{
    SECStatus rv = SECFailure;
    PRArenaPool *arena;
    ECPrivateKey *key;
    mp_int k;
    mp_err err = MP_OKAY;
    int len;

#if EC_DEBUG
    printf("ec_NewKey called\n");
#endif
    k.dp = (mp_digit*)NULL;

    if (!ecParams || !privKey || !privKeyBytes || (privKeyLen < 0)) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }

    /* Initialize an arena for the EC key. */
    if (!(arena = PORT_NewArena(NSS_FREEBL_DEFAULT_CHUNKSIZE)))
        return SECFailure;

    key = (ECPrivateKey *)PORT_ArenaZAlloc(arena, sizeof(ECPrivateKey),
        kmflag);
    if (!key) {
        PORT_FreeArena(arena, PR_TRUE);
        return SECFailure;
    }

    /* Set the version number (SEC 1 section C.4 says it should be 1) */
    SECITEM_AllocItem(arena, &key->version, 1, kmflag);
    key->version.data[0] = 1;

    /* Copy all of the fields from the ECParams argument to the
     * ECParams structure within the private key.
     */
    key->ecParams.arena = arena;
    key->ecParams.type = ecParams->type;
    key->ecParams.fieldID.size = ecParams->fieldID.size;
    key->ecParams.fieldID.type = ecParams->fieldID.type;
    if (ecParams->fieldID.type == ec_field_GFp) {
        CHECK_SEC_OK(SECITEM_CopyItem(arena, &key->ecParams.fieldID.u.prime,
            &ecParams->fieldID.u.prime, kmflag));
    } else {
        CHECK_SEC_OK(SECITEM_CopyItem(arena, &key->ecParams.fieldID.u.poly,
            &ecParams->fieldID.u.poly, kmflag));
    }
    key->ecParams.fieldID.k1 = ecParams->fieldID.k1;
    key->ecParams.fieldID.k2 = ecParams->fieldID.k2;
    key->ecParams.fieldID.k3 = ecParams->fieldID.k3;
    CHECK_SEC_OK(SECITEM_CopyItem(arena, &key->ecParams.curve.a,
        &ecParams->curve.a, kmflag));
    CHECK_SEC_OK(SECITEM_CopyItem(arena, &key->ecParams.curve.b,
        &ecParams->curve.b, kmflag));
    CHECK_SEC_OK(SECITEM_CopyItem(arena, &key->ecParams.curve.seed,
        &ecParams->curve.seed, kmflag));
    CHECK_SEC_OK(SECITEM_CopyItem(arena, &key->ecParams.base,
        &ecParams->base, kmflag));
    CHECK_SEC_OK(SECITEM_CopyItem(arena, &key->ecParams.order,
        &ecParams->order, kmflag));
    key->ecParams.cofactor = ecParams->cofactor;
    CHECK_SEC_OK(SECITEM_CopyItem(arena, &key->ecParams.DEREncoding,
        &ecParams->DEREncoding, kmflag));
    key->ecParams.name = ecParams->name;
    CHECK_SEC_OK(SECITEM_CopyItem(arena, &key->ecParams.curveOID,
        &ecParams->curveOID, kmflag));

    len = (ecParams->fieldID.size + 7) >> 3;
    SECITEM_AllocItem(arena, &key->publicValue, 2*len + 1, kmflag);
    len = ecParams->order.len;
    SECITEM_AllocItem(arena, &key->privateValue, len, kmflag);

    /* Copy private key */
    if (privKeyLen >= len) {
        memcpy(key->privateValue.data, privKeyBytes, len);
    } else {
        memset(key->privateValue.data, 0, (len - privKeyLen));
        memcpy(key->privateValue.data + (len - privKeyLen), privKeyBytes, privKeyLen);
    }

    /* Compute corresponding public key */
    MP_DIGITS(&k) = 0;
    CHECK_MPI_OK( mp_init(&k, kmflag) );
    CHECK_MPI_OK( mp_read_unsigned_octets(&k, key->privateValue.data,
        (mp_size) len) );

    /* key generation does not support timing mitigation */
    rv = ec_points_mul(ecParams, &k, NULL, NULL, &(key->publicValue), kmflag, /*timing*/ 0);
    if (rv != SECSuccess) goto cleanup;
    *privKey = key;

cleanup:
    mp_clear(&k);
    if (rv) {
        PORT_FreeArena(arena, PR_TRUE);
    }

#if EC_DEBUG
    printf("ec_NewKey returning %s\n",
        (rv == SECSuccess) ? "success" : "failure");
#endif

    return rv;

}

/* Generates a new EC key pair. The private key is a supplied
 * random value (in seed) and the public key is the result of
 * performing a scalar point multiplication of that value with
 * the curve's base point.
 */
SECStatus
EC_NewKeyFromSeed(ECParams *ecParams, ECPrivateKey **privKey,
    const unsigned char *seed, int seedlen, int kmflag)
{
    SECStatus rv = SECFailure;
    rv = ec_NewKey(ecParams, privKey, seed, seedlen, kmflag);
    return rv;
}

/* Generate a random private key using the algorithm A.4.1 of ANSI X9.62,
 * modified a la FIPS 186-2 Change Notice 1 to eliminate the bias in the
 * random number generator.
 *
 * Parameters
 * - order: a buffer that holds the curve's group order
 * - len: the length in octets of the order buffer
 * - random: a buffer of 2 * len random bytes
 * - randomlen: the length in octets of the random buffer
 *
 * Return Value
 * Returns a buffer of len octets that holds the private key. The caller
 * is responsible for freeing the buffer with PORT_ZFree.
 */
static unsigned char *
ec_GenerateRandomPrivateKey(const unsigned char *order, int len,
    const unsigned char *random, int randomlen, int kmflag)
{
    SECStatus rv = SECSuccess;
    mp_err err;
    unsigned char *privKeyBytes = NULL;
    mp_int privKeyVal, order_1, one;

    MP_DIGITS(&privKeyVal) = 0;
    MP_DIGITS(&order_1) = 0;
    MP_DIGITS(&one) = 0;
    CHECK_MPI_OK( mp_init(&privKeyVal, kmflag) );
    CHECK_MPI_OK( mp_init(&order_1, kmflag) );
    CHECK_MPI_OK( mp_init(&one, kmflag) );

    /*
     * Reduces the 2*len buffer of random bytes modulo the group order.
     */
    if ((privKeyBytes = PORT_Alloc(2*len, kmflag)) == NULL) goto cleanup;
    if (randomlen != 2 * len) {
        randomlen = 2 * len;
    }
    /* No need to generate - random bytes are now supplied */
    /* CHECK_SEC_OK( RNG_GenerateGlobalRandomBytes(privKeyBytes, 2*len) );*/
    memcpy(privKeyBytes, random, randomlen);

    CHECK_MPI_OK( mp_read_unsigned_octets(&privKeyVal, privKeyBytes, 2*len) );
    CHECK_MPI_OK( mp_read_unsigned_octets(&order_1, order, len) );
    CHECK_MPI_OK( mp_set_int(&one, 1) );
    CHECK_MPI_OK( mp_sub(&order_1, &one, &order_1) );
    CHECK_MPI_OK( mp_mod(&privKeyVal, &order_1, &privKeyVal) );
    CHECK_MPI_OK( mp_add(&privKeyVal, &one, &privKeyVal) );
    CHECK_MPI_OK( mp_to_fixlen_octets(&privKeyVal, privKeyBytes, len) );
    memset(privKeyBytes+len, 0, len);
cleanup:
    mp_clear(&privKeyVal);
    mp_clear(&order_1);
    mp_clear(&one);
    if (err < MP_OKAY) {
        MP_TO_SEC_ERROR(err);
        rv = SECFailure;
    }
    if (rv != SECSuccess && privKeyBytes) {
#ifdef _KERNEL
        kmem_free(privKeyBytes, 2*len);
#else
        free(privKeyBytes);
#endif
        privKeyBytes = NULL;
    }
    return privKeyBytes;
}

/* Generates a new EC key pair. The private key is a random value and
 * the public key is the result of performing a scalar point multiplication
 * of that value with the curve's base point.
 */
SECStatus
EC_NewKey(ECParams *ecParams, ECPrivateKey **privKey,
    const unsigned char* random, int randomlen, int kmflag)
{
    SECStatus rv = SECFailure;
    int len;
    unsigned char *privKeyBytes = NULL;

    if (!ecParams) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }

    len = ecParams->order.len;
    privKeyBytes = ec_GenerateRandomPrivateKey(ecParams->order.data, len,
        random, randomlen, kmflag);
    if (privKeyBytes == NULL) goto cleanup;
    /* generate public key */
    CHECK_SEC_OK( ec_NewKey(ecParams, privKey, privKeyBytes, len, kmflag) );

cleanup:
    if (privKeyBytes) {
        PORT_ZFree(privKeyBytes, len * 2);
    }
#if EC_DEBUG
    printf("EC_NewKey returning %s\n",
        (rv == SECSuccess) ? "success" : "failure");
#endif

    return rv;
}

/* Validates an EC public key as described in Section 5.2.2 of
 * X9.62. The ECDH primitive when used without the cofactor does
 * not address small subgroup attacks, which may occur when the
 * public key is not valid. These attacks can be prevented by
 * validating the public key before using ECDH.
 */
SECStatus
EC_ValidatePublicKey(ECParams *ecParams, SECItem *publicValue, int kmflag)
{
    mp_int Px, Py;
    ECGroup *group = NULL;
    SECStatus rv = SECFailure;
    mp_err err = MP_OKAY;
    unsigned int len;

    if (!ecParams || !publicValue) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }

    /* NOTE: We only support uncompressed points for now */
    len = (ecParams->fieldID.size + 7) >> 3;
    if (publicValue->data[0] != EC_POINT_FORM_UNCOMPRESSED) {
        PORT_SetError(SEC_ERROR_UNSUPPORTED_EC_POINT_FORM);
        return SECFailure;
    } else if (publicValue->len != (2 * len + 1)) {
        PORT_SetError(SEC_ERROR_BAD_KEY);
        return SECFailure;
    }

    MP_DIGITS(&Px) = 0;
    MP_DIGITS(&Py) = 0;
    CHECK_MPI_OK( mp_init(&Px, kmflag) );
    CHECK_MPI_OK( mp_init(&Py, kmflag) );

    /* Initialize Px and Py */
    CHECK_MPI_OK( mp_read_unsigned_octets(&Px, publicValue->data + 1, (mp_size) len) );
    CHECK_MPI_OK( mp_read_unsigned_octets(&Py, publicValue->data + 1 + len, (mp_size) len) );

    /* construct from named params */
    group = ECGroup_fromName(ecParams->name, kmflag);
    if (group == NULL) {
        /*
         * ECGroup_fromName fails if ecParams->name is not a valid
         * ECCurveName value, or if we run out of memory, or perhaps
         * for other reasons.  Unfortunately if ecParams->name is a
         * valid ECCurveName value, we don't know what the right error
         * code should be because ECGroup_fromName doesn't return an
         * error code to the caller.  Set err to MP_UNDEF because
         * that's what ECGroup_fromName uses internally.
         */
        if ((ecParams->name <= ECCurve_noName) ||
            (ecParams->name >= ECCurve_pastLastCurve)) {
            err = MP_BADARG;
        } else {
            err = MP_UNDEF;
        }
        goto cleanup;
    }

    /* validate public point */
    if ((err = ECPoint_validate(group, &Px, &Py)) < MP_YES) {
        if (err == MP_NO) {
            PORT_SetError(SEC_ERROR_BAD_KEY);
            rv = SECFailure;
            err = MP_OKAY;  /* don't change the error code */
        }
        goto cleanup;
    }

    rv = SECSuccess;

cleanup:
    ECGroup_free(group);
    mp_clear(&Px);
    mp_clear(&Py);
    if (err) {
        MP_TO_SEC_ERROR(err);
        rv = SECFailure;
    }
    return rv;
}

/*
** Performs an ECDH key derivation by computing the scalar point
** multiplication of privateValue and publicValue (with or without the
** cofactor) and returns the x-coordinate of the resulting elliptic
** curve point in derived secret.  If successful, derivedSecret->data
** is set to the address of the newly allocated buffer containing the
** derived secret, and derivedSecret->len is the size of the secret
** produced. It is the caller's responsibility to free the allocated
** buffer containing the derived secret.
*/
SECStatus
ECDH_Derive(SECItem  *publicValue,
            ECParams *ecParams,
            SECItem  *privateValue,
            PRBool    withCofactor,
            SECItem  *derivedSecret,
            int kmflag)
{
    SECStatus rv = SECFailure;
    unsigned int len = 0;
    SECItem pointQ = {siBuffer, NULL, 0};
    mp_int k; /* to hold the private value */
    mp_int cofactor;
    mp_err err = MP_OKAY;
#if EC_DEBUG
    int i;
#endif

    if (!publicValue || !ecParams || !privateValue ||
        !derivedSecret) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }

    if (EC_ValidatePublicKey(ecParams, publicValue, kmflag) != SECSuccess) {
        return SECFailure;
    }

    memset(derivedSecret, 0, sizeof *derivedSecret);
    len = (ecParams->fieldID.size + 7) >> 3;
    pointQ.len = 2*len + 1;
    if ((pointQ.data = PORT_Alloc(2*len + 1, kmflag)) == NULL) goto cleanup;

    MP_DIGITS(&k) = 0;
    CHECK_MPI_OK( mp_init(&k, kmflag) );
    CHECK_MPI_OK( mp_read_unsigned_octets(&k, privateValue->data,
                                          (mp_size) privateValue->len) );

    if (withCofactor && (ecParams->cofactor != 1)) {
            /* multiply k with the cofactor */
            MP_DIGITS(&cofactor) = 0;
            CHECK_MPI_OK( mp_init(&cofactor, kmflag) );
            mp_set(&cofactor, ecParams->cofactor);
            CHECK_MPI_OK( mp_mul(&k, &cofactor, &k) );
    }

    /* Multiply our private key and peer's public point */
    /* ECDH doesn't support timing mitigation */
    if ((ec_points_mul(ecParams, NULL, &k, publicValue, &pointQ, kmflag, /*timing*/ 0) != SECSuccess) ||
        ec_point_at_infinity(&pointQ))
        goto cleanup;

    /* Allocate memory for the derived secret and copy
     * the x co-ordinate of pointQ into it.
     */
    SECITEM_AllocItem(NULL, derivedSecret, len, kmflag);
    memcpy(derivedSecret->data, pointQ.data + 1, len);

    rv = SECSuccess;

#if EC_DEBUG
    printf("derived_secret:\n");
    for (i = 0; i < derivedSecret->len; i++)
        printf("%02x:", derivedSecret->data[i]);
    printf("\n");
#endif

cleanup:
    mp_clear(&k);

    if (pointQ.data) {
        PORT_ZFree(pointQ.data, 2*len + 1);
    }

    return rv;
}

/* Computes the ECDSA signature (a concatenation of two values r and s)
 * on the digest using the given key and the random value kb (used in
 * computing s).
 */
SECStatus
ECDSA_SignDigestWithSeed(ECPrivateKey *key, SECItem *signature,
    const SECItem *digest, const unsigned char *kb, const int kblen, int kmflag,
    int timing)
{
    SECStatus rv = SECFailure;
    mp_int x1;
    mp_int d, k;     /* private key, random integer */
    mp_int r, s;     /* tuple (r, s) is the signature */
    mp_int n;
    mp_err err = MP_OKAY;
    ECParams *ecParams = NULL;
    SECItem kGpoint = { siBuffer, NULL, 0};
    int flen = 0;    /* length in bytes of the field size */
    unsigned olen;   /* length in bytes of the base point order */
    unsigned int orderBitSize;

#if EC_DEBUG
    char mpstr[256];
#endif

    /* Initialize MPI integers. */
    /* must happen before the first potential call to cleanup */
    MP_DIGITS(&x1) = 0;
    MP_DIGITS(&d) = 0;
    MP_DIGITS(&k) = 0;
    MP_DIGITS(&r) = 0;
    MP_DIGITS(&s) = 0;
    MP_DIGITS(&n) = 0;

    /* Check args */
    if (!key || !signature || !digest || !kb || (kblen < 0)) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        goto cleanup;
    }

    ecParams = &(key->ecParams);
    flen = (ecParams->fieldID.size + 7) >> 3;
    olen = ecParams->order.len;
    if (signature->data == NULL) {
        /* a call to get the signature length only */
        goto finish;
    }
    if (signature->len < 2*olen) {
        PORT_SetError(SEC_ERROR_OUTPUT_LEN);
        rv = SECBufferTooSmall;
        goto cleanup;
    }


    CHECK_MPI_OK( mp_init(&x1, kmflag) );
    CHECK_MPI_OK( mp_init(&d, kmflag) );
    CHECK_MPI_OK( mp_init(&k, kmflag) );
    CHECK_MPI_OK( mp_init(&r, kmflag) );
    CHECK_MPI_OK( mp_init(&s, kmflag) );
    CHECK_MPI_OK( mp_init(&n, kmflag) );

    SECITEM_TO_MPINT( ecParams->order, &n );
    SECITEM_TO_MPINT( key->privateValue, &d );
    CHECK_MPI_OK( mp_read_unsigned_octets(&k, kb, kblen) );
    /* Make sure k is in the interval [1, n-1] */
    if ((mp_cmp_z(&k) <= 0) || (mp_cmp(&k, &n) >= 0)) {
#if EC_DEBUG
        printf("k is outside [1, n-1]\n");
        mp_tohex(&k, mpstr);
        printf("k : %s \n", mpstr);
        mp_tohex(&n, mpstr);
        printf("n : %s \n", mpstr);
#endif
        PORT_SetError(SEC_ERROR_NEED_RANDOM);
        goto cleanup;
    }

    /*
    ** ANSI X9.62, Section 5.3.2, Step 2
    **
    ** Compute kG
    */
    kGpoint.len = 2*flen + 1;
    kGpoint.data = PORT_Alloc(2*flen + 1, kmflag);
    if ((kGpoint.data == NULL) ||
        (ec_points_mul(ecParams, &k, NULL, NULL, &kGpoint, kmflag, timing)
            != SECSuccess))
        goto cleanup;

    /*
    ** ANSI X9.62, Section 5.3.3, Step 1
    **
    ** Extract the x co-ordinate of kG into x1
    */
    CHECK_MPI_OK( mp_read_unsigned_octets(&x1, kGpoint.data + 1,
                                          (mp_size) flen) );

    /*
    ** ANSI X9.62, Section 5.3.3, Step 2
    **
    ** r = x1 mod n  NOTE: n is the order of the curve
    */
    CHECK_MPI_OK( mp_mod(&x1, &n, &r) );

    /*
    ** ANSI X9.62, Section 5.3.3, Step 3
    **
    ** verify r != 0
    */
    if (mp_cmp_z(&r) == 0) {
        PORT_SetError(SEC_ERROR_NEED_RANDOM);
        goto cleanup;
    }

    /*
    ** ANSI X9.62, Section 5.3.3, Step 4
    **
    ** s = (k**-1 * (HASH(M) + d*r)) mod n
    */
    SECITEM_TO_MPINT(*digest, &s);        /* s = HASH(M)     */

    /* In the definition of EC signing, digests are truncated
     * to the order length
     * (see SEC 1 "Elliptic Curve Digit Signature Algorithm" section 4.1.*/
    orderBitSize = mpl_significant_bits(&n);
    if (digest->len*8 > orderBitSize) {
        mpl_rsh(&s,&s,digest->len*8 - orderBitSize);
    }

#if EC_DEBUG
    mp_todecimal(&n, mpstr);
    printf("n : %s (dec)\n", mpstr);
    mp_todecimal(&d, mpstr);
    printf("d : %s (dec)\n", mpstr);
    mp_tohex(&x1, mpstr);
    printf("x1: %s\n", mpstr);
    mp_todecimal(&s, mpstr);
    printf("digest: %s (decimal)\n", mpstr);
    mp_todecimal(&r, mpstr);
    printf("r : %s (dec)\n", mpstr);
    mp_tohex(&r, mpstr);
    printf("r : %s\n", mpstr);
#endif

    CHECK_MPI_OK( mp_invmod(&k, &n, &k) );      /* k = k**-1 mod n */
    CHECK_MPI_OK( mp_mulmod(&d, &r, &n, &d) );  /* d = d * r mod n */
    CHECK_MPI_OK( mp_addmod(&s, &d, &n, &s) );  /* s = s + d mod n */
    CHECK_MPI_OK( mp_mulmod(&s, &k, &n, &s) );  /* s = s * k mod n */

#if EC_DEBUG
    mp_todecimal(&s, mpstr);
    printf("s : %s (dec)\n", mpstr);
    mp_tohex(&s, mpstr);
    printf("s : %s\n", mpstr);
#endif

    /*
    ** ANSI X9.62, Section 5.3.3, Step 5
    **
    ** verify s != 0
    */
    if (mp_cmp_z(&s) == 0) {
        PORT_SetError(SEC_ERROR_NEED_RANDOM);
        goto cleanup;
    }

   /*
    **
    ** Signature is tuple (r, s)
    */
    CHECK_MPI_OK( mp_to_fixlen_octets(&r, signature->data, olen) );
    CHECK_MPI_OK( mp_to_fixlen_octets(&s, signature->data + olen, olen) );
finish:
    signature->len = 2*olen;

    rv = SECSuccess;
    err = MP_OKAY;
cleanup:
    mp_clear(&x1);
    mp_clear(&d);
    mp_clear(&k);
    mp_clear(&r);
    mp_clear(&s);
    mp_clear(&n);

    if (kGpoint.data) {
        PORT_ZFree(kGpoint.data, 2*flen + 1);
    }

    if (err) {
        MP_TO_SEC_ERROR(err);
        rv = SECFailure;
    }

#if EC_DEBUG
    printf("ECDSA signing with seed %s\n",
        (rv == SECSuccess) ? "succeeded" : "failed");
#endif

   return rv;
}

/*
** Computes the ECDSA signature on the digest using the given key
** and a random seed.
*/
SECStatus
ECDSA_SignDigest(ECPrivateKey *key, SECItem *signature, const SECItem *digest,
    const unsigned char* random, int randomLen, int kmflag, int timing)
{
    SECStatus rv = SECFailure;
    int len;
    unsigned char *kBytes= NULL;

    if (!key) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }

    /* Generate random value k */
    len = key->ecParams.order.len;
    kBytes = ec_GenerateRandomPrivateKey(key->ecParams.order.data, len,
        random, randomLen, kmflag);
    if (kBytes == NULL) goto cleanup;

    /* Generate ECDSA signature with the specified k value */
    rv = ECDSA_SignDigestWithSeed(key, signature, digest, kBytes, len, kmflag, timing);

cleanup:
    if (kBytes) {
        PORT_ZFree(kBytes, len * 2);
    }

#if EC_DEBUG
    printf("ECDSA signing %s\n",
        (rv == SECSuccess) ? "succeeded" : "failed");
#endif

    return rv;
}

/*
** Checks the signature on the given digest using the key provided.
*/
SECStatus
ECDSA_VerifyDigest(ECPublicKey *key, const SECItem *signature,
                 const SECItem *digest, int kmflag)
{
    SECStatus rv = SECFailure;
    mp_int r_, s_;           /* tuple (r', s') is received signature) */
    mp_int c, u1, u2, v;     /* intermediate values used in verification */
    mp_int x1;
    mp_int n;
    mp_err err = MP_OKAY;
    ECParams *ecParams = NULL;
    SECItem pointC = { siBuffer, NULL, 0 };
    int slen;       /* length in bytes of a half signature (r or s) */
    int flen;       /* length in bytes of the field size */
    unsigned olen;  /* length in bytes of the base point order */
    unsigned int orderBitSize;

#if EC_DEBUG
    char mpstr[256];
    printf("ECDSA verification called\n");
#endif

    /* Initialize MPI integers. */
    /* must happen before the first potential call to cleanup */
    MP_DIGITS(&r_) = 0;
    MP_DIGITS(&s_) = 0;
    MP_DIGITS(&c) = 0;
    MP_DIGITS(&u1) = 0;
    MP_DIGITS(&u2) = 0;
    MP_DIGITS(&x1) = 0;
    MP_DIGITS(&v)  = 0;
    MP_DIGITS(&n)  = 0;

    /* Check args */
    if (!key || !signature || !digest) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        goto cleanup;
    }

    ecParams = &(key->ecParams);
    flen = (ecParams->fieldID.size + 7) >> 3;
    olen = ecParams->order.len;
    if (signature->len == 0 || signature->len%2 != 0 ||
        signature->len > 2*olen) {
        PORT_SetError(SEC_ERROR_INPUT_LEN);
        goto cleanup;
    }
    slen = signature->len/2;

    SECITEM_AllocItem(NULL, &pointC, 2*flen + 1, kmflag);
    if (pointC.data == NULL)
        goto cleanup;

    CHECK_MPI_OK( mp_init(&r_, kmflag) );
    CHECK_MPI_OK( mp_init(&s_, kmflag) );
    CHECK_MPI_OK( mp_init(&c, kmflag)  );
    CHECK_MPI_OK( mp_init(&u1, kmflag) );
    CHECK_MPI_OK( mp_init(&u2, kmflag) );
    CHECK_MPI_OK( mp_init(&x1, kmflag)  );
    CHECK_MPI_OK( mp_init(&v, kmflag)  );
    CHECK_MPI_OK( mp_init(&n, kmflag)  );

    /*
    ** Convert received signature (r', s') into MPI integers.
    */
    CHECK_MPI_OK( mp_read_unsigned_octets(&r_, signature->data, slen) );
    CHECK_MPI_OK( mp_read_unsigned_octets(&s_, signature->data + slen, slen) );

    /*
    ** ANSI X9.62, Section 5.4.2, Steps 1 and 2
    **
    ** Verify that 0 < r' < n and 0 < s' < n
    */
    SECITEM_TO_MPINT(ecParams->order, &n);
    if (mp_cmp_z(&r_) <= 0 || mp_cmp_z(&s_) <= 0 ||
        mp_cmp(&r_, &n) >= 0 || mp_cmp(&s_, &n) >= 0) {
        PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
        goto cleanup; /* will return rv == SECFailure */
    }

    /*
    ** ANSI X9.62, Section 5.4.2, Step 3
    **
    ** c = (s')**-1 mod n
    */
    CHECK_MPI_OK( mp_invmod(&s_, &n, &c) );      /* c = (s')**-1 mod n */

    /*
    ** ANSI X9.62, Section 5.4.2, Step 4
    **
    ** u1 = ((HASH(M')) * c) mod n
    */
    SECITEM_TO_MPINT(*digest, &u1);                  /* u1 = HASH(M)     */

    /* In the definition of EC signing, digests are truncated
     * to the order length, in bits.
     * (see SEC 1 "Elliptic Curve Digit Signature Algorithm" section 4.1.*/
    /* u1 = HASH(M')     */
    orderBitSize = mpl_significant_bits(&n);
    if (digest->len*8 > orderBitSize) {
        mpl_rsh(&u1,&u1,digest->len*8- orderBitSize);
    }

#if EC_DEBUG
    mp_todecimal(&r_, mpstr);
    printf("r_: %s (dec)\n", mpstr);
    mp_todecimal(&s_, mpstr);
    printf("s_: %s (dec)\n", mpstr);
    mp_todecimal(&c, mpstr);
    printf("c : %s (dec)\n", mpstr);
    mp_todecimal(&u1, mpstr);
    printf("digest: %s (dec)\n", mpstr);
#endif

    CHECK_MPI_OK( mp_mulmod(&u1, &c, &n, &u1) );  /* u1 = u1 * c mod n */

    /*
    ** ANSI X9.62, Section 5.4.2, Step 4
    **
    ** u2 = ((r') * c) mod n
    */
    CHECK_MPI_OK( mp_mulmod(&r_, &c, &n, &u2) );

    /*
    ** ANSI X9.62, Section 5.4.3, Step 1
    **
    ** Compute u1*G + u2*Q
    ** Here, A = u1.G     B = u2.Q    and   C = A + B
    ** If the result, C, is the point at infinity, reject the signature
    */
    /* verification does not support timing mitigation */
    if (ec_points_mul(ecParams, &u1, &u2, &key->publicValue, &pointC, kmflag, /*timing*/ 0)
        != SECSuccess) {
        rv = SECFailure;
        goto cleanup;
    }
    if (ec_point_at_infinity(&pointC)) {
        PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
        rv = SECFailure;
        goto cleanup;
    }

    CHECK_MPI_OK( mp_read_unsigned_octets(&x1, pointC.data + 1, flen) );

    /*
    ** ANSI X9.62, Section 5.4.4, Step 2
    **
    ** v = x1 mod n
    */
    CHECK_MPI_OK( mp_mod(&x1, &n, &v) );

#if EC_DEBUG
    mp_todecimal(&r_, mpstr);
    printf("r_: %s (dec)\n", mpstr);
    mp_todecimal(&v, mpstr);
    printf("v : %s (dec)\n", mpstr);
#endif

    /*
    ** ANSI X9.62, Section 5.4.4, Step 3
    **
    ** Verification:  v == r'
    */
    if (mp_cmp(&v, &r_)) {
        PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
        rv = SECFailure; /* Signature failed to verify. */
    } else {
        rv = SECSuccess; /* Signature verified. */
    }

#if EC_DEBUG
    mp_todecimal(&u1, mpstr);
    printf("u1: %s (dec)\n", mpstr);
    mp_todecimal(&u2, mpstr);
    printf("u2: %s (dec)\n", mpstr);
    mp_tohex(&x1, mpstr);
    printf("x1: %s\n", mpstr);
    mp_todecimal(&v, mpstr);
    printf("v : %s (dec)\n", mpstr);
#endif

cleanup:
    mp_clear(&r_);
    mp_clear(&s_);
    mp_clear(&c);
    mp_clear(&u1);
    mp_clear(&u2);
    mp_clear(&x1);
    mp_clear(&v);
    mp_clear(&n);

    if (pointC.data) SECITEM_FreeItem(&pointC, PR_FALSE);
    if (err) {
        MP_TO_SEC_ERROR(err);
        rv = SECFailure;
    }

#if EC_DEBUG
    printf("ECDSA verification %s\n",
        (rv == SECSuccess) ? "succeeded" : "failed");
#endif

    return rv;
}
