Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Firefox/security/nss/cmd/bltest/   (Browser von der Mozilla Stiftung Version 136.0.1©)  Datei vom 10.2.2025 mit Größe 148 kB image not shown  

Quelle  blapitest.c   Sprache: C

 
/* 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 <stdio.h>
#include <stdlib.h>

#include "blapi.h"
#include "secrng.h"
#include "prmem.h"
#include "prprf.h"
#include "prtime.h"
#include "prsystem.h"
#include "plstr.h"
#include "nssb64.h"
#include "basicutil.h"
#include "plgetopt.h"
#include "softoken.h"
#include "nspr.h"
#include "secport.h"
#include "secoid.h"
#include "nssutil.h"
#include "ecl-curve.h"
#include "chacha20poly1305.h"

#include "pkcs1_vectors.h"

SECStatus EC_DecodeParams(const SECItem *encodedParams,
                          ECParams **ecparams);
SECStatus EC_CopyParams(PLArenaPool *arena, ECParams *dstParams,
                        const ECParams *srcParams);

char *progName;
char *testdir = NULL;

#define BLTEST_DEFAULT_CHUNKSIZE 4096

#define WORDSIZE sizeof(unsigned long)

#define CHECKERROR(rv, ln)                                               \
    if (rv) {                                                            \
        PRErrorCode prerror = PR_GetError();                             \
        PR_fprintf(PR_STDERR, "%s: ERR %d (%s) at line %d.\n", progName, \
                   prerror, PORT_ErrorToString(prerror), ln);            \
        exit(-1);                                                        \
    }

/* Macros for performance timing. */
#define TIMESTART() \
    time1 = PR_IntervalNow();

#define TIMEFINISH(time, reps)                          \
    time2 = (PRIntervalTime)(PR_IntervalNow() - time1); \
    time1 = PR_IntervalToMilliseconds(time2);           \
    time = ((double)(time1)) / reps;

#define TIMEMARK(seconds)                      \
    time1 = PR_SecondsToInterval(seconds);     \
    {                                          \
        PRInt64 tmp;                           \
        if (time2 == 0) {                      \
            time2 = 1;                         \
        }                                      \
        LL_DIV(tmp, time1, time2);             \
        if (tmp < 10) {                        \
            if (tmp == 0) {                    \
                opsBetweenChecks = 1;          \
            } else {                           \
                LL_L2I(opsBetweenChecks, tmp); \
            }                                  \
        } else {                               \
            opsBetweenChecks = 10;             \
        }                                      \
    }                                          \
    time2 = time1;                             \
    time1 = PR_IntervalNow();

#define TIMETOFINISH() \
    PR_IntervalNow() - time1 >= time2

static void
Usage()
{
#define PRINTUSAGE(subject, option, predicate) \
    fprintf(stderr, "%10s %s\t%s\n", subject, option, predicate);
    fprintf(stderr, "\n");
    PRINTUSAGE(progName, "[-DEHSVR]""List available cipher modes"); /* XXX */
    fprintf(stderr, "\n");
    PRINTUSAGE(progName, "-E -m mode ""Encrypt a buffer");
    PRINTUSAGE("""""[-i plaintext] [-o ciphertext] [-k key] [-v iv]");
    PRINTUSAGE("""""[-b bufsize] [-g keysize] [-e exp] [-r rounds]");
    PRINTUSAGE("""""[-w wordsize] [-p repetitions | -5 time_interval]");
    PRINTUSAGE("""""[-4 th_num]");
    PRINTUSAGE("""-m""cipher mode to use");
    PRINTUSAGE("""-i""file which contains input buffer");
    PRINTUSAGE("""-o""file for output buffer");
    PRINTUSAGE("""-k""file which contains key");
    PRINTUSAGE("""-v""file which contains initialization vector");
    PRINTUSAGE("""-b""size of input buffer");
    PRINTUSAGE("""-g""key size (in bytes)");
    PRINTUSAGE("""-p""do performance test");
    PRINTUSAGE("""-4""run test in multithread mode. th_num number of parallel threads");
    PRINTUSAGE("""-5""run test for specified time interval(in seconds)");
    PRINTUSAGE("""--aad""File with contains additional auth data");
    PRINTUSAGE("(rsa)""-e""rsa public exponent");
    PRINTUSAGE("(rc5)""-r""number of rounds");
    PRINTUSAGE("(rc5)""-w""wordsize (32 or 64)");
    fprintf(stderr, "\n");
    PRINTUSAGE(progName, "-D -m mode""Decrypt a buffer");
    PRINTUSAGE("""""[-i plaintext] [-o ciphertext] [-k key] [-v iv]");
    PRINTUSAGE("""""[-p repetitions | -5 time_interval] [-4 th_num]");
    PRINTUSAGE("""-m""cipher mode to use");
    PRINTUSAGE("""-i""file which contains input buffer");
    PRINTUSAGE("""-o""file for output buffer");
    PRINTUSAGE("""-k""file which contains key");
    PRINTUSAGE("""-v""file which contains initialization vector");
    PRINTUSAGE("""-p""do performance test");
    PRINTUSAGE("""-4""run test in multithread mode. th_num number of parallel threads");
    PRINTUSAGE("""-5""run test for specified time interval(in seconds)");
    PRINTUSAGE("""--aad""File with contains additional auth data");
    fprintf(stderr, "\n");
    PRINTUSAGE(progName, "-H -m mode""Hash a buffer");
    PRINTUSAGE("""""[-i plaintext] [-o hash]");
    PRINTUSAGE("""""[-b bufsize]");
    PRINTUSAGE("""""[-p repetitions | -5 time_interval] [-4 th_num]");
    PRINTUSAGE("""-m""cipher mode to use");
    PRINTUSAGE("""-i""file which contains input buffer");
    PRINTUSAGE("""-o""file for hash");
    PRINTUSAGE("""-b""size of input buffer");
    PRINTUSAGE("""-p""do performance test");
    PRINTUSAGE("""-4""run test in multithread mode. th_num number of parallel threads");
    PRINTUSAGE("""-5""run test for specified time interval(in seconds)");
    fprintf(stderr, "\n");
    PRINTUSAGE(progName, "-S -m mode""Sign a buffer");
    PRINTUSAGE("""""[-i plaintext] [-o signature] [-k key]");
    PRINTUSAGE("""""[-b bufsize]");
    PRINTUSAGE("""""[-n curvename]");
    PRINTUSAGE("""""[-p repetitions | -5 time_interval] [-4 th_num]");
    PRINTUSAGE("""-m""cipher mode to use");
    PRINTUSAGE("""-i""file which contains input buffer");
    PRINTUSAGE("""-o""file for signature");
    PRINTUSAGE("""-k""file which contains key");
    PRINTUSAGE("""-n""name of curve for EC key generation; one of:");
    PRINTUSAGE(""""" nistp256, nistp384, nistp521");
    PRINTUSAGE("""-p""do performance test");
    PRINTUSAGE("""-4""run test in multithread mode. th_num number of parallel threads");
    PRINTUSAGE("""-5""run test for specified time interval(in seconds)");
    fprintf(stderr, "\n");
    PRINTUSAGE(progName, "-V -m mode""Verify a signed buffer");
    PRINTUSAGE("""""[-i plaintext] [-s signature] [-k key]");
    PRINTUSAGE("""""[-p repetitions | -5 time_interval] [-4 th_num]");
    PRINTUSAGE("""-m""cipher mode to use");
    PRINTUSAGE("""-i""file which contains input buffer");
    PRINTUSAGE("""-s""file which contains signature of input buffer");
    PRINTUSAGE("""-k""file which contains key");
    PRINTUSAGE("""-p""do performance test");
    PRINTUSAGE("""-4""run test in multithread mode. th_num number of parallel threads");
    PRINTUSAGE("""-5""run test for specified time interval(in seconds)");
    fprintf(stderr, "\n");
    PRINTUSAGE(progName, "-N -m mode -b bufsize",
               "Create a nonce plaintext and key");
    PRINTUSAGE("""""[-g keysize] [-u cxreps]");
    PRINTUSAGE("""-g""key size (in bytes)");
    PRINTUSAGE("""-u""number of repetitions of context creation");
    fprintf(stderr, "\n");
    PRINTUSAGE(progName, "-R [-g keysize] [-e exp]",
               "Test the RSA populate key function");
    PRINTUSAGE("""""[-r repetitions]");
    PRINTUSAGE("""-g""key size (in bytes)");
    PRINTUSAGE("""-e""rsa public exponent");
    PRINTUSAGE("""-r""repetitions of the test");
    fprintf(stderr, "\n");
    PRINTUSAGE(progName, "-F""Run the FIPS self-test");
    fprintf(stderr, "\n");
    PRINTUSAGE(progName, "-T [-m mode1,mode2...]""Run the BLAPI self-test");
    fprintf(stderr, "\n");
    exit(1);
}

/*  Helper functions for ascii<-->binary conversion/reading/writing */

/* XXX argh */
struct item_with_arena {
    SECItem *item;
    PLArenaPool *arena;
};

static PRInt32
get_binary(void *arg, const unsigned char *ibuf, PRInt32 size)
{
    struct item_with_arena *it = arg;
    SECItem *binary = it->item;
    SECItem *tmp;
    int index;
    if (binary->data == NULL) {
        tmp = SECITEM_AllocItem(it->arena, NULL, size);
        binary->data = tmp->data;
        binary->len = tmp->len;
        index = 0;
    } else {
        SECITEM_ReallocItem(NULL, binary, binary->len, binary->len + size);
        index = binary->len;
    }
    PORT_Memcpy(&binary->data[index], ibuf, size);
    return binary->len;
}

static SECStatus
atob(SECItem *ascii, SECItem *binary, PLArenaPool *arena)
{
    SECStatus status;
    NSSBase64Decoder *cx;
    struct item_with_arena it;
    int len;
    binary->data = NULL;
    binary->len = 0;
    it.item = binary;
    it.arena = arena;
    len = (strncmp((const char *)&ascii->data[ascii->len - 2], "\r\n", 2)) ? ascii->len
                                                                           : ascii->len - 2;
    cx = NSSBase64Decoder_Create(get_binary, &it);
    status = NSSBase64Decoder_Update(cx, (const char *)ascii->data, len);
    status = NSSBase64Decoder_Destroy(cx, PR_FALSE);
    return status;
}

static PRInt32
output_ascii(void *arg, const char *obuf, PRInt32 size)
{
    PRFileDesc *outfile = arg;
    PRInt32 nb = PR_Write(outfile, obuf, size);
    if (nb != size) {
        PORT_SetError(SEC_ERROR_IO);
        return -1;
    }
    return nb;
}

static SECStatus
btoa_file(SECItem *binary, PRFileDesc *outfile)
{
    SECStatus status;
    NSSBase64Encoder *cx;
    if (binary->len == 0)
        return SECSuccess;
    cx = NSSBase64Encoder_Create(output_ascii, outfile);
    status = NSSBase64Encoder_Update(cx, binary->data, binary->len);
    status = NSSBase64Encoder_Destroy(cx, PR_FALSE);
    status = PR_Write(outfile, "\r\n", 2);
    return status;
}

SECStatus
hex_from_2char(unsigned char *c2, unsigned char *byteval)
{
    int i;
    unsigned char offset;
    *byteval = 0;
    for (i = 0; i < 2; i++) {
        if (c2[i] >= '0' && c2[i] <= '9') {
            offset = c2[i] - '0';
            *byteval |= offset << 4 * (1 - i);
        } else if (c2[i] >= 'a' && c2[i] <= 'f') {
            offset = c2[i] - 'a';
            *byteval |= (offset + 10) << 4 * (1 - i);
        } else if (c2[i] >= 'A' && c2[i] <= 'F') {
            offset = c2[i] - 'A';
            *byteval |= (offset + 10) << 4 * (1 - i);
        } else {
            return SECFailure;
        }
    }
    return SECSuccess;
}

SECStatus
char2_from_hex(unsigned char byteval, char *c2)
{
    int i;
    unsigned char offset;
    for (i = 0; i < 2; i++) {
        offset = (byteval >> 4 * (1 - i)) & 0x0f;
        if (offset < 10) {
            c2[i] = '0' + offset;
        } else {
            c2[i] = 'A' + offset - 10;
        }
    }
    return SECSuccess;
}

void
serialize_key(SECItem *it, int ni, PRFileDesc *file)
{
    unsigned char len[4];
    int i;
    NSSBase64Encoder *cx;
    cx = NSSBase64Encoder_Create(output_ascii, file);
    for (i = 0; i < ni; i++, it++) {
        len[0] = (it->len >> 24) & 0xff;
        len[1] = (it->len >> 16) & 0xff;
        len[2] = (it->len >> 8) & 0xff;
        len[3] = (it->len & 0xff);
        NSSBase64Encoder_Update(cx, len, 4);
        NSSBase64Encoder_Update(cx, it->data, it->len);
    }
    NSSBase64Encoder_Destroy(cx, PR_FALSE);
    PR_Write(file, "\r\n", 2);
}

void
key_from_filedata(PLArenaPool *arena, SECItem *it, int ns, int ni, SECItem *filedata)
{
    int fpos = 0;
    int i, len;
    unsigned char *buf = filedata->data;
    for (i = 0; i < ni; i++) {
        len = (buf[fpos++] & 0xff) << 24;
        len |= (buf[fpos++] & 0xff) << 16;
        len |= (buf[fpos++] & 0xff) << 8;
        len |= (buf[fpos++] & 0xff);
        if (ns <= i) {
            if (len > 0) {
                it->len = len;
                it->data = PORT_ArenaAlloc(arena, it->len);
                PORT_Memcpy(it->data, &buf[fpos], it->len);
            } else {
                it->len = 0;
                it->data = NULL;
            }
            it++;
        }
        fpos += len;
    }
}

static RSAPrivateKey *
rsakey_from_filedata(PLArenaPool *arena, SECItem *filedata)
{
    RSAPrivateKey *key;
    key = (RSAPrivateKey *)PORT_ArenaZAlloc(arena, sizeof(RSAPrivateKey));
    key->arena = arena;
    key_from_filedata(arena, &key->version, 0, 9, filedata);
    return key;
}

static PQGParams *
pqg_from_filedata(PLArenaPool *arena, SECItem *filedata)
{
    PQGParams *pqg;
    pqg = (PQGParams *)PORT_ArenaZAlloc(arena, sizeof(PQGParams));
    pqg->arena = arena;
    key_from_filedata(arena, &pqg->prime, 0, 3, filedata);
    return pqg;
}

static DSAPrivateKey *
dsakey_from_filedata(PLArenaPool *arena, SECItem *filedata)
{
    DSAPrivateKey *key;
    key = (DSAPrivateKey *)PORT_ArenaZAlloc(arena, sizeof(DSAPrivateKey));
    key->params.arena = arena;
    key_from_filedata(arena, &key->params.prime, 0, 5, filedata);
    return key;
}

static ECPrivateKey *
eckey_from_filedata(PLArenaPool *arena, SECItem *filedata)
{
    ECPrivateKey *key;
    SECStatus rv;
    ECParams *tmpECParams = NULL;
    key = (ECPrivateKey *)PORT_ArenaZAlloc(arena, sizeof(ECPrivateKey));
    /* read and convert params */
    key->ecParams.arena = arena;
    key_from_filedata(arena, &key->ecParams.DEREncoding, 0, 1, filedata);
    rv = SECOID_Init();
    CHECKERROR(rv, __LINE__);
    rv = EC_DecodeParams(&key->ecParams.DEREncoding, &tmpECParams);
    CHECKERROR(rv, __LINE__);
    rv = EC_CopyParams(key->ecParams.arena, &key->ecParams, tmpECParams);
    CHECKERROR(rv, __LINE__);
    rv = SECOID_Shutdown();
    CHECKERROR(rv, __LINE__);
    PORT_FreeArena(tmpECParams->arena, PR_TRUE);
    /* read key */
    key_from_filedata(arena, &key->publicValue, 1, 3, filedata);
    return key;
}

typedef struct curveNameTagPairStr {
    char *curveName;
    SECOidTag curveOidTag;
} CurveNameTagPair;

static CurveNameTagPair nameTagPair[] = {
    { "sect163k1", SEC_OID_SECG_EC_SECT163K1 },
    { "nistk163", SEC_OID_SECG_EC_SECT163K1 },
    { "sect163r1", SEC_OID_SECG_EC_SECT163R1 },
    { "sect163r2", SEC_OID_SECG_EC_SECT163R2 },
    { "nistb163", SEC_OID_SECG_EC_SECT163R2 },
    { "sect193r1", SEC_OID_SECG_EC_SECT193R1 },
    { "sect193r2", SEC_OID_SECG_EC_SECT193R2 },
    { "sect233k1", SEC_OID_SECG_EC_SECT233K1 },
    { "nistk233", SEC_OID_SECG_EC_SECT233K1 },
    { "sect233r1", SEC_OID_SECG_EC_SECT233R1 },
    { "nistb233", SEC_OID_SECG_EC_SECT233R1 },
    { "sect239k1", SEC_OID_SECG_EC_SECT239K1 },
    { "sect283k1", SEC_OID_SECG_EC_SECT283K1 },
    { "nistk283", SEC_OID_SECG_EC_SECT283K1 },
    { "sect283r1", SEC_OID_SECG_EC_SECT283R1 },
    { "nistb283", SEC_OID_SECG_EC_SECT283R1 },
    { "sect409k1", SEC_OID_SECG_EC_SECT409K1 },
    { "nistk409", SEC_OID_SECG_EC_SECT409K1 },
    { "sect409r1", SEC_OID_SECG_EC_SECT409R1 },
    { "nistb409", SEC_OID_SECG_EC_SECT409R1 },
    { "sect571k1", SEC_OID_SECG_EC_SECT571K1 },
    { "nistk571", SEC_OID_SECG_EC_SECT571K1 },
    { "sect571r1", SEC_OID_SECG_EC_SECT571R1 },
    { "nistb571", SEC_OID_SECG_EC_SECT571R1 },
    { "secp160k1", SEC_OID_SECG_EC_SECP160K1 },
    { "secp160r1", SEC_OID_SECG_EC_SECP160R1 },
    { "secp160r2", SEC_OID_SECG_EC_SECP160R2 },
    { "secp192k1", SEC_OID_SECG_EC_SECP192K1 },
    { "secp192r1", SEC_OID_SECG_EC_SECP192R1 },
    { "nistp192", SEC_OID_SECG_EC_SECP192R1 },
    { "secp224k1", SEC_OID_SECG_EC_SECP224K1 },
    { "secp224r1", SEC_OID_SECG_EC_SECP224R1 },
    { "nistp224", SEC_OID_SECG_EC_SECP224R1 },
    { "secp256k1", SEC_OID_SECG_EC_SECP256K1 },
    { "secp256r1", SEC_OID_SECG_EC_SECP256R1 },
    { "nistp256", SEC_OID_SECG_EC_SECP256R1 },
    { "secp384r1", SEC_OID_SECG_EC_SECP384R1 },
    { "nistp384", SEC_OID_SECG_EC_SECP384R1 },
    { "secp521r1", SEC_OID_SECG_EC_SECP521R1 },
    { "nistp521", SEC_OID_SECG_EC_SECP521R1 },

    { "prime192v1", SEC_OID_ANSIX962_EC_PRIME192V1 },
    { "prime192v2", SEC_OID_ANSIX962_EC_PRIME192V2 },
    { "prime192v3", SEC_OID_ANSIX962_EC_PRIME192V3 },
    { "prime239v1", SEC_OID_ANSIX962_EC_PRIME239V1 },
    { "prime239v2", SEC_OID_ANSIX962_EC_PRIME239V2 },
    { "prime239v3", SEC_OID_ANSIX962_EC_PRIME239V3 },

    { "c2pnb163v1", SEC_OID_ANSIX962_EC_C2PNB163V1 },
    { "c2pnb163v2", SEC_OID_ANSIX962_EC_C2PNB163V2 },
    { "c2pnb163v3", SEC_OID_ANSIX962_EC_C2PNB163V3 },
    { "c2pnb176v1", SEC_OID_ANSIX962_EC_C2PNB176V1 },
    { "c2tnb191v1", SEC_OID_ANSIX962_EC_C2TNB191V1 },
    { "c2tnb191v2", SEC_OID_ANSIX962_EC_C2TNB191V2 },
    { "c2tnb191v3", SEC_OID_ANSIX962_EC_C2TNB191V3 },
    { "c2onb191v4", SEC_OID_ANSIX962_EC_C2ONB191V4 },
    { "c2onb191v5", SEC_OID_ANSIX962_EC_C2ONB191V5 },
    { "c2pnb208w1", SEC_OID_ANSIX962_EC_C2PNB208W1 },
    { "c2tnb239v1", SEC_OID_ANSIX962_EC_C2TNB239V1 },
    { "c2tnb239v2", SEC_OID_ANSIX962_EC_C2TNB239V2 },
    { "c2tnb239v3", SEC_OID_ANSIX962_EC_C2TNB239V3 },
    { "c2onb239v4", SEC_OID_ANSIX962_EC_C2ONB239V4 },
    { "c2onb239v5", SEC_OID_ANSIX962_EC_C2ONB239V5 },
    { "c2pnb272w1", SEC_OID_ANSIX962_EC_C2PNB272W1 },
    { "c2pnb304w1", SEC_OID_ANSIX962_EC_C2PNB304W1 },
    { "c2tnb359v1", SEC_OID_ANSIX962_EC_C2TNB359V1 },
    { "c2pnb368w1", SEC_OID_ANSIX962_EC_C2PNB368W1 },
    { "c2tnb431r1", SEC_OID_ANSIX962_EC_C2TNB431R1 },

    { "secp112r1", SEC_OID_SECG_EC_SECP112R1 },
    { "secp112r2", SEC_OID_SECG_EC_SECP112R2 },
    { "secp128r1", SEC_OID_SECG_EC_SECP128R1 },
    { "secp128r2", SEC_OID_SECG_EC_SECP128R2 },

    { "sect113r1", SEC_OID_SECG_EC_SECT113R1 },
    { "sect113r2", SEC_OID_SECG_EC_SECT113R2 },
    { "sect131r1", SEC_OID_SECG_EC_SECT131R1 },
    { "sect131r2", SEC_OID_SECG_EC_SECT131R2 },
    { "curve25519", SEC_OID_CURVE25519 },
};

static SECItem *
getECParams(const char *curve)
{
    SECItem *ecparams;
    SECOidData *oidData = NULL;
    SECOidTag curveOidTag = SEC_OID_UNKNOWN; /* default */
    int i, numCurves;

    if (curve != NULL) {
        numCurves = sizeof(nameTagPair) / sizeof(CurveNameTagPair);
        for (i = 0; ((i < numCurves) && (curveOidTag == SEC_OID_UNKNOWN));
             i++) {
            if (PL_strcmp(curve, nameTagPair[i].curveName) == 0)
                curveOidTag = nameTagPair[i].curveOidTag;
        }
    }

    /* Return NULL if curve name is not recognized */
    if ((curveOidTag == SEC_OID_UNKNOWN) ||
        (oidData = SECOID_FindOIDByTag(curveOidTag)) == NULL) {
        fprintf(stderr, "Unrecognized elliptic curve %s\n", curve);
        return NULL;
    }

    ecparams = SECITEM_AllocItem(NULL, NULL, (2 + oidData->oid.len));

    /*
     * ecparams->data needs to contain the ASN encoding of an object ID (OID)
     * representing the named curve. The actual OID is in
     * oidData->oid.data so we simply prepend 0x06 and OID length
     */

    ecparams->data[0] = SEC_ASN1_OBJECT_ID;
    ecparams->data[1] = oidData->oid.len;
    memcpy(ecparams->data + 2, oidData->oid.data, oidData->oid.len);

    return ecparams;
}

static void
dump_pqg(PQGParams *pqg)
{
    SECU_PrintInteger(stdout, &pqg->prime, "PRIME:", 0);
    SECU_PrintInteger(stdout, &pqg->subPrime, "SUBPRIME:", 0);
    SECU_PrintInteger(stdout, &pqg->base, "BASE:", 0);
}

static void
dump_dsakey(DSAPrivateKey *key)
{
    dump_pqg(&key->params);
    SECU_PrintInteger(stdout, &key->publicValue, "PUBLIC VALUE:", 0);
    SECU_PrintInteger(stdout, &key->privateValue, "PRIVATE VALUE:", 0);
}

static void
dump_ecp(ECParams *ecp)
{
    /* TODO other fields */
    SECU_PrintInteger(stdout, &ecp->base, "BASE POINT:", 0);
}

static void
dump_eckey(ECPrivateKey *key)
{
    dump_ecp(&key->ecParams);
    SECU_PrintInteger(stdout, &key->publicValue, "PUBLIC VALUE:", 0);
    SECU_PrintInteger(stdout, &key->privateValue, "PRIVATE VALUE:", 0);
}

static void
dump_rsakey(RSAPrivateKey *key)
{
    SECU_PrintInteger(stdout, &key->version, "VERSION:", 0);
    SECU_PrintInteger(stdout, &key->modulus, "MODULUS:", 0);
    SECU_PrintInteger(stdout, &key->publicExponent, "PUBLIC EXP:", 0);
    SECU_PrintInteger(stdout, &key->privateExponent, "PRIVATE EXP:", 0);
    SECU_PrintInteger(stdout, &key->prime1, "CRT PRIME 1:", 0);
    SECU_PrintInteger(stdout, &key->prime2, "CRT PRIME 2:", 0);
    SECU_PrintInteger(stdout, &key->exponent1, "CRT EXP 1:", 0);
    SECU_PrintInteger(stdout, &key->exponent2, "CRT EXP 2:", 0);
    SECU_PrintInteger(stdout, &key->coefficient, "CRT COEFFICIENT:", 0);
}

typedef enum {
    bltestBase64Encoded, /* Base64 encoded ASCII */
    bltestBinary,        /* straight binary */
    bltestHexSpaceDelim, /* 0x12 0x34 0xab 0xCD ... */
    bltestHexStream      /* 1234abCD ... */
} bltestIOMode;

typedef struct
{
    SECItem buf;
    SECItem pBuf;
    bltestIOMode mode;
    PRFileDesc *file;
} bltestIO;

typedef SECStatus (*bltestSymmCipherFn)(void *cx,
                                        unsigned char *output,
                                        unsigned int *outputLen,
                                        unsigned int maxOutputLen,
                                        const unsigned char *input,
                                        unsigned int inputLen);

typedef SECStatus (*bltestAEADFn)(void *cx,
                                  unsigned char *output,
                                  unsigned int *outputLen,
                                  unsigned int maxOutputLen,
                                  const unsigned char *input,
                                  unsigned int inputLen,
                                  const unsigned char *nonce,
                                  unsigned int nonceLen,
                                  const unsigned char *ad,
                                  unsigned int adLen);

typedef SECStatus (*bltestPubKeyCipherFn)(void *key,
                                          SECItem *output,
                                          const SECItem *input);

typedef SECStatus (*bltestHashCipherFn)(unsigned char *dest,
                                        const unsigned char *src,
                                        PRUint32 src_length);

/* Note: Algorithms are grouped in order to support is_symmkeyCipher /
 * is_pubkeyCipher / is_hashCipher / is_sigCipher
 */

typedef enum {
    bltestINVALID = -1,
    bltestDES_ECB,     /* Symmetric Key Ciphers */
    bltestDES_CBC,     /* .            */
    bltestDES_EDE_ECB, /* .            */
    bltestDES_EDE_CBC, /* .            */
#ifndef NSS_DISABLE_DEPRECATED_RC2
    bltestRC2_ECB, /* .            */
    bltestRC2_CBC, /* .            */
#endif
    bltestRC4, /* .            */
#ifdef NSS_SOFTOKEN_DOES_RC5
    bltestRC5_ECB, /* .            */
    bltestRC5_CBC, /* .            */
#endif
    bltestAES_ECB,      /* .                     */
    bltestAES_CBC,      /* .                     */
    bltestAES_CTS,      /* .                     */
    bltestAES_CTR,      /* .                     */
    bltestAES_GCM,      /* .                     */
    bltestCAMELLIA_ECB, /* .                     */
    bltestCAMELLIA_CBC, /* .                     */
#ifndef NSS_DISABLE_DEPRECATED_SEED
    bltestSEED_ECB, /* SEED algorithm      */
    bltestSEED_CBC, /* SEED algorithm      */
#endif
    bltestCHACHA20_CTR, /* ChaCha20 block cipher */
    bltestCHACHA20,     /* ChaCha20 + Poly1305   */
    bltestRSA,          /* Public Key Ciphers    */
    bltestRSA_OAEP,     /* . (Public Key Enc.)   */
    bltestRSA_PSS,      /* . (Public Key Sig.)   */
    bltestECDSA,        /* . (Public Key Sig.)   */
    bltestDSA,          /* . (Public Key Sig.)   */
    bltestMD2,          /* Hash algorithms       */
    bltestMD5,          /* .             */
    bltestSHA1,         /* .             */
    bltestSHA224,       /* .             */
    bltestSHA256,       /* .             */
    bltestSHA384,       /* .             */
    bltestSHA512,       /* .             */
    bltestSHA3_224,     /* .             */
    bltestSHA3_256,     /* .             */
    bltestSHA3_384,     /* .             */
    bltestSHA3_512,     /* .             */
    NUMMODES
} bltestCipherMode;

static char *mode_strings[] = {
    "des_ecb",
    "des_cbc",
    "des3_ecb",
    "des3_cbc",
#ifndef NSS_DISABLE_DEPRECATED_RC2
    "rc2_ecb",
    "rc2_cbc",
#endif
    "rc4",
#ifdef NSS_SOFTOKEN_DOES_RC5
    "rc5_ecb",
    "rc5_cbc",
#endif
    "aes_ecb",
    "aes_cbc",
    "aes_cts",
    "aes_ctr",
    "aes_gcm",
    "camellia_ecb",
    "camellia_cbc",
#ifndef NSS_DISABLE_DEPRECATED_SEED
    "seed_ecb",
    "seed_cbc",
#endif
    "chacha20_ctr",
    "chacha20_poly1305",
    "rsa",
    "rsa_oaep",
    "rsa_pss",
    "ecdsa",
    /*"pqg",*/
    "dsa",
    "md2",
    "md5",
    "sha1",
    "sha224",
    "sha256",
    "sha384",
    "sha512",
    "sha3_224",
    "sha3_256",
    "sha3_384",
    "sha3_512",
};

typedef struct
{
    bltestIO key;
    bltestIO iv;
} bltestSymmKeyParams;

typedef struct
{
    bltestSymmKeyParams sk; /* must be first */
    bltestIO aad;
} bltestAuthSymmKeyParams;

typedef struct
{
    bltestIO key;
    bltestIO iv;
    int rounds;
    int wordsize;
} bltestRC5Params;

typedef struct
{
    bltestIO key;
    int keysizeInBits;

    /* OAEP & PSS */
    HASH_HashType hashAlg;
    HASH_HashType maskHashAlg;
    bltestIO seed; /* salt if PSS */
} bltestRSAParams;

typedef struct
{
    bltestIO pqgdata;
    unsigned int keysize;
    bltestIO keyseed;
    bltestIO sigseed;
    PQGParams *pqg;
} bltestDSAParams;

typedef struct
{
    char *curveName;
    bltestIO sigseed;
} bltestECDSAParams;

typedef struct
{
    bltestIO key;
    void *privKey;
    void *pubKey;
    bltestIO sig; /* if doing verify, the signature (which may come
                   * from sigfile. */


    union {
        bltestRSAParams rsa;
        bltestDSAParams dsa;
        bltestECDSAParams ecdsa;
    } cipherParams;
} bltestAsymKeyParams;

typedef struct
{
    bltestIO key; /* unused */
    PRBool restart;
} bltestHashParams;

typedef union {
    bltestIO key;
    bltestSymmKeyParams sk;
    bltestAuthSymmKeyParams ask;
    bltestRC5Params rc5;
    bltestAsymKeyParams asymk;
    bltestHashParams hash;
} bltestParams;

typedef struct bltestCipherInfoStr bltestCipherInfo;

struct bltestCipherInfoStr {
    PLArenaPool *arena;
    /* link to next in multithreaded test */
    bltestCipherInfo *next;
    PRThread *cipherThread;

    /* MonteCarlo test flag*/
    PRBool mCarlo;
    /* cipher context */
    void *cx;
    /* I/O streams */
    bltestIO input;
    bltestIO output;
    /* Cipher-specific parameters */
    bltestParams params;
    /* Cipher mode */
    bltestCipherMode mode;
    /* Cipher function (encrypt/decrypt/sign/verify/hash) */
    union {
        bltestSymmCipherFn symmkeyCipher;
        bltestAEADFn aeadCipher;
        bltestPubKeyCipherFn pubkeyCipher;
        bltestHashCipherFn hashCipher;
    } cipher;
    /* performance testing */
    int repetitionsToPerfom;
    int seconds;
    int repetitions;
    int cxreps;
    double cxtime;
    double optime;
};

PRBool
is_symmkeyCipher(bltestCipherMode mode)
{
    /* change as needed! */
    if (mode >= bltestDES_ECB && mode <= bltestCHACHA20_CTR)
        return PR_TRUE;
    return PR_FALSE;
}

PRBool
is_aeadCipher(bltestCipherMode mode)
{
    /* change as needed! */
    switch (mode) {
        case bltestCHACHA20:
            return PR_TRUE;
        default:
            return PR_FALSE;
    }
}

PRBool
is_authCipher(bltestCipherMode mode)
{
    /* change as needed! */
    switch (mode) {
        case bltestAES_GCM:
        case bltestCHACHA20:
            return PR_TRUE;
        default:
            return PR_FALSE;
    }
}

PRBool
is_singleShotCipher(bltestCipherMode mode)
{
    /* change as needed! */
    switch (mode) {
        case bltestAES_GCM:
        case bltestAES_CTS:
        case bltestCHACHA20_CTR:
        case bltestCHACHA20:
            return PR_TRUE;
        default:
            return PR_FALSE;
    }
}

PRBool
is_pubkeyCipher(bltestCipherMode mode)
{
    /* change as needed! */
    if (mode >= bltestRSA && mode <= bltestDSA)
        return PR_TRUE;
    return PR_FALSE;
}

PRBool
is_hashCipher(bltestCipherMode mode)
{
    /* change as needed! */
    if (mode >= bltestMD2 && mode <= bltestSHA3_512)
        return PR_TRUE;
    return PR_FALSE;
}

PRBool
is_sigCipher(bltestCipherMode mode)
{
    /* change as needed! */
    if (mode >= bltestRSA_PSS && mode <= bltestDSA)
        return PR_TRUE;
    return PR_FALSE;
}

PRBool
cipher_requires_IV(bltestCipherMode mode)
{
    /* change as needed! */
    switch (mode) {
        case bltestDES_CBC:
        case bltestDES_EDE_CBC:
#ifndef NSS_DISABLE_DEPRECATED_RC2
        case bltestRC2_CBC:
#endif
#ifdef NSS_SOFTOKEN_DOES_RC5
        case bltestRC5_CBC:
#endif
        case bltestAES_CBC:
        case bltestAES_CTS:
        case bltestAES_CTR:
        case bltestAES_GCM:
        case bltestCAMELLIA_CBC:
#ifndef NSS_DISABLE_DEPRECATED_SEED
        case bltestSEED_CBC:
#endif
        case bltestCHACHA20_CTR:
        case bltestCHACHA20:
            return PR_TRUE;
        default:
            return PR_FALSE;
    }
}

SECStatus finishIO(bltestIO *output, PRFileDesc *file);

SECStatus
setupIO(PLArenaPool *arena, bltestIO *input, PRFileDesc *file,
        char *str, int numBytes)
{
    SECStatus rv = SECSuccess;
    SECItem fileData;
    SECItem *in;
    unsigned char *tok;
    unsigned int i, j;
    PRBool needToFreeFile = PR_FALSE;

    if (file && (numBytes == 0 || file == PR_STDIN)) {
        /* grabbing data from a file */
        rv = SECU_FileToItem(&fileData, file);
        if (rv != SECSuccess)
            return SECFailure;
        in = &fileData;
        needToFreeFile = PR_TRUE;
    } else if (str) {
        /* grabbing data from command line */
        fileData.data = (unsigned char *)str;
        fileData.len = PL_strlen(str);
        in = &fileData;
    } else if (file) {
        /* create nonce */
        SECITEM_AllocItem(arena, &input->buf, numBytes);
        RNG_GenerateGlobalRandomBytes(input->buf.data, numBytes);
        return finishIO(input, file);
    } else {
        return SECFailure;
    }

    switch (input->mode) {
        case bltestBase64Encoded:
            if (in->len == 0) {
                input->buf.data = NULL;
                input->buf.len = 0;
                break;
            }
            rv = atob(in, &input->buf, arena);
            break;
        case bltestBinary:
            if (in->len == 0) {
                input->buf.data = NULL;
                input->buf.len = 0;
                break;
            }
            if (in->data[in->len - 1] == '\n')
                --in->len;
            if (in->data[in->len - 1] == '\r')
                --in->len;
            rv = SECITEM_CopyItem(arena, &input->buf, in);
            break;
        case bltestHexSpaceDelim:
            SECITEM_AllocItem(arena, &input->buf, in->len / 5);
            for (i = 0, j = 0; i < in->len; i += 5, j++) {
                tok = &in->data[i];
                if (tok[0] != '0' || tok[1] != 'x' || tok[4] != ' ')
                    /* bad hex token */
                    break;

                rv = hex_from_2char(&tok[2], input->buf.data + j);
                if (rv)
                    break;
            }
            break;
        case bltestHexStream:
            SECITEM_AllocItem(arena, &input->buf, in->len / 2);
            for (i = 0, j = 0; i < in->len; i += 2, j++) {
                tok = &in->data[i];
                rv = hex_from_2char(tok, input->buf.data + j);
                if (rv)
                    break;
            }
            break;
    }

    if (needToFreeFile)
        SECITEM_FreeItem(&fileData, PR_FALSE);
    return rv;
}

SECStatus
finishIO(bltestIO *output, PRFileDesc *file)
{
    SECStatus rv = SECSuccess;
    PRInt32 nb;
    unsigned char byteval;
    SECItem *it;
    char hexstr[5];
    unsigned int i;
    if (output->pBuf.len > 0) {
        it = &output->pBuf;
    } else {
        it = &output->buf;
    }
    switch (output->mode) {
        case bltestBase64Encoded:
            rv = btoa_file(it, file);
            break;
        case bltestBinary:
            nb = PR_Write(file, it->data, it->len);
            rv = (nb == (PRInt32)it->len) ? SECSuccess : SECFailure;
            break;
        case bltestHexSpaceDelim:
            hexstr[0] = '0';
            hexstr[1] = 'x';
            hexstr[4] = ' ';
            for (i = 0; i < it->len; i++) {
                byteval = it->data[i];
                rv = char2_from_hex(byteval, hexstr + 2);
                nb = PR_Write(file, hexstr, 5);
                if (rv)
                    break;
            }
            PR_Write(file, "\n", 1);
            break;
        case bltestHexStream:
            for (i = 0; i < it->len; i++) {
                byteval = it->data[i];
                rv = char2_from_hex(byteval, hexstr);
                if (rv)
                    break;
                nb = PR_Write(file, hexstr, 2);
            }
            PR_Write(file, "\n", 1);
            break;
    }
    return rv;
}

SECStatus
bltestCopyIO(PLArenaPool *arena, bltestIO *dest, bltestIO *src)
{
    if (SECITEM_CopyItem(arena, &dest->buf, &src->buf) != SECSuccess) {
        return SECFailure;
    }
    if (src->pBuf.len > 0) {
        dest->pBuf.len = src->pBuf.len;
        dest->pBuf.data = dest->buf.data + (src->pBuf.data - src->buf.data);
    }
    dest->mode = src->mode;
    dest->file = src->file;

    return SECSuccess;
}

void
misalignBuffer(PLArenaPool *arena, bltestIO *io, int off)
{
    ptrdiff_t offset = (ptrdiff_t)io->buf.data % WORDSIZE;
    int length = io->buf.len;
    if (offset != off) {
        SECITEM_ReallocItemV2(arena, &io->buf, length + 2 * WORDSIZE);
        /* offset may have changed? */
        offset = (ptrdiff_t)io->buf.data % WORDSIZE;
        if (offset != off) {
            memmove(io->buf.data + off, io->buf.data, length);
            io->pBuf.data = io->buf.data + off;
            io->pBuf.len = length;
        } else {
            io->pBuf.data = io->buf.data;
            io->pBuf.len = length;
        }
    } else {
        io->pBuf.data = io->buf.data;
        io->pBuf.len = length;
    }
}

SECStatus
des_Encrypt(void *cx, unsigned char *output, unsigned int *outputLen,
            unsigned int maxOutputLen, const unsigned char *input,
            unsigned int inputLen)
{
    return DES_Encrypt((DESContext *)cx, output, outputLen, maxOutputLen,
                       input, inputLen);
}

SECStatus
des_Decrypt(void *cx, unsigned char *output, unsigned int *outputLen,
            unsigned int maxOutputLen, const unsigned char *input,
            unsigned int inputLen)
{
    return DES_Decrypt((DESContext *)cx, output, outputLen, maxOutputLen,
                       input, inputLen);
}

#ifndef NSS_DISABLE_DEPRECATED_RC2
SECStatus
rc2_Encrypt(void *cx, unsigned char *output, unsigned int *outputLen,
            unsigned int maxOutputLen, const unsigned char *input,
            unsigned int inputLen)
{
    return RC2_Encrypt((RC2Context *)cx, output, outputLen, maxOutputLen,
                       input, inputLen);
}

SECStatus
rc2_Decrypt(void *cx, unsigned char *output, unsigned int *outputLen,
            unsigned int maxOutputLen, const unsigned char *input,
            unsigned int inputLen)
{
    return RC2_Decrypt((RC2Context *)cx, output, outputLen, maxOutputLen,
                       input, inputLen);
}
#endif /* NSS_DISABLE_DEPRECATED_RC2 */

SECStatus
rc4_Encrypt(void *cx, unsigned char *output, unsigned int *outputLen,
            unsigned int maxOutputLen, const unsigned char *input,
            unsigned int inputLen)
{
    return RC4_Encrypt((RC4Context *)cx, output, outputLen, maxOutputLen,
                       input, inputLen);
}

SECStatus
rc4_Decrypt(void *cx, unsigned char *output, unsigned int *outputLen,
            unsigned int maxOutputLen, const unsigned char *input,
            unsigned int inputLen)
{
    return RC4_Decrypt((RC4Context *)cx, output, outputLen, maxOutputLen,
                       input, inputLen);
}

SECStatus
aes_Encrypt(void *cx, unsigned char *output, unsigned int *outputLen,
            unsigned int maxOutputLen, const unsigned char *input,
            unsigned int inputLen)
{
    return AES_Encrypt((AESContext *)cx, output, outputLen, maxOutputLen,
                       input, inputLen);
}

SECStatus
aes_Decrypt(void *cx, unsigned char *output, unsigned int *outputLen,
            unsigned int maxOutputLen, const unsigned char *input,
            unsigned int inputLen)
{
    return AES_Decrypt((AESContext *)cx, output, outputLen, maxOutputLen,
                       input, inputLen);
}

SECStatus
chacha20_Encrypt(void *cx, unsigned char *output, unsigned int *outputLen,
                 unsigned int maxOutputLen, const unsigned char *input,
                 unsigned int inputLen)
{
    if (maxOutputLen < inputLen) {
        PORT_SetError(SEC_ERROR_OUTPUT_LEN);
        return SECFailure;
    }
    ChaCha20Context *ctx = cx;
    *outputLen = inputLen;
    return ChaCha20_Xor(output, input, inputLen, ctx->key, ctx->nonce,
                        ctx->counter);
}

SECStatus
chacha20_poly1305_Encrypt(void *cx, unsigned char *output,
                          unsigned int *outputLen, unsigned int maxOutputLen,
                          const unsigned char *input, unsigned int inputLen,
                          const unsigned char *nonce, unsigned int nonceLen,
                          const unsigned char *ad, unsigned int adLen)
{
    return ChaCha20Poly1305_Seal((ChaCha20Poly1305Context *)cx, output,
                                 outputLen, maxOutputLen, input, inputLen,
                                 nonce, nonceLen, ad, adLen);
}

SECStatus
chacha20_poly1305_Decrypt(void *cx, unsigned char *output,
                          unsigned int *outputLen, unsigned int maxOutputLen,
                          const unsigned char *input, unsigned int inputLen,
                          const unsigned char *nonce, unsigned int nonceLen,
                          const unsigned char *ad, unsigned int adLen)
{
    return ChaCha20Poly1305_Open((ChaCha20Poly1305Context *)cx, output,
                                 outputLen, maxOutputLen, input, inputLen,
                                 nonce, nonceLen, ad, adLen);
}

SECStatus
camellia_Encrypt(void *cx, unsigned char *output, unsigned int *outputLen,
                 unsigned int maxOutputLen, const unsigned char *input,
                 unsigned int inputLen)
{
    return Camellia_Encrypt((CamelliaContext *)cx, output, outputLen,
                            maxOutputLen,
                            input, inputLen);
}

SECStatus
camellia_Decrypt(void *cx, unsigned char *output, unsigned int *outputLen,
                 unsigned int maxOutputLen, const unsigned char *input,
                 unsigned int inputLen)
{
    return Camellia_Decrypt((CamelliaContext *)cx, output, outputLen,
                            maxOutputLen,
                            input, inputLen);
}

#ifndef NSS_DISABLE_DEPRECATED_SEED
SECStatus
seed_Encrypt(void *cx, unsigned char *output, unsigned int *outputLen,
             unsigned int maxOutputLen, const unsigned char *input,
             unsigned int inputLen)
{
    return SEED_Encrypt((SEEDContext *)cx, output, outputLen, maxOutputLen,
                        input, inputLen);
}

SECStatus
seed_Decrypt(void *cx, unsigned char *output, unsigned int *outputLen,
             unsigned int maxOutputLen, const unsigned char *input,
             unsigned int inputLen)
{
    return SEED_Decrypt((SEEDContext *)cx, output, outputLen, maxOutputLen,
                        input, inputLen);
}
#endif /* NSS_DISABLE_DEPRECATED_SEED */

SECStatus
rsa_PublicKeyOp(void *cx, SECItem *output, const SECItem *input)
{
    bltestAsymKeyParams *params = (bltestAsymKeyParams *)cx;
    RSAPublicKey *pubKey = (RSAPublicKey *)params->pubKey;
    SECStatus rv = RSA_PublicKeyOp(pubKey, output->data, input->data);
    if (rv == SECSuccess) {
        output->len = pubKey->modulus.data[0] ? pubKey->modulus.len : pubKey->modulus.len - 1;
    }
    return rv;
}

SECStatus
rsa_PrivateKeyOp(void *cx, SECItem *output, const SECItem *input)
{
    bltestAsymKeyParams *params = (bltestAsymKeyParams *)cx;
    RSAPrivateKey *privKey = (RSAPrivateKey *)params->privKey;
    SECStatus rv = RSA_PrivateKeyOp(privKey, output->data, input->data);
    if (rv == SECSuccess) {
        output->len = privKey->modulus.data[0] ? privKey->modulus.len : privKey->modulus.len - 1;
    }
    return rv;
}

SECStatus
rsa_signDigestPSS(void *cx, SECItem *output, const SECItem *input)
{
    bltestAsymKeyParams *params = (bltestAsymKeyParams *)cx;
    bltestRSAParams *rsaParams = ¶ms->cipherParams.rsa;
    return RSA_SignPSS((RSAPrivateKey *)params->privKey,
                       rsaParams->hashAlg,
                       rsaParams->maskHashAlg,
                       rsaParams->seed.buf.data,
                       rsaParams->seed.buf.len,
                       output->data, &output->len, output->len,
                       input->data, input->len);
}

SECStatus
rsa_verifyDigestPSS(void *cx, SECItem *output, const SECItem *input)
{
    bltestAsymKeyParams *params = (bltestAsymKeyParams *)cx;
    bltestRSAParams *rsaParams = ¶ms->cipherParams.rsa;
    return RSA_CheckSignPSS((RSAPublicKey *)params->pubKey,
                            rsaParams->hashAlg,
                            rsaParams->maskHashAlg,
                            rsaParams->seed.buf.len,
                            output->data, output->len,
                            input->data, input->len);
}

SECStatus
rsa_encryptOAEP(void *cx, SECItem *output, const SECItem *input)
{
    bltestAsymKeyParams *params = (bltestAsymKeyParams *)cx;
    bltestRSAParams *rsaParams = ¶ms->cipherParams.rsa;
    return RSA_EncryptOAEP((RSAPublicKey *)params->pubKey,
                           rsaParams->hashAlg,
                           rsaParams->maskHashAlg,
                           NULL, 0,
                           rsaParams->seed.buf.data,
                           rsaParams->seed.buf.len,
                           output->data, &output->len, output->len,
                           input->data, input->len);
}

SECStatus
rsa_decryptOAEP(void *cx, SECItem *output, const SECItem *input)
{
    bltestAsymKeyParams *params = (bltestAsymKeyParams *)cx;
    bltestRSAParams *rsaParams = ¶ms->cipherParams.rsa;
    return RSA_DecryptOAEP((RSAPrivateKey *)params->privKey,
                           rsaParams->hashAlg,
                           rsaParams->maskHashAlg,
                           NULL, 0,
                           output->data, &output->len, output->len,
                           input->data, input->len);
}

SECStatus
dsa_signDigest(void *cx, SECItem *output, const SECItem *input)
{
    bltestAsymKeyParams *params = (bltestAsymKeyParams *)cx;
    if (params->cipherParams.dsa.sigseed.buf.len > 0) {
        return DSA_SignDigestWithSeed((DSAPrivateKey *)params->privKey,
                                      output, input,
                                      params->cipherParams.dsa.sigseed.buf.data);
    }
    return DSA_SignDigest((DSAPrivateKey *)params->privKey, output, input);
}

SECStatus
dsa_verifyDigest(void *cx, SECItem *output, const SECItem *input)
{
    bltestAsymKeyParams *params = (bltestAsymKeyParams *)cx;
    return DSA_VerifyDigest((DSAPublicKey *)params->pubKey, output, input);
}

SECStatus
ecdsa_signDigest(void *cx, SECItem *output, const SECItem *input)
{
    bltestAsymKeyParams *params = (bltestAsymKeyParams *)cx;
    if (params->cipherParams.ecdsa.sigseed.buf.len > 0) {
        return ECDSA_SignDigestWithSeed(
            (ECPrivateKey *)params->privKey,
            output, input,
            params->cipherParams.ecdsa.sigseed.buf.data,
            params->cipherParams.ecdsa.sigseed.buf.len);
    }
    return ECDSA_SignDigest((ECPrivateKey *)params->privKey, output, input);
}

SECStatus
ecdsa_verifyDigest(void *cx, SECItem *output, const SECItem *input)
{
    bltestAsymKeyParams *params = (bltestAsymKeyParams *)cx;
    return ECDSA_VerifyDigest((ECPublicKey *)params->pubKey, output, input);
}

SECStatus
bltest_des_init(bltestCipherInfo *cipherInfo, PRBool encrypt)
{
    PRIntervalTime time1, time2;
    bltestSymmKeyParams *desp = &cipherInfo->params.sk;
    int minorMode;
    int i;
    switch (cipherInfo->mode) {
        case bltestDES_ECB:
            minorMode = NSS_DES;
            break;
        case bltestDES_CBC:
            minorMode = NSS_DES_CBC;
            break;
        case bltestDES_EDE_ECB:
            minorMode = NSS_DES_EDE3;
            break;
        case bltestDES_EDE_CBC:
            minorMode = NSS_DES_EDE3_CBC;
            break;
        default:
            return SECFailure;
    }
    cipherInfo->cx = (void *)DES_CreateContext(desp->key.buf.data,
                                               desp->iv.buf.data,
                                               minorMode, encrypt);
    if (cipherInfo->cxreps > 0) {
        DESContext **dummycx;
        dummycx = PORT_Alloc(cipherInfo->cxreps * sizeof(DESContext *));
        TIMESTART();
        for (i = 0; i < cipherInfo->cxreps; i++) {
            dummycx[i] = (void *)DES_CreateContext(desp->key.buf.data,
                                                   desp->iv.buf.data,
                                                   minorMode, encrypt);
        }
        TIMEFINISH(cipherInfo->cxtime, 1.0);
        for (i = 0; i < cipherInfo->cxreps; i++) {
            DES_DestroyContext(dummycx[i], PR_TRUE);
        }
        PORT_Free(dummycx);
    }
    if (encrypt)
        cipherInfo->cipher.symmkeyCipher = des_Encrypt;
    else
        cipherInfo->cipher.symmkeyCipher = des_Decrypt;
    return SECSuccess;
}

#ifndef NSS_DISABLE_DEPRECATED_RC2
SECStatus
bltest_rc2_init(bltestCipherInfo *cipherInfo, PRBool encrypt)
{
    PRIntervalTime time1, time2;
    bltestSymmKeyParams *rc2p = &cipherInfo->params.sk;
    int minorMode;
    int i;
    switch (cipherInfo->mode) {
        case bltestRC2_ECB:
            minorMode = NSS_RC2;
            break;
        case bltestRC2_CBC:
            minorMode = NSS_RC2_CBC;
            break;
        default:
            return SECFailure;
    }
    cipherInfo->cx = (void *)RC2_CreateContext(rc2p->key.buf.data,
                                               rc2p->key.buf.len,
                                               rc2p->iv.buf.data,
                                               minorMode,
                                               rc2p->key.buf.len);
    if (cipherInfo->cxreps > 0) {
        RC2Context **dummycx;
        dummycx = PORT_Alloc(cipherInfo->cxreps * sizeof(RC2Context *));
        TIMESTART();
        for (i = 0; i < cipherInfo->cxreps; i++) {
            dummycx[i] = (void *)RC2_CreateContext(rc2p->key.buf.data,
                                                   rc2p->key.buf.len,
                                                   rc2p->iv.buf.data,
                                                   minorMode,
                                                   rc2p->key.buf.len);
        }
        TIMEFINISH(cipherInfo->cxtime, 1.0);
        for (i = 0; i < cipherInfo->cxreps; i++) {
            RC2_DestroyContext(dummycx[i], PR_TRUE);
        }
        PORT_Free(dummycx);
    }
    if (encrypt)
        cipherInfo->cipher.symmkeyCipher = rc2_Encrypt;
    else
        cipherInfo->cipher.symmkeyCipher = rc2_Decrypt;
    return SECSuccess;
}
#endif /* NSS_DISABLE_DEPRECATED_RC2 */

SECStatus
bltest_rc4_init(bltestCipherInfo *cipherInfo, PRBool encrypt)
{
    PRIntervalTime time1, time2;
    int i;
    bltestSymmKeyParams *rc4p = &cipherInfo->params.sk;
    cipherInfo->cx = (void *)RC4_CreateContext(rc4p->key.buf.data,
                                               rc4p->key.buf.len);
    if (cipherInfo->cxreps > 0) {
        RC4Context **dummycx;
        dummycx = PORT_Alloc(cipherInfo->cxreps * sizeof(RC4Context *));
        TIMESTART();
        for (i = 0; i < cipherInfo->cxreps; i++) {
            dummycx[i] = (void *)RC4_CreateContext(rc4p->key.buf.data,
                                                   rc4p->key.buf.len);
        }
        TIMEFINISH(cipherInfo->cxtime, 1.0);
        for (i = 0; i < cipherInfo->cxreps; i++) {
            RC4_DestroyContext(dummycx[i], PR_TRUE);
        }
        PORT_Free(dummycx);
    }
    if (encrypt)
        cipherInfo->cipher.symmkeyCipher = rc4_Encrypt;
    else
        cipherInfo->cipher.symmkeyCipher = rc4_Decrypt;
    return SECSuccess;
}

SECStatus
bltest_rc5_init(bltestCipherInfo *cipherInfo, PRBool encrypt)
{
#ifdef NSS_SOFTOKEN_DOES_RC5
    PRIntervalTime time1, time2;
    bltestRC5Params *rc5p = &cipherInfo->params.rc5;
    int minorMode;
    switch (cipherInfo->mode) {
        case bltestRC5_ECB:
            minorMode = NSS_RC5;
            break;
        case bltestRC5_CBC:
            minorMode = NSS_RC5_CBC;
            break;
        default:
            return SECFailure;
    }
    TIMESTART();
    cipherInfo->cx = (void *)RC5_CreateContext(&rc5p->key.buf,
                                               rc5p->rounds, rc5p->wordsize,
                                               rc5p->iv.buf.data, minorMode);
    TIMEFINISH(cipherInfo->cxtime, 1.0);
    if (encrypt)
        cipherInfo->cipher.symmkeyCipher = RC5_Encrypt;
    else
        cipherInfo->cipher.symmkeyCipher = RC5_Decrypt;
    return SECSuccess;
#else
    return SECFailure;
#endif
}

SECStatus
bltest_aes_init(bltestCipherInfo *cipherInfo, PRBool encrypt)
{
    bltestSymmKeyParams *aesp = &cipherInfo->params.sk;
    bltestAuthSymmKeyParams *gcmp = &cipherInfo->params.ask;
    int minorMode;
    int i;
    int keylen = aesp->key.buf.len;
    unsigned int blocklen = AES_BLOCK_SIZE;
    PRIntervalTime time1, time2;
    unsigned char *params;
    int len;
    CK_AES_CTR_PARAMS ctrParams;
    CK_NSS_GCM_PARAMS gcmParams;

    params = aesp->iv.buf.data;
    switch (cipherInfo->mode) {
        case bltestAES_ECB:
            minorMode = NSS_AES;
            break;
        case bltestAES_CBC:
            minorMode = NSS_AES_CBC;
            break;
        case bltestAES_CTS:
            minorMode = NSS_AES_CTS;
            break;
        case bltestAES_CTR:
            minorMode = NSS_AES_CTR;
            ctrParams.ulCounterBits = 32;
            len = PR_MIN(aesp->iv.buf.len, blocklen);
            PORT_Memset(ctrParams.cb, 0, blocklen);
            PORT_Memcpy(ctrParams.cb, aesp->iv.buf.data, len);
            params = (unsigned char *)&ctrParams;
            break;
        case bltestAES_GCM:
            minorMode = NSS_AES_GCM;
            gcmParams.pIv = gcmp->sk.iv.buf.data;
            gcmParams.ulIvLen = gcmp->sk.iv.buf.len;
            gcmParams.pAAD = gcmp->aad.buf.data;
            gcmParams.ulAADLen = gcmp->aad.buf.len;
            gcmParams.ulTagBits = blocklen * 8;
            params = (unsigned char *)&gcmParams;
            break;
        default:
            return SECFailure;
    }
    cipherInfo->cx = (void *)AES_CreateContext(aesp->key.buf.data,
                                               params,
                                               minorMode, encrypt,
                                               keylen, blocklen);
    if (cipherInfo->cxreps > 0) {
        AESContext **dummycx;
        dummycx = PORT_Alloc(cipherInfo->cxreps * sizeof(AESContext *));
        TIMESTART();
        for (i = 0; i < cipherInfo->cxreps; i++) {
            dummycx[i] = (void *)AES_CreateContext(aesp->key.buf.data,
                                                   params,
                                                   minorMode, encrypt,
                                                   keylen, blocklen);
        }
        TIMEFINISH(cipherInfo->cxtime, 1.0);
        for (i = 0; i < cipherInfo->cxreps; i++) {
            AES_DestroyContext(dummycx[i], PR_TRUE);
        }
        PORT_Free(dummycx);
    }
    if (encrypt)
        cipherInfo->cipher.symmkeyCipher = aes_Encrypt;
    else
        cipherInfo->cipher.symmkeyCipher = aes_Decrypt;
    return SECSuccess;
}

SECStatus
bltest_camellia_init(bltestCipherInfo *cipherInfo, PRBool encrypt)
{
    bltestSymmKeyParams *camelliap = &cipherInfo->params.sk;
    int minorMode;
    int i;
    int keylen = camelliap->key.buf.len;
    PRIntervalTime time1, time2;

    switch (cipherInfo->mode) {
        case bltestCAMELLIA_ECB:
            minorMode = NSS_CAMELLIA;
            break;
        case bltestCAMELLIA_CBC:
            minorMode = NSS_CAMELLIA_CBC;
            break;
        default:
            return SECFailure;
    }
    cipherInfo->cx = (void *)Camellia_CreateContext(camelliap->key.buf.data,
                                                    camelliap->iv.buf.data,
                                                    minorMode, encrypt,
                                                    keylen);
    if (cipherInfo->cxreps > 0) {
        CamelliaContext **dummycx;
        dummycx = PORT_Alloc(cipherInfo->cxreps * sizeof(CamelliaContext *));
        TIMESTART();
        for (i = 0; i < cipherInfo->cxreps; i++) {
            dummycx[i] = (void *)Camellia_CreateContext(camelliap->key.buf.data,
                                                        camelliap->iv.buf.data,
                                                        minorMode, encrypt,
                                                        keylen);
        }
        TIMEFINISH(cipherInfo->cxtime, 1.0);
        for (i = 0; i < cipherInfo->cxreps; i++) {
            Camellia_DestroyContext(dummycx[i], PR_TRUE);
        }
        PORT_Free(dummycx);
    }
    if (encrypt)
        cipherInfo->cipher.symmkeyCipher = camellia_Encrypt;
    else
        cipherInfo->cipher.symmkeyCipher = camellia_Decrypt;
    return SECSuccess;
}

#ifndef NSS_DISABLE_DEPRECATED_SEED
SECStatus
bltest_seed_init(bltestCipherInfo *cipherInfo, PRBool encrypt)
{
    PRIntervalTime time1, time2;
    bltestSymmKeyParams *seedp = &cipherInfo->params.sk;
    int minorMode;
    int i;

    switch (cipherInfo->mode) {
        case bltestSEED_ECB:
            minorMode = NSS_SEED;
            break;
        case bltestSEED_CBC:
            minorMode = NSS_SEED_CBC;
            break;
        default:
            return SECFailure;
    }
    cipherInfo->cx = (void *)SEED_CreateContext(seedp->key.buf.data,
                                                seedp->iv.buf.data,
                                                minorMode, encrypt);
    if (cipherInfo->cxreps > 0) {
        SEEDContext **dummycx;
        dummycx = PORT_Alloc(cipherInfo->cxreps * sizeof(SEEDContext *));
        TIMESTART();
        for (i = 0; i < cipherInfo->cxreps; i++) {
            dummycx[i] = (void *)SEED_CreateContext(seedp->key.buf.data,
                                                    seedp->iv.buf.data,
                                                    minorMode, encrypt);
        }
        TIMEFINISH(cipherInfo->cxtime, 1.0);
        for (i = 0; i < cipherInfo->cxreps; i++) {
            SEED_DestroyContext(dummycx[i], PR_TRUE);
        }
        PORT_Free(dummycx);
    }
    if (encrypt)
        cipherInfo->cipher.symmkeyCipher = seed_Encrypt;
    else
        cipherInfo->cipher.symmkeyCipher = seed_Decrypt;

    return SECSuccess;
}
#endif /* NSS_DISABLE_DEPRECATED_SEED */

SECStatus
bltest_chacha20_ctr_init(bltestCipherInfo *cipherInfo, PRBool encrypt)
{
    const PRUint32 counter = 1;
    bltestSymmKeyParams *sk = &cipherInfo->params.sk;
    cipherInfo->cx = ChaCha20_CreateContext(sk->key.buf.data, sk->key.buf.len,
                                            sk->iv.buf.data, sk->iv.buf.len,
                                            counter);

    if (cipherInfo->cx == NULL) {
        PR_fprintf(PR_STDERR, "ChaCha20_CreateContext() returned NULL\n"
                              "key must be 32 bytes, iv must be 12 bytes\n");
        return SECFailure;
    }
    cipherInfo->cipher.symmkeyCipher = chacha20_Encrypt;
    return SECSuccess;
}

SECStatus
bltest_chacha20_init(bltestCipherInfo *cipherInfo, PRBool encrypt)
{
    const unsigned int tagLen = 16;
    const bltestSymmKeyParams *sk = &cipherInfo->params.sk;
    cipherInfo->cx = ChaCha20Poly1305_CreateContext(sk->key.buf.data,
                                                    sk->key.buf.len, tagLen);

    if (encrypt)
        cipherInfo->cipher.aeadCipher = chacha20_poly1305_Encrypt;
    else
        cipherInfo->cipher.aeadCipher = chacha20_poly1305_Decrypt;
    return SECSuccess;
}

SECStatus
bltest_rsa_init(bltestCipherInfo *cipherInfo, PRBool encrypt)
{
    int i;
    RSAPrivateKey **dummyKey;
    RSAPrivateKey *privKey;
    RSAPublicKey *pubKey;
    PRIntervalTime time1, time2;

    bltestAsymKeyParams *asymk = &cipherInfo->params.asymk;
    bltestRSAParams *rsap = &asymk->cipherParams.rsa;

    /* RSA key gen was done during parameter setup */
    cipherInfo->cx = asymk;
    privKey = (RSAPrivateKey *)asymk->privKey;

    /* For performance testing */
    if (cipherInfo->cxreps > 0) {
        /* Create space for n private key objects */
        dummyKey = (RSAPrivateKey **)PORT_Alloc(cipherInfo->cxreps *
                                                sizeof(RSAPrivateKey *));
        /* Time n keygens, storing in the array */
        TIMESTART();
        for (i = 0; i < cipherInfo->cxreps; i++)
            dummyKey[i] = RSA_NewKey(rsap->keysizeInBits,
                                     &privKey->publicExponent);
        TIMEFINISH(cipherInfo->cxtime, cipherInfo->cxreps);
        /* Free the n key objects */
        for (i = 0; i < cipherInfo->cxreps; i++)
            PORT_FreeArena(dummyKey[i]->arena, PR_TRUE);
        PORT_Free(dummyKey);
    }

    if ((encrypt && !is_sigCipher(cipherInfo->mode)) ||
        (!encrypt && is_sigCipher(cipherInfo->mode))) {
        /* Have to convert private key to public key.  Memory
         * is freed with private key's arena  */

        pubKey = (RSAPublicKey *)PORT_ArenaAlloc(privKey->arena,
                                                 sizeof(RSAPublicKey));
        pubKey->modulus.len = privKey->modulus.len;
        pubKey->modulus.data = privKey->modulus.data;
        pubKey->publicExponent.len = privKey->publicExponent.len;
        pubKey->publicExponent.data = privKey->publicExponent.data;
        asymk->pubKey = (void *)pubKey;
    }
    switch (cipherInfo->mode) {
        case bltestRSA:
            cipherInfo->cipher.pubkeyCipher = encrypt ? rsa_PublicKeyOp
                                                      : rsa_PrivateKeyOp;
            break;
        case bltestRSA_PSS:
            cipherInfo->cipher.pubkeyCipher = encrypt ? rsa_signDigestPSS
                                                      : rsa_verifyDigestPSS;
            break;
        case bltestRSA_OAEP:
            cipherInfo->cipher.pubkeyCipher = encrypt ? rsa_encryptOAEP
                                                      : rsa_decryptOAEP;
            break;
        default:
            break;
    }
    return SECSuccess;
}

SECStatus
blapi_pqg_param_gen(unsigned int keysize, PQGParams **pqg, PQGVerify **vfy)
{
    if (keysize < 1024) {
        int j = PQG_PBITS_TO_INDEX(keysize);
        return PQG_ParamGen(j, pqg, vfy);
    }
    return PQG_ParamGenV2(keysize, 0, 0, pqg, vfy);
}

SECStatus
bltest_pqg_init(bltestDSAParams *dsap)
{
    SECStatus rv, res;
    PQGVerify *vfy = NULL;
    rv = blapi_pqg_param_gen(dsap->keysize, &dsap->pqg, &vfy);
    CHECKERROR(rv, __LINE__);
    rv = PQG_VerifyParams(dsap->pqg, vfy, &res);
    CHECKERROR(res, __LINE__);
    CHECKERROR(rv, __LINE__);
    return rv;
}

SECStatus
bltest_dsa_init(bltestCipherInfo *cipherInfo, PRBool encrypt)
{
    int i;
    DSAPrivateKey **dummyKey;
    PQGParams *dummypqg;
    PRIntervalTime time1, time2;
    bltestAsymKeyParams *asymk = &cipherInfo->params.asymk;
    bltestDSAParams *dsap = &asymk->cipherParams.dsa;
    PQGVerify *ignore = NULL;
    cipherInfo->cx = asymk;
    /* For performance testing */
    if (cipherInfo->cxreps > 0) {
        /* Create space for n private key objects */
        dummyKey = (DSAPrivateKey **)PORT_ZAlloc(cipherInfo->cxreps *
                                                 sizeof(DSAPrivateKey *));
        /* Time n keygens, storing in the array */
        TIMESTART();
        for (i = 0; i < cipherInfo->cxreps; i++) {
            dummypqg = NULL;
            blapi_pqg_param_gen(dsap->keysize, &dummypqg, &ignore);
            DSA_NewKey(dummypqg, &dummyKey[i]);
        }
        TIMEFINISH(cipherInfo->cxtime, cipherInfo->cxreps);
        /* Free the n key objects */
        for (i = 0; i < cipherInfo->cxreps; i++)
            PORT_FreeArena(dummyKey[i]->params.arena, PR_TRUE);
        PORT_Free(dummyKey);
    }
    if (!dsap->pqg && dsap->pqgdata.buf.len > 0) {
        dsap->pqg = pqg_from_filedata(cipherInfo->arena, &dsap->pqgdata.buf);
    }
    if (!asymk->privKey && asymk->key.buf.len > 0) {
        asymk->privKey = dsakey_from_filedata(cipherInfo->arena, &asymk->key.buf);
    }
    if (encrypt) {
        cipherInfo->cipher.pubkeyCipher = dsa_signDigest;
    } else {
        /* Have to convert private key to public key.  Memory
         * is freed with private key's arena  */

        DSAPublicKey *pubkey;
        DSAPrivateKey *key = (DSAPrivateKey *)asymk->privKey;
        pubkey = (DSAPublicKey *)PORT_ArenaZAlloc(key->params.arena,
                                                  sizeof(DSAPublicKey));
        pubkey->params.prime.len = key->params.prime.len;
        pubkey->params.prime.data = key->params.prime.data;
        pubkey->params.subPrime.len = key->params.subPrime.len;
        pubkey->params.subPrime.data = key->params.subPrime.data;
        pubkey->params.base.len = key->params.base.len;
        pubkey->params.base.data = key->params.base.data;
        pubkey->publicValue.len = key->publicValue.len;
        pubkey->publicValue.data = key->publicValue.data;
        asymk->pubKey = pubkey;
        cipherInfo->cipher.pubkeyCipher = dsa_verifyDigest;
    }
    return SECSuccess;
}

SECStatus
bltest_ecdsa_init(bltestCipherInfo *cipherInfo, PRBool encrypt)
{
    int i;
    ECPrivateKey **dummyKey;
    PRIntervalTime time1, time2;
    bltestAsymKeyParams *asymk = &cipherInfo->params.asymk;
    cipherInfo->cx = asymk;
    /* For performance testing */
    if (cipherInfo->cxreps > 0) {
        /* Create space for n private key objects */
        dummyKey = (ECPrivateKey **)PORT_ZAlloc(cipherInfo->cxreps *
                                                sizeof(ECPrivateKey *));
        /* Time n keygens, storing in the array */
        TIMESTART();
        for (i = 0; i < cipherInfo->cxreps; i++) {
            EC_NewKey(&((ECPrivateKey *)asymk->privKey)->ecParams, &dummyKey[i]);
        }
        TIMEFINISH(cipherInfo->cxtime, cipherInfo->cxreps);
        /* Free the n key objects */
        for (i = 0; i < cipherInfo->cxreps; i++)
            PORT_FreeArena(dummyKey[i]->ecParams.arena, PR_TRUE);
        PORT_Free(dummyKey);
    }
    if (!asymk->privKey && asymk->key.buf.len > 0) {
        asymk->privKey = eckey_from_filedata(cipherInfo->arena, &asymk->key.buf);
    }
    if (encrypt) {
        cipherInfo->cipher.pubkeyCipher = ecdsa_signDigest;
    } else {
        /* Have to convert private key to public key.  Memory
         * is freed with private key's arena  */

        ECPublicKey *pubkey;
        ECPrivateKey *key = (ECPrivateKey *)asymk->privKey;
        pubkey = (ECPublicKey *)PORT_ArenaZAlloc(key->ecParams.arena,
                                                 sizeof(ECPublicKey));
        pubkey->ecParams.type = key->ecParams.type;
        pubkey->ecParams.fieldID.size = key->ecParams.fieldID.size;
        pubkey->ecParams.fieldID.type = key->ecParams.fieldID.type;
        pubkey->ecParams.fieldID.u.prime.len = key->ecParams.fieldID.u.prime.len;
        pubkey->ecParams.fieldID.u.prime.data = key->ecParams.fieldID.u.prime.data;
        pubkey->ecParams.fieldID.k1 = key->ecParams.fieldID.k1;
        pubkey->ecParams.fieldID.k2 = key->ecParams.fieldID.k2;
        pubkey->ecParams.fieldID.k3 = key->ecParams.fieldID.k3;
        pubkey->ecParams.curve.a.len = key->ecParams.curve.a.len;
        pubkey->ecParams.curve.a.data = key->ecParams.curve.a.data;
        pubkey->ecParams.curve.b.len = key->ecParams.curve.b.len;
        pubkey->ecParams.curve.b.data = key->ecParams.curve.b.data;
        pubkey->ecParams.curve.seed.len = key->ecParams.curve.seed.len;
        pubkey->ecParams.curve.seed.data = key->ecParams.curve.seed.data;
        pubkey->ecParams.base.len = key->ecParams.base.len;
        pubkey->ecParams.base.data = key->ecParams.base.data;
        pubkey->ecParams.order.len = key->ecParams.order.len;
        pubkey->ecParams.order.data = key->ecParams.order.data;
        pubkey->ecParams.cofactor = key->ecParams.cofactor;
        pubkey->ecParams.DEREncoding.len = key->ecParams.DEREncoding.len;
        pubkey->ecParams.DEREncoding.data = key->ecParams.DEREncoding.data;
        pubkey->ecParams.name = key->ecParams.name;
        pubkey->publicValue.len = key->publicValue.len;
--> --------------------

--> maximum size reached

--> --------------------

Messung V0.5
C=95 H=94 G=94

¤ Dauer der Verarbeitung: 0.25 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.