tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

blapitest.c (151723B)


      1 /* This Source Code Form is subject to the terms of the Mozilla Public
      2 * License, v. 2.0. If a copy of the MPL was not distributed with this
      3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      4 
      5 #include <stdio.h>
      6 #include <stdlib.h>
      7 
      8 #include "blapi.h"
      9 #include "secrng.h"
     10 #include "prmem.h"
     11 #include "prprf.h"
     12 #include "prtime.h"
     13 #include "prsystem.h"
     14 #include "plstr.h"
     15 #include "nssb64.h"
     16 #include "basicutil.h"
     17 #include "plgetopt.h"
     18 #include "softoken.h"
     19 #include "nspr.h"
     20 #include "secport.h"
     21 #include "secoid.h"
     22 #include "nssutil.h"
     23 #include "ecl-curve.h"
     24 #include "chacha20poly1305.h"
     25 
     26 #include "pkcs1_vectors.h"
     27 
     28 SECStatus EC_DecodeParams(const SECItem *encodedParams,
     29                          ECParams **ecparams);
     30 SECStatus EC_CopyParams(PLArenaPool *arena, ECParams *dstParams,
     31                        const ECParams *srcParams);
     32 
     33 char *progName;
     34 char *testdir = NULL;
     35 
     36 #define BLTEST_DEFAULT_CHUNKSIZE 4096
     37 
     38 #define WORDSIZE sizeof(unsigned long)
     39 
     40 #define CHECKERROR(rv, ln)                                               \
     41    if (rv) {                                                            \
     42        PRErrorCode prerror = PR_GetError();                             \
     43        PR_fprintf(PR_STDERR, "%s: ERR %d (%s) at line %d.\n", progName, \
     44                   prerror, PORT_ErrorToString(prerror), ln);            \
     45        exit(-1);                                                        \
     46    }
     47 
     48 /* Macros for performance timing. */
     49 #define TIMESTART() \
     50    time1 = PR_IntervalNow();
     51 
     52 #define TIMEFINISH(time, reps)                          \
     53    time2 = (PRIntervalTime)(PR_IntervalNow() - time1); \
     54    time1 = PR_IntervalToMilliseconds(time2);           \
     55    time = ((double)(time1)) / reps;
     56 
     57 #define TIMEMARK(seconds)                      \
     58    time1 = PR_SecondsToInterval(seconds);     \
     59    {                                          \
     60        PRInt64 tmp;                           \
     61        if (time2 == 0) {                      \
     62            time2 = 1;                         \
     63        }                                      \
     64        LL_DIV(tmp, time1, time2);             \
     65        if (tmp < 10) {                        \
     66            if (tmp == 0) {                    \
     67                opsBetweenChecks = 1;          \
     68            } else {                           \
     69                LL_L2I(opsBetweenChecks, tmp); \
     70            }                                  \
     71        } else {                               \
     72            opsBetweenChecks = 10;             \
     73        }                                      \
     74    }                                          \
     75    time2 = time1;                             \
     76    time1 = PR_IntervalNow();
     77 
     78 #define TIMETOFINISH() \
     79    PR_IntervalNow() - time1 >= time2
     80 
     81 static void
     82 Usage()
     83 {
     84 #define PRINTUSAGE(subject, option, predicate) \
     85    fprintf(stderr, "%10s %s\t%s\n", subject, option, predicate);
     86    fprintf(stderr, "\n");
     87    PRINTUSAGE(progName, "[-DEHSVR]", "List available cipher modes"); /* XXX */
     88    fprintf(stderr, "\n");
     89    PRINTUSAGE(progName, "-E -m mode ", "Encrypt a buffer");
     90    PRINTUSAGE("", "", "[-i plaintext] [-o ciphertext] [-k key] [-v iv]");
     91    PRINTUSAGE("", "", "[-b bufsize] [-g keysize] [-e exp] [-r rounds]");
     92    PRINTUSAGE("", "", "[-w wordsize] [-p repetitions | -5 time_interval]");
     93    PRINTUSAGE("", "", "[-4 th_num]");
     94    PRINTUSAGE("", "-m", "cipher mode to use");
     95    PRINTUSAGE("", "-i", "file which contains input buffer");
     96    PRINTUSAGE("", "-o", "file for output buffer");
     97    PRINTUSAGE("", "-k", "file which contains key");
     98    PRINTUSAGE("", "-v", "file which contains initialization vector");
     99    PRINTUSAGE("", "-b", "size of input buffer");
    100    PRINTUSAGE("", "-g", "key size (in bytes)");
    101    PRINTUSAGE("", "-p", "do performance test");
    102    PRINTUSAGE("", "-4", "run test in multithread mode. th_num number of parallel threads");
    103    PRINTUSAGE("", "-5", "run test for specified time interval(in seconds)");
    104    PRINTUSAGE("", "--aad", "File with contains additional auth data");
    105    PRINTUSAGE("(rsa)", "-e", "rsa public exponent");
    106    PRINTUSAGE("(rc5)", "-r", "number of rounds");
    107    PRINTUSAGE("(rc5)", "-w", "wordsize (32 or 64)");
    108    fprintf(stderr, "\n");
    109    PRINTUSAGE(progName, "-D -m mode", "Decrypt a buffer");
    110    PRINTUSAGE("", "", "[-i plaintext] [-o ciphertext] [-k key] [-v iv]");
    111    PRINTUSAGE("", "", "[-p repetitions | -5 time_interval] [-4 th_num]");
    112    PRINTUSAGE("", "-m", "cipher mode to use");
    113    PRINTUSAGE("", "-i", "file which contains input buffer");
    114    PRINTUSAGE("", "-o", "file for output buffer");
    115    PRINTUSAGE("", "-k", "file which contains key");
    116    PRINTUSAGE("", "-v", "file which contains initialization vector");
    117    PRINTUSAGE("", "-p", "do performance test");
    118    PRINTUSAGE("", "-4", "run test in multithread mode. th_num number of parallel threads");
    119    PRINTUSAGE("", "-5", "run test for specified time interval(in seconds)");
    120    PRINTUSAGE("", "--aad", "File with contains additional auth data");
    121    fprintf(stderr, "\n");
    122    PRINTUSAGE(progName, "-H -m mode", "Hash a buffer");
    123    PRINTUSAGE("", "", "[-i plaintext] [-o hash]");
    124    PRINTUSAGE("", "", "[-b bufsize]");
    125    PRINTUSAGE("", "", "[-p repetitions | -5 time_interval] [-4 th_num]");
    126    PRINTUSAGE("", "-m", "cipher mode to use");
    127    PRINTUSAGE("", "-i", "file which contains input buffer");
    128    PRINTUSAGE("", "-o", "file for hash");
    129    PRINTUSAGE("", "-b", "size of input buffer");
    130    PRINTUSAGE("", "-p", "do performance test");
    131    PRINTUSAGE("", "-4", "run test in multithread mode. th_num number of parallel threads");
    132    PRINTUSAGE("", "-5", "run test for specified time interval(in seconds)");
    133    fprintf(stderr, "\n");
    134    PRINTUSAGE(progName, "-S -m mode", "Sign a buffer");
    135    PRINTUSAGE("", "", "[-i plaintext] [-o signature] [-k key]");
    136    PRINTUSAGE("", "", "[-b bufsize]");
    137    PRINTUSAGE("", "", "[-n curvename]");
    138    PRINTUSAGE("", "", "[-p repetitions | -5 time_interval] [-4 th_num]");
    139    PRINTUSAGE("", "-m", "cipher mode to use");
    140    PRINTUSAGE("", "-i", "file which contains input buffer");
    141    PRINTUSAGE("", "-o", "file for signature");
    142    PRINTUSAGE("", "-k", "file which contains key");
    143    PRINTUSAGE("", "-n", "name of curve for EC key generation; one of:");
    144    PRINTUSAGE("", "", "  nistp256, nistp384, nistp521");
    145    PRINTUSAGE("", "-p", "do performance test");
    146    PRINTUSAGE("", "-4", "run test in multithread mode. th_num number of parallel threads");
    147    PRINTUSAGE("", "-5", "run test for specified time interval(in seconds)");
    148    fprintf(stderr, "\n");
    149    PRINTUSAGE(progName, "-V -m mode", "Verify a signed buffer");
    150    PRINTUSAGE("", "", "[-i plaintext] [-s signature] [-k key]");
    151    PRINTUSAGE("", "", "[-p repetitions | -5 time_interval] [-4 th_num]");
    152    PRINTUSAGE("", "-m", "cipher mode to use");
    153    PRINTUSAGE("", "-i", "file which contains input buffer");
    154    PRINTUSAGE("", "-s", "file which contains signature of input buffer");
    155    PRINTUSAGE("", "-k", "file which contains key");
    156    PRINTUSAGE("", "-p", "do performance test");
    157    PRINTUSAGE("", "-4", "run test in multithread mode. th_num number of parallel threads");
    158    PRINTUSAGE("", "-5", "run test for specified time interval(in seconds)");
    159    fprintf(stderr, "\n");
    160    PRINTUSAGE(progName, "-N -m mode -b bufsize",
    161               "Create a nonce plaintext and key");
    162    PRINTUSAGE("", "", "[-g keysize] [-u cxreps]");
    163    PRINTUSAGE("", "-g", "key size (in bytes)");
    164    PRINTUSAGE("", "-u", "number of repetitions of context creation");
    165    fprintf(stderr, "\n");
    166    PRINTUSAGE(progName, "-R [-g keysize] [-e exp]",
    167               "Test the RSA populate key function");
    168    PRINTUSAGE("", "", "[-r repetitions]");
    169    PRINTUSAGE("", "-g", "key size (in bytes)");
    170    PRINTUSAGE("", "-e", "rsa public exponent");
    171    PRINTUSAGE("", "-r", "repetitions of the test");
    172    fprintf(stderr, "\n");
    173    PRINTUSAGE(progName, "-F", "Run the FIPS self-test");
    174    fprintf(stderr, "\n");
    175    PRINTUSAGE(progName, "-T [-m mode1,mode2...]", "Run the BLAPI self-test");
    176    fprintf(stderr, "\n");
    177    exit(1);
    178 }
    179 
    180 /*  Helper functions for ascii<-->binary conversion/reading/writing */
    181 
    182 /* XXX argh */
    183 struct item_with_arena {
    184    SECItem *item;
    185    PLArenaPool *arena;
    186 };
    187 
    188 static PRInt32
    189 get_binary(void *arg, const unsigned char *ibuf, PRInt32 size)
    190 {
    191    struct item_with_arena *it = arg;
    192    SECItem *binary = it->item;
    193    SECItem *tmp;
    194    int index;
    195    if (binary->data == NULL) {
    196        tmp = SECITEM_AllocItem(it->arena, NULL, size);
    197        binary->data = tmp->data;
    198        binary->len = tmp->len;
    199        index = 0;
    200    } else {
    201        SECITEM_ReallocItem(NULL, binary, binary->len, binary->len + size);
    202        index = binary->len;
    203    }
    204    PORT_Memcpy(&binary->data[index], ibuf, size);
    205    return binary->len;
    206 }
    207 
    208 static SECStatus
    209 atob(SECItem *ascii, SECItem *binary, PLArenaPool *arena)
    210 {
    211    SECStatus status;
    212    NSSBase64Decoder *cx;
    213    struct item_with_arena it;
    214    int len;
    215    binary->data = NULL;
    216    binary->len = 0;
    217    it.item = binary;
    218    it.arena = arena;
    219    len = (strncmp((const char *)&ascii->data[ascii->len - 2], "\r\n", 2)) ? ascii->len
    220                                                                           : ascii->len - 2;
    221    cx = NSSBase64Decoder_Create(get_binary, &it);
    222    status = NSSBase64Decoder_Update(cx, (const char *)ascii->data, len);
    223    status = NSSBase64Decoder_Destroy(cx, PR_FALSE);
    224    return status;
    225 }
    226 
    227 static PRInt32
    228 output_ascii(void *arg, const char *obuf, PRInt32 size)
    229 {
    230    PRFileDesc *outfile = arg;
    231    PRInt32 nb = PR_Write(outfile, obuf, size);
    232    if (nb != size) {
    233        PORT_SetError(SEC_ERROR_IO);
    234        return -1;
    235    }
    236    return nb;
    237 }
    238 
    239 static SECStatus
    240 btoa_file(SECItem *binary, PRFileDesc *outfile)
    241 {
    242    SECStatus status;
    243    NSSBase64Encoder *cx;
    244    if (binary->len == 0)
    245        return SECSuccess;
    246    cx = NSSBase64Encoder_Create(output_ascii, outfile);
    247    status = NSSBase64Encoder_Update(cx, binary->data, binary->len);
    248    status = NSSBase64Encoder_Destroy(cx, PR_FALSE);
    249    status = PR_Write(outfile, "\r\n", 2);
    250    return status;
    251 }
    252 
    253 SECStatus
    254 hex_from_2char(unsigned char *c2, unsigned char *byteval)
    255 {
    256    int i;
    257    unsigned char offset;
    258    *byteval = 0;
    259    for (i = 0; i < 2; i++) {
    260        if (c2[i] >= '0' && c2[i] <= '9') {
    261            offset = c2[i] - '0';
    262            *byteval |= offset << 4 * (1 - i);
    263        } else if (c2[i] >= 'a' && c2[i] <= 'f') {
    264            offset = c2[i] - 'a';
    265            *byteval |= (offset + 10) << 4 * (1 - i);
    266        } else if (c2[i] >= 'A' && c2[i] <= 'F') {
    267            offset = c2[i] - 'A';
    268            *byteval |= (offset + 10) << 4 * (1 - i);
    269        } else {
    270            return SECFailure;
    271        }
    272    }
    273    return SECSuccess;
    274 }
    275 
    276 SECStatus
    277 char2_from_hex(unsigned char byteval, char *c2)
    278 {
    279    int i;
    280    unsigned char offset;
    281    for (i = 0; i < 2; i++) {
    282        offset = (byteval >> 4 * (1 - i)) & 0x0f;
    283        if (offset < 10) {
    284            c2[i] = '0' + offset;
    285        } else {
    286            c2[i] = 'A' + offset - 10;
    287        }
    288    }
    289    return SECSuccess;
    290 }
    291 
    292 void
    293 serialize_key(SECItem *it, int ni, PRFileDesc *file)
    294 {
    295    unsigned char len[4];
    296    int i;
    297    NSSBase64Encoder *cx;
    298    cx = NSSBase64Encoder_Create(output_ascii, file);
    299    for (i = 0; i < ni; i++, it++) {
    300        len[0] = (it->len >> 24) & 0xff;
    301        len[1] = (it->len >> 16) & 0xff;
    302        len[2] = (it->len >> 8) & 0xff;
    303        len[3] = (it->len & 0xff);
    304        NSSBase64Encoder_Update(cx, len, 4);
    305        NSSBase64Encoder_Update(cx, it->data, it->len);
    306    }
    307    NSSBase64Encoder_Destroy(cx, PR_FALSE);
    308    PR_Write(file, "\r\n", 2);
    309 }
    310 
    311 void
    312 key_from_filedata(PLArenaPool *arena, SECItem *it, int ns, int ni, SECItem *filedata)
    313 {
    314    int fpos = 0;
    315    int i, len;
    316    unsigned char *buf = filedata->data;
    317    for (i = 0; i < ni; i++) {
    318        len = (buf[fpos++] & 0xff) << 24;
    319        len |= (buf[fpos++] & 0xff) << 16;
    320        len |= (buf[fpos++] & 0xff) << 8;
    321        len |= (buf[fpos++] & 0xff);
    322        if (ns <= i) {
    323            if (len > 0) {
    324                it->len = len;
    325                it->data = PORT_ArenaAlloc(arena, it->len);
    326                PORT_Memcpy(it->data, &buf[fpos], it->len);
    327            } else {
    328                it->len = 0;
    329                it->data = NULL;
    330            }
    331            it++;
    332        }
    333        fpos += len;
    334    }
    335 }
    336 
    337 static RSAPrivateKey *
    338 rsakey_from_filedata(PLArenaPool *arena, SECItem *filedata)
    339 {
    340    RSAPrivateKey *key;
    341    key = (RSAPrivateKey *)PORT_ArenaZAlloc(arena, sizeof(RSAPrivateKey));
    342    key->arena = arena;
    343    key_from_filedata(arena, &key->version, 0, 9, filedata);
    344    return key;
    345 }
    346 
    347 static PQGParams *
    348 pqg_from_filedata(PLArenaPool *arena, SECItem *filedata)
    349 {
    350    PQGParams *pqg;
    351    pqg = (PQGParams *)PORT_ArenaZAlloc(arena, sizeof(PQGParams));
    352    pqg->arena = arena;
    353    key_from_filedata(arena, &pqg->prime, 0, 3, filedata);
    354    return pqg;
    355 }
    356 
    357 static DSAPrivateKey *
    358 dsakey_from_filedata(PLArenaPool *arena, SECItem *filedata)
    359 {
    360    DSAPrivateKey *key;
    361    key = (DSAPrivateKey *)PORT_ArenaZAlloc(arena, sizeof(DSAPrivateKey));
    362    key->params.arena = arena;
    363    key_from_filedata(arena, &key->params.prime, 0, 5, filedata);
    364    return key;
    365 }
    366 
    367 static ECPrivateKey *
    368 eckey_from_filedata(PLArenaPool *arena, SECItem *filedata)
    369 {
    370    ECPrivateKey *key;
    371    SECStatus rv;
    372    ECParams *tmpECParams = NULL;
    373    key = (ECPrivateKey *)PORT_ArenaZAlloc(arena, sizeof(ECPrivateKey));
    374    /* read and convert params */
    375    key->ecParams.arena = arena;
    376    key_from_filedata(arena, &key->ecParams.DEREncoding, 0, 1, filedata);
    377    rv = SECOID_Init();
    378    CHECKERROR(rv, __LINE__);
    379    rv = EC_DecodeParams(&key->ecParams.DEREncoding, &tmpECParams);
    380    CHECKERROR(rv, __LINE__);
    381    rv = EC_CopyParams(key->ecParams.arena, &key->ecParams, tmpECParams);
    382    CHECKERROR(rv, __LINE__);
    383    rv = SECOID_Shutdown();
    384    CHECKERROR(rv, __LINE__);
    385    PORT_FreeArena(tmpECParams->arena, PR_TRUE);
    386    /* read key */
    387    key_from_filedata(arena, &key->publicValue, 1, 3, filedata);
    388    return key;
    389 }
    390 
    391 typedef struct curveNameTagPairStr {
    392    char *curveName;
    393    SECOidTag curveOidTag;
    394 } CurveNameTagPair;
    395 
    396 static CurveNameTagPair nameTagPair[] = {
    397    { "sect163k1", SEC_OID_SECG_EC_SECT163K1 },
    398    { "nistk163", SEC_OID_SECG_EC_SECT163K1 },
    399    { "sect163r1", SEC_OID_SECG_EC_SECT163R1 },
    400    { "sect163r2", SEC_OID_SECG_EC_SECT163R2 },
    401    { "nistb163", SEC_OID_SECG_EC_SECT163R2 },
    402    { "sect193r1", SEC_OID_SECG_EC_SECT193R1 },
    403    { "sect193r2", SEC_OID_SECG_EC_SECT193R2 },
    404    { "sect233k1", SEC_OID_SECG_EC_SECT233K1 },
    405    { "nistk233", SEC_OID_SECG_EC_SECT233K1 },
    406    { "sect233r1", SEC_OID_SECG_EC_SECT233R1 },
    407    { "nistb233", SEC_OID_SECG_EC_SECT233R1 },
    408    { "sect239k1", SEC_OID_SECG_EC_SECT239K1 },
    409    { "sect283k1", SEC_OID_SECG_EC_SECT283K1 },
    410    { "nistk283", SEC_OID_SECG_EC_SECT283K1 },
    411    { "sect283r1", SEC_OID_SECG_EC_SECT283R1 },
    412    { "nistb283", SEC_OID_SECG_EC_SECT283R1 },
    413    { "sect409k1", SEC_OID_SECG_EC_SECT409K1 },
    414    { "nistk409", SEC_OID_SECG_EC_SECT409K1 },
    415    { "sect409r1", SEC_OID_SECG_EC_SECT409R1 },
    416    { "nistb409", SEC_OID_SECG_EC_SECT409R1 },
    417    { "sect571k1", SEC_OID_SECG_EC_SECT571K1 },
    418    { "nistk571", SEC_OID_SECG_EC_SECT571K1 },
    419    { "sect571r1", SEC_OID_SECG_EC_SECT571R1 },
    420    { "nistb571", SEC_OID_SECG_EC_SECT571R1 },
    421    { "secp160k1", SEC_OID_SECG_EC_SECP160K1 },
    422    { "secp160r1", SEC_OID_SECG_EC_SECP160R1 },
    423    { "secp160r2", SEC_OID_SECG_EC_SECP160R2 },
    424    { "secp192k1", SEC_OID_SECG_EC_SECP192K1 },
    425    { "secp192r1", SEC_OID_SECG_EC_SECP192R1 },
    426    { "nistp192", SEC_OID_SECG_EC_SECP192R1 },
    427    { "secp224k1", SEC_OID_SECG_EC_SECP224K1 },
    428    { "secp224r1", SEC_OID_SECG_EC_SECP224R1 },
    429    { "nistp224", SEC_OID_SECG_EC_SECP224R1 },
    430    { "secp256k1", SEC_OID_SECG_EC_SECP256K1 },
    431    { "secp256r1", SEC_OID_SECG_EC_SECP256R1 },
    432    { "nistp256", SEC_OID_SECG_EC_SECP256R1 },
    433    { "secp384r1", SEC_OID_SECG_EC_SECP384R1 },
    434    { "nistp384", SEC_OID_SECG_EC_SECP384R1 },
    435    { "secp521r1", SEC_OID_SECG_EC_SECP521R1 },
    436    { "nistp521", SEC_OID_SECG_EC_SECP521R1 },
    437 
    438    { "prime192v1", SEC_OID_ANSIX962_EC_PRIME192V1 },
    439    { "prime192v2", SEC_OID_ANSIX962_EC_PRIME192V2 },
    440    { "prime192v3", SEC_OID_ANSIX962_EC_PRIME192V3 },
    441    { "prime239v1", SEC_OID_ANSIX962_EC_PRIME239V1 },
    442    { "prime239v2", SEC_OID_ANSIX962_EC_PRIME239V2 },
    443    { "prime239v3", SEC_OID_ANSIX962_EC_PRIME239V3 },
    444 
    445    { "c2pnb163v1", SEC_OID_ANSIX962_EC_C2PNB163V1 },
    446    { "c2pnb163v2", SEC_OID_ANSIX962_EC_C2PNB163V2 },
    447    { "c2pnb163v3", SEC_OID_ANSIX962_EC_C2PNB163V3 },
    448    { "c2pnb176v1", SEC_OID_ANSIX962_EC_C2PNB176V1 },
    449    { "c2tnb191v1", SEC_OID_ANSIX962_EC_C2TNB191V1 },
    450    { "c2tnb191v2", SEC_OID_ANSIX962_EC_C2TNB191V2 },
    451    { "c2tnb191v3", SEC_OID_ANSIX962_EC_C2TNB191V3 },
    452    { "c2onb191v4", SEC_OID_ANSIX962_EC_C2ONB191V4 },
    453    { "c2onb191v5", SEC_OID_ANSIX962_EC_C2ONB191V5 },
    454    { "c2pnb208w1", SEC_OID_ANSIX962_EC_C2PNB208W1 },
    455    { "c2tnb239v1", SEC_OID_ANSIX962_EC_C2TNB239V1 },
    456    { "c2tnb239v2", SEC_OID_ANSIX962_EC_C2TNB239V2 },
    457    { "c2tnb239v3", SEC_OID_ANSIX962_EC_C2TNB239V3 },
    458    { "c2onb239v4", SEC_OID_ANSIX962_EC_C2ONB239V4 },
    459    { "c2onb239v5", SEC_OID_ANSIX962_EC_C2ONB239V5 },
    460    { "c2pnb272w1", SEC_OID_ANSIX962_EC_C2PNB272W1 },
    461    { "c2pnb304w1", SEC_OID_ANSIX962_EC_C2PNB304W1 },
    462    { "c2tnb359v1", SEC_OID_ANSIX962_EC_C2TNB359V1 },
    463    { "c2pnb368w1", SEC_OID_ANSIX962_EC_C2PNB368W1 },
    464    { "c2tnb431r1", SEC_OID_ANSIX962_EC_C2TNB431R1 },
    465 
    466    { "secp112r1", SEC_OID_SECG_EC_SECP112R1 },
    467    { "secp112r2", SEC_OID_SECG_EC_SECP112R2 },
    468    { "secp128r1", SEC_OID_SECG_EC_SECP128R1 },
    469    { "secp128r2", SEC_OID_SECG_EC_SECP128R2 },
    470 
    471    { "sect113r1", SEC_OID_SECG_EC_SECT113R1 },
    472    { "sect113r2", SEC_OID_SECG_EC_SECT113R2 },
    473    { "sect131r1", SEC_OID_SECG_EC_SECT131R1 },
    474    { "sect131r2", SEC_OID_SECG_EC_SECT131R2 },
    475    { "curve25519", SEC_OID_CURVE25519 },
    476 };
    477 
    478 static SECItem *
    479 getECParams(const char *curve)
    480 {
    481    SECItem *ecparams;
    482    SECOidData *oidData = NULL;
    483    SECOidTag curveOidTag = SEC_OID_UNKNOWN; /* default */
    484    int i, numCurves;
    485 
    486    if (curve != NULL) {
    487        numCurves = sizeof(nameTagPair) / sizeof(CurveNameTagPair);
    488        for (i = 0; ((i < numCurves) && (curveOidTag == SEC_OID_UNKNOWN));
    489             i++) {
    490            if (PL_strcmp(curve, nameTagPair[i].curveName) == 0)
    491                curveOidTag = nameTagPair[i].curveOidTag;
    492        }
    493    }
    494 
    495    /* Return NULL if curve name is not recognized */
    496    if ((curveOidTag == SEC_OID_UNKNOWN) ||
    497        (oidData = SECOID_FindOIDByTag(curveOidTag)) == NULL) {
    498        fprintf(stderr, "Unrecognized elliptic curve %s\n", curve);
    499        return NULL;
    500    }
    501 
    502    ecparams = SECITEM_AllocItem(NULL, NULL, (2 + oidData->oid.len));
    503 
    504    /*
    505     * ecparams->data needs to contain the ASN encoding of an object ID (OID)
    506     * representing the named curve. The actual OID is in
    507     * oidData->oid.data so we simply prepend 0x06 and OID length
    508     */
    509    ecparams->data[0] = SEC_ASN1_OBJECT_ID;
    510    ecparams->data[1] = oidData->oid.len;
    511    memcpy(ecparams->data + 2, oidData->oid.data, oidData->oid.len);
    512 
    513    return ecparams;
    514 }
    515 
    516 static void
    517 dump_pqg(PQGParams *pqg)
    518 {
    519    SECU_PrintInteger(stdout, &pqg->prime, "PRIME:", 0);
    520    SECU_PrintInteger(stdout, &pqg->subPrime, "SUBPRIME:", 0);
    521    SECU_PrintInteger(stdout, &pqg->base, "BASE:", 0);
    522 }
    523 
    524 static void
    525 dump_dsakey(DSAPrivateKey *key)
    526 {
    527    dump_pqg(&key->params);
    528    SECU_PrintInteger(stdout, &key->publicValue, "PUBLIC VALUE:", 0);
    529    SECU_PrintInteger(stdout, &key->privateValue, "PRIVATE VALUE:", 0);
    530 }
    531 
    532 static void
    533 dump_ecp(ECParams *ecp)
    534 {
    535    /* TODO other fields */
    536    SECU_PrintInteger(stdout, &ecp->base, "BASE POINT:", 0);
    537 }
    538 
    539 static void
    540 dump_eckey(ECPrivateKey *key)
    541 {
    542    dump_ecp(&key->ecParams);
    543    SECU_PrintInteger(stdout, &key->publicValue, "PUBLIC VALUE:", 0);
    544    SECU_PrintInteger(stdout, &key->privateValue, "PRIVATE VALUE:", 0);
    545 }
    546 
    547 static void
    548 dump_rsakey(RSAPrivateKey *key)
    549 {
    550    SECU_PrintInteger(stdout, &key->version, "VERSION:", 0);
    551    SECU_PrintInteger(stdout, &key->modulus, "MODULUS:", 0);
    552    SECU_PrintInteger(stdout, &key->publicExponent, "PUBLIC EXP:", 0);
    553    SECU_PrintInteger(stdout, &key->privateExponent, "PRIVATE EXP:", 0);
    554    SECU_PrintInteger(stdout, &key->prime1, "CRT PRIME 1:", 0);
    555    SECU_PrintInteger(stdout, &key->prime2, "CRT PRIME 2:", 0);
    556    SECU_PrintInteger(stdout, &key->exponent1, "CRT EXP 1:", 0);
    557    SECU_PrintInteger(stdout, &key->exponent2, "CRT EXP 2:", 0);
    558    SECU_PrintInteger(stdout, &key->coefficient, "CRT COEFFICIENT:", 0);
    559 }
    560 
    561 typedef enum {
    562    bltestBase64Encoded, /* Base64 encoded ASCII */
    563    bltestBinary,        /* straight binary */
    564    bltestHexSpaceDelim, /* 0x12 0x34 0xab 0xCD ... */
    565    bltestHexStream      /* 1234abCD ... */
    566 } bltestIOMode;
    567 
    568 typedef struct
    569 {
    570    SECItem buf;
    571    SECItem pBuf;
    572    bltestIOMode mode;
    573    PRFileDesc *file;
    574 } bltestIO;
    575 
    576 typedef SECStatus (*bltestSymmCipherFn)(void *cx,
    577                                        unsigned char *output,
    578                                        unsigned int *outputLen,
    579                                        unsigned int maxOutputLen,
    580                                        const unsigned char *input,
    581                                        unsigned int inputLen);
    582 
    583 typedef SECStatus (*bltestAEADFn)(void *cx,
    584                                  unsigned char *output,
    585                                  unsigned int *outputLen,
    586                                  unsigned int maxOutputLen,
    587                                  const unsigned char *input,
    588                                  unsigned int inputLen,
    589                                  const unsigned char *nonce,
    590                                  unsigned int nonceLen,
    591                                  const unsigned char *ad,
    592                                  unsigned int adLen);
    593 
    594 typedef SECStatus (*bltestPubKeyCipherFn)(void *key,
    595                                          SECItem *output,
    596                                          const SECItem *input);
    597 
    598 typedef SECStatus (*bltestHashCipherFn)(unsigned char *dest,
    599                                        const unsigned char *src,
    600                                        PRUint32 src_length);
    601 
    602 /* Note: Algorithms are grouped in order to support is_symmkeyCipher /
    603 * is_pubkeyCipher / is_hashCipher / is_sigCipher
    604 */
    605 typedef enum {
    606    bltestINVALID = -1,
    607    bltestDES_ECB,     /* Symmetric Key Ciphers */
    608    bltestDES_CBC,     /* .            */
    609    bltestDES_EDE_ECB, /* .            */
    610    bltestDES_EDE_CBC, /* .            */
    611 #ifndef NSS_DISABLE_DEPRECATED_RC2
    612    bltestRC2_ECB, /* .            */
    613    bltestRC2_CBC, /* .            */
    614 #endif
    615    bltestRC4, /* .            */
    616 #ifdef NSS_SOFTOKEN_DOES_RC5
    617    bltestRC5_ECB, /* .            */
    618    bltestRC5_CBC, /* .            */
    619 #endif
    620    bltestAES_ECB,      /* .                     */
    621    bltestAES_CBC,      /* .                     */
    622    bltestAES_CTS,      /* .                     */
    623    bltestAES_CTR,      /* .                     */
    624    bltestAES_GCM,      /* .                     */
    625    bltestCAMELLIA_ECB, /* .                     */
    626    bltestCAMELLIA_CBC, /* .                     */
    627 #ifndef NSS_DISABLE_DEPRECATED_SEED
    628    bltestSEED_ECB, /* SEED algorithm      */
    629    bltestSEED_CBC, /* SEED algorithm      */
    630 #endif
    631    bltestCHACHA20_CTR, /* ChaCha20 block cipher */
    632    bltestCHACHA20,     /* ChaCha20 + Poly1305   */
    633    bltestRSA,          /* Public Key Ciphers    */
    634    bltestRSA_OAEP,     /* . (Public Key Enc.)   */
    635    bltestRSA_PSS,      /* . (Public Key Sig.)   */
    636    bltestECDSA,        /* . (Public Key Sig.)   */
    637    bltestDSA,          /* . (Public Key Sig.)   */
    638    bltestMD2,          /* Hash algorithms       */
    639    bltestMD5,          /* .             */
    640    bltestSHA1,         /* .             */
    641    bltestSHA224,       /* .             */
    642    bltestSHA256,       /* .             */
    643    bltestSHA384,       /* .             */
    644    bltestSHA512,       /* .             */
    645    bltestSHA3_224,     /* .             */
    646    bltestSHA3_256,     /* .             */
    647    bltestSHA3_384,     /* .             */
    648    bltestSHA3_512,     /* .             */
    649    NUMMODES
    650 } bltestCipherMode;
    651 
    652 static char *mode_strings[] = {
    653    "des_ecb",
    654    "des_cbc",
    655    "des3_ecb",
    656    "des3_cbc",
    657 #ifndef NSS_DISABLE_DEPRECATED_RC2
    658    "rc2_ecb",
    659    "rc2_cbc",
    660 #endif
    661    "rc4",
    662 #ifdef NSS_SOFTOKEN_DOES_RC5
    663    "rc5_ecb",
    664    "rc5_cbc",
    665 #endif
    666    "aes_ecb",
    667    "aes_cbc",
    668    "aes_cts",
    669    "aes_ctr",
    670    "aes_gcm",
    671    "camellia_ecb",
    672    "camellia_cbc",
    673 #ifndef NSS_DISABLE_DEPRECATED_SEED
    674    "seed_ecb",
    675    "seed_cbc",
    676 #endif
    677    "chacha20_ctr",
    678    "chacha20_poly1305",
    679    "rsa",
    680    "rsa_oaep",
    681    "rsa_pss",
    682    "ecdsa",
    683    /*"pqg",*/
    684    "dsa",
    685    "md2",
    686    "md5",
    687    "sha1",
    688    "sha224",
    689    "sha256",
    690    "sha384",
    691    "sha512",
    692    "sha3_224",
    693    "sha3_256",
    694    "sha3_384",
    695    "sha3_512",
    696 };
    697 
    698 typedef struct
    699 {
    700    bltestIO key;
    701    bltestIO iv;
    702 } bltestSymmKeyParams;
    703 
    704 typedef struct
    705 {
    706    bltestSymmKeyParams sk; /* must be first */
    707    bltestIO aad;
    708 } bltestAuthSymmKeyParams;
    709 
    710 typedef struct
    711 {
    712    bltestIO key;
    713    bltestIO iv;
    714    int rounds;
    715    int wordsize;
    716 } bltestRC5Params;
    717 
    718 typedef struct
    719 {
    720    bltestIO key;
    721    int keysizeInBits;
    722 
    723    /* OAEP & PSS */
    724    HASH_HashType hashAlg;
    725    HASH_HashType maskHashAlg;
    726    bltestIO seed; /* salt if PSS */
    727 } bltestRSAParams;
    728 
    729 typedef struct
    730 {
    731    bltestIO pqgdata;
    732    unsigned int keysize;
    733    bltestIO keyseed;
    734    bltestIO sigseed;
    735    PQGParams *pqg;
    736 } bltestDSAParams;
    737 
    738 typedef struct
    739 {
    740    char *curveName;
    741    bltestIO sigseed;
    742 } bltestECDSAParams;
    743 
    744 typedef struct
    745 {
    746    bltestIO key;
    747    void *privKey;
    748    void *pubKey;
    749    bltestIO sig; /* if doing verify, the signature (which may come
    750                   * from sigfile. */
    751 
    752    union {
    753        bltestRSAParams rsa;
    754        bltestDSAParams dsa;
    755        bltestECDSAParams ecdsa;
    756    } cipherParams;
    757 } bltestAsymKeyParams;
    758 
    759 typedef struct
    760 {
    761    bltestIO key; /* unused */
    762    PRBool restart;
    763 } bltestHashParams;
    764 
    765 typedef union {
    766    bltestIO key;
    767    bltestSymmKeyParams sk;
    768    bltestAuthSymmKeyParams ask;
    769    bltestRC5Params rc5;
    770    bltestAsymKeyParams asymk;
    771    bltestHashParams hash;
    772 } bltestParams;
    773 
    774 typedef struct bltestCipherInfoStr bltestCipherInfo;
    775 
    776 struct bltestCipherInfoStr {
    777    PLArenaPool *arena;
    778    /* link to next in multithreaded test */
    779    bltestCipherInfo *next;
    780    PRThread *cipherThread;
    781 
    782    /* MonteCarlo test flag*/
    783    PRBool mCarlo;
    784    /* cipher context */
    785    void *cx;
    786    /* I/O streams */
    787    bltestIO input;
    788    bltestIO output;
    789    /* Cipher-specific parameters */
    790    bltestParams params;
    791    /* Cipher mode */
    792    bltestCipherMode mode;
    793    /* Cipher function (encrypt/decrypt/sign/verify/hash) */
    794    union {
    795        bltestSymmCipherFn symmkeyCipher;
    796        bltestAEADFn aeadCipher;
    797        bltestPubKeyCipherFn pubkeyCipher;
    798        bltestHashCipherFn hashCipher;
    799    } cipher;
    800    /* performance testing */
    801    int repetitionsToPerfom;
    802    int seconds;
    803    int repetitions;
    804    int cxreps;
    805    double cxtime;
    806    double optime;
    807 };
    808 
    809 PRBool
    810 is_symmkeyCipher(bltestCipherMode mode)
    811 {
    812    /* change as needed! */
    813    if (mode >= bltestDES_ECB && mode <= bltestCHACHA20_CTR)
    814        return PR_TRUE;
    815    return PR_FALSE;
    816 }
    817 
    818 PRBool
    819 is_aeadCipher(bltestCipherMode mode)
    820 {
    821    /* change as needed! */
    822    switch (mode) {
    823        case bltestCHACHA20:
    824            return PR_TRUE;
    825        default:
    826            return PR_FALSE;
    827    }
    828 }
    829 
    830 PRBool
    831 is_authCipher(bltestCipherMode mode)
    832 {
    833    /* change as needed! */
    834    switch (mode) {
    835        case bltestAES_GCM:
    836        case bltestCHACHA20:
    837            return PR_TRUE;
    838        default:
    839            return PR_FALSE;
    840    }
    841 }
    842 
    843 PRBool
    844 is_singleShotCipher(bltestCipherMode mode)
    845 {
    846    /* change as needed! */
    847    switch (mode) {
    848        case bltestAES_GCM:
    849        case bltestAES_CTS:
    850        case bltestCHACHA20_CTR:
    851        case bltestCHACHA20:
    852            return PR_TRUE;
    853        default:
    854            return PR_FALSE;
    855    }
    856 }
    857 
    858 PRBool
    859 is_pubkeyCipher(bltestCipherMode mode)
    860 {
    861    /* change as needed! */
    862    if (mode >= bltestRSA && mode <= bltestDSA)
    863        return PR_TRUE;
    864    return PR_FALSE;
    865 }
    866 
    867 PRBool
    868 is_hashCipher(bltestCipherMode mode)
    869 {
    870    /* change as needed! */
    871    if (mode >= bltestMD2 && mode <= bltestSHA3_512)
    872        return PR_TRUE;
    873    return PR_FALSE;
    874 }
    875 
    876 PRBool
    877 is_sigCipher(bltestCipherMode mode)
    878 {
    879    /* change as needed! */
    880    if (mode >= bltestRSA_PSS && mode <= bltestDSA)
    881        return PR_TRUE;
    882    return PR_FALSE;
    883 }
    884 
    885 PRBool
    886 cipher_requires_IV(bltestCipherMode mode)
    887 {
    888    /* change as needed! */
    889    switch (mode) {
    890        case bltestDES_CBC:
    891        case bltestDES_EDE_CBC:
    892 #ifndef NSS_DISABLE_DEPRECATED_RC2
    893        case bltestRC2_CBC:
    894 #endif
    895 #ifdef NSS_SOFTOKEN_DOES_RC5
    896        case bltestRC5_CBC:
    897 #endif
    898        case bltestAES_CBC:
    899        case bltestAES_CTS:
    900        case bltestAES_CTR:
    901        case bltestAES_GCM:
    902        case bltestCAMELLIA_CBC:
    903 #ifndef NSS_DISABLE_DEPRECATED_SEED
    904        case bltestSEED_CBC:
    905 #endif
    906        case bltestCHACHA20_CTR:
    907        case bltestCHACHA20:
    908            return PR_TRUE;
    909        default:
    910            return PR_FALSE;
    911    }
    912 }
    913 
    914 SECStatus finishIO(bltestIO *output, PRFileDesc *file);
    915 
    916 SECStatus
    917 setupIO(PLArenaPool *arena, bltestIO *input, PRFileDesc *file,
    918        char *str, int numBytes)
    919 {
    920    SECStatus rv = SECSuccess;
    921    SECItem fileData;
    922    SECItem *in;
    923    unsigned char *tok;
    924    unsigned int i, j;
    925    PRBool needToFreeFile = PR_FALSE;
    926 
    927    if (file && (numBytes == 0 || file == PR_STDIN)) {
    928        /* grabbing data from a file */
    929        rv = SECU_FileToItem(&fileData, file);
    930        if (rv != SECSuccess)
    931            return SECFailure;
    932        in = &fileData;
    933        needToFreeFile = PR_TRUE;
    934    } else if (str) {
    935        /* grabbing data from command line */
    936        fileData.data = (unsigned char *)str;
    937        fileData.len = PL_strlen(str);
    938        in = &fileData;
    939    } else if (file) {
    940        /* create nonce */
    941        SECITEM_AllocItem(arena, &input->buf, numBytes);
    942        RNG_GenerateGlobalRandomBytes(input->buf.data, numBytes);
    943        return finishIO(input, file);
    944    } else {
    945        return SECFailure;
    946    }
    947 
    948    switch (input->mode) {
    949        case bltestBase64Encoded:
    950            if (in->len == 0) {
    951                input->buf.data = NULL;
    952                input->buf.len = 0;
    953                break;
    954            }
    955            rv = atob(in, &input->buf, arena);
    956            break;
    957        case bltestBinary:
    958            if (in->len == 0) {
    959                input->buf.data = NULL;
    960                input->buf.len = 0;
    961                break;
    962            }
    963            if (in->data[in->len - 1] == '\n')
    964                --in->len;
    965            if (in->data[in->len - 1] == '\r')
    966                --in->len;
    967            rv = SECITEM_CopyItem(arena, &input->buf, in);
    968            break;
    969        case bltestHexSpaceDelim:
    970            SECITEM_AllocItem(arena, &input->buf, in->len / 5);
    971            for (i = 0, j = 0; i < in->len; i += 5, j++) {
    972                tok = &in->data[i];
    973                if (tok[0] != '0' || tok[1] != 'x' || tok[4] != ' ')
    974                    /* bad hex token */
    975                    break;
    976 
    977                rv = hex_from_2char(&tok[2], input->buf.data + j);
    978                if (rv)
    979                    break;
    980            }
    981            break;
    982        case bltestHexStream:
    983            SECITEM_AllocItem(arena, &input->buf, in->len / 2);
    984            for (i = 0, j = 0; i < in->len; i += 2, j++) {
    985                tok = &in->data[i];
    986                rv = hex_from_2char(tok, input->buf.data + j);
    987                if (rv)
    988                    break;
    989            }
    990            break;
    991    }
    992 
    993    if (needToFreeFile)
    994        SECITEM_FreeItem(&fileData, PR_FALSE);
    995    return rv;
    996 }
    997 
    998 SECStatus
    999 finishIO(bltestIO *output, PRFileDesc *file)
   1000 {
   1001    SECStatus rv = SECSuccess;
   1002    PRInt32 nb;
   1003    unsigned char byteval;
   1004    SECItem *it;
   1005    char hexstr[5];
   1006    unsigned int i;
   1007    if (output->pBuf.len > 0) {
   1008        it = &output->pBuf;
   1009    } else {
   1010        it = &output->buf;
   1011    }
   1012    switch (output->mode) {
   1013        case bltestBase64Encoded:
   1014            rv = btoa_file(it, file);
   1015            break;
   1016        case bltestBinary:
   1017            nb = PR_Write(file, it->data, it->len);
   1018            rv = (nb == (PRInt32)it->len) ? SECSuccess : SECFailure;
   1019            break;
   1020        case bltestHexSpaceDelim:
   1021            hexstr[0] = '0';
   1022            hexstr[1] = 'x';
   1023            hexstr[4] = ' ';
   1024            for (i = 0; i < it->len; i++) {
   1025                byteval = it->data[i];
   1026                rv = char2_from_hex(byteval, hexstr + 2);
   1027                nb = PR_Write(file, hexstr, 5);
   1028                if (rv)
   1029                    break;
   1030            }
   1031            PR_Write(file, "\n", 1);
   1032            break;
   1033        case bltestHexStream:
   1034            for (i = 0; i < it->len; i++) {
   1035                byteval = it->data[i];
   1036                rv = char2_from_hex(byteval, hexstr);
   1037                if (rv)
   1038                    break;
   1039                nb = PR_Write(file, hexstr, 2);
   1040            }
   1041            PR_Write(file, "\n", 1);
   1042            break;
   1043    }
   1044    return rv;
   1045 }
   1046 
   1047 SECStatus
   1048 bltestCopyIO(PLArenaPool *arena, bltestIO *dest, bltestIO *src)
   1049 {
   1050    if (SECITEM_CopyItem(arena, &dest->buf, &src->buf) != SECSuccess) {
   1051        return SECFailure;
   1052    }
   1053    if (src->pBuf.len > 0) {
   1054        dest->pBuf.len = src->pBuf.len;
   1055        dest->pBuf.data = dest->buf.data + (src->pBuf.data - src->buf.data);
   1056    }
   1057    dest->mode = src->mode;
   1058    dest->file = src->file;
   1059 
   1060    return SECSuccess;
   1061 }
   1062 
   1063 void
   1064 misalignBuffer(PLArenaPool *arena, bltestIO *io, int off)
   1065 {
   1066    ptrdiff_t offset = (ptrdiff_t)io->buf.data % WORDSIZE;
   1067    int length = io->buf.len;
   1068    if (offset != off) {
   1069        SECITEM_ReallocItemV2(arena, &io->buf, length + 2 * WORDSIZE);
   1070        /* offset may have changed? */
   1071        offset = (ptrdiff_t)io->buf.data % WORDSIZE;
   1072        if (offset != off) {
   1073            memmove(io->buf.data + off, io->buf.data, length);
   1074            io->pBuf.data = io->buf.data + off;
   1075            io->pBuf.len = length;
   1076        } else {
   1077            io->pBuf.data = io->buf.data;
   1078            io->pBuf.len = length;
   1079        }
   1080    } else {
   1081        io->pBuf.data = io->buf.data;
   1082        io->pBuf.len = length;
   1083    }
   1084 }
   1085 
   1086 SECStatus
   1087 des_Encrypt(void *cx, unsigned char *output, unsigned int *outputLen,
   1088            unsigned int maxOutputLen, const unsigned char *input,
   1089            unsigned int inputLen)
   1090 {
   1091    return DES_Encrypt((DESContext *)cx, output, outputLen, maxOutputLen,
   1092                       input, inputLen);
   1093 }
   1094 
   1095 SECStatus
   1096 des_Decrypt(void *cx, unsigned char *output, unsigned int *outputLen,
   1097            unsigned int maxOutputLen, const unsigned char *input,
   1098            unsigned int inputLen)
   1099 {
   1100    return DES_Decrypt((DESContext *)cx, output, outputLen, maxOutputLen,
   1101                       input, inputLen);
   1102 }
   1103 
   1104 #ifndef NSS_DISABLE_DEPRECATED_RC2
   1105 SECStatus
   1106 rc2_Encrypt(void *cx, unsigned char *output, unsigned int *outputLen,
   1107            unsigned int maxOutputLen, const unsigned char *input,
   1108            unsigned int inputLen)
   1109 {
   1110    return RC2_Encrypt((RC2Context *)cx, output, outputLen, maxOutputLen,
   1111                       input, inputLen);
   1112 }
   1113 
   1114 SECStatus
   1115 rc2_Decrypt(void *cx, unsigned char *output, unsigned int *outputLen,
   1116            unsigned int maxOutputLen, const unsigned char *input,
   1117            unsigned int inputLen)
   1118 {
   1119    return RC2_Decrypt((RC2Context *)cx, output, outputLen, maxOutputLen,
   1120                       input, inputLen);
   1121 }
   1122 #endif /* NSS_DISABLE_DEPRECATED_RC2 */
   1123 
   1124 SECStatus
   1125 rc4_Encrypt(void *cx, unsigned char *output, unsigned int *outputLen,
   1126            unsigned int maxOutputLen, const unsigned char *input,
   1127            unsigned int inputLen)
   1128 {
   1129    return RC4_Encrypt((RC4Context *)cx, output, outputLen, maxOutputLen,
   1130                       input, inputLen);
   1131 }
   1132 
   1133 SECStatus
   1134 rc4_Decrypt(void *cx, unsigned char *output, unsigned int *outputLen,
   1135            unsigned int maxOutputLen, const unsigned char *input,
   1136            unsigned int inputLen)
   1137 {
   1138    return RC4_Decrypt((RC4Context *)cx, output, outputLen, maxOutputLen,
   1139                       input, inputLen);
   1140 }
   1141 
   1142 SECStatus
   1143 aes_Encrypt(void *cx, unsigned char *output, unsigned int *outputLen,
   1144            unsigned int maxOutputLen, const unsigned char *input,
   1145            unsigned int inputLen)
   1146 {
   1147    return AES_Encrypt((AESContext *)cx, output, outputLen, maxOutputLen,
   1148                       input, inputLen);
   1149 }
   1150 
   1151 SECStatus
   1152 aes_Decrypt(void *cx, unsigned char *output, unsigned int *outputLen,
   1153            unsigned int maxOutputLen, const unsigned char *input,
   1154            unsigned int inputLen)
   1155 {
   1156    return AES_Decrypt((AESContext *)cx, output, outputLen, maxOutputLen,
   1157                       input, inputLen);
   1158 }
   1159 
   1160 SECStatus
   1161 chacha20_Encrypt(void *cx, unsigned char *output, unsigned int *outputLen,
   1162                 unsigned int maxOutputLen, const unsigned char *input,
   1163                 unsigned int inputLen)
   1164 {
   1165    if (maxOutputLen < inputLen) {
   1166        PORT_SetError(SEC_ERROR_OUTPUT_LEN);
   1167        return SECFailure;
   1168    }
   1169    ChaCha20Context *ctx = cx;
   1170    *outputLen = inputLen;
   1171    return ChaCha20_Xor(output, input, inputLen, ctx->key, ctx->nonce,
   1172                        ctx->counter);
   1173 }
   1174 
   1175 SECStatus
   1176 chacha20_poly1305_Encrypt(void *cx, unsigned char *output,
   1177                          unsigned int *outputLen, unsigned int maxOutputLen,
   1178                          const unsigned char *input, unsigned int inputLen,
   1179                          const unsigned char *nonce, unsigned int nonceLen,
   1180                          const unsigned char *ad, unsigned int adLen)
   1181 {
   1182    return ChaCha20Poly1305_Seal((ChaCha20Poly1305Context *)cx, output,
   1183                                 outputLen, maxOutputLen, input, inputLen,
   1184                                 nonce, nonceLen, ad, adLen);
   1185 }
   1186 
   1187 SECStatus
   1188 chacha20_poly1305_Decrypt(void *cx, unsigned char *output,
   1189                          unsigned int *outputLen, unsigned int maxOutputLen,
   1190                          const unsigned char *input, unsigned int inputLen,
   1191                          const unsigned char *nonce, unsigned int nonceLen,
   1192                          const unsigned char *ad, unsigned int adLen)
   1193 {
   1194    return ChaCha20Poly1305_Open((ChaCha20Poly1305Context *)cx, output,
   1195                                 outputLen, maxOutputLen, input, inputLen,
   1196                                 nonce, nonceLen, ad, adLen);
   1197 }
   1198 
   1199 SECStatus
   1200 camellia_Encrypt(void *cx, unsigned char *output, unsigned int *outputLen,
   1201                 unsigned int maxOutputLen, const unsigned char *input,
   1202                 unsigned int inputLen)
   1203 {
   1204    return Camellia_Encrypt((CamelliaContext *)cx, output, outputLen,
   1205                            maxOutputLen,
   1206                            input, inputLen);
   1207 }
   1208 
   1209 SECStatus
   1210 camellia_Decrypt(void *cx, unsigned char *output, unsigned int *outputLen,
   1211                 unsigned int maxOutputLen, const unsigned char *input,
   1212                 unsigned int inputLen)
   1213 {
   1214    return Camellia_Decrypt((CamelliaContext *)cx, output, outputLen,
   1215                            maxOutputLen,
   1216                            input, inputLen);
   1217 }
   1218 
   1219 #ifndef NSS_DISABLE_DEPRECATED_SEED
   1220 SECStatus
   1221 seed_Encrypt(void *cx, unsigned char *output, unsigned int *outputLen,
   1222             unsigned int maxOutputLen, const unsigned char *input,
   1223             unsigned int inputLen)
   1224 {
   1225    return SEED_Encrypt((SEEDContext *)cx, output, outputLen, maxOutputLen,
   1226                        input, inputLen);
   1227 }
   1228 
   1229 SECStatus
   1230 seed_Decrypt(void *cx, unsigned char *output, unsigned int *outputLen,
   1231             unsigned int maxOutputLen, const unsigned char *input,
   1232             unsigned int inputLen)
   1233 {
   1234    return SEED_Decrypt((SEEDContext *)cx, output, outputLen, maxOutputLen,
   1235                        input, inputLen);
   1236 }
   1237 #endif /* NSS_DISABLE_DEPRECATED_SEED */
   1238 
   1239 SECStatus
   1240 rsa_PublicKeyOp(void *cx, SECItem *output, const SECItem *input)
   1241 {
   1242    bltestAsymKeyParams *params = (bltestAsymKeyParams *)cx;
   1243    RSAPublicKey *pubKey = (RSAPublicKey *)params->pubKey;
   1244    SECStatus rv = RSA_PublicKeyOp(pubKey, output->data, input->data);
   1245    if (rv == SECSuccess) {
   1246        output->len = pubKey->modulus.data[0] ? pubKey->modulus.len : pubKey->modulus.len - 1;
   1247    }
   1248    return rv;
   1249 }
   1250 
   1251 SECStatus
   1252 rsa_PrivateKeyOp(void *cx, SECItem *output, const SECItem *input)
   1253 {
   1254    bltestAsymKeyParams *params = (bltestAsymKeyParams *)cx;
   1255    RSAPrivateKey *privKey = (RSAPrivateKey *)params->privKey;
   1256    SECStatus rv = RSA_PrivateKeyOp(privKey, output->data, input->data);
   1257    if (rv == SECSuccess) {
   1258        output->len = privKey->modulus.data[0] ? privKey->modulus.len : privKey->modulus.len - 1;
   1259    }
   1260    return rv;
   1261 }
   1262 
   1263 SECStatus
   1264 rsa_signDigestPSS(void *cx, SECItem *output, const SECItem *input)
   1265 {
   1266    bltestAsymKeyParams *params = (bltestAsymKeyParams *)cx;
   1267    bltestRSAParams *rsaParams = &params->cipherParams.rsa;
   1268    return RSA_SignPSS((RSAPrivateKey *)params->privKey,
   1269                       rsaParams->hashAlg,
   1270                       rsaParams->maskHashAlg,
   1271                       rsaParams->seed.buf.data,
   1272                       rsaParams->seed.buf.len,
   1273                       output->data, &output->len, output->len,
   1274                       input->data, input->len);
   1275 }
   1276 
   1277 SECStatus
   1278 rsa_verifyDigestPSS(void *cx, SECItem *output, const SECItem *input)
   1279 {
   1280    bltestAsymKeyParams *params = (bltestAsymKeyParams *)cx;
   1281    bltestRSAParams *rsaParams = &params->cipherParams.rsa;
   1282    return RSA_CheckSignPSS((RSAPublicKey *)params->pubKey,
   1283                            rsaParams->hashAlg,
   1284                            rsaParams->maskHashAlg,
   1285                            rsaParams->seed.buf.len,
   1286                            output->data, output->len,
   1287                            input->data, input->len);
   1288 }
   1289 
   1290 SECStatus
   1291 rsa_encryptOAEP(void *cx, SECItem *output, const SECItem *input)
   1292 {
   1293    bltestAsymKeyParams *params = (bltestAsymKeyParams *)cx;
   1294    bltestRSAParams *rsaParams = &params->cipherParams.rsa;
   1295    return RSA_EncryptOAEP((RSAPublicKey *)params->pubKey,
   1296                           rsaParams->hashAlg,
   1297                           rsaParams->maskHashAlg,
   1298                           NULL, 0,
   1299                           rsaParams->seed.buf.data,
   1300                           rsaParams->seed.buf.len,
   1301                           output->data, &output->len, output->len,
   1302                           input->data, input->len);
   1303 }
   1304 
   1305 SECStatus
   1306 rsa_decryptOAEP(void *cx, SECItem *output, const SECItem *input)
   1307 {
   1308    bltestAsymKeyParams *params = (bltestAsymKeyParams *)cx;
   1309    bltestRSAParams *rsaParams = &params->cipherParams.rsa;
   1310    return RSA_DecryptOAEP((RSAPrivateKey *)params->privKey,
   1311                           rsaParams->hashAlg,
   1312                           rsaParams->maskHashAlg,
   1313                           NULL, 0,
   1314                           output->data, &output->len, output->len,
   1315                           input->data, input->len);
   1316 }
   1317 
   1318 SECStatus
   1319 dsa_signDigest(void *cx, SECItem *output, const SECItem *input)
   1320 {
   1321    bltestAsymKeyParams *params = (bltestAsymKeyParams *)cx;
   1322    if (params->cipherParams.dsa.sigseed.buf.len > 0) {
   1323        return DSA_SignDigestWithSeed((DSAPrivateKey *)params->privKey,
   1324                                      output, input,
   1325                                      params->cipherParams.dsa.sigseed.buf.data);
   1326    }
   1327    return DSA_SignDigest((DSAPrivateKey *)params->privKey, output, input);
   1328 }
   1329 
   1330 SECStatus
   1331 dsa_verifyDigest(void *cx, SECItem *output, const SECItem *input)
   1332 {
   1333    bltestAsymKeyParams *params = (bltestAsymKeyParams *)cx;
   1334    return DSA_VerifyDigest((DSAPublicKey *)params->pubKey, output, input);
   1335 }
   1336 
   1337 SECStatus
   1338 ecdsa_signDigest(void *cx, SECItem *output, const SECItem *input)
   1339 {
   1340    bltestAsymKeyParams *params = (bltestAsymKeyParams *)cx;
   1341    if (params->cipherParams.ecdsa.sigseed.buf.len > 0) {
   1342        return ECDSA_SignDigestWithSeed(
   1343            (ECPrivateKey *)params->privKey,
   1344            output, input,
   1345            params->cipherParams.ecdsa.sigseed.buf.data,
   1346            params->cipherParams.ecdsa.sigseed.buf.len);
   1347    }
   1348    return ECDSA_SignDigest((ECPrivateKey *)params->privKey, output, input);
   1349 }
   1350 
   1351 SECStatus
   1352 ecdsa_verifyDigest(void *cx, SECItem *output, const SECItem *input)
   1353 {
   1354    bltestAsymKeyParams *params = (bltestAsymKeyParams *)cx;
   1355    return ECDSA_VerifyDigest((ECPublicKey *)params->pubKey, output, input);
   1356 }
   1357 
   1358 SECStatus
   1359 bltest_des_init(bltestCipherInfo *cipherInfo, PRBool encrypt)
   1360 {
   1361    PRIntervalTime time1, time2;
   1362    bltestSymmKeyParams *desp = &cipherInfo->params.sk;
   1363    int minorMode;
   1364    int i;
   1365    switch (cipherInfo->mode) {
   1366        case bltestDES_ECB:
   1367            minorMode = NSS_DES;
   1368            break;
   1369        case bltestDES_CBC:
   1370            minorMode = NSS_DES_CBC;
   1371            break;
   1372        case bltestDES_EDE_ECB:
   1373            minorMode = NSS_DES_EDE3;
   1374            break;
   1375        case bltestDES_EDE_CBC:
   1376            minorMode = NSS_DES_EDE3_CBC;
   1377            break;
   1378        default:
   1379            return SECFailure;
   1380    }
   1381    cipherInfo->cx = (void *)DES_CreateContext(desp->key.buf.data,
   1382                                               desp->iv.buf.data,
   1383                                               minorMode, encrypt);
   1384    if (cipherInfo->cxreps > 0) {
   1385        DESContext **dummycx;
   1386        dummycx = PORT_Alloc(cipherInfo->cxreps * sizeof(DESContext *));
   1387        TIMESTART();
   1388        for (i = 0; i < cipherInfo->cxreps; i++) {
   1389            dummycx[i] = (void *)DES_CreateContext(desp->key.buf.data,
   1390                                                   desp->iv.buf.data,
   1391                                                   minorMode, encrypt);
   1392        }
   1393        TIMEFINISH(cipherInfo->cxtime, 1.0);
   1394        for (i = 0; i < cipherInfo->cxreps; i++) {
   1395            DES_DestroyContext(dummycx[i], PR_TRUE);
   1396        }
   1397        PORT_Free(dummycx);
   1398    }
   1399    if (encrypt)
   1400        cipherInfo->cipher.symmkeyCipher = des_Encrypt;
   1401    else
   1402        cipherInfo->cipher.symmkeyCipher = des_Decrypt;
   1403    return SECSuccess;
   1404 }
   1405 
   1406 #ifndef NSS_DISABLE_DEPRECATED_RC2
   1407 SECStatus
   1408 bltest_rc2_init(bltestCipherInfo *cipherInfo, PRBool encrypt)
   1409 {
   1410    PRIntervalTime time1, time2;
   1411    bltestSymmKeyParams *rc2p = &cipherInfo->params.sk;
   1412    int minorMode;
   1413    int i;
   1414    switch (cipherInfo->mode) {
   1415        case bltestRC2_ECB:
   1416            minorMode = NSS_RC2;
   1417            break;
   1418        case bltestRC2_CBC:
   1419            minorMode = NSS_RC2_CBC;
   1420            break;
   1421        default:
   1422            return SECFailure;
   1423    }
   1424    cipherInfo->cx = (void *)RC2_CreateContext(rc2p->key.buf.data,
   1425                                               rc2p->key.buf.len,
   1426                                               rc2p->iv.buf.data,
   1427                                               minorMode,
   1428                                               rc2p->key.buf.len);
   1429    if (cipherInfo->cxreps > 0) {
   1430        RC2Context **dummycx;
   1431        dummycx = PORT_Alloc(cipherInfo->cxreps * sizeof(RC2Context *));
   1432        TIMESTART();
   1433        for (i = 0; i < cipherInfo->cxreps; i++) {
   1434            dummycx[i] = (void *)RC2_CreateContext(rc2p->key.buf.data,
   1435                                                   rc2p->key.buf.len,
   1436                                                   rc2p->iv.buf.data,
   1437                                                   minorMode,
   1438                                                   rc2p->key.buf.len);
   1439        }
   1440        TIMEFINISH(cipherInfo->cxtime, 1.0);
   1441        for (i = 0; i < cipherInfo->cxreps; i++) {
   1442            RC2_DestroyContext(dummycx[i], PR_TRUE);
   1443        }
   1444        PORT_Free(dummycx);
   1445    }
   1446    if (encrypt)
   1447        cipherInfo->cipher.symmkeyCipher = rc2_Encrypt;
   1448    else
   1449        cipherInfo->cipher.symmkeyCipher = rc2_Decrypt;
   1450    return SECSuccess;
   1451 }
   1452 #endif /* NSS_DISABLE_DEPRECATED_RC2 */
   1453 
   1454 SECStatus
   1455 bltest_rc4_init(bltestCipherInfo *cipherInfo, PRBool encrypt)
   1456 {
   1457    PRIntervalTime time1, time2;
   1458    int i;
   1459    bltestSymmKeyParams *rc4p = &cipherInfo->params.sk;
   1460    cipherInfo->cx = (void *)RC4_CreateContext(rc4p->key.buf.data,
   1461                                               rc4p->key.buf.len);
   1462    if (cipherInfo->cxreps > 0) {
   1463        RC4Context **dummycx;
   1464        dummycx = PORT_Alloc(cipherInfo->cxreps * sizeof(RC4Context *));
   1465        TIMESTART();
   1466        for (i = 0; i < cipherInfo->cxreps; i++) {
   1467            dummycx[i] = (void *)RC4_CreateContext(rc4p->key.buf.data,
   1468                                                   rc4p->key.buf.len);
   1469        }
   1470        TIMEFINISH(cipherInfo->cxtime, 1.0);
   1471        for (i = 0; i < cipherInfo->cxreps; i++) {
   1472            RC4_DestroyContext(dummycx[i], PR_TRUE);
   1473        }
   1474        PORT_Free(dummycx);
   1475    }
   1476    if (encrypt)
   1477        cipherInfo->cipher.symmkeyCipher = rc4_Encrypt;
   1478    else
   1479        cipherInfo->cipher.symmkeyCipher = rc4_Decrypt;
   1480    return SECSuccess;
   1481 }
   1482 
   1483 SECStatus
   1484 bltest_rc5_init(bltestCipherInfo *cipherInfo, PRBool encrypt)
   1485 {
   1486 #ifdef NSS_SOFTOKEN_DOES_RC5
   1487    PRIntervalTime time1, time2;
   1488    bltestRC5Params *rc5p = &cipherInfo->params.rc5;
   1489    int minorMode;
   1490    switch (cipherInfo->mode) {
   1491        case bltestRC5_ECB:
   1492            minorMode = NSS_RC5;
   1493            break;
   1494        case bltestRC5_CBC:
   1495            minorMode = NSS_RC5_CBC;
   1496            break;
   1497        default:
   1498            return SECFailure;
   1499    }
   1500    TIMESTART();
   1501    cipherInfo->cx = (void *)RC5_CreateContext(&rc5p->key.buf,
   1502                                               rc5p->rounds, rc5p->wordsize,
   1503                                               rc5p->iv.buf.data, minorMode);
   1504    TIMEFINISH(cipherInfo->cxtime, 1.0);
   1505    if (encrypt)
   1506        cipherInfo->cipher.symmkeyCipher = RC5_Encrypt;
   1507    else
   1508        cipherInfo->cipher.symmkeyCipher = RC5_Decrypt;
   1509    return SECSuccess;
   1510 #else
   1511    return SECFailure;
   1512 #endif
   1513 }
   1514 
   1515 SECStatus
   1516 bltest_aes_init(bltestCipherInfo *cipherInfo, PRBool encrypt)
   1517 {
   1518    bltestSymmKeyParams *aesp = &cipherInfo->params.sk;
   1519    bltestAuthSymmKeyParams *gcmp = &cipherInfo->params.ask;
   1520    int minorMode;
   1521    int i;
   1522    int keylen = aesp->key.buf.len;
   1523    unsigned int blocklen = AES_BLOCK_SIZE;
   1524    PRIntervalTime time1, time2;
   1525    unsigned char *params;
   1526    int len;
   1527    CK_AES_CTR_PARAMS ctrParams;
   1528    CK_NSS_GCM_PARAMS gcmParams;
   1529 
   1530    params = aesp->iv.buf.data;
   1531    switch (cipherInfo->mode) {
   1532        case bltestAES_ECB:
   1533            minorMode = NSS_AES;
   1534            break;
   1535        case bltestAES_CBC:
   1536            minorMode = NSS_AES_CBC;
   1537            break;
   1538        case bltestAES_CTS:
   1539            minorMode = NSS_AES_CTS;
   1540            break;
   1541        case bltestAES_CTR:
   1542            minorMode = NSS_AES_CTR;
   1543            ctrParams.ulCounterBits = 32;
   1544            len = PR_MIN(aesp->iv.buf.len, blocklen);
   1545            PORT_Memset(ctrParams.cb, 0, blocklen);
   1546            PORT_Memcpy(ctrParams.cb, aesp->iv.buf.data, len);
   1547            params = (unsigned char *)&ctrParams;
   1548            break;
   1549        case bltestAES_GCM:
   1550            minorMode = NSS_AES_GCM;
   1551            gcmParams.pIv = gcmp->sk.iv.buf.data;
   1552            gcmParams.ulIvLen = gcmp->sk.iv.buf.len;
   1553            gcmParams.pAAD = gcmp->aad.buf.data;
   1554            gcmParams.ulAADLen = gcmp->aad.buf.len;
   1555            gcmParams.ulTagBits = blocklen * 8;
   1556            params = (unsigned char *)&gcmParams;
   1557            break;
   1558        default:
   1559            return SECFailure;
   1560    }
   1561    cipherInfo->cx = (void *)AES_CreateContext(aesp->key.buf.data,
   1562                                               params,
   1563                                               minorMode, encrypt,
   1564                                               keylen, blocklen);
   1565    if (cipherInfo->cxreps > 0) {
   1566        AESContext **dummycx;
   1567        dummycx = PORT_Alloc(cipherInfo->cxreps * sizeof(AESContext *));
   1568        TIMESTART();
   1569        for (i = 0; i < cipherInfo->cxreps; i++) {
   1570            dummycx[i] = (void *)AES_CreateContext(aesp->key.buf.data,
   1571                                                   params,
   1572                                                   minorMode, encrypt,
   1573                                                   keylen, blocklen);
   1574        }
   1575        TIMEFINISH(cipherInfo->cxtime, 1.0);
   1576        for (i = 0; i < cipherInfo->cxreps; i++) {
   1577            AES_DestroyContext(dummycx[i], PR_TRUE);
   1578        }
   1579        PORT_Free(dummycx);
   1580    }
   1581    if (encrypt)
   1582        cipherInfo->cipher.symmkeyCipher = aes_Encrypt;
   1583    else
   1584        cipherInfo->cipher.symmkeyCipher = aes_Decrypt;
   1585    return SECSuccess;
   1586 }
   1587 
   1588 SECStatus
   1589 bltest_camellia_init(bltestCipherInfo *cipherInfo, PRBool encrypt)
   1590 {
   1591    bltestSymmKeyParams *camelliap = &cipherInfo->params.sk;
   1592    int minorMode;
   1593    int i;
   1594    int keylen = camelliap->key.buf.len;
   1595    PRIntervalTime time1, time2;
   1596 
   1597    switch (cipherInfo->mode) {
   1598        case bltestCAMELLIA_ECB:
   1599            minorMode = NSS_CAMELLIA;
   1600            break;
   1601        case bltestCAMELLIA_CBC:
   1602            minorMode = NSS_CAMELLIA_CBC;
   1603            break;
   1604        default:
   1605            return SECFailure;
   1606    }
   1607    cipherInfo->cx = (void *)Camellia_CreateContext(camelliap->key.buf.data,
   1608                                                    camelliap->iv.buf.data,
   1609                                                    minorMode, encrypt,
   1610                                                    keylen);
   1611    if (cipherInfo->cxreps > 0) {
   1612        CamelliaContext **dummycx;
   1613        dummycx = PORT_Alloc(cipherInfo->cxreps * sizeof(CamelliaContext *));
   1614        TIMESTART();
   1615        for (i = 0; i < cipherInfo->cxreps; i++) {
   1616            dummycx[i] = (void *)Camellia_CreateContext(camelliap->key.buf.data,
   1617                                                        camelliap->iv.buf.data,
   1618                                                        minorMode, encrypt,
   1619                                                        keylen);
   1620        }
   1621        TIMEFINISH(cipherInfo->cxtime, 1.0);
   1622        for (i = 0; i < cipherInfo->cxreps; i++) {
   1623            Camellia_DestroyContext(dummycx[i], PR_TRUE);
   1624        }
   1625        PORT_Free(dummycx);
   1626    }
   1627    if (encrypt)
   1628        cipherInfo->cipher.symmkeyCipher = camellia_Encrypt;
   1629    else
   1630        cipherInfo->cipher.symmkeyCipher = camellia_Decrypt;
   1631    return SECSuccess;
   1632 }
   1633 
   1634 #ifndef NSS_DISABLE_DEPRECATED_SEED
   1635 SECStatus
   1636 bltest_seed_init(bltestCipherInfo *cipherInfo, PRBool encrypt)
   1637 {
   1638    PRIntervalTime time1, time2;
   1639    bltestSymmKeyParams *seedp = &cipherInfo->params.sk;
   1640    int minorMode;
   1641    int i;
   1642 
   1643    switch (cipherInfo->mode) {
   1644        case bltestSEED_ECB:
   1645            minorMode = NSS_SEED;
   1646            break;
   1647        case bltestSEED_CBC:
   1648            minorMode = NSS_SEED_CBC;
   1649            break;
   1650        default:
   1651            return SECFailure;
   1652    }
   1653    cipherInfo->cx = (void *)SEED_CreateContext(seedp->key.buf.data,
   1654                                                seedp->iv.buf.data,
   1655                                                minorMode, encrypt);
   1656    if (cipherInfo->cxreps > 0) {
   1657        SEEDContext **dummycx;
   1658        dummycx = PORT_Alloc(cipherInfo->cxreps * sizeof(SEEDContext *));
   1659        TIMESTART();
   1660        for (i = 0; i < cipherInfo->cxreps; i++) {
   1661            dummycx[i] = (void *)SEED_CreateContext(seedp->key.buf.data,
   1662                                                    seedp->iv.buf.data,
   1663                                                    minorMode, encrypt);
   1664        }
   1665        TIMEFINISH(cipherInfo->cxtime, 1.0);
   1666        for (i = 0; i < cipherInfo->cxreps; i++) {
   1667            SEED_DestroyContext(dummycx[i], PR_TRUE);
   1668        }
   1669        PORT_Free(dummycx);
   1670    }
   1671    if (encrypt)
   1672        cipherInfo->cipher.symmkeyCipher = seed_Encrypt;
   1673    else
   1674        cipherInfo->cipher.symmkeyCipher = seed_Decrypt;
   1675 
   1676    return SECSuccess;
   1677 }
   1678 #endif /* NSS_DISABLE_DEPRECATED_SEED */
   1679 
   1680 SECStatus
   1681 bltest_chacha20_ctr_init(bltestCipherInfo *cipherInfo, PRBool encrypt)
   1682 {
   1683    const PRUint32 counter = 1;
   1684    bltestSymmKeyParams *sk = &cipherInfo->params.sk;
   1685    cipherInfo->cx = ChaCha20_CreateContext(sk->key.buf.data, sk->key.buf.len,
   1686                                            sk->iv.buf.data, sk->iv.buf.len,
   1687                                            counter);
   1688 
   1689    if (cipherInfo->cx == NULL) {
   1690        PR_fprintf(PR_STDERR, "ChaCha20_CreateContext() returned NULL\n"
   1691                              "key must be 32 bytes, iv must be 12 bytes\n");
   1692        return SECFailure;
   1693    }
   1694    cipherInfo->cipher.symmkeyCipher = chacha20_Encrypt;
   1695    return SECSuccess;
   1696 }
   1697 
   1698 SECStatus
   1699 bltest_chacha20_init(bltestCipherInfo *cipherInfo, PRBool encrypt)
   1700 {
   1701    const unsigned int tagLen = 16;
   1702    const bltestSymmKeyParams *sk = &cipherInfo->params.sk;
   1703    cipherInfo->cx = ChaCha20Poly1305_CreateContext(sk->key.buf.data,
   1704                                                    sk->key.buf.len, tagLen);
   1705 
   1706    if (encrypt)
   1707        cipherInfo->cipher.aeadCipher = chacha20_poly1305_Encrypt;
   1708    else
   1709        cipherInfo->cipher.aeadCipher = chacha20_poly1305_Decrypt;
   1710    return SECSuccess;
   1711 }
   1712 
   1713 SECStatus
   1714 bltest_rsa_init(bltestCipherInfo *cipherInfo, PRBool encrypt)
   1715 {
   1716    int i;
   1717    RSAPrivateKey **dummyKey;
   1718    RSAPrivateKey *privKey;
   1719    RSAPublicKey *pubKey;
   1720    PRIntervalTime time1, time2;
   1721 
   1722    bltestAsymKeyParams *asymk = &cipherInfo->params.asymk;
   1723    bltestRSAParams *rsap = &asymk->cipherParams.rsa;
   1724 
   1725    /* RSA key gen was done during parameter setup */
   1726    cipherInfo->cx = asymk;
   1727    privKey = (RSAPrivateKey *)asymk->privKey;
   1728 
   1729    /* For performance testing */
   1730    if (cipherInfo->cxreps > 0) {
   1731        /* Create space for n private key objects */
   1732        dummyKey = (RSAPrivateKey **)PORT_Alloc(cipherInfo->cxreps *
   1733                                                sizeof(RSAPrivateKey *));
   1734        /* Time n keygens, storing in the array */
   1735        TIMESTART();
   1736        for (i = 0; i < cipherInfo->cxreps; i++)
   1737            dummyKey[i] = RSA_NewKey(rsap->keysizeInBits,
   1738                                     &privKey->publicExponent);
   1739        TIMEFINISH(cipherInfo->cxtime, cipherInfo->cxreps);
   1740        /* Free the n key objects */
   1741        for (i = 0; i < cipherInfo->cxreps; i++)
   1742            PORT_FreeArena(dummyKey[i]->arena, PR_TRUE);
   1743        PORT_Free(dummyKey);
   1744    }
   1745 
   1746    if ((encrypt && !is_sigCipher(cipherInfo->mode)) ||
   1747        (!encrypt && is_sigCipher(cipherInfo->mode))) {
   1748        /* Have to convert private key to public key.  Memory
   1749         * is freed with private key's arena  */
   1750        pubKey = (RSAPublicKey *)PORT_ArenaAlloc(privKey->arena,
   1751                                                 sizeof(RSAPublicKey));
   1752        pubKey->modulus.len = privKey->modulus.len;
   1753        pubKey->modulus.data = privKey->modulus.data;
   1754        pubKey->publicExponent.len = privKey->publicExponent.len;
   1755        pubKey->publicExponent.data = privKey->publicExponent.data;
   1756        asymk->pubKey = (void *)pubKey;
   1757    }
   1758    switch (cipherInfo->mode) {
   1759        case bltestRSA:
   1760            cipherInfo->cipher.pubkeyCipher = encrypt ? rsa_PublicKeyOp
   1761                                                      : rsa_PrivateKeyOp;
   1762            break;
   1763        case bltestRSA_PSS:
   1764            cipherInfo->cipher.pubkeyCipher = encrypt ? rsa_signDigestPSS
   1765                                                      : rsa_verifyDigestPSS;
   1766            break;
   1767        case bltestRSA_OAEP:
   1768            cipherInfo->cipher.pubkeyCipher = encrypt ? rsa_encryptOAEP
   1769                                                      : rsa_decryptOAEP;
   1770            break;
   1771        default:
   1772            break;
   1773    }
   1774    return SECSuccess;
   1775 }
   1776 
   1777 SECStatus
   1778 blapi_pqg_param_gen(unsigned int keysize, PQGParams **pqg, PQGVerify **vfy)
   1779 {
   1780    if (keysize < 1024) {
   1781        int j = PQG_PBITS_TO_INDEX(keysize);
   1782        return PQG_ParamGen(j, pqg, vfy);
   1783    }
   1784    return PQG_ParamGenV2(keysize, 0, 0, pqg, vfy);
   1785 }
   1786 
   1787 SECStatus
   1788 bltest_pqg_init(bltestDSAParams *dsap)
   1789 {
   1790    SECStatus rv, res;
   1791    PQGVerify *vfy = NULL;
   1792    rv = blapi_pqg_param_gen(dsap->keysize, &dsap->pqg, &vfy);
   1793    CHECKERROR(rv, __LINE__);
   1794    rv = PQG_VerifyParams(dsap->pqg, vfy, &res);
   1795    CHECKERROR(res, __LINE__);
   1796    CHECKERROR(rv, __LINE__);
   1797    return rv;
   1798 }
   1799 
   1800 SECStatus
   1801 bltest_dsa_init(bltestCipherInfo *cipherInfo, PRBool encrypt)
   1802 {
   1803    int i;
   1804    DSAPrivateKey **dummyKey;
   1805    PQGParams *dummypqg;
   1806    PRIntervalTime time1, time2;
   1807    bltestAsymKeyParams *asymk = &cipherInfo->params.asymk;
   1808    bltestDSAParams *dsap = &asymk->cipherParams.dsa;
   1809    PQGVerify *ignore = NULL;
   1810    cipherInfo->cx = asymk;
   1811    /* For performance testing */
   1812    if (cipherInfo->cxreps > 0) {
   1813        /* Create space for n private key objects */
   1814        dummyKey = (DSAPrivateKey **)PORT_ZAlloc(cipherInfo->cxreps *
   1815                                                 sizeof(DSAPrivateKey *));
   1816        /* Time n keygens, storing in the array */
   1817        TIMESTART();
   1818        for (i = 0; i < cipherInfo->cxreps; i++) {
   1819            dummypqg = NULL;
   1820            blapi_pqg_param_gen(dsap->keysize, &dummypqg, &ignore);
   1821            DSA_NewKey(dummypqg, &dummyKey[i]);
   1822        }
   1823        TIMEFINISH(cipherInfo->cxtime, cipherInfo->cxreps);
   1824        /* Free the n key objects */
   1825        for (i = 0; i < cipherInfo->cxreps; i++)
   1826            PORT_FreeArena(dummyKey[i]->params.arena, PR_TRUE);
   1827        PORT_Free(dummyKey);
   1828    }
   1829    if (!dsap->pqg && dsap->pqgdata.buf.len > 0) {
   1830        dsap->pqg = pqg_from_filedata(cipherInfo->arena, &dsap->pqgdata.buf);
   1831    }
   1832    if (!asymk->privKey && asymk->key.buf.len > 0) {
   1833        asymk->privKey = dsakey_from_filedata(cipherInfo->arena, &asymk->key.buf);
   1834    }
   1835    if (encrypt) {
   1836        cipherInfo->cipher.pubkeyCipher = dsa_signDigest;
   1837    } else {
   1838        /* Have to convert private key to public key.  Memory
   1839         * is freed with private key's arena  */
   1840        DSAPublicKey *pubkey;
   1841        DSAPrivateKey *key = (DSAPrivateKey *)asymk->privKey;
   1842        pubkey = (DSAPublicKey *)PORT_ArenaZAlloc(key->params.arena,
   1843                                                  sizeof(DSAPublicKey));
   1844        pubkey->params.prime.len = key->params.prime.len;
   1845        pubkey->params.prime.data = key->params.prime.data;
   1846        pubkey->params.subPrime.len = key->params.subPrime.len;
   1847        pubkey->params.subPrime.data = key->params.subPrime.data;
   1848        pubkey->params.base.len = key->params.base.len;
   1849        pubkey->params.base.data = key->params.base.data;
   1850        pubkey->publicValue.len = key->publicValue.len;
   1851        pubkey->publicValue.data = key->publicValue.data;
   1852        asymk->pubKey = pubkey;
   1853        cipherInfo->cipher.pubkeyCipher = dsa_verifyDigest;
   1854    }
   1855    return SECSuccess;
   1856 }
   1857 
   1858 SECStatus
   1859 bltest_ecdsa_init(bltestCipherInfo *cipherInfo, PRBool encrypt)
   1860 {
   1861    int i;
   1862    ECPrivateKey **dummyKey;
   1863    PRIntervalTime time1, time2;
   1864    bltestAsymKeyParams *asymk = &cipherInfo->params.asymk;
   1865    cipherInfo->cx = asymk;
   1866    /* For performance testing */
   1867    if (cipherInfo->cxreps > 0) {
   1868        /* Create space for n private key objects */
   1869        dummyKey = (ECPrivateKey **)PORT_ZAlloc(cipherInfo->cxreps *
   1870                                                sizeof(ECPrivateKey *));
   1871        /* Time n keygens, storing in the array */
   1872        TIMESTART();
   1873        for (i = 0; i < cipherInfo->cxreps; i++) {
   1874            EC_NewKey(&((ECPrivateKey *)asymk->privKey)->ecParams, &dummyKey[i]);
   1875        }
   1876        TIMEFINISH(cipherInfo->cxtime, cipherInfo->cxreps);
   1877        /* Free the n key objects */
   1878        for (i = 0; i < cipherInfo->cxreps; i++)
   1879            PORT_FreeArena(dummyKey[i]->ecParams.arena, PR_TRUE);
   1880        PORT_Free(dummyKey);
   1881    }
   1882    if (!asymk->privKey && asymk->key.buf.len > 0) {
   1883        asymk->privKey = eckey_from_filedata(cipherInfo->arena, &asymk->key.buf);
   1884    }
   1885    if (encrypt) {
   1886        cipherInfo->cipher.pubkeyCipher = ecdsa_signDigest;
   1887    } else {
   1888        /* Have to convert private key to public key.  Memory
   1889         * is freed with private key's arena  */
   1890        ECPublicKey *pubkey;
   1891        ECPrivateKey *key = (ECPrivateKey *)asymk->privKey;
   1892        pubkey = (ECPublicKey *)PORT_ArenaZAlloc(key->ecParams.arena,
   1893                                                 sizeof(ECPublicKey));
   1894        pubkey->ecParams.type = key->ecParams.type;
   1895        pubkey->ecParams.fieldID.size = key->ecParams.fieldID.size;
   1896        pubkey->ecParams.fieldID.type = key->ecParams.fieldID.type;
   1897        pubkey->ecParams.fieldID.u.prime.len = key->ecParams.fieldID.u.prime.len;
   1898        pubkey->ecParams.fieldID.u.prime.data = key->ecParams.fieldID.u.prime.data;
   1899        pubkey->ecParams.fieldID.k1 = key->ecParams.fieldID.k1;
   1900        pubkey->ecParams.fieldID.k2 = key->ecParams.fieldID.k2;
   1901        pubkey->ecParams.fieldID.k3 = key->ecParams.fieldID.k3;
   1902        pubkey->ecParams.curve.a.len = key->ecParams.curve.a.len;
   1903        pubkey->ecParams.curve.a.data = key->ecParams.curve.a.data;
   1904        pubkey->ecParams.curve.b.len = key->ecParams.curve.b.len;
   1905        pubkey->ecParams.curve.b.data = key->ecParams.curve.b.data;
   1906        pubkey->ecParams.curve.seed.len = key->ecParams.curve.seed.len;
   1907        pubkey->ecParams.curve.seed.data = key->ecParams.curve.seed.data;
   1908        pubkey->ecParams.base.len = key->ecParams.base.len;
   1909        pubkey->ecParams.base.data = key->ecParams.base.data;
   1910        pubkey->ecParams.order.len = key->ecParams.order.len;
   1911        pubkey->ecParams.order.data = key->ecParams.order.data;
   1912        pubkey->ecParams.cofactor = key->ecParams.cofactor;
   1913        pubkey->ecParams.DEREncoding.len = key->ecParams.DEREncoding.len;
   1914        pubkey->ecParams.DEREncoding.data = key->ecParams.DEREncoding.data;
   1915        pubkey->ecParams.name = key->ecParams.name;
   1916        pubkey->publicValue.len = key->publicValue.len;
   1917        pubkey->publicValue.data = key->publicValue.data;
   1918        asymk->pubKey = pubkey;
   1919        cipherInfo->cipher.pubkeyCipher = ecdsa_verifyDigest;
   1920    }
   1921    return SECSuccess;
   1922 }
   1923 
   1924 /* XXX unfortunately, this is not defined in blapi.h */
   1925 SECStatus
   1926 md2_HashBuf(unsigned char *dest, const unsigned char *src, PRUint32 src_length)
   1927 {
   1928    unsigned int len;
   1929    MD2Context *cx = MD2_NewContext();
   1930    if (cx == NULL)
   1931        return SECFailure;
   1932    MD2_Begin(cx);
   1933    MD2_Update(cx, src, src_length);
   1934    MD2_End(cx, dest, &len, MD2_LENGTH);
   1935    MD2_DestroyContext(cx, PR_TRUE);
   1936    return SECSuccess;
   1937 }
   1938 
   1939 SECStatus
   1940 md2_restart(unsigned char *dest, const unsigned char *src, PRUint32 src_length)
   1941 {
   1942    MD2Context *cx, *cx_cpy;
   1943    unsigned char *cxbytes;
   1944    unsigned int len;
   1945    unsigned int i, quarter;
   1946    SECStatus rv = SECSuccess;
   1947    cx = MD2_NewContext();
   1948    MD2_Begin(cx);
   1949    /* divide message by 4, restarting 3 times */
   1950    quarter = (src_length + 3) / 4;
   1951    for (i = 0; i < 4 && src_length > 0; i++) {
   1952        MD2_Update(cx, src + i * quarter, PR_MIN(quarter, src_length));
   1953        len = MD2_FlattenSize(cx);
   1954        cxbytes = PORT_Alloc(len);
   1955        MD2_Flatten(cx, cxbytes);
   1956        cx_cpy = MD2_Resurrect(cxbytes, NULL);
   1957        if (!cx_cpy) {
   1958            PR_fprintf(PR_STDERR, "%s: MD2_Resurrect failed!\n", progName);
   1959            goto finish;
   1960        }
   1961        rv = PORT_Memcmp(cx, cx_cpy, len);
   1962        if (rv) {
   1963            MD2_DestroyContext(cx_cpy, PR_TRUE);
   1964            PR_fprintf(PR_STDERR, "%s: MD2_restart failed!\n", progName);
   1965            goto finish;
   1966        }
   1967        MD2_DestroyContext(cx_cpy, PR_TRUE);
   1968        PORT_Free(cxbytes);
   1969        src_length -= quarter;
   1970    }
   1971    MD2_End(cx, dest, &len, MD2_LENGTH);
   1972 finish:
   1973    MD2_DestroyContext(cx, PR_TRUE);
   1974    return rv;
   1975 }
   1976 
   1977 SECStatus
   1978 md5_restart(unsigned char *dest, const unsigned char *src, PRUint32 src_length)
   1979 {
   1980    SECStatus rv = SECSuccess;
   1981    MD5Context *cx, *cx_cpy;
   1982    unsigned char *cxbytes;
   1983    unsigned int len;
   1984    unsigned int i, quarter;
   1985    cx = MD5_NewContext();
   1986    MD5_Begin(cx);
   1987    /* divide message by 4, restarting 3 times */
   1988    quarter = (src_length + 3) / 4;
   1989    for (i = 0; i < 4 && src_length > 0; i++) {
   1990        MD5_Update(cx, src + i * quarter, PR_MIN(quarter, src_length));
   1991        len = MD5_FlattenSize(cx);
   1992        cxbytes = PORT_Alloc(len);
   1993        MD5_Flatten(cx, cxbytes);
   1994        cx_cpy = MD5_Resurrect(cxbytes, NULL);
   1995        if (!cx_cpy) {
   1996            PR_fprintf(PR_STDERR, "%s: MD5_Resurrect failed!\n", progName);
   1997            rv = SECFailure;
   1998            goto finish;
   1999        }
   2000        rv = PORT_Memcmp(cx, cx_cpy, len);
   2001        if (rv) {
   2002            MD5_DestroyContext(cx_cpy, PR_TRUE);
   2003            PR_fprintf(PR_STDERR, "%s: MD5_restart failed!\n", progName);
   2004            goto finish;
   2005        }
   2006        MD5_DestroyContext(cx_cpy, PR_TRUE);
   2007        PORT_Free(cxbytes);
   2008        src_length -= quarter;
   2009    }
   2010    MD5_End(cx, dest, &len, MD5_LENGTH);
   2011 finish:
   2012    MD5_DestroyContext(cx, PR_TRUE);
   2013    return rv;
   2014 }
   2015 
   2016 SECStatus
   2017 sha1_restart(unsigned char *dest, const unsigned char *src, PRUint32 src_length)
   2018 {
   2019    SECStatus rv = SECSuccess;
   2020    SHA1Context *cx, *cx_cpy;
   2021    unsigned char *cxbytes;
   2022    unsigned int len;
   2023    unsigned int i, quarter;
   2024    cx = SHA1_NewContext();
   2025    SHA1_Begin(cx);
   2026    /* divide message by 4, restarting 3 times */
   2027    quarter = (src_length + 3) / 4;
   2028    for (i = 0; i < 4 && src_length > 0; i++) {
   2029        SHA1_Update(cx, src + i * quarter, PR_MIN(quarter, src_length));
   2030        len = SHA1_FlattenSize(cx);
   2031        cxbytes = PORT_Alloc(len);
   2032        SHA1_Flatten(cx, cxbytes);
   2033        cx_cpy = SHA1_Resurrect(cxbytes, NULL);
   2034        if (!cx_cpy) {
   2035            PR_fprintf(PR_STDERR, "%s: SHA1_Resurrect failed!\n", progName);
   2036            rv = SECFailure;
   2037            goto finish;
   2038        }
   2039        rv = PORT_Memcmp(cx, cx_cpy, len);
   2040        if (rv) {
   2041            SHA1_DestroyContext(cx_cpy, PR_TRUE);
   2042            PR_fprintf(PR_STDERR, "%s: SHA1_restart failed!\n", progName);
   2043            goto finish;
   2044        }
   2045        SHA1_DestroyContext(cx_cpy, PR_TRUE);
   2046        PORT_Free(cxbytes);
   2047        src_length -= quarter;
   2048    }
   2049    SHA1_End(cx, dest, &len, MD5_LENGTH);
   2050 finish:
   2051    SHA1_DestroyContext(cx, PR_TRUE);
   2052    return rv;
   2053 }
   2054 
   2055 SECStatus
   2056 SHA224_restart(unsigned char *dest, const unsigned char *src, PRUint32 src_length)
   2057 {
   2058    SECStatus rv = SECSuccess;
   2059    SHA224Context *cx, *cx_cpy;
   2060    unsigned char *cxbytes;
   2061    unsigned int len;
   2062    unsigned int i, quarter;
   2063    cx = SHA224_NewContext();
   2064    SHA224_Begin(cx);
   2065    /* divide message by 4, restarting 3 times */
   2066    quarter = (src_length + 3) / 4;
   2067    for (i = 0; i < 4 && src_length > 0; i++) {
   2068        SHA224_Update(cx, src + i * quarter, PR_MIN(quarter, src_length));
   2069        len = SHA224_FlattenSize(cx);
   2070        cxbytes = PORT_Alloc(len);
   2071        SHA224_Flatten(cx, cxbytes);
   2072        cx_cpy = SHA224_Resurrect(cxbytes, NULL);
   2073        if (!cx_cpy) {
   2074            PR_fprintf(PR_STDERR, "%s: SHA224_Resurrect failed!\n", progName);
   2075            rv = SECFailure;
   2076            goto finish;
   2077        }
   2078        rv = PORT_Memcmp(cx, cx_cpy, len);
   2079        if (rv) {
   2080            SHA224_DestroyContext(cx_cpy, PR_TRUE);
   2081            PR_fprintf(PR_STDERR, "%s: SHA224_restart failed!\n", progName);
   2082            goto finish;
   2083        }
   2084 
   2085        SHA224_DestroyContext(cx_cpy, PR_TRUE);
   2086        PORT_Free(cxbytes);
   2087        src_length -= quarter;
   2088    }
   2089    SHA224_End(cx, dest, &len, MD5_LENGTH);
   2090 finish:
   2091    SHA224_DestroyContext(cx, PR_TRUE);
   2092    return rv;
   2093 }
   2094 
   2095 SECStatus
   2096 SHA256_restart(unsigned char *dest, const unsigned char *src, PRUint32 src_length)
   2097 {
   2098    SECStatus rv = SECSuccess;
   2099    SHA256Context *cx, *cx_cpy;
   2100    unsigned char *cxbytes;
   2101    unsigned int len;
   2102    unsigned int i, quarter;
   2103    cx = SHA256_NewContext();
   2104    SHA256_Begin(cx);
   2105    /* divide message by 4, restarting 3 times */
   2106    quarter = (src_length + 3) / 4;
   2107    for (i = 0; i < 4 && src_length > 0; i++) {
   2108        SHA256_Update(cx, src + i * quarter, PR_MIN(quarter, src_length));
   2109        len = SHA256_FlattenSize(cx);
   2110        cxbytes = PORT_Alloc(len);
   2111        SHA256_Flatten(cx, cxbytes);
   2112        cx_cpy = SHA256_Resurrect(cxbytes, NULL);
   2113        if (!cx_cpy) {
   2114            PR_fprintf(PR_STDERR, "%s: SHA256_Resurrect failed!\n", progName);
   2115            rv = SECFailure;
   2116            goto finish;
   2117        }
   2118        rv = PORT_Memcmp(cx, cx_cpy, len);
   2119        if (rv) {
   2120            SHA256_DestroyContext(cx_cpy, PR_TRUE);
   2121            PR_fprintf(PR_STDERR, "%s: SHA256_restart failed!\n", progName);
   2122            goto finish;
   2123        }
   2124        SHA256_DestroyContext(cx_cpy, PR_TRUE);
   2125        PORT_Free(cxbytes);
   2126        src_length -= quarter;
   2127    }
   2128    SHA256_End(cx, dest, &len, MD5_LENGTH);
   2129 finish:
   2130    SHA256_DestroyContext(cx, PR_TRUE);
   2131    return rv;
   2132 }
   2133 
   2134 SECStatus
   2135 SHA384_restart(unsigned char *dest, const unsigned char *src, PRUint32 src_length)
   2136 {
   2137    SECStatus rv = SECSuccess;
   2138    SHA384Context *cx, *cx_cpy;
   2139    unsigned char *cxbytes;
   2140    unsigned int len;
   2141    unsigned int i, quarter;
   2142    cx = SHA384_NewContext();
   2143    SHA384_Begin(cx);
   2144    /* divide message by 4, restarting 3 times */
   2145    quarter = (src_length + 3) / 4;
   2146    for (i = 0; i < 4 && src_length > 0; i++) {
   2147        SHA384_Update(cx, src + i * quarter, PR_MIN(quarter, src_length));
   2148        len = SHA384_FlattenSize(cx);
   2149        cxbytes = PORT_Alloc(len);
   2150        SHA384_Flatten(cx, cxbytes);
   2151        cx_cpy = SHA384_Resurrect(cxbytes, NULL);
   2152        if (!cx_cpy) {
   2153            PR_fprintf(PR_STDERR, "%s: SHA384_Resurrect failed!\n", progName);
   2154            rv = SECFailure;
   2155            goto finish;
   2156        }
   2157        rv = PORT_Memcmp(cx, cx_cpy, len);
   2158        if (rv) {
   2159            SHA384_DestroyContext(cx_cpy, PR_TRUE);
   2160            PR_fprintf(PR_STDERR, "%s: SHA384_restart failed!\n", progName);
   2161            goto finish;
   2162        }
   2163        SHA384_DestroyContext(cx_cpy, PR_TRUE);
   2164        PORT_Free(cxbytes);
   2165        src_length -= quarter;
   2166    }
   2167    SHA384_End(cx, dest, &len, MD5_LENGTH);
   2168 finish:
   2169    SHA384_DestroyContext(cx, PR_TRUE);
   2170    return rv;
   2171 }
   2172 
   2173 SECStatus
   2174 SHA512_restart(unsigned char *dest, const unsigned char *src, PRUint32 src_length)
   2175 {
   2176    SECStatus rv = SECSuccess;
   2177    SHA512Context *cx, *cx_cpy;
   2178    unsigned char *cxbytes;
   2179    unsigned int len;
   2180    unsigned int i, quarter;
   2181    cx = SHA512_NewContext();
   2182    SHA512_Begin(cx);
   2183    /* divide message by 4, restarting 3 times */
   2184    quarter = (src_length + 3) / 4;
   2185    for (i = 0; i < 4 && src_length > 0; i++) {
   2186        SHA512_Update(cx, src + i * quarter, PR_MIN(quarter, src_length));
   2187        len = SHA512_FlattenSize(cx);
   2188        cxbytes = PORT_Alloc(len);
   2189        SHA512_Flatten(cx, cxbytes);
   2190        cx_cpy = SHA512_Resurrect(cxbytes, NULL);
   2191        if (!cx_cpy) {
   2192            PR_fprintf(PR_STDERR, "%s: SHA512_Resurrect failed!\n", progName);
   2193            rv = SECFailure;
   2194            goto finish;
   2195        }
   2196        rv = PORT_Memcmp(cx, cx_cpy, len);
   2197        if (rv) {
   2198            SHA512_DestroyContext(cx_cpy, PR_TRUE);
   2199            PR_fprintf(PR_STDERR, "%s: SHA512_restart failed!\n", progName);
   2200            goto finish;
   2201        }
   2202        SHA512_DestroyContext(cx_cpy, PR_TRUE);
   2203        PORT_Free(cxbytes);
   2204        src_length -= quarter;
   2205    }
   2206    SHA512_End(cx, dest, &len, MD5_LENGTH);
   2207 finish:
   2208    SHA512_DestroyContext(cx, PR_TRUE);
   2209    return rv;
   2210 }
   2211 
   2212 SECStatus
   2213 pubkeyInitKey(bltestCipherInfo *cipherInfo, PRFileDesc *file,
   2214              int keysize, int exponent, char *curveName)
   2215 {
   2216    int i;
   2217    SECStatus rv = SECSuccess;
   2218    bltestAsymKeyParams *asymk = &cipherInfo->params.asymk;
   2219    bltestRSAParams *rsap;
   2220    RSAPrivateKey **rsaKey = NULL;
   2221    bltestDSAParams *dsap;
   2222    DSAPrivateKey **dsaKey = NULL;
   2223    SECItem *tmpECParamsDER;
   2224    ECParams *tmpECParams = NULL;
   2225    SECItem ecSerialize[3];
   2226    ECPrivateKey **ecKey = NULL;
   2227    switch (cipherInfo->mode) {
   2228        case bltestRSA:
   2229        case bltestRSA_PSS:
   2230        case bltestRSA_OAEP:
   2231            rsap = &asymk->cipherParams.rsa;
   2232            rsaKey = (RSAPrivateKey **)&asymk->privKey;
   2233            if (keysize > 0) {
   2234                SECItem expitem = { 0, 0, 0 };
   2235                SECITEM_AllocItem(cipherInfo->arena, &expitem, sizeof(int));
   2236                for (i = 1; i <= sizeof(int); i++)
   2237                    expitem.data[i - 1] = exponent >> (8 * (sizeof(int) - i));
   2238                *rsaKey = RSA_NewKey(keysize * 8, &expitem);
   2239                serialize_key(&(*rsaKey)->version, 9, file);
   2240                rsap->keysizeInBits = keysize * 8;
   2241            } else {
   2242                setupIO(cipherInfo->arena, &asymk->key, file, NULL, 0);
   2243                *rsaKey = rsakey_from_filedata(cipherInfo->arena, &asymk->key.buf);
   2244                rsap->keysizeInBits = (*rsaKey)->modulus.len * 8;
   2245            }
   2246            break;
   2247        case bltestDSA:
   2248            dsap = &asymk->cipherParams.dsa;
   2249            dsaKey = (DSAPrivateKey **)&asymk->privKey;
   2250            if (keysize > 0) {
   2251                dsap->keysize = keysize * 8;
   2252                if (!dsap->pqg)
   2253                    bltest_pqg_init(dsap);
   2254                rv = DSA_NewKey(dsap->pqg, dsaKey);
   2255                CHECKERROR(rv, __LINE__);
   2256                serialize_key(&(*dsaKey)->params.prime, 5, file);
   2257            } else {
   2258                setupIO(cipherInfo->arena, &asymk->key, file, NULL, 0);
   2259                *dsaKey = dsakey_from_filedata(cipherInfo->arena, &asymk->key.buf);
   2260                dsap->keysize = (*dsaKey)->params.prime.len * 8;
   2261            }
   2262            break;
   2263        case bltestECDSA:
   2264            ecKey = (ECPrivateKey **)&asymk->privKey;
   2265            if (curveName != NULL) {
   2266                tmpECParamsDER = getECParams(curveName);
   2267                rv = SECOID_Init();
   2268                CHECKERROR(rv, __LINE__);
   2269                rv = EC_DecodeParams(tmpECParamsDER, &tmpECParams) == SECFailure;
   2270                CHECKERROR(rv, __LINE__);
   2271                rv = EC_NewKey(tmpECParams, ecKey);
   2272                CHECKERROR(rv, __LINE__);
   2273                ecSerialize[0].type = tmpECParamsDER->type;
   2274                ecSerialize[0].data = tmpECParamsDER->data;
   2275                ecSerialize[0].len = tmpECParamsDER->len;
   2276                ecSerialize[1].type = (*ecKey)->publicValue.type;
   2277                ecSerialize[1].data = (*ecKey)->publicValue.data;
   2278                ecSerialize[1].len = (*ecKey)->publicValue.len;
   2279                ecSerialize[2].type = (*ecKey)->privateValue.type;
   2280                ecSerialize[2].data = (*ecKey)->privateValue.data;
   2281                ecSerialize[2].len = (*ecKey)->privateValue.len;
   2282                serialize_key(&(ecSerialize[0]), 3, file);
   2283                SECITEM_FreeItem(tmpECParamsDER, PR_TRUE);
   2284                PORT_FreeArena(tmpECParams->arena, PR_TRUE);
   2285                rv = SECOID_Shutdown();
   2286                CHECKERROR(rv, __LINE__);
   2287            } else {
   2288                setupIO(cipherInfo->arena, &asymk->key, file, NULL, 0);
   2289                *ecKey = eckey_from_filedata(cipherInfo->arena, &asymk->key.buf);
   2290            }
   2291            break;
   2292        default:
   2293            return SECFailure;
   2294    }
   2295    return SECSuccess;
   2296 }
   2297 
   2298 SECStatus
   2299 cipherInit(bltestCipherInfo *cipherInfo, PRBool encrypt)
   2300 {
   2301    PRBool restart;
   2302    int outlen;
   2303    switch (cipherInfo->mode) {
   2304        case bltestDES_ECB:
   2305        case bltestDES_CBC:
   2306        case bltestDES_EDE_ECB:
   2307        case bltestDES_EDE_CBC:
   2308            SECITEM_AllocItem(cipherInfo->arena, &cipherInfo->output.buf,
   2309                              cipherInfo->input.pBuf.len);
   2310            return bltest_des_init(cipherInfo, encrypt);
   2311            break;
   2312 #ifndef NSS_DISABLE_DEPRECATED_RC2
   2313        case bltestRC2_ECB:
   2314        case bltestRC2_CBC:
   2315            SECITEM_AllocItem(cipherInfo->arena, &cipherInfo->output.buf,
   2316                              cipherInfo->input.pBuf.len);
   2317            return bltest_rc2_init(cipherInfo, encrypt);
   2318            break;
   2319 #endif /* NSS_DISABLE_DEPRECATED_RC2 */
   2320        case bltestRC4:
   2321            SECITEM_AllocItem(cipherInfo->arena, &cipherInfo->output.buf,
   2322                              cipherInfo->input.pBuf.len);
   2323            return bltest_rc4_init(cipherInfo, encrypt);
   2324            break;
   2325 #ifdef NSS_SOFTOKEN_DOES_RC5
   2326        case bltestRC5_ECB:
   2327        case bltestRC5_CBC:
   2328            SECITEM_AllocItem(cipherInfo->arena, &cipherInfo->output.buf,
   2329                              cipherInfo->input.pBuf.len);
   2330            return bltest_rc5_init(cipherInfo, encrypt);
   2331            break;
   2332 #endif
   2333        case bltestAES_ECB:
   2334        case bltestAES_CBC:
   2335        case bltestAES_CTS:
   2336        case bltestAES_CTR:
   2337        case bltestAES_GCM:
   2338            outlen = cipherInfo->input.pBuf.len;
   2339            if (cipherInfo->mode == bltestAES_GCM && encrypt) {
   2340                outlen += 16;
   2341            }
   2342            SECITEM_AllocItem(cipherInfo->arena, &cipherInfo->output.buf, outlen);
   2343            return bltest_aes_init(cipherInfo, encrypt);
   2344            break;
   2345        case bltestCAMELLIA_ECB:
   2346        case bltestCAMELLIA_CBC:
   2347            SECITEM_AllocItem(cipherInfo->arena, &cipherInfo->output.buf,
   2348                              cipherInfo->input.pBuf.len);
   2349            return bltest_camellia_init(cipherInfo, encrypt);
   2350            break;
   2351 #ifndef NSS_DISABLE_DEPRECATED_SEED
   2352        case bltestSEED_ECB:
   2353        case bltestSEED_CBC:
   2354            SECITEM_AllocItem(cipherInfo->arena, &cipherInfo->output.buf,
   2355                              cipherInfo->input.pBuf.len);
   2356            return bltest_seed_init(cipherInfo, encrypt);
   2357            break;
   2358 #endif /* NSS_DISABLE_DEPRECATED_SEED */
   2359        case bltestCHACHA20_CTR:
   2360            outlen = cipherInfo->input.pBuf.len;
   2361            SECITEM_AllocItem(cipherInfo->arena, &cipherInfo->output.buf, outlen);
   2362            return bltest_chacha20_ctr_init(cipherInfo, encrypt);
   2363            break;
   2364        case bltestCHACHA20:
   2365            outlen = cipherInfo->input.pBuf.len + (encrypt ? 16 : 0);
   2366            SECITEM_AllocItem(cipherInfo->arena, &cipherInfo->output.buf, outlen);
   2367            return bltest_chacha20_init(cipherInfo, encrypt);
   2368            break;
   2369        case bltestRSA:
   2370        case bltestRSA_OAEP:
   2371        case bltestRSA_PSS:
   2372            if (encrypt || cipherInfo->mode != bltestRSA_PSS) {
   2373                /* Don't allocate a buffer for PSS in verify mode, as no actual
   2374                 * output is produced. */
   2375                SECITEM_AllocItem(cipherInfo->arena, &cipherInfo->output.buf,
   2376                                  RSA_MAX_MODULUS_BITS / 8);
   2377            }
   2378            return bltest_rsa_init(cipherInfo, encrypt);
   2379            break;
   2380        case bltestDSA:
   2381            if (encrypt) {
   2382                SECITEM_AllocItem(cipherInfo->arena, &cipherInfo->output.buf,
   2383                                  DSA_MAX_SIGNATURE_LEN);
   2384            }
   2385            return bltest_dsa_init(cipherInfo, encrypt);
   2386            break;
   2387        case bltestECDSA:
   2388            if (encrypt) {
   2389                SECITEM_AllocItem(cipherInfo->arena, &cipherInfo->output.buf,
   2390                                  2 * MAX_ECKEY_LEN);
   2391            }
   2392            return bltest_ecdsa_init(cipherInfo, encrypt);
   2393            break;
   2394        case bltestMD2:
   2395            restart = cipherInfo->params.hash.restart;
   2396            SECITEM_AllocItem(cipherInfo->arena, &cipherInfo->output.buf,
   2397                              MD2_LENGTH);
   2398            cipherInfo->cipher.hashCipher = (restart) ? md2_restart : md2_HashBuf;
   2399            return SECSuccess;
   2400            break;
   2401        case bltestMD5:
   2402            restart = cipherInfo->params.hash.restart;
   2403            SECITEM_AllocItem(cipherInfo->arena, &cipherInfo->output.buf,
   2404                              MD5_LENGTH);
   2405            cipherInfo->cipher.hashCipher = (restart) ? md5_restart : MD5_HashBuf;
   2406            return SECSuccess;
   2407            break;
   2408        case bltestSHA1:
   2409            restart = cipherInfo->params.hash.restart;
   2410            SECITEM_AllocItem(cipherInfo->arena, &cipherInfo->output.buf,
   2411                              SHA1_LENGTH);
   2412            cipherInfo->cipher.hashCipher = (restart) ? sha1_restart : SHA1_HashBuf;
   2413            return SECSuccess;
   2414            break;
   2415        case bltestSHA224:
   2416            restart = cipherInfo->params.hash.restart;
   2417            SECITEM_AllocItem(cipherInfo->arena, &cipherInfo->output.buf,
   2418                              SHA224_LENGTH);
   2419            cipherInfo->cipher.hashCipher = (restart) ? SHA224_restart
   2420                                                      : SHA224_HashBuf;
   2421            return SECSuccess;
   2422            break;
   2423        case bltestSHA256:
   2424            restart = cipherInfo->params.hash.restart;
   2425            SECITEM_AllocItem(cipherInfo->arena, &cipherInfo->output.buf,
   2426                              SHA256_LENGTH);
   2427            cipherInfo->cipher.hashCipher = (restart) ? SHA256_restart
   2428                                                      : SHA256_HashBuf;
   2429            return SECSuccess;
   2430            break;
   2431        case bltestSHA384:
   2432            restart = cipherInfo->params.hash.restart;
   2433            SECITEM_AllocItem(cipherInfo->arena, &cipherInfo->output.buf,
   2434                              SHA384_LENGTH);
   2435            cipherInfo->cipher.hashCipher = (restart) ? SHA384_restart
   2436                                                      : SHA384_HashBuf;
   2437            return SECSuccess;
   2438            break;
   2439        case bltestSHA512:
   2440            restart = cipherInfo->params.hash.restart;
   2441            SECITEM_AllocItem(cipherInfo->arena, &cipherInfo->output.buf,
   2442                              SHA512_LENGTH);
   2443            cipherInfo->cipher.hashCipher = (restart) ? SHA512_restart
   2444                                                      : SHA512_HashBuf;
   2445            return SECSuccess;
   2446            break;
   2447        case bltestSHA3_224:
   2448            restart = cipherInfo->params.hash.restart;
   2449            SECITEM_AllocItem(cipherInfo->arena, &cipherInfo->output.buf,
   2450                              SHA3_224_LENGTH);
   2451            cipherInfo->cipher.hashCipher = SHA3_224_HashBuf;
   2452            return SECSuccess;
   2453            break;
   2454        case bltestSHA3_256:
   2455            restart = cipherInfo->params.hash.restart;
   2456            SECITEM_AllocItem(cipherInfo->arena, &cipherInfo->output.buf,
   2457                              SHA3_256_LENGTH);
   2458            cipherInfo->cipher.hashCipher = SHA3_256_HashBuf;
   2459            return SECSuccess;
   2460            break;
   2461        case bltestSHA3_384:
   2462            restart = cipherInfo->params.hash.restart;
   2463            SECITEM_AllocItem(cipherInfo->arena, &cipherInfo->output.buf,
   2464                              SHA3_384_LENGTH);
   2465            cipherInfo->cipher.hashCipher = SHA3_384_HashBuf;
   2466            return SECSuccess;
   2467            break;
   2468        case bltestSHA3_512:
   2469            restart = cipherInfo->params.hash.restart;
   2470            SECITEM_AllocItem(cipherInfo->arena, &cipherInfo->output.buf,
   2471                              SHA3_512_LENGTH);
   2472            cipherInfo->cipher.hashCipher = SHA3_512_HashBuf;
   2473            return SECSuccess;
   2474            break;
   2475        default:
   2476            return SECFailure;
   2477    }
   2478    return SECSuccess;
   2479 }
   2480 
   2481 SECStatus
   2482 cipherDoOp(bltestCipherInfo *cipherInfo)
   2483 {
   2484    PRIntervalTime time1, time2;
   2485    SECStatus rv = SECSuccess;
   2486    int i;
   2487    unsigned int len;
   2488    unsigned int maxLen = cipherInfo->output.pBuf.len;
   2489    unsigned char *dummyOut;
   2490    dummyOut = PORT_Alloc(maxLen);
   2491    if (is_symmkeyCipher(cipherInfo->mode)) {
   2492        const unsigned char *input = cipherInfo->input.pBuf.data;
   2493        unsigned int inputLen = is_singleShotCipher(cipherInfo->mode) ? cipherInfo->input.pBuf.len
   2494                                                                      : PR_MIN(cipherInfo->input.pBuf.len, 16);
   2495        unsigned char *output = cipherInfo->output.pBuf.data;
   2496        unsigned int outputLen = maxLen;
   2497        unsigned int totalOutputLen = 0;
   2498        TIMESTART();
   2499        rv = (*cipherInfo->cipher.symmkeyCipher)(cipherInfo->cx,
   2500                                                 output, &len, outputLen,
   2501                                                 input, inputLen);
   2502        CHECKERROR(rv, __LINE__);
   2503        totalOutputLen += len;
   2504        if (cipherInfo->input.pBuf.len > inputLen) {
   2505            input += inputLen;
   2506            inputLen = cipherInfo->input.pBuf.len - inputLen;
   2507            output += len;
   2508            outputLen -= len;
   2509            rv = (*cipherInfo->cipher.symmkeyCipher)(cipherInfo->cx,
   2510                                                     output, &len, outputLen,
   2511                                                     input, inputLen);
   2512            CHECKERROR(rv, __LINE__);
   2513            totalOutputLen += len;
   2514        }
   2515        cipherInfo->output.pBuf.len = totalOutputLen;
   2516        TIMEFINISH(cipherInfo->optime, 1.0);
   2517        cipherInfo->repetitions = 0;
   2518        if (cipherInfo->repetitionsToPerfom != 0) {
   2519            TIMESTART();
   2520            for (i = 0; i < cipherInfo->repetitionsToPerfom; i++,
   2521                cipherInfo->repetitions++) {
   2522                (*cipherInfo->cipher.symmkeyCipher)(cipherInfo->cx, dummyOut,
   2523                                                    &len, maxLen,
   2524                                                    cipherInfo->input.pBuf.data,
   2525                                                    cipherInfo->input.pBuf.len);
   2526 
   2527                CHECKERROR(rv, __LINE__);
   2528            }
   2529        } else {
   2530            int opsBetweenChecks = 0;
   2531            TIMEMARK(cipherInfo->seconds);
   2532            while (!(TIMETOFINISH())) {
   2533                int j = 0;
   2534                for (; j < opsBetweenChecks; j++) {
   2535                    (*cipherInfo->cipher.symmkeyCipher)(
   2536                        cipherInfo->cx, dummyOut, &len, maxLen,
   2537                        cipherInfo->input.pBuf.data,
   2538                        cipherInfo->input.pBuf.len);
   2539                }
   2540                cipherInfo->repetitions += j;
   2541            }
   2542        }
   2543        TIMEFINISH(cipherInfo->optime, 1.0);
   2544    } else if (is_aeadCipher(cipherInfo->mode)) {
   2545        const unsigned char *input = cipherInfo->input.pBuf.data;
   2546        unsigned int inputLen = cipherInfo->input.pBuf.len;
   2547        unsigned char *output = cipherInfo->output.pBuf.data;
   2548        unsigned int outputLen;
   2549        bltestSymmKeyParams *sk = &cipherInfo->params.sk;
   2550        bltestAuthSymmKeyParams *ask = &cipherInfo->params.ask;
   2551 
   2552        TIMESTART();
   2553        rv = (*cipherInfo->cipher.aeadCipher)(
   2554            cipherInfo->cx,
   2555            output, &outputLen, maxLen,
   2556            input, inputLen,
   2557            sk->iv.buf.data, sk->iv.buf.len,
   2558            ask->aad.buf.data, ask->aad.buf.len);
   2559        CHECKERROR(rv, __LINE__);
   2560        cipherInfo->output.pBuf.len = outputLen;
   2561        TIMEFINISH(cipherInfo->optime, 1.0);
   2562 
   2563        cipherInfo->repetitions = 0;
   2564        if (cipherInfo->repetitionsToPerfom != 0) {
   2565            TIMESTART();
   2566            for (i = 0; i < cipherInfo->repetitionsToPerfom; i++,
   2567                cipherInfo->repetitions++) {
   2568                rv = (*cipherInfo->cipher.aeadCipher)(
   2569                    cipherInfo->cx,
   2570                    output, &outputLen, maxLen,
   2571                    input, inputLen,
   2572                    sk->iv.buf.data, sk->iv.buf.len,
   2573                    ask->aad.buf.data, ask->aad.buf.len);
   2574                CHECKERROR(rv, __LINE__);
   2575            }
   2576        } else {
   2577            int opsBetweenChecks = 0;
   2578            TIMEMARK(cipherInfo->seconds);
   2579            while (!(TIMETOFINISH())) {
   2580                int j = 0;
   2581                for (; j < opsBetweenChecks; j++) {
   2582                    (*cipherInfo->cipher.aeadCipher)(
   2583                        cipherInfo->cx,
   2584                        output, &outputLen, maxLen,
   2585                        input, inputLen,
   2586                        sk->iv.buf.data, sk->iv.buf.len,
   2587                        ask->aad.buf.data, ask->aad.buf.len);
   2588                }
   2589                cipherInfo->repetitions += j;
   2590            }
   2591        }
   2592        TIMEFINISH(cipherInfo->optime, 1.0);
   2593    } else if (is_pubkeyCipher(cipherInfo->mode)) {
   2594        TIMESTART();
   2595        rv = (*cipherInfo->cipher.pubkeyCipher)(cipherInfo->cx,
   2596                                                &cipherInfo->output.pBuf,
   2597                                                &cipherInfo->input.pBuf);
   2598        TIMEFINISH(cipherInfo->optime, 1.0);
   2599        CHECKERROR(rv, __LINE__);
   2600        cipherInfo->repetitions = 0;
   2601        if (cipherInfo->repetitionsToPerfom != 0) {
   2602            TIMESTART();
   2603            for (i = 0; i < cipherInfo->repetitionsToPerfom;
   2604                 i++, cipherInfo->repetitions++) {
   2605                SECItem dummy;
   2606                dummy.data = dummyOut;
   2607                dummy.len = maxLen;
   2608                (*cipherInfo->cipher.pubkeyCipher)(cipherInfo->cx, &dummy,
   2609                                                   &cipherInfo->input.pBuf);
   2610                CHECKERROR(rv, __LINE__);
   2611            }
   2612        } else {
   2613            int opsBetweenChecks = 0;
   2614            TIMEMARK(cipherInfo->seconds);
   2615            while (!(TIMETOFINISH())) {
   2616                int j = 0;
   2617                for (; j < opsBetweenChecks; j++) {
   2618                    SECItem dummy;
   2619                    dummy.data = dummyOut;
   2620                    dummy.len = maxLen;
   2621                    (*cipherInfo->cipher.pubkeyCipher)(cipherInfo->cx, &dummy,
   2622                                                       &cipherInfo->input.pBuf);
   2623                    CHECKERROR(rv, __LINE__);
   2624                }
   2625                cipherInfo->repetitions += j;
   2626            }
   2627        }
   2628        TIMEFINISH(cipherInfo->optime, 1.0);
   2629    } else if (is_hashCipher(cipherInfo->mode)) {
   2630        TIMESTART();
   2631        rv = (*cipherInfo->cipher.hashCipher)(cipherInfo->output.pBuf.data,
   2632                                              cipherInfo->input.pBuf.data,
   2633                                              cipherInfo->input.pBuf.len);
   2634        TIMEFINISH(cipherInfo->optime, 1.0);
   2635        CHECKERROR(rv, __LINE__);
   2636        cipherInfo->repetitions = 0;
   2637        if (cipherInfo->repetitionsToPerfom != 0) {
   2638            TIMESTART();
   2639            for (i = 0; i < cipherInfo->repetitionsToPerfom;
   2640                 i++, cipherInfo->repetitions++) {
   2641                (*cipherInfo->cipher.hashCipher)(dummyOut,
   2642                                                 cipherInfo->input.pBuf.data,
   2643                                                 cipherInfo->input.pBuf.len);
   2644                CHECKERROR(rv, __LINE__);
   2645            }
   2646        } else {
   2647            int opsBetweenChecks = 0;
   2648            TIMEMARK(cipherInfo->seconds);
   2649            while (!(TIMETOFINISH())) {
   2650                int j = 0;
   2651                for (; j < opsBetweenChecks; j++) {
   2652                    bltestIO *input = &cipherInfo->input;
   2653                    (*cipherInfo->cipher.hashCipher)(dummyOut,
   2654                                                     input->pBuf.data,
   2655                                                     input->pBuf.len);
   2656                    CHECKERROR(rv, __LINE__);
   2657                }
   2658                cipherInfo->repetitions += j;
   2659            }
   2660        }
   2661        TIMEFINISH(cipherInfo->optime, 1.0);
   2662    }
   2663    PORT_Free(dummyOut);
   2664    return rv;
   2665 }
   2666 
   2667 SECStatus
   2668 cipherFinish(bltestCipherInfo *cipherInfo)
   2669 {
   2670    SECStatus rv = SECSuccess;
   2671 
   2672    switch (cipherInfo->mode) {
   2673        case bltestDES_ECB:
   2674        case bltestDES_CBC:
   2675        case bltestDES_EDE_ECB:
   2676        case bltestDES_EDE_CBC:
   2677            DES_DestroyContext((DESContext *)cipherInfo->cx, PR_TRUE);
   2678            break;
   2679        case bltestAES_GCM:
   2680        case bltestAES_ECB:
   2681        case bltestAES_CBC:
   2682        case bltestAES_CTS:
   2683        case bltestAES_CTR:
   2684            AES_DestroyContext((AESContext *)cipherInfo->cx, PR_TRUE);
   2685            break;
   2686        case bltestCAMELLIA_ECB:
   2687        case bltestCAMELLIA_CBC:
   2688            Camellia_DestroyContext((CamelliaContext *)cipherInfo->cx, PR_TRUE);
   2689            break;
   2690 #ifndef NSS_DISABLE_DEPRECATED_SEED
   2691        case bltestSEED_ECB:
   2692        case bltestSEED_CBC:
   2693            SEED_DestroyContext((SEEDContext *)cipherInfo->cx, PR_TRUE);
   2694            break;
   2695 #endif /* NSS_DISABLE_DEPRECATED_SEED */
   2696        case bltestCHACHA20_CTR:
   2697            ChaCha20_DestroyContext((ChaCha20Context *)cipherInfo->cx, PR_TRUE);
   2698            break;
   2699        case bltestCHACHA20:
   2700            ChaCha20Poly1305_DestroyContext((ChaCha20Poly1305Context *)
   2701                                                cipherInfo->cx,
   2702                                            PR_TRUE);
   2703            break;
   2704 #ifndef NSS_DISABLE_DEPRECATED_RC2
   2705        case bltestRC2_ECB:
   2706        case bltestRC2_CBC:
   2707            RC2_DestroyContext((RC2Context *)cipherInfo->cx, PR_TRUE);
   2708            break;
   2709 #endif /* NSS_DISABLE_DEPRECATED_RC2 */
   2710        case bltestRC4:
   2711            RC4_DestroyContext((RC4Context *)cipherInfo->cx, PR_TRUE);
   2712            break;
   2713 #ifdef NSS_SOFTOKEN_DOES_RC5
   2714        case bltestRC5_ECB:
   2715        case bltestRC5_CBC:
   2716            RC5_DestroyContext((RC5Context *)cipherInfo->cx, PR_TRUE);
   2717            break;
   2718 #endif
   2719        case bltestRSA:     /* keys are alloc'ed within cipherInfo's arena, */
   2720        case bltestRSA_PSS: /* will be freed with it. */
   2721        case bltestRSA_OAEP:
   2722        case bltestDSA:
   2723        case bltestECDSA:
   2724        case bltestMD2: /* hash contexts are ephemeral */
   2725        case bltestMD5:
   2726        case bltestSHA1:
   2727        case bltestSHA224:
   2728        case bltestSHA256:
   2729        case bltestSHA384:
   2730        case bltestSHA512:
   2731        case bltestSHA3_224:
   2732        case bltestSHA3_256:
   2733        case bltestSHA3_384:
   2734        case bltestSHA3_512:
   2735            return SECSuccess;
   2736            break;
   2737        default:
   2738            return SECFailure;
   2739    }
   2740    return rv;
   2741 }
   2742 
   2743 void
   2744 print_exponent(SECItem *exp)
   2745 {
   2746    int i;
   2747    int e = 0;
   2748    if (exp->len <= 4) {
   2749        for (i = exp->len; i >= 0; --i)
   2750            e |= exp->data[exp->len - i] << 8 * (i - 1);
   2751        fprintf(stdout, "%12d", e);
   2752    } else {
   2753        e = 8 * exp->len;
   2754        fprintf(stdout, "~2**%-8d", e);
   2755    }
   2756 }
   2757 
   2758 static void
   2759 splitToReportUnit(PRInt64 res, int *resArr, int *del, int size)
   2760 {
   2761    PRInt64 remaining = res, tmp = 0;
   2762    PRInt64 Ldel;
   2763    int i = -1;
   2764 
   2765    while (remaining > 0 && ++i < size) {
   2766        LL_I2L(Ldel, del[i]);
   2767        LL_MOD(tmp, remaining, Ldel);
   2768        LL_L2I(resArr[i], tmp);
   2769        LL_DIV(remaining, remaining, Ldel);
   2770    }
   2771 }
   2772 
   2773 static char *
   2774 getHighUnitBytes(PRInt64 res)
   2775 {
   2776    int spl[] = { 0, 0, 0, 0 };
   2777    int del[] = { 1024, 1024, 1024, 1024 };
   2778    char *marks[] = { "b", "Kb", "Mb", "Gb" };
   2779    int i = 3;
   2780 
   2781    splitToReportUnit(res, spl, del, 4);
   2782 
   2783    for (; i > 0; i--) {
   2784        if (spl[i] != 0) {
   2785            break;
   2786        }
   2787    }
   2788 
   2789    if (i == 0)
   2790        return PR_smprintf("%d%s", spl[i], marks[i]);
   2791    else
   2792        return PR_smprintf("%d%s %d%s", spl[i], marks[i], spl[i - 1], marks[i - 1]);
   2793 }
   2794 
   2795 static void
   2796 printPR_smpString(const char *sformat, char *reportStr,
   2797                  const char *nformat, PRInt64 rNum)
   2798 {
   2799    if (reportStr) {
   2800        fprintf(stdout, sformat, reportStr);
   2801        PR_smprintf_free(reportStr);
   2802    } else {
   2803        fprintf(stdout, nformat, rNum);
   2804    }
   2805 }
   2806 
   2807 static char *
   2808 getHighUnitOps(PRInt64 res)
   2809 {
   2810    int spl[] = { 0, 0, 0, 0 };
   2811    int del[] = { 1000, 1000, 1000, 1000 };
   2812    char *marks[] = { "", "T", "M", "B" };
   2813    int i = 3;
   2814 
   2815    splitToReportUnit(res, spl, del, 4);
   2816 
   2817    for (; i > 0; i--) {
   2818        if (spl[i] != 0) {
   2819            break;
   2820        }
   2821    }
   2822 
   2823    return PR_smprintf("%d%s", spl[i], marks[i]);
   2824 }
   2825 
   2826 void
   2827 dump_performance_info(bltestCipherInfo *infoList, double totalTimeInt,
   2828                      PRBool encrypt, PRBool cxonly)
   2829 {
   2830    bltestCipherInfo *info = infoList;
   2831 
   2832    PRInt64 totalIn = 0;
   2833    PRBool td = PR_TRUE;
   2834 
   2835    int repetitions = 0;
   2836    int cxreps = 0;
   2837    double cxtime = 0;
   2838    double optime = 0;
   2839    while (info != NULL) {
   2840        repetitions += info->repetitions;
   2841        cxreps += info->cxreps;
   2842        cxtime += info->cxtime;
   2843        optime += info->optime;
   2844        totalIn += (PRInt64)info->input.buf.len * (PRInt64)info->repetitions;
   2845 
   2846        info = info->next;
   2847    }
   2848    info = infoList;
   2849 
   2850    fprintf(stdout, "#%9s", "mode");
   2851    fprintf(stdout, "%12s", "in");
   2852 print_td:
   2853    switch (info->mode) {
   2854        case bltestDES_ECB:
   2855        case bltestDES_CBC:
   2856        case bltestDES_EDE_ECB:
   2857        case bltestDES_EDE_CBC:
   2858        case bltestAES_ECB:
   2859        case bltestAES_CBC:
   2860        case bltestAES_CTS:
   2861        case bltestAES_CTR:
   2862        case bltestAES_GCM:
   2863        case bltestCAMELLIA_ECB:
   2864        case bltestCAMELLIA_CBC:
   2865 #ifndef NSS_DISABLE_DEPRECATED_SEED
   2866        case bltestSEED_ECB:
   2867        case bltestSEED_CBC:
   2868 #endif
   2869 #ifndef NSS_DISABLE_DEPRECATED_RC2
   2870        case bltestRC2_ECB:
   2871        case bltestRC2_CBC:
   2872 #endif
   2873        case bltestRC4:
   2874            if (td)
   2875                fprintf(stdout, "%8s", "symmkey");
   2876            else
   2877                fprintf(stdout, "%8d", 8 * info->params.sk.key.buf.len);
   2878            break;
   2879 #ifdef NSS_SOFTOKEN_DOES_RC5
   2880        case bltestRC5_ECB:
   2881        case bltestRC5_CBC:
   2882            if (info->params.sk.key.buf.len > 0)
   2883                printf("symmetric key(bytes)=%d,", info->params.sk.key.buf.len);
   2884            if (info->rounds > 0)
   2885                printf("rounds=%d,", info->params.rc5.rounds);
   2886            if (info->wordsize > 0)
   2887                printf("wordsize(bytes)=%d,", info->params.rc5.wordsize);
   2888            break;
   2889 #endif
   2890        case bltestRSA:
   2891        case bltestRSA_PSS:
   2892        case bltestRSA_OAEP:
   2893            if (td) {
   2894                fprintf(stdout, "%8s", "rsa_mod");
   2895                fprintf(stdout, "%12s", "rsa_pe");
   2896            } else {
   2897                bltestAsymKeyParams *asymk = &info->params.asymk;
   2898                fprintf(stdout, "%8d", asymk->cipherParams.rsa.keysizeInBits);
   2899                print_exponent(
   2900                    &((RSAPrivateKey *)asymk->privKey)->publicExponent);
   2901            }
   2902            break;
   2903        case bltestDSA:
   2904            if (td) {
   2905                fprintf(stdout, "%8s", "pqg_mod");
   2906            } else {
   2907                fprintf(stdout, "%8d", info->params.asymk.cipherParams.dsa.keysize);
   2908            }
   2909            break;
   2910        case bltestECDSA:
   2911            if (td) {
   2912                fprintf(stdout, "%12s", "ec_curve");
   2913            } else {
   2914                ECPrivateKey *key = (ECPrivateKey *)info->params.asymk.privKey;
   2915                ECCurveName curveName = key->ecParams.name;
   2916                fprintf(stdout, "%12s",
   2917                        ecCurve_map[curveName] ? ecCurve_map[curveName]->text : "Unsupported curve");
   2918            }
   2919            break;
   2920        case bltestMD2:
   2921        case bltestMD5:
   2922        case bltestSHA1:
   2923        case bltestSHA256:
   2924        case bltestSHA384:
   2925        case bltestSHA512:
   2926        default:
   2927            break;
   2928    }
   2929    if (!td) {
   2930        PRInt64 totalThroughPut;
   2931 
   2932        printPR_smpString("%8s", getHighUnitOps(repetitions),
   2933                          "%8d", repetitions);
   2934 
   2935        printPR_smpString("%8s", getHighUnitOps(cxreps), "%8d", cxreps);
   2936 
   2937        fprintf(stdout, "%12.3f", cxtime);
   2938        fprintf(stdout, "%12.3f", optime);
   2939        fprintf(stdout, "%12.03f", totalTimeInt / 1000);
   2940 
   2941        totalThroughPut = (PRInt64)(totalIn / totalTimeInt * 1000);
   2942        printPR_smpString("%12s", getHighUnitBytes(totalThroughPut),
   2943                          "%12d", totalThroughPut);
   2944 
   2945        fprintf(stdout, "\n");
   2946        return;
   2947    }
   2948 
   2949    fprintf(stdout, "%8s", "opreps");
   2950    fprintf(stdout, "%8s", "cxreps");
   2951    fprintf(stdout, "%12s", "context");
   2952    fprintf(stdout, "%12s", "op");
   2953    fprintf(stdout, "%12s", "time(sec)");
   2954    fprintf(stdout, "%12s", "thrgput");
   2955    fprintf(stdout, "\n");
   2956    fprintf(stdout, "%8s", mode_strings[info->mode]);
   2957    fprintf(stdout, "_%c", (cxonly) ? 'c' : (encrypt) ? 'e'
   2958                                                      : 'd');
   2959    printPR_smpString("%12s", getHighUnitBytes(totalIn), "%12d", totalIn);
   2960 
   2961    td = !td;
   2962    goto print_td;
   2963 }
   2964 
   2965 void
   2966 printmodes()
   2967 {
   2968    bltestCipherMode mode;
   2969    int nummodes = sizeof(mode_strings) / sizeof(char *);
   2970    fprintf(stderr, "%s: Available modes (specify with -m):\n", progName);
   2971    for (mode = 0; mode < nummodes; mode++)
   2972        fprintf(stderr, "%s\n", mode_strings[mode]);
   2973 }
   2974 
   2975 bltestCipherMode
   2976 get_mode(const char *modestring)
   2977 {
   2978    bltestCipherMode mode;
   2979    int nummodes = sizeof(mode_strings) / sizeof(char *);
   2980    for (mode = 0; mode < nummodes; mode++)
   2981        if (PL_strcmp(modestring, mode_strings[mode]) == 0)
   2982            return mode;
   2983    fprintf(stderr, "%s: invalid mode: %s\n", progName, modestring);
   2984    return bltestINVALID;
   2985 }
   2986 
   2987 void
   2988 load_file_data(PLArenaPool *arena, bltestIO *data,
   2989               char *fn, bltestIOMode ioMode)
   2990 {
   2991    PRFileDesc *file;
   2992    data->mode = ioMode;
   2993    data->file = NULL; /* don't use -- not saving anything */
   2994    data->pBuf.data = NULL;
   2995    data->pBuf.len = 0;
   2996    file = PR_Open(fn, PR_RDONLY, 00660);
   2997    if (file) {
   2998        setupIO(arena, data, file, NULL, 0);
   2999        PR_Close(file);
   3000    }
   3001 }
   3002 
   3003 HASH_HashType
   3004 mode_str_to_hash_alg(const SECItem *modeStr)
   3005 {
   3006    bltestCipherMode mode;
   3007    char *tempModeStr = NULL;
   3008    if (!modeStr || modeStr->len == 0)
   3009        return HASH_AlgNULL;
   3010    tempModeStr = PORT_Alloc(modeStr->len + 1);
   3011    if (!tempModeStr)
   3012        return HASH_AlgNULL;
   3013    memcpy(tempModeStr, modeStr->data, modeStr->len);
   3014    tempModeStr[modeStr->len] = '\0';
   3015    mode = get_mode(tempModeStr);
   3016    PORT_Free(tempModeStr);
   3017    switch (mode) {
   3018        case bltestMD2:
   3019            return HASH_AlgMD2;
   3020        case bltestMD5:
   3021            return HASH_AlgMD5;
   3022        case bltestSHA1:
   3023            return HASH_AlgSHA1;
   3024        case bltestSHA224:
   3025            return HASH_AlgSHA224;
   3026        case bltestSHA256:
   3027            return HASH_AlgSHA256;
   3028        case bltestSHA384:
   3029            return HASH_AlgSHA384;
   3030        case bltestSHA512:
   3031            return HASH_AlgSHA512;
   3032        default:
   3033            return HASH_AlgNULL;
   3034    }
   3035 }
   3036 
   3037 void
   3038 get_params(PLArenaPool *arena, bltestParams *params,
   3039           bltestCipherMode mode, int j)
   3040 {
   3041    char filename[256];
   3042    char *modestr = mode_strings[mode];
   3043    bltestIO tempIO;
   3044 
   3045 #ifdef NSS_SOFTOKEN_DOES_RC5
   3046    FILE *file;
   3047    char *mark, *param, *val;
   3048    int index = 0;
   3049 #endif
   3050    switch (mode) {
   3051        case bltestAES_GCM:
   3052        case bltestCHACHA20:
   3053            snprintf(filename, sizeof(filename), "%s/tests/%s/%s%d", testdir, modestr, "aad", j);
   3054            load_file_data(arena, &params->ask.aad, filename, bltestBinary);
   3055        case bltestDES_CBC:
   3056        case bltestDES_EDE_CBC:
   3057 #ifndef NSS_DISABLE_DEPRECATED_RC2
   3058        case bltestRC2_CBC:
   3059 #endif
   3060        case bltestAES_CBC:
   3061        case bltestAES_CTS:
   3062        case bltestAES_CTR:
   3063        case bltestCAMELLIA_CBC:
   3064 #ifndef NSS_DISABLE_DEPRECATED_SEED
   3065        case bltestSEED_CBC:
   3066 #endif
   3067            snprintf(filename, sizeof(filename), "%s/tests/%s/%s%d", testdir, modestr, "iv", j);
   3068            load_file_data(arena, &params->sk.iv, filename, bltestBinary);
   3069        case bltestDES_ECB:
   3070        case bltestDES_EDE_ECB:
   3071 #ifndef NSS_DISABLE_DEPRECATED_RC2
   3072        case bltestRC2_ECB:
   3073 #endif
   3074        case bltestRC4:
   3075        case bltestAES_ECB:
   3076        case bltestCAMELLIA_ECB:
   3077 #ifndef NSS_DISABLE_DEPRECATED_SEED
   3078        case bltestSEED_ECB:
   3079 #endif
   3080            snprintf(filename, sizeof(filename), "%s/tests/%s/%s%d", testdir, modestr, "key", j);
   3081            load_file_data(arena, &params->sk.key, filename, bltestBinary);
   3082            break;
   3083 #ifdef NSS_SOFTOKEN_DOES_RC5
   3084        case bltestRC5_ECB:
   3085        case bltestRC5_CBC:
   3086            snprintf(filename, sizeof(filename), "%s/tests/%s/%s%d", testdir, modestr, "iv", j);
   3087            load_file_data(arena, &params->sk.iv, filename, bltestBinary);
   3088            snprintf(filename, sizeof(filename), "%s/tests/%s/%s%d", testdir, modestr, "key", j);
   3089            load_file_data(arena, &params->sk.key, filename, bltestBinary);
   3090            snprintf(filename, sizeof(filename), "%s/tests/%s/%s%d", testdir, modestr,
   3091                     "params", j);
   3092            file = fopen(filename, "r");
   3093            if (!file)
   3094                return;
   3095            param = malloc(100);
   3096            len = fread(param, 1, 100, file);
   3097            while (index < len) {
   3098                mark = PL_strchr(param, '=');
   3099                *mark = '\0';
   3100                val = mark + 1;
   3101                mark = PL_strchr(val, '\n');
   3102                *mark = '\0';
   3103                if (PL_strcmp(param, "rounds") == 0) {
   3104                    params->rc5.rounds = atoi(val);
   3105                } else if (PL_strcmp(param, "wordsize") == 0) {
   3106                    params->rc5.wordsize = atoi(val);
   3107                }
   3108                index += PL_strlen(param) + PL_strlen(val) + 2;
   3109                param = mark + 1;
   3110            }
   3111            break;
   3112 #endif
   3113        case bltestRSA_PSS:
   3114            snprintf(filename, sizeof(filename), "%s/tests/%s/%s%d", testdir, modestr, "ciphertext", j);
   3115            load_file_data(arena, &params->asymk.sig, filename, bltestBase64Encoded);
   3116        /* fall through */
   3117        case bltestRSA_OAEP:
   3118            snprintf(filename, sizeof(filename), "%s/tests/%s/%s%d", testdir, modestr, "seed", j);
   3119            load_file_data(arena, &params->asymk.cipherParams.rsa.seed,
   3120                           filename, bltestBase64Encoded);
   3121 
   3122            snprintf(filename, sizeof(filename), "%s/tests/%s/%s%d", testdir, modestr, "hash", j);
   3123            load_file_data(arena, &tempIO, filename, bltestBinary);
   3124            params->asymk.cipherParams.rsa.hashAlg =
   3125                mode_str_to_hash_alg(&tempIO.buf);
   3126 
   3127            snprintf(filename, sizeof(filename), "%s/tests/%s/%s%d", testdir, modestr, "maskhash", j);
   3128            load_file_data(arena, &tempIO, filename, bltestBinary);
   3129            params->asymk.cipherParams.rsa.maskHashAlg =
   3130                mode_str_to_hash_alg(&tempIO.buf);
   3131        /* fall through */
   3132        case bltestRSA:
   3133            snprintf(filename, sizeof(filename), "%s/tests/%s/%s%d", testdir, modestr, "key", j);
   3134            load_file_data(arena, &params->asymk.key, filename,
   3135                           bltestBase64Encoded);
   3136            params->asymk.privKey =
   3137                (void *)rsakey_from_filedata(arena, &params->asymk.key.buf);
   3138            break;
   3139        case bltestDSA:
   3140            snprintf(filename, sizeof(filename), "%s/tests/%s/%s%d", testdir, modestr, "key", j);
   3141            load_file_data(arena, &params->asymk.key, filename, bltestBase64Encoded);
   3142            params->asymk.privKey =
   3143                (void *)dsakey_from_filedata(arena, &params->asymk.key.buf);
   3144            snprintf(filename, sizeof(filename), "%s/tests/%s/%s%d", testdir, modestr, "pqg", j);
   3145            load_file_data(arena, &params->asymk.cipherParams.dsa.pqgdata, filename,
   3146                           bltestBase64Encoded);
   3147            params->asymk.cipherParams.dsa.pqg =
   3148                pqg_from_filedata(arena, &params->asymk.cipherParams.dsa.pqgdata.buf);
   3149            snprintf(filename, sizeof(filename), "%s/tests/%s/%s%d", testdir, modestr, "keyseed", j);
   3150            load_file_data(arena, &params->asymk.cipherParams.dsa.keyseed, filename,
   3151                           bltestBase64Encoded);
   3152            snprintf(filename, sizeof(filename), "%s/tests/%s/%s%d", testdir, modestr, "sigseed", j);
   3153            load_file_data(arena, &params->asymk.cipherParams.dsa.sigseed, filename,
   3154                           bltestBase64Encoded);
   3155            snprintf(filename, sizeof(filename), "%s/tests/%s/%s%d", testdir, modestr, "ciphertext", j);
   3156            load_file_data(arena, &params->asymk.sig, filename, bltestBase64Encoded);
   3157            break;
   3158        case bltestECDSA:
   3159            snprintf(filename, sizeof(filename), "%s/tests/%s/%s%d", testdir, modestr, "key", j);
   3160            load_file_data(arena, &params->asymk.key, filename, bltestBase64Encoded);
   3161            params->asymk.privKey =
   3162                (void *)eckey_from_filedata(arena, &params->asymk.key.buf);
   3163            snprintf(filename, sizeof(filename), "%s/tests/%s/%s%d", testdir, modestr, "sigseed", j);
   3164            load_file_data(arena, &params->asymk.cipherParams.ecdsa.sigseed,
   3165                           filename, bltestBase64Encoded);
   3166            snprintf(filename, sizeof(filename), "%s/tests/%s/%s%d", testdir, modestr, "ciphertext", j);
   3167            load_file_data(arena, &params->asymk.sig, filename, bltestBase64Encoded);
   3168            break;
   3169        case bltestMD2:
   3170        case bltestMD5:
   3171        case bltestSHA1:
   3172        case bltestSHA224:
   3173        case bltestSHA256:
   3174        case bltestSHA384:
   3175        case bltestSHA512:
   3176            /*params->hash.restart = PR_TRUE;*/
   3177            params->hash.restart = PR_FALSE;
   3178            break;
   3179        default:
   3180            break;
   3181    }
   3182 }
   3183 
   3184 SECStatus
   3185 verify_self_test(bltestIO *result, bltestIO *cmp, bltestCipherMode mode,
   3186                 PRBool forward, SECStatus sigstatus)
   3187 {
   3188    PRBool equal;
   3189    char *modestr = mode_strings[mode];
   3190    equal = SECITEM_ItemsAreEqual(&result->pBuf, &cmp->buf);
   3191    if (is_sigCipher(mode)) {
   3192        if (forward) {
   3193            if (equal) {
   3194                printf("Signature self-test for %s passed.\n", modestr);
   3195            } else {
   3196                printf("Signature self-test for %s failed!\n", modestr);
   3197            }
   3198            return equal ? SECSuccess : SECFailure;
   3199        } else {
   3200            if (sigstatus == SECSuccess) {
   3201                printf("Verification self-test for %s passed.\n", modestr);
   3202            } else {
   3203                printf("Verification self-test for %s failed!\n", modestr);
   3204            }
   3205            return sigstatus;
   3206        }
   3207    } else if (is_hashCipher(mode)) {
   3208        if (equal) {
   3209            printf("Hash self-test for %s passed.\n", modestr);
   3210        } else {
   3211            printf("Hash self-test for %s failed!\n", modestr);
   3212        }
   3213    } else {
   3214        if (forward) {
   3215            if (equal) {
   3216                printf("Encryption self-test for %s passed.\n", modestr);
   3217            } else {
   3218                printf("Encryption self-test for %s failed!\n", modestr);
   3219            }
   3220        } else {
   3221            if (equal) {
   3222                printf("Decryption self-test for %s passed.\n", modestr);
   3223            } else {
   3224                printf("Decryption self-test for %s failed!\n", modestr);
   3225            }
   3226        }
   3227    }
   3228    return equal ? SECSuccess : SECFailure;
   3229 }
   3230 
   3231 static SECStatus
   3232 ReadFileToItem(PLArenaPool *arena, SECItem *dst, const char *filename)
   3233 {
   3234    SECItem tmp = { siBuffer, NULL, 0 };
   3235    PRFileDesc *file;
   3236    SECStatus rv;
   3237 
   3238    file = PR_Open(filename, PR_RDONLY, 00660);
   3239    if (!file) {
   3240        return SECFailure;
   3241    }
   3242    rv = SECU_FileToItem(&tmp, file);
   3243    rv |= SECITEM_CopyItem(arena, dst, &tmp);
   3244    SECITEM_FreeItem(&tmp, PR_FALSE);
   3245    PR_Close(file);
   3246    return rv;
   3247 }
   3248 
   3249 static SECStatus
   3250 blapi_selftest(bltestCipherMode *modes, int numModes, int inoff, int outoff,
   3251               PRBool encrypt, PRBool decrypt)
   3252 {
   3253    bltestCipherInfo cipherInfo;
   3254    bltestIO pt, ct;
   3255    bltestCipherMode mode;
   3256    bltestParams *params;
   3257    unsigned int i, j, nummodes, numtests;
   3258    char *modestr;
   3259    char filename[256];
   3260    PLArenaPool *arena;
   3261    SECItem item;
   3262    SECStatus rv = SECSuccess, srv;
   3263 
   3264    PORT_Memset(&cipherInfo, 0, sizeof(cipherInfo));
   3265    arena = PORT_NewArena(BLTEST_DEFAULT_CHUNKSIZE);
   3266    cipherInfo.arena = arena;
   3267 
   3268    nummodes = (numModes == 0) ? NUMMODES : numModes;
   3269    for (i = 0; i < nummodes; i++) {
   3270        if (numModes > 0)
   3271            mode = modes[i];
   3272        else
   3273            mode = i;
   3274        if (mode == bltestINVALID) {
   3275            fprintf(stderr, "%s: Skipping invalid mode.\n", progName);
   3276            continue;
   3277        }
   3278        modestr = mode_strings[mode];
   3279        cipherInfo.mode = mode;
   3280        params = &cipherInfo.params;
   3281        /* get the number of tests in the directory */
   3282        snprintf(filename, sizeof(filename), "%s/tests/%s/%s", testdir, modestr, "numtests");
   3283        if (ReadFileToItem(arena, &item, filename) != SECSuccess) {
   3284            fprintf(stderr, "%s: Cannot read file %s.\n", progName, filename);
   3285            rv = SECFailure;
   3286            continue;
   3287        }
   3288        /* loop over the tests in the directory */
   3289        numtests = 0;
   3290        for (j = 0; j < item.len; j++) {
   3291            if (!isdigit(item.data[j])) {
   3292                break;
   3293            }
   3294            numtests *= 10;
   3295            numtests += (int)(item.data[j] - '0');
   3296        }
   3297        for (j = 0; j < numtests; j++) {
   3298            snprintf(filename, sizeof(filename), "%s/tests/%s/%s%d", testdir, modestr,
   3299                     "plaintext", j);
   3300            load_file_data(arena, &pt, filename,
   3301                           is_sigCipher(mode) ? bltestBase64Encoded
   3302                                              : bltestBinary);
   3303            snprintf(filename, sizeof(filename), "%s/tests/%s/%s%d", testdir, modestr,
   3304                     "ciphertext", j);
   3305            load_file_data(arena, &ct, filename, bltestBase64Encoded);
   3306 
   3307            get_params(arena, params, mode, j);
   3308            /* Forward Operation (Encrypt/Sign/Hash)
   3309            ** Align the input buffer (plaintext) according to request
   3310            ** then perform operation and compare to ciphertext
   3311            */
   3312            if (encrypt) {
   3313                rv |= bltestCopyIO(arena, &cipherInfo.input, &pt);
   3314                misalignBuffer(arena, &cipherInfo.input, inoff);
   3315                memset(&cipherInfo.output.buf, 0, sizeof cipherInfo.output.buf);
   3316                rv |= cipherInit(&cipherInfo, PR_TRUE);
   3317                misalignBuffer(arena, &cipherInfo.output, outoff);
   3318                rv |= cipherDoOp(&cipherInfo);
   3319                rv |= cipherFinish(&cipherInfo);
   3320                rv |= verify_self_test(&cipherInfo.output,
   3321                                       &ct, mode, PR_TRUE, SECSuccess);
   3322                /* If testing hash, only one op to test */
   3323                if (is_hashCipher(mode))
   3324                    continue;
   3325                if (is_sigCipher(mode)) {
   3326                    /* Verify operations support detached signature files. For
   3327                    ** consistency between tests that run Sign/Verify back to
   3328                    ** back (eg: self-tests) and tests that are only running
   3329                    ** verify operations, copy the output into the sig buf,
   3330                    ** and then copy the sig buf back out when verifying. For
   3331                    ** self-tests, this is unnecessary copying, but for
   3332                    ** verify-only operations, this ensures that the output
   3333                    ** buffer is properly configured
   3334                    */
   3335                    rv |= bltestCopyIO(arena, &params->asymk.sig, &cipherInfo.output);
   3336                }
   3337            }
   3338            if (!decrypt)
   3339                continue;
   3340            /* Reverse Operation (Decrypt/Verify)
   3341            ** Align the input buffer (ciphertext) according to request
   3342            ** then perform operation and compare to plaintext
   3343            */
   3344            if (is_sigCipher(mode)) {
   3345                rv |= bltestCopyIO(arena, &cipherInfo.input, &pt);
   3346                rv |= bltestCopyIO(arena, &cipherInfo.output, &params->asymk.sig);
   3347            } else {
   3348                rv |= bltestCopyIO(arena, &cipherInfo.input, &ct);
   3349                memset(&cipherInfo.output.buf, 0, sizeof cipherInfo.output.buf);
   3350            }
   3351            misalignBuffer(arena, &cipherInfo.input, inoff);
   3352            rv |= cipherInit(&cipherInfo, PR_FALSE);
   3353            misalignBuffer(arena, &cipherInfo.output, outoff);
   3354            srv = SECSuccess;
   3355            srv |= cipherDoOp(&cipherInfo);
   3356            rv |= cipherFinish(&cipherInfo);
   3357            rv |= verify_self_test(&cipherInfo.output,
   3358                                   &pt, mode, PR_FALSE, srv);
   3359        }
   3360    }
   3361    PORT_FreeArena(arena, PR_FALSE);
   3362    return rv;
   3363 }
   3364 
   3365 SECStatus
   3366 dump_file(bltestCipherMode mode, char *filename)
   3367 {
   3368    bltestIO keydata;
   3369    PLArenaPool *arena = NULL;
   3370    arena = PORT_NewArena(BLTEST_DEFAULT_CHUNKSIZE);
   3371    if (!arena) {
   3372        return SECFailure;
   3373    }
   3374    if (mode == bltestRSA || mode == bltestRSA_PSS || mode == bltestRSA_OAEP) {
   3375        RSAPrivateKey *key;
   3376        load_file_data(arena, &keydata, filename, bltestBase64Encoded);
   3377        key = rsakey_from_filedata(arena, &keydata.buf);
   3378        dump_rsakey(key);
   3379    } else if (mode == bltestDSA) {
   3380 #if 0
   3381    PQGParams *pqg;
   3382    get_file_data(filename, &item, PR_TRUE);
   3383    pqg = pqg_from_filedata(&item);
   3384    dump_pqg(pqg);
   3385 #endif
   3386        DSAPrivateKey *key;
   3387        load_file_data(arena, &keydata, filename, bltestBase64Encoded);
   3388        key = dsakey_from_filedata(arena, &keydata.buf);
   3389        dump_dsakey(key);
   3390    } else if (mode == bltestECDSA) {
   3391        ECPrivateKey *key;
   3392        load_file_data(arena, &keydata, filename, bltestBase64Encoded);
   3393        key = eckey_from_filedata(arena, &keydata.buf);
   3394        dump_eckey(key);
   3395    }
   3396    PORT_FreeArena(arena, PR_FALSE);
   3397    return SECFailure;
   3398 }
   3399 
   3400 void
   3401 ThreadExecTest(void *data)
   3402 {
   3403    bltestCipherInfo *cipherInfo = (bltestCipherInfo *)data;
   3404 
   3405    if (cipherInfo->mCarlo == PR_TRUE) {
   3406        int mciter;
   3407        for (mciter = 0; mciter < 10000; mciter++) {
   3408            cipherDoOp(cipherInfo);
   3409            memcpy(cipherInfo->input.buf.data,
   3410                   cipherInfo->output.buf.data,
   3411                   cipherInfo->input.buf.len);
   3412        }
   3413    } else {
   3414        cipherDoOp(cipherInfo);
   3415    }
   3416    cipherFinish(cipherInfo);
   3417 }
   3418 
   3419 static void
   3420 rsaPrivKeyReset(RSAPrivateKey *tstKey)
   3421 {
   3422    PLArenaPool *arena;
   3423 
   3424    tstKey->version.data = NULL;
   3425    tstKey->version.len = 0;
   3426    tstKey->modulus.data = NULL;
   3427    tstKey->modulus.len = 0;
   3428    tstKey->publicExponent.data = NULL;
   3429    tstKey->publicExponent.len = 0;
   3430    tstKey->privateExponent.data = NULL;
   3431    tstKey->privateExponent.len = 0;
   3432    tstKey->prime1.data = NULL;
   3433    tstKey->prime1.len = 0;
   3434    tstKey->prime2.data = NULL;
   3435    tstKey->prime2.len = 0;
   3436    tstKey->exponent1.data = NULL;
   3437    tstKey->exponent1.len = 0;
   3438    tstKey->exponent2.data = NULL;
   3439    tstKey->exponent2.len = 0;
   3440    tstKey->coefficient.data = NULL;
   3441    tstKey->coefficient.len = 0;
   3442 
   3443    arena = tstKey->arena;
   3444    tstKey->arena = NULL;
   3445    if (arena) {
   3446        PORT_FreeArena(arena, PR_TRUE);
   3447    }
   3448 }
   3449 
   3450 #define RSA_TEST_EQUAL(comp)                                   \
   3451    if (!SECITEM_ItemsAreEqual(&(src->comp), &(dest->comp))) { \
   3452        fprintf(stderr, "key->" #comp " not equal");           \
   3453        if (src->comp.len != dest->comp.len) {                 \
   3454            fprintf(stderr, "src_len = %d, dest_len = %d",     \
   3455                    src->comp.len, dest->comp.len);            \
   3456        }                                                      \
   3457        fprintf(stderr, "\n");                                 \
   3458        areEqual = PR_FALSE;                                   \
   3459    }
   3460 
   3461 static PRBool
   3462 rsaPrivKeysAreEqual(RSAPrivateKey *src, RSAPrivateKey *dest)
   3463 {
   3464    PRBool areEqual = PR_TRUE;
   3465    RSA_TEST_EQUAL(modulus)
   3466    RSA_TEST_EQUAL(publicExponent)
   3467    RSA_TEST_EQUAL(privateExponent)
   3468    RSA_TEST_EQUAL(prime1)
   3469    RSA_TEST_EQUAL(prime2)
   3470    RSA_TEST_EQUAL(exponent1)
   3471    RSA_TEST_EQUAL(exponent2)
   3472    RSA_TEST_EQUAL(coefficient)
   3473    if (!areEqual) {
   3474        fprintf(stderr, "original key:\n");
   3475        dump_rsakey(src);
   3476        fprintf(stderr, "recreated key:\n");
   3477        dump_rsakey(dest);
   3478    }
   3479    return areEqual;
   3480 }
   3481 
   3482 static int
   3483 doRSAPopulateTestKV()
   3484 {
   3485    RSAPrivateKey tstKey = { 0 };
   3486    SECStatus rv;
   3487    int failed = 0;
   3488    int i;
   3489 
   3490    tstKey.arena = NULL;
   3491 
   3492    /* Test public exponent, private exponent, modulus cases from
   3493     * pkcs1v15sign-vectors.txt. Some are valid PKCS#1 keys but not valid RSA
   3494     * ones (de = 1 mod lcm(p − 1, q − 1))
   3495     */
   3496    for (i = 0; i < PR_ARRAY_SIZE(PKCS1_VECTORS); ++i) {
   3497        struct pkcs1_test_vector *v = &PKCS1_VECTORS[i];
   3498 
   3499        rsaPrivKeyReset(&tstKey);
   3500        tstKey.privateExponent.data = v->d;
   3501        tstKey.privateExponent.len = v->d_len;
   3502        tstKey.publicExponent.data = v->e;
   3503        tstKey.publicExponent.len = v->e_len;
   3504        tstKey.modulus.data = v->n;
   3505        tstKey.modulus.len = v->n_len;
   3506 
   3507        rv = RSA_PopulatePrivateKey(&tstKey);
   3508        if (rv != SECSuccess) {
   3509            fprintf(stderr, "RSA Populate failed: pkcs1v15sign-vector %d\n", i);
   3510            failed = 1;
   3511        } else if (memcmp(v->q, tstKey.prime1.data, v->q_len) ||
   3512                   tstKey.prime1.len != v->q_len) {
   3513            fprintf(stderr, "RSA Populate key mismatch: pkcs1v15sign-vector %d q\n", i);
   3514            failed = 1;
   3515        } else if (memcmp(v->p, tstKey.prime2.data, v->p_len) ||
   3516                   tstKey.prime1.len != v->p_len) {
   3517            fprintf(stderr, "RSA Populate key mismatch: pkcs1v15sign-vector %d p\n", i);
   3518            failed = 1;
   3519        } else {
   3520            fprintf(stderr, "RSA Populate success: pkcs1v15sign-vector %d p\n", i);
   3521        }
   3522    }
   3523 
   3524    PORT_FreeArena(tstKey.arena, PR_TRUE);
   3525    return failed;
   3526 }
   3527 
   3528 /*
   3529 * Test the RSA populate command to see that it can really build
   3530 * keys from its components.
   3531 */
   3532 static int
   3533 doRSAPopulateTest(unsigned int keySize, unsigned long exponent)
   3534 {
   3535    RSAPrivateKey *srcKey;
   3536    RSAPrivateKey tstKey = { 0 };
   3537    SECItem expitem = { 0, 0, 0 };
   3538    SECStatus rv;
   3539    unsigned char pubExp[32];
   3540    int expLen = 0;
   3541    int failed = 0;
   3542    int i;
   3543 
   3544    for (i = 0; i < sizeof(unsigned long); i++) {
   3545        int shift = (sizeof(unsigned long) - i - 1) * 8;
   3546        if (expLen || (exponent && ((unsigned long)0xffL << shift))) {
   3547            pubExp[expLen] = (unsigned char)((exponent >> shift) & 0xff);
   3548            expLen++;
   3549        }
   3550    }
   3551 
   3552    expitem.data = pubExp;
   3553    expitem.len = expLen;
   3554 
   3555    srcKey = RSA_NewKey(keySize, &expitem);
   3556    if (srcKey == NULL) {
   3557        fprintf(stderr, "RSA Key Gen failed");
   3558        return -1;
   3559    }
   3560 
   3561    /* test the basic case - most common, public exponent, modulus, prime */
   3562    tstKey.arena = NULL;
   3563    rsaPrivKeyReset(&tstKey);
   3564 
   3565    tstKey.publicExponent = srcKey->publicExponent;
   3566    tstKey.modulus = srcKey->modulus;
   3567    tstKey.prime1 = srcKey->prime1;
   3568 
   3569    rv = RSA_PopulatePrivateKey(&tstKey);
   3570    if (rv != SECSuccess) {
   3571        fprintf(stderr, "RSA Populate failed: pubExp mod p\n");
   3572        failed = 1;
   3573    } else if (!rsaPrivKeysAreEqual(&tstKey, srcKey)) {
   3574        fprintf(stderr, "RSA Populate key mismatch: pubExp mod p\n");
   3575        failed = 1;
   3576    }
   3577 
   3578    /* test the basic2 case, public exponent, modulus, prime2 */
   3579    rsaPrivKeyReset(&tstKey);
   3580 
   3581    tstKey.publicExponent = srcKey->publicExponent;
   3582    tstKey.modulus = srcKey->modulus;
   3583    tstKey.prime1 = srcKey->prime2; /* test with q in the prime1 position */
   3584 
   3585    rv = RSA_PopulatePrivateKey(&tstKey);
   3586    if (rv != SECSuccess) {
   3587        fprintf(stderr, "RSA Populate failed: pubExp mod q\n");
   3588        failed = 1;
   3589    } else if (!rsaPrivKeysAreEqual(&tstKey, srcKey)) {
   3590        fprintf(stderr, "RSA Populate key mismatch: pubExp mod q\n");
   3591        failed = 1;
   3592    }
   3593 
   3594    /* test the medium case, private exponent, prime1, prime2 */
   3595    rsaPrivKeyReset(&tstKey);
   3596 
   3597    tstKey.privateExponent = srcKey->privateExponent;
   3598    tstKey.prime1 = srcKey->prime2; /* purposefully swap them to make */
   3599    tstKey.prime2 = srcKey->prime1; /* sure populated swaps them back */
   3600 
   3601    rv = RSA_PopulatePrivateKey(&tstKey);
   3602    if (rv != SECSuccess) {
   3603        fprintf(stderr, "RSA Populate failed: privExp p q\n");
   3604        failed = 1;
   3605    } else if (!rsaPrivKeysAreEqual(&tstKey, srcKey)) {
   3606        fprintf(stderr, "RSA Populate key mismatch: privExp  p q\n");
   3607        failed = 1;
   3608    }
   3609 
   3610    /* test the advanced case, public exponent, private exponent, prime2 */
   3611    rsaPrivKeyReset(&tstKey);
   3612 
   3613    tstKey.privateExponent = srcKey->privateExponent;
   3614    tstKey.publicExponent = srcKey->publicExponent;
   3615    tstKey.prime2 = srcKey->prime2; /* use q in the prime2 position */
   3616 
   3617    rv = RSA_PopulatePrivateKey(&tstKey);
   3618    if (rv != SECSuccess) {
   3619        fprintf(stderr, "RSA Populate failed: pubExp privExp q\n");
   3620        fprintf(stderr, " - not fatal\n");
   3621        /* it's possible that we can't uniquely determine the original key
   3622         * from just the exponents and prime. Populate returns an error rather
   3623         * than return the wrong key. */
   3624    } else if (!rsaPrivKeysAreEqual(&tstKey, srcKey)) {
   3625        /* if we returned a key, it *must* be correct */
   3626        fprintf(stderr, "RSA Populate key mismatch: pubExp privExp  q\n");
   3627        rv = RSA_PrivateKeyCheck(&tstKey);
   3628        failed = 1;
   3629    }
   3630 
   3631    /* test the advanced case2, public exponent, private exponent, modulus */
   3632    rsaPrivKeyReset(&tstKey);
   3633 
   3634    tstKey.privateExponent = srcKey->privateExponent;
   3635    tstKey.publicExponent = srcKey->publicExponent;
   3636    tstKey.modulus = srcKey->modulus;
   3637 
   3638    rv = RSA_PopulatePrivateKey(&tstKey);
   3639    if (rv != SECSuccess) {
   3640        fprintf(stderr, "RSA Populate failed: pubExp privExp mod\n");
   3641        failed = 1;
   3642    } else if (!rsaPrivKeysAreEqual(&tstKey, srcKey)) {
   3643        fprintf(stderr, "RSA Populate key mismatch: pubExp privExp  mod\n");
   3644        failed = 1;
   3645    }
   3646 
   3647    PORT_FreeArena(srcKey->arena, PR_TRUE);
   3648    return failed ? -1 : 0;
   3649 }
   3650 
   3651 /* bltest commands */
   3652 enum {
   3653    cmd_Decrypt = 0,
   3654    cmd_Encrypt,
   3655    cmd_FIPS,
   3656    cmd_Hash,
   3657    cmd_Nonce,
   3658    cmd_Dump,
   3659    cmd_RSAPopulate,
   3660    cmd_RSAPopulateKV,
   3661    cmd_Sign,
   3662    cmd_SelfTest,
   3663    cmd_Verify
   3664 };
   3665 
   3666 /* bltest options */
   3667 enum {
   3668    opt_B64 = 0,
   3669    opt_BufSize,
   3670    opt_Restart,
   3671    opt_SelfTestDir,
   3672    opt_Exponent,
   3673    opt_SigFile,
   3674    opt_KeySize,
   3675    opt_Hex,
   3676    opt_Input,
   3677    opt_PQGFile,
   3678    opt_Key,
   3679    opt_HexWSpc,
   3680    opt_Mode,
   3681    opt_CurveName,
   3682    opt_Output,
   3683    opt_Repetitions,
   3684    opt_ZeroBuf,
   3685    opt_Rounds,
   3686    opt_Seed,
   3687    opt_SigSeedFile,
   3688    opt_CXReps,
   3689    opt_IV,
   3690    opt_WordSize,
   3691    opt_UseSeed,
   3692    opt_UseSigSeed,
   3693    opt_SeedFile,
   3694    opt_AAD,
   3695    opt_InputOffset,
   3696    opt_OutputOffset,
   3697    opt_MonteCarlo,
   3698    opt_ThreadNum,
   3699    opt_SecondsToRun,
   3700    opt_CmdLine
   3701 };
   3702 
   3703 static secuCommandFlag bltest_commands[] = {
   3704    { /* cmd_Decrypt */ 'D', PR_FALSE, 0, PR_FALSE },
   3705    { /* cmd_Encrypt */ 'E', PR_FALSE, 0, PR_FALSE },
   3706    { /* cmd_FIPS */ 'F', PR_FALSE, 0, PR_FALSE },
   3707    { /* cmd_Hash */ 'H', PR_FALSE, 0, PR_FALSE },
   3708    { /* cmd_Nonce */ 'N', PR_FALSE, 0, PR_FALSE },
   3709    { /* cmd_Dump */ 'P', PR_FALSE, 0, PR_FALSE },
   3710    { /* cmd_RSAPopulate */ 'R', PR_FALSE, 0, PR_FALSE },
   3711    { /* cmd_RSAPopulateKV */ 'K', PR_FALSE, 0, PR_FALSE },
   3712    { /* cmd_Sign */ 'S', PR_FALSE, 0, PR_FALSE },
   3713    { /* cmd_SelfTest */ 'T', PR_FALSE, 0, PR_FALSE },
   3714    { /* cmd_Verify */ 'V', PR_FALSE, 0, PR_FALSE }
   3715 };
   3716 
   3717 static secuCommandFlag bltest_options[] = {
   3718    { /* opt_B64 */ 'a', PR_FALSE, 0, PR_FALSE },
   3719    { /* opt_BufSize */ 'b', PR_TRUE, 0, PR_FALSE },
   3720    { /* opt_Restart */ 'c', PR_FALSE, 0, PR_FALSE },
   3721    { /* opt_SelfTestDir */ 'd', PR_TRUE, 0, PR_FALSE },
   3722    { /* opt_Exponent */ 'e', PR_TRUE, 0, PR_FALSE },
   3723    { /* opt_SigFile */ 'f', PR_TRUE, 0, PR_FALSE },
   3724    { /* opt_KeySize */ 'g', PR_TRUE, 0, PR_FALSE },
   3725    { /* opt_Hex */ 'h', PR_FALSE, 0, PR_FALSE },
   3726    { /* opt_Input */ 'i', PR_TRUE, 0, PR_FALSE },
   3727    { /* opt_PQGFile */ 'j', PR_TRUE, 0, PR_FALSE },
   3728    { /* opt_Key */ 'k', PR_TRUE, 0, PR_FALSE },
   3729    { /* opt_HexWSpc */ 'l', PR_FALSE, 0, PR_FALSE },
   3730    { /* opt_Mode */ 'm', PR_TRUE, 0, PR_FALSE },
   3731    { /* opt_CurveName */ 'n', PR_TRUE, 0, PR_FALSE },
   3732    { /* opt_Output */ 'o', PR_TRUE, 0, PR_FALSE },
   3733    { /* opt_Repetitions */ 'p', PR_TRUE, 0, PR_FALSE },
   3734    { /* opt_ZeroBuf */ 'q', PR_FALSE, 0, PR_FALSE },
   3735    { /* opt_Rounds */ 'r', PR_TRUE, 0, PR_FALSE },
   3736    { /* opt_Seed */ 's', PR_TRUE, 0, PR_FALSE },
   3737    { /* opt_SigSeedFile */ 't', PR_TRUE, 0, PR_FALSE },
   3738    { /* opt_CXReps */ 'u', PR_TRUE, 0, PR_FALSE },
   3739    { /* opt_IV */ 'v', PR_TRUE, 0, PR_FALSE },
   3740    { /* opt_WordSize */ 'w', PR_TRUE, 0, PR_FALSE },
   3741    { /* opt_UseSeed */ 'x', PR_FALSE, 0, PR_FALSE },
   3742    { /* opt_UseSigSeed */ 'y', PR_FALSE, 0, PR_FALSE },
   3743    { /* opt_SeedFile */ 'z', PR_FALSE, 0, PR_FALSE },
   3744    { /* opt_AAD */ 0, PR_TRUE, 0, PR_FALSE, "aad" },
   3745    { /* opt_InputOffset */ '1', PR_TRUE, 0, PR_FALSE },
   3746    { /* opt_OutputOffset */ '2', PR_TRUE, 0, PR_FALSE },
   3747    { /* opt_MonteCarlo */ '3', PR_FALSE, 0, PR_FALSE },
   3748    { /* opt_ThreadNum */ '4', PR_TRUE, 0, PR_FALSE },
   3749    { /* opt_SecondsToRun */ '5', PR_TRUE, 0, PR_FALSE },
   3750    { /* opt_CmdLine */ '-', PR_FALSE, 0, PR_FALSE }
   3751 };
   3752 
   3753 int
   3754 main(int argc, char **argv)
   3755 {
   3756    SECStatus rv = SECFailure;
   3757 
   3758    double totalTime = 0.0;
   3759    PRIntervalTime time1, time2;
   3760    PRFileDesc *outfile = NULL;
   3761    bltestCipherInfo *cipherInfoListHead, *cipherInfo = NULL;
   3762    bltestIOMode ioMode;
   3763    int bufsize, exponent, curThrdNum;
   3764    char *curveName = NULL;
   3765    int i, commandsEntered;
   3766    int inoff, outoff;
   3767    int threads = 1;
   3768 
   3769    secuCommand bltest;
   3770    bltest.numCommands = sizeof(bltest_commands) / sizeof(secuCommandFlag);
   3771    bltest.numOptions = sizeof(bltest_options) / sizeof(secuCommandFlag);
   3772    bltest.commands = bltest_commands;
   3773    bltest.options = bltest_options;
   3774 
   3775    progName = strrchr(argv[0], '/');
   3776    if (!progName)
   3777        progName = strrchr(argv[0], '\\');
   3778    progName = progName ? progName + 1 : argv[0];
   3779 
   3780    rv = NSS_InitializePRErrorTable();
   3781    if (rv != SECSuccess) {
   3782        SECU_PrintPRandOSError(progName);
   3783        return -1;
   3784    }
   3785    rv = RNG_RNGInit();
   3786    if (rv != SECSuccess) {
   3787        SECU_PrintPRandOSError(progName);
   3788        return -1;
   3789    }
   3790    rv = BL_Init();
   3791    if (rv != SECSuccess) {
   3792        SECU_PrintPRandOSError(progName);
   3793        return -1;
   3794    }
   3795    RNG_SystemInfoForRNG();
   3796 
   3797    rv = SECU_ParseCommandLine(argc, argv, progName, &bltest);
   3798    if (rv == SECFailure) {
   3799        fprintf(stderr, "%s: command line parsing error!\n", progName);
   3800        goto print_usage;
   3801    }
   3802    rv = SECFailure;
   3803 
   3804    cipherInfo = PORT_ZNew(bltestCipherInfo);
   3805    cipherInfoListHead = cipherInfo;
   3806 
   3807    /* Check the number of commands entered on the command line. */
   3808    commandsEntered = 0;
   3809    for (i = 0; i < bltest.numCommands; i++)
   3810        if (bltest.commands[i].activated)
   3811            commandsEntered++;
   3812 
   3813    if (commandsEntered > 1 &&
   3814        !(commandsEntered == 2 && bltest.commands[cmd_SelfTest].activated)) {
   3815        fprintf(stderr, "%s: one command at a time!\n", progName);
   3816        goto print_usage;
   3817    }
   3818 
   3819    if (commandsEntered == 0) {
   3820        fprintf(stderr, "%s: you must enter a command!\n", progName);
   3821        goto print_usage;
   3822    }
   3823 
   3824    if (bltest.commands[cmd_Sign].activated)
   3825        bltest.commands[cmd_Encrypt].activated = PR_TRUE;
   3826    if (bltest.commands[cmd_Verify].activated)
   3827        bltest.commands[cmd_Decrypt].activated = PR_TRUE;
   3828    if (bltest.commands[cmd_Hash].activated)
   3829        bltest.commands[cmd_Encrypt].activated = PR_TRUE;
   3830 
   3831    inoff = outoff = 0;
   3832    if (bltest.options[opt_InputOffset].activated)
   3833        inoff = PORT_Atoi(bltest.options[opt_InputOffset].arg);
   3834    if (bltest.options[opt_OutputOffset].activated)
   3835        outoff = PORT_Atoi(bltest.options[opt_OutputOffset].arg);
   3836 
   3837    testdir = (bltest.options[opt_SelfTestDir].activated) ? strdup(bltest.options[opt_SelfTestDir].arg)
   3838                                                          : ".";
   3839 
   3840    /*
   3841     * Handle three simple cases first
   3842     */
   3843 
   3844    /* test the RSA_PopulatePrivateKey function with known vectors */
   3845    if (bltest.commands[cmd_RSAPopulateKV].activated) {
   3846        PORT_Free(cipherInfo);
   3847        return doRSAPopulateTestKV();
   3848    }
   3849 
   3850    /* test the RSA_PopulatePrivateKey function */
   3851    if (bltest.commands[cmd_RSAPopulate].activated) {
   3852        unsigned int keySize = 1024;
   3853        unsigned long keyExponent = 65537;
   3854        int rounds = 1;
   3855        int ret = -1;
   3856 
   3857        if (bltest.options[opt_KeySize].activated) {
   3858            keySize = PORT_Atoi(bltest.options[opt_KeySize].arg);
   3859        }
   3860        if (bltest.options[opt_Rounds].activated) {
   3861            rounds = PORT_Atoi(bltest.options[opt_Rounds].arg);
   3862        }
   3863        if (bltest.options[opt_Exponent].activated) {
   3864            keyExponent = PORT_Atoi(bltest.options[opt_Exponent].arg);
   3865        }
   3866 
   3867        for (i = 0; i < rounds; i++) {
   3868            printf("Running RSA Populate test round %d\n", i);
   3869            ret = doRSAPopulateTest(keySize, keyExponent);
   3870            if (ret != 0) {
   3871                break;
   3872            }
   3873        }
   3874        if (ret != 0) {
   3875            fprintf(stderr, "RSA Populate test round %d: FAILED\n", i);
   3876        }
   3877        PORT_Free(cipherInfo);
   3878        return ret;
   3879    }
   3880 
   3881    /* Do BLAPI self-test */
   3882    if (bltest.commands[cmd_SelfTest].activated) {
   3883        PRBool encrypt = PR_TRUE, decrypt = PR_TRUE;
   3884        /* user may specified a set of ciphers to test.  parse them. */
   3885        bltestCipherMode modesToTest[NUMMODES];
   3886        int numModesToTest = 0;
   3887        char *tok, *str;
   3888        str = bltest.options[opt_Mode].arg;
   3889        while (str) {
   3890            tok = strchr(str, ',');
   3891            if (tok)
   3892                *tok = '\0';
   3893            modesToTest[numModesToTest++] = get_mode(str);
   3894            if (tok) {
   3895                *tok = ',';
   3896                str = tok + 1;
   3897            } else {
   3898                break;
   3899            }
   3900        }
   3901        if (bltest.commands[cmd_Decrypt].activated &&
   3902            !bltest.commands[cmd_Encrypt].activated)
   3903            encrypt = PR_FALSE;
   3904        if (bltest.commands[cmd_Encrypt].activated &&
   3905            !bltest.commands[cmd_Decrypt].activated)
   3906            decrypt = PR_FALSE;
   3907        rv = blapi_selftest(modesToTest, numModesToTest, inoff, outoff,
   3908                            encrypt, decrypt);
   3909        PORT_Free(cipherInfo);
   3910        return rv == SECSuccess ? 0 : 1;
   3911    }
   3912 
   3913    /* Do FIPS self-test */
   3914    if (bltest.commands[cmd_FIPS].activated) {
   3915        PORT_Free(cipherInfo);
   3916 #ifdef NSS_FIPS_DISABLED
   3917        fprintf(stdout, "FIPS self-test failed with: NSS_FIPS_DISABLED\n");
   3918        return SECFailure;
   3919 #else
   3920        CK_RV ckrv = sftk_FIPSEntryOK(PR_FALSE);
   3921        if (ckrv == CKR_OK) {
   3922            fprintf(stdout, "FIPS self-test was successful.\n");
   3923            return SECSuccess;
   3924        }
   3925        fprintf(stdout, "FIPS self-test failed with the CK_RV: %ld.\n", ckrv);
   3926        return SECFailure;
   3927 #endif
   3928    }
   3929 
   3930    /*
   3931     * Check command line arguments for Encrypt/Decrypt/Hash/Sign/Verify
   3932     */
   3933 
   3934    if ((bltest.commands[cmd_Decrypt].activated ||
   3935         bltest.commands[cmd_Verify].activated) &&
   3936        bltest.options[opt_BufSize].activated) {
   3937        fprintf(stderr, "%s: Cannot use a nonce as input to decrypt/verify.\n",
   3938                progName);
   3939        goto print_usage;
   3940    }
   3941 
   3942    if (bltest.options[opt_Mode].activated) {
   3943        cipherInfo->mode = get_mode(bltest.options[opt_Mode].arg);
   3944        if (cipherInfo->mode == bltestINVALID) {
   3945            goto print_usage;
   3946        }
   3947    } else {
   3948        fprintf(stderr, "%s: You must specify a cipher mode with -m.\n",
   3949                progName);
   3950        goto print_usage;
   3951    }
   3952 
   3953    if (bltest.options[opt_Repetitions].activated &&
   3954        bltest.options[opt_SecondsToRun].activated) {
   3955        fprintf(stderr, "%s: Operation time should be defined in either "
   3956                        "repetitions(-p) or seconds(-5) not both",
   3957                progName);
   3958        goto print_usage;
   3959    }
   3960 
   3961    if (bltest.options[opt_Repetitions].activated) {
   3962        cipherInfo->repetitionsToPerfom =
   3963            PORT_Atoi(bltest.options[opt_Repetitions].arg);
   3964    } else {
   3965        cipherInfo->repetitionsToPerfom = 0;
   3966    }
   3967 
   3968    if (bltest.options[opt_SecondsToRun].activated) {
   3969        cipherInfo->seconds = PORT_Atoi(bltest.options[opt_SecondsToRun].arg);
   3970    } else {
   3971        cipherInfo->seconds = 0;
   3972    }
   3973 
   3974    if (bltest.options[opt_CXReps].activated) {
   3975        cipherInfo->cxreps = PORT_Atoi(bltest.options[opt_CXReps].arg);
   3976    } else {
   3977        cipherInfo->cxreps = 0;
   3978    }
   3979 
   3980    if (bltest.options[opt_ThreadNum].activated) {
   3981        threads = PORT_Atoi(bltest.options[opt_ThreadNum].arg);
   3982        if (threads <= 0) {
   3983            threads = 1;
   3984        }
   3985    }
   3986 
   3987    /* Dump a file (rsakey, dsakey, etc.) */
   3988    if (bltest.commands[cmd_Dump].activated) {
   3989        rv = dump_file(cipherInfo->mode, bltest.options[opt_Input].arg);
   3990        PORT_Free(cipherInfo);
   3991        return rv;
   3992    }
   3993 
   3994    /* default input mode is binary */
   3995    ioMode = (bltest.options[opt_B64].activated)
   3996                 ? bltestBase64Encoded
   3997             : (bltest.options[opt_Hex].activated)
   3998                 ? bltestHexStream
   3999             : (bltest.options[opt_HexWSpc].activated) ? bltestHexSpaceDelim
   4000                                                       : bltestBinary;
   4001 
   4002    if (bltest.options[opt_Exponent].activated)
   4003        exponent = PORT_Atoi(bltest.options[opt_Exponent].arg);
   4004    else
   4005        exponent = 65537;
   4006 
   4007    if (bltest.options[opt_CurveName].activated)
   4008        curveName = PORT_Strdup(bltest.options[opt_CurveName].arg);
   4009    else
   4010        curveName = NULL;
   4011 
   4012    if (bltest.commands[cmd_Verify].activated &&
   4013        !bltest.options[opt_SigFile].activated) {
   4014        fprintf(stderr, "%s: You must specify a signature file with -f.\n",
   4015                progName);
   4016 
   4017    print_usage:
   4018        if (cipherInfo) {
   4019            PORT_Free(cipherInfo);
   4020        }
   4021        Usage();
   4022    }
   4023 
   4024    if (bltest.options[opt_MonteCarlo].activated) {
   4025        cipherInfo->mCarlo = PR_TRUE;
   4026    } else {
   4027        cipherInfo->mCarlo = PR_FALSE;
   4028    }
   4029 
   4030    for (curThrdNum = 0; curThrdNum < threads; curThrdNum++) {
   4031        int keysize = 0;
   4032        PRFileDesc *file = NULL, *infile;
   4033        bltestParams *params;
   4034        char *instr = NULL;
   4035        PLArenaPool *arena;
   4036 
   4037        if (curThrdNum > 0) {
   4038            bltestCipherInfo *newCInfo = PORT_ZNew(bltestCipherInfo);
   4039            if (!newCInfo) {
   4040                fprintf(stderr, "%s: Can not allocate  memory.\n", progName);
   4041                goto exit_point;
   4042            }
   4043            newCInfo->mode = cipherInfo->mode;
   4044            newCInfo->mCarlo = cipherInfo->mCarlo;
   4045            newCInfo->repetitionsToPerfom =
   4046                cipherInfo->repetitionsToPerfom;
   4047            newCInfo->seconds = cipherInfo->seconds;
   4048            newCInfo->cxreps = cipherInfo->cxreps;
   4049            cipherInfo->next = newCInfo;
   4050            cipherInfo = newCInfo;
   4051        }
   4052        arena = PORT_NewArena(BLTEST_DEFAULT_CHUNKSIZE);
   4053        if (!arena) {
   4054            fprintf(stderr, "%s: Can not allocate memory.\n", progName);
   4055            goto exit_point;
   4056        }
   4057        cipherInfo->arena = arena;
   4058        params = &cipherInfo->params;
   4059 
   4060        /* Set up an encryption key. */
   4061        keysize = 0;
   4062        file = NULL;
   4063        if (is_symmkeyCipher(cipherInfo->mode) ||
   4064            is_aeadCipher(cipherInfo->mode)) {
   4065            char *keystr = NULL; /* if key is on command line */
   4066            if (bltest.options[opt_Key].activated) {
   4067                if (bltest.options[opt_CmdLine].activated) {
   4068                    keystr = bltest.options[opt_Key].arg;
   4069                } else {
   4070                    file = PR_Open(bltest.options[opt_Key].arg,
   4071                                   PR_RDONLY, 00660);
   4072                }
   4073            } else {
   4074                if (bltest.options[opt_KeySize].activated)
   4075                    keysize = PORT_Atoi(bltest.options[opt_KeySize].arg);
   4076                else
   4077                    keysize = 8; /* use 64-bit default (DES) */
   4078                /* save the random key for reference */
   4079                file = PR_Open("tmp.key", PR_WRONLY | PR_CREATE_FILE, 00660);
   4080            }
   4081            params->key.mode = ioMode;
   4082            setupIO(cipherInfo->arena, &params->key, file, keystr, keysize);
   4083            if (file)
   4084                PR_Close(file);
   4085        } else if (is_pubkeyCipher(cipherInfo->mode)) {
   4086            if (bltest.options[opt_Key].activated) {
   4087                file = PR_Open(bltest.options[opt_Key].arg, PR_RDONLY, 00660);
   4088            } else {
   4089                if (bltest.options[opt_KeySize].activated)
   4090                    keysize = PORT_Atoi(bltest.options[opt_KeySize].arg);
   4091                else
   4092                    keysize = 64; /* use 512-bit default */
   4093                file = PR_Open("tmp.key", PR_WRONLY | PR_CREATE_FILE, 00660);
   4094            }
   4095            params->key.mode = bltestBase64Encoded;
   4096            pubkeyInitKey(cipherInfo, file, keysize, exponent, curveName);
   4097            PR_Close(file);
   4098        }
   4099 
   4100        /* set up an initialization vector. */
   4101        if (cipher_requires_IV(cipherInfo->mode)) {
   4102            char *ivstr = NULL;
   4103            bltestSymmKeyParams *skp;
   4104            file = NULL;
   4105 #ifdef NSS_SOFTOKEN_DOES_RC5
   4106            if (cipherInfo->mode == bltestRC5_CBC)
   4107                skp = (bltestSymmKeyParams *)&params->rc5;
   4108            else
   4109 #endif
   4110                skp = &params->sk;
   4111            if (bltest.options[opt_IV].activated) {
   4112                if (bltest.options[opt_CmdLine].activated) {
   4113                    ivstr = bltest.options[opt_IV].arg;
   4114                } else {
   4115                    file = PR_Open(bltest.options[opt_IV].arg,
   4116                                   PR_RDONLY, 00660);
   4117                }
   4118            } else {
   4119                /* save the random iv for reference */
   4120                file = PR_Open("tmp.iv", PR_WRONLY | PR_CREATE_FILE, 00660);
   4121            }
   4122            memset(&skp->iv, 0, sizeof skp->iv);
   4123            skp->iv.mode = ioMode;
   4124            setupIO(cipherInfo->arena, &skp->iv, file, ivstr, keysize);
   4125            if (file) {
   4126                PR_Close(file);
   4127            }
   4128        }
   4129 
   4130        /* set up an initialization vector. */
   4131        if (is_authCipher(cipherInfo->mode)) {
   4132            char *aadstr = NULL;
   4133            bltestAuthSymmKeyParams *askp;
   4134            file = NULL;
   4135            askp = &params->ask;
   4136            if (bltest.options[opt_AAD].activated) {
   4137                if (bltest.options[opt_CmdLine].activated) {
   4138                    aadstr = bltest.options[opt_AAD].arg;
   4139                } else {
   4140                    file = PR_Open(bltest.options[opt_AAD].arg,
   4141                                   PR_RDONLY, 00660);
   4142                }
   4143            } else {
   4144                file = NULL;
   4145            }
   4146            memset(&askp->aad, 0, sizeof askp->aad);
   4147            askp->aad.mode = ioMode;
   4148            setupIO(cipherInfo->arena, &askp->aad, file, aadstr, 0);
   4149            if (file) {
   4150                PR_Close(file);
   4151            }
   4152        }
   4153 
   4154        if (bltest.commands[cmd_Verify].activated) {
   4155            file = PR_Open(bltest.options[opt_SigFile].arg, PR_RDONLY, 00660);
   4156            if (is_sigCipher(cipherInfo->mode)) {
   4157                memset(&params->asymk.sig, 0, sizeof(bltestIO));
   4158                params->asymk.sig.mode = ioMode;
   4159                setupIO(cipherInfo->arena, &params->asymk.sig, file, NULL, 0);
   4160            }
   4161            if (file) {
   4162                PR_Close(file);
   4163            }
   4164        }
   4165 
   4166        if (bltest.options[opt_PQGFile].activated) {
   4167            file = PR_Open(bltest.options[opt_PQGFile].arg, PR_RDONLY, 00660);
   4168            params->asymk.cipherParams.dsa.pqgdata.mode = bltestBase64Encoded;
   4169            setupIO(cipherInfo->arena, &params->asymk.cipherParams.dsa.pqgdata,
   4170                    file, NULL, 0);
   4171            if (file) {
   4172                PR_Close(file);
   4173            }
   4174        }
   4175 
   4176        /* Set up the input buffer */
   4177        if (bltest.options[opt_Input].activated) {
   4178            if (bltest.options[opt_CmdLine].activated) {
   4179                instr = bltest.options[opt_Input].arg;
   4180                infile = NULL;
   4181            } else {
   4182                /* form file name from testdir and input arg. */
   4183                char *filename = bltest.options[opt_Input].arg;
   4184                if (bltest.options[opt_SelfTestDir].activated &&
   4185                    testdir && filename && filename[0] != '/') {
   4186                    filename = PR_smprintf("%s/tests/%s/%s", testdir,
   4187                                           mode_strings[cipherInfo->mode],
   4188                                           filename);
   4189                    if (!filename) {
   4190                        fprintf(stderr, "%s: Can not allocate memory.\n",
   4191                                progName);
   4192                        goto exit_point;
   4193                    }
   4194                    infile = PR_Open(filename, PR_RDONLY, 00660);
   4195                    PR_smprintf_free(filename);
   4196                } else {
   4197                    infile = PR_Open(filename, PR_RDONLY, 00660);
   4198                }
   4199            }
   4200        } else if (bltest.options[opt_BufSize].activated) {
   4201            /* save the random plaintext for reference */
   4202            char *tmpFName = PR_smprintf("tmp.in.%d", curThrdNum);
   4203            if (!tmpFName) {
   4204                fprintf(stderr, "%s: Can not allocate memory.\n", progName);
   4205                goto exit_point;
   4206            }
   4207            infile = PR_Open(tmpFName, PR_WRONLY | PR_CREATE_FILE, 00660);
   4208            PR_smprintf_free(tmpFName);
   4209        } else {
   4210            infile = PR_STDIN;
   4211        }
   4212        if (!infile) {
   4213            fprintf(stderr, "%s: Failed to open input file.\n", progName);
   4214            goto exit_point;
   4215        }
   4216        cipherInfo->input.mode = ioMode;
   4217 
   4218        /* Set up the output stream */
   4219        if (bltest.options[opt_Output].activated) {
   4220            /* form file name from testdir and input arg. */
   4221            char *filename = bltest.options[opt_Output].arg;
   4222            if (bltest.options[opt_SelfTestDir].activated &&
   4223                testdir && filename && filename[0] != '/') {
   4224                filename = PR_smprintf("%s/tests/%s/%s", testdir,
   4225                                       mode_strings[cipherInfo->mode],
   4226                                       filename);
   4227                if (!filename) {
   4228                    fprintf(stderr, "%s: Can not allocate memory.\n", progName);
   4229                    goto exit_point;
   4230                }
   4231                outfile = PR_Open(filename, PR_WRONLY | PR_CREATE_FILE, 00660);
   4232                PR_smprintf_free(filename);
   4233            } else {
   4234                outfile = PR_Open(filename, PR_WRONLY | PR_CREATE_FILE, 00660);
   4235            }
   4236        } else {
   4237            outfile = PR_STDOUT;
   4238        }
   4239        if (!outfile) {
   4240            fprintf(stderr, "%s: Failed to open output file.\n", progName);
   4241            rv = SECFailure;
   4242            goto exit_point;
   4243        }
   4244        cipherInfo->output.mode = ioMode;
   4245        if (bltest.options[opt_SelfTestDir].activated && ioMode == bltestBinary)
   4246            cipherInfo->output.mode = bltestBase64Encoded;
   4247 
   4248        if (is_hashCipher(cipherInfo->mode))
   4249            cipherInfo->params.hash.restart =
   4250                bltest.options[opt_Restart].activated;
   4251 
   4252        bufsize = 0;
   4253        if (bltest.options[opt_BufSize].activated)
   4254            bufsize = PORT_Atoi(bltest.options[opt_BufSize].arg);
   4255 
   4256        /*infile = NULL;*/
   4257        setupIO(cipherInfo->arena, &cipherInfo->input, infile, instr, bufsize);
   4258        if (infile && infile != PR_STDIN)
   4259            PR_Close(infile);
   4260        misalignBuffer(cipherInfo->arena, &cipherInfo->input, inoff);
   4261 
   4262        cipherInit(cipherInfo, bltest.commands[cmd_Encrypt].activated);
   4263        misalignBuffer(cipherInfo->arena, &cipherInfo->output, outoff);
   4264    }
   4265 
   4266    if (!bltest.commands[cmd_Nonce].activated) {
   4267        TIMESTART();
   4268        cipherInfo = cipherInfoListHead;
   4269        while (cipherInfo != NULL) {
   4270            cipherInfo->cipherThread =
   4271                PR_CreateThread(PR_USER_THREAD,
   4272                                ThreadExecTest,
   4273                                cipherInfo,
   4274                                PR_PRIORITY_NORMAL,
   4275                                PR_GLOBAL_THREAD,
   4276                                PR_JOINABLE_THREAD,
   4277                                0);
   4278            cipherInfo = cipherInfo->next;
   4279        }
   4280 
   4281        cipherInfo = cipherInfoListHead;
   4282        while (cipherInfo != NULL) {
   4283            PR_JoinThread(cipherInfo->cipherThread);
   4284            finishIO(&cipherInfo->output, outfile);
   4285            cipherInfo = cipherInfo->next;
   4286        }
   4287        TIMEFINISH(totalTime, 1);
   4288    }
   4289 
   4290    cipherInfo = cipherInfoListHead;
   4291    if (cipherInfo->repetitions > 0 || cipherInfo->cxreps > 0 ||
   4292        threads > 1)
   4293        dump_performance_info(cipherInfoListHead, totalTime,
   4294                              bltest.commands[cmd_Encrypt].activated,
   4295                              (cipherInfo->repetitions == 0));
   4296 
   4297    rv = SECSuccess;
   4298 
   4299 exit_point:
   4300    if (outfile && outfile != PR_STDOUT)
   4301        PR_Close(outfile);
   4302    cipherInfo = cipherInfoListHead;
   4303    while (cipherInfo != NULL) {
   4304        bltestCipherInfo *tmpInfo = cipherInfo;
   4305 
   4306        if (cipherInfo->arena)
   4307            PORT_FreeArena(cipherInfo->arena, PR_TRUE);
   4308        cipherInfo = cipherInfo->next;
   4309        PORT_Free(tmpInfo);
   4310    }
   4311 
   4312    /*NSS_Shutdown();*/
   4313 
   4314    return SECSuccess;
   4315 }