security/nss/cmd/bltest/blapitest.c

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/security/nss/cmd/bltest/blapitest.c	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,4015 @@
     1.4 +/* This Source Code Form is subject to the terms of the Mozilla Public
     1.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this
     1.6 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     1.7 +
     1.8 +#include <stdio.h>
     1.9 +#include <stdlib.h>
    1.10 +
    1.11 +#include "blapi.h"
    1.12 +#include "secrng.h"
    1.13 +#include "prmem.h"
    1.14 +#include "prprf.h"
    1.15 +#include "prtime.h"
    1.16 +#include "prsystem.h"
    1.17 +#include "plstr.h"
    1.18 +#include "nssb64.h"
    1.19 +#include "basicutil.h"
    1.20 +#include "plgetopt.h"
    1.21 +#include "softoken.h"
    1.22 +#include "nspr.h"
    1.23 +#include "secport.h"
    1.24 +#include "secoid.h"
    1.25 +#include "nssutil.h"
    1.26 +
    1.27 +#ifndef NSS_DISABLE_ECC
    1.28 +#include "ecl-curve.h"
    1.29 +SECStatus EC_DecodeParams(const SECItem *encodedParams, 
    1.30 +	ECParams **ecparams);
    1.31 +SECStatus EC_CopyParams(PLArenaPool *arena, ECParams *dstParams,
    1.32 +	      const ECParams *srcParams);
    1.33 +#endif
    1.34 +
    1.35 +char *progName;
    1.36 +char *testdir = NULL;
    1.37 +
    1.38 +#define BLTEST_DEFAULT_CHUNKSIZE 4096
    1.39 +
    1.40 +#define WORDSIZE sizeof(unsigned long)
    1.41 +
    1.42 +#define CHECKERROR(rv, ln) \
    1.43 +    if (rv) { \
    1.44 +	PRErrorCode prerror = PR_GetError(); \
    1.45 +	PR_fprintf(PR_STDERR, "%s: ERR %d (%s) at line %d.\n", progName, \
    1.46 +	prerror, PORT_ErrorToString(prerror), ln); \
    1.47 +	exit(-1); \
    1.48 +    }
    1.49 +
    1.50 +/* Macros for performance timing. */
    1.51 +#define TIMESTART() \
    1.52 +    time1 = PR_IntervalNow();
    1.53 +
    1.54 +#define TIMEFINISH(time, reps) \
    1.55 +    time2 = (PRIntervalTime)(PR_IntervalNow() - time1); \
    1.56 +    time1 = PR_IntervalToMilliseconds(time2); \
    1.57 +    time = ((double)(time1))/reps;
    1.58 +
    1.59 +#define TIMEMARK(seconds) \
    1.60 +    time1 = PR_SecondsToInterval(seconds); \
    1.61 +    { \
    1.62 +        PRInt64 tmp, L100; \
    1.63 +        LL_I2L(L100, 100); \
    1.64 +        if (time2 == 0) { \
    1.65 +            time2 = 1; \
    1.66 +        } \
    1.67 +        LL_DIV(tmp, time1, time2); \
    1.68 +        if (tmp < 10) { \
    1.69 +            if (tmp == 0) { \
    1.70 +                opsBetweenChecks = 1; \
    1.71 +            } else { \
    1.72 +                LL_L2I(opsBetweenChecks, tmp); \
    1.73 +            } \
    1.74 +        } else { \
    1.75 +            opsBetweenChecks = 10; \
    1.76 +        } \
    1.77 +    } \
    1.78 +    time2 = time1; \
    1.79 +    time1 = PR_IntervalNow();
    1.80 +
    1.81 +#define TIMETOFINISH() \
    1.82 +    PR_IntervalNow() - time1 >= time2
    1.83 +
    1.84 +static void Usage()
    1.85 +{
    1.86 +#define PRINTUSAGE(subject, option, predicate) \
    1.87 +    fprintf(stderr, "%10s %s\t%s\n", subject, option, predicate);
    1.88 +    fprintf(stderr, "\n");
    1.89 +    PRINTUSAGE(progName, "[-DEHSVR]", "List available cipher modes"); /* XXX */
    1.90 +    fprintf(stderr, "\n");
    1.91 +    PRINTUSAGE(progName, "-E -m mode ", "Encrypt a buffer");
    1.92 +    PRINTUSAGE("",	"", "[-i plaintext] [-o ciphertext] [-k key] [-v iv]");
    1.93 +    PRINTUSAGE("",	"", "[-b bufsize] [-g keysize] [-e exp] [-r rounds]");
    1.94 +    PRINTUSAGE("",	"", "[-w wordsize] [-p repetitions | -5 time_interval]");
    1.95 +    PRINTUSAGE("",	"", "[-4 th_num]");
    1.96 +    PRINTUSAGE("",	"-m", "cipher mode to use");
    1.97 +    PRINTUSAGE("",	"-i", "file which contains input buffer");
    1.98 +    PRINTUSAGE("",	"-o", "file for output buffer");
    1.99 +    PRINTUSAGE("",	"-k", "file which contains key");
   1.100 +    PRINTUSAGE("",	"-v", "file which contains initialization vector");
   1.101 +    PRINTUSAGE("",	"-b", "size of input buffer");
   1.102 +    PRINTUSAGE("",	"-g", "key size (in bytes)");
   1.103 +    PRINTUSAGE("",	"-p", "do performance test");
   1.104 +    PRINTUSAGE("",	"-4", "run test in multithread mode. th_num number of parallel threads");
   1.105 +    PRINTUSAGE("",	"-5", "run test for specified time interval(in seconds)");
   1.106 +    PRINTUSAGE("",	"--aad", "File with contains additional auth data");
   1.107 +    PRINTUSAGE("(rsa)", "-e", "rsa public exponent");
   1.108 +    PRINTUSAGE("(rc5)", "-r", "number of rounds");
   1.109 +    PRINTUSAGE("(rc5)", "-w", "wordsize (32 or 64)");
   1.110 +    fprintf(stderr, "\n");
   1.111 +    PRINTUSAGE(progName, "-D -m mode", "Decrypt a buffer");
   1.112 +    PRINTUSAGE("",	"", "[-i plaintext] [-o ciphertext] [-k key] [-v iv]");
   1.113 +    PRINTUSAGE("",	"", "[-p repetitions | -5 time_interval] [-4 th_num]");
   1.114 +    PRINTUSAGE("",	"-m", "cipher mode to use");
   1.115 +    PRINTUSAGE("",	"-i", "file which contains input buffer");
   1.116 +    PRINTUSAGE("",	"-o", "file for output buffer");
   1.117 +    PRINTUSAGE("",	"-k", "file which contains key");
   1.118 +    PRINTUSAGE("",	"-v", "file which contains initialization vector");
   1.119 +    PRINTUSAGE("",	"-p", "do performance test");
   1.120 +    PRINTUSAGE("",	"-4", "run test in multithread mode. th_num number of parallel threads");
   1.121 +    PRINTUSAGE("",	"-5", "run test for specified time interval(in seconds)");
   1.122 +    PRINTUSAGE("",	"--aad", "File with contains additional auth data");
   1.123 +    fprintf(stderr, "\n");
   1.124 +    PRINTUSAGE(progName, "-H -m mode", "Hash a buffer");
   1.125 +    PRINTUSAGE("",	"", "[-i plaintext] [-o hash]");
   1.126 +    PRINTUSAGE("",	"", "[-b bufsize]");
   1.127 +    PRINTUSAGE("",	"", "[-p repetitions | -5 time_interval] [-4 th_num]");
   1.128 +    PRINTUSAGE("",	"-m", "cipher mode to use");
   1.129 +    PRINTUSAGE("",	"-i", "file which contains input buffer");
   1.130 +    PRINTUSAGE("",	"-o", "file for hash");
   1.131 +    PRINTUSAGE("",	"-b", "size of input buffer");
   1.132 +    PRINTUSAGE("",	"-p", "do performance test");
   1.133 +    PRINTUSAGE("",	"-4", "run test in multithread mode. th_num number of parallel threads");
   1.134 +    PRINTUSAGE("",	"-5", "run test for specified time interval(in seconds)");
   1.135 +    fprintf(stderr, "\n");
   1.136 +    PRINTUSAGE(progName, "-S -m mode", "Sign a buffer");
   1.137 +    PRINTUSAGE("",	"", "[-i plaintext] [-o signature] [-k key]");
   1.138 +    PRINTUSAGE("",	"", "[-b bufsize]");
   1.139 +#ifndef NSS_DISABLE_ECC
   1.140 +    PRINTUSAGE("",	"", "[-n curvename]");
   1.141 +#endif
   1.142 +    PRINTUSAGE("",	"", "[-p repetitions | -5 time_interval] [-4 th_num]");
   1.143 +    PRINTUSAGE("",	"-m", "cipher mode to use");
   1.144 +    PRINTUSAGE("",	"-i", "file which contains input buffer");
   1.145 +    PRINTUSAGE("",	"-o", "file for signature");
   1.146 +    PRINTUSAGE("",	"-k", "file which contains key");
   1.147 +#ifndef NSS_DISABLE_ECC
   1.148 +    PRINTUSAGE("",	"-n", "name of curve for EC key generation; one of:");
   1.149 +    PRINTUSAGE("",  "",   "  sect163k1, nistk163, sect163r1, sect163r2,");
   1.150 +    PRINTUSAGE("",  "",   "  nistb163, sect193r1, sect193r2, sect233k1, nistk233,");
   1.151 +    PRINTUSAGE("",  "",   "  sect233r1, nistb233, sect239k1, sect283k1, nistk283,");
   1.152 +    PRINTUSAGE("",  "",   "  sect283r1, nistb283, sect409k1, nistk409, sect409r1,");
   1.153 +    PRINTUSAGE("",  "",   "  nistb409, sect571k1, nistk571, sect571r1, nistb571,");
   1.154 +    PRINTUSAGE("",  "",   "  secp160k1, secp160r1, secp160r2, secp192k1, secp192r1,");
   1.155 +    PRINTUSAGE("",  "",   "  nistp192, secp224k1, secp224r1, nistp224, secp256k1,");
   1.156 +    PRINTUSAGE("",  "",   "  secp256r1, nistp256, secp384r1, nistp384, secp521r1,");
   1.157 +    PRINTUSAGE("",  "",   "  nistp521, prime192v1, prime192v2, prime192v3,");
   1.158 +    PRINTUSAGE("",  "",   "  prime239v1, prime239v2, prime239v3, c2pnb163v1,");
   1.159 +    PRINTUSAGE("",  "",   "  c2pnb163v2, c2pnb163v3, c2pnb176v1, c2tnb191v1,");
   1.160 +    PRINTUSAGE("",  "",   "  c2tnb191v2, c2tnb191v3, c2onb191v4, c2onb191v5,");
   1.161 +    PRINTUSAGE("",  "",   "  c2pnb208w1, c2tnb239v1, c2tnb239v2, c2tnb239v3,");
   1.162 +    PRINTUSAGE("",  "",   "  c2onb239v4, c2onb239v5, c2pnb272w1, c2pnb304w1,");
   1.163 +    PRINTUSAGE("",  "",   "  c2tnb359w1, c2pnb368w1, c2tnb431r1, secp112r1,");
   1.164 +    PRINTUSAGE("",  "",   "  secp112r2, secp128r1, secp128r2, sect113r1, sect113r2,");
   1.165 +    PRINTUSAGE("",  "",   "  sect131r1, sect131r2");
   1.166 +#endif
   1.167 +    PRINTUSAGE("",	"-p", "do performance test");
   1.168 +    PRINTUSAGE("",	"-4", "run test in multithread mode. th_num number of parallel threads");
   1.169 +    PRINTUSAGE("",	"-5", "run test for specified time interval(in seconds)");
   1.170 +    fprintf(stderr, "\n");
   1.171 +    PRINTUSAGE(progName, "-V -m mode", "Verify a signed buffer");
   1.172 +    PRINTUSAGE("",	"", "[-i plaintext] [-s signature] [-k key]");
   1.173 +    PRINTUSAGE("",	"", "[-p repetitions | -5 time_interval] [-4 th_num]");
   1.174 +    PRINTUSAGE("",	"-m", "cipher mode to use");
   1.175 +    PRINTUSAGE("",	"-i", "file which contains input buffer");
   1.176 +    PRINTUSAGE("",	"-s", "file which contains signature of input buffer");
   1.177 +    PRINTUSAGE("",	"-k", "file which contains key");
   1.178 +    PRINTUSAGE("",	"-p", "do performance test");
   1.179 +    PRINTUSAGE("",	"-4", "run test in multithread mode. th_num number of parallel threads");
   1.180 +    PRINTUSAGE("",	"-5", "run test for specified time interval(in seconds)");
   1.181 +    fprintf(stderr, "\n");
   1.182 +    PRINTUSAGE(progName, "-N -m mode -b bufsize", 
   1.183 +                                            "Create a nonce plaintext and key");
   1.184 +    PRINTUSAGE("",      "", "[-g keysize] [-u cxreps]");
   1.185 +    PRINTUSAGE("",	"-g", "key size (in bytes)");
   1.186 +    PRINTUSAGE("",      "-u", "number of repetitions of context creation");
   1.187 +    fprintf(stderr, "\n");
   1.188 +    PRINTUSAGE(progName, "-R [-g keysize] [-e exp]", 
   1.189 +                                            "Test the RSA populate key function");
   1.190 +    PRINTUSAGE("",      "", "[-r repetitions]");
   1.191 +    PRINTUSAGE("",	"-g", "key size (in bytes)");
   1.192 +    PRINTUSAGE("", 	"-e", "rsa public exponent");
   1.193 +    PRINTUSAGE("", 	"-r", "repetitions of the test");
   1.194 +    fprintf(stderr, "\n");
   1.195 +    PRINTUSAGE(progName, "-F", "Run the FIPS self-test");
   1.196 +    fprintf(stderr, "\n");
   1.197 +    PRINTUSAGE(progName, "-T [-m mode1,mode2...]", "Run the BLAPI self-test");
   1.198 +    fprintf(stderr, "\n");
   1.199 +    exit(1);
   1.200 +}
   1.201 +
   1.202 +/*  Helper functions for ascii<-->binary conversion/reading/writing */
   1.203 +
   1.204 +/* XXX argh */
   1.205 +struct item_with_arena {
   1.206 +    SECItem	*item;
   1.207 +    PLArenaPool *arena;
   1.208 +};
   1.209 +
   1.210 +static PRInt32
   1.211 +get_binary(void *arg, const unsigned char *ibuf, PRInt32 size)
   1.212 +{
   1.213 +    struct item_with_arena *it = arg;
   1.214 +    SECItem *binary = it->item;
   1.215 +    SECItem *tmp;
   1.216 +    int index;
   1.217 +    if (binary->data == NULL) {
   1.218 +	tmp = SECITEM_AllocItem(it->arena, NULL, size);
   1.219 +	binary->data = tmp->data;
   1.220 +	binary->len = tmp->len;
   1.221 +	index = 0;
   1.222 +    } else {
   1.223 +	SECITEM_ReallocItem(NULL, binary, binary->len, binary->len + size);
   1.224 +	index = binary->len;
   1.225 +    }
   1.226 +    PORT_Memcpy(&binary->data[index], ibuf, size);
   1.227 +    return binary->len;
   1.228 +}
   1.229 +
   1.230 +static SECStatus
   1.231 +atob(SECItem *ascii, SECItem *binary, PLArenaPool *arena)
   1.232 +{
   1.233 +    SECStatus status;
   1.234 +    NSSBase64Decoder *cx;
   1.235 +    struct item_with_arena it;
   1.236 +    int len;
   1.237 +    binary->data = NULL;
   1.238 +    binary->len = 0;
   1.239 +    it.item = binary;
   1.240 +    it.arena = arena;
   1.241 +    len = (strncmp((const char *)&ascii->data[ascii->len-2],"\r\n",2)) ?
   1.242 +           ascii->len : ascii->len-2;
   1.243 +    cx = NSSBase64Decoder_Create(get_binary, &it);
   1.244 +    status = NSSBase64Decoder_Update(cx, (const char *)ascii->data, len);
   1.245 +    status = NSSBase64Decoder_Destroy(cx, PR_FALSE);
   1.246 +    return status;
   1.247 +}
   1.248 +
   1.249 +static PRInt32
   1.250 +output_ascii(void *arg, const char *obuf, PRInt32 size)
   1.251 +{
   1.252 +    PRFileDesc *outfile = arg;
   1.253 +    PRInt32 nb = PR_Write(outfile, obuf, size);
   1.254 +    if (nb != size) {
   1.255 +	PORT_SetError(SEC_ERROR_IO);
   1.256 +	return -1;
   1.257 +    }
   1.258 +    return nb;
   1.259 +}
   1.260 +
   1.261 +static SECStatus
   1.262 +btoa_file(SECItem *binary, PRFileDesc *outfile)
   1.263 +{
   1.264 +    SECStatus status;
   1.265 +    NSSBase64Encoder *cx;
   1.266 +    if (binary->len == 0)
   1.267 +	return SECSuccess;
   1.268 +    cx = NSSBase64Encoder_Create(output_ascii, outfile);
   1.269 +    status = NSSBase64Encoder_Update(cx, binary->data, binary->len);
   1.270 +    status = NSSBase64Encoder_Destroy(cx, PR_FALSE);
   1.271 +    status = PR_Write(outfile, "\r\n", 2);
   1.272 +    return status;
   1.273 +}
   1.274 +
   1.275 +SECStatus
   1.276 +hex_from_2char(unsigned char *c2, unsigned char *byteval)
   1.277 +{
   1.278 +    int i;
   1.279 +    unsigned char offset;
   1.280 +    *byteval = 0;
   1.281 +    for (i=0; i<2; i++) {
   1.282 +	if (c2[i] >= '0' && c2[i] <= '9') {
   1.283 +	    offset = c2[i] - '0';
   1.284 +	    *byteval |= offset << 4*(1-i);
   1.285 +	} else if (c2[i] >= 'a' && c2[i] <= 'f') {
   1.286 +	    offset = c2[i] - 'a';
   1.287 +	    *byteval |= (offset + 10) << 4*(1-i);
   1.288 +	} else if (c2[i] >= 'A' && c2[i] <= 'F') {
   1.289 +	    offset = c2[i] - 'A';
   1.290 +	    *byteval |= (offset + 10) << 4*(1-i);
   1.291 +	} else {
   1.292 +	    return SECFailure;
   1.293 +	}
   1.294 +    }
   1.295 +    return SECSuccess;
   1.296 +}
   1.297 +
   1.298 +SECStatus
   1.299 +char2_from_hex(unsigned char byteval, char *c2)
   1.300 +{
   1.301 +    int i;
   1.302 +    unsigned char offset;
   1.303 +    for (i=0; i<2; i++) {
   1.304 +	offset = (byteval >> 4*(1-i)) & 0x0f;
   1.305 +	if (offset < 10) {
   1.306 +	    c2[i] = '0' + offset;
   1.307 +	} else {
   1.308 +	    c2[i] = 'A' + offset - 10;
   1.309 +	}
   1.310 +    }
   1.311 +    return SECSuccess;
   1.312 +}
   1.313 +
   1.314 +void
   1.315 +serialize_key(SECItem *it, int ni, PRFileDesc *file)
   1.316 +{
   1.317 +    unsigned char len[4];
   1.318 +    int i;
   1.319 +    SECStatus status;
   1.320 +    NSSBase64Encoder *cx;
   1.321 +    cx = NSSBase64Encoder_Create(output_ascii, file);
   1.322 +    for (i=0; i<ni; i++, it++) {
   1.323 +	len[0] = (it->len >> 24) & 0xff;
   1.324 +	len[1] = (it->len >> 16) & 0xff;
   1.325 +	len[2] = (it->len >>  8) & 0xff;
   1.326 +	len[3] = (it->len	 & 0xff);
   1.327 +	status = NSSBase64Encoder_Update(cx, len, 4);
   1.328 +	status = NSSBase64Encoder_Update(cx, it->data, it->len);
   1.329 +    }
   1.330 +    status = NSSBase64Encoder_Destroy(cx, PR_FALSE);
   1.331 +    status = PR_Write(file, "\r\n", 2);
   1.332 +}
   1.333 +
   1.334 +void
   1.335 +key_from_filedata(PLArenaPool *arena, SECItem *it, int ns, int ni, SECItem *filedata)
   1.336 +{
   1.337 +    int fpos = 0;
   1.338 +    int i, len;
   1.339 +    unsigned char *buf = filedata->data;
   1.340 +    for (i=0; i<ni; i++) {
   1.341 +	len  = (buf[fpos++] & 0xff) << 24;
   1.342 +	len |= (buf[fpos++] & 0xff) << 16;
   1.343 +	len |= (buf[fpos++] & 0xff) <<  8;
   1.344 +	len |= (buf[fpos++] & 0xff);
   1.345 +	if (ns <= i) {
   1.346 +	    if (len > 0) {
   1.347 +		it->len = len;
   1.348 +		it->data = PORT_ArenaAlloc(arena, it->len);
   1.349 +		PORT_Memcpy(it->data, &buf[fpos], it->len);
   1.350 +	    } else {
   1.351 +		it->len = 0;
   1.352 +		it->data = NULL;
   1.353 +	    }
   1.354 +	    it++;
   1.355 +	}
   1.356 +	fpos += len;
   1.357 +    }
   1.358 +}
   1.359 +
   1.360 +static RSAPrivateKey *
   1.361 +rsakey_from_filedata(SECItem *filedata)
   1.362 +{
   1.363 +    RSAPrivateKey *key;
   1.364 +    PLArenaPool *arena;
   1.365 +    arena = PORT_NewArena(BLTEST_DEFAULT_CHUNKSIZE);
   1.366 +    key = (RSAPrivateKey *)PORT_ArenaZAlloc(arena, sizeof(RSAPrivateKey));
   1.367 +    key->arena = arena;
   1.368 +    key_from_filedata(arena, &key->version, 0, 9, filedata);
   1.369 +    return key;
   1.370 +}
   1.371 +
   1.372 +static PQGParams *
   1.373 +pqg_from_filedata(SECItem *filedata)
   1.374 +{
   1.375 +    PQGParams *pqg;
   1.376 +    PLArenaPool *arena;
   1.377 +    arena = PORT_NewArena(BLTEST_DEFAULT_CHUNKSIZE);
   1.378 +    pqg = (PQGParams *)PORT_ArenaZAlloc(arena, sizeof(PQGParams));
   1.379 +    pqg->arena = arena;
   1.380 +    key_from_filedata(arena, &pqg->prime, 0, 3, filedata);
   1.381 +    return pqg;
   1.382 +}
   1.383 +
   1.384 +static DSAPrivateKey *
   1.385 +dsakey_from_filedata(SECItem *filedata)
   1.386 +{
   1.387 +    DSAPrivateKey *key;
   1.388 +    PLArenaPool *arena;
   1.389 +    arena = PORT_NewArena(BLTEST_DEFAULT_CHUNKSIZE);
   1.390 +    key = (DSAPrivateKey *)PORT_ArenaZAlloc(arena, sizeof(DSAPrivateKey));
   1.391 +    key->params.arena = arena;
   1.392 +    key_from_filedata(arena, &key->params.prime, 0, 5, filedata);
   1.393 +    return key;
   1.394 +}
   1.395 +
   1.396 +#ifndef NSS_DISABLE_ECC
   1.397 +static ECPrivateKey *
   1.398 +eckey_from_filedata(SECItem *filedata)
   1.399 +{
   1.400 +    ECPrivateKey *key;
   1.401 +    PLArenaPool *arena;
   1.402 +    SECStatus rv;
   1.403 +    ECParams *tmpECParams = NULL;
   1.404 +    arena = PORT_NewArena(BLTEST_DEFAULT_CHUNKSIZE);
   1.405 +    key = (ECPrivateKey *)PORT_ArenaZAlloc(arena, sizeof(ECPrivateKey));
   1.406 +    /* read and convert params */
   1.407 +    key->ecParams.arena = arena;
   1.408 +    key_from_filedata(arena, &key->ecParams.DEREncoding, 0, 1, filedata);
   1.409 +    rv = SECOID_Init();
   1.410 +    CHECKERROR(rv, __LINE__);
   1.411 +    rv = EC_DecodeParams(&key->ecParams.DEREncoding, &tmpECParams);
   1.412 +    CHECKERROR(rv, __LINE__);
   1.413 +    rv = EC_CopyParams(key->ecParams.arena, &key->ecParams, tmpECParams);
   1.414 +    CHECKERROR(rv, __LINE__);
   1.415 +    rv = SECOID_Shutdown();
   1.416 +    CHECKERROR(rv, __LINE__);
   1.417 +    PORT_FreeArena(tmpECParams->arena, PR_TRUE);
   1.418 +    /* read key */
   1.419 +    key_from_filedata(arena, &key->publicValue, 1, 3, filedata);
   1.420 +    return key;
   1.421 +}
   1.422 +
   1.423 +typedef struct curveNameTagPairStr {
   1.424 +    char *curveName;
   1.425 +    SECOidTag curveOidTag;
   1.426 +} CurveNameTagPair;
   1.427 +
   1.428 +#define DEFAULT_CURVE_OID_TAG  SEC_OID_SECG_EC_SECP192R1
   1.429 +/* #define DEFAULT_CURVE_OID_TAG  SEC_OID_SECG_EC_SECP160R1 */
   1.430 +
   1.431 +static CurveNameTagPair nameTagPair[] =
   1.432 +{ 
   1.433 +  { "sect163k1", SEC_OID_SECG_EC_SECT163K1},
   1.434 +  { "nistk163", SEC_OID_SECG_EC_SECT163K1},
   1.435 +  { "sect163r1", SEC_OID_SECG_EC_SECT163R1},
   1.436 +  { "sect163r2", SEC_OID_SECG_EC_SECT163R2},
   1.437 +  { "nistb163", SEC_OID_SECG_EC_SECT163R2},
   1.438 +  { "sect193r1", SEC_OID_SECG_EC_SECT193R1},
   1.439 +  { "sect193r2", SEC_OID_SECG_EC_SECT193R2},
   1.440 +  { "sect233k1", SEC_OID_SECG_EC_SECT233K1},
   1.441 +  { "nistk233", SEC_OID_SECG_EC_SECT233K1},
   1.442 +  { "sect233r1", SEC_OID_SECG_EC_SECT233R1},
   1.443 +  { "nistb233", SEC_OID_SECG_EC_SECT233R1},
   1.444 +  { "sect239k1", SEC_OID_SECG_EC_SECT239K1},
   1.445 +  { "sect283k1", SEC_OID_SECG_EC_SECT283K1},
   1.446 +  { "nistk283", SEC_OID_SECG_EC_SECT283K1},
   1.447 +  { "sect283r1", SEC_OID_SECG_EC_SECT283R1},
   1.448 +  { "nistb283", SEC_OID_SECG_EC_SECT283R1},
   1.449 +  { "sect409k1", SEC_OID_SECG_EC_SECT409K1},
   1.450 +  { "nistk409", SEC_OID_SECG_EC_SECT409K1},
   1.451 +  { "sect409r1", SEC_OID_SECG_EC_SECT409R1},
   1.452 +  { "nistb409", SEC_OID_SECG_EC_SECT409R1},
   1.453 +  { "sect571k1", SEC_OID_SECG_EC_SECT571K1},
   1.454 +  { "nistk571", SEC_OID_SECG_EC_SECT571K1},
   1.455 +  { "sect571r1", SEC_OID_SECG_EC_SECT571R1},
   1.456 +  { "nistb571", SEC_OID_SECG_EC_SECT571R1},
   1.457 +  { "secp160k1", SEC_OID_SECG_EC_SECP160K1},
   1.458 +  { "secp160r1", SEC_OID_SECG_EC_SECP160R1},
   1.459 +  { "secp160r2", SEC_OID_SECG_EC_SECP160R2},
   1.460 +  { "secp192k1", SEC_OID_SECG_EC_SECP192K1},
   1.461 +  { "secp192r1", SEC_OID_SECG_EC_SECP192R1},
   1.462 +  { "nistp192", SEC_OID_SECG_EC_SECP192R1},
   1.463 +  { "secp224k1", SEC_OID_SECG_EC_SECP224K1},
   1.464 +  { "secp224r1", SEC_OID_SECG_EC_SECP224R1},
   1.465 +  { "nistp224", SEC_OID_SECG_EC_SECP224R1},
   1.466 +  { "secp256k1", SEC_OID_SECG_EC_SECP256K1},
   1.467 +  { "secp256r1", SEC_OID_SECG_EC_SECP256R1},
   1.468 +  { "nistp256", SEC_OID_SECG_EC_SECP256R1},
   1.469 +  { "secp384r1", SEC_OID_SECG_EC_SECP384R1},
   1.470 +  { "nistp384", SEC_OID_SECG_EC_SECP384R1},
   1.471 +  { "secp521r1", SEC_OID_SECG_EC_SECP521R1},
   1.472 +  { "nistp521", SEC_OID_SECG_EC_SECP521R1},
   1.473 +
   1.474 +  { "prime192v1", SEC_OID_ANSIX962_EC_PRIME192V1 },
   1.475 +  { "prime192v2", SEC_OID_ANSIX962_EC_PRIME192V2 },
   1.476 +  { "prime192v3", SEC_OID_ANSIX962_EC_PRIME192V3 },
   1.477 +  { "prime239v1", SEC_OID_ANSIX962_EC_PRIME239V1 },
   1.478 +  { "prime239v2", SEC_OID_ANSIX962_EC_PRIME239V2 },
   1.479 +  { "prime239v3", SEC_OID_ANSIX962_EC_PRIME239V3 },
   1.480 +
   1.481 +  { "c2pnb163v1", SEC_OID_ANSIX962_EC_C2PNB163V1 },
   1.482 +  { "c2pnb163v2", SEC_OID_ANSIX962_EC_C2PNB163V2 },
   1.483 +  { "c2pnb163v3", SEC_OID_ANSIX962_EC_C2PNB163V3 },
   1.484 +  { "c2pnb176v1", SEC_OID_ANSIX962_EC_C2PNB176V1 },
   1.485 +  { "c2tnb191v1", SEC_OID_ANSIX962_EC_C2TNB191V1 },
   1.486 +  { "c2tnb191v2", SEC_OID_ANSIX962_EC_C2TNB191V2 },
   1.487 +  { "c2tnb191v3", SEC_OID_ANSIX962_EC_C2TNB191V3 },
   1.488 +  { "c2onb191v4", SEC_OID_ANSIX962_EC_C2ONB191V4 },
   1.489 +  { "c2onb191v5", SEC_OID_ANSIX962_EC_C2ONB191V5 },
   1.490 +  { "c2pnb208w1", SEC_OID_ANSIX962_EC_C2PNB208W1 },
   1.491 +  { "c2tnb239v1", SEC_OID_ANSIX962_EC_C2TNB239V1 },
   1.492 +  { "c2tnb239v2", SEC_OID_ANSIX962_EC_C2TNB239V2 },
   1.493 +  { "c2tnb239v3", SEC_OID_ANSIX962_EC_C2TNB239V3 },
   1.494 +  { "c2onb239v4", SEC_OID_ANSIX962_EC_C2ONB239V4 },
   1.495 +  { "c2onb239v5", SEC_OID_ANSIX962_EC_C2ONB239V5 },
   1.496 +  { "c2pnb272w1", SEC_OID_ANSIX962_EC_C2PNB272W1 },
   1.497 +  { "c2pnb304w1", SEC_OID_ANSIX962_EC_C2PNB304W1 },
   1.498 +  { "c2tnb359v1", SEC_OID_ANSIX962_EC_C2TNB359V1 },
   1.499 +  { "c2pnb368w1", SEC_OID_ANSIX962_EC_C2PNB368W1 },
   1.500 +  { "c2tnb431r1", SEC_OID_ANSIX962_EC_C2TNB431R1 },
   1.501 +
   1.502 +  { "secp112r1", SEC_OID_SECG_EC_SECP112R1},
   1.503 +  { "secp112r2", SEC_OID_SECG_EC_SECP112R2},
   1.504 +  { "secp128r1", SEC_OID_SECG_EC_SECP128R1},
   1.505 +  { "secp128r2", SEC_OID_SECG_EC_SECP128R2},
   1.506 +
   1.507 +  { "sect113r1", SEC_OID_SECG_EC_SECT113R1},
   1.508 +  { "sect113r2", SEC_OID_SECG_EC_SECT113R2},
   1.509 +  { "sect131r1", SEC_OID_SECG_EC_SECT131R1},
   1.510 +  { "sect131r2", SEC_OID_SECG_EC_SECT131R2},
   1.511 +};
   1.512 +
   1.513 +static SECItem * 
   1.514 +getECParams(const char *curve)
   1.515 +{
   1.516 +    SECItem *ecparams;
   1.517 +    SECOidData *oidData = NULL;
   1.518 +    SECOidTag curveOidTag = SEC_OID_UNKNOWN; /* default */
   1.519 +    int i, numCurves;
   1.520 +
   1.521 +    if (curve != NULL) {
   1.522 +        numCurves = sizeof(nameTagPair)/sizeof(CurveNameTagPair);
   1.523 +	for (i = 0; ((i < numCurves) && (curveOidTag == SEC_OID_UNKNOWN)); 
   1.524 +	     i++) {
   1.525 +	    if (PL_strcmp(curve, nameTagPair[i].curveName) == 0)
   1.526 +	        curveOidTag = nameTagPair[i].curveOidTag;
   1.527 +	}
   1.528 +    }
   1.529 +
   1.530 +    /* Return NULL if curve name is not recognized */
   1.531 +    if ((curveOidTag == SEC_OID_UNKNOWN) || 
   1.532 +	(oidData = SECOID_FindOIDByTag(curveOidTag)) == NULL) {
   1.533 +        fprintf(stderr, "Unrecognized elliptic curve %s\n", curve);
   1.534 +	return NULL;
   1.535 +    }
   1.536 +
   1.537 +    ecparams = SECITEM_AllocItem(NULL, NULL, (2 + oidData->oid.len));
   1.538 +
   1.539 +    /* 
   1.540 +     * ecparams->data needs to contain the ASN encoding of an object ID (OID)
   1.541 +     * representing the named curve. The actual OID is in 
   1.542 +     * oidData->oid.data so we simply prepend 0x06 and OID length
   1.543 +     */
   1.544 +    ecparams->data[0] = SEC_ASN1_OBJECT_ID;
   1.545 +    ecparams->data[1] = oidData->oid.len;
   1.546 +    memcpy(ecparams->data + 2, oidData->oid.data, oidData->oid.len);
   1.547 +
   1.548 +    return ecparams;
   1.549 +}
   1.550 +#endif /* NSS_DISABLE_ECC */
   1.551 +
   1.552 +static void
   1.553 +dump_pqg(PQGParams *pqg)
   1.554 +{
   1.555 +    SECU_PrintInteger(stdout, &pqg->prime, "PRIME:", 0);
   1.556 +    SECU_PrintInteger(stdout, &pqg->subPrime, "SUBPRIME:", 0);
   1.557 +    SECU_PrintInteger(stdout, &pqg->base, "BASE:", 0);
   1.558 +}
   1.559 +
   1.560 +static void
   1.561 +dump_dsakey(DSAPrivateKey *key)
   1.562 +{
   1.563 +    dump_pqg(&key->params);
   1.564 +    SECU_PrintInteger(stdout, &key->publicValue, "PUBLIC VALUE:", 0);
   1.565 +    SECU_PrintInteger(stdout, &key->privateValue, "PRIVATE VALUE:", 0);
   1.566 +}
   1.567 +
   1.568 +#ifndef NSS_DISABLE_ECC
   1.569 +static void
   1.570 +dump_ecp(ECParams *ecp)
   1.571 +{
   1.572 +    /* TODO other fields */
   1.573 +    SECU_PrintInteger(stdout, &ecp->base, "BASE POINT:", 0);
   1.574 +}
   1.575 +
   1.576 +static void
   1.577 +dump_eckey(ECPrivateKey *key)
   1.578 +{
   1.579 +    dump_ecp(&key->ecParams);
   1.580 +    SECU_PrintInteger(stdout, &key->publicValue, "PUBLIC VALUE:", 0);
   1.581 +    SECU_PrintInteger(stdout, &key->privateValue, "PRIVATE VALUE:", 0);
   1.582 +}
   1.583 +#endif
   1.584 +
   1.585 +static void
   1.586 +dump_rsakey(RSAPrivateKey *key)
   1.587 +{
   1.588 +    SECU_PrintInteger(stdout, &key->version, "VERSION:", 0);
   1.589 +    SECU_PrintInteger(stdout, &key->modulus, "MODULUS:", 0);
   1.590 +    SECU_PrintInteger(stdout, &key->publicExponent, "PUBLIC EXP:", 0);
   1.591 +    SECU_PrintInteger(stdout, &key->privateExponent, "PRIVATE EXP:", 0);
   1.592 +    SECU_PrintInteger(stdout, &key->prime1, "CRT PRIME 1:", 0);
   1.593 +    SECU_PrintInteger(stdout, &key->prime2, "CRT PRIME 2:", 0);
   1.594 +    SECU_PrintInteger(stdout, &key->exponent1, "CRT EXP 1:", 0);
   1.595 +    SECU_PrintInteger(stdout, &key->exponent2, "CRT EXP 2:", 0);
   1.596 +    SECU_PrintInteger(stdout, &key->coefficient, "CRT COEFFICIENT:", 0);
   1.597 +}
   1.598 +
   1.599 +typedef enum {
   1.600 +    bltestBase64Encoded,       /* Base64 encoded ASCII */
   1.601 +    bltestBinary,	       /* straight binary */
   1.602 +    bltestHexSpaceDelim,       /* 0x12 0x34 0xab 0xCD ... */
   1.603 +    bltestHexStream 	       /* 1234abCD ... */
   1.604 +} bltestIOMode;
   1.605 +
   1.606 +typedef struct
   1.607 +{
   1.608 +    SECItem	   buf;
   1.609 +    SECItem	   pBuf;
   1.610 +    bltestIOMode   mode;
   1.611 +    PRFileDesc*	   file;
   1.612 +} bltestIO;
   1.613 +
   1.614 +typedef SECStatus (* bltestSymmCipherFn)(void *cx,
   1.615 +					 unsigned char *output,
   1.616 +					 unsigned int *outputLen,
   1.617 +					 unsigned int maxOutputLen,
   1.618 +					 const unsigned char *input,
   1.619 +					 unsigned int inputLen);
   1.620 +
   1.621 +typedef SECStatus (* bltestPubKeyCipherFn)(void *key,
   1.622 +					   SECItem *output,
   1.623 +					   const SECItem *input);
   1.624 +
   1.625 +typedef SECStatus (* bltestHashCipherFn)(unsigned char *dest,
   1.626 +					 const unsigned char *src,
   1.627 +					 PRUint32 src_length);
   1.628 +
   1.629 +/* Note: Algorithms are grouped in order to support is_symmkeyCipher /
   1.630 + * is_pubkeyCipher / is_hashCipher / is_sigCipher
   1.631 + */
   1.632 +typedef enum {
   1.633 +    bltestINVALID = -1,
   1.634 +    bltestDES_ECB,	  /* Symmetric Key Ciphers */
   1.635 +    bltestDES_CBC,	  /* .			   */
   1.636 +    bltestDES_EDE_ECB,	  /* .			   */
   1.637 +    bltestDES_EDE_CBC,	  /* .			   */
   1.638 +    bltestRC2_ECB,	  /* .			   */
   1.639 +    bltestRC2_CBC,	  /* .			   */
   1.640 +    bltestRC4,		  /* .			   */
   1.641 +#ifdef NSS_SOFTOKEN_DOES_RC5
   1.642 +    bltestRC5_ECB,	  /* .			   */
   1.643 +    bltestRC5_CBC,	  /* .			   */
   1.644 +#endif
   1.645 +    bltestAES_ECB,        /* .                     */
   1.646 +    bltestAES_CBC,        /* .                     */
   1.647 +    bltestAES_CTS,        /* .                     */
   1.648 +    bltestAES_CTR,        /* .                     */
   1.649 +    bltestAES_GCM,        /* .                     */
   1.650 +    bltestCAMELLIA_ECB,   /* .                     */
   1.651 +    bltestCAMELLIA_CBC,   /* .                     */
   1.652 +    bltestSEED_ECB,       /* SEED algorithm	   */
   1.653 +    bltestSEED_CBC,       /* SEED algorithm	   */
   1.654 +    bltestRSA,            /* Public Key Ciphers    */
   1.655 +    bltestRSA_OAEP,       /* . (Public Key Enc.)   */
   1.656 +    bltestRSA_PSS,        /* . (Public Key Sig.)   */
   1.657 +#ifndef NSS_DISABLE_ECC
   1.658 +    bltestECDSA,          /* . (Public Key Sig.)   */
   1.659 +#endif
   1.660 +    bltestDSA,            /* . (Public Key Sig.)   */
   1.661 +    bltestMD2,		  /* Hash algorithms	   */
   1.662 +    bltestMD5,		  /* .			   */
   1.663 +    bltestSHA1,           /* .			   */
   1.664 +    bltestSHA224,         /* .			   */
   1.665 +    bltestSHA256,         /* .			   */
   1.666 +    bltestSHA384,         /* .			   */
   1.667 +    bltestSHA512,         /* .			   */
   1.668 +    NUMMODES
   1.669 +} bltestCipherMode;
   1.670 +
   1.671 +static char *mode_strings[] =
   1.672 +{
   1.673 +    "des_ecb",
   1.674 +    "des_cbc",
   1.675 +    "des3_ecb",
   1.676 +    "des3_cbc",
   1.677 +    "rc2_ecb",
   1.678 +    "rc2_cbc",
   1.679 +    "rc4",
   1.680 +#ifdef NSS_SOFTOKEN_DOES_RC5
   1.681 +    "rc5_ecb",
   1.682 +    "rc5_cbc",
   1.683 +#endif
   1.684 +    "aes_ecb",
   1.685 +    "aes_cbc",
   1.686 +    "aes_cts",
   1.687 +    "aes_ctr",
   1.688 +    "aes_gcm",
   1.689 +    "camellia_ecb",
   1.690 +    "camellia_cbc",
   1.691 +    "seed_ecb",
   1.692 +    "seed_cbc",
   1.693 +    "rsa",
   1.694 +    "rsa_oaep",
   1.695 +    "rsa_pss",
   1.696 +#ifndef NSS_DISABLE_ECC
   1.697 +    "ecdsa",
   1.698 +#endif
   1.699 +    /*"pqg",*/
   1.700 +    "dsa",
   1.701 +    "md2",
   1.702 +    "md5",
   1.703 +    "sha1",
   1.704 +    "sha224",
   1.705 +    "sha256",
   1.706 +    "sha384",
   1.707 +    "sha512",
   1.708 +};
   1.709 +
   1.710 +typedef struct
   1.711 +{
   1.712 +    bltestIO key;
   1.713 +    bltestIO iv;
   1.714 +} bltestSymmKeyParams;
   1.715 +
   1.716 +typedef struct
   1.717 +{
   1.718 +    bltestSymmKeyParams sk; /* must be first */
   1.719 +    bltestIO aad;
   1.720 +} bltestAuthSymmKeyParams;
   1.721 +
   1.722 +typedef struct
   1.723 +{
   1.724 +    bltestIO key;
   1.725 +    bltestIO iv;
   1.726 +    int	     rounds;
   1.727 +    int	     wordsize;
   1.728 +} bltestRC5Params;
   1.729 +
   1.730 +typedef struct
   1.731 +{
   1.732 +    bltestIO key;
   1.733 +    int keysizeInBits;
   1.734 +
   1.735 +    /* OAEP & PSS */
   1.736 +    HASH_HashType hashAlg;
   1.737 +    HASH_HashType maskHashAlg;
   1.738 +    bltestIO      seed; /* salt if PSS */
   1.739 +} bltestRSAParams;
   1.740 +
   1.741 +typedef struct
   1.742 +{
   1.743 +    bltestIO   pqgdata;
   1.744 +    unsigned int keysize;
   1.745 +    bltestIO   keyseed;
   1.746 +    bltestIO   sigseed;
   1.747 +    PQGParams *pqg;
   1.748 +} bltestDSAParams;
   1.749 +
   1.750 +#ifndef NSS_DISABLE_ECC
   1.751 +typedef struct
   1.752 +{
   1.753 +    char      *curveName;
   1.754 +    bltestIO   sigseed;
   1.755 +} bltestECDSAParams;
   1.756 +#endif
   1.757 +
   1.758 +typedef struct
   1.759 +{
   1.760 +    bltestIO key;
   1.761 +    void *   privKey;
   1.762 +    void *   pubKey;
   1.763 +    bltestIO sig; /* if doing verify, the signature (which may come
   1.764 +                   * from sigfile. */
   1.765 +
   1.766 +    union {
   1.767 +        bltestRSAParams rsa;
   1.768 +        bltestDSAParams dsa;
   1.769 +#ifndef NSS_DISABLE_ECC
   1.770 +        bltestECDSAParams ecdsa;
   1.771 +#endif
   1.772 +    } cipherParams;
   1.773 +} bltestAsymKeyParams;
   1.774 +
   1.775 +typedef struct
   1.776 +{
   1.777 +    bltestIO   key; /* unused */
   1.778 +    PRBool     restart;
   1.779 +} bltestHashParams;
   1.780 +
   1.781 +typedef union
   1.782 +{
   1.783 +    bltestIO		key;
   1.784 +    bltestSymmKeyParams sk;
   1.785 +    bltestAuthSymmKeyParams ask;
   1.786 +    bltestRC5Params	rc5;
   1.787 +    bltestAsymKeyParams	asymk;
   1.788 +    bltestHashParams	hash;
   1.789 +} bltestParams;
   1.790 +
   1.791 +typedef struct bltestCipherInfoStr bltestCipherInfo;
   1.792 +
   1.793 +struct  bltestCipherInfoStr {
   1.794 +    PLArenaPool *arena;
   1.795 +    /* link to next in multithreaded test */
   1.796 +    bltestCipherInfo *next;
   1.797 +    PRThread         *cipherThread;
   1.798 +
   1.799 +    /* MonteCarlo test flag*/
   1.800 +    PRBool mCarlo;
   1.801 +    /* cipher context */
   1.802 +    void *cx;
   1.803 +    /* I/O streams */
   1.804 +    bltestIO input;
   1.805 +    bltestIO output;
   1.806 +    /* Cipher-specific parameters */
   1.807 +    bltestParams params;
   1.808 +    /* Cipher mode */
   1.809 +    bltestCipherMode  mode;
   1.810 +    /* Cipher function (encrypt/decrypt/sign/verify/hash) */
   1.811 +    union {
   1.812 +	bltestSymmCipherFn   symmkeyCipher;
   1.813 +	bltestPubKeyCipherFn pubkeyCipher;
   1.814 +	bltestHashCipherFn   hashCipher;
   1.815 +    } cipher;
   1.816 +    /* performance testing */
   1.817 +    int   repetitionsToPerfom;
   1.818 +    int   seconds;
   1.819 +    int	  repetitions;
   1.820 +    int   cxreps;
   1.821 +    double cxtime;
   1.822 +    double optime;
   1.823 +};
   1.824 +
   1.825 +PRBool
   1.826 +is_symmkeyCipher(bltestCipherMode mode)
   1.827 +{
   1.828 +    /* change as needed! */
   1.829 +    if (mode >= bltestDES_ECB && mode <= bltestSEED_CBC)
   1.830 +	return PR_TRUE;
   1.831 +    return PR_FALSE;
   1.832 +}
   1.833 +
   1.834 +PRBool
   1.835 +is_authCipher(bltestCipherMode mode)
   1.836 +{
   1.837 +    /* change as needed! */
   1.838 +    if (mode == bltestAES_GCM)
   1.839 +	return PR_TRUE;
   1.840 +    return PR_FALSE;
   1.841 +}
   1.842 +
   1.843 +
   1.844 +PRBool
   1.845 +is_singleShotCipher(bltestCipherMode mode)
   1.846 +{
   1.847 +    /* change as needed! */
   1.848 +    if (mode == bltestAES_GCM)
   1.849 +	return PR_TRUE;
   1.850 +    if (mode == bltestAES_CTS)
   1.851 +	return PR_TRUE;
   1.852 +    return PR_FALSE;
   1.853 +}
   1.854 +
   1.855 +PRBool
   1.856 +is_pubkeyCipher(bltestCipherMode mode)
   1.857 +{
   1.858 +    /* change as needed! */
   1.859 +    if (mode >= bltestRSA && mode <= bltestDSA)
   1.860 +	return PR_TRUE;
   1.861 +    return PR_FALSE;
   1.862 +}
   1.863 +
   1.864 +PRBool
   1.865 +is_hashCipher(bltestCipherMode mode)
   1.866 +{
   1.867 +    /* change as needed! */
   1.868 +    if (mode >= bltestMD2 && mode <= bltestSHA512)
   1.869 +	return PR_TRUE;
   1.870 +    return PR_FALSE;
   1.871 +}
   1.872 +
   1.873 +PRBool
   1.874 +is_sigCipher(bltestCipherMode mode)
   1.875 +{
   1.876 +    /* change as needed! */
   1.877 +    if (mode >= bltestRSA_PSS && mode <= bltestDSA)
   1.878 +       return PR_TRUE;
   1.879 +    return PR_FALSE;
   1.880 +}
   1.881 +
   1.882 +PRBool
   1.883 +cipher_requires_IV(bltestCipherMode mode)
   1.884 +{
   1.885 +    /* change as needed! */
   1.886 +    if (mode == bltestDES_CBC || mode == bltestDES_EDE_CBC ||
   1.887 +	mode == bltestRC2_CBC || 
   1.888 +#ifdef NSS_SOFTOKEN_DOES_RC5
   1.889 +	mode == bltestRC5_CBC ||
   1.890 +#endif
   1.891 +	mode == bltestAES_CBC || mode == bltestAES_CTS || 
   1.892 +	mode == bltestAES_CTR || mode == bltestAES_GCM ||
   1.893 +	mode == bltestCAMELLIA_CBC || mode == bltestSEED_CBC)
   1.894 +	return PR_TRUE;
   1.895 +    return PR_FALSE;
   1.896 +}
   1.897 +
   1.898 +SECStatus finishIO(bltestIO *output, PRFileDesc *file);
   1.899 +
   1.900 +SECStatus
   1.901 +setupIO(PLArenaPool *arena, bltestIO *input, PRFileDesc *file,
   1.902 +	char *str, int numBytes)
   1.903 +{
   1.904 +    SECStatus rv = SECSuccess;
   1.905 +    SECItem fileData;
   1.906 +    SECItem *in;
   1.907 +    unsigned char *tok;
   1.908 +    unsigned int i, j;
   1.909 +
   1.910 +    if (file && (numBytes == 0 || file == PR_STDIN)) {
   1.911 +	/* grabbing data from a file */
   1.912 +	rv = SECU_FileToItem(&fileData, file);
   1.913 +	if (rv != SECSuccess)
   1.914 +	    return SECFailure;
   1.915 +	in = &fileData;
   1.916 +    } else if (str) {
   1.917 +	/* grabbing data from command line */
   1.918 +	fileData.data = (unsigned char *)str;
   1.919 +	fileData.len = PL_strlen(str);
   1.920 +	in = &fileData;
   1.921 +    } else if (file) {
   1.922 +	/* create nonce */
   1.923 +	SECITEM_AllocItem(arena, &input->buf, numBytes);
   1.924 +	RNG_GenerateGlobalRandomBytes(input->buf.data, numBytes);
   1.925 +	return finishIO(input, file);
   1.926 +    } else {
   1.927 +	return SECFailure;
   1.928 +    }
   1.929 +
   1.930 +    switch (input->mode) {
   1.931 +    case bltestBase64Encoded:
   1.932 +	if (in->len == 0) {
   1.933 +	    input->buf.data = NULL;
   1.934 +	    input->buf.len = 0;
   1.935 +	    break;
   1.936 +	}
   1.937 +	rv = atob(in, &input->buf, arena);
   1.938 +	break;
   1.939 +    case bltestBinary:
   1.940 +	if (in->len == 0) {
   1.941 +	    input->buf.data = NULL;
   1.942 +	    input->buf.len = 0;
   1.943 +	    break;
   1.944 +	}
   1.945 +	if (in->data[in->len-1] == '\n') --in->len;
   1.946 +	if (in->data[in->len-1] == '\r') --in->len;
   1.947 +	SECITEM_CopyItem(arena, &input->buf, in);
   1.948 +	break;
   1.949 +    case bltestHexSpaceDelim:
   1.950 +	SECITEM_AllocItem(arena, &input->buf, in->len/5);
   1.951 +	for (i=0, j=0; i<in->len; i+=5, j++) {
   1.952 +	    tok = &in->data[i];
   1.953 +	    if (tok[0] != '0' || tok[1] != 'x' || tok[4] != ' ')
   1.954 +		/* bad hex token */
   1.955 +		break;
   1.956 +
   1.957 +	    rv = hex_from_2char(&tok[2], input->buf.data + j);
   1.958 +	    if (rv)
   1.959 +		break;
   1.960 +	}
   1.961 +	break;
   1.962 +    case bltestHexStream:
   1.963 +	SECITEM_AllocItem(arena, &input->buf, in->len/2);
   1.964 +	for (i=0, j=0; i<in->len; i+=2, j++) {
   1.965 +	    tok = &in->data[i];
   1.966 +	    rv = hex_from_2char(tok, input->buf.data + j);
   1.967 +	    if (rv)
   1.968 +		break;
   1.969 +	}
   1.970 +	break;
   1.971 +    }
   1.972 +
   1.973 +    if (file)
   1.974 +	SECITEM_FreeItem(&fileData, PR_FALSE);
   1.975 +    return rv;
   1.976 +}
   1.977 +
   1.978 +SECStatus
   1.979 +finishIO(bltestIO *output, PRFileDesc *file)
   1.980 +{
   1.981 +    SECStatus rv = SECSuccess;
   1.982 +    PRInt32 nb;
   1.983 +    unsigned char byteval;
   1.984 +    SECItem *it;
   1.985 +    char hexstr[5];
   1.986 +    unsigned int i;
   1.987 +    if (output->pBuf.len > 0) {
   1.988 +	it = &output->pBuf;
   1.989 +    } else {
   1.990 +	it = &output->buf;
   1.991 +    }
   1.992 +    switch (output->mode) {
   1.993 +    case bltestBase64Encoded:
   1.994 +	rv = btoa_file(it, file);
   1.995 +	break;
   1.996 +    case bltestBinary:
   1.997 +	nb = PR_Write(file, it->data, it->len);
   1.998 +	rv = (nb == (PRInt32)it->len) ? SECSuccess : SECFailure;
   1.999 +	break;
  1.1000 +    case bltestHexSpaceDelim:
  1.1001 +	hexstr[0] = '0';
  1.1002 +	hexstr[1] = 'x';
  1.1003 +	hexstr[4] = ' ';
  1.1004 +	for (i=0; i<it->len; i++) {
  1.1005 +	    byteval = it->data[i];
  1.1006 +	    rv = char2_from_hex(byteval, hexstr + 2);
  1.1007 +	    nb = PR_Write(file, hexstr, 5);
  1.1008 +	    if (rv)
  1.1009 +		break;
  1.1010 +	}
  1.1011 +	PR_Write(file, "\n", 1);
  1.1012 +	break;
  1.1013 +    case bltestHexStream:
  1.1014 +	for (i=0; i<it->len; i++) {
  1.1015 +	    byteval = it->data[i];
  1.1016 +	    rv = char2_from_hex(byteval, hexstr);
  1.1017 +	    if (rv)
  1.1018 +		break;
  1.1019 +	    nb = PR_Write(file, hexstr, 2);
  1.1020 +	}
  1.1021 +	PR_Write(file, "\n", 1);
  1.1022 +	break;
  1.1023 +    }
  1.1024 +    return rv;
  1.1025 +}
  1.1026 +
  1.1027 +void
  1.1028 +bltestCopyIO(PLArenaPool *arena, bltestIO *dest, bltestIO *src)
  1.1029 +{
  1.1030 +    SECITEM_CopyItem(arena, &dest->buf, &src->buf);
  1.1031 +    if (src->pBuf.len > 0) {
  1.1032 +	dest->pBuf.len = src->pBuf.len;
  1.1033 +	dest->pBuf.data = dest->buf.data + (src->pBuf.data - src->buf.data);
  1.1034 +    }
  1.1035 +    dest->mode = src->mode;
  1.1036 +    dest->file = src->file;
  1.1037 +}
  1.1038 +
  1.1039 +void
  1.1040 +misalignBuffer(PLArenaPool *arena, bltestIO *io, int off)
  1.1041 +{
  1.1042 +    ptrdiff_t offset = (ptrdiff_t)io->buf.data % WORDSIZE;
  1.1043 +    int length = io->buf.len;
  1.1044 +    if (offset != off) {
  1.1045 +	SECITEM_ReallocItemV2(arena, &io->buf, length + 2*WORDSIZE);
  1.1046 +	/* offset may have changed? */
  1.1047 +	offset = (ptrdiff_t)io->buf.data % WORDSIZE;
  1.1048 +	if (offset != off) {
  1.1049 +	    memmove(io->buf.data + off, io->buf.data, length);
  1.1050 +	    io->pBuf.data = io->buf.data + off;
  1.1051 +	    io->pBuf.len = length;
  1.1052 +	} else {
  1.1053 +	    io->pBuf.data = io->buf.data;
  1.1054 +	    io->pBuf.len = length;
  1.1055 +	}
  1.1056 +    } else {
  1.1057 +	io->pBuf.data = io->buf.data;
  1.1058 +	io->pBuf.len = length;
  1.1059 +    }
  1.1060 +}
  1.1061 +
  1.1062 +SECStatus
  1.1063 +des_Encrypt(void *cx, unsigned char *output, unsigned int *outputLen,
  1.1064 +            unsigned int maxOutputLen, const unsigned char *input,
  1.1065 +            unsigned int inputLen)
  1.1066 +{
  1.1067 +    return DES_Encrypt((DESContext *)cx, output, outputLen, maxOutputLen,
  1.1068 +                       input, inputLen);
  1.1069 +}
  1.1070 +
  1.1071 +SECStatus
  1.1072 +des_Decrypt(void *cx, unsigned char *output, unsigned int *outputLen,
  1.1073 +            unsigned int maxOutputLen, const unsigned char *input,
  1.1074 +            unsigned int inputLen)
  1.1075 +{
  1.1076 +    return DES_Decrypt((DESContext *)cx, output, outputLen, maxOutputLen,
  1.1077 +                       input, inputLen);
  1.1078 +}
  1.1079 +
  1.1080 +SECStatus
  1.1081 +rc2_Encrypt(void *cx, unsigned char *output, unsigned int *outputLen,
  1.1082 +            unsigned int maxOutputLen, const unsigned char *input,
  1.1083 +            unsigned int inputLen)
  1.1084 +{
  1.1085 +    return RC2_Encrypt((RC2Context *)cx, output, outputLen, maxOutputLen,
  1.1086 +                       input, inputLen);
  1.1087 +}
  1.1088 +
  1.1089 +SECStatus
  1.1090 +rc2_Decrypt(void *cx, unsigned char *output, unsigned int *outputLen,
  1.1091 +            unsigned int maxOutputLen, const unsigned char *input,
  1.1092 +            unsigned int inputLen)
  1.1093 +{
  1.1094 +    return RC2_Decrypt((RC2Context *)cx, output, outputLen, maxOutputLen,
  1.1095 +                       input, inputLen);
  1.1096 +}
  1.1097 +
  1.1098 +SECStatus
  1.1099 +rc4_Encrypt(void *cx, unsigned char *output, unsigned int *outputLen,
  1.1100 +            unsigned int maxOutputLen, const unsigned char *input,
  1.1101 +            unsigned int inputLen)
  1.1102 +{
  1.1103 +    return RC4_Encrypt((RC4Context *)cx, output, outputLen, maxOutputLen,
  1.1104 +                       input, inputLen);
  1.1105 +}
  1.1106 +
  1.1107 +SECStatus
  1.1108 +rc4_Decrypt(void *cx, unsigned char *output, unsigned int *outputLen,
  1.1109 +            unsigned int maxOutputLen, const unsigned char *input,
  1.1110 +            unsigned int inputLen)
  1.1111 +{
  1.1112 +    return RC4_Decrypt((RC4Context *)cx, output, outputLen, maxOutputLen,
  1.1113 +                       input, inputLen);
  1.1114 +}
  1.1115 +
  1.1116 +SECStatus
  1.1117 +aes_Encrypt(void *cx, unsigned char *output, unsigned int *outputLen,
  1.1118 +            unsigned int maxOutputLen, const unsigned char *input,
  1.1119 +            unsigned int inputLen)
  1.1120 +{
  1.1121 +    return AES_Encrypt((AESContext *)cx, output, outputLen, maxOutputLen,
  1.1122 +                       input, inputLen);
  1.1123 +}
  1.1124 +
  1.1125 +SECStatus
  1.1126 +aes_Decrypt(void *cx, unsigned char *output, unsigned int *outputLen,
  1.1127 +            unsigned int maxOutputLen, const unsigned char *input,
  1.1128 +            unsigned int inputLen)
  1.1129 +{
  1.1130 +    return AES_Decrypt((AESContext *)cx, output, outputLen, maxOutputLen,
  1.1131 +                       input, inputLen);
  1.1132 +}
  1.1133 +
  1.1134 +SECStatus
  1.1135 +camellia_Encrypt(void *cx, unsigned char *output, unsigned int *outputLen,
  1.1136 +		 unsigned int maxOutputLen, const unsigned char *input,
  1.1137 +		 unsigned int inputLen)
  1.1138 +{
  1.1139 +    return Camellia_Encrypt((CamelliaContext *)cx, output, outputLen,
  1.1140 +			    maxOutputLen,
  1.1141 +			    input, inputLen);
  1.1142 +}
  1.1143 +
  1.1144 +SECStatus
  1.1145 +camellia_Decrypt(void *cx, unsigned char *output, unsigned int *outputLen,
  1.1146 +		 unsigned int maxOutputLen, const unsigned char *input,
  1.1147 +		 unsigned int inputLen)
  1.1148 +{
  1.1149 +    return Camellia_Decrypt((CamelliaContext *)cx, output, outputLen,
  1.1150 +			    maxOutputLen,
  1.1151 +			    input, inputLen);
  1.1152 +}
  1.1153 +
  1.1154 +SECStatus
  1.1155 +seed_Encrypt(void *cx, unsigned char *output, unsigned int *outputLen,
  1.1156 +            unsigned int maxOutputLen, const unsigned char *input,
  1.1157 +            unsigned int inputLen)
  1.1158 +{
  1.1159 +    return SEED_Encrypt((SEEDContext *)cx, output, outputLen, maxOutputLen,
  1.1160 +                       input, inputLen);
  1.1161 +}
  1.1162 +
  1.1163 +SECStatus
  1.1164 +seed_Decrypt(void *cx, unsigned char *output, unsigned int *outputLen,
  1.1165 +            unsigned int maxOutputLen, const unsigned char *input,
  1.1166 +            unsigned int inputLen)
  1.1167 +{
  1.1168 +    return SEED_Decrypt((SEEDContext *)cx, output, outputLen, maxOutputLen,
  1.1169 +                       input, inputLen);
  1.1170 +}
  1.1171 +
  1.1172 +SECStatus
  1.1173 +rsa_PublicKeyOp(void *cx, SECItem *output, const SECItem *input)
  1.1174 +{
  1.1175 +    bltestAsymKeyParams *params = (bltestAsymKeyParams *)cx;
  1.1176 +    RSAPublicKey *pubKey = (RSAPublicKey *)params->pubKey;
  1.1177 +    SECStatus rv = RSA_PublicKeyOp(pubKey, output->data, input->data);
  1.1178 +    if (rv == SECSuccess) {
  1.1179 +        output->len = pubKey->modulus.data[0] ? pubKey->modulus.len :
  1.1180 +                                                pubKey->modulus.len - 1;
  1.1181 +    }
  1.1182 +    return rv;
  1.1183 +}
  1.1184 +
  1.1185 +SECStatus
  1.1186 +rsa_PrivateKeyOp(void *cx, SECItem *output, const SECItem *input)
  1.1187 +{
  1.1188 +    bltestAsymKeyParams *params = (bltestAsymKeyParams *)cx;
  1.1189 +    RSAPrivateKey *privKey = (RSAPrivateKey *)params->privKey;
  1.1190 +    SECStatus rv = RSA_PrivateKeyOp(privKey, output->data, input->data);
  1.1191 +    if (rv == SECSuccess) {
  1.1192 +        output->len = privKey->modulus.data[0] ? privKey->modulus.len :
  1.1193 +                                                 privKey->modulus.len - 1;
  1.1194 +    }
  1.1195 +    return rv;
  1.1196 +}
  1.1197 +
  1.1198 +SECStatus
  1.1199 +rsa_signDigestPSS(void *cx, SECItem *output, const SECItem *input)
  1.1200 +{
  1.1201 +    bltestAsymKeyParams *params = (bltestAsymKeyParams *)cx;
  1.1202 +    bltestRSAParams *rsaParams = &params->cipherParams.rsa;
  1.1203 +    return RSA_SignPSS((RSAPrivateKey *)params->privKey,
  1.1204 +                       rsaParams->hashAlg,
  1.1205 +                       rsaParams->maskHashAlg,
  1.1206 +                       rsaParams->seed.buf.data,
  1.1207 +                       rsaParams->seed.buf.len,
  1.1208 +                       output->data, &output->len, output->len,
  1.1209 +                       input->data, input->len);
  1.1210 +}
  1.1211 +
  1.1212 +SECStatus
  1.1213 +rsa_verifyDigestPSS(void *cx, SECItem *output, const SECItem *input)
  1.1214 +{
  1.1215 +    bltestAsymKeyParams *params = (bltestAsymKeyParams *)cx;
  1.1216 +    bltestRSAParams *rsaParams = &params->cipherParams.rsa;
  1.1217 +    return RSA_CheckSignPSS((RSAPublicKey *)params->pubKey,
  1.1218 +                            rsaParams->hashAlg,
  1.1219 +                            rsaParams->maskHashAlg,
  1.1220 +                            rsaParams->seed.buf.len,
  1.1221 +                            output->data, output->len,
  1.1222 +                            input->data, input->len);
  1.1223 +}
  1.1224 +
  1.1225 +SECStatus
  1.1226 +rsa_encryptOAEP(void *cx, SECItem *output, const SECItem *input)
  1.1227 +{
  1.1228 +    bltestAsymKeyParams *params = (bltestAsymKeyParams *)cx;
  1.1229 +    bltestRSAParams *rsaParams = &params->cipherParams.rsa;
  1.1230 +    return RSA_EncryptOAEP((RSAPublicKey *)params->pubKey,
  1.1231 +                           rsaParams->hashAlg,
  1.1232 +                           rsaParams->maskHashAlg,
  1.1233 +                           NULL, 0,
  1.1234 +                           rsaParams->seed.buf.data,
  1.1235 +                           rsaParams->seed.buf.len,
  1.1236 +                           output->data, &output->len, output->len,
  1.1237 +                           input->data, input->len);
  1.1238 +}
  1.1239 +
  1.1240 +SECStatus
  1.1241 +rsa_decryptOAEP(void *cx, SECItem *output, const SECItem *input)
  1.1242 +{
  1.1243 +    bltestAsymKeyParams *params = (bltestAsymKeyParams *)cx;
  1.1244 +    bltestRSAParams *rsaParams = &params->cipherParams.rsa;
  1.1245 +    return RSA_DecryptOAEP((RSAPrivateKey *)params->privKey,
  1.1246 +                           rsaParams->hashAlg,
  1.1247 +                           rsaParams->maskHashAlg,
  1.1248 +                           NULL, 0,
  1.1249 +                           output->data, &output->len, output->len,
  1.1250 +                           input->data, input->len);
  1.1251 +}
  1.1252 +
  1.1253 +SECStatus
  1.1254 +dsa_signDigest(void *cx, SECItem *output, const SECItem *input)
  1.1255 +{
  1.1256 +    bltestAsymKeyParams *params = (bltestAsymKeyParams *)cx;
  1.1257 +    if (params->cipherParams.dsa.sigseed.buf.len > 0) {
  1.1258 +        return DSA_SignDigestWithSeed((DSAPrivateKey *)params->privKey,
  1.1259 +                                      output, input,
  1.1260 +                                      params->cipherParams.dsa.sigseed.buf.data);
  1.1261 +    }
  1.1262 +    return DSA_SignDigest((DSAPrivateKey *)params->privKey, output, input);
  1.1263 +}
  1.1264 +
  1.1265 +SECStatus
  1.1266 +dsa_verifyDigest(void *cx, SECItem *output, const SECItem *input)
  1.1267 +{
  1.1268 +    bltestAsymKeyParams *params = (bltestAsymKeyParams *)cx;
  1.1269 +    return DSA_VerifyDigest((DSAPublicKey *)params->pubKey, output, input);
  1.1270 +}
  1.1271 +
  1.1272 +#ifndef NSS_DISABLE_ECC
  1.1273 +SECStatus
  1.1274 +ecdsa_signDigest(void *cx, SECItem *output, const SECItem *input)
  1.1275 +{
  1.1276 +    bltestAsymKeyParams *params = (bltestAsymKeyParams *)cx;
  1.1277 +    if (params->cipherParams.ecdsa.sigseed.buf.len > 0) {
  1.1278 +        return ECDSA_SignDigestWithSeed(
  1.1279 +                        (ECPrivateKey *)params->privKey,
  1.1280 +                        output, input,
  1.1281 +                        params->cipherParams.ecdsa.sigseed.buf.data,
  1.1282 +                        params->cipherParams.ecdsa.sigseed.buf.len);
  1.1283 +    }
  1.1284 +    return ECDSA_SignDigest((ECPrivateKey *)params->privKey, output, input);
  1.1285 +}
  1.1286 +
  1.1287 +SECStatus
  1.1288 +ecdsa_verifyDigest(void *cx, SECItem *output, const SECItem *input)
  1.1289 +{
  1.1290 +    bltestAsymKeyParams *params = (bltestAsymKeyParams *)cx;
  1.1291 +    return ECDSA_VerifyDigest((ECPublicKey *)params->pubKey, output, input);
  1.1292 +}
  1.1293 +#endif
  1.1294 +
  1.1295 +SECStatus
  1.1296 +bltest_des_init(bltestCipherInfo *cipherInfo, PRBool encrypt)
  1.1297 +{
  1.1298 +    PRIntervalTime time1, time2;
  1.1299 +    bltestSymmKeyParams *desp = &cipherInfo->params.sk;
  1.1300 +    int minorMode;
  1.1301 +    int i;
  1.1302 +    switch (cipherInfo->mode) {
  1.1303 +    case bltestDES_ECB:	    minorMode = NSS_DES;	  break;
  1.1304 +    case bltestDES_CBC:	    minorMode = NSS_DES_CBC;	  break;
  1.1305 +    case bltestDES_EDE_ECB: minorMode = NSS_DES_EDE3;	  break;
  1.1306 +    case bltestDES_EDE_CBC: minorMode = NSS_DES_EDE3_CBC; break;
  1.1307 +    default:
  1.1308 +	return SECFailure;
  1.1309 +    }
  1.1310 +    cipherInfo->cx = (void*)DES_CreateContext(desp->key.buf.data,
  1.1311 +					      desp->iv.buf.data,
  1.1312 +					      minorMode, encrypt);
  1.1313 +    if (cipherInfo->cxreps > 0) {
  1.1314 +	DESContext **dummycx;
  1.1315 +	dummycx = PORT_Alloc(cipherInfo->cxreps * sizeof(DESContext *));
  1.1316 +	TIMESTART();
  1.1317 +	for (i=0; i<cipherInfo->cxreps; i++) {
  1.1318 +	    dummycx[i] = (void*)DES_CreateContext(desp->key.buf.data,
  1.1319 +					          desp->iv.buf.data,
  1.1320 +					          minorMode, encrypt);
  1.1321 +	}
  1.1322 +	TIMEFINISH(cipherInfo->cxtime, 1.0);
  1.1323 +	for (i=0; i<cipherInfo->cxreps; i++) {
  1.1324 +	    DES_DestroyContext(dummycx[i], PR_TRUE);
  1.1325 +	}
  1.1326 +	PORT_Free(dummycx);
  1.1327 +    }
  1.1328 +    if (encrypt)
  1.1329 +	cipherInfo->cipher.symmkeyCipher = des_Encrypt;
  1.1330 +    else
  1.1331 +	cipherInfo->cipher.symmkeyCipher = des_Decrypt;
  1.1332 +    return SECSuccess;
  1.1333 +}
  1.1334 +
  1.1335 +SECStatus
  1.1336 +bltest_rc2_init(bltestCipherInfo *cipherInfo, PRBool encrypt)
  1.1337 +{
  1.1338 +    PRIntervalTime time1, time2;
  1.1339 +    bltestSymmKeyParams *rc2p = &cipherInfo->params.sk;
  1.1340 +    int minorMode;
  1.1341 +    int i;
  1.1342 +    switch (cipherInfo->mode) {
  1.1343 +    case bltestRC2_ECB: minorMode = NSS_RC2;	 break;
  1.1344 +    case bltestRC2_CBC: minorMode = NSS_RC2_CBC; break;
  1.1345 +    default:
  1.1346 +	return SECFailure;
  1.1347 +    }
  1.1348 +    cipherInfo->cx = (void*)RC2_CreateContext(rc2p->key.buf.data,
  1.1349 +					      rc2p->key.buf.len,
  1.1350 +					      rc2p->iv.buf.data,
  1.1351 +					      minorMode,
  1.1352 +					      rc2p->key.buf.len);
  1.1353 +    if (cipherInfo->cxreps > 0) {
  1.1354 +	RC2Context **dummycx;
  1.1355 +	dummycx = PORT_Alloc(cipherInfo->cxreps * sizeof(RC2Context *));
  1.1356 +	TIMESTART();
  1.1357 +	for (i=0; i<cipherInfo->cxreps; i++) {
  1.1358 +	    dummycx[i] = (void*)RC2_CreateContext(rc2p->key.buf.data,
  1.1359 +	                                          rc2p->key.buf.len,
  1.1360 +	                                          rc2p->iv.buf.data,
  1.1361 +	                                          minorMode,
  1.1362 +	                                          rc2p->key.buf.len);
  1.1363 +	}
  1.1364 +	TIMEFINISH(cipherInfo->cxtime, 1.0);
  1.1365 +	for (i=0; i<cipherInfo->cxreps; i++) {
  1.1366 +	    RC2_DestroyContext(dummycx[i], PR_TRUE);
  1.1367 +	}
  1.1368 +	PORT_Free(dummycx);
  1.1369 +    }
  1.1370 +    if (encrypt)
  1.1371 +	cipherInfo->cipher.symmkeyCipher = rc2_Encrypt;
  1.1372 +    else
  1.1373 +	cipherInfo->cipher.symmkeyCipher = rc2_Decrypt;
  1.1374 +    return SECSuccess;
  1.1375 +}
  1.1376 +
  1.1377 +SECStatus
  1.1378 +bltest_rc4_init(bltestCipherInfo *cipherInfo, PRBool encrypt)
  1.1379 +{
  1.1380 +    PRIntervalTime time1, time2;
  1.1381 +    int i;
  1.1382 +    bltestSymmKeyParams *rc4p = &cipherInfo->params.sk;
  1.1383 +    cipherInfo->cx = (void*)RC4_CreateContext(rc4p->key.buf.data,
  1.1384 +					      rc4p->key.buf.len);
  1.1385 +    if (cipherInfo->cxreps > 0) {
  1.1386 +	RC4Context **dummycx;
  1.1387 +	dummycx = PORT_Alloc(cipherInfo->cxreps * sizeof(RC4Context *));
  1.1388 +	TIMESTART();
  1.1389 +	for (i=0; i<cipherInfo->cxreps; i++) {
  1.1390 +	    dummycx[i] = (void*)RC4_CreateContext(rc4p->key.buf.data,
  1.1391 +	                                          rc4p->key.buf.len);
  1.1392 +	}
  1.1393 +	TIMEFINISH(cipherInfo->cxtime, 1.0);
  1.1394 +	for (i=0; i<cipherInfo->cxreps; i++) {
  1.1395 +	    RC4_DestroyContext(dummycx[i], PR_TRUE);
  1.1396 +	}
  1.1397 +	PORT_Free(dummycx);
  1.1398 +    }
  1.1399 +    if (encrypt)
  1.1400 +	cipherInfo->cipher.symmkeyCipher = rc4_Encrypt;
  1.1401 +    else
  1.1402 +	cipherInfo->cipher.symmkeyCipher = rc4_Decrypt;
  1.1403 +    return SECSuccess;
  1.1404 +}
  1.1405 +
  1.1406 +SECStatus
  1.1407 +bltest_rc5_init(bltestCipherInfo *cipherInfo, PRBool encrypt)
  1.1408 +{
  1.1409 +#ifdef NSS_SOFTOKEN_DOES_RC5
  1.1410 +    PRIntervalTime time1, time2;
  1.1411 +    bltestRC5Params *rc5p = &cipherInfo->params.rc5;
  1.1412 +    int minorMode;
  1.1413 +    switch (cipherInfo->mode) {
  1.1414 +    case bltestRC5_ECB: minorMode = NSS_RC5;	 break;
  1.1415 +    case bltestRC5_CBC: minorMode = NSS_RC5_CBC; break;
  1.1416 +    default:
  1.1417 +	return SECFailure;
  1.1418 +    }
  1.1419 +    TIMESTART();
  1.1420 +    cipherInfo->cx = (void*)RC5_CreateContext(&rc5p->key.buf,
  1.1421 +					      rc5p->rounds, rc5p->wordsize,
  1.1422 +					      rc5p->iv.buf.data, minorMode);
  1.1423 +    TIMEFINISH(cipherInfo->cxtime, 1.0);
  1.1424 +    if (encrypt)
  1.1425 +	cipherInfo->cipher.symmkeyCipher = RC5_Encrypt;
  1.1426 +    else
  1.1427 +	cipherInfo->cipher.symmkeyCipher = RC5_Decrypt;
  1.1428 +    return SECSuccess;
  1.1429 +#else
  1.1430 +    return SECFailure;
  1.1431 +#endif
  1.1432 +}
  1.1433 +
  1.1434 +SECStatus
  1.1435 +bltest_aes_init(bltestCipherInfo *cipherInfo, PRBool encrypt)
  1.1436 +{
  1.1437 +    bltestSymmKeyParams *aesp = &cipherInfo->params.sk;
  1.1438 +    bltestAuthSymmKeyParams *gcmp = &cipherInfo->params.ask;
  1.1439 +    int minorMode;
  1.1440 +    int i;
  1.1441 +    int keylen   = aesp->key.buf.len;
  1.1442 +    int blocklen = AES_BLOCK_SIZE; 
  1.1443 +    PRIntervalTime time1, time2;
  1.1444 +    unsigned char *params;
  1.1445 +    int len;
  1.1446 +    CK_AES_CTR_PARAMS ctrParams;
  1.1447 +    CK_GCM_PARAMS gcmParams;
  1.1448 +
  1.1449 +    params = aesp->iv.buf.data;
  1.1450 +    switch (cipherInfo->mode) {
  1.1451 +    case bltestAES_ECB:	    minorMode = NSS_AES;	  break;
  1.1452 +    case bltestAES_CBC:	    minorMode = NSS_AES_CBC;	  break;
  1.1453 +    case bltestAES_CTS:	    minorMode = NSS_AES_CTS;	  break;
  1.1454 +    case bltestAES_CTR:	    
  1.1455 +	minorMode = NSS_AES_CTR;
  1.1456 +	ctrParams.ulCounterBits = 32;
  1.1457 +	len = PR_MIN(aesp->iv.buf.len, blocklen);
  1.1458 +	PORT_Memset(ctrParams.cb, 0, blocklen);
  1.1459 +	PORT_Memcpy(ctrParams.cb, aesp->iv.buf.data, len);
  1.1460 +	params = (unsigned char *)&ctrParams;
  1.1461 +	break;
  1.1462 +    case bltestAES_GCM:
  1.1463 +	minorMode = NSS_AES_GCM;
  1.1464 +	gcmParams.pIv = gcmp->sk.iv.buf.data;
  1.1465 +	gcmParams.ulIvLen = gcmp->sk.iv.buf.len;
  1.1466 +	gcmParams.pAAD = gcmp->aad.buf.data;
  1.1467 +	gcmParams.ulAADLen = gcmp->aad.buf.len;
  1.1468 +	gcmParams.ulTagBits = blocklen*8;
  1.1469 +	params = (unsigned char *)&gcmParams;
  1.1470 +	break;
  1.1471 +    default:
  1.1472 +	return SECFailure;
  1.1473 +    }
  1.1474 +    cipherInfo->cx = (void*)AES_CreateContext(aesp->key.buf.data,
  1.1475 +					      params,
  1.1476 +					      minorMode, encrypt, 
  1.1477 +                                              keylen, blocklen);
  1.1478 +    if (cipherInfo->cxreps > 0) {
  1.1479 +	AESContext **dummycx;
  1.1480 +	dummycx = PORT_Alloc(cipherInfo->cxreps * sizeof(AESContext *));
  1.1481 +	TIMESTART();
  1.1482 +	for (i=0; i<cipherInfo->cxreps; i++) {
  1.1483 +	    dummycx[i] = (void*)AES_CreateContext(aesp->key.buf.data,
  1.1484 +					          params,
  1.1485 +					          minorMode, encrypt,
  1.1486 +	                                          keylen, blocklen);
  1.1487 +	}
  1.1488 +	TIMEFINISH(cipherInfo->cxtime, 1.0);
  1.1489 +	for (i=0; i<cipherInfo->cxreps; i++) {
  1.1490 +	    AES_DestroyContext(dummycx[i], PR_TRUE);
  1.1491 +	}
  1.1492 +	PORT_Free(dummycx);
  1.1493 +    }
  1.1494 +    if (encrypt)
  1.1495 +	cipherInfo->cipher.symmkeyCipher = aes_Encrypt;
  1.1496 +    else
  1.1497 +	cipherInfo->cipher.symmkeyCipher = aes_Decrypt;
  1.1498 +    return SECSuccess;
  1.1499 +}
  1.1500 +
  1.1501 +SECStatus
  1.1502 +bltest_camellia_init(bltestCipherInfo *cipherInfo, PRBool encrypt)
  1.1503 +{
  1.1504 +    bltestSymmKeyParams *camelliap = &cipherInfo->params.sk;
  1.1505 +    int minorMode;
  1.1506 +    int i;
  1.1507 +    int keylen   = camelliap->key.buf.len;
  1.1508 +    PRIntervalTime time1, time2;
  1.1509 +    
  1.1510 +    switch (cipherInfo->mode) {
  1.1511 +    case bltestCAMELLIA_ECB:	    minorMode = NSS_CAMELLIA;	  break;
  1.1512 +    case bltestCAMELLIA_CBC:	    minorMode = NSS_CAMELLIA_CBC;  break;
  1.1513 +    default:
  1.1514 +	return SECFailure;
  1.1515 +    }
  1.1516 +    cipherInfo->cx = (void*)Camellia_CreateContext(camelliap->key.buf.data,
  1.1517 +						   camelliap->iv.buf.data,
  1.1518 +						   minorMode, encrypt, 
  1.1519 +						   keylen);
  1.1520 +    if (cipherInfo->cxreps > 0) {
  1.1521 +	CamelliaContext **dummycx;
  1.1522 +	dummycx = PORT_Alloc(cipherInfo->cxreps * sizeof(CamelliaContext *));
  1.1523 +	TIMESTART();
  1.1524 +	for (i=0; i<cipherInfo->cxreps; i++) {
  1.1525 +	    dummycx[i] = (void*)Camellia_CreateContext(camelliap->key.buf.data,
  1.1526 +						       camelliap->iv.buf.data,
  1.1527 +						       minorMode, encrypt,
  1.1528 +						       keylen);
  1.1529 +	}
  1.1530 +	TIMEFINISH(cipherInfo->cxtime, 1.0);
  1.1531 +	for (i=0; i<cipherInfo->cxreps; i++) {
  1.1532 +	    Camellia_DestroyContext(dummycx[i], PR_TRUE);
  1.1533 +	}
  1.1534 +	PORT_Free(dummycx);
  1.1535 +    }
  1.1536 +    if (encrypt)
  1.1537 +	cipherInfo->cipher.symmkeyCipher = camellia_Encrypt;
  1.1538 +    else
  1.1539 +	cipherInfo->cipher.symmkeyCipher = camellia_Decrypt;
  1.1540 +    return SECSuccess;
  1.1541 +}
  1.1542 +
  1.1543 +SECStatus
  1.1544 +bltest_seed_init(bltestCipherInfo *cipherInfo, PRBool encrypt)
  1.1545 +{
  1.1546 +    PRIntervalTime time1, time2;
  1.1547 +    bltestSymmKeyParams *seedp = &cipherInfo->params.sk;
  1.1548 +    int minorMode;
  1.1549 +    int i;
  1.1550 +
  1.1551 +    switch (cipherInfo->mode) {
  1.1552 +    case bltestSEED_ECB:	minorMode = NSS_SEED;		break;
  1.1553 +    case bltestSEED_CBC:	minorMode = NSS_SEED_CBC;	break;
  1.1554 +    default:
  1.1555 +	return SECFailure;
  1.1556 +    }
  1.1557 +    cipherInfo->cx = (void*)SEED_CreateContext(seedp->key.buf.data,
  1.1558 +					      seedp->iv.buf.data,
  1.1559 +					      minorMode, encrypt);
  1.1560 +    if (cipherInfo->cxreps > 0) {
  1.1561 +	SEEDContext **dummycx;
  1.1562 +	dummycx = PORT_Alloc(cipherInfo->cxreps * sizeof(SEEDContext *));
  1.1563 +	TIMESTART();
  1.1564 +	for (i=0; i<cipherInfo->cxreps; i++) {
  1.1565 +	    dummycx[i] = (void*)SEED_CreateContext(seedp->key.buf.data,
  1.1566 +					          seedp->iv.buf.data,
  1.1567 +					          minorMode, encrypt);
  1.1568 +	}
  1.1569 +	TIMEFINISH(cipherInfo->cxtime, 1.0);
  1.1570 +	for (i=0; i<cipherInfo->cxreps; i++) {
  1.1571 +	    SEED_DestroyContext(dummycx[i], PR_TRUE);
  1.1572 +	}
  1.1573 +	PORT_Free(dummycx);
  1.1574 +    }
  1.1575 +    if (encrypt)
  1.1576 +	cipherInfo->cipher.symmkeyCipher = seed_Encrypt;
  1.1577 +    else
  1.1578 +	cipherInfo->cipher.symmkeyCipher = seed_Decrypt;
  1.1579 +	
  1.1580 +	return SECSuccess;
  1.1581 +}
  1.1582 +
  1.1583 +SECStatus
  1.1584 +bltest_rsa_init(bltestCipherInfo *cipherInfo, PRBool encrypt)
  1.1585 +{
  1.1586 +    int i;
  1.1587 +    RSAPrivateKey **dummyKey;
  1.1588 +    RSAPrivateKey *privKey;
  1.1589 +    RSAPublicKey *pubKey;
  1.1590 +    PRIntervalTime time1, time2;
  1.1591 +
  1.1592 +    bltestAsymKeyParams *asymk = &cipherInfo->params.asymk;
  1.1593 +    bltestRSAParams *rsap = &asymk->cipherParams.rsa;
  1.1594 +
  1.1595 +    /* RSA key gen was done during parameter setup */
  1.1596 +    cipherInfo->cx = asymk;
  1.1597 +    privKey = (RSAPrivateKey *)asymk->privKey;
  1.1598 +
  1.1599 +    /* For performance testing */
  1.1600 +    if (cipherInfo->cxreps > 0) {
  1.1601 +	/* Create space for n private key objects */
  1.1602 +	dummyKey = (RSAPrivateKey **)PORT_Alloc(cipherInfo->cxreps *
  1.1603 +						sizeof(RSAPrivateKey *));
  1.1604 +	/* Time n keygens, storing in the array */
  1.1605 +	TIMESTART();
  1.1606 +	for (i=0; i<cipherInfo->cxreps; i++)
  1.1607 +	    dummyKey[i] = RSA_NewKey(rsap->keysizeInBits, 
  1.1608 +	                             &privKey->publicExponent);
  1.1609 +	TIMEFINISH(cipherInfo->cxtime, cipherInfo->cxreps);
  1.1610 +	/* Free the n key objects */
  1.1611 +	for (i=0; i<cipherInfo->cxreps; i++)
  1.1612 +	    PORT_FreeArena(dummyKey[i]->arena, PR_TRUE);
  1.1613 +	PORT_Free(dummyKey);
  1.1614 +    }
  1.1615 +
  1.1616 +    if ((encrypt && !is_sigCipher(cipherInfo->mode)) ||
  1.1617 +        (!encrypt && is_sigCipher(cipherInfo->mode))) {
  1.1618 +	/* Have to convert private key to public key.  Memory
  1.1619 +	 * is freed with private key's arena  */
  1.1620 +	pubKey = (RSAPublicKey *)PORT_ArenaAlloc(privKey->arena,
  1.1621 +						 sizeof(RSAPublicKey));
  1.1622 +	pubKey->modulus.len = privKey->modulus.len;
  1.1623 +	pubKey->modulus.data = privKey->modulus.data;
  1.1624 +	pubKey->publicExponent.len = privKey->publicExponent.len;
  1.1625 +	pubKey->publicExponent.data = privKey->publicExponent.data;
  1.1626 +	asymk->pubKey = (void *)pubKey;
  1.1627 +    }
  1.1628 +    switch (cipherInfo->mode) {
  1.1629 +        case bltestRSA:
  1.1630 +            cipherInfo->cipher.pubkeyCipher = encrypt ? rsa_PublicKeyOp
  1.1631 +                                                      : rsa_PrivateKeyOp;
  1.1632 +            break;
  1.1633 +        case bltestRSA_PSS:
  1.1634 +            cipherInfo->cipher.pubkeyCipher = encrypt ? rsa_signDigestPSS
  1.1635 +                                                      : rsa_verifyDigestPSS;
  1.1636 +            break;
  1.1637 +        case bltestRSA_OAEP:
  1.1638 +            cipherInfo->cipher.pubkeyCipher = encrypt ? rsa_encryptOAEP
  1.1639 +                                                      : rsa_decryptOAEP;
  1.1640 +            break;
  1.1641 +    }
  1.1642 +    return SECSuccess;
  1.1643 +}
  1.1644 +
  1.1645 +SECStatus
  1.1646 +blapi_pqg_param_gen(unsigned int keysize, PQGParams **pqg, PQGVerify **vfy)
  1.1647 +{
  1.1648 +    if (keysize < 1024) {
  1.1649 +	int j = PQG_PBITS_TO_INDEX(keysize);
  1.1650 +	return PQG_ParamGen(j, pqg, vfy);
  1.1651 +    }
  1.1652 +    return PQG_ParamGenV2(keysize, 0, 0, pqg, vfy);
  1.1653 +}
  1.1654 +
  1.1655 +SECStatus
  1.1656 +bltest_pqg_init(bltestDSAParams *dsap)
  1.1657 +{
  1.1658 +    SECStatus rv, res;
  1.1659 +    PQGVerify *vfy = NULL;
  1.1660 +    rv = blapi_pqg_param_gen(dsap->keysize, &dsap->pqg, &vfy);
  1.1661 +    CHECKERROR(rv, __LINE__);
  1.1662 +    rv = PQG_VerifyParams(dsap->pqg, vfy, &res);
  1.1663 +    CHECKERROR(res, __LINE__);
  1.1664 +    CHECKERROR(rv, __LINE__);
  1.1665 +    return rv;
  1.1666 +}
  1.1667 +
  1.1668 +SECStatus
  1.1669 +bltest_dsa_init(bltestCipherInfo *cipherInfo, PRBool encrypt)
  1.1670 +{
  1.1671 +    int i;
  1.1672 +    DSAPrivateKey **dummyKey;
  1.1673 +    PQGParams *dummypqg;
  1.1674 +    PRIntervalTime time1, time2;
  1.1675 +    bltestAsymKeyParams *asymk = &cipherInfo->params.asymk;
  1.1676 +    bltestDSAParams *dsap = &asymk->cipherParams.dsa;
  1.1677 +    PQGVerify *ignore = NULL;
  1.1678 +    cipherInfo->cx = asymk;
  1.1679 +    /* For performance testing */
  1.1680 +    if (cipherInfo->cxreps > 0) {
  1.1681 +	/* Create space for n private key objects */
  1.1682 +	dummyKey = (DSAPrivateKey **)PORT_ZAlloc(cipherInfo->cxreps *
  1.1683 +	                                         sizeof(DSAPrivateKey *));
  1.1684 +	/* Time n keygens, storing in the array */
  1.1685 +	TIMESTART();
  1.1686 +	for (i=0; i<cipherInfo->cxreps; i++) {
  1.1687 +	    dummypqg = NULL;
  1.1688 +	    blapi_pqg_param_gen(dsap->keysize, &dummypqg, &ignore);
  1.1689 +	    DSA_NewKey(dummypqg, &dummyKey[i]);
  1.1690 +	}
  1.1691 +	TIMEFINISH(cipherInfo->cxtime, cipherInfo->cxreps);
  1.1692 +	/* Free the n key objects */
  1.1693 +	for (i=0; i<cipherInfo->cxreps; i++)
  1.1694 +	    PORT_FreeArena(dummyKey[i]->params.arena, PR_TRUE);
  1.1695 +	PORT_Free(dummyKey);
  1.1696 +    }
  1.1697 +    if (!dsap->pqg && dsap->pqgdata.buf.len > 0) {
  1.1698 +	dsap->pqg = pqg_from_filedata(&dsap->pqgdata.buf);
  1.1699 +    }
  1.1700 +    if (!asymk->privKey && asymk->key.buf.len > 0) {
  1.1701 +	asymk->privKey = dsakey_from_filedata(&asymk->key.buf);
  1.1702 +    }
  1.1703 +    if (encrypt) {
  1.1704 +	cipherInfo->cipher.pubkeyCipher = dsa_signDigest;
  1.1705 +    } else {
  1.1706 +	/* Have to convert private key to public key.  Memory
  1.1707 +	 * is freed with private key's arena  */
  1.1708 +	DSAPublicKey *pubkey;
  1.1709 +	DSAPrivateKey *key = (DSAPrivateKey *)asymk->privKey;
  1.1710 +	pubkey = (DSAPublicKey *)PORT_ArenaZAlloc(key->params.arena,
  1.1711 +						  sizeof(DSAPublicKey));
  1.1712 +	pubkey->params.prime.len = key->params.prime.len;
  1.1713 +	pubkey->params.prime.data = key->params.prime.data;
  1.1714 +	pubkey->params.subPrime.len = key->params.subPrime.len;
  1.1715 +	pubkey->params.subPrime.data = key->params.subPrime.data;
  1.1716 +	pubkey->params.base.len = key->params.base.len;
  1.1717 +	pubkey->params.base.data = key->params.base.data;
  1.1718 +	pubkey->publicValue.len = key->publicValue.len;
  1.1719 +	pubkey->publicValue.data = key->publicValue.data;
  1.1720 +	asymk->pubKey = pubkey;
  1.1721 +	cipherInfo->cipher.pubkeyCipher = dsa_verifyDigest;
  1.1722 +    }
  1.1723 +    return SECSuccess;
  1.1724 +}
  1.1725 +
  1.1726 +#ifndef NSS_DISABLE_ECC
  1.1727 +SECStatus
  1.1728 +bltest_ecdsa_init(bltestCipherInfo *cipherInfo, PRBool encrypt)
  1.1729 +{
  1.1730 +    int i;
  1.1731 +    ECPrivateKey **dummyKey;
  1.1732 +    PRIntervalTime time1, time2;
  1.1733 +    bltestAsymKeyParams *asymk = &cipherInfo->params.asymk;
  1.1734 +    cipherInfo->cx = asymk;
  1.1735 +    /* For performance testing */
  1.1736 +    if (cipherInfo->cxreps > 0) {
  1.1737 +	/* Create space for n private key objects */
  1.1738 +	dummyKey = (ECPrivateKey **)PORT_ZAlloc(cipherInfo->cxreps *
  1.1739 +	                                         sizeof(ECPrivateKey *));
  1.1740 +	/* Time n keygens, storing in the array */
  1.1741 +	TIMESTART();
  1.1742 +	for (i=0; i<cipherInfo->cxreps; i++) {
  1.1743 +	    EC_NewKey(&((ECPrivateKey *)asymk->privKey)->ecParams, &dummyKey[i]);
  1.1744 +	}
  1.1745 +	TIMEFINISH(cipherInfo->cxtime, cipherInfo->cxreps);
  1.1746 +	/* Free the n key objects */
  1.1747 +	for (i=0; i<cipherInfo->cxreps; i++)
  1.1748 +	    PORT_FreeArena(dummyKey[i]->ecParams.arena, PR_TRUE);
  1.1749 +	PORT_Free(dummyKey);
  1.1750 +    }
  1.1751 +    if (!asymk->privKey && asymk->key.buf.len > 0) {
  1.1752 +        asymk->privKey = eckey_from_filedata(&asymk->key.buf);
  1.1753 +    }
  1.1754 +    if (encrypt) {
  1.1755 +	cipherInfo->cipher.pubkeyCipher = ecdsa_signDigest;
  1.1756 +    } else {
  1.1757 +	/* Have to convert private key to public key.  Memory
  1.1758 +	 * is freed with private key's arena  */
  1.1759 +	ECPublicKey *pubkey;
  1.1760 +	ECPrivateKey *key = (ECPrivateKey *)asymk->privKey;
  1.1761 +	pubkey = (ECPublicKey *)PORT_ArenaZAlloc(key->ecParams.arena,
  1.1762 +						  sizeof(ECPublicKey));
  1.1763 +	pubkey->ecParams.type = key->ecParams.type;
  1.1764 +	pubkey->ecParams.fieldID.size = key->ecParams.fieldID.size;
  1.1765 +	pubkey->ecParams.fieldID.type = key->ecParams.fieldID.type;
  1.1766 +	pubkey->ecParams.fieldID.u.prime.len = key->ecParams.fieldID.u.prime.len;
  1.1767 +	pubkey->ecParams.fieldID.u.prime.data = key->ecParams.fieldID.u.prime.data;
  1.1768 +	pubkey->ecParams.fieldID.k1 = key->ecParams.fieldID.k1;
  1.1769 +	pubkey->ecParams.fieldID.k2 = key->ecParams.fieldID.k2;
  1.1770 +	pubkey->ecParams.fieldID.k3 = key->ecParams.fieldID.k3;
  1.1771 +	pubkey->ecParams.curve.a.len = key->ecParams.curve.a.len;
  1.1772 +	pubkey->ecParams.curve.a.data = key->ecParams.curve.a.data;
  1.1773 +	pubkey->ecParams.curve.b.len = key->ecParams.curve.b.len;
  1.1774 +	pubkey->ecParams.curve.b.data = key->ecParams.curve.b.data;
  1.1775 +	pubkey->ecParams.curve.seed.len = key->ecParams.curve.seed.len;
  1.1776 +	pubkey->ecParams.curve.seed.data = key->ecParams.curve.seed.data;
  1.1777 +	pubkey->ecParams.base.len = key->ecParams.base.len;
  1.1778 +	pubkey->ecParams.base.data = key->ecParams.base.data;
  1.1779 +	pubkey->ecParams.order.len = key->ecParams.order.len;
  1.1780 +	pubkey->ecParams.order.data = key->ecParams.order.data;
  1.1781 +	pubkey->ecParams.cofactor = key->ecParams.cofactor;
  1.1782 +	pubkey->ecParams.DEREncoding.len = key->ecParams.DEREncoding.len;
  1.1783 +	pubkey->ecParams.DEREncoding.data = key->ecParams.DEREncoding.data;
  1.1784 +	pubkey->ecParams.name= key->ecParams.name;
  1.1785 +	pubkey->publicValue.len = key->publicValue.len;
  1.1786 +	pubkey->publicValue.data = key->publicValue.data;
  1.1787 +	asymk->pubKey = pubkey;
  1.1788 +	cipherInfo->cipher.pubkeyCipher = ecdsa_verifyDigest;
  1.1789 +    }
  1.1790 +    return SECSuccess;
  1.1791 +}
  1.1792 +#endif
  1.1793 +
  1.1794 +/* XXX unfortunately, this is not defined in blapi.h */
  1.1795 +SECStatus
  1.1796 +md2_HashBuf(unsigned char *dest, const unsigned char *src, PRUint32 src_length)
  1.1797 +{
  1.1798 +    unsigned int len;
  1.1799 +    MD2Context *cx = MD2_NewContext();
  1.1800 +    if (cx == NULL) return SECFailure;
  1.1801 +    MD2_Begin(cx);
  1.1802 +    MD2_Update(cx, src, src_length);
  1.1803 +    MD2_End(cx, dest, &len, MD2_LENGTH);
  1.1804 +    MD2_DestroyContext(cx, PR_TRUE);
  1.1805 +    return SECSuccess;
  1.1806 +}
  1.1807 +
  1.1808 +SECStatus
  1.1809 +md2_restart(unsigned char *dest, const unsigned char *src, PRUint32 src_length)
  1.1810 +{
  1.1811 +    MD2Context *cx, *cx_cpy;
  1.1812 +    unsigned char *cxbytes;
  1.1813 +    unsigned int len;
  1.1814 +    unsigned int i, quarter;
  1.1815 +    SECStatus rv = SECSuccess;
  1.1816 +    cx = MD2_NewContext();
  1.1817 +    MD2_Begin(cx);
  1.1818 +    /* divide message by 4, restarting 3 times */
  1.1819 +    quarter = (src_length + 3)/ 4;
  1.1820 +    for (i=0; i < 4 && src_length > 0; i++) {
  1.1821 +	MD2_Update(cx, src + i*quarter, PR_MIN(quarter, src_length));
  1.1822 +	len = MD2_FlattenSize(cx);
  1.1823 +	cxbytes = PORT_Alloc(len);
  1.1824 +	MD2_Flatten(cx, cxbytes);
  1.1825 +	cx_cpy = MD2_Resurrect(cxbytes, NULL);
  1.1826 +	if (!cx_cpy) {
  1.1827 +	    PR_fprintf(PR_STDERR, "%s: MD2_Resurrect failed!\n", progName);
  1.1828 +	    goto finish;
  1.1829 +	}
  1.1830 +	rv = PORT_Memcmp(cx, cx_cpy, len);
  1.1831 +	if (rv) {
  1.1832 +	    MD2_DestroyContext(cx_cpy, PR_TRUE);
  1.1833 +	    PR_fprintf(PR_STDERR, "%s: MD2_restart failed!\n", progName);
  1.1834 +	    goto finish;
  1.1835 +	}
  1.1836 +	MD2_DestroyContext(cx_cpy, PR_TRUE);
  1.1837 +	PORT_Free(cxbytes);
  1.1838 +	src_length -= quarter;
  1.1839 +    }
  1.1840 +    MD2_End(cx, dest, &len, MD2_LENGTH);
  1.1841 +finish:
  1.1842 +    MD2_DestroyContext(cx, PR_TRUE);
  1.1843 +    return rv;
  1.1844 +}
  1.1845 +
  1.1846 +SECStatus
  1.1847 +md5_restart(unsigned char *dest, const unsigned char *src, PRUint32 src_length)
  1.1848 +{
  1.1849 +    SECStatus rv = SECSuccess;
  1.1850 +    MD5Context *cx, *cx_cpy;
  1.1851 +    unsigned char *cxbytes;
  1.1852 +    unsigned int len;
  1.1853 +    unsigned int i, quarter;
  1.1854 +    cx = MD5_NewContext();
  1.1855 +    MD5_Begin(cx);
  1.1856 +    /* divide message by 4, restarting 3 times */
  1.1857 +    quarter = (src_length + 3)/ 4;
  1.1858 +    for (i=0; i < 4 && src_length > 0; i++) {
  1.1859 +	MD5_Update(cx, src + i*quarter, PR_MIN(quarter, src_length));
  1.1860 +	len = MD5_FlattenSize(cx);
  1.1861 +	cxbytes = PORT_Alloc(len);
  1.1862 +	MD5_Flatten(cx, cxbytes);
  1.1863 +	cx_cpy = MD5_Resurrect(cxbytes, NULL);
  1.1864 +	if (!cx_cpy) {
  1.1865 +	    PR_fprintf(PR_STDERR, "%s: MD5_Resurrect failed!\n", progName);
  1.1866 +	    rv = SECFailure;
  1.1867 +	    goto finish;
  1.1868 +	}
  1.1869 +	rv = PORT_Memcmp(cx, cx_cpy, len);
  1.1870 +	if (rv) {
  1.1871 +	    MD5_DestroyContext(cx_cpy, PR_TRUE);
  1.1872 +	    PR_fprintf(PR_STDERR, "%s: MD5_restart failed!\n", progName);
  1.1873 +	    goto finish;
  1.1874 +	}
  1.1875 +	MD5_DestroyContext(cx_cpy, PR_TRUE);
  1.1876 +	PORT_Free(cxbytes);
  1.1877 +	src_length -= quarter;
  1.1878 +    }
  1.1879 +    MD5_End(cx, dest, &len, MD5_LENGTH);
  1.1880 +finish:
  1.1881 +    MD5_DestroyContext(cx, PR_TRUE);
  1.1882 +    return rv;
  1.1883 +}
  1.1884 +
  1.1885 +SECStatus
  1.1886 +sha1_restart(unsigned char *dest, const unsigned char *src, PRUint32 src_length)
  1.1887 +{
  1.1888 +    SECStatus rv = SECSuccess;
  1.1889 +    SHA1Context *cx, *cx_cpy;
  1.1890 +    unsigned char *cxbytes;
  1.1891 +    unsigned int len;
  1.1892 +    unsigned int i, quarter;
  1.1893 +    cx = SHA1_NewContext();
  1.1894 +    SHA1_Begin(cx);
  1.1895 +    /* divide message by 4, restarting 3 times */
  1.1896 +    quarter = (src_length + 3)/ 4;
  1.1897 +    for (i=0; i < 4 && src_length > 0; i++) {
  1.1898 +	SHA1_Update(cx, src + i*quarter, PR_MIN(quarter, src_length));
  1.1899 +	len = SHA1_FlattenSize(cx);
  1.1900 +	cxbytes = PORT_Alloc(len);
  1.1901 +	SHA1_Flatten(cx, cxbytes);
  1.1902 +	cx_cpy = SHA1_Resurrect(cxbytes, NULL);
  1.1903 +	if (!cx_cpy) {
  1.1904 +	    PR_fprintf(PR_STDERR, "%s: SHA1_Resurrect failed!\n", progName);
  1.1905 +	    rv = SECFailure;
  1.1906 +	    goto finish;
  1.1907 +	}
  1.1908 +	rv = PORT_Memcmp(cx, cx_cpy, len);
  1.1909 +	if (rv) {
  1.1910 +	    SHA1_DestroyContext(cx_cpy, PR_TRUE);
  1.1911 +	    PR_fprintf(PR_STDERR, "%s: SHA1_restart failed!\n", progName);
  1.1912 +	    goto finish;
  1.1913 +	}
  1.1914 +	SHA1_DestroyContext(cx_cpy, PR_TRUE);
  1.1915 +	PORT_Free(cxbytes);
  1.1916 +	src_length -= quarter;
  1.1917 +    }
  1.1918 +    SHA1_End(cx, dest, &len, MD5_LENGTH);
  1.1919 +finish:
  1.1920 +    SHA1_DestroyContext(cx, PR_TRUE);
  1.1921 +    return rv;
  1.1922 +}
  1.1923 +
  1.1924 +SECStatus
  1.1925 +SHA224_restart(unsigned char *dest, const unsigned char *src, PRUint32 src_length)
  1.1926 +{
  1.1927 +    SECStatus rv = SECSuccess;
  1.1928 +    SHA224Context *cx, *cx_cpy;
  1.1929 +    unsigned char *cxbytes;
  1.1930 +    unsigned int len;
  1.1931 +    unsigned int i, quarter;
  1.1932 +    cx = SHA224_NewContext();
  1.1933 +    SHA224_Begin(cx);
  1.1934 +    /* divide message by 4, restarting 3 times */
  1.1935 +    quarter = (src_length + 3) / 4;
  1.1936 +    for (i=0; i < 4 && src_length > 0; i++) {
  1.1937 +	SHA224_Update(cx, src + i*quarter, PR_MIN(quarter, src_length));
  1.1938 +	len = SHA224_FlattenSize(cx);
  1.1939 +	cxbytes = PORT_Alloc(len);
  1.1940 +	SHA224_Flatten(cx, cxbytes);
  1.1941 +	cx_cpy = SHA224_Resurrect(cxbytes, NULL);
  1.1942 +	if (!cx_cpy) {
  1.1943 +	    PR_fprintf(PR_STDERR, "%s: SHA224_Resurrect failed!\n", progName);
  1.1944 +	    rv = SECFailure;
  1.1945 +	    goto finish;
  1.1946 +	}
  1.1947 +	rv = PORT_Memcmp(cx, cx_cpy, len);
  1.1948 +	if (rv) {
  1.1949 +	    SHA224_DestroyContext(cx_cpy, PR_TRUE);
  1.1950 +	    PR_fprintf(PR_STDERR, "%s: SHA224_restart failed!\n", progName);
  1.1951 +	    goto finish;
  1.1952 +	}
  1.1953 +	
  1.1954 +	SHA224_DestroyContext(cx_cpy, PR_TRUE);
  1.1955 +	PORT_Free(cxbytes);
  1.1956 +	src_length -= quarter;
  1.1957 +    }
  1.1958 +    SHA224_End(cx, dest, &len, MD5_LENGTH);
  1.1959 +finish:
  1.1960 +    SHA224_DestroyContext(cx, PR_TRUE);
  1.1961 +    return rv;
  1.1962 +}
  1.1963 +
  1.1964 +SECStatus
  1.1965 +SHA256_restart(unsigned char *dest, const unsigned char *src, PRUint32 src_length)
  1.1966 +{
  1.1967 +    SECStatus rv = SECSuccess;
  1.1968 +    SHA256Context *cx, *cx_cpy;
  1.1969 +    unsigned char *cxbytes;
  1.1970 +    unsigned int len;
  1.1971 +    unsigned int i, quarter;
  1.1972 +    cx = SHA256_NewContext();
  1.1973 +    SHA256_Begin(cx);
  1.1974 +    /* divide message by 4, restarting 3 times */
  1.1975 +    quarter = (src_length + 3)/ 4;
  1.1976 +    for (i=0; i < 4 && src_length > 0; i++) {
  1.1977 +	SHA256_Update(cx, src + i*quarter, PR_MIN(quarter, src_length));
  1.1978 +	len = SHA256_FlattenSize(cx);
  1.1979 +	cxbytes = PORT_Alloc(len);
  1.1980 +	SHA256_Flatten(cx, cxbytes);
  1.1981 +	cx_cpy = SHA256_Resurrect(cxbytes, NULL);
  1.1982 +	if (!cx_cpy) {
  1.1983 +	    PR_fprintf(PR_STDERR, "%s: SHA256_Resurrect failed!\n", progName);
  1.1984 +	    rv = SECFailure;
  1.1985 +	    goto finish;
  1.1986 +	}
  1.1987 +	rv = PORT_Memcmp(cx, cx_cpy, len);
  1.1988 +	if (rv) {
  1.1989 +	    SHA256_DestroyContext(cx_cpy, PR_TRUE);
  1.1990 +	    PR_fprintf(PR_STDERR, "%s: SHA256_restart failed!\n", progName);
  1.1991 +	    goto finish;
  1.1992 +	}
  1.1993 +	SHA256_DestroyContext(cx_cpy, PR_TRUE);
  1.1994 +	PORT_Free(cxbytes);
  1.1995 +	src_length -= quarter;
  1.1996 +    }
  1.1997 +    SHA256_End(cx, dest, &len, MD5_LENGTH);
  1.1998 +finish:
  1.1999 +    SHA256_DestroyContext(cx, PR_TRUE);
  1.2000 +    return rv;
  1.2001 +}
  1.2002 +
  1.2003 +SECStatus
  1.2004 +SHA384_restart(unsigned char *dest, const unsigned char *src, PRUint32 src_length)
  1.2005 +{
  1.2006 +    SECStatus rv = SECSuccess;
  1.2007 +    SHA384Context *cx, *cx_cpy;
  1.2008 +    unsigned char *cxbytes;
  1.2009 +    unsigned int len;
  1.2010 +    unsigned int i, quarter;
  1.2011 +    cx = SHA384_NewContext();
  1.2012 +    SHA384_Begin(cx);
  1.2013 +    /* divide message by 4, restarting 3 times */
  1.2014 +    quarter = (src_length + 3)/ 4;
  1.2015 +    for (i=0; i < 4 && src_length > 0; i++) {
  1.2016 +	SHA384_Update(cx, src + i*quarter, PR_MIN(quarter, src_length));
  1.2017 +	len = SHA384_FlattenSize(cx);
  1.2018 +	cxbytes = PORT_Alloc(len);
  1.2019 +	SHA384_Flatten(cx, cxbytes);
  1.2020 +	cx_cpy = SHA384_Resurrect(cxbytes, NULL);
  1.2021 +	if (!cx_cpy) {
  1.2022 +	    PR_fprintf(PR_STDERR, "%s: SHA384_Resurrect failed!\n", progName);
  1.2023 +	    rv = SECFailure;
  1.2024 +	    goto finish;
  1.2025 +	}
  1.2026 +	rv = PORT_Memcmp(cx, cx_cpy, len);
  1.2027 +	if (rv) {
  1.2028 +	    SHA384_DestroyContext(cx_cpy, PR_TRUE);
  1.2029 +	    PR_fprintf(PR_STDERR, "%s: SHA384_restart failed!\n", progName);
  1.2030 +	    goto finish;
  1.2031 +	}
  1.2032 +	SHA384_DestroyContext(cx_cpy, PR_TRUE);
  1.2033 +	PORT_Free(cxbytes);
  1.2034 +	src_length -= quarter;
  1.2035 +    }
  1.2036 +    SHA384_End(cx, dest, &len, MD5_LENGTH);
  1.2037 +finish:
  1.2038 +    SHA384_DestroyContext(cx, PR_TRUE);
  1.2039 +    return rv;
  1.2040 +}
  1.2041 +
  1.2042 +SECStatus
  1.2043 +SHA512_restart(unsigned char *dest, const unsigned char *src, PRUint32 src_length)
  1.2044 +{
  1.2045 +    SECStatus rv = SECSuccess;
  1.2046 +    SHA512Context *cx, *cx_cpy;
  1.2047 +    unsigned char *cxbytes;
  1.2048 +    unsigned int len;
  1.2049 +    unsigned int i, quarter;
  1.2050 +    cx = SHA512_NewContext();
  1.2051 +    SHA512_Begin(cx);
  1.2052 +    /* divide message by 4, restarting 3 times */
  1.2053 +    quarter = (src_length + 3)/ 4;
  1.2054 +    for (i=0; i < 4 && src_length > 0; i++) {
  1.2055 +	SHA512_Update(cx, src + i*quarter, PR_MIN(quarter, src_length));
  1.2056 +	len = SHA512_FlattenSize(cx);
  1.2057 +	cxbytes = PORT_Alloc(len);
  1.2058 +	SHA512_Flatten(cx, cxbytes);
  1.2059 +	cx_cpy = SHA512_Resurrect(cxbytes, NULL);
  1.2060 +	if (!cx_cpy) {
  1.2061 +	    PR_fprintf(PR_STDERR, "%s: SHA512_Resurrect failed!\n", progName);
  1.2062 +	    rv = SECFailure;
  1.2063 +	    goto finish;
  1.2064 +	}
  1.2065 +	rv = PORT_Memcmp(cx, cx_cpy, len);
  1.2066 +	if (rv) {
  1.2067 +	    SHA512_DestroyContext(cx_cpy, PR_TRUE);
  1.2068 +	    PR_fprintf(PR_STDERR, "%s: SHA512_restart failed!\n", progName);
  1.2069 +	    goto finish;
  1.2070 +	}
  1.2071 +	SHA512_DestroyContext(cx_cpy, PR_TRUE);
  1.2072 +	PORT_Free(cxbytes);
  1.2073 +	src_length -= quarter;
  1.2074 +    }
  1.2075 +    SHA512_End(cx, dest, &len, MD5_LENGTH);
  1.2076 +finish:
  1.2077 +    SHA512_DestroyContext(cx, PR_TRUE);
  1.2078 +    return rv;
  1.2079 +}
  1.2080 +
  1.2081 +SECStatus
  1.2082 +pubkeyInitKey(bltestCipherInfo *cipherInfo, PRFileDesc *file,
  1.2083 +#ifndef NSS_DISABLE_ECC
  1.2084 +	      int keysize, int exponent, char *curveName)
  1.2085 +#else
  1.2086 +	      int keysize, int exponent)
  1.2087 +#endif
  1.2088 +{
  1.2089 +    int i;
  1.2090 +    SECStatus rv = SECSuccess;
  1.2091 +    bltestAsymKeyParams *asymk = &cipherInfo->params.asymk;
  1.2092 +    bltestRSAParams *rsap;
  1.2093 +    RSAPrivateKey **rsaKey = NULL;
  1.2094 +    bltestDSAParams *dsap;
  1.2095 +    DSAPrivateKey **dsaKey = NULL;
  1.2096 +#ifndef NSS_DISABLE_ECC
  1.2097 +    SECItem *tmpECParamsDER;
  1.2098 +    ECParams *tmpECParams = NULL;
  1.2099 +    SECItem ecSerialize[3];
  1.2100 +    ECPrivateKey **ecKey = NULL;
  1.2101 +#endif
  1.2102 +    switch (cipherInfo->mode) {
  1.2103 +    case bltestRSA:
  1.2104 +    case bltestRSA_PSS:
  1.2105 +    case bltestRSA_OAEP:
  1.2106 +	rsap = &asymk->cipherParams.rsa;
  1.2107 +        rsaKey = (RSAPrivateKey **)&asymk->privKey;
  1.2108 +	if (keysize > 0) {
  1.2109 +	    SECItem expitem = { 0, 0, 0 };
  1.2110 +	    SECITEM_AllocItem(cipherInfo->arena, &expitem, sizeof(int));
  1.2111 +	    for (i = 1; i <= sizeof(int); i++)
  1.2112 +		expitem.data[i-1] = exponent >> (8*(sizeof(int) - i));
  1.2113 +	    *rsaKey = RSA_NewKey(keysize * 8, &expitem);
  1.2114 +	    serialize_key(&(*rsaKey)->version, 9, file);
  1.2115 +	    rsap->keysizeInBits = keysize * 8;
  1.2116 +	} else {
  1.2117 +	    setupIO(cipherInfo->arena, &asymk->key, file, NULL, 0);
  1.2118 +	    *rsaKey = rsakey_from_filedata(&asymk->key.buf);
  1.2119 +	    rsap->keysizeInBits = (*rsaKey)->modulus.len * 8;
  1.2120 +	}
  1.2121 +	break;
  1.2122 +    case bltestDSA:
  1.2123 +	dsap = &asymk->cipherParams.dsa;
  1.2124 +	dsaKey = (DSAPrivateKey **)&asymk->privKey;
  1.2125 +	if (keysize > 0) {
  1.2126 +	    dsap->keysize = keysize*8;
  1.2127 +	    if (!dsap->pqg)
  1.2128 +		bltest_pqg_init(dsap);
  1.2129 +	    rv = DSA_NewKey(dsap->pqg, dsaKey);
  1.2130 +	    CHECKERROR(rv, __LINE__);
  1.2131 +	    serialize_key(&(*dsaKey)->params.prime, 5, file);
  1.2132 +	} else {
  1.2133 +	    setupIO(cipherInfo->arena, &asymk->key, file, NULL, 0);
  1.2134 +	    *dsaKey = dsakey_from_filedata(&asymk->key.buf);
  1.2135 +	    dsap->keysize = (*dsaKey)->params.prime.len*8;
  1.2136 +	}
  1.2137 +	break;
  1.2138 +#ifndef NSS_DISABLE_ECC
  1.2139 +    case bltestECDSA:
  1.2140 +	ecKey = (ECPrivateKey **)&asymk->privKey;
  1.2141 +	if (curveName != NULL) {
  1.2142 +	    tmpECParamsDER = getECParams(curveName);
  1.2143 +	    rv = SECOID_Init();
  1.2144 +	    CHECKERROR(rv, __LINE__);
  1.2145 +	    rv = EC_DecodeParams(tmpECParamsDER, &tmpECParams) == SECFailure;
  1.2146 +	    CHECKERROR(rv, __LINE__);
  1.2147 +	    rv = EC_NewKey(tmpECParams, ecKey);
  1.2148 +	    CHECKERROR(rv, __LINE__);
  1.2149 +	    ecSerialize[0].type = tmpECParamsDER->type;
  1.2150 +	    ecSerialize[0].data = tmpECParamsDER->data;
  1.2151 +	    ecSerialize[0].len  = tmpECParamsDER->len;
  1.2152 +	    ecSerialize[1].type = (*ecKey)->publicValue.type;
  1.2153 +	    ecSerialize[1].data = (*ecKey)->publicValue.data;
  1.2154 +	    ecSerialize[1].len  = (*ecKey)->publicValue.len;
  1.2155 +	    ecSerialize[2].type = (*ecKey)->privateValue.type;
  1.2156 +	    ecSerialize[2].data = (*ecKey)->privateValue.data;
  1.2157 +	    ecSerialize[2].len  = (*ecKey)->privateValue.len;
  1.2158 +	    serialize_key(&(ecSerialize[0]), 3, file);
  1.2159 +	    SECITEM_FreeItem(tmpECParamsDER, PR_TRUE);
  1.2160 +	    PORT_FreeArena(tmpECParams->arena, PR_TRUE);
  1.2161 +	    rv = SECOID_Shutdown();
  1.2162 +	    CHECKERROR(rv, __LINE__);
  1.2163 +	} else {
  1.2164 +	    setupIO(cipherInfo->arena, &asymk->key, file, NULL, 0);
  1.2165 +	    *ecKey = eckey_from_filedata(&asymk->key.buf);
  1.2166 +	}
  1.2167 +	break;
  1.2168 +#endif
  1.2169 +    default:
  1.2170 +	return SECFailure;
  1.2171 +    }
  1.2172 +    return SECSuccess;
  1.2173 +}
  1.2174 +
  1.2175 +SECStatus
  1.2176 +cipherInit(bltestCipherInfo *cipherInfo, PRBool encrypt)
  1.2177 +{
  1.2178 +    PRBool restart;
  1.2179 +    int outlen;
  1.2180 +    switch (cipherInfo->mode) {
  1.2181 +    case bltestDES_ECB:
  1.2182 +    case bltestDES_CBC:
  1.2183 +    case bltestDES_EDE_ECB:
  1.2184 +    case bltestDES_EDE_CBC:
  1.2185 +	SECITEM_AllocItem(cipherInfo->arena, &cipherInfo->output.buf,
  1.2186 +			  cipherInfo->input.pBuf.len);
  1.2187 +	return bltest_des_init(cipherInfo, encrypt);
  1.2188 +	break;
  1.2189 +    case bltestRC2_ECB:
  1.2190 +    case bltestRC2_CBC:
  1.2191 +	SECITEM_AllocItem(cipherInfo->arena, &cipherInfo->output.buf,
  1.2192 +			  cipherInfo->input.pBuf.len);
  1.2193 +	return bltest_rc2_init(cipherInfo, encrypt);
  1.2194 +	break;
  1.2195 +    case bltestRC4:
  1.2196 +	SECITEM_AllocItem(cipherInfo->arena, &cipherInfo->output.buf,
  1.2197 +			  cipherInfo->input.pBuf.len);
  1.2198 +	return bltest_rc4_init(cipherInfo, encrypt);
  1.2199 +	break;
  1.2200 +#ifdef NSS_SOFTOKEN_DOES_RC5
  1.2201 +    case bltestRC5_ECB:
  1.2202 +    case bltestRC5_CBC:
  1.2203 +	SECITEM_AllocItem(cipherInfo->arena, &cipherInfo->output.buf,
  1.2204 +			  cipherInfo->input.pBuf.len);
  1.2205 +#endif
  1.2206 +	return bltest_rc5_init(cipherInfo, encrypt);
  1.2207 +	break;
  1.2208 +    case bltestAES_ECB:
  1.2209 +    case bltestAES_CBC:
  1.2210 +    case bltestAES_CTS:
  1.2211 +    case bltestAES_CTR:
  1.2212 +    case bltestAES_GCM:
  1.2213 +	outlen = cipherInfo->input.pBuf.len;
  1.2214 +	if (cipherInfo->mode == bltestAES_GCM && encrypt) {
  1.2215 +	    outlen += 16;
  1.2216 +	}
  1.2217 +	SECITEM_AllocItem(cipherInfo->arena, &cipherInfo->output.buf, outlen);
  1.2218 +	return bltest_aes_init(cipherInfo, encrypt);
  1.2219 +	break;
  1.2220 +    case bltestCAMELLIA_ECB:
  1.2221 +    case bltestCAMELLIA_CBC:
  1.2222 +	SECITEM_AllocItem(cipherInfo->arena, &cipherInfo->output.buf,
  1.2223 +			  cipherInfo->input.pBuf.len);
  1.2224 +	return bltest_camellia_init(cipherInfo, encrypt);
  1.2225 +	break;
  1.2226 +    case bltestSEED_ECB:
  1.2227 +    case bltestSEED_CBC:
  1.2228 +	SECITEM_AllocItem(cipherInfo->arena, &cipherInfo->output.buf,
  1.2229 +			  cipherInfo->input.pBuf.len);
  1.2230 +	return bltest_seed_init(cipherInfo, encrypt);
  1.2231 +	break;
  1.2232 +    case bltestRSA:
  1.2233 +    case bltestRSA_OAEP:
  1.2234 +    case bltestRSA_PSS:
  1.2235 +	if (encrypt || cipherInfo->mode != bltestRSA_PSS) {
  1.2236 +		/* Don't allocate a buffer for PSS in verify mode, as no actual
  1.2237 +		 * output is produced. */
  1.2238 +		SECITEM_AllocItem(cipherInfo->arena, &cipherInfo->output.buf,
  1.2239 +		                  RSA_MAX_MODULUS_BITS / 8);
  1.2240 +	}
  1.2241 +	return bltest_rsa_init(cipherInfo, encrypt);
  1.2242 +	break;
  1.2243 +    case bltestDSA:
  1.2244 +	if (encrypt) {
  1.2245 +		SECITEM_AllocItem(cipherInfo->arena, &cipherInfo->output.buf,
  1.2246 +		                  DSA_MAX_SIGNATURE_LEN);
  1.2247 +	}
  1.2248 +	return bltest_dsa_init(cipherInfo, encrypt);
  1.2249 +	break;
  1.2250 +#ifndef NSS_DISABLE_ECC
  1.2251 +    case bltestECDSA:
  1.2252 +	if (encrypt) {
  1.2253 +		SECITEM_AllocItem(cipherInfo->arena, &cipherInfo->output.buf,
  1.2254 +		                  2 * MAX_ECKEY_LEN);
  1.2255 +	}
  1.2256 +	return bltest_ecdsa_init(cipherInfo, encrypt);
  1.2257 +	break;
  1.2258 +#endif
  1.2259 +    case bltestMD2:
  1.2260 +	restart = cipherInfo->params.hash.restart;
  1.2261 +	SECITEM_AllocItem(cipherInfo->arena, &cipherInfo->output.buf,
  1.2262 +			  MD2_LENGTH);
  1.2263 +	cipherInfo->cipher.hashCipher = (restart) ? md2_restart : md2_HashBuf;
  1.2264 +	return SECSuccess;
  1.2265 +	break;
  1.2266 +    case bltestMD5:
  1.2267 +	restart = cipherInfo->params.hash.restart;
  1.2268 +	SECITEM_AllocItem(cipherInfo->arena, &cipherInfo->output.buf,
  1.2269 +			  MD5_LENGTH);
  1.2270 +	cipherInfo->cipher.hashCipher = (restart) ? md5_restart : MD5_HashBuf;
  1.2271 +	return SECSuccess;
  1.2272 +	break;
  1.2273 +    case bltestSHA1:
  1.2274 +	restart = cipherInfo->params.hash.restart;
  1.2275 +	SECITEM_AllocItem(cipherInfo->arena, &cipherInfo->output.buf,
  1.2276 +			  SHA1_LENGTH);
  1.2277 +	cipherInfo->cipher.hashCipher = (restart) ? sha1_restart : SHA1_HashBuf;
  1.2278 +	return SECSuccess;
  1.2279 +	break;
  1.2280 +    case bltestSHA224:
  1.2281 +	restart = cipherInfo->params.hash.restart;
  1.2282 +	SECITEM_AllocItem(cipherInfo->arena, &cipherInfo->output.buf,
  1.2283 +			  SHA224_LENGTH);
  1.2284 +	cipherInfo->cipher.hashCipher = (restart) ? SHA224_restart 
  1.2285 +	                                          : SHA224_HashBuf;
  1.2286 +	return SECSuccess;
  1.2287 +	break;
  1.2288 +    case bltestSHA256:
  1.2289 +	restart = cipherInfo->params.hash.restart;
  1.2290 +	SECITEM_AllocItem(cipherInfo->arena, &cipherInfo->output.buf,
  1.2291 +			  SHA256_LENGTH);
  1.2292 +	cipherInfo->cipher.hashCipher = (restart) ? SHA256_restart 
  1.2293 +	                                          : SHA256_HashBuf;
  1.2294 +	return SECSuccess;
  1.2295 +	break;
  1.2296 +    case bltestSHA384:
  1.2297 +	restart = cipherInfo->params.hash.restart;
  1.2298 +	SECITEM_AllocItem(cipherInfo->arena, &cipherInfo->output.buf,
  1.2299 +			  SHA384_LENGTH);
  1.2300 +	cipherInfo->cipher.hashCipher = (restart) ? SHA384_restart 
  1.2301 +	                                          : SHA384_HashBuf;
  1.2302 +	return SECSuccess;
  1.2303 +	break;
  1.2304 +    case bltestSHA512:
  1.2305 +	restart = cipherInfo->params.hash.restart;
  1.2306 +	SECITEM_AllocItem(cipherInfo->arena, &cipherInfo->output.buf,
  1.2307 +			  SHA512_LENGTH);
  1.2308 +	cipherInfo->cipher.hashCipher = (restart) ? SHA512_restart 
  1.2309 +	                                          : SHA512_HashBuf;
  1.2310 +	return SECSuccess;
  1.2311 +	break;
  1.2312 +    default:
  1.2313 +	return SECFailure;
  1.2314 +    }
  1.2315 +    return SECSuccess;
  1.2316 +}
  1.2317 +
  1.2318 +SECStatus
  1.2319 +cipherDoOp(bltestCipherInfo *cipherInfo)
  1.2320 +{
  1.2321 +    PRIntervalTime time1, time2;
  1.2322 +    SECStatus rv = SECSuccess;
  1.2323 +    int i;
  1.2324 +    unsigned int len;
  1.2325 +    unsigned int maxLen = cipherInfo->output.pBuf.len;
  1.2326 +    unsigned char *dummyOut;
  1.2327 +    dummyOut = PORT_Alloc(maxLen);
  1.2328 +    if (is_symmkeyCipher(cipherInfo->mode)) {
  1.2329 +        const unsigned char *input = cipherInfo->input.pBuf.data;
  1.2330 +        unsigned int inputLen = is_singleShotCipher(cipherInfo->mode) ?
  1.2331 +                 cipherInfo->input.pBuf.len :
  1.2332 +                 PR_MIN(cipherInfo->input.pBuf.len, 16);
  1.2333 +        unsigned char *output = cipherInfo->output.pBuf.data;
  1.2334 +        unsigned int outputLen = maxLen;
  1.2335 +        unsigned int totalOutputLen = 0;
  1.2336 +        TIMESTART();
  1.2337 +        rv = (*cipherInfo->cipher.symmkeyCipher)(cipherInfo->cx,
  1.2338 +                                                 output, &len, outputLen,
  1.2339 +                                                 input, inputLen);
  1.2340 +        CHECKERROR(rv, __LINE__);
  1.2341 +        totalOutputLen += len;
  1.2342 +        if (cipherInfo->input.pBuf.len > inputLen) {
  1.2343 +            input += inputLen;
  1.2344 +            inputLen = cipherInfo->input.pBuf.len - inputLen;
  1.2345 +            output += len;
  1.2346 +            outputLen -= len;
  1.2347 +            rv = (*cipherInfo->cipher.symmkeyCipher)(cipherInfo->cx,
  1.2348 +                                                     output, &len, outputLen,
  1.2349 +                                                     input, inputLen);
  1.2350 +            CHECKERROR(rv, __LINE__);
  1.2351 +	    totalOutputLen += len;
  1.2352 +        }
  1.2353 +	cipherInfo->output.pBuf.len = totalOutputLen;
  1.2354 +        TIMEFINISH(cipherInfo->optime, 1.0);
  1.2355 +        cipherInfo->repetitions = 0;
  1.2356 +        if (cipherInfo->repetitionsToPerfom != 0) {
  1.2357 +            TIMESTART();
  1.2358 +            for (i=0; i<cipherInfo->repetitionsToPerfom; i++,
  1.2359 +                     cipherInfo->repetitions++) {
  1.2360 +                (*cipherInfo->cipher.symmkeyCipher)(cipherInfo->cx, dummyOut,
  1.2361 +                                                    &len, maxLen,
  1.2362 +                                                    cipherInfo->input.pBuf.data,
  1.2363 +                                                    cipherInfo->input.pBuf.len);
  1.2364 +                
  1.2365 +                CHECKERROR(rv, __LINE__);
  1.2366 +            }
  1.2367 +        } else {
  1.2368 +            int opsBetweenChecks = 0;
  1.2369 +            TIMEMARK(cipherInfo->seconds);
  1.2370 +            while (! (TIMETOFINISH())) {
  1.2371 +                int j = 0;
  1.2372 +                for (;j < opsBetweenChecks;j++) {
  1.2373 +                    (*cipherInfo->cipher.symmkeyCipher)(
  1.2374 +                        cipherInfo->cx, dummyOut, &len, maxLen,
  1.2375 +                        cipherInfo->input.pBuf.data,
  1.2376 +                        cipherInfo->input.pBuf.len);
  1.2377 +                }
  1.2378 +                cipherInfo->repetitions += j;
  1.2379 +            }
  1.2380 +        }
  1.2381 +        TIMEFINISH(cipherInfo->optime, 1.0);
  1.2382 +    } else if (is_pubkeyCipher(cipherInfo->mode)) {
  1.2383 +        TIMESTART();
  1.2384 +        rv = (*cipherInfo->cipher.pubkeyCipher)(cipherInfo->cx,
  1.2385 +                                                &cipherInfo->output.pBuf,
  1.2386 +                                                &cipherInfo->input.pBuf);
  1.2387 +        TIMEFINISH(cipherInfo->optime, 1.0);
  1.2388 +        CHECKERROR(rv, __LINE__);
  1.2389 +        cipherInfo->repetitions = 0;
  1.2390 +        if (cipherInfo->repetitionsToPerfom != 0) {
  1.2391 +            TIMESTART();
  1.2392 +            for (i=0; i<cipherInfo->repetitionsToPerfom;
  1.2393 +                 i++, cipherInfo->repetitions++) {
  1.2394 +                SECItem dummy;
  1.2395 +                dummy.data = dummyOut;
  1.2396 +                dummy.len = maxLen;
  1.2397 +                (*cipherInfo->cipher.pubkeyCipher)(cipherInfo->cx, &dummy, 
  1.2398 +                                                   &cipherInfo->input.pBuf);
  1.2399 +                CHECKERROR(rv, __LINE__);
  1.2400 +            }
  1.2401 +        } else {
  1.2402 +            int opsBetweenChecks = 0;
  1.2403 +            TIMEMARK(cipherInfo->seconds);
  1.2404 +            while (! (TIMETOFINISH())) {
  1.2405 +                int j = 0;
  1.2406 +                for (;j < opsBetweenChecks;j++) {
  1.2407 +                    SECItem dummy;
  1.2408 +                    dummy.data = dummyOut;
  1.2409 +                    dummy.len = maxLen;
  1.2410 +                    (*cipherInfo->cipher.pubkeyCipher)(cipherInfo->cx, &dummy,
  1.2411 +                                                       &cipherInfo->input.pBuf);
  1.2412 +                    CHECKERROR(rv, __LINE__);
  1.2413 +                }
  1.2414 +                cipherInfo->repetitions += j;
  1.2415 +            }
  1.2416 +        }
  1.2417 +        TIMEFINISH(cipherInfo->optime, 1.0);
  1.2418 +    } else if (is_hashCipher(cipherInfo->mode)) {
  1.2419 +        TIMESTART();
  1.2420 +        rv = (*cipherInfo->cipher.hashCipher)(cipherInfo->output.pBuf.data,
  1.2421 +                                              cipherInfo->input.pBuf.data,
  1.2422 +                                              cipherInfo->input.pBuf.len);
  1.2423 +        TIMEFINISH(cipherInfo->optime, 1.0);
  1.2424 +        CHECKERROR(rv, __LINE__);
  1.2425 +        cipherInfo->repetitions = 0;
  1.2426 +        if (cipherInfo->repetitionsToPerfom != 0) {
  1.2427 +            TIMESTART();
  1.2428 +            for (i=0; i<cipherInfo->repetitionsToPerfom;
  1.2429 +                 i++, cipherInfo->repetitions++) {
  1.2430 +                (*cipherInfo->cipher.hashCipher)(dummyOut,
  1.2431 +                                                 cipherInfo->input.pBuf.data,
  1.2432 +                                                 cipherInfo->input.pBuf.len);
  1.2433 +                CHECKERROR(rv, __LINE__);
  1.2434 +            }
  1.2435 +        } else {
  1.2436 +            int opsBetweenChecks = 0;
  1.2437 +            TIMEMARK(cipherInfo->seconds);
  1.2438 +            while (! (TIMETOFINISH())) {
  1.2439 +                int j = 0;
  1.2440 +                for (;j < opsBetweenChecks;j++) {
  1.2441 +                    bltestIO *input = &cipherInfo->input;
  1.2442 +                    (*cipherInfo->cipher.hashCipher)(dummyOut,
  1.2443 +                                                     input->pBuf.data,
  1.2444 +                                                     input->pBuf.len);
  1.2445 +                    CHECKERROR(rv, __LINE__);
  1.2446 +                }
  1.2447 +                cipherInfo->repetitions += j;
  1.2448 +            }
  1.2449 +        }
  1.2450 +        TIMEFINISH(cipherInfo->optime, 1.0);
  1.2451 +    }
  1.2452 +    PORT_Free(dummyOut);
  1.2453 +    return rv;
  1.2454 +}
  1.2455 +
  1.2456 +SECStatus
  1.2457 +cipherFinish(bltestCipherInfo *cipherInfo)
  1.2458 +{
  1.2459 +    SECStatus rv = SECSuccess;
  1.2460 +
  1.2461 +    switch (cipherInfo->mode) {
  1.2462 +    case bltestDES_ECB:
  1.2463 +    case bltestDES_CBC:
  1.2464 +    case bltestDES_EDE_ECB:
  1.2465 +    case bltestDES_EDE_CBC:
  1.2466 +	DES_DestroyContext((DESContext *)cipherInfo->cx, PR_TRUE);
  1.2467 +	break;
  1.2468 +    case bltestAES_GCM:
  1.2469 +    case bltestAES_ECB:
  1.2470 +    case bltestAES_CBC:
  1.2471 +    case bltestAES_CTS:
  1.2472 +    case bltestAES_CTR:
  1.2473 +	AES_DestroyContext((AESContext *)cipherInfo->cx, PR_TRUE);
  1.2474 +	break;
  1.2475 +    case bltestCAMELLIA_ECB:
  1.2476 +    case bltestCAMELLIA_CBC:
  1.2477 +	Camellia_DestroyContext((CamelliaContext *)cipherInfo->cx, PR_TRUE);
  1.2478 +	break;
  1.2479 +    case bltestSEED_ECB:
  1.2480 +    case bltestSEED_CBC:
  1.2481 +	SEED_DestroyContext((SEEDContext *)cipherInfo->cx, PR_TRUE);
  1.2482 +	break;
  1.2483 +    case bltestRC2_ECB:
  1.2484 +    case bltestRC2_CBC:
  1.2485 +	RC2_DestroyContext((RC2Context *)cipherInfo->cx, PR_TRUE);
  1.2486 +	break;
  1.2487 +    case bltestRC4:
  1.2488 +	RC4_DestroyContext((RC4Context *)cipherInfo->cx, PR_TRUE);
  1.2489 +	break;
  1.2490 +#ifdef NSS_SOFTOKEN_DOES_RC5
  1.2491 +    case bltestRC5_ECB:
  1.2492 +    case bltestRC5_CBC:
  1.2493 +	RC5_DestroyContext((RC5Context *)cipherInfo->cx, PR_TRUE);
  1.2494 +	break;
  1.2495 +#endif
  1.2496 +    case bltestRSA:      /* keys are alloc'ed within cipherInfo's arena, */
  1.2497 +    case bltestRSA_PSS:  /* will be freed with it. */
  1.2498 +    case bltestRSA_OAEP:
  1.2499 +    case bltestDSA:
  1.2500 +#ifndef NSS_DISABLE_ECC
  1.2501 +    case bltestECDSA:
  1.2502 +#endif
  1.2503 +    case bltestMD2: /* hash contexts are ephemeral */
  1.2504 +    case bltestMD5:
  1.2505 +    case bltestSHA1:
  1.2506 +    case bltestSHA224:
  1.2507 +    case bltestSHA256:
  1.2508 +    case bltestSHA384:
  1.2509 +    case bltestSHA512:
  1.2510 +	return SECSuccess;
  1.2511 +	break;
  1.2512 +    default:
  1.2513 +	return SECFailure;
  1.2514 +    }
  1.2515 +    return rv;
  1.2516 +}
  1.2517 +
  1.2518 +void
  1.2519 +print_exponent(SECItem *exp)
  1.2520 +{
  1.2521 +    int i;
  1.2522 +    int e = 0;
  1.2523 +    if (exp->len <= 4) {
  1.2524 +	for (i=exp->len; i >=0; --i) e |= exp->data[exp->len-i] << 8*(i-1);
  1.2525 +	fprintf(stdout, "%12d", e);
  1.2526 +    } else {
  1.2527 +	e = 8*exp->len;
  1.2528 +	fprintf(stdout, "~2**%-8d", e);
  1.2529 +    }
  1.2530 +}
  1.2531 +
  1.2532 +static void
  1.2533 +splitToReportUnit(PRInt64 res, int *resArr, int *del, int size)
  1.2534 +{
  1.2535 +    PRInt64 remaining = res, tmp = 0;
  1.2536 +    PRInt64 Ldel;
  1.2537 +    int i = -1;
  1.2538 +
  1.2539 +    while (remaining > 0 && ++i < size) {
  1.2540 +        LL_I2L(Ldel, del[i]);
  1.2541 +        LL_MOD(tmp, remaining, Ldel);
  1.2542 +        LL_L2I(resArr[i], tmp);
  1.2543 +        LL_DIV(remaining, remaining, Ldel);
  1.2544 +    }
  1.2545 +}
  1.2546 +
  1.2547 +static char*
  1.2548 +getHighUnitBytes(PRInt64 res)
  1.2549 +{
  1.2550 +    int spl[] = {0, 0, 0, 0};
  1.2551 +    int del[] = {1024, 1024, 1024, 1024};
  1.2552 +    char *marks[] = {"b", "Kb", "Mb", "Gb"};
  1.2553 +    int i = 3;
  1.2554 +
  1.2555 +    splitToReportUnit(res, spl, del, 4);
  1.2556 +
  1.2557 +    for (;i>0;i--) {
  1.2558 +        if (spl[i] != 0) {
  1.2559 +            break;
  1.2560 +        }
  1.2561 +    }
  1.2562 +
  1.2563 +    return PR_smprintf("%d%s", spl[i], marks[i]);
  1.2564 +}
  1.2565 +
  1.2566 +
  1.2567 +static void
  1.2568 +printPR_smpString(const char *sformat, char *reportStr,
  1.2569 +                  const char *nformat, PRInt64 rNum)
  1.2570 +{
  1.2571 +    if (reportStr) {
  1.2572 +        fprintf(stdout, sformat, reportStr);
  1.2573 +        PR_smprintf_free(reportStr);
  1.2574 +    } else {
  1.2575 +        int prnRes;
  1.2576 +        LL_L2I(prnRes, rNum);
  1.2577 +        fprintf(stdout, nformat, rNum);
  1.2578 +    }
  1.2579 +}
  1.2580 +
  1.2581 +static char*
  1.2582 +getHighUnitOps(PRInt64 res)
  1.2583 +{
  1.2584 +    int spl[] = {0, 0, 0, 0};
  1.2585 +    int del[] = {1000, 1000, 1000, 1000};
  1.2586 +    char *marks[] = {"", "T", "M", "B"};
  1.2587 +    int i = 3;
  1.2588 +
  1.2589 +    splitToReportUnit(res, spl, del, 4);
  1.2590 +
  1.2591 +    for (;i>0;i--) {
  1.2592 +        if (spl[i] != 0) {
  1.2593 +            break;
  1.2594 +        }
  1.2595 +    }
  1.2596 +
  1.2597 +    return PR_smprintf("%d%s", spl[i], marks[i]);
  1.2598 +}
  1.2599 +
  1.2600 +void
  1.2601 +dump_performance_info(bltestCipherInfo *infoList, double totalTimeInt,
  1.2602 +                      PRBool encrypt, PRBool cxonly)
  1.2603 +{
  1.2604 +    bltestCipherInfo *info = infoList;
  1.2605 +    
  1.2606 +    PRInt64 totalIn = 0;
  1.2607 +    PRBool td = PR_TRUE;
  1.2608 +
  1.2609 +    int   repetitions = 0;
  1.2610 +    int   cxreps = 0;
  1.2611 +    double cxtime = 0;
  1.2612 +    double optime = 0;
  1.2613 +    while (info != NULL) {
  1.2614 +        repetitions += info->repetitions;
  1.2615 +        cxreps += info->cxreps;
  1.2616 +        cxtime += info->cxtime;
  1.2617 +        optime += info->optime;
  1.2618 +        totalIn += (PRInt64) info->input.buf.len * (PRInt64) info->repetitions;
  1.2619 +        
  1.2620 +        info = info->next;
  1.2621 +    }
  1.2622 +    info = infoList;
  1.2623 +
  1.2624 +    fprintf(stdout, "#%9s", "mode");
  1.2625 +    fprintf(stdout, "%12s", "in");
  1.2626 +print_td:
  1.2627 +    switch (info->mode) {
  1.2628 +      case bltestDES_ECB:
  1.2629 +      case bltestDES_CBC:
  1.2630 +      case bltestDES_EDE_ECB:
  1.2631 +      case bltestDES_EDE_CBC:
  1.2632 +      case bltestAES_ECB:
  1.2633 +      case bltestAES_CBC:
  1.2634 +      case bltestAES_CTS:
  1.2635 +      case bltestAES_CTR:
  1.2636 +      case bltestAES_GCM:
  1.2637 +      case bltestCAMELLIA_ECB:
  1.2638 +      case bltestCAMELLIA_CBC:
  1.2639 +      case bltestSEED_ECB:
  1.2640 +      case bltestSEED_CBC:
  1.2641 +      case bltestRC2_ECB:
  1.2642 +      case bltestRC2_CBC:
  1.2643 +      case bltestRC4:
  1.2644 +          if (td)
  1.2645 +              fprintf(stdout, "%8s", "symmkey");
  1.2646 +          else
  1.2647 +              fprintf(stdout, "%8d", 8*info->params.sk.key.buf.len);
  1.2648 +          break;
  1.2649 +#ifdef NSS_SOFTOKEN_DOES_RC5
  1.2650 +      case bltestRC5_ECB:
  1.2651 +      case bltestRC5_CBC:
  1.2652 +          if (info->params.sk.key.buf.len > 0)
  1.2653 +              printf("symmetric key(bytes)=%d,", info->params.sk.key.buf.len);
  1.2654 +          if (info->rounds > 0)
  1.2655 +              printf("rounds=%d,", info->params.rc5.rounds);
  1.2656 +          if (info->wordsize > 0)
  1.2657 +              printf("wordsize(bytes)=%d,", info->params.rc5.wordsize);
  1.2658 +          break;
  1.2659 +#endif
  1.2660 +      case bltestRSA:
  1.2661 +      case bltestRSA_PSS:
  1.2662 +      case bltestRSA_OAEP:
  1.2663 +          if (td) {
  1.2664 +              fprintf(stdout, "%8s", "rsa_mod");
  1.2665 +              fprintf(stdout, "%12s", "rsa_pe");
  1.2666 +          } else {
  1.2667 +              bltestAsymKeyParams *asymk = &info->params.asymk;
  1.2668 +              fprintf(stdout, "%8d", asymk->cipherParams.rsa.keysizeInBits);
  1.2669 +              print_exponent(
  1.2670 +                  &((RSAPrivateKey *)asymk->privKey)->publicExponent);
  1.2671 +          }
  1.2672 +          break;
  1.2673 +      case bltestDSA:
  1.2674 +          if (td) {
  1.2675 +              fprintf(stdout, "%8s", "pqg_mod");
  1.2676 +          } else {
  1.2677 +              fprintf(stdout, "%8d", info->params.asymk.cipherParams.dsa.keysize);
  1.2678 +          }
  1.2679 +          break;
  1.2680 +#ifndef NSS_DISABLE_ECC
  1.2681 +      case bltestECDSA:
  1.2682 +          if (td) {
  1.2683 +              fprintf(stdout, "%12s", "ec_curve");
  1.2684 +          } else {
  1.2685 +              ECPrivateKey *key = (ECPrivateKey*)info->params.asymk.privKey;
  1.2686 +              ECCurveName curveName = key->ecParams.name;
  1.2687 +              fprintf(stdout, "%12s",
  1.2688 +                      ecCurve_map[curveName]? ecCurve_map[curveName]->text:
  1.2689 +                      "Unsupported curve");
  1.2690 +          }
  1.2691 +          break;
  1.2692 +#endif
  1.2693 +      case bltestMD2:
  1.2694 +      case bltestMD5:
  1.2695 +      case bltestSHA1:
  1.2696 +      case bltestSHA256:
  1.2697 +      case bltestSHA384:
  1.2698 +      case bltestSHA512:
  1.2699 +      default:
  1.2700 +          break;
  1.2701 +    }
  1.2702 +    if (!td) {
  1.2703 +        PRInt64 totalThroughPut;
  1.2704 +
  1.2705 +        printPR_smpString("%8s", getHighUnitOps(repetitions),
  1.2706 +                          "%8d", repetitions);
  1.2707 +
  1.2708 +        printPR_smpString("%8s", getHighUnitOps(cxreps), "%8d", cxreps);
  1.2709 +
  1.2710 +        fprintf(stdout, "%12.3f", cxtime);
  1.2711 +        fprintf(stdout, "%12.3f", optime);
  1.2712 +        fprintf(stdout, "%12.03f", totalTimeInt / 1000);
  1.2713 +
  1.2714 +        totalThroughPut = (PRInt64)(totalIn / totalTimeInt * 1000);
  1.2715 +        printPR_smpString("%12s", getHighUnitBytes(totalThroughPut),
  1.2716 +                          "%12d", totalThroughPut);
  1.2717 +
  1.2718 +        fprintf(stdout, "\n");
  1.2719 +        return;
  1.2720 +    }
  1.2721 +    
  1.2722 +    fprintf(stdout, "%8s", "opreps");
  1.2723 +    fprintf(stdout, "%8s", "cxreps");
  1.2724 +    fprintf(stdout, "%12s", "context");
  1.2725 +    fprintf(stdout, "%12s", "op");
  1.2726 +    fprintf(stdout, "%12s", "time(sec)");
  1.2727 +    fprintf(stdout, "%12s", "thrgput");
  1.2728 +    fprintf(stdout, "\n");
  1.2729 +    fprintf(stdout, "%8s", mode_strings[info->mode]);
  1.2730 +    fprintf(stdout, "_%c", (cxonly) ? 'c' : (encrypt) ? 'e' : 'd');
  1.2731 +    printPR_smpString("%12s", getHighUnitBytes(totalIn), "%12d", totalIn);
  1.2732 +    
  1.2733 +    td = !td;
  1.2734 +    goto print_td;
  1.2735 +}
  1.2736 +
  1.2737 +void
  1.2738 +printmodes()
  1.2739 +{
  1.2740 +    bltestCipherMode mode;
  1.2741 +    int nummodes = sizeof(mode_strings) / sizeof(char *);
  1.2742 +    fprintf(stderr, "%s: Available modes (specify with -m):\n", progName);
  1.2743 +    for (mode=0; mode<nummodes; mode++)
  1.2744 +	fprintf(stderr, "%s\n", mode_strings[mode]);
  1.2745 +}
  1.2746 +
  1.2747 +bltestCipherMode
  1.2748 +get_mode(const char *modestring)
  1.2749 +{
  1.2750 +    bltestCipherMode mode;
  1.2751 +    int nummodes = sizeof(mode_strings) / sizeof(char *);
  1.2752 +    for (mode=0; mode<nummodes; mode++)
  1.2753 +	if (PL_strcmp(modestring, mode_strings[mode]) == 0)
  1.2754 +	    return mode;
  1.2755 +    fprintf(stderr, "%s: invalid mode: %s\n", progName, modestring);
  1.2756 +    return bltestINVALID;
  1.2757 +}
  1.2758 +
  1.2759 +void
  1.2760 +load_file_data(PLArenaPool *arena, bltestIO *data,
  1.2761 +	       char *fn, bltestIOMode ioMode)
  1.2762 +{
  1.2763 +    PRFileDesc *file;
  1.2764 +    data->mode = ioMode;
  1.2765 +    data->file = NULL; /* don't use -- not saving anything */
  1.2766 +    data->pBuf.data = NULL;
  1.2767 +    data->pBuf.len = 0;
  1.2768 +    file = PR_Open(fn, PR_RDONLY, 00660);
  1.2769 +    if (file) {
  1.2770 +	setupIO(arena, data, file, NULL, 0);
  1.2771 +	PR_Close(file);
  1.2772 +    }
  1.2773 +}
  1.2774 +
  1.2775 +HASH_HashType
  1.2776 +mode_str_to_hash_alg(const SECItem *modeStr)
  1.2777 +{
  1.2778 +    bltestCipherMode mode;
  1.2779 +    char* tempModeStr = NULL;
  1.2780 +    if (!modeStr || modeStr->len == 0)
  1.2781 +        return HASH_AlgNULL;
  1.2782 +    tempModeStr = PORT_Alloc(modeStr->len + 1);
  1.2783 +    if (!tempModeStr)
  1.2784 +        return HASH_AlgNULL;
  1.2785 +    memcpy(tempModeStr, modeStr->data, modeStr->len);
  1.2786 +    tempModeStr[modeStr->len] = '\0';
  1.2787 +    mode = get_mode(tempModeStr);
  1.2788 +    PORT_Free(tempModeStr);
  1.2789 +    switch (mode) {
  1.2790 +        case bltestMD2:    return HASH_AlgMD2;
  1.2791 +        case bltestMD5:    return HASH_AlgMD5;
  1.2792 +        case bltestSHA1:   return HASH_AlgSHA1;
  1.2793 +        case bltestSHA224: return HASH_AlgSHA224;
  1.2794 +        case bltestSHA256: return HASH_AlgSHA256;
  1.2795 +        case bltestSHA384: return HASH_AlgSHA384;
  1.2796 +        case bltestSHA512: return HASH_AlgSHA512;
  1.2797 +    }
  1.2798 +    return HASH_AlgNULL;
  1.2799 +}
  1.2800 +
  1.2801 +void
  1.2802 +get_params(PLArenaPool *arena, bltestParams *params,
  1.2803 +	   bltestCipherMode mode, int j)
  1.2804 +{
  1.2805 +    char filename[256];
  1.2806 +    char *modestr = mode_strings[mode];
  1.2807 +    bltestIO tempIO;
  1.2808 +
  1.2809 +#ifdef NSS_SOFTOKEN_DOES_RC5
  1.2810 +    FILE *file;
  1.2811 +    char *mark, *param, *val;
  1.2812 +    int index = 0;
  1.2813 +#endif
  1.2814 +    switch (mode) {
  1.2815 +    case bltestAES_GCM:
  1.2816 +	sprintf(filename, "%s/tests/%s/%s%d", testdir, modestr, "aad", j);
  1.2817 +	load_file_data(arena, &params->ask.aad, filename, bltestBinary);
  1.2818 +    case bltestDES_CBC:
  1.2819 +    case bltestDES_EDE_CBC:
  1.2820 +    case bltestRC2_CBC:
  1.2821 +    case bltestAES_CBC:
  1.2822 +    case bltestAES_CTS:
  1.2823 +    case bltestAES_CTR:
  1.2824 +    case bltestCAMELLIA_CBC:
  1.2825 +    case bltestSEED_CBC: 
  1.2826 +	sprintf(filename, "%s/tests/%s/%s%d", testdir, modestr, "iv", j);
  1.2827 +	load_file_data(arena, &params->sk.iv, filename, bltestBinary);
  1.2828 +    case bltestDES_ECB:
  1.2829 +    case bltestDES_EDE_ECB:
  1.2830 +    case bltestRC2_ECB:
  1.2831 +    case bltestRC4:
  1.2832 +    case bltestAES_ECB:
  1.2833 +    case bltestCAMELLIA_ECB:
  1.2834 +    case bltestSEED_ECB:
  1.2835 +	sprintf(filename, "%s/tests/%s/%s%d", testdir, modestr, "key", j);
  1.2836 +	load_file_data(arena, &params->sk.key, filename, bltestBinary);
  1.2837 +	break;
  1.2838 +#ifdef NSS_SOFTOKEN_DOES_RC5
  1.2839 +    case bltestRC5_ECB:
  1.2840 +    case bltestRC5_CBC:
  1.2841 +	sprintf(filename, "%s/tests/%s/%s%d", testdir, modestr, "iv", j);
  1.2842 +	load_file_data(arena, &params->sk.iv, filename, bltestBinary);
  1.2843 +	sprintf(filename, "%s/tests/%s/%s%d", testdir, modestr, "key", j);
  1.2844 +	load_file_data(arena, &params->sk.key, filename, bltestBinary);
  1.2845 +	    sprintf(filename, "%s/tests/%s/%s%d", testdir, modestr,
  1.2846 +			      "params", j);
  1.2847 +	file = fopen(filename, "r");
  1.2848 +	if (!file) return;
  1.2849 +	param = malloc(100);
  1.2850 +	len = fread(param, 1, 100, file);
  1.2851 +	while (index < len) {
  1.2852 +	    mark = PL_strchr(param, '=');
  1.2853 +	    *mark = '\0';
  1.2854 +	    val = mark + 1;
  1.2855 +	    mark = PL_strchr(val, '\n');
  1.2856 +	    *mark = '\0';
  1.2857 +	    if (PL_strcmp(param, "rounds") == 0) {
  1.2858 +		params->rc5.rounds = atoi(val);
  1.2859 +	    } else if (PL_strcmp(param, "wordsize") == 0) {
  1.2860 +		params->rc5.wordsize = atoi(val);
  1.2861 +	    }
  1.2862 +	    index += PL_strlen(param) + PL_strlen(val) + 2;
  1.2863 +	    param = mark + 1;
  1.2864 +	}
  1.2865 +	break;
  1.2866 +#endif
  1.2867 +    case bltestRSA_PSS:
  1.2868 +	sprintf(filename, "%s/tests/%s/%s%d", testdir, modestr, "ciphertext", j);
  1.2869 +	load_file_data(arena, &params->asymk.sig, filename, bltestBase64Encoded);
  1.2870 +	/* fall through */
  1.2871 +    case bltestRSA_OAEP:
  1.2872 +	sprintf(filename, "%s/tests/%s/%s%d", testdir, modestr, "seed", j);
  1.2873 +	load_file_data(arena, &params->asymk.cipherParams.rsa.seed,
  1.2874 +	               filename, bltestBase64Encoded);
  1.2875 +
  1.2876 +	sprintf(filename, "%s/tests/%s/%s%d", testdir, modestr, "hash", j);
  1.2877 +	load_file_data(arena, &tempIO, filename, bltestBinary);
  1.2878 +	params->asymk.cipherParams.rsa.hashAlg =
  1.2879 +	    mode_str_to_hash_alg(&tempIO.buf);
  1.2880 +
  1.2881 +	sprintf(filename, "%s/tests/%s/%s%d", testdir, modestr, "maskhash", j);
  1.2882 +	load_file_data(arena, &tempIO, filename, bltestBinary);
  1.2883 +	params->asymk.cipherParams.rsa.maskHashAlg =
  1.2884 +	    mode_str_to_hash_alg(&tempIO.buf);
  1.2885 +	/* fall through */
  1.2886 +    case bltestRSA:
  1.2887 +	sprintf(filename, "%s/tests/%s/%s%d", testdir, modestr, "key", j);
  1.2888 +	load_file_data(arena, &params->asymk.key, filename,
  1.2889 +	               bltestBase64Encoded);
  1.2890 +	params->asymk.privKey =
  1.2891 +	    (void *)rsakey_from_filedata(&params->asymk.key.buf);
  1.2892 +	break;
  1.2893 +    case bltestDSA:
  1.2894 +	sprintf(filename, "%s/tests/%s/%s%d", testdir, modestr, "key", j);
  1.2895 +	load_file_data(arena, &params->asymk.key, filename, bltestBase64Encoded);
  1.2896 +	params->asymk.privKey =
  1.2897 +	     (void *)dsakey_from_filedata(&params->asymk.key.buf);
  1.2898 +	sprintf(filename, "%s/tests/%s/%s%d", testdir, modestr, "pqg", j);
  1.2899 +	load_file_data(arena, &params->asymk.cipherParams.dsa.pqgdata, filename,
  1.2900 +	               bltestBase64Encoded);
  1.2901 +	params->asymk.cipherParams.dsa.pqg =
  1.2902 +	      pqg_from_filedata(&params->asymk.cipherParams.dsa.pqgdata.buf);
  1.2903 +	sprintf(filename, "%s/tests/%s/%s%d", testdir, modestr, "keyseed", j);
  1.2904 +	load_file_data(arena, &params->asymk.cipherParams.dsa.keyseed, filename,
  1.2905 +	               bltestBase64Encoded);
  1.2906 +	sprintf(filename, "%s/tests/%s/%s%d", testdir, modestr, "sigseed", j);
  1.2907 +	load_file_data(arena, &params->asymk.cipherParams.dsa.sigseed, filename,
  1.2908 +	               bltestBase64Encoded);
  1.2909 +	sprintf(filename, "%s/tests/%s/%s%d", testdir, modestr, "ciphertext",j);
  1.2910 +	load_file_data(arena, &params->asymk.sig, filename, bltestBase64Encoded);
  1.2911 +	break;
  1.2912 +#ifndef NSS_DISABLE_ECC
  1.2913 +    case bltestECDSA:
  1.2914 +	sprintf(filename, "%s/tests/%s/%s%d", testdir, modestr, "key", j);
  1.2915 +	load_file_data(arena, &params->asymk.key, filename, bltestBase64Encoded);
  1.2916 +	params->asymk.privKey =
  1.2917 +	      (void *)eckey_from_filedata(&params->asymk.key.buf);
  1.2918 +	sprintf(filename, "%s/tests/%s/%s%d", testdir, modestr, "sigseed", j);
  1.2919 +	load_file_data(arena, &params->asymk.cipherParams.ecdsa.sigseed,
  1.2920 +	               filename, bltestBase64Encoded);
  1.2921 +	sprintf(filename, "%s/tests/%s/%s%d", testdir, modestr, "ciphertext",j);
  1.2922 +	load_file_data(arena, &params->asymk.sig, filename, bltestBase64Encoded);
  1.2923 +	break;
  1.2924 +#endif
  1.2925 +    case bltestMD2:
  1.2926 +    case bltestMD5:
  1.2927 +    case bltestSHA1:
  1.2928 +    case bltestSHA224:
  1.2929 +    case bltestSHA256:
  1.2930 +    case bltestSHA384:
  1.2931 +    case bltestSHA512:
  1.2932 +	/*params->hash.restart = PR_TRUE;*/
  1.2933 +	params->hash.restart = PR_FALSE;
  1.2934 +	break;
  1.2935 +    default:
  1.2936 +	break;
  1.2937 +    }
  1.2938 +}
  1.2939 +
  1.2940 +SECStatus
  1.2941 +verify_self_test(bltestIO *result, bltestIO *cmp, bltestCipherMode mode,
  1.2942 +		 PRBool forward, SECStatus sigstatus)
  1.2943 +{
  1.2944 +    PRBool equal;
  1.2945 +    char *modestr = mode_strings[mode];
  1.2946 +    equal = SECITEM_ItemsAreEqual(&result->pBuf, &cmp->buf);
  1.2947 +    if (is_sigCipher(mode)) {
  1.2948 +	if (forward) {
  1.2949 +	    if (equal) {
  1.2950 +		printf("Signature self-test for %s passed.\n", modestr);
  1.2951 +	    } else {
  1.2952 +		printf("Signature self-test for %s failed!\n", modestr);
  1.2953 +	    }
  1.2954 +	    return equal ? SECSuccess : SECFailure;
  1.2955 +	} else {
  1.2956 +	    if (sigstatus == SECSuccess) {
  1.2957 +		printf("Verification self-test for %s passed.\n", modestr);
  1.2958 +	    } else {
  1.2959 +		printf("Verification self-test for %s failed!\n", modestr);
  1.2960 +	    }
  1.2961 +	    return sigstatus;
  1.2962 +	}
  1.2963 +    } else if (is_hashCipher(mode)) {
  1.2964 +	if (equal) {
  1.2965 +	    printf("Hash self-test for %s passed.\n", modestr);
  1.2966 +	} else {
  1.2967 +	    printf("Hash self-test for %s failed!\n", modestr);
  1.2968 +	}
  1.2969 +    } else {
  1.2970 +	if (forward) {
  1.2971 +	    if (equal) {
  1.2972 +		printf("Encryption self-test for %s passed.\n", modestr);
  1.2973 +	    } else {
  1.2974 +		printf("Encryption self-test for %s failed!\n", modestr);
  1.2975 +	    }
  1.2976 +	} else {
  1.2977 +	    if (equal) {
  1.2978 +		printf("Decryption self-test for %s passed.\n", modestr);
  1.2979 +	    } else {
  1.2980 +		printf("Decryption self-test for %s failed!\n", modestr);
  1.2981 +	    }
  1.2982 +	}
  1.2983 +    }
  1.2984 +    return equal ? SECSuccess : SECFailure;
  1.2985 +}
  1.2986 +
  1.2987 +static SECStatus
  1.2988 +ReadFileToItem(SECItem *dst, const char *filename)
  1.2989 +{
  1.2990 +    PRFileDesc *file;
  1.2991 +    SECStatus rv;
  1.2992 +
  1.2993 +    file = PR_Open(filename, PR_RDONLY, 00660);
  1.2994 +    if (!file) {
  1.2995 +	return SECFailure;
  1.2996 +    }
  1.2997 +    rv = SECU_FileToItem(dst, file);
  1.2998 +    PR_Close(file);
  1.2999 +    return rv;
  1.3000 +}
  1.3001 +
  1.3002 +static SECStatus
  1.3003 +blapi_selftest(bltestCipherMode *modes, int numModes, int inoff, int outoff,
  1.3004 +               PRBool encrypt, PRBool decrypt)
  1.3005 +{
  1.3006 +    bltestCipherInfo cipherInfo;
  1.3007 +    bltestIO pt, ct;
  1.3008 +    bltestCipherMode mode;
  1.3009 +    bltestParams *params;
  1.3010 +    int i, j, nummodes, numtests;
  1.3011 +    char *modestr;
  1.3012 +    char filename[256];
  1.3013 +    PLArenaPool *arena;
  1.3014 +    SECItem item;
  1.3015 +    SECStatus rv = SECSuccess, srv;
  1.3016 +
  1.3017 +    PORT_Memset(&cipherInfo, 0, sizeof(cipherInfo));
  1.3018 +    arena = PORT_NewArena(BLTEST_DEFAULT_CHUNKSIZE);
  1.3019 +    cipherInfo.arena = arena;
  1.3020 +
  1.3021 +    nummodes = (numModes == 0) ? NUMMODES : numModes;
  1.3022 +    for (i=0; i < nummodes; i++) {
  1.3023 +	if (numModes > 0)
  1.3024 +	    mode = modes[i];
  1.3025 +	else
  1.3026 +	    mode = i;
  1.3027 +	if (mode == bltestINVALID) {
  1.3028 +	    fprintf(stderr, "%s: Skipping invalid mode.\n",progName);
  1.3029 +	    continue;
  1.3030 +	}
  1.3031 +	modestr = mode_strings[mode];
  1.3032 +	cipherInfo.mode = mode;
  1.3033 +	params = &cipherInfo.params;
  1.3034 +	/* get the number of tests in the directory */
  1.3035 +	sprintf(filename, "%s/tests/%s/%s", testdir, modestr, "numtests");
  1.3036 +	if (ReadFileToItem(&item, filename) != SECSuccess) {
  1.3037 +	    fprintf(stderr, "%s: Cannot read file %s.\n", progName, filename);
  1.3038 +	    rv = SECFailure;
  1.3039 +	    continue;
  1.3040 +	}
  1.3041 +	/* loop over the tests in the directory */
  1.3042 +	numtests = 0;
  1.3043 +	for (j=0; j<item.len; j++) {
  1.3044 +	    if (!isdigit(item.data[j])) {
  1.3045 +		break;
  1.3046 +	    }
  1.3047 +	    numtests *= 10;
  1.3048 +	    numtests += (int) (item.data[j] - '0');
  1.3049 +	}
  1.3050 +	for (j=0; j<numtests; j++) {
  1.3051 +	    sprintf(filename, "%s/tests/%s/%s%d", testdir, modestr,
  1.3052 +	            "plaintext", j);
  1.3053 +	    load_file_data(arena, &pt, filename,
  1.3054 +	                   is_sigCipher(mode) ? bltestBase64Encoded
  1.3055 +	                                      : bltestBinary);
  1.3056 +	    sprintf(filename, "%s/tests/%s/%s%d", testdir, modestr,
  1.3057 +	            "ciphertext", j);
  1.3058 +	    load_file_data(arena, &ct, filename, bltestBase64Encoded);
  1.3059 +
  1.3060 +	    get_params(arena, params, mode, j);
  1.3061 +	    /* Forward Operation (Encrypt/Sign/Hash)
  1.3062 +	    ** Align the input buffer (plaintext) according to request
  1.3063 +	    ** then perform operation and compare to ciphertext
  1.3064 +	    */
  1.3065 +	    if (encrypt) {
  1.3066 +		bltestCopyIO(arena, &cipherInfo.input, &pt);
  1.3067 +		misalignBuffer(arena, &cipherInfo.input, inoff);
  1.3068 +		memset(&cipherInfo.output.buf, 0, sizeof cipherInfo.output.buf);
  1.3069 +		rv |= cipherInit(&cipherInfo, PR_TRUE);
  1.3070 +		misalignBuffer(arena, &cipherInfo.output, outoff);
  1.3071 +		rv |= cipherDoOp(&cipherInfo);
  1.3072 +		rv |= cipherFinish(&cipherInfo);
  1.3073 +		rv |= verify_self_test(&cipherInfo.output, 
  1.3074 +		                       &ct, mode, PR_TRUE, SECSuccess);
  1.3075 +		/* If testing hash, only one op to test */
  1.3076 +		if (is_hashCipher(mode))
  1.3077 +		    continue;
  1.3078 +		if (is_sigCipher(mode)) {
  1.3079 +		    /* Verify operations support detached signature files. For
  1.3080 +		    ** consistency between tests that run Sign/Verify back to
  1.3081 +		    ** back (eg: self-tests) and tests that are only running
  1.3082 +		    ** verify operations, copy the output into the sig buf,
  1.3083 +		    ** and then copy the sig buf back out when verifying. For
  1.3084 +		    ** self-tests, this is unnecessary copying, but for
  1.3085 +		    ** verify-only operations, this ensures that the output
  1.3086 +		    ** buffer is properly configured
  1.3087 +		    */
  1.3088 +		    bltestCopyIO(arena, &params->asymk.sig, &cipherInfo.output);
  1.3089 +		}
  1.3090 +	    }
  1.3091 +	    if (!decrypt)
  1.3092 +		continue;
  1.3093 +	    /* Reverse Operation (Decrypt/Verify)
  1.3094 +	    ** Align the input buffer (ciphertext) according to request
  1.3095 +	    ** then perform operation and compare to plaintext
  1.3096 +	    */
  1.3097 +	    if (is_sigCipher(mode)) {
  1.3098 +		bltestCopyIO(arena, &cipherInfo.input, &pt);
  1.3099 +		bltestCopyIO(arena, &cipherInfo.output, &params->asymk.sig);
  1.3100 +	    } else {
  1.3101 +		bltestCopyIO(arena, &cipherInfo.input, &ct);
  1.3102 +		memset(&cipherInfo.output.buf, 0, sizeof cipherInfo.output.buf);
  1.3103 +	    }
  1.3104 +	    misalignBuffer(arena, &cipherInfo.input, inoff);
  1.3105 +	    rv |= cipherInit(&cipherInfo, PR_FALSE);
  1.3106 +	    misalignBuffer(arena, &cipherInfo.output, outoff);
  1.3107 +	    srv = SECSuccess;
  1.3108 +	    srv |= cipherDoOp(&cipherInfo);
  1.3109 +	    rv |= cipherFinish(&cipherInfo);
  1.3110 +	    rv |= verify_self_test(&cipherInfo.output, 
  1.3111 +	                           &pt, mode, PR_FALSE, srv);
  1.3112 +	}
  1.3113 +    }
  1.3114 +    return rv;
  1.3115 +}
  1.3116 +
  1.3117 +SECStatus
  1.3118 +dump_file(bltestCipherMode mode, char *filename)
  1.3119 +{
  1.3120 +    bltestIO keydata;
  1.3121 +    PLArenaPool *arena = NULL;
  1.3122 +    arena = PORT_NewArena(BLTEST_DEFAULT_CHUNKSIZE);
  1.3123 +    if (mode == bltestRSA || mode == bltestRSA_PSS || mode == bltestRSA_OAEP) {
  1.3124 +	RSAPrivateKey *key;
  1.3125 +	load_file_data(arena, &keydata, filename, bltestBase64Encoded);
  1.3126 +	key = rsakey_from_filedata(&keydata.buf);
  1.3127 +	dump_rsakey(key);
  1.3128 +    } else if (mode == bltestDSA) {
  1.3129 +#if 0
  1.3130 +	PQGParams *pqg;
  1.3131 +	get_file_data(filename, &item, PR_TRUE);
  1.3132 +	pqg = pqg_from_filedata(&item);
  1.3133 +	dump_pqg(pqg);
  1.3134 +#endif
  1.3135 +	DSAPrivateKey *key;
  1.3136 +	load_file_data(arena, &keydata, filename, bltestBase64Encoded);
  1.3137 +	key = dsakey_from_filedata(&keydata.buf);
  1.3138 +	dump_dsakey(key);
  1.3139 +#ifndef NSS_DISABLE_ECC
  1.3140 +    } else if (mode == bltestECDSA) {
  1.3141 +	ECPrivateKey *key;
  1.3142 +	load_file_data(arena, &keydata, filename, bltestBase64Encoded);
  1.3143 +	key = eckey_from_filedata(&keydata.buf);
  1.3144 +	dump_eckey(key);
  1.3145 +#endif
  1.3146 +    }
  1.3147 +    PORT_FreeArena(arena, PR_FALSE);
  1.3148 +    return SECFailure;
  1.3149 +}
  1.3150 +
  1.3151 +void ThreadExecTest(void *data)
  1.3152 +{
  1.3153 +    bltestCipherInfo *cipherInfo = (bltestCipherInfo*)data;
  1.3154 +
  1.3155 +    if (cipherInfo->mCarlo == PR_TRUE) {
  1.3156 +        int mciter;
  1.3157 +        for (mciter=0; mciter<10000; mciter++) {
  1.3158 +            cipherDoOp(cipherInfo);
  1.3159 +            memcpy(cipherInfo->input.buf.data,
  1.3160 +                   cipherInfo->output.buf.data,
  1.3161 +                   cipherInfo->input.buf.len);
  1.3162 +        }
  1.3163 +    } else {
  1.3164 +        cipherDoOp(cipherInfo);
  1.3165 +    }
  1.3166 +    cipherFinish(cipherInfo);
  1.3167 +}
  1.3168 +
  1.3169 +static void rsaPrivKeyReset(RSAPrivateKey *tstKey)
  1.3170 +{
  1.3171 +    PLArenaPool *arena;
  1.3172 +
  1.3173 +    tstKey->version.data = NULL;
  1.3174 +    tstKey->version.len = 0;
  1.3175 +    tstKey->modulus.data = NULL;
  1.3176 +    tstKey->modulus.len = 0;
  1.3177 +    tstKey->publicExponent.data = NULL;
  1.3178 +    tstKey->publicExponent.len = 0;
  1.3179 +    tstKey->privateExponent.data = NULL;
  1.3180 +    tstKey->privateExponent.len = 0;
  1.3181 +    tstKey->prime1.data = NULL;
  1.3182 +    tstKey->prime1.len = 0;
  1.3183 +    tstKey->prime2.data = NULL;
  1.3184 +    tstKey->prime2.len = 0;
  1.3185 +    tstKey->exponent1.data = NULL;
  1.3186 +    tstKey->exponent1.len = 0;
  1.3187 +    tstKey->exponent2.data = NULL;
  1.3188 +    tstKey->exponent2.len = 0;
  1.3189 +    tstKey->coefficient.data = NULL;
  1.3190 +    tstKey->coefficient.len = 0;
  1.3191 +
  1.3192 +    arena = tstKey->arena;
  1.3193 +    tstKey->arena = NULL;
  1.3194 +    if (arena) {
  1.3195 +	PORT_FreeArena(arena, PR_TRUE);
  1.3196 +    }
  1.3197 +}
  1.3198 +
  1.3199 +
  1.3200 +#define RSA_TEST_EQUAL(comp) \
  1.3201 +    if (!SECITEM_ItemsAreEqual(&(src->comp),&(dest->comp))) { \
  1.3202 +	fprintf(stderr, "key->" #comp " not equal"); \
  1.3203 +	if (src->comp.len != dest->comp.len) { \
  1.3204 +	    fprintf(stderr, "src_len = %d, dest_len = %d",  \
  1.3205 +					src->comp.len, dest->comp.len); \
  1.3206 +	} \
  1.3207 +	fprintf(stderr, "\n"); \
  1.3208 +	areEqual = PR_FALSE; \
  1.3209 +    }
  1.3210 +	    
  1.3211 +
  1.3212 +static PRBool rsaPrivKeysAreEqual(RSAPrivateKey *src, RSAPrivateKey *dest)
  1.3213 +{
  1.3214 +    PRBool areEqual = PR_TRUE;
  1.3215 +    RSA_TEST_EQUAL(modulus)
  1.3216 +    RSA_TEST_EQUAL(publicExponent)
  1.3217 +    RSA_TEST_EQUAL(privateExponent)
  1.3218 +    RSA_TEST_EQUAL(prime1)
  1.3219 +    RSA_TEST_EQUAL(prime2)
  1.3220 +    RSA_TEST_EQUAL(exponent1)
  1.3221 +    RSA_TEST_EQUAL(exponent2)
  1.3222 +    RSA_TEST_EQUAL(coefficient)
  1.3223 +    if (!areEqual) {
  1.3224 +	fprintf(stderr, "original key:\n");
  1.3225 +	dump_rsakey(src);
  1.3226 +	fprintf(stderr, "recreated key:\n");
  1.3227 +	dump_rsakey(dest);
  1.3228 +    }
  1.3229 +    return areEqual;
  1.3230 +}
  1.3231 +
  1.3232 +/*
  1.3233 + * Test the RSA populate command to see that it can really build
  1.3234 + * keys from it's components.
  1.3235 + */
  1.3236 +static int doRSAPopulateTest(unsigned int keySize, unsigned long exponent)
  1.3237 +{
  1.3238 +    RSAPrivateKey *srcKey;
  1.3239 +    RSAPrivateKey tstKey = { 0 };
  1.3240 +    SECItem expitem = { 0, 0, 0 };
  1.3241 +    SECStatus rv;
  1.3242 +    unsigned char pubExp[4];
  1.3243 +    int expLen = 0;
  1.3244 +    int failed = 0;
  1.3245 +    int i;
  1.3246 +
  1.3247 +    for (i=0; i < sizeof(unsigned long); i++) {
  1.3248 +	int shift = (sizeof(unsigned long) - i -1 ) * 8;
  1.3249 +	if (expLen || (exponent && ((unsigned long)0xffL << shift))) {
  1.3250 +	    pubExp[expLen] = (unsigned char) ((exponent >> shift) & 0xff);
  1.3251 +	    expLen++;
  1.3252 +        }
  1.3253 +    }
  1.3254 +
  1.3255 +    expitem.data = pubExp;
  1.3256 +    expitem.len = expLen;
  1.3257 +
  1.3258 +    srcKey = RSA_NewKey(keySize, &expitem);
  1.3259 +    if (srcKey == NULL) {
  1.3260 +	fprintf(stderr, "RSA Key Gen failed");
  1.3261 +	return -1;
  1.3262 +    }
  1.3263 +
  1.3264 +    /* test the basic case - most common, public exponent, modulus, prime */
  1.3265 +    tstKey.arena = NULL;
  1.3266 +    rsaPrivKeyReset(&tstKey);
  1.3267 +
  1.3268 +    tstKey.publicExponent = srcKey->publicExponent;
  1.3269 +    tstKey.modulus = srcKey->modulus;
  1.3270 +    tstKey.prime1 = srcKey->prime1;
  1.3271 +
  1.3272 +    rv = RSA_PopulatePrivateKey(&tstKey);
  1.3273 +    if (rv != SECSuccess) {
  1.3274 +	fprintf(stderr, "RSA Populate failed: pubExp mod p\n");
  1.3275 +	failed = 1;
  1.3276 +    } else if (!rsaPrivKeysAreEqual(&tstKey, srcKey)) {
  1.3277 +	fprintf(stderr, "RSA Populate key mismatch: pubExp mod p\n");
  1.3278 +	failed = 1;
  1.3279 +    }
  1.3280 +
  1.3281 +    /* test the basic2 case, public exponent, modulus, prime2 */
  1.3282 +    rsaPrivKeyReset(&tstKey);
  1.3283 +
  1.3284 +    tstKey.publicExponent = srcKey->publicExponent;
  1.3285 +    tstKey.modulus = srcKey->modulus;
  1.3286 +    tstKey.prime1 = srcKey->prime2; /* test with q in the prime1 position */
  1.3287 +
  1.3288 +    rv = RSA_PopulatePrivateKey(&tstKey);
  1.3289 +    if (rv != SECSuccess) {
  1.3290 +	fprintf(stderr, "RSA Populate failed: pubExp mod q\n");
  1.3291 +	failed = 1;
  1.3292 +    } else if (!rsaPrivKeysAreEqual(&tstKey, srcKey)) {
  1.3293 +	fprintf(stderr, "RSA Populate key mismatch: pubExp mod q\n");
  1.3294 +	failed = 1;
  1.3295 +    }
  1.3296 +
  1.3297 +    /* test the medium case, private exponent, prime1, prime2 */
  1.3298 +    rsaPrivKeyReset(&tstKey);
  1.3299 +
  1.3300 +    tstKey.privateExponent = srcKey->privateExponent;
  1.3301 +    tstKey.prime1 = srcKey->prime2; /* purposefully swap them to make */
  1.3302 +    tstKey.prime2 = srcKey->prime1; /* sure populated swaps them back */
  1.3303 +
  1.3304 +    rv = RSA_PopulatePrivateKey(&tstKey);
  1.3305 +    if (rv != SECSuccess) {
  1.3306 +	fprintf(stderr, "RSA Populate failed: privExp p q\n");
  1.3307 +	failed = 1;
  1.3308 +    } else if (!rsaPrivKeysAreEqual(&tstKey, srcKey)) {
  1.3309 +	fprintf(stderr, "RSA Populate key mismatch: privExp  p q\n");
  1.3310 +	failed = 1;
  1.3311 +    }
  1.3312 +
  1.3313 +    /* test the advanced case, public exponent, private exponent, prime2 */
  1.3314 +    rsaPrivKeyReset(&tstKey);
  1.3315 +
  1.3316 +    tstKey.privateExponent = srcKey->privateExponent;
  1.3317 +    tstKey.publicExponent = srcKey->publicExponent;
  1.3318 +    tstKey.prime2 = srcKey->prime2; /* use q in the prime2 position */
  1.3319 +
  1.3320 +    rv = RSA_PopulatePrivateKey(&tstKey);
  1.3321 +    if (rv != SECSuccess) {
  1.3322 +	fprintf(stderr, "RSA Populate failed: pubExp privExp q\n");
  1.3323 +	fprintf(stderr, " - not fatal\n");
  1.3324 +	/* it's possible that we can't uniquely determine the original key
  1.3325 +	 * from just the exponents and prime. Populate returns an error rather
  1.3326 +	 * than return the wrong key. */
  1.3327 +    } else if (!rsaPrivKeysAreEqual(&tstKey, srcKey)) {
  1.3328 +	/* if we returned a key, it *must* be correct */
  1.3329 +	fprintf(stderr, "RSA Populate key mismatch: pubExp privExp  q\n");
  1.3330 +	rv = RSA_PrivateKeyCheck(&tstKey);
  1.3331 +	failed = 1;
  1.3332 +    }
  1.3333 +
  1.3334 +    /* test the advanced case2, public exponent, private exponent, modulus */
  1.3335 +    rsaPrivKeyReset(&tstKey);
  1.3336 +
  1.3337 +    tstKey.privateExponent = srcKey->privateExponent;
  1.3338 +    tstKey.publicExponent = srcKey->publicExponent;
  1.3339 +    tstKey.modulus = srcKey->modulus;
  1.3340 +
  1.3341 +    rv = RSA_PopulatePrivateKey(&tstKey);
  1.3342 +    if (rv != SECSuccess) {
  1.3343 +	fprintf(stderr, "RSA Populate failed: pubExp privExp mod\n");
  1.3344 +	failed = 1;
  1.3345 +    } else if (!rsaPrivKeysAreEqual(&tstKey, srcKey)) {
  1.3346 +	fprintf(stderr, "RSA Populate key mismatch: pubExp privExp  mod\n");
  1.3347 +	failed = 1;
  1.3348 +    }
  1.3349 +
  1.3350 +    return failed ? -1 : 0;
  1.3351 +}
  1.3352 +
  1.3353 +
  1.3354 +
  1.3355 +/* bltest commands */
  1.3356 +enum {
  1.3357 +    cmd_Decrypt = 0,
  1.3358 +    cmd_Encrypt,
  1.3359 +    cmd_FIPS,
  1.3360 +    cmd_Hash,
  1.3361 +    cmd_Nonce,
  1.3362 +    cmd_Dump,
  1.3363 +    cmd_RSAPopulate,
  1.3364 +    cmd_Sign,
  1.3365 +    cmd_SelfTest,
  1.3366 +    cmd_Verify
  1.3367 +};
  1.3368 +
  1.3369 +/* bltest options */
  1.3370 +enum {
  1.3371 +    opt_B64 = 0,
  1.3372 +    opt_BufSize,
  1.3373 +    opt_Restart,
  1.3374 +    opt_SelfTestDir,
  1.3375 +    opt_Exponent,
  1.3376 +    opt_SigFile,
  1.3377 +    opt_KeySize,
  1.3378 +    opt_Hex,
  1.3379 +    opt_Input,
  1.3380 +    opt_PQGFile,
  1.3381 +    opt_Key,
  1.3382 +    opt_HexWSpc,
  1.3383 +    opt_Mode,
  1.3384 +#ifndef NSS_DISABLE_ECC
  1.3385 +    opt_CurveName,
  1.3386 +#endif
  1.3387 +    opt_Output,
  1.3388 +    opt_Repetitions,
  1.3389 +    opt_ZeroBuf,
  1.3390 +    opt_Rounds,
  1.3391 +    opt_Seed,
  1.3392 +    opt_SigSeedFile,
  1.3393 +    opt_CXReps,
  1.3394 +    opt_IV,
  1.3395 +    opt_WordSize,
  1.3396 +    opt_UseSeed,
  1.3397 +    opt_UseSigSeed,
  1.3398 +    opt_SeedFile,
  1.3399 +    opt_AAD,
  1.3400 +    opt_InputOffset,
  1.3401 +    opt_OutputOffset,
  1.3402 +    opt_MonteCarlo,
  1.3403 +    opt_ThreadNum,
  1.3404 +    opt_SecondsToRun,
  1.3405 +    opt_CmdLine
  1.3406 +};
  1.3407 +
  1.3408 +static secuCommandFlag bltest_commands[] =
  1.3409 +{
  1.3410 +    { /* cmd_Decrypt	*/ 'D', PR_FALSE, 0, PR_FALSE },
  1.3411 +    { /* cmd_Encrypt	*/ 'E', PR_FALSE, 0, PR_FALSE },
  1.3412 +    { /* cmd_FIPS	*/ 'F', PR_FALSE, 0, PR_FALSE },
  1.3413 +    { /* cmd_Hash	*/ 'H', PR_FALSE, 0, PR_FALSE },
  1.3414 +    { /* cmd_Nonce      */ 'N', PR_FALSE, 0, PR_FALSE },
  1.3415 +    { /* cmd_Dump	*/ 'P', PR_FALSE, 0, PR_FALSE },
  1.3416 +    { /* cmd_RSAPopulate*/ 'R', PR_FALSE, 0, PR_FALSE },
  1.3417 +    { /* cmd_Sign	*/ 'S', PR_FALSE, 0, PR_FALSE },
  1.3418 +    { /* cmd_SelfTest	*/ 'T', PR_FALSE, 0, PR_FALSE },
  1.3419 +    { /* cmd_Verify	*/ 'V', PR_FALSE, 0, PR_FALSE }
  1.3420 +};
  1.3421 +
  1.3422 +static secuCommandFlag bltest_options[] =
  1.3423 +{
  1.3424 +    { /* opt_B64	  */ 'a', PR_FALSE, 0, PR_FALSE },
  1.3425 +    { /* opt_BufSize	  */ 'b', PR_TRUE,  0, PR_FALSE },
  1.3426 +    { /* opt_Restart	  */ 'c', PR_FALSE, 0, PR_FALSE },
  1.3427 +    { /* opt_SelfTestDir  */ 'd', PR_TRUE,  0, PR_FALSE },
  1.3428 +    { /* opt_Exponent	  */ 'e', PR_TRUE,  0, PR_FALSE },
  1.3429 +    { /* opt_SigFile      */ 'f', PR_TRUE,  0, PR_FALSE },
  1.3430 +    { /* opt_KeySize	  */ 'g', PR_TRUE,  0, PR_FALSE },
  1.3431 +    { /* opt_Hex	  */ 'h', PR_FALSE, 0, PR_FALSE },
  1.3432 +    { /* opt_Input	  */ 'i', PR_TRUE,  0, PR_FALSE },
  1.3433 +    { /* opt_PQGFile	  */ 'j', PR_TRUE,  0, PR_FALSE },
  1.3434 +    { /* opt_Key	  */ 'k', PR_TRUE,  0, PR_FALSE },
  1.3435 +    { /* opt_HexWSpc	  */ 'l', PR_FALSE, 0, PR_FALSE },
  1.3436 +    { /* opt_Mode	  */ 'm', PR_TRUE,  0, PR_FALSE },
  1.3437 +#ifndef NSS_DISABLE_ECC
  1.3438 +    { /* opt_CurveName	  */ 'n', PR_TRUE,  0, PR_FALSE },
  1.3439 +#endif
  1.3440 +    { /* opt_Output	  */ 'o', PR_TRUE,  0, PR_FALSE },
  1.3441 +    { /* opt_Repetitions  */ 'p', PR_TRUE,  0, PR_FALSE },
  1.3442 +    { /* opt_ZeroBuf	  */ 'q', PR_FALSE, 0, PR_FALSE },
  1.3443 +    { /* opt_Rounds	  */ 'r', PR_TRUE,  0, PR_FALSE },
  1.3444 +    { /* opt_Seed	  */ 's', PR_TRUE,  0, PR_FALSE },
  1.3445 +    { /* opt_SigSeedFile  */ 't', PR_TRUE,  0, PR_FALSE },
  1.3446 +    { /* opt_CXReps       */ 'u', PR_TRUE,  0, PR_FALSE },
  1.3447 +    { /* opt_IV		  */ 'v', PR_TRUE,  0, PR_FALSE },
  1.3448 +    { /* opt_WordSize	  */ 'w', PR_TRUE,  0, PR_FALSE },
  1.3449 +    { /* opt_UseSeed	  */ 'x', PR_FALSE, 0, PR_FALSE },
  1.3450 +    { /* opt_UseSigSeed	  */ 'y', PR_FALSE, 0, PR_FALSE },
  1.3451 +    { /* opt_SeedFile	  */ 'z', PR_FALSE, 0, PR_FALSE },
  1.3452 +    { /* opt_AAD	  */  0 , PR_TRUE,  0, PR_FALSE, "aad" },
  1.3453 +    { /* opt_InputOffset  */ '1', PR_TRUE,  0, PR_FALSE },
  1.3454 +    { /* opt_OutputOffset */ '2', PR_TRUE,  0, PR_FALSE },
  1.3455 +    { /* opt_MonteCarlo   */ '3', PR_FALSE, 0, PR_FALSE },
  1.3456 +    { /* opt_ThreadNum    */ '4', PR_TRUE,  0, PR_FALSE },
  1.3457 +    { /* opt_SecondsToRun */ '5', PR_TRUE,  0, PR_FALSE },
  1.3458 +    { /* opt_CmdLine	  */ '-', PR_FALSE, 0, PR_FALSE }
  1.3459 +};
  1.3460 +
  1.3461 +int main(int argc, char **argv)
  1.3462 +{
  1.3463 +    char *infileName, *outfileName, *keyfileName, *ivfileName;
  1.3464 +    SECStatus rv = SECFailure;
  1.3465 +
  1.3466 +    double              totalTime;
  1.3467 +    PRIntervalTime      time1, time2;
  1.3468 +    PRFileDesc          *outfile = NULL;
  1.3469 +    bltestCipherInfo    *cipherInfoListHead, *cipherInfo;
  1.3470 +    bltestIOMode        ioMode;
  1.3471 +    int                 bufsize, exponent, curThrdNum;
  1.3472 +#ifndef NSS_DISABLE_ECC
  1.3473 +    char		*curveName = NULL;
  1.3474 +#endif
  1.3475 +    int			 i, commandsEntered;
  1.3476 +    int			 inoff, outoff;
  1.3477 +    int                  threads = 1;
  1.3478 +
  1.3479 +    secuCommand bltest;
  1.3480 +    bltest.numCommands = sizeof(bltest_commands) / sizeof(secuCommandFlag);
  1.3481 +    bltest.numOptions = sizeof(bltest_options) / sizeof(secuCommandFlag);
  1.3482 +    bltest.commands = bltest_commands;
  1.3483 +    bltest.options = bltest_options;
  1.3484 +
  1.3485 +    progName = strrchr(argv[0], '/');
  1.3486 +    if (!progName) 
  1.3487 +	progName = strrchr(argv[0], '\\');
  1.3488 +    progName = progName ? progName+1 : argv[0];
  1.3489 +
  1.3490 +    rv = NSS_InitializePRErrorTable();
  1.3491 +    if (rv != SECSuccess) {
  1.3492 +	SECU_PrintPRandOSError(progName);
  1.3493 +	return -1;
  1.3494 +    }
  1.3495 +    rv = RNG_RNGInit();
  1.3496 +    if (rv != SECSuccess) {
  1.3497 +	SECU_PrintPRandOSError(progName);
  1.3498 +	return -1;
  1.3499 +    }
  1.3500 +    rv = BL_Init();
  1.3501 +    if (rv != SECSuccess) {
  1.3502 +	SECU_PrintPRandOSError(progName);
  1.3503 +	return -1;
  1.3504 +    }
  1.3505 +    RNG_SystemInfoForRNG();
  1.3506 +
  1.3507 +
  1.3508 +    rv = SECU_ParseCommandLine(argc, argv, progName, &bltest);
  1.3509 +    if (rv == SECFailure) {
  1.3510 +	fprintf(stderr, "%s: command line parsing error!\n", progName);
  1.3511 +	goto print_usage;
  1.3512 +    }
  1.3513 +    rv = SECFailure;
  1.3514 +
  1.3515 +    cipherInfo = PORT_ZNew(bltestCipherInfo);
  1.3516 +    cipherInfoListHead = cipherInfo;
  1.3517 +    /* set some defaults */
  1.3518 +    infileName = outfileName = keyfileName = ivfileName = NULL;
  1.3519 +
  1.3520 +    /* Check the number of commands entered on the command line. */
  1.3521 +    commandsEntered = 0;
  1.3522 +    for (i=0; i<bltest.numCommands; i++)
  1.3523 +	if (bltest.commands[i].activated)
  1.3524 +	    commandsEntered++;
  1.3525 +
  1.3526 +    if (commandsEntered > 1 &&
  1.3527 +	!(commandsEntered == 2 && bltest.commands[cmd_SelfTest].activated)) {
  1.3528 +	fprintf(stderr, "%s: one command at a time!\n", progName);
  1.3529 +        goto print_usage;
  1.3530 +    }
  1.3531 +
  1.3532 +    if (commandsEntered == 0) {
  1.3533 +	fprintf(stderr, "%s: you must enter a command!\n", progName);
  1.3534 +        goto print_usage;
  1.3535 +    }
  1.3536 +
  1.3537 +
  1.3538 +    if (bltest.commands[cmd_Sign].activated)
  1.3539 +	bltest.commands[cmd_Encrypt].activated = PR_TRUE;
  1.3540 +    if (bltest.commands[cmd_Verify].activated)
  1.3541 +	bltest.commands[cmd_Decrypt].activated = PR_TRUE;
  1.3542 +    if (bltest.commands[cmd_Hash].activated)
  1.3543 +	bltest.commands[cmd_Encrypt].activated = PR_TRUE;
  1.3544 +
  1.3545 +    inoff = outoff = 0;
  1.3546 +    if (bltest.options[opt_InputOffset].activated)
  1.3547 +	inoff = PORT_Atoi(bltest.options[opt_InputOffset].arg);
  1.3548 +    if (bltest.options[opt_OutputOffset].activated)
  1.3549 +	outoff = PORT_Atoi(bltest.options[opt_OutputOffset].arg);
  1.3550 +
  1.3551 +    testdir = (bltest.options[opt_SelfTestDir].activated) ? 
  1.3552 +                 strdup(bltest.options[opt_SelfTestDir].arg) : ".";
  1.3553 +
  1.3554 +    /*
  1.3555 +     * Handle three simple cases first
  1.3556 +     */
  1.3557 +
  1.3558 +    /* test the RSA_PopulatePrivateKey function */
  1.3559 +    if (bltest.commands[cmd_RSAPopulate].activated) {
  1.3560 +	unsigned int keySize = 1024;
  1.3561 +	unsigned long exponent = 65537;
  1.3562 +	int rounds = 1;
  1.3563 +	int ret;
  1.3564 +	
  1.3565 +	if (bltest.options[opt_KeySize].activated) {
  1.3566 +	    keySize = PORT_Atoi(bltest.options[opt_KeySize].arg);
  1.3567 +	}
  1.3568 +	if (bltest.options[opt_Rounds].activated) {
  1.3569 +	    rounds = PORT_Atoi(bltest.options[opt_Rounds].arg);
  1.3570 +	}
  1.3571 +	if (bltest.options[opt_Exponent].activated) {
  1.3572 +	    exponent = PORT_Atoi(bltest.options[opt_Exponent].arg);
  1.3573 +	}
  1.3574 +
  1.3575 +	for (i=0; i < rounds; i++) {
  1.3576 +	    printf("Running RSA Populate test round %d\n",i);
  1.3577 +	    ret = doRSAPopulateTest(keySize,exponent);
  1.3578 +	    if (ret != 0) {
  1.3579 +		break;
  1.3580 +	    }
  1.3581 +	}
  1.3582 +	if (ret != 0) {
  1.3583 +	    fprintf(stderr,"RSA Populate test round %d: FAILED\n",i);
  1.3584 +	}
  1.3585 +	return ret;
  1.3586 +    }
  1.3587 +
  1.3588 +    /* Do BLAPI self-test */
  1.3589 +    if (bltest.commands[cmd_SelfTest].activated) {
  1.3590 +	PRBool encrypt = PR_TRUE, decrypt = PR_TRUE;
  1.3591 +	/* user may specified a set of ciphers to test.  parse them. */
  1.3592 +	bltestCipherMode modesToTest[NUMMODES];
  1.3593 +	int numModesToTest = 0;
  1.3594 +	char *tok, *str;
  1.3595 +	str = bltest.options[opt_Mode].arg;
  1.3596 +	while (str) {
  1.3597 +	    tok = strchr(str, ',');
  1.3598 +	    if (tok) *tok = '\0';
  1.3599 +	    modesToTest[numModesToTest++] = get_mode(str);
  1.3600 +	    if (tok) {
  1.3601 +		*tok = ',';
  1.3602 +		str = tok + 1;
  1.3603 +	    } else {
  1.3604 +		break;
  1.3605 +	    }
  1.3606 +	}
  1.3607 +	if (bltest.commands[cmd_Decrypt].activated &&
  1.3608 +	    !bltest.commands[cmd_Encrypt].activated)
  1.3609 +	    encrypt = PR_FALSE;
  1.3610 +	if (bltest.commands[cmd_Encrypt].activated &&
  1.3611 +	    !bltest.commands[cmd_Decrypt].activated)
  1.3612 +	    decrypt = PR_FALSE;
  1.3613 +	rv = blapi_selftest(modesToTest, numModesToTest, inoff, outoff,
  1.3614 +	                    encrypt, decrypt);
  1.3615 +	PORT_Free(cipherInfo);
  1.3616 +	return rv == SECSuccess ? 0 : 1;
  1.3617 +    }
  1.3618 +
  1.3619 +    /* Do FIPS self-test */
  1.3620 +    if (bltest.commands[cmd_FIPS].activated) {
  1.3621 +	CK_RV ckrv = sftk_fipsPowerUpSelfTest();
  1.3622 +	fprintf(stdout, "CK_RV: %ld.\n", ckrv);
  1.3623 +        PORT_Free(cipherInfo);
  1.3624 +        if (ckrv == CKR_OK)
  1.3625 +            return SECSuccess;
  1.3626 +        return SECFailure;
  1.3627 +    }
  1.3628 +
  1.3629 +    /*
  1.3630 +     * Check command line arguments for Encrypt/Decrypt/Hash/Sign/Verify
  1.3631 +     */
  1.3632 +
  1.3633 +    if ((bltest.commands[cmd_Decrypt].activated ||
  1.3634 +	 bltest.commands[cmd_Verify].activated) &&
  1.3635 +	bltest.options[opt_BufSize].activated) {
  1.3636 +	fprintf(stderr, "%s: Cannot use a nonce as input to decrypt/verify.\n",
  1.3637 +			 progName);
  1.3638 +        goto print_usage;
  1.3639 +    }
  1.3640 +
  1.3641 +    if (bltest.options[opt_Mode].activated) {
  1.3642 +	cipherInfo->mode = get_mode(bltest.options[opt_Mode].arg);
  1.3643 +	if (cipherInfo->mode == bltestINVALID) {
  1.3644 +            goto print_usage;
  1.3645 +	}
  1.3646 +    } else {
  1.3647 +	fprintf(stderr, "%s: You must specify a cipher mode with -m.\n",
  1.3648 +			 progName);
  1.3649 +        goto print_usage;
  1.3650 +    }
  1.3651 +
  1.3652 +    
  1.3653 +    if (bltest.options[opt_Repetitions].activated &&
  1.3654 +        bltest.options[opt_SecondsToRun].activated) {
  1.3655 +        fprintf(stderr, "%s: Operation time should be defined in either "
  1.3656 +                "repetitions(-p) or seconds(-5) not both",
  1.3657 +                progName);
  1.3658 +        goto print_usage;
  1.3659 +    }
  1.3660 +
  1.3661 +    if (bltest.options[opt_Repetitions].activated) {
  1.3662 +        cipherInfo->repetitionsToPerfom =
  1.3663 +            PORT_Atoi(bltest.options[opt_Repetitions].arg);
  1.3664 +    } else {
  1.3665 +        cipherInfo->repetitionsToPerfom = 0;
  1.3666 +    }
  1.3667 +
  1.3668 +    if (bltest.options[opt_SecondsToRun].activated) {
  1.3669 +        cipherInfo->seconds = PORT_Atoi(bltest.options[opt_SecondsToRun].arg);
  1.3670 +    } else {
  1.3671 +        cipherInfo->seconds = 0;
  1.3672 +    }
  1.3673 +
  1.3674 +
  1.3675 +    if (bltest.options[opt_CXReps].activated) {
  1.3676 +        cipherInfo->cxreps = PORT_Atoi(bltest.options[opt_CXReps].arg);
  1.3677 +    } else {
  1.3678 +        cipherInfo->cxreps = 0;
  1.3679 +    }
  1.3680 +
  1.3681 +    if (bltest.options[opt_ThreadNum].activated) {
  1.3682 +        threads = PORT_Atoi(bltest.options[opt_ThreadNum].arg);
  1.3683 +        if (threads <= 0) {
  1.3684 +            threads = 1;
  1.3685 +        }
  1.3686 +    }
  1.3687 +
  1.3688 +    /* Dump a file (rsakey, dsakey, etc.) */
  1.3689 +    if (bltest.commands[cmd_Dump].activated) {
  1.3690 +        rv = dump_file(cipherInfo->mode, bltest.options[opt_Input].arg);
  1.3691 +        PORT_Free(cipherInfo);
  1.3692 +        return rv;
  1.3693 +    }
  1.3694 +
  1.3695 +    /* default input mode is binary */
  1.3696 +    ioMode = (bltest.options[opt_B64].activated)     ? bltestBase64Encoded :
  1.3697 +	     (bltest.options[opt_Hex].activated)     ? bltestHexStream :
  1.3698 +	     (bltest.options[opt_HexWSpc].activated) ? bltestHexSpaceDelim :
  1.3699 +						       bltestBinary;
  1.3700 +
  1.3701 +    if (bltest.options[opt_Exponent].activated)
  1.3702 +	exponent = PORT_Atoi(bltest.options[opt_Exponent].arg);
  1.3703 +    else
  1.3704 +	exponent = 65537;
  1.3705 +
  1.3706 +#ifndef NSS_DISABLE_ECC
  1.3707 +    if (bltest.options[opt_CurveName].activated)
  1.3708 +	curveName = PORT_Strdup(bltest.options[opt_CurveName].arg);
  1.3709 +    else
  1.3710 +	curveName = NULL;
  1.3711 +#endif
  1.3712 +
  1.3713 +    if (bltest.commands[cmd_Verify].activated &&
  1.3714 +        !bltest.options[opt_SigFile].activated) {
  1.3715 +        fprintf(stderr, "%s: You must specify a signature file with -f.\n",
  1.3716 +                progName);
  1.3717 +
  1.3718 +      print_usage:
  1.3719 +        PORT_Free(cipherInfo);
  1.3720 +        Usage();
  1.3721 +    }
  1.3722 +
  1.3723 +    if (bltest.options[opt_MonteCarlo].activated) {
  1.3724 +        cipherInfo->mCarlo = PR_TRUE;
  1.3725 +    } else {
  1.3726 +        cipherInfo->mCarlo = PR_FALSE;
  1.3727 +    }
  1.3728 +
  1.3729 +    for (curThrdNum = 0;curThrdNum < threads;curThrdNum++) {
  1.3730 +        int            keysize = 0;
  1.3731 +        PRFileDesc     *file = NULL, *infile;
  1.3732 +        bltestParams   *params;
  1.3733 +        char           *instr = NULL;
  1.3734 +        PLArenaPool    *arena;
  1.3735 +
  1.3736 +        if (curThrdNum > 0) {
  1.3737 +            bltestCipherInfo *newCInfo = PORT_ZNew(bltestCipherInfo);
  1.3738 +            if (!newCInfo) {
  1.3739 +                fprintf(stderr, "%s: Can not allocate  memory.\n", progName);
  1.3740 +                goto exit_point;
  1.3741 +            }
  1.3742 +            newCInfo->mode = cipherInfo->mode;
  1.3743 +            newCInfo->mCarlo = cipherInfo->mCarlo;
  1.3744 +            newCInfo->repetitionsToPerfom =
  1.3745 +                cipherInfo->repetitionsToPerfom;
  1.3746 +            newCInfo->seconds = cipherInfo->seconds;
  1.3747 +            newCInfo->cxreps = cipherInfo->cxreps;
  1.3748 +            cipherInfo->next = newCInfo;
  1.3749 +            cipherInfo = newCInfo;
  1.3750 +        }
  1.3751 +        arena = PORT_NewArena(BLTEST_DEFAULT_CHUNKSIZE);
  1.3752 +        if (!arena) {
  1.3753 +            fprintf(stderr, "%s: Can not allocate memory.\n", progName);
  1.3754 +            goto exit_point;
  1.3755 +        }
  1.3756 +        cipherInfo->arena = arena;
  1.3757 +        params = &cipherInfo->params;
  1.3758 +        
  1.3759 +        /* Set up an encryption key. */
  1.3760 +        keysize = 0;
  1.3761 +        file = NULL;
  1.3762 +        if (is_symmkeyCipher(cipherInfo->mode)) {
  1.3763 +            char *keystr = NULL;  /* if key is on command line */
  1.3764 +            if (bltest.options[opt_Key].activated) {
  1.3765 +                if (bltest.options[opt_CmdLine].activated) {
  1.3766 +                    keystr = bltest.options[opt_Key].arg;
  1.3767 +                } else {
  1.3768 +                    file = PR_Open(bltest.options[opt_Key].arg,
  1.3769 +                                   PR_RDONLY, 00660);
  1.3770 +                }
  1.3771 +            } else {
  1.3772 +                if (bltest.options[opt_KeySize].activated)
  1.3773 +                    keysize = PORT_Atoi(bltest.options[opt_KeySize].arg);
  1.3774 +                else
  1.3775 +                    keysize = 8; /* use 64-bit default (DES) */
  1.3776 +                /* save the random key for reference */
  1.3777 +                file = PR_Open("tmp.key", PR_WRONLY|PR_CREATE_FILE, 00660);
  1.3778 +            }
  1.3779 +            params->key.mode = ioMode;
  1.3780 +            setupIO(cipherInfo->arena, &params->key, file, keystr, keysize);
  1.3781 +            if (file)
  1.3782 +                PR_Close(file);
  1.3783 +        } else if (is_pubkeyCipher(cipherInfo->mode)) {
  1.3784 +            if (bltest.options[opt_Key].activated) {
  1.3785 +                file = PR_Open(bltest.options[opt_Key].arg, PR_RDONLY, 00660);
  1.3786 +            } else {
  1.3787 +                if (bltest.options[opt_KeySize].activated)
  1.3788 +                    keysize = PORT_Atoi(bltest.options[opt_KeySize].arg);
  1.3789 +                else
  1.3790 +                    keysize = 64; /* use 512-bit default */
  1.3791 +                file = PR_Open("tmp.key", PR_WRONLY|PR_CREATE_FILE, 00660);
  1.3792 +            }
  1.3793 +            params->key.mode = bltestBase64Encoded;
  1.3794 +#ifndef NSS_DISABLE_ECC
  1.3795 +            pubkeyInitKey(cipherInfo, file, keysize, exponent, curveName);
  1.3796 +#else
  1.3797 +            pubkeyInitKey(cipherInfo, file, keysize, exponent);
  1.3798 +#endif
  1.3799 +            PR_Close(file);
  1.3800 +        }
  1.3801 +
  1.3802 +        /* set up an initialization vector. */
  1.3803 +        if (cipher_requires_IV(cipherInfo->mode)) {
  1.3804 +            char *ivstr = NULL;
  1.3805 +            bltestSymmKeyParams *skp;
  1.3806 +            file = NULL;
  1.3807 +#ifdef NSS_SOFTOKEN_DOES_RC5
  1.3808 +            if (cipherInfo->mode == bltestRC5_CBC)
  1.3809 +                skp = (bltestSymmKeyParams *)&params->rc5;
  1.3810 +            else
  1.3811 +#endif
  1.3812 +                skp = &params->sk;
  1.3813 +            if (bltest.options[opt_IV].activated) {
  1.3814 +                if (bltest.options[opt_CmdLine].activated) {
  1.3815 +                    ivstr = bltest.options[opt_IV].arg;
  1.3816 +                } else {
  1.3817 +                    file = PR_Open(bltest.options[opt_IV].arg,
  1.3818 +                                   PR_RDONLY, 00660);
  1.3819 +                }
  1.3820 +            } else {
  1.3821 +                /* save the random iv for reference */
  1.3822 +                file = PR_Open("tmp.iv", PR_WRONLY|PR_CREATE_FILE, 00660);
  1.3823 +            }
  1.3824 +            memset(&skp->iv, 0, sizeof skp->iv);
  1.3825 +            skp->iv.mode = ioMode;
  1.3826 +            setupIO(cipherInfo->arena, &skp->iv, file, ivstr, keysize);
  1.3827 +            if (file) {
  1.3828 +                PR_Close(file);
  1.3829 +            }
  1.3830 +        }
  1.3831 +
  1.3832 +        /* set up an initialization vector. */
  1.3833 +        if (is_authCipher(cipherInfo->mode)) {
  1.3834 +            char *aadstr = NULL;
  1.3835 +            bltestAuthSymmKeyParams *askp;
  1.3836 +            file = NULL;
  1.3837 +            askp = &params->ask;
  1.3838 +            if (bltest.options[opt_AAD].activated) {
  1.3839 +                if (bltest.options[opt_CmdLine].activated) {
  1.3840 +                    aadstr = bltest.options[opt_AAD].arg;
  1.3841 +                } else {
  1.3842 +                    file = PR_Open(bltest.options[opt_AAD].arg,
  1.3843 +                                   PR_RDONLY, 00660);
  1.3844 +                }
  1.3845 +            } else {
  1.3846 +                file = NULL;
  1.3847 +            }
  1.3848 +            memset(&askp->aad, 0, sizeof askp->aad);
  1.3849 +            askp->aad.mode = ioMode;
  1.3850 +            setupIO(cipherInfo->arena, &askp->aad, file, aadstr, 0);
  1.3851 +            if (file) {
  1.3852 +                PR_Close(file);
  1.3853 +            }
  1.3854 +        }
  1.3855 +        
  1.3856 +        if (bltest.commands[cmd_Verify].activated) {
  1.3857 +            file = PR_Open(bltest.options[opt_SigFile].arg, PR_RDONLY, 00660);
  1.3858 +            if (is_sigCipher(cipherInfo->mode)) {
  1.3859 +                memset(&params->asymk.sig, 0, sizeof(bltestIO));
  1.3860 +                params->asymk.sig.mode = ioMode;
  1.3861 +                setupIO(cipherInfo->arena, &params->asymk.sig, file, NULL, 0);
  1.3862 +            }
  1.3863 +            if (file) {
  1.3864 +                PR_Close(file);
  1.3865 +            }
  1.3866 +        }
  1.3867 +        
  1.3868 +        if (bltest.options[opt_PQGFile].activated) {
  1.3869 +            file = PR_Open(bltest.options[opt_PQGFile].arg, PR_RDONLY, 00660);
  1.3870 +            params->asymk.cipherParams.dsa.pqgdata.mode = bltestBase64Encoded;
  1.3871 +            setupIO(cipherInfo->arena, &params->asymk.cipherParams.dsa.pqgdata,
  1.3872 +                    file, NULL, 0);
  1.3873 +            if (file) {
  1.3874 +                PR_Close(file);
  1.3875 +            }
  1.3876 +        }
  1.3877 +
  1.3878 +        /* Set up the input buffer */
  1.3879 +        if (bltest.options[opt_Input].activated) {
  1.3880 +            if (bltest.options[opt_CmdLine].activated) {
  1.3881 +                instr = bltest.options[opt_Input].arg;
  1.3882 +                infile = NULL;
  1.3883 +            } else {
  1.3884 +                /* form file name from testdir and input arg. */
  1.3885 +                char * filename = bltest.options[opt_Input].arg;
  1.3886 +                if (bltest.options[opt_SelfTestDir].activated && 
  1.3887 +                    testdir && filename && filename[0] != '/') {
  1.3888 +                    filename = PR_smprintf("%s/tests/%s/%s", testdir, 
  1.3889 +                                           mode_strings[cipherInfo->mode],
  1.3890 +                                           filename);
  1.3891 +                    if (!filename) {
  1.3892 +                        fprintf(stderr, "%s: Can not allocate memory.\n",
  1.3893 +                                progName);
  1.3894 +                        goto exit_point;
  1.3895 +                    }
  1.3896 +                    infile = PR_Open(filename, PR_RDONLY, 00660);
  1.3897 +                    PR_smprintf_free(filename);
  1.3898 +                } else {
  1.3899 +                    infile = PR_Open(filename, PR_RDONLY, 00660);
  1.3900 +                }
  1.3901 +            }
  1.3902 +        } else if (bltest.options[opt_BufSize].activated) {
  1.3903 +            /* save the random plaintext for reference */
  1.3904 +            char *tmpFName = PR_smprintf("tmp.in.%d", curThrdNum);
  1.3905 +            if (!tmpFName) {
  1.3906 +                fprintf(stderr, "%s: Can not allocate memory.\n", progName);
  1.3907 +                goto exit_point;
  1.3908 +            }
  1.3909 +            infile = PR_Open(tmpFName, PR_WRONLY|PR_CREATE_FILE, 00660);
  1.3910 +            PR_smprintf_free(tmpFName);
  1.3911 +        } else {
  1.3912 +            infile = PR_STDIN;
  1.3913 +        }
  1.3914 +        if (!infile) {
  1.3915 +            fprintf(stderr, "%s: Failed to open input file.\n", progName);
  1.3916 +            goto exit_point;
  1.3917 +        }
  1.3918 +        cipherInfo->input.mode = ioMode;
  1.3919 +
  1.3920 +        /* Set up the output stream */
  1.3921 +        if (bltest.options[opt_Output].activated) {
  1.3922 +            /* form file name from testdir and input arg. */
  1.3923 +            char * filename = bltest.options[opt_Output].arg;
  1.3924 +            if (bltest.options[opt_SelfTestDir].activated && 
  1.3925 +                testdir && filename && filename[0] != '/') {
  1.3926 +                filename = PR_smprintf("%s/tests/%s/%s", testdir, 
  1.3927 +                                       mode_strings[cipherInfo->mode],
  1.3928 +                                       filename);
  1.3929 +                if (!filename) {
  1.3930 +                    fprintf(stderr, "%s: Can not allocate memory.\n", progName);
  1.3931 +                    goto exit_point;
  1.3932 +                }
  1.3933 +                outfile = PR_Open(filename, PR_WRONLY|PR_CREATE_FILE, 00660);
  1.3934 +                PR_smprintf_free(filename);
  1.3935 +            } else {
  1.3936 +                outfile = PR_Open(filename, PR_WRONLY|PR_CREATE_FILE, 00660);
  1.3937 +            }
  1.3938 +        } else {
  1.3939 +            outfile = PR_STDOUT;
  1.3940 +        }
  1.3941 +        if (!outfile) {
  1.3942 +            fprintf(stderr, "%s: Failed to open output file.\n", progName);
  1.3943 +            rv = SECFailure;
  1.3944 +            goto exit_point;
  1.3945 +        }
  1.3946 +        cipherInfo->output.mode = ioMode;
  1.3947 +        if (bltest.options[opt_SelfTestDir].activated && ioMode == bltestBinary)
  1.3948 +            cipherInfo->output.mode = bltestBase64Encoded;
  1.3949 +
  1.3950 +        if (is_hashCipher(cipherInfo->mode))
  1.3951 +            cipherInfo->params.hash.restart =
  1.3952 +                bltest.options[opt_Restart].activated;
  1.3953 +
  1.3954 +        bufsize = 0;
  1.3955 +        if (bltest.options[opt_BufSize].activated)
  1.3956 +            bufsize = PORT_Atoi(bltest.options[opt_BufSize].arg);
  1.3957 +
  1.3958 +        /*infile = NULL;*/
  1.3959 +        setupIO(cipherInfo->arena, &cipherInfo->input, infile, instr, bufsize);
  1.3960 +        if (infile && infile != PR_STDIN)
  1.3961 +            PR_Close(infile);
  1.3962 +        misalignBuffer(cipherInfo->arena, &cipherInfo->input, inoff);
  1.3963 +
  1.3964 +        cipherInit(cipherInfo, bltest.commands[cmd_Encrypt].activated);
  1.3965 +        misalignBuffer(cipherInfo->arena, &cipherInfo->output, outoff);
  1.3966 +    }
  1.3967 +
  1.3968 +    if (!bltest.commands[cmd_Nonce].activated) {
  1.3969 +        TIMESTART();
  1.3970 +        cipherInfo = cipherInfoListHead;
  1.3971 +        while (cipherInfo != NULL) {
  1.3972 +            cipherInfo->cipherThread = 
  1.3973 +                PR_CreateThread(PR_USER_THREAD,
  1.3974 +                                    ThreadExecTest,
  1.3975 +                                    cipherInfo,
  1.3976 +                                    PR_PRIORITY_NORMAL,
  1.3977 +                                    PR_GLOBAL_THREAD,
  1.3978 +                                    PR_JOINABLE_THREAD,
  1.3979 +                                    0);
  1.3980 +            cipherInfo = cipherInfo->next;
  1.3981 +        } 
  1.3982 +
  1.3983 +        cipherInfo = cipherInfoListHead;
  1.3984 +        while (cipherInfo != NULL) {
  1.3985 +            PR_JoinThread(cipherInfo->cipherThread);
  1.3986 +            finishIO(&cipherInfo->output, outfile);
  1.3987 +            cipherInfo = cipherInfo->next;
  1.3988 +        }
  1.3989 +        TIMEFINISH(totalTime, 1);
  1.3990 +    }
  1.3991 +    
  1.3992 +    cipherInfo = cipherInfoListHead;
  1.3993 +    if (cipherInfo->repetitions > 0 || cipherInfo->cxreps > 0 ||
  1.3994 +        threads > 1)
  1.3995 +        dump_performance_info(cipherInfoListHead, totalTime,
  1.3996 +                              bltest.commands[cmd_Encrypt].activated,
  1.3997 +	                      (cipherInfo->repetitions == 0));
  1.3998 +    
  1.3999 +    rv = SECSuccess;
  1.4000 +
  1.4001 +  exit_point:
  1.4002 +    if (outfile && outfile != PR_STDOUT)
  1.4003 +	PR_Close(outfile);
  1.4004 +    cipherInfo = cipherInfoListHead;
  1.4005 +    while (cipherInfo != NULL) {
  1.4006 +        bltestCipherInfo *tmpInfo = cipherInfo;
  1.4007 +
  1.4008 +        if (cipherInfo->arena)
  1.4009 +            PORT_FreeArena(cipherInfo->arena, PR_TRUE);
  1.4010 +        cipherInfo = cipherInfo->next;
  1.4011 +        PORT_Free(tmpInfo);
  1.4012 +    }
  1.4013 +
  1.4014 +    /*NSS_Shutdown();*/
  1.4015 +
  1.4016 +    return SECSuccess;
  1.4017 +}
  1.4018 +

mercurial