/* 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/. */

#include "blapi.h"
#include "ec.h"
#include "ecl-curve.h"
#include "prprf.h"
#include "basicutil.h"
#include "secder.h"
#include "secitem.h"
#include "nspr.h"
#include <stdio.h>

typedef struct {
    ECCurveName curve;
    int iterations;
    char *privhex;
    char *our_pubhex;
    char *their_pubhex;
    char *common_key;
    char *name;
    ECFieldType fieldType;
} ECDH_KAT;

typedef struct {
    ECCurveName curve;
    char *point;
    char *name;
    ECFieldType fieldType;
} ECDH_BAD;

#include "testvecs.h"

void
printBuf(const SECItem *item)
{
    int i;
    if (!item || !item->len) {
        printf("(null)\n");
        return;
    }

    for (i = 0; i < item->len; i++) {
        printf("%02x", item->data[i]);
    }
    printf("\n");
}

/* Initialise test with basic curve populate with only the necessary things */
SECStatus
init_params(ECParams *ecParams, ECCurveName curve, PLArenaPool **arena,
            ECFieldType type)
{
    if ((curve < ECCurve_noName) || (curve > ECCurve_pastLastCurve)) {
        return SECFailure;
    }
    *arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
    if (!*arena) {
        return SECFailure;
    }
    ecParams->name = curve;
    ecParams->type = ec_params_named;
    ecParams->curveOID.data = NULL;
    ecParams->curveOID.len = 0;
    ecParams->curve.seed.data = NULL;
    ecParams->curve.seed.len = 0;
    ecParams->DEREncoding.data = NULL;
    ecParams->DEREncoding.len = 0;
    ecParams->arena = *arena;
    ecParams->fieldID.size = ecCurve_map[curve]->size;
    ecParams->fieldID.type = type;
    ecParams->cofactor = ecCurve_map[curve]->cofactor;

    return SECSuccess;
}

SECStatus
ectest_ecdh_kat(ECDH_KAT *kat)
{
    ECCurveName curve = kat->curve;
    ECParams ecParams = { 0 };
    ECPrivateKey *ecPriv = NULL;
    SECItem theirKey = { siBuffer, NULL, 0 };
    SECStatus rv = SECFailure;
    PLArenaPool *arena = NULL;
    SECItem seed = { siBuffer, NULL, 0 };
    SECItem answer = { siBuffer, NULL, 0 };
    SECItem answer2 = { siBuffer, NULL, 0 };
    SECItem derived = { siBuffer, NULL, 0 };
    SECItem ecEncodedParams = { siBuffer, NULL, 0 };
    int i;

    arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
    if (!arena) {
        return SECFailure;
    }

    rv = SECU_ecName2params(curve, &ecEncodedParams);
    if (rv != SECSuccess) {
        goto cleanup;
    }
    EC_FillParams(arena, &ecEncodedParams, &ecParams);

    if (kat->our_pubhex) {
        SECU_HexString2SECItem(arena, &answer, kat->our_pubhex);
    }
    SECU_HexString2SECItem(arena, &seed, kat->privhex);
    rv = EC_NewKeyFromSeed(&ecParams, &ecPriv, seed.data, seed.len);
    if (rv != SECSuccess) {
        rv = SECFailure;
        goto cleanup;
    }
    if (kat->our_pubhex) {
        if (SECITEM_CompareItem(&answer, &ecPriv->publicValue) != SECEqual) {
            rv = SECFailure;
            goto cleanup;
        }
    }

    SECU_HexString2SECItem(arena, &theirKey, kat->their_pubhex);
    SECU_HexString2SECItem(arena, &answer2, kat->common_key);

    rv = EC_ValidatePublicKey(&ecParams, &theirKey);
    if (rv != SECSuccess) {
        printf("EC_ValidatePublicKey failed\n");
        goto cleanup;
    }

    for (i = 0; i < kat->iterations; ++i) {
        rv = ECDH_Derive(&theirKey, &ecParams, &ecPriv->privateValue, PR_TRUE, &derived);
        if (rv != SECSuccess) {
            rv = SECFailure;
            goto cleanup;
        }
        rv = SECITEM_CopyItem(ecParams.arena, &theirKey, &ecPriv->privateValue);
        if (rv != SECSuccess) {
            goto cleanup;
        }
        rv = SECITEM_CopyItem(ecParams.arena, &ecPriv->privateValue, &derived);
        if (rv != SECSuccess) {
            goto cleanup;
        }
        SECITEM_FreeItem(&derived, PR_FALSE);
    }

    if (SECITEM_CompareItem(&answer2, &ecPriv->privateValue) != SECEqual) {
        printf("expected: ");
        printBuf(&answer2);
        printf("derived:  ");
        printBuf(&ecPriv->privateValue);
        rv = SECFailure;
        goto cleanup;
    }

cleanup:
    SECITEM_FreeItem(&ecEncodedParams, PR_FALSE);
    PORT_FreeArena(arena, PR_FALSE);
    if (ecPriv) {
        PORT_FreeArena(ecPriv->ecParams.arena, PR_FALSE);
    }
    if (derived.data) {
        SECITEM_FreeItem(&derived, PR_FALSE);
    }
    return rv;
}

SECStatus
ectest_validate_point(ECDH_BAD *bad)
{
    ECParams ecParams = { 0 };
    SECItem point = { siBuffer, NULL, 0 };
    SECStatus rv = SECFailure;
    PLArenaPool *arena = NULL;

    rv = init_params(&ecParams, bad->curve, &arena, bad->fieldType);
    if (rv != SECSuccess) {
        return rv;
    }

    SECU_HexString2SECItem(arena, &point, bad->point);
    rv = EC_ValidatePublicKey(&ecParams, &point);

    PORT_FreeArena(arena, PR_FALSE);
    return rv;
}

void
printUsage(char *prog)
{
    printf("Usage: %s [-fp] [-nd]\n"
           "\t-n: NIST curves\n"
           "\t-d: non-NIST curves\n"
           "You have to specify at at least one of n or d.\n"
           "By default no tests are executed.\n",
           prog);
}

/* Performs tests of elliptic curve cryptography over prime fields If
 * tests fail, then it prints an error message, aborts, and returns an
 * error code. Otherwise, returns 0. */
int
main(int argv, char **argc)
{
    SECStatus rv = SECSuccess;
    int numkats = 0;
    int i = 0;
    int nist = 0;
    int nonnist = 0;

    for (i = 1; i < argv; i++) {
        if (PL_strcasecmp(argc[i], "-n") == 0) {
            nist = 1;
        } else if (PL_strcasecmp(argc[i], "-d") == 0) {
            nonnist = 1;
        } else {
            printUsage(argc[0]);
            return 1;
        }
    }
    if (!nist && !nonnist) {
        printUsage(argc[0]);
        return 1;
    }

    rv = SECOID_Init();
    if (rv != SECSuccess) {
        SECU_PrintError("Error:", "SECOID_Init");
        goto cleanup;
    }

    /* Test P256, P384, P521 */
    if (nist) {
        while (ecdh_testvecs[numkats].curve != ECCurve_pastLastCurve) {
            numkats++;
        }
        printf("1..%d\n", numkats);
        for (i = 0; ecdh_testvecs[i].curve != ECCurve_pastLastCurve; i++) {
            if (ectest_ecdh_kat(&ecdh_testvecs[i]) != SECSuccess) {
                printf("not okay %d - %s\n", i + 1, ecdh_testvecs[i].name);
                rv = SECFailure;
            } else {
                printf("okay %d - %s\n", i + 1, ecdh_testvecs[i].name);
            }
        }
    }

    /* Test KAT for non-NIST curves */
    if (nonnist) {
        for (i = 0; nonnist_testvecs[i].curve != ECCurve_pastLastCurve; i++) {
            if (ectest_ecdh_kat(&nonnist_testvecs[i]) != SECSuccess) {
                printf("not okay %d - %s\n", i + 1, nonnist_testvecs[i].name);
                rv = SECFailure;
            } else {
                printf("okay %d - %s\n", i + 1, nonnist_testvecs[i].name);
            }
        }
        for (i = 0; nonnist_testvecs_bad_values[i].curve != ECCurve_pastLastCurve; i++) {
            if (ectest_validate_point(&nonnist_testvecs_bad_values[i]) == SECSuccess) {
                printf("not okay %d - %s\n", i + 1, nonnist_testvecs_bad_values[i].name);
                rv = SECFailure;
            } else {
                printf("okay %d - %s\n", i + 1, nonnist_testvecs_bad_values[i].name);
            }
        }
    }

cleanup:
    rv |= SECOID_Shutdown();

    if (rv != SECSuccess) {
        printf("Error: exiting with error value\n");
    }
    return rv;
}
