security/nss/cmd/bltest/blapitest.c

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

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

mercurial