security/nss/cmd/bltest/blapitest.c

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

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

mercurial