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