michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #include michael@0: #include michael@0: michael@0: #include "blapi.h" michael@0: #include "secrng.h" michael@0: #include "prmem.h" michael@0: #include "prprf.h" michael@0: #include "prtime.h" michael@0: #include "prsystem.h" michael@0: #include "plstr.h" michael@0: #include "nssb64.h" michael@0: #include "basicutil.h" michael@0: #include "plgetopt.h" michael@0: #include "softoken.h" michael@0: #include "nspr.h" michael@0: #include "secport.h" michael@0: #include "secoid.h" michael@0: #include "nssutil.h" michael@0: michael@0: #ifndef NSS_DISABLE_ECC michael@0: #include "ecl-curve.h" michael@0: SECStatus EC_DecodeParams(const SECItem *encodedParams, michael@0: ECParams **ecparams); michael@0: SECStatus EC_CopyParams(PLArenaPool *arena, ECParams *dstParams, michael@0: const ECParams *srcParams); michael@0: #endif michael@0: michael@0: char *progName; michael@0: char *testdir = NULL; michael@0: michael@0: #define BLTEST_DEFAULT_CHUNKSIZE 4096 michael@0: michael@0: #define WORDSIZE sizeof(unsigned long) michael@0: michael@0: #define CHECKERROR(rv, ln) \ michael@0: if (rv) { \ michael@0: PRErrorCode prerror = PR_GetError(); \ michael@0: PR_fprintf(PR_STDERR, "%s: ERR %d (%s) at line %d.\n", progName, \ michael@0: prerror, PORT_ErrorToString(prerror), ln); \ michael@0: exit(-1); \ michael@0: } michael@0: michael@0: /* Macros for performance timing. */ michael@0: #define TIMESTART() \ michael@0: time1 = PR_IntervalNow(); michael@0: michael@0: #define TIMEFINISH(time, reps) \ michael@0: time2 = (PRIntervalTime)(PR_IntervalNow() - time1); \ michael@0: time1 = PR_IntervalToMilliseconds(time2); \ michael@0: time = ((double)(time1))/reps; michael@0: michael@0: #define TIMEMARK(seconds) \ michael@0: time1 = PR_SecondsToInterval(seconds); \ michael@0: { \ michael@0: PRInt64 tmp, L100; \ michael@0: LL_I2L(L100, 100); \ michael@0: if (time2 == 0) { \ michael@0: time2 = 1; \ michael@0: } \ michael@0: LL_DIV(tmp, time1, time2); \ michael@0: if (tmp < 10) { \ michael@0: if (tmp == 0) { \ michael@0: opsBetweenChecks = 1; \ michael@0: } else { \ michael@0: LL_L2I(opsBetweenChecks, tmp); \ michael@0: } \ michael@0: } else { \ michael@0: opsBetweenChecks = 10; \ michael@0: } \ michael@0: } \ michael@0: time2 = time1; \ michael@0: time1 = PR_IntervalNow(); michael@0: michael@0: #define TIMETOFINISH() \ michael@0: PR_IntervalNow() - time1 >= time2 michael@0: michael@0: static void Usage() michael@0: { michael@0: #define PRINTUSAGE(subject, option, predicate) \ michael@0: fprintf(stderr, "%10s %s\t%s\n", subject, option, predicate); michael@0: fprintf(stderr, "\n"); michael@0: PRINTUSAGE(progName, "[-DEHSVR]", "List available cipher modes"); /* XXX */ michael@0: fprintf(stderr, "\n"); michael@0: PRINTUSAGE(progName, "-E -m mode ", "Encrypt a buffer"); michael@0: PRINTUSAGE("", "", "[-i plaintext] [-o ciphertext] [-k key] [-v iv]"); michael@0: PRINTUSAGE("", "", "[-b bufsize] [-g keysize] [-e exp] [-r rounds]"); michael@0: PRINTUSAGE("", "", "[-w wordsize] [-p repetitions | -5 time_interval]"); michael@0: PRINTUSAGE("", "", "[-4 th_num]"); michael@0: PRINTUSAGE("", "-m", "cipher mode to use"); michael@0: PRINTUSAGE("", "-i", "file which contains input buffer"); michael@0: PRINTUSAGE("", "-o", "file for output buffer"); michael@0: PRINTUSAGE("", "-k", "file which contains key"); michael@0: PRINTUSAGE("", "-v", "file which contains initialization vector"); michael@0: PRINTUSAGE("", "-b", "size of input buffer"); michael@0: PRINTUSAGE("", "-g", "key size (in bytes)"); michael@0: PRINTUSAGE("", "-p", "do performance test"); michael@0: PRINTUSAGE("", "-4", "run test in multithread mode. th_num number of parallel threads"); michael@0: PRINTUSAGE("", "-5", "run test for specified time interval(in seconds)"); michael@0: PRINTUSAGE("", "--aad", "File with contains additional auth data"); michael@0: PRINTUSAGE("(rsa)", "-e", "rsa public exponent"); michael@0: PRINTUSAGE("(rc5)", "-r", "number of rounds"); michael@0: PRINTUSAGE("(rc5)", "-w", "wordsize (32 or 64)"); michael@0: fprintf(stderr, "\n"); michael@0: PRINTUSAGE(progName, "-D -m mode", "Decrypt a buffer"); michael@0: PRINTUSAGE("", "", "[-i plaintext] [-o ciphertext] [-k key] [-v iv]"); michael@0: PRINTUSAGE("", "", "[-p repetitions | -5 time_interval] [-4 th_num]"); michael@0: PRINTUSAGE("", "-m", "cipher mode to use"); michael@0: PRINTUSAGE("", "-i", "file which contains input buffer"); michael@0: PRINTUSAGE("", "-o", "file for output buffer"); michael@0: PRINTUSAGE("", "-k", "file which contains key"); michael@0: PRINTUSAGE("", "-v", "file which contains initialization vector"); michael@0: PRINTUSAGE("", "-p", "do performance test"); michael@0: PRINTUSAGE("", "-4", "run test in multithread mode. th_num number of parallel threads"); michael@0: PRINTUSAGE("", "-5", "run test for specified time interval(in seconds)"); michael@0: PRINTUSAGE("", "--aad", "File with contains additional auth data"); michael@0: fprintf(stderr, "\n"); michael@0: PRINTUSAGE(progName, "-H -m mode", "Hash a buffer"); michael@0: PRINTUSAGE("", "", "[-i plaintext] [-o hash]"); michael@0: PRINTUSAGE("", "", "[-b bufsize]"); michael@0: PRINTUSAGE("", "", "[-p repetitions | -5 time_interval] [-4 th_num]"); michael@0: PRINTUSAGE("", "-m", "cipher mode to use"); michael@0: PRINTUSAGE("", "-i", "file which contains input buffer"); michael@0: PRINTUSAGE("", "-o", "file for hash"); michael@0: PRINTUSAGE("", "-b", "size of input buffer"); michael@0: PRINTUSAGE("", "-p", "do performance test"); michael@0: PRINTUSAGE("", "-4", "run test in multithread mode. th_num number of parallel threads"); michael@0: PRINTUSAGE("", "-5", "run test for specified time interval(in seconds)"); michael@0: fprintf(stderr, "\n"); michael@0: PRINTUSAGE(progName, "-S -m mode", "Sign a buffer"); michael@0: PRINTUSAGE("", "", "[-i plaintext] [-o signature] [-k key]"); michael@0: PRINTUSAGE("", "", "[-b bufsize]"); michael@0: #ifndef NSS_DISABLE_ECC michael@0: PRINTUSAGE("", "", "[-n curvename]"); michael@0: #endif michael@0: PRINTUSAGE("", "", "[-p repetitions | -5 time_interval] [-4 th_num]"); michael@0: PRINTUSAGE("", "-m", "cipher mode to use"); michael@0: PRINTUSAGE("", "-i", "file which contains input buffer"); michael@0: PRINTUSAGE("", "-o", "file for signature"); michael@0: PRINTUSAGE("", "-k", "file which contains key"); michael@0: #ifndef NSS_DISABLE_ECC michael@0: PRINTUSAGE("", "-n", "name of curve for EC key generation; one of:"); michael@0: PRINTUSAGE("", "", " sect163k1, nistk163, sect163r1, sect163r2,"); michael@0: PRINTUSAGE("", "", " nistb163, sect193r1, sect193r2, sect233k1, nistk233,"); michael@0: PRINTUSAGE("", "", " sect233r1, nistb233, sect239k1, sect283k1, nistk283,"); michael@0: PRINTUSAGE("", "", " sect283r1, nistb283, sect409k1, nistk409, sect409r1,"); michael@0: PRINTUSAGE("", "", " nistb409, sect571k1, nistk571, sect571r1, nistb571,"); michael@0: PRINTUSAGE("", "", " secp160k1, secp160r1, secp160r2, secp192k1, secp192r1,"); michael@0: PRINTUSAGE("", "", " nistp192, secp224k1, secp224r1, nistp224, secp256k1,"); michael@0: PRINTUSAGE("", "", " secp256r1, nistp256, secp384r1, nistp384, secp521r1,"); michael@0: PRINTUSAGE("", "", " nistp521, prime192v1, prime192v2, prime192v3,"); michael@0: PRINTUSAGE("", "", " prime239v1, prime239v2, prime239v3, c2pnb163v1,"); michael@0: PRINTUSAGE("", "", " c2pnb163v2, c2pnb163v3, c2pnb176v1, c2tnb191v1,"); michael@0: PRINTUSAGE("", "", " c2tnb191v2, c2tnb191v3, c2onb191v4, c2onb191v5,"); michael@0: PRINTUSAGE("", "", " c2pnb208w1, c2tnb239v1, c2tnb239v2, c2tnb239v3,"); michael@0: PRINTUSAGE("", "", " c2onb239v4, c2onb239v5, c2pnb272w1, c2pnb304w1,"); michael@0: PRINTUSAGE("", "", " c2tnb359w1, c2pnb368w1, c2tnb431r1, secp112r1,"); michael@0: PRINTUSAGE("", "", " secp112r2, secp128r1, secp128r2, sect113r1, sect113r2,"); michael@0: PRINTUSAGE("", "", " sect131r1, sect131r2"); michael@0: #endif michael@0: PRINTUSAGE("", "-p", "do performance test"); michael@0: PRINTUSAGE("", "-4", "run test in multithread mode. th_num number of parallel threads"); michael@0: PRINTUSAGE("", "-5", "run test for specified time interval(in seconds)"); michael@0: fprintf(stderr, "\n"); michael@0: PRINTUSAGE(progName, "-V -m mode", "Verify a signed buffer"); michael@0: PRINTUSAGE("", "", "[-i plaintext] [-s signature] [-k key]"); michael@0: PRINTUSAGE("", "", "[-p repetitions | -5 time_interval] [-4 th_num]"); michael@0: PRINTUSAGE("", "-m", "cipher mode to use"); michael@0: PRINTUSAGE("", "-i", "file which contains input buffer"); michael@0: PRINTUSAGE("", "-s", "file which contains signature of input buffer"); michael@0: PRINTUSAGE("", "-k", "file which contains key"); michael@0: PRINTUSAGE("", "-p", "do performance test"); michael@0: PRINTUSAGE("", "-4", "run test in multithread mode. th_num number of parallel threads"); michael@0: PRINTUSAGE("", "-5", "run test for specified time interval(in seconds)"); michael@0: fprintf(stderr, "\n"); michael@0: PRINTUSAGE(progName, "-N -m mode -b bufsize", michael@0: "Create a nonce plaintext and key"); michael@0: PRINTUSAGE("", "", "[-g keysize] [-u cxreps]"); michael@0: PRINTUSAGE("", "-g", "key size (in bytes)"); michael@0: PRINTUSAGE("", "-u", "number of repetitions of context creation"); michael@0: fprintf(stderr, "\n"); michael@0: PRINTUSAGE(progName, "-R [-g keysize] [-e exp]", michael@0: "Test the RSA populate key function"); michael@0: PRINTUSAGE("", "", "[-r repetitions]"); michael@0: PRINTUSAGE("", "-g", "key size (in bytes)"); michael@0: PRINTUSAGE("", "-e", "rsa public exponent"); michael@0: PRINTUSAGE("", "-r", "repetitions of the test"); michael@0: fprintf(stderr, "\n"); michael@0: PRINTUSAGE(progName, "-F", "Run the FIPS self-test"); michael@0: fprintf(stderr, "\n"); michael@0: PRINTUSAGE(progName, "-T [-m mode1,mode2...]", "Run the BLAPI self-test"); michael@0: fprintf(stderr, "\n"); michael@0: exit(1); michael@0: } michael@0: michael@0: /* Helper functions for ascii<-->binary conversion/reading/writing */ michael@0: michael@0: /* XXX argh */ michael@0: struct item_with_arena { michael@0: SECItem *item; michael@0: PLArenaPool *arena; michael@0: }; michael@0: michael@0: static PRInt32 michael@0: get_binary(void *arg, const unsigned char *ibuf, PRInt32 size) michael@0: { michael@0: struct item_with_arena *it = arg; michael@0: SECItem *binary = it->item; michael@0: SECItem *tmp; michael@0: int index; michael@0: if (binary->data == NULL) { michael@0: tmp = SECITEM_AllocItem(it->arena, NULL, size); michael@0: binary->data = tmp->data; michael@0: binary->len = tmp->len; michael@0: index = 0; michael@0: } else { michael@0: SECITEM_ReallocItem(NULL, binary, binary->len, binary->len + size); michael@0: index = binary->len; michael@0: } michael@0: PORT_Memcpy(&binary->data[index], ibuf, size); michael@0: return binary->len; michael@0: } michael@0: michael@0: static SECStatus michael@0: atob(SECItem *ascii, SECItem *binary, PLArenaPool *arena) michael@0: { michael@0: SECStatus status; michael@0: NSSBase64Decoder *cx; michael@0: struct item_with_arena it; michael@0: int len; michael@0: binary->data = NULL; michael@0: binary->len = 0; michael@0: it.item = binary; michael@0: it.arena = arena; michael@0: len = (strncmp((const char *)&ascii->data[ascii->len-2],"\r\n",2)) ? michael@0: ascii->len : ascii->len-2; michael@0: cx = NSSBase64Decoder_Create(get_binary, &it); michael@0: status = NSSBase64Decoder_Update(cx, (const char *)ascii->data, len); michael@0: status = NSSBase64Decoder_Destroy(cx, PR_FALSE); michael@0: return status; michael@0: } michael@0: michael@0: static PRInt32 michael@0: output_ascii(void *arg, const char *obuf, PRInt32 size) michael@0: { michael@0: PRFileDesc *outfile = arg; michael@0: PRInt32 nb = PR_Write(outfile, obuf, size); michael@0: if (nb != size) { michael@0: PORT_SetError(SEC_ERROR_IO); michael@0: return -1; michael@0: } michael@0: return nb; michael@0: } michael@0: michael@0: static SECStatus michael@0: btoa_file(SECItem *binary, PRFileDesc *outfile) michael@0: { michael@0: SECStatus status; michael@0: NSSBase64Encoder *cx; michael@0: if (binary->len == 0) michael@0: return SECSuccess; michael@0: cx = NSSBase64Encoder_Create(output_ascii, outfile); michael@0: status = NSSBase64Encoder_Update(cx, binary->data, binary->len); michael@0: status = NSSBase64Encoder_Destroy(cx, PR_FALSE); michael@0: status = PR_Write(outfile, "\r\n", 2); michael@0: return status; michael@0: } michael@0: michael@0: SECStatus michael@0: hex_from_2char(unsigned char *c2, unsigned char *byteval) michael@0: { michael@0: int i; michael@0: unsigned char offset; michael@0: *byteval = 0; michael@0: for (i=0; i<2; i++) { michael@0: if (c2[i] >= '0' && c2[i] <= '9') { michael@0: offset = c2[i] - '0'; michael@0: *byteval |= offset << 4*(1-i); michael@0: } else if (c2[i] >= 'a' && c2[i] <= 'f') { michael@0: offset = c2[i] - 'a'; michael@0: *byteval |= (offset + 10) << 4*(1-i); michael@0: } else if (c2[i] >= 'A' && c2[i] <= 'F') { michael@0: offset = c2[i] - 'A'; michael@0: *byteval |= (offset + 10) << 4*(1-i); michael@0: } else { michael@0: return SECFailure; michael@0: } michael@0: } michael@0: return SECSuccess; michael@0: } michael@0: michael@0: SECStatus michael@0: char2_from_hex(unsigned char byteval, char *c2) michael@0: { michael@0: int i; michael@0: unsigned char offset; michael@0: for (i=0; i<2; i++) { michael@0: offset = (byteval >> 4*(1-i)) & 0x0f; michael@0: if (offset < 10) { michael@0: c2[i] = '0' + offset; michael@0: } else { michael@0: c2[i] = 'A' + offset - 10; michael@0: } michael@0: } michael@0: return SECSuccess; michael@0: } michael@0: michael@0: void michael@0: serialize_key(SECItem *it, int ni, PRFileDesc *file) michael@0: { michael@0: unsigned char len[4]; michael@0: int i; michael@0: SECStatus status; michael@0: NSSBase64Encoder *cx; michael@0: cx = NSSBase64Encoder_Create(output_ascii, file); michael@0: for (i=0; ilen >> 24) & 0xff; michael@0: len[1] = (it->len >> 16) & 0xff; michael@0: len[2] = (it->len >> 8) & 0xff; michael@0: len[3] = (it->len & 0xff); michael@0: status = NSSBase64Encoder_Update(cx, len, 4); michael@0: status = NSSBase64Encoder_Update(cx, it->data, it->len); michael@0: } michael@0: status = NSSBase64Encoder_Destroy(cx, PR_FALSE); michael@0: status = PR_Write(file, "\r\n", 2); michael@0: } michael@0: michael@0: void michael@0: key_from_filedata(PLArenaPool *arena, SECItem *it, int ns, int ni, SECItem *filedata) michael@0: { michael@0: int fpos = 0; michael@0: int i, len; michael@0: unsigned char *buf = filedata->data; michael@0: for (i=0; i 0) { michael@0: it->len = len; michael@0: it->data = PORT_ArenaAlloc(arena, it->len); michael@0: PORT_Memcpy(it->data, &buf[fpos], it->len); michael@0: } else { michael@0: it->len = 0; michael@0: it->data = NULL; michael@0: } michael@0: it++; michael@0: } michael@0: fpos += len; michael@0: } michael@0: } michael@0: michael@0: static RSAPrivateKey * michael@0: rsakey_from_filedata(SECItem *filedata) michael@0: { michael@0: RSAPrivateKey *key; michael@0: PLArenaPool *arena; michael@0: arena = PORT_NewArena(BLTEST_DEFAULT_CHUNKSIZE); michael@0: key = (RSAPrivateKey *)PORT_ArenaZAlloc(arena, sizeof(RSAPrivateKey)); michael@0: key->arena = arena; michael@0: key_from_filedata(arena, &key->version, 0, 9, filedata); michael@0: return key; michael@0: } michael@0: michael@0: static PQGParams * michael@0: pqg_from_filedata(SECItem *filedata) michael@0: { michael@0: PQGParams *pqg; michael@0: PLArenaPool *arena; michael@0: arena = PORT_NewArena(BLTEST_DEFAULT_CHUNKSIZE); michael@0: pqg = (PQGParams *)PORT_ArenaZAlloc(arena, sizeof(PQGParams)); michael@0: pqg->arena = arena; michael@0: key_from_filedata(arena, &pqg->prime, 0, 3, filedata); michael@0: return pqg; michael@0: } michael@0: michael@0: static DSAPrivateKey * michael@0: dsakey_from_filedata(SECItem *filedata) michael@0: { michael@0: DSAPrivateKey *key; michael@0: PLArenaPool *arena; michael@0: arena = PORT_NewArena(BLTEST_DEFAULT_CHUNKSIZE); michael@0: key = (DSAPrivateKey *)PORT_ArenaZAlloc(arena, sizeof(DSAPrivateKey)); michael@0: key->params.arena = arena; michael@0: key_from_filedata(arena, &key->params.prime, 0, 5, filedata); michael@0: return key; michael@0: } michael@0: michael@0: #ifndef NSS_DISABLE_ECC michael@0: static ECPrivateKey * michael@0: eckey_from_filedata(SECItem *filedata) michael@0: { michael@0: ECPrivateKey *key; michael@0: PLArenaPool *arena; michael@0: SECStatus rv; michael@0: ECParams *tmpECParams = NULL; michael@0: arena = PORT_NewArena(BLTEST_DEFAULT_CHUNKSIZE); michael@0: key = (ECPrivateKey *)PORT_ArenaZAlloc(arena, sizeof(ECPrivateKey)); michael@0: /* read and convert params */ michael@0: key->ecParams.arena = arena; michael@0: key_from_filedata(arena, &key->ecParams.DEREncoding, 0, 1, filedata); michael@0: rv = SECOID_Init(); michael@0: CHECKERROR(rv, __LINE__); michael@0: rv = EC_DecodeParams(&key->ecParams.DEREncoding, &tmpECParams); michael@0: CHECKERROR(rv, __LINE__); michael@0: rv = EC_CopyParams(key->ecParams.arena, &key->ecParams, tmpECParams); michael@0: CHECKERROR(rv, __LINE__); michael@0: rv = SECOID_Shutdown(); michael@0: CHECKERROR(rv, __LINE__); michael@0: PORT_FreeArena(tmpECParams->arena, PR_TRUE); michael@0: /* read key */ michael@0: key_from_filedata(arena, &key->publicValue, 1, 3, filedata); michael@0: return key; michael@0: } michael@0: michael@0: typedef struct curveNameTagPairStr { michael@0: char *curveName; michael@0: SECOidTag curveOidTag; michael@0: } CurveNameTagPair; michael@0: michael@0: #define DEFAULT_CURVE_OID_TAG SEC_OID_SECG_EC_SECP192R1 michael@0: /* #define DEFAULT_CURVE_OID_TAG SEC_OID_SECG_EC_SECP160R1 */ michael@0: michael@0: static CurveNameTagPair nameTagPair[] = michael@0: { michael@0: { "sect163k1", SEC_OID_SECG_EC_SECT163K1}, michael@0: { "nistk163", SEC_OID_SECG_EC_SECT163K1}, michael@0: { "sect163r1", SEC_OID_SECG_EC_SECT163R1}, michael@0: { "sect163r2", SEC_OID_SECG_EC_SECT163R2}, michael@0: { "nistb163", SEC_OID_SECG_EC_SECT163R2}, michael@0: { "sect193r1", SEC_OID_SECG_EC_SECT193R1}, michael@0: { "sect193r2", SEC_OID_SECG_EC_SECT193R2}, michael@0: { "sect233k1", SEC_OID_SECG_EC_SECT233K1}, michael@0: { "nistk233", SEC_OID_SECG_EC_SECT233K1}, michael@0: { "sect233r1", SEC_OID_SECG_EC_SECT233R1}, michael@0: { "nistb233", SEC_OID_SECG_EC_SECT233R1}, michael@0: { "sect239k1", SEC_OID_SECG_EC_SECT239K1}, michael@0: { "sect283k1", SEC_OID_SECG_EC_SECT283K1}, michael@0: { "nistk283", SEC_OID_SECG_EC_SECT283K1}, michael@0: { "sect283r1", SEC_OID_SECG_EC_SECT283R1}, michael@0: { "nistb283", SEC_OID_SECG_EC_SECT283R1}, michael@0: { "sect409k1", SEC_OID_SECG_EC_SECT409K1}, michael@0: { "nistk409", SEC_OID_SECG_EC_SECT409K1}, michael@0: { "sect409r1", SEC_OID_SECG_EC_SECT409R1}, michael@0: { "nistb409", SEC_OID_SECG_EC_SECT409R1}, michael@0: { "sect571k1", SEC_OID_SECG_EC_SECT571K1}, michael@0: { "nistk571", SEC_OID_SECG_EC_SECT571K1}, michael@0: { "sect571r1", SEC_OID_SECG_EC_SECT571R1}, michael@0: { "nistb571", SEC_OID_SECG_EC_SECT571R1}, michael@0: { "secp160k1", SEC_OID_SECG_EC_SECP160K1}, michael@0: { "secp160r1", SEC_OID_SECG_EC_SECP160R1}, michael@0: { "secp160r2", SEC_OID_SECG_EC_SECP160R2}, michael@0: { "secp192k1", SEC_OID_SECG_EC_SECP192K1}, michael@0: { "secp192r1", SEC_OID_SECG_EC_SECP192R1}, michael@0: { "nistp192", SEC_OID_SECG_EC_SECP192R1}, michael@0: { "secp224k1", SEC_OID_SECG_EC_SECP224K1}, michael@0: { "secp224r1", SEC_OID_SECG_EC_SECP224R1}, michael@0: { "nistp224", SEC_OID_SECG_EC_SECP224R1}, michael@0: { "secp256k1", SEC_OID_SECG_EC_SECP256K1}, michael@0: { "secp256r1", SEC_OID_SECG_EC_SECP256R1}, michael@0: { "nistp256", SEC_OID_SECG_EC_SECP256R1}, michael@0: { "secp384r1", SEC_OID_SECG_EC_SECP384R1}, michael@0: { "nistp384", SEC_OID_SECG_EC_SECP384R1}, michael@0: { "secp521r1", SEC_OID_SECG_EC_SECP521R1}, michael@0: { "nistp521", SEC_OID_SECG_EC_SECP521R1}, michael@0: michael@0: { "prime192v1", SEC_OID_ANSIX962_EC_PRIME192V1 }, michael@0: { "prime192v2", SEC_OID_ANSIX962_EC_PRIME192V2 }, michael@0: { "prime192v3", SEC_OID_ANSIX962_EC_PRIME192V3 }, michael@0: { "prime239v1", SEC_OID_ANSIX962_EC_PRIME239V1 }, michael@0: { "prime239v2", SEC_OID_ANSIX962_EC_PRIME239V2 }, michael@0: { "prime239v3", SEC_OID_ANSIX962_EC_PRIME239V3 }, michael@0: michael@0: { "c2pnb163v1", SEC_OID_ANSIX962_EC_C2PNB163V1 }, michael@0: { "c2pnb163v2", SEC_OID_ANSIX962_EC_C2PNB163V2 }, michael@0: { "c2pnb163v3", SEC_OID_ANSIX962_EC_C2PNB163V3 }, michael@0: { "c2pnb176v1", SEC_OID_ANSIX962_EC_C2PNB176V1 }, michael@0: { "c2tnb191v1", SEC_OID_ANSIX962_EC_C2TNB191V1 }, michael@0: { "c2tnb191v2", SEC_OID_ANSIX962_EC_C2TNB191V2 }, michael@0: { "c2tnb191v3", SEC_OID_ANSIX962_EC_C2TNB191V3 }, michael@0: { "c2onb191v4", SEC_OID_ANSIX962_EC_C2ONB191V4 }, michael@0: { "c2onb191v5", SEC_OID_ANSIX962_EC_C2ONB191V5 }, michael@0: { "c2pnb208w1", SEC_OID_ANSIX962_EC_C2PNB208W1 }, michael@0: { "c2tnb239v1", SEC_OID_ANSIX962_EC_C2TNB239V1 }, michael@0: { "c2tnb239v2", SEC_OID_ANSIX962_EC_C2TNB239V2 }, michael@0: { "c2tnb239v3", SEC_OID_ANSIX962_EC_C2TNB239V3 }, michael@0: { "c2onb239v4", SEC_OID_ANSIX962_EC_C2ONB239V4 }, michael@0: { "c2onb239v5", SEC_OID_ANSIX962_EC_C2ONB239V5 }, michael@0: { "c2pnb272w1", SEC_OID_ANSIX962_EC_C2PNB272W1 }, michael@0: { "c2pnb304w1", SEC_OID_ANSIX962_EC_C2PNB304W1 }, michael@0: { "c2tnb359v1", SEC_OID_ANSIX962_EC_C2TNB359V1 }, michael@0: { "c2pnb368w1", SEC_OID_ANSIX962_EC_C2PNB368W1 }, michael@0: { "c2tnb431r1", SEC_OID_ANSIX962_EC_C2TNB431R1 }, michael@0: michael@0: { "secp112r1", SEC_OID_SECG_EC_SECP112R1}, michael@0: { "secp112r2", SEC_OID_SECG_EC_SECP112R2}, michael@0: { "secp128r1", SEC_OID_SECG_EC_SECP128R1}, michael@0: { "secp128r2", SEC_OID_SECG_EC_SECP128R2}, michael@0: michael@0: { "sect113r1", SEC_OID_SECG_EC_SECT113R1}, michael@0: { "sect113r2", SEC_OID_SECG_EC_SECT113R2}, michael@0: { "sect131r1", SEC_OID_SECG_EC_SECT131R1}, michael@0: { "sect131r2", SEC_OID_SECG_EC_SECT131R2}, michael@0: }; michael@0: michael@0: static SECItem * michael@0: getECParams(const char *curve) michael@0: { michael@0: SECItem *ecparams; michael@0: SECOidData *oidData = NULL; michael@0: SECOidTag curveOidTag = SEC_OID_UNKNOWN; /* default */ michael@0: int i, numCurves; michael@0: michael@0: if (curve != NULL) { michael@0: numCurves = sizeof(nameTagPair)/sizeof(CurveNameTagPair); michael@0: for (i = 0; ((i < numCurves) && (curveOidTag == SEC_OID_UNKNOWN)); michael@0: i++) { michael@0: if (PL_strcmp(curve, nameTagPair[i].curveName) == 0) michael@0: curveOidTag = nameTagPair[i].curveOidTag; michael@0: } michael@0: } michael@0: michael@0: /* Return NULL if curve name is not recognized */ michael@0: if ((curveOidTag == SEC_OID_UNKNOWN) || michael@0: (oidData = SECOID_FindOIDByTag(curveOidTag)) == NULL) { michael@0: fprintf(stderr, "Unrecognized elliptic curve %s\n", curve); michael@0: return NULL; michael@0: } michael@0: michael@0: ecparams = SECITEM_AllocItem(NULL, NULL, (2 + oidData->oid.len)); michael@0: michael@0: /* michael@0: * ecparams->data needs to contain the ASN encoding of an object ID (OID) michael@0: * representing the named curve. The actual OID is in michael@0: * oidData->oid.data so we simply prepend 0x06 and OID length michael@0: */ michael@0: ecparams->data[0] = SEC_ASN1_OBJECT_ID; michael@0: ecparams->data[1] = oidData->oid.len; michael@0: memcpy(ecparams->data + 2, oidData->oid.data, oidData->oid.len); michael@0: michael@0: return ecparams; michael@0: } michael@0: #endif /* NSS_DISABLE_ECC */ michael@0: michael@0: static void michael@0: dump_pqg(PQGParams *pqg) michael@0: { michael@0: SECU_PrintInteger(stdout, &pqg->prime, "PRIME:", 0); michael@0: SECU_PrintInteger(stdout, &pqg->subPrime, "SUBPRIME:", 0); michael@0: SECU_PrintInteger(stdout, &pqg->base, "BASE:", 0); michael@0: } michael@0: michael@0: static void michael@0: dump_dsakey(DSAPrivateKey *key) michael@0: { michael@0: dump_pqg(&key->params); michael@0: SECU_PrintInteger(stdout, &key->publicValue, "PUBLIC VALUE:", 0); michael@0: SECU_PrintInteger(stdout, &key->privateValue, "PRIVATE VALUE:", 0); michael@0: } michael@0: michael@0: #ifndef NSS_DISABLE_ECC michael@0: static void michael@0: dump_ecp(ECParams *ecp) michael@0: { michael@0: /* TODO other fields */ michael@0: SECU_PrintInteger(stdout, &ecp->base, "BASE POINT:", 0); michael@0: } michael@0: michael@0: static void michael@0: dump_eckey(ECPrivateKey *key) michael@0: { michael@0: dump_ecp(&key->ecParams); michael@0: SECU_PrintInteger(stdout, &key->publicValue, "PUBLIC VALUE:", 0); michael@0: SECU_PrintInteger(stdout, &key->privateValue, "PRIVATE VALUE:", 0); michael@0: } michael@0: #endif michael@0: michael@0: static void michael@0: dump_rsakey(RSAPrivateKey *key) michael@0: { michael@0: SECU_PrintInteger(stdout, &key->version, "VERSION:", 0); michael@0: SECU_PrintInteger(stdout, &key->modulus, "MODULUS:", 0); michael@0: SECU_PrintInteger(stdout, &key->publicExponent, "PUBLIC EXP:", 0); michael@0: SECU_PrintInteger(stdout, &key->privateExponent, "PRIVATE EXP:", 0); michael@0: SECU_PrintInteger(stdout, &key->prime1, "CRT PRIME 1:", 0); michael@0: SECU_PrintInteger(stdout, &key->prime2, "CRT PRIME 2:", 0); michael@0: SECU_PrintInteger(stdout, &key->exponent1, "CRT EXP 1:", 0); michael@0: SECU_PrintInteger(stdout, &key->exponent2, "CRT EXP 2:", 0); michael@0: SECU_PrintInteger(stdout, &key->coefficient, "CRT COEFFICIENT:", 0); michael@0: } michael@0: michael@0: typedef enum { michael@0: bltestBase64Encoded, /* Base64 encoded ASCII */ michael@0: bltestBinary, /* straight binary */ michael@0: bltestHexSpaceDelim, /* 0x12 0x34 0xab 0xCD ... */ michael@0: bltestHexStream /* 1234abCD ... */ michael@0: } bltestIOMode; michael@0: michael@0: typedef struct michael@0: { michael@0: SECItem buf; michael@0: SECItem pBuf; michael@0: bltestIOMode mode; michael@0: PRFileDesc* file; michael@0: } bltestIO; michael@0: michael@0: typedef SECStatus (* bltestSymmCipherFn)(void *cx, michael@0: unsigned char *output, michael@0: unsigned int *outputLen, michael@0: unsigned int maxOutputLen, michael@0: const unsigned char *input, michael@0: unsigned int inputLen); michael@0: michael@0: typedef SECStatus (* bltestPubKeyCipherFn)(void *key, michael@0: SECItem *output, michael@0: const SECItem *input); michael@0: michael@0: typedef SECStatus (* bltestHashCipherFn)(unsigned char *dest, michael@0: const unsigned char *src, michael@0: PRUint32 src_length); michael@0: michael@0: /* Note: Algorithms are grouped in order to support is_symmkeyCipher / michael@0: * is_pubkeyCipher / is_hashCipher / is_sigCipher michael@0: */ michael@0: typedef enum { michael@0: bltestINVALID = -1, michael@0: bltestDES_ECB, /* Symmetric Key Ciphers */ michael@0: bltestDES_CBC, /* . */ michael@0: bltestDES_EDE_ECB, /* . */ michael@0: bltestDES_EDE_CBC, /* . */ michael@0: bltestRC2_ECB, /* . */ michael@0: bltestRC2_CBC, /* . */ michael@0: bltestRC4, /* . */ michael@0: #ifdef NSS_SOFTOKEN_DOES_RC5 michael@0: bltestRC5_ECB, /* . */ michael@0: bltestRC5_CBC, /* . */ michael@0: #endif michael@0: bltestAES_ECB, /* . */ michael@0: bltestAES_CBC, /* . */ michael@0: bltestAES_CTS, /* . */ michael@0: bltestAES_CTR, /* . */ michael@0: bltestAES_GCM, /* . */ michael@0: bltestCAMELLIA_ECB, /* . */ michael@0: bltestCAMELLIA_CBC, /* . */ michael@0: bltestSEED_ECB, /* SEED algorithm */ michael@0: bltestSEED_CBC, /* SEED algorithm */ michael@0: bltestRSA, /* Public Key Ciphers */ michael@0: bltestRSA_OAEP, /* . (Public Key Enc.) */ michael@0: bltestRSA_PSS, /* . (Public Key Sig.) */ michael@0: #ifndef NSS_DISABLE_ECC michael@0: bltestECDSA, /* . (Public Key Sig.) */ michael@0: #endif michael@0: bltestDSA, /* . (Public Key Sig.) */ michael@0: bltestMD2, /* Hash algorithms */ michael@0: bltestMD5, /* . */ michael@0: bltestSHA1, /* . */ michael@0: bltestSHA224, /* . */ michael@0: bltestSHA256, /* . */ michael@0: bltestSHA384, /* . */ michael@0: bltestSHA512, /* . */ michael@0: NUMMODES michael@0: } bltestCipherMode; michael@0: michael@0: static char *mode_strings[] = michael@0: { michael@0: "des_ecb", michael@0: "des_cbc", michael@0: "des3_ecb", michael@0: "des3_cbc", michael@0: "rc2_ecb", michael@0: "rc2_cbc", michael@0: "rc4", michael@0: #ifdef NSS_SOFTOKEN_DOES_RC5 michael@0: "rc5_ecb", michael@0: "rc5_cbc", michael@0: #endif michael@0: "aes_ecb", michael@0: "aes_cbc", michael@0: "aes_cts", michael@0: "aes_ctr", michael@0: "aes_gcm", michael@0: "camellia_ecb", michael@0: "camellia_cbc", michael@0: "seed_ecb", michael@0: "seed_cbc", michael@0: "rsa", michael@0: "rsa_oaep", michael@0: "rsa_pss", michael@0: #ifndef NSS_DISABLE_ECC michael@0: "ecdsa", michael@0: #endif michael@0: /*"pqg",*/ michael@0: "dsa", michael@0: "md2", michael@0: "md5", michael@0: "sha1", michael@0: "sha224", michael@0: "sha256", michael@0: "sha384", michael@0: "sha512", michael@0: }; michael@0: michael@0: typedef struct michael@0: { michael@0: bltestIO key; michael@0: bltestIO iv; michael@0: } bltestSymmKeyParams; michael@0: michael@0: typedef struct michael@0: { michael@0: bltestSymmKeyParams sk; /* must be first */ michael@0: bltestIO aad; michael@0: } bltestAuthSymmKeyParams; michael@0: michael@0: typedef struct michael@0: { michael@0: bltestIO key; michael@0: bltestIO iv; michael@0: int rounds; michael@0: int wordsize; michael@0: } bltestRC5Params; michael@0: michael@0: typedef struct michael@0: { michael@0: bltestIO key; michael@0: int keysizeInBits; michael@0: michael@0: /* OAEP & PSS */ michael@0: HASH_HashType hashAlg; michael@0: HASH_HashType maskHashAlg; michael@0: bltestIO seed; /* salt if PSS */ michael@0: } bltestRSAParams; michael@0: michael@0: typedef struct michael@0: { michael@0: bltestIO pqgdata; michael@0: unsigned int keysize; michael@0: bltestIO keyseed; michael@0: bltestIO sigseed; michael@0: PQGParams *pqg; michael@0: } bltestDSAParams; michael@0: michael@0: #ifndef NSS_DISABLE_ECC michael@0: typedef struct michael@0: { michael@0: char *curveName; michael@0: bltestIO sigseed; michael@0: } bltestECDSAParams; michael@0: #endif michael@0: michael@0: typedef struct michael@0: { michael@0: bltestIO key; michael@0: void * privKey; michael@0: void * pubKey; michael@0: bltestIO sig; /* if doing verify, the signature (which may come michael@0: * from sigfile. */ michael@0: michael@0: union { michael@0: bltestRSAParams rsa; michael@0: bltestDSAParams dsa; michael@0: #ifndef NSS_DISABLE_ECC michael@0: bltestECDSAParams ecdsa; michael@0: #endif michael@0: } cipherParams; michael@0: } bltestAsymKeyParams; michael@0: michael@0: typedef struct michael@0: { michael@0: bltestIO key; /* unused */ michael@0: PRBool restart; michael@0: } bltestHashParams; michael@0: michael@0: typedef union michael@0: { michael@0: bltestIO key; michael@0: bltestSymmKeyParams sk; michael@0: bltestAuthSymmKeyParams ask; michael@0: bltestRC5Params rc5; michael@0: bltestAsymKeyParams asymk; michael@0: bltestHashParams hash; michael@0: } bltestParams; michael@0: michael@0: typedef struct bltestCipherInfoStr bltestCipherInfo; michael@0: michael@0: struct bltestCipherInfoStr { michael@0: PLArenaPool *arena; michael@0: /* link to next in multithreaded test */ michael@0: bltestCipherInfo *next; michael@0: PRThread *cipherThread; michael@0: michael@0: /* MonteCarlo test flag*/ michael@0: PRBool mCarlo; michael@0: /* cipher context */ michael@0: void *cx; michael@0: /* I/O streams */ michael@0: bltestIO input; michael@0: bltestIO output; michael@0: /* Cipher-specific parameters */ michael@0: bltestParams params; michael@0: /* Cipher mode */ michael@0: bltestCipherMode mode; michael@0: /* Cipher function (encrypt/decrypt/sign/verify/hash) */ michael@0: union { michael@0: bltestSymmCipherFn symmkeyCipher; michael@0: bltestPubKeyCipherFn pubkeyCipher; michael@0: bltestHashCipherFn hashCipher; michael@0: } cipher; michael@0: /* performance testing */ michael@0: int repetitionsToPerfom; michael@0: int seconds; michael@0: int repetitions; michael@0: int cxreps; michael@0: double cxtime; michael@0: double optime; michael@0: }; michael@0: michael@0: PRBool michael@0: is_symmkeyCipher(bltestCipherMode mode) michael@0: { michael@0: /* change as needed! */ michael@0: if (mode >= bltestDES_ECB && mode <= bltestSEED_CBC) michael@0: return PR_TRUE; michael@0: return PR_FALSE; michael@0: } michael@0: michael@0: PRBool michael@0: is_authCipher(bltestCipherMode mode) michael@0: { michael@0: /* change as needed! */ michael@0: if (mode == bltestAES_GCM) michael@0: return PR_TRUE; michael@0: return PR_FALSE; michael@0: } michael@0: michael@0: michael@0: PRBool michael@0: is_singleShotCipher(bltestCipherMode mode) michael@0: { michael@0: /* change as needed! */ michael@0: if (mode == bltestAES_GCM) michael@0: return PR_TRUE; michael@0: if (mode == bltestAES_CTS) michael@0: return PR_TRUE; michael@0: return PR_FALSE; michael@0: } michael@0: michael@0: PRBool michael@0: is_pubkeyCipher(bltestCipherMode mode) michael@0: { michael@0: /* change as needed! */ michael@0: if (mode >= bltestRSA && mode <= bltestDSA) michael@0: return PR_TRUE; michael@0: return PR_FALSE; michael@0: } michael@0: michael@0: PRBool michael@0: is_hashCipher(bltestCipherMode mode) michael@0: { michael@0: /* change as needed! */ michael@0: if (mode >= bltestMD2 && mode <= bltestSHA512) michael@0: return PR_TRUE; michael@0: return PR_FALSE; michael@0: } michael@0: michael@0: PRBool michael@0: is_sigCipher(bltestCipherMode mode) michael@0: { michael@0: /* change as needed! */ michael@0: if (mode >= bltestRSA_PSS && mode <= bltestDSA) michael@0: return PR_TRUE; michael@0: return PR_FALSE; michael@0: } michael@0: michael@0: PRBool michael@0: cipher_requires_IV(bltestCipherMode mode) michael@0: { michael@0: /* change as needed! */ michael@0: if (mode == bltestDES_CBC || mode == bltestDES_EDE_CBC || michael@0: mode == bltestRC2_CBC || michael@0: #ifdef NSS_SOFTOKEN_DOES_RC5 michael@0: mode == bltestRC5_CBC || michael@0: #endif michael@0: mode == bltestAES_CBC || mode == bltestAES_CTS || michael@0: mode == bltestAES_CTR || mode == bltestAES_GCM || michael@0: mode == bltestCAMELLIA_CBC || mode == bltestSEED_CBC) michael@0: return PR_TRUE; michael@0: return PR_FALSE; michael@0: } michael@0: michael@0: SECStatus finishIO(bltestIO *output, PRFileDesc *file); michael@0: michael@0: SECStatus michael@0: setupIO(PLArenaPool *arena, bltestIO *input, PRFileDesc *file, michael@0: char *str, int numBytes) michael@0: { michael@0: SECStatus rv = SECSuccess; michael@0: SECItem fileData; michael@0: SECItem *in; michael@0: unsigned char *tok; michael@0: unsigned int i, j; michael@0: michael@0: if (file && (numBytes == 0 || file == PR_STDIN)) { michael@0: /* grabbing data from a file */ michael@0: rv = SECU_FileToItem(&fileData, file); michael@0: if (rv != SECSuccess) michael@0: return SECFailure; michael@0: in = &fileData; michael@0: } else if (str) { michael@0: /* grabbing data from command line */ michael@0: fileData.data = (unsigned char *)str; michael@0: fileData.len = PL_strlen(str); michael@0: in = &fileData; michael@0: } else if (file) { michael@0: /* create nonce */ michael@0: SECITEM_AllocItem(arena, &input->buf, numBytes); michael@0: RNG_GenerateGlobalRandomBytes(input->buf.data, numBytes); michael@0: return finishIO(input, file); michael@0: } else { michael@0: return SECFailure; michael@0: } michael@0: michael@0: switch (input->mode) { michael@0: case bltestBase64Encoded: michael@0: if (in->len == 0) { michael@0: input->buf.data = NULL; michael@0: input->buf.len = 0; michael@0: break; michael@0: } michael@0: rv = atob(in, &input->buf, arena); michael@0: break; michael@0: case bltestBinary: michael@0: if (in->len == 0) { michael@0: input->buf.data = NULL; michael@0: input->buf.len = 0; michael@0: break; michael@0: } michael@0: if (in->data[in->len-1] == '\n') --in->len; michael@0: if (in->data[in->len-1] == '\r') --in->len; michael@0: SECITEM_CopyItem(arena, &input->buf, in); michael@0: break; michael@0: case bltestHexSpaceDelim: michael@0: SECITEM_AllocItem(arena, &input->buf, in->len/5); michael@0: for (i=0, j=0; ilen; i+=5, j++) { michael@0: tok = &in->data[i]; michael@0: if (tok[0] != '0' || tok[1] != 'x' || tok[4] != ' ') michael@0: /* bad hex token */ michael@0: break; michael@0: michael@0: rv = hex_from_2char(&tok[2], input->buf.data + j); michael@0: if (rv) michael@0: break; michael@0: } michael@0: break; michael@0: case bltestHexStream: michael@0: SECITEM_AllocItem(arena, &input->buf, in->len/2); michael@0: for (i=0, j=0; ilen; i+=2, j++) { michael@0: tok = &in->data[i]; michael@0: rv = hex_from_2char(tok, input->buf.data + j); michael@0: if (rv) michael@0: break; michael@0: } michael@0: break; michael@0: } michael@0: michael@0: if (file) michael@0: SECITEM_FreeItem(&fileData, PR_FALSE); michael@0: return rv; michael@0: } michael@0: michael@0: SECStatus michael@0: finishIO(bltestIO *output, PRFileDesc *file) michael@0: { michael@0: SECStatus rv = SECSuccess; michael@0: PRInt32 nb; michael@0: unsigned char byteval; michael@0: SECItem *it; michael@0: char hexstr[5]; michael@0: unsigned int i; michael@0: if (output->pBuf.len > 0) { michael@0: it = &output->pBuf; michael@0: } else { michael@0: it = &output->buf; michael@0: } michael@0: switch (output->mode) { michael@0: case bltestBase64Encoded: michael@0: rv = btoa_file(it, file); michael@0: break; michael@0: case bltestBinary: michael@0: nb = PR_Write(file, it->data, it->len); michael@0: rv = (nb == (PRInt32)it->len) ? SECSuccess : SECFailure; michael@0: break; michael@0: case bltestHexSpaceDelim: michael@0: hexstr[0] = '0'; michael@0: hexstr[1] = 'x'; michael@0: hexstr[4] = ' '; michael@0: for (i=0; ilen; i++) { michael@0: byteval = it->data[i]; michael@0: rv = char2_from_hex(byteval, hexstr + 2); michael@0: nb = PR_Write(file, hexstr, 5); michael@0: if (rv) michael@0: break; michael@0: } michael@0: PR_Write(file, "\n", 1); michael@0: break; michael@0: case bltestHexStream: michael@0: for (i=0; ilen; i++) { michael@0: byteval = it->data[i]; michael@0: rv = char2_from_hex(byteval, hexstr); michael@0: if (rv) michael@0: break; michael@0: nb = PR_Write(file, hexstr, 2); michael@0: } michael@0: PR_Write(file, "\n", 1); michael@0: break; michael@0: } michael@0: return rv; michael@0: } michael@0: michael@0: void michael@0: bltestCopyIO(PLArenaPool *arena, bltestIO *dest, bltestIO *src) michael@0: { michael@0: SECITEM_CopyItem(arena, &dest->buf, &src->buf); michael@0: if (src->pBuf.len > 0) { michael@0: dest->pBuf.len = src->pBuf.len; michael@0: dest->pBuf.data = dest->buf.data + (src->pBuf.data - src->buf.data); michael@0: } michael@0: dest->mode = src->mode; michael@0: dest->file = src->file; michael@0: } michael@0: michael@0: void michael@0: misalignBuffer(PLArenaPool *arena, bltestIO *io, int off) michael@0: { michael@0: ptrdiff_t offset = (ptrdiff_t)io->buf.data % WORDSIZE; michael@0: int length = io->buf.len; michael@0: if (offset != off) { michael@0: SECITEM_ReallocItemV2(arena, &io->buf, length + 2*WORDSIZE); michael@0: /* offset may have changed? */ michael@0: offset = (ptrdiff_t)io->buf.data % WORDSIZE; michael@0: if (offset != off) { michael@0: memmove(io->buf.data + off, io->buf.data, length); michael@0: io->pBuf.data = io->buf.data + off; michael@0: io->pBuf.len = length; michael@0: } else { michael@0: io->pBuf.data = io->buf.data; michael@0: io->pBuf.len = length; michael@0: } michael@0: } else { michael@0: io->pBuf.data = io->buf.data; michael@0: io->pBuf.len = length; michael@0: } michael@0: } michael@0: michael@0: SECStatus michael@0: des_Encrypt(void *cx, unsigned char *output, unsigned int *outputLen, michael@0: unsigned int maxOutputLen, const unsigned char *input, michael@0: unsigned int inputLen) michael@0: { michael@0: return DES_Encrypt((DESContext *)cx, output, outputLen, maxOutputLen, michael@0: input, inputLen); michael@0: } michael@0: michael@0: SECStatus michael@0: des_Decrypt(void *cx, unsigned char *output, unsigned int *outputLen, michael@0: unsigned int maxOutputLen, const unsigned char *input, michael@0: unsigned int inputLen) michael@0: { michael@0: return DES_Decrypt((DESContext *)cx, output, outputLen, maxOutputLen, michael@0: input, inputLen); michael@0: } michael@0: michael@0: SECStatus michael@0: rc2_Encrypt(void *cx, unsigned char *output, unsigned int *outputLen, michael@0: unsigned int maxOutputLen, const unsigned char *input, michael@0: unsigned int inputLen) michael@0: { michael@0: return RC2_Encrypt((RC2Context *)cx, output, outputLen, maxOutputLen, michael@0: input, inputLen); michael@0: } michael@0: michael@0: SECStatus michael@0: rc2_Decrypt(void *cx, unsigned char *output, unsigned int *outputLen, michael@0: unsigned int maxOutputLen, const unsigned char *input, michael@0: unsigned int inputLen) michael@0: { michael@0: return RC2_Decrypt((RC2Context *)cx, output, outputLen, maxOutputLen, michael@0: input, inputLen); michael@0: } michael@0: michael@0: SECStatus michael@0: rc4_Encrypt(void *cx, unsigned char *output, unsigned int *outputLen, michael@0: unsigned int maxOutputLen, const unsigned char *input, michael@0: unsigned int inputLen) michael@0: { michael@0: return RC4_Encrypt((RC4Context *)cx, output, outputLen, maxOutputLen, michael@0: input, inputLen); michael@0: } michael@0: michael@0: SECStatus michael@0: rc4_Decrypt(void *cx, unsigned char *output, unsigned int *outputLen, michael@0: unsigned int maxOutputLen, const unsigned char *input, michael@0: unsigned int inputLen) michael@0: { michael@0: return RC4_Decrypt((RC4Context *)cx, output, outputLen, maxOutputLen, michael@0: input, inputLen); michael@0: } michael@0: michael@0: SECStatus michael@0: aes_Encrypt(void *cx, unsigned char *output, unsigned int *outputLen, michael@0: unsigned int maxOutputLen, const unsigned char *input, michael@0: unsigned int inputLen) michael@0: { michael@0: return AES_Encrypt((AESContext *)cx, output, outputLen, maxOutputLen, michael@0: input, inputLen); michael@0: } michael@0: michael@0: SECStatus michael@0: aes_Decrypt(void *cx, unsigned char *output, unsigned int *outputLen, michael@0: unsigned int maxOutputLen, const unsigned char *input, michael@0: unsigned int inputLen) michael@0: { michael@0: return AES_Decrypt((AESContext *)cx, output, outputLen, maxOutputLen, michael@0: input, inputLen); michael@0: } michael@0: michael@0: SECStatus michael@0: camellia_Encrypt(void *cx, unsigned char *output, unsigned int *outputLen, michael@0: unsigned int maxOutputLen, const unsigned char *input, michael@0: unsigned int inputLen) michael@0: { michael@0: return Camellia_Encrypt((CamelliaContext *)cx, output, outputLen, michael@0: maxOutputLen, michael@0: input, inputLen); michael@0: } michael@0: michael@0: SECStatus michael@0: camellia_Decrypt(void *cx, unsigned char *output, unsigned int *outputLen, michael@0: unsigned int maxOutputLen, const unsigned char *input, michael@0: unsigned int inputLen) michael@0: { michael@0: return Camellia_Decrypt((CamelliaContext *)cx, output, outputLen, michael@0: maxOutputLen, michael@0: input, inputLen); michael@0: } michael@0: michael@0: SECStatus michael@0: seed_Encrypt(void *cx, unsigned char *output, unsigned int *outputLen, michael@0: unsigned int maxOutputLen, const unsigned char *input, michael@0: unsigned int inputLen) michael@0: { michael@0: return SEED_Encrypt((SEEDContext *)cx, output, outputLen, maxOutputLen, michael@0: input, inputLen); michael@0: } michael@0: michael@0: SECStatus michael@0: seed_Decrypt(void *cx, unsigned char *output, unsigned int *outputLen, michael@0: unsigned int maxOutputLen, const unsigned char *input, michael@0: unsigned int inputLen) michael@0: { michael@0: return SEED_Decrypt((SEEDContext *)cx, output, outputLen, maxOutputLen, michael@0: input, inputLen); michael@0: } michael@0: michael@0: SECStatus michael@0: rsa_PublicKeyOp(void *cx, SECItem *output, const SECItem *input) michael@0: { michael@0: bltestAsymKeyParams *params = (bltestAsymKeyParams *)cx; michael@0: RSAPublicKey *pubKey = (RSAPublicKey *)params->pubKey; michael@0: SECStatus rv = RSA_PublicKeyOp(pubKey, output->data, input->data); michael@0: if (rv == SECSuccess) { michael@0: output->len = pubKey->modulus.data[0] ? pubKey->modulus.len : michael@0: pubKey->modulus.len - 1; michael@0: } michael@0: return rv; michael@0: } michael@0: michael@0: SECStatus michael@0: rsa_PrivateKeyOp(void *cx, SECItem *output, const SECItem *input) michael@0: { michael@0: bltestAsymKeyParams *params = (bltestAsymKeyParams *)cx; michael@0: RSAPrivateKey *privKey = (RSAPrivateKey *)params->privKey; michael@0: SECStatus rv = RSA_PrivateKeyOp(privKey, output->data, input->data); michael@0: if (rv == SECSuccess) { michael@0: output->len = privKey->modulus.data[0] ? privKey->modulus.len : michael@0: privKey->modulus.len - 1; michael@0: } michael@0: return rv; michael@0: } michael@0: michael@0: SECStatus michael@0: rsa_signDigestPSS(void *cx, SECItem *output, const SECItem *input) michael@0: { michael@0: bltestAsymKeyParams *params = (bltestAsymKeyParams *)cx; michael@0: bltestRSAParams *rsaParams = ¶ms->cipherParams.rsa; michael@0: return RSA_SignPSS((RSAPrivateKey *)params->privKey, michael@0: rsaParams->hashAlg, michael@0: rsaParams->maskHashAlg, michael@0: rsaParams->seed.buf.data, michael@0: rsaParams->seed.buf.len, michael@0: output->data, &output->len, output->len, michael@0: input->data, input->len); michael@0: } michael@0: michael@0: SECStatus michael@0: rsa_verifyDigestPSS(void *cx, SECItem *output, const SECItem *input) michael@0: { michael@0: bltestAsymKeyParams *params = (bltestAsymKeyParams *)cx; michael@0: bltestRSAParams *rsaParams = ¶ms->cipherParams.rsa; michael@0: return RSA_CheckSignPSS((RSAPublicKey *)params->pubKey, michael@0: rsaParams->hashAlg, michael@0: rsaParams->maskHashAlg, michael@0: rsaParams->seed.buf.len, michael@0: output->data, output->len, michael@0: input->data, input->len); michael@0: } michael@0: michael@0: SECStatus michael@0: rsa_encryptOAEP(void *cx, SECItem *output, const SECItem *input) michael@0: { michael@0: bltestAsymKeyParams *params = (bltestAsymKeyParams *)cx; michael@0: bltestRSAParams *rsaParams = ¶ms->cipherParams.rsa; michael@0: return RSA_EncryptOAEP((RSAPublicKey *)params->pubKey, michael@0: rsaParams->hashAlg, michael@0: rsaParams->maskHashAlg, michael@0: NULL, 0, michael@0: rsaParams->seed.buf.data, michael@0: rsaParams->seed.buf.len, michael@0: output->data, &output->len, output->len, michael@0: input->data, input->len); michael@0: } michael@0: michael@0: SECStatus michael@0: rsa_decryptOAEP(void *cx, SECItem *output, const SECItem *input) michael@0: { michael@0: bltestAsymKeyParams *params = (bltestAsymKeyParams *)cx; michael@0: bltestRSAParams *rsaParams = ¶ms->cipherParams.rsa; michael@0: return RSA_DecryptOAEP((RSAPrivateKey *)params->privKey, michael@0: rsaParams->hashAlg, michael@0: rsaParams->maskHashAlg, michael@0: NULL, 0, michael@0: output->data, &output->len, output->len, michael@0: input->data, input->len); michael@0: } michael@0: michael@0: SECStatus michael@0: dsa_signDigest(void *cx, SECItem *output, const SECItem *input) michael@0: { michael@0: bltestAsymKeyParams *params = (bltestAsymKeyParams *)cx; michael@0: if (params->cipherParams.dsa.sigseed.buf.len > 0) { michael@0: return DSA_SignDigestWithSeed((DSAPrivateKey *)params->privKey, michael@0: output, input, michael@0: params->cipherParams.dsa.sigseed.buf.data); michael@0: } michael@0: return DSA_SignDigest((DSAPrivateKey *)params->privKey, output, input); michael@0: } michael@0: michael@0: SECStatus michael@0: dsa_verifyDigest(void *cx, SECItem *output, const SECItem *input) michael@0: { michael@0: bltestAsymKeyParams *params = (bltestAsymKeyParams *)cx; michael@0: return DSA_VerifyDigest((DSAPublicKey *)params->pubKey, output, input); michael@0: } michael@0: michael@0: #ifndef NSS_DISABLE_ECC michael@0: SECStatus michael@0: ecdsa_signDigest(void *cx, SECItem *output, const SECItem *input) michael@0: { michael@0: bltestAsymKeyParams *params = (bltestAsymKeyParams *)cx; michael@0: if (params->cipherParams.ecdsa.sigseed.buf.len > 0) { michael@0: return ECDSA_SignDigestWithSeed( michael@0: (ECPrivateKey *)params->privKey, michael@0: output, input, michael@0: params->cipherParams.ecdsa.sigseed.buf.data, michael@0: params->cipherParams.ecdsa.sigseed.buf.len); michael@0: } michael@0: return ECDSA_SignDigest((ECPrivateKey *)params->privKey, output, input); michael@0: } michael@0: michael@0: SECStatus michael@0: ecdsa_verifyDigest(void *cx, SECItem *output, const SECItem *input) michael@0: { michael@0: bltestAsymKeyParams *params = (bltestAsymKeyParams *)cx; michael@0: return ECDSA_VerifyDigest((ECPublicKey *)params->pubKey, output, input); michael@0: } michael@0: #endif michael@0: michael@0: SECStatus michael@0: bltest_des_init(bltestCipherInfo *cipherInfo, PRBool encrypt) michael@0: { michael@0: PRIntervalTime time1, time2; michael@0: bltestSymmKeyParams *desp = &cipherInfo->params.sk; michael@0: int minorMode; michael@0: int i; michael@0: switch (cipherInfo->mode) { michael@0: case bltestDES_ECB: minorMode = NSS_DES; break; michael@0: case bltestDES_CBC: minorMode = NSS_DES_CBC; break; michael@0: case bltestDES_EDE_ECB: minorMode = NSS_DES_EDE3; break; michael@0: case bltestDES_EDE_CBC: minorMode = NSS_DES_EDE3_CBC; break; michael@0: default: michael@0: return SECFailure; michael@0: } michael@0: cipherInfo->cx = (void*)DES_CreateContext(desp->key.buf.data, michael@0: desp->iv.buf.data, michael@0: minorMode, encrypt); michael@0: if (cipherInfo->cxreps > 0) { michael@0: DESContext **dummycx; michael@0: dummycx = PORT_Alloc(cipherInfo->cxreps * sizeof(DESContext *)); michael@0: TIMESTART(); michael@0: for (i=0; icxreps; i++) { michael@0: dummycx[i] = (void*)DES_CreateContext(desp->key.buf.data, michael@0: desp->iv.buf.data, michael@0: minorMode, encrypt); michael@0: } michael@0: TIMEFINISH(cipherInfo->cxtime, 1.0); michael@0: for (i=0; icxreps; i++) { michael@0: DES_DestroyContext(dummycx[i], PR_TRUE); michael@0: } michael@0: PORT_Free(dummycx); michael@0: } michael@0: if (encrypt) michael@0: cipherInfo->cipher.symmkeyCipher = des_Encrypt; michael@0: else michael@0: cipherInfo->cipher.symmkeyCipher = des_Decrypt; michael@0: return SECSuccess; michael@0: } michael@0: michael@0: SECStatus michael@0: bltest_rc2_init(bltestCipherInfo *cipherInfo, PRBool encrypt) michael@0: { michael@0: PRIntervalTime time1, time2; michael@0: bltestSymmKeyParams *rc2p = &cipherInfo->params.sk; michael@0: int minorMode; michael@0: int i; michael@0: switch (cipherInfo->mode) { michael@0: case bltestRC2_ECB: minorMode = NSS_RC2; break; michael@0: case bltestRC2_CBC: minorMode = NSS_RC2_CBC; break; michael@0: default: michael@0: return SECFailure; michael@0: } michael@0: cipherInfo->cx = (void*)RC2_CreateContext(rc2p->key.buf.data, michael@0: rc2p->key.buf.len, michael@0: rc2p->iv.buf.data, michael@0: minorMode, michael@0: rc2p->key.buf.len); michael@0: if (cipherInfo->cxreps > 0) { michael@0: RC2Context **dummycx; michael@0: dummycx = PORT_Alloc(cipherInfo->cxreps * sizeof(RC2Context *)); michael@0: TIMESTART(); michael@0: for (i=0; icxreps; i++) { michael@0: dummycx[i] = (void*)RC2_CreateContext(rc2p->key.buf.data, michael@0: rc2p->key.buf.len, michael@0: rc2p->iv.buf.data, michael@0: minorMode, michael@0: rc2p->key.buf.len); michael@0: } michael@0: TIMEFINISH(cipherInfo->cxtime, 1.0); michael@0: for (i=0; icxreps; i++) { michael@0: RC2_DestroyContext(dummycx[i], PR_TRUE); michael@0: } michael@0: PORT_Free(dummycx); michael@0: } michael@0: if (encrypt) michael@0: cipherInfo->cipher.symmkeyCipher = rc2_Encrypt; michael@0: else michael@0: cipherInfo->cipher.symmkeyCipher = rc2_Decrypt; michael@0: return SECSuccess; michael@0: } michael@0: michael@0: SECStatus michael@0: bltest_rc4_init(bltestCipherInfo *cipherInfo, PRBool encrypt) michael@0: { michael@0: PRIntervalTime time1, time2; michael@0: int i; michael@0: bltestSymmKeyParams *rc4p = &cipherInfo->params.sk; michael@0: cipherInfo->cx = (void*)RC4_CreateContext(rc4p->key.buf.data, michael@0: rc4p->key.buf.len); michael@0: if (cipherInfo->cxreps > 0) { michael@0: RC4Context **dummycx; michael@0: dummycx = PORT_Alloc(cipherInfo->cxreps * sizeof(RC4Context *)); michael@0: TIMESTART(); michael@0: for (i=0; icxreps; i++) { michael@0: dummycx[i] = (void*)RC4_CreateContext(rc4p->key.buf.data, michael@0: rc4p->key.buf.len); michael@0: } michael@0: TIMEFINISH(cipherInfo->cxtime, 1.0); michael@0: for (i=0; icxreps; i++) { michael@0: RC4_DestroyContext(dummycx[i], PR_TRUE); michael@0: } michael@0: PORT_Free(dummycx); michael@0: } michael@0: if (encrypt) michael@0: cipherInfo->cipher.symmkeyCipher = rc4_Encrypt; michael@0: else michael@0: cipherInfo->cipher.symmkeyCipher = rc4_Decrypt; michael@0: return SECSuccess; michael@0: } michael@0: michael@0: SECStatus michael@0: bltest_rc5_init(bltestCipherInfo *cipherInfo, PRBool encrypt) michael@0: { michael@0: #ifdef NSS_SOFTOKEN_DOES_RC5 michael@0: PRIntervalTime time1, time2; michael@0: bltestRC5Params *rc5p = &cipherInfo->params.rc5; michael@0: int minorMode; michael@0: switch (cipherInfo->mode) { michael@0: case bltestRC5_ECB: minorMode = NSS_RC5; break; michael@0: case bltestRC5_CBC: minorMode = NSS_RC5_CBC; break; michael@0: default: michael@0: return SECFailure; michael@0: } michael@0: TIMESTART(); michael@0: cipherInfo->cx = (void*)RC5_CreateContext(&rc5p->key.buf, michael@0: rc5p->rounds, rc5p->wordsize, michael@0: rc5p->iv.buf.data, minorMode); michael@0: TIMEFINISH(cipherInfo->cxtime, 1.0); michael@0: if (encrypt) michael@0: cipherInfo->cipher.symmkeyCipher = RC5_Encrypt; michael@0: else michael@0: cipherInfo->cipher.symmkeyCipher = RC5_Decrypt; michael@0: return SECSuccess; michael@0: #else michael@0: return SECFailure; michael@0: #endif michael@0: } michael@0: michael@0: SECStatus michael@0: bltest_aes_init(bltestCipherInfo *cipherInfo, PRBool encrypt) michael@0: { michael@0: bltestSymmKeyParams *aesp = &cipherInfo->params.sk; michael@0: bltestAuthSymmKeyParams *gcmp = &cipherInfo->params.ask; michael@0: int minorMode; michael@0: int i; michael@0: int keylen = aesp->key.buf.len; michael@0: int blocklen = AES_BLOCK_SIZE; michael@0: PRIntervalTime time1, time2; michael@0: unsigned char *params; michael@0: int len; michael@0: CK_AES_CTR_PARAMS ctrParams; michael@0: CK_GCM_PARAMS gcmParams; michael@0: michael@0: params = aesp->iv.buf.data; michael@0: switch (cipherInfo->mode) { michael@0: case bltestAES_ECB: minorMode = NSS_AES; break; michael@0: case bltestAES_CBC: minorMode = NSS_AES_CBC; break; michael@0: case bltestAES_CTS: minorMode = NSS_AES_CTS; break; michael@0: case bltestAES_CTR: michael@0: minorMode = NSS_AES_CTR; michael@0: ctrParams.ulCounterBits = 32; michael@0: len = PR_MIN(aesp->iv.buf.len, blocklen); michael@0: PORT_Memset(ctrParams.cb, 0, blocklen); michael@0: PORT_Memcpy(ctrParams.cb, aesp->iv.buf.data, len); michael@0: params = (unsigned char *)&ctrParams; michael@0: break; michael@0: case bltestAES_GCM: michael@0: minorMode = NSS_AES_GCM; michael@0: gcmParams.pIv = gcmp->sk.iv.buf.data; michael@0: gcmParams.ulIvLen = gcmp->sk.iv.buf.len; michael@0: gcmParams.pAAD = gcmp->aad.buf.data; michael@0: gcmParams.ulAADLen = gcmp->aad.buf.len; michael@0: gcmParams.ulTagBits = blocklen*8; michael@0: params = (unsigned char *)&gcmParams; michael@0: break; michael@0: default: michael@0: return SECFailure; michael@0: } michael@0: cipherInfo->cx = (void*)AES_CreateContext(aesp->key.buf.data, michael@0: params, michael@0: minorMode, encrypt, michael@0: keylen, blocklen); michael@0: if (cipherInfo->cxreps > 0) { michael@0: AESContext **dummycx; michael@0: dummycx = PORT_Alloc(cipherInfo->cxreps * sizeof(AESContext *)); michael@0: TIMESTART(); michael@0: for (i=0; icxreps; i++) { michael@0: dummycx[i] = (void*)AES_CreateContext(aesp->key.buf.data, michael@0: params, michael@0: minorMode, encrypt, michael@0: keylen, blocklen); michael@0: } michael@0: TIMEFINISH(cipherInfo->cxtime, 1.0); michael@0: for (i=0; icxreps; i++) { michael@0: AES_DestroyContext(dummycx[i], PR_TRUE); michael@0: } michael@0: PORT_Free(dummycx); michael@0: } michael@0: if (encrypt) michael@0: cipherInfo->cipher.symmkeyCipher = aes_Encrypt; michael@0: else michael@0: cipherInfo->cipher.symmkeyCipher = aes_Decrypt; michael@0: return SECSuccess; michael@0: } michael@0: michael@0: SECStatus michael@0: bltest_camellia_init(bltestCipherInfo *cipherInfo, PRBool encrypt) michael@0: { michael@0: bltestSymmKeyParams *camelliap = &cipherInfo->params.sk; michael@0: int minorMode; michael@0: int i; michael@0: int keylen = camelliap->key.buf.len; michael@0: PRIntervalTime time1, time2; michael@0: michael@0: switch (cipherInfo->mode) { michael@0: case bltestCAMELLIA_ECB: minorMode = NSS_CAMELLIA; break; michael@0: case bltestCAMELLIA_CBC: minorMode = NSS_CAMELLIA_CBC; break; michael@0: default: michael@0: return SECFailure; michael@0: } michael@0: cipherInfo->cx = (void*)Camellia_CreateContext(camelliap->key.buf.data, michael@0: camelliap->iv.buf.data, michael@0: minorMode, encrypt, michael@0: keylen); michael@0: if (cipherInfo->cxreps > 0) { michael@0: CamelliaContext **dummycx; michael@0: dummycx = PORT_Alloc(cipherInfo->cxreps * sizeof(CamelliaContext *)); michael@0: TIMESTART(); michael@0: for (i=0; icxreps; i++) { michael@0: dummycx[i] = (void*)Camellia_CreateContext(camelliap->key.buf.data, michael@0: camelliap->iv.buf.data, michael@0: minorMode, encrypt, michael@0: keylen); michael@0: } michael@0: TIMEFINISH(cipherInfo->cxtime, 1.0); michael@0: for (i=0; icxreps; i++) { michael@0: Camellia_DestroyContext(dummycx[i], PR_TRUE); michael@0: } michael@0: PORT_Free(dummycx); michael@0: } michael@0: if (encrypt) michael@0: cipherInfo->cipher.symmkeyCipher = camellia_Encrypt; michael@0: else michael@0: cipherInfo->cipher.symmkeyCipher = camellia_Decrypt; michael@0: return SECSuccess; michael@0: } michael@0: michael@0: SECStatus michael@0: bltest_seed_init(bltestCipherInfo *cipherInfo, PRBool encrypt) michael@0: { michael@0: PRIntervalTime time1, time2; michael@0: bltestSymmKeyParams *seedp = &cipherInfo->params.sk; michael@0: int minorMode; michael@0: int i; michael@0: michael@0: switch (cipherInfo->mode) { michael@0: case bltestSEED_ECB: minorMode = NSS_SEED; break; michael@0: case bltestSEED_CBC: minorMode = NSS_SEED_CBC; break; michael@0: default: michael@0: return SECFailure; michael@0: } michael@0: cipherInfo->cx = (void*)SEED_CreateContext(seedp->key.buf.data, michael@0: seedp->iv.buf.data, michael@0: minorMode, encrypt); michael@0: if (cipherInfo->cxreps > 0) { michael@0: SEEDContext **dummycx; michael@0: dummycx = PORT_Alloc(cipherInfo->cxreps * sizeof(SEEDContext *)); michael@0: TIMESTART(); michael@0: for (i=0; icxreps; i++) { michael@0: dummycx[i] = (void*)SEED_CreateContext(seedp->key.buf.data, michael@0: seedp->iv.buf.data, michael@0: minorMode, encrypt); michael@0: } michael@0: TIMEFINISH(cipherInfo->cxtime, 1.0); michael@0: for (i=0; icxreps; i++) { michael@0: SEED_DestroyContext(dummycx[i], PR_TRUE); michael@0: } michael@0: PORT_Free(dummycx); michael@0: } michael@0: if (encrypt) michael@0: cipherInfo->cipher.symmkeyCipher = seed_Encrypt; michael@0: else michael@0: cipherInfo->cipher.symmkeyCipher = seed_Decrypt; michael@0: michael@0: return SECSuccess; michael@0: } michael@0: michael@0: SECStatus michael@0: bltest_rsa_init(bltestCipherInfo *cipherInfo, PRBool encrypt) michael@0: { michael@0: int i; michael@0: RSAPrivateKey **dummyKey; michael@0: RSAPrivateKey *privKey; michael@0: RSAPublicKey *pubKey; michael@0: PRIntervalTime time1, time2; michael@0: michael@0: bltestAsymKeyParams *asymk = &cipherInfo->params.asymk; michael@0: bltestRSAParams *rsap = &asymk->cipherParams.rsa; michael@0: michael@0: /* RSA key gen was done during parameter setup */ michael@0: cipherInfo->cx = asymk; michael@0: privKey = (RSAPrivateKey *)asymk->privKey; michael@0: michael@0: /* For performance testing */ michael@0: if (cipherInfo->cxreps > 0) { michael@0: /* Create space for n private key objects */ michael@0: dummyKey = (RSAPrivateKey **)PORT_Alloc(cipherInfo->cxreps * michael@0: sizeof(RSAPrivateKey *)); michael@0: /* Time n keygens, storing in the array */ michael@0: TIMESTART(); michael@0: for (i=0; icxreps; i++) michael@0: dummyKey[i] = RSA_NewKey(rsap->keysizeInBits, michael@0: &privKey->publicExponent); michael@0: TIMEFINISH(cipherInfo->cxtime, cipherInfo->cxreps); michael@0: /* Free the n key objects */ michael@0: for (i=0; icxreps; i++) michael@0: PORT_FreeArena(dummyKey[i]->arena, PR_TRUE); michael@0: PORT_Free(dummyKey); michael@0: } michael@0: michael@0: if ((encrypt && !is_sigCipher(cipherInfo->mode)) || michael@0: (!encrypt && is_sigCipher(cipherInfo->mode))) { michael@0: /* Have to convert private key to public key. Memory michael@0: * is freed with private key's arena */ michael@0: pubKey = (RSAPublicKey *)PORT_ArenaAlloc(privKey->arena, michael@0: sizeof(RSAPublicKey)); michael@0: pubKey->modulus.len = privKey->modulus.len; michael@0: pubKey->modulus.data = privKey->modulus.data; michael@0: pubKey->publicExponent.len = privKey->publicExponent.len; michael@0: pubKey->publicExponent.data = privKey->publicExponent.data; michael@0: asymk->pubKey = (void *)pubKey; michael@0: } michael@0: switch (cipherInfo->mode) { michael@0: case bltestRSA: michael@0: cipherInfo->cipher.pubkeyCipher = encrypt ? rsa_PublicKeyOp michael@0: : rsa_PrivateKeyOp; michael@0: break; michael@0: case bltestRSA_PSS: michael@0: cipherInfo->cipher.pubkeyCipher = encrypt ? rsa_signDigestPSS michael@0: : rsa_verifyDigestPSS; michael@0: break; michael@0: case bltestRSA_OAEP: michael@0: cipherInfo->cipher.pubkeyCipher = encrypt ? rsa_encryptOAEP michael@0: : rsa_decryptOAEP; michael@0: break; michael@0: } michael@0: return SECSuccess; michael@0: } michael@0: michael@0: SECStatus michael@0: blapi_pqg_param_gen(unsigned int keysize, PQGParams **pqg, PQGVerify **vfy) michael@0: { michael@0: if (keysize < 1024) { michael@0: int j = PQG_PBITS_TO_INDEX(keysize); michael@0: return PQG_ParamGen(j, pqg, vfy); michael@0: } michael@0: return PQG_ParamGenV2(keysize, 0, 0, pqg, vfy); michael@0: } michael@0: michael@0: SECStatus michael@0: bltest_pqg_init(bltestDSAParams *dsap) michael@0: { michael@0: SECStatus rv, res; michael@0: PQGVerify *vfy = NULL; michael@0: rv = blapi_pqg_param_gen(dsap->keysize, &dsap->pqg, &vfy); michael@0: CHECKERROR(rv, __LINE__); michael@0: rv = PQG_VerifyParams(dsap->pqg, vfy, &res); michael@0: CHECKERROR(res, __LINE__); michael@0: CHECKERROR(rv, __LINE__); michael@0: return rv; michael@0: } michael@0: michael@0: SECStatus michael@0: bltest_dsa_init(bltestCipherInfo *cipherInfo, PRBool encrypt) michael@0: { michael@0: int i; michael@0: DSAPrivateKey **dummyKey; michael@0: PQGParams *dummypqg; michael@0: PRIntervalTime time1, time2; michael@0: bltestAsymKeyParams *asymk = &cipherInfo->params.asymk; michael@0: bltestDSAParams *dsap = &asymk->cipherParams.dsa; michael@0: PQGVerify *ignore = NULL; michael@0: cipherInfo->cx = asymk; michael@0: /* For performance testing */ michael@0: if (cipherInfo->cxreps > 0) { michael@0: /* Create space for n private key objects */ michael@0: dummyKey = (DSAPrivateKey **)PORT_ZAlloc(cipherInfo->cxreps * michael@0: sizeof(DSAPrivateKey *)); michael@0: /* Time n keygens, storing in the array */ michael@0: TIMESTART(); michael@0: for (i=0; icxreps; i++) { michael@0: dummypqg = NULL; michael@0: blapi_pqg_param_gen(dsap->keysize, &dummypqg, &ignore); michael@0: DSA_NewKey(dummypqg, &dummyKey[i]); michael@0: } michael@0: TIMEFINISH(cipherInfo->cxtime, cipherInfo->cxreps); michael@0: /* Free the n key objects */ michael@0: for (i=0; icxreps; i++) michael@0: PORT_FreeArena(dummyKey[i]->params.arena, PR_TRUE); michael@0: PORT_Free(dummyKey); michael@0: } michael@0: if (!dsap->pqg && dsap->pqgdata.buf.len > 0) { michael@0: dsap->pqg = pqg_from_filedata(&dsap->pqgdata.buf); michael@0: } michael@0: if (!asymk->privKey && asymk->key.buf.len > 0) { michael@0: asymk->privKey = dsakey_from_filedata(&asymk->key.buf); michael@0: } michael@0: if (encrypt) { michael@0: cipherInfo->cipher.pubkeyCipher = dsa_signDigest; michael@0: } else { michael@0: /* Have to convert private key to public key. Memory michael@0: * is freed with private key's arena */ michael@0: DSAPublicKey *pubkey; michael@0: DSAPrivateKey *key = (DSAPrivateKey *)asymk->privKey; michael@0: pubkey = (DSAPublicKey *)PORT_ArenaZAlloc(key->params.arena, michael@0: sizeof(DSAPublicKey)); michael@0: pubkey->params.prime.len = key->params.prime.len; michael@0: pubkey->params.prime.data = key->params.prime.data; michael@0: pubkey->params.subPrime.len = key->params.subPrime.len; michael@0: pubkey->params.subPrime.data = key->params.subPrime.data; michael@0: pubkey->params.base.len = key->params.base.len; michael@0: pubkey->params.base.data = key->params.base.data; michael@0: pubkey->publicValue.len = key->publicValue.len; michael@0: pubkey->publicValue.data = key->publicValue.data; michael@0: asymk->pubKey = pubkey; michael@0: cipherInfo->cipher.pubkeyCipher = dsa_verifyDigest; michael@0: } michael@0: return SECSuccess; michael@0: } michael@0: michael@0: #ifndef NSS_DISABLE_ECC michael@0: SECStatus michael@0: bltest_ecdsa_init(bltestCipherInfo *cipherInfo, PRBool encrypt) michael@0: { michael@0: int i; michael@0: ECPrivateKey **dummyKey; michael@0: PRIntervalTime time1, time2; michael@0: bltestAsymKeyParams *asymk = &cipherInfo->params.asymk; michael@0: cipherInfo->cx = asymk; michael@0: /* For performance testing */ michael@0: if (cipherInfo->cxreps > 0) { michael@0: /* Create space for n private key objects */ michael@0: dummyKey = (ECPrivateKey **)PORT_ZAlloc(cipherInfo->cxreps * michael@0: sizeof(ECPrivateKey *)); michael@0: /* Time n keygens, storing in the array */ michael@0: TIMESTART(); michael@0: for (i=0; icxreps; i++) { michael@0: EC_NewKey(&((ECPrivateKey *)asymk->privKey)->ecParams, &dummyKey[i]); michael@0: } michael@0: TIMEFINISH(cipherInfo->cxtime, cipherInfo->cxreps); michael@0: /* Free the n key objects */ michael@0: for (i=0; icxreps; i++) michael@0: PORT_FreeArena(dummyKey[i]->ecParams.arena, PR_TRUE); michael@0: PORT_Free(dummyKey); michael@0: } michael@0: if (!asymk->privKey && asymk->key.buf.len > 0) { michael@0: asymk->privKey = eckey_from_filedata(&asymk->key.buf); michael@0: } michael@0: if (encrypt) { michael@0: cipherInfo->cipher.pubkeyCipher = ecdsa_signDigest; michael@0: } else { michael@0: /* Have to convert private key to public key. Memory michael@0: * is freed with private key's arena */ michael@0: ECPublicKey *pubkey; michael@0: ECPrivateKey *key = (ECPrivateKey *)asymk->privKey; michael@0: pubkey = (ECPublicKey *)PORT_ArenaZAlloc(key->ecParams.arena, michael@0: sizeof(ECPublicKey)); michael@0: pubkey->ecParams.type = key->ecParams.type; michael@0: pubkey->ecParams.fieldID.size = key->ecParams.fieldID.size; michael@0: pubkey->ecParams.fieldID.type = key->ecParams.fieldID.type; michael@0: pubkey->ecParams.fieldID.u.prime.len = key->ecParams.fieldID.u.prime.len; michael@0: pubkey->ecParams.fieldID.u.prime.data = key->ecParams.fieldID.u.prime.data; michael@0: pubkey->ecParams.fieldID.k1 = key->ecParams.fieldID.k1; michael@0: pubkey->ecParams.fieldID.k2 = key->ecParams.fieldID.k2; michael@0: pubkey->ecParams.fieldID.k3 = key->ecParams.fieldID.k3; michael@0: pubkey->ecParams.curve.a.len = key->ecParams.curve.a.len; michael@0: pubkey->ecParams.curve.a.data = key->ecParams.curve.a.data; michael@0: pubkey->ecParams.curve.b.len = key->ecParams.curve.b.len; michael@0: pubkey->ecParams.curve.b.data = key->ecParams.curve.b.data; michael@0: pubkey->ecParams.curve.seed.len = key->ecParams.curve.seed.len; michael@0: pubkey->ecParams.curve.seed.data = key->ecParams.curve.seed.data; michael@0: pubkey->ecParams.base.len = key->ecParams.base.len; michael@0: pubkey->ecParams.base.data = key->ecParams.base.data; michael@0: pubkey->ecParams.order.len = key->ecParams.order.len; michael@0: pubkey->ecParams.order.data = key->ecParams.order.data; michael@0: pubkey->ecParams.cofactor = key->ecParams.cofactor; michael@0: pubkey->ecParams.DEREncoding.len = key->ecParams.DEREncoding.len; michael@0: pubkey->ecParams.DEREncoding.data = key->ecParams.DEREncoding.data; michael@0: pubkey->ecParams.name= key->ecParams.name; michael@0: pubkey->publicValue.len = key->publicValue.len; michael@0: pubkey->publicValue.data = key->publicValue.data; michael@0: asymk->pubKey = pubkey; michael@0: cipherInfo->cipher.pubkeyCipher = ecdsa_verifyDigest; michael@0: } michael@0: return SECSuccess; michael@0: } michael@0: #endif michael@0: michael@0: /* XXX unfortunately, this is not defined in blapi.h */ michael@0: SECStatus michael@0: md2_HashBuf(unsigned char *dest, const unsigned char *src, PRUint32 src_length) michael@0: { michael@0: unsigned int len; michael@0: MD2Context *cx = MD2_NewContext(); michael@0: if (cx == NULL) return SECFailure; michael@0: MD2_Begin(cx); michael@0: MD2_Update(cx, src, src_length); michael@0: MD2_End(cx, dest, &len, MD2_LENGTH); michael@0: MD2_DestroyContext(cx, PR_TRUE); michael@0: return SECSuccess; michael@0: } michael@0: michael@0: SECStatus michael@0: md2_restart(unsigned char *dest, const unsigned char *src, PRUint32 src_length) michael@0: { michael@0: MD2Context *cx, *cx_cpy; michael@0: unsigned char *cxbytes; michael@0: unsigned int len; michael@0: unsigned int i, quarter; michael@0: SECStatus rv = SECSuccess; michael@0: cx = MD2_NewContext(); michael@0: MD2_Begin(cx); michael@0: /* divide message by 4, restarting 3 times */ michael@0: quarter = (src_length + 3)/ 4; michael@0: for (i=0; i < 4 && src_length > 0; i++) { michael@0: MD2_Update(cx, src + i*quarter, PR_MIN(quarter, src_length)); michael@0: len = MD2_FlattenSize(cx); michael@0: cxbytes = PORT_Alloc(len); michael@0: MD2_Flatten(cx, cxbytes); michael@0: cx_cpy = MD2_Resurrect(cxbytes, NULL); michael@0: if (!cx_cpy) { michael@0: PR_fprintf(PR_STDERR, "%s: MD2_Resurrect failed!\n", progName); michael@0: goto finish; michael@0: } michael@0: rv = PORT_Memcmp(cx, cx_cpy, len); michael@0: if (rv) { michael@0: MD2_DestroyContext(cx_cpy, PR_TRUE); michael@0: PR_fprintf(PR_STDERR, "%s: MD2_restart failed!\n", progName); michael@0: goto finish; michael@0: } michael@0: MD2_DestroyContext(cx_cpy, PR_TRUE); michael@0: PORT_Free(cxbytes); michael@0: src_length -= quarter; michael@0: } michael@0: MD2_End(cx, dest, &len, MD2_LENGTH); michael@0: finish: michael@0: MD2_DestroyContext(cx, PR_TRUE); michael@0: return rv; michael@0: } michael@0: michael@0: SECStatus michael@0: md5_restart(unsigned char *dest, const unsigned char *src, PRUint32 src_length) michael@0: { michael@0: SECStatus rv = SECSuccess; michael@0: MD5Context *cx, *cx_cpy; michael@0: unsigned char *cxbytes; michael@0: unsigned int len; michael@0: unsigned int i, quarter; michael@0: cx = MD5_NewContext(); michael@0: MD5_Begin(cx); michael@0: /* divide message by 4, restarting 3 times */ michael@0: quarter = (src_length + 3)/ 4; michael@0: for (i=0; i < 4 && src_length > 0; i++) { michael@0: MD5_Update(cx, src + i*quarter, PR_MIN(quarter, src_length)); michael@0: len = MD5_FlattenSize(cx); michael@0: cxbytes = PORT_Alloc(len); michael@0: MD5_Flatten(cx, cxbytes); michael@0: cx_cpy = MD5_Resurrect(cxbytes, NULL); michael@0: if (!cx_cpy) { michael@0: PR_fprintf(PR_STDERR, "%s: MD5_Resurrect failed!\n", progName); michael@0: rv = SECFailure; michael@0: goto finish; michael@0: } michael@0: rv = PORT_Memcmp(cx, cx_cpy, len); michael@0: if (rv) { michael@0: MD5_DestroyContext(cx_cpy, PR_TRUE); michael@0: PR_fprintf(PR_STDERR, "%s: MD5_restart failed!\n", progName); michael@0: goto finish; michael@0: } michael@0: MD5_DestroyContext(cx_cpy, PR_TRUE); michael@0: PORT_Free(cxbytes); michael@0: src_length -= quarter; michael@0: } michael@0: MD5_End(cx, dest, &len, MD5_LENGTH); michael@0: finish: michael@0: MD5_DestroyContext(cx, PR_TRUE); michael@0: return rv; michael@0: } michael@0: michael@0: SECStatus michael@0: sha1_restart(unsigned char *dest, const unsigned char *src, PRUint32 src_length) michael@0: { michael@0: SECStatus rv = SECSuccess; michael@0: SHA1Context *cx, *cx_cpy; michael@0: unsigned char *cxbytes; michael@0: unsigned int len; michael@0: unsigned int i, quarter; michael@0: cx = SHA1_NewContext(); michael@0: SHA1_Begin(cx); michael@0: /* divide message by 4, restarting 3 times */ michael@0: quarter = (src_length + 3)/ 4; michael@0: for (i=0; i < 4 && src_length > 0; i++) { michael@0: SHA1_Update(cx, src + i*quarter, PR_MIN(quarter, src_length)); michael@0: len = SHA1_FlattenSize(cx); michael@0: cxbytes = PORT_Alloc(len); michael@0: SHA1_Flatten(cx, cxbytes); michael@0: cx_cpy = SHA1_Resurrect(cxbytes, NULL); michael@0: if (!cx_cpy) { michael@0: PR_fprintf(PR_STDERR, "%s: SHA1_Resurrect failed!\n", progName); michael@0: rv = SECFailure; michael@0: goto finish; michael@0: } michael@0: rv = PORT_Memcmp(cx, cx_cpy, len); michael@0: if (rv) { michael@0: SHA1_DestroyContext(cx_cpy, PR_TRUE); michael@0: PR_fprintf(PR_STDERR, "%s: SHA1_restart failed!\n", progName); michael@0: goto finish; michael@0: } michael@0: SHA1_DestroyContext(cx_cpy, PR_TRUE); michael@0: PORT_Free(cxbytes); michael@0: src_length -= quarter; michael@0: } michael@0: SHA1_End(cx, dest, &len, MD5_LENGTH); michael@0: finish: michael@0: SHA1_DestroyContext(cx, PR_TRUE); michael@0: return rv; michael@0: } michael@0: michael@0: SECStatus michael@0: SHA224_restart(unsigned char *dest, const unsigned char *src, PRUint32 src_length) michael@0: { michael@0: SECStatus rv = SECSuccess; michael@0: SHA224Context *cx, *cx_cpy; michael@0: unsigned char *cxbytes; michael@0: unsigned int len; michael@0: unsigned int i, quarter; michael@0: cx = SHA224_NewContext(); michael@0: SHA224_Begin(cx); michael@0: /* divide message by 4, restarting 3 times */ michael@0: quarter = (src_length + 3) / 4; michael@0: for (i=0; i < 4 && src_length > 0; i++) { michael@0: SHA224_Update(cx, src + i*quarter, PR_MIN(quarter, src_length)); michael@0: len = SHA224_FlattenSize(cx); michael@0: cxbytes = PORT_Alloc(len); michael@0: SHA224_Flatten(cx, cxbytes); michael@0: cx_cpy = SHA224_Resurrect(cxbytes, NULL); michael@0: if (!cx_cpy) { michael@0: PR_fprintf(PR_STDERR, "%s: SHA224_Resurrect failed!\n", progName); michael@0: rv = SECFailure; michael@0: goto finish; michael@0: } michael@0: rv = PORT_Memcmp(cx, cx_cpy, len); michael@0: if (rv) { michael@0: SHA224_DestroyContext(cx_cpy, PR_TRUE); michael@0: PR_fprintf(PR_STDERR, "%s: SHA224_restart failed!\n", progName); michael@0: goto finish; michael@0: } michael@0: michael@0: SHA224_DestroyContext(cx_cpy, PR_TRUE); michael@0: PORT_Free(cxbytes); michael@0: src_length -= quarter; michael@0: } michael@0: SHA224_End(cx, dest, &len, MD5_LENGTH); michael@0: finish: michael@0: SHA224_DestroyContext(cx, PR_TRUE); michael@0: return rv; michael@0: } michael@0: michael@0: SECStatus michael@0: SHA256_restart(unsigned char *dest, const unsigned char *src, PRUint32 src_length) michael@0: { michael@0: SECStatus rv = SECSuccess; michael@0: SHA256Context *cx, *cx_cpy; michael@0: unsigned char *cxbytes; michael@0: unsigned int len; michael@0: unsigned int i, quarter; michael@0: cx = SHA256_NewContext(); michael@0: SHA256_Begin(cx); michael@0: /* divide message by 4, restarting 3 times */ michael@0: quarter = (src_length + 3)/ 4; michael@0: for (i=0; i < 4 && src_length > 0; i++) { michael@0: SHA256_Update(cx, src + i*quarter, PR_MIN(quarter, src_length)); michael@0: len = SHA256_FlattenSize(cx); michael@0: cxbytes = PORT_Alloc(len); michael@0: SHA256_Flatten(cx, cxbytes); michael@0: cx_cpy = SHA256_Resurrect(cxbytes, NULL); michael@0: if (!cx_cpy) { michael@0: PR_fprintf(PR_STDERR, "%s: SHA256_Resurrect failed!\n", progName); michael@0: rv = SECFailure; michael@0: goto finish; michael@0: } michael@0: rv = PORT_Memcmp(cx, cx_cpy, len); michael@0: if (rv) { michael@0: SHA256_DestroyContext(cx_cpy, PR_TRUE); michael@0: PR_fprintf(PR_STDERR, "%s: SHA256_restart failed!\n", progName); michael@0: goto finish; michael@0: } michael@0: SHA256_DestroyContext(cx_cpy, PR_TRUE); michael@0: PORT_Free(cxbytes); michael@0: src_length -= quarter; michael@0: } michael@0: SHA256_End(cx, dest, &len, MD5_LENGTH); michael@0: finish: michael@0: SHA256_DestroyContext(cx, PR_TRUE); michael@0: return rv; michael@0: } michael@0: michael@0: SECStatus michael@0: SHA384_restart(unsigned char *dest, const unsigned char *src, PRUint32 src_length) michael@0: { michael@0: SECStatus rv = SECSuccess; michael@0: SHA384Context *cx, *cx_cpy; michael@0: unsigned char *cxbytes; michael@0: unsigned int len; michael@0: unsigned int i, quarter; michael@0: cx = SHA384_NewContext(); michael@0: SHA384_Begin(cx); michael@0: /* divide message by 4, restarting 3 times */ michael@0: quarter = (src_length + 3)/ 4; michael@0: for (i=0; i < 4 && src_length > 0; i++) { michael@0: SHA384_Update(cx, src + i*quarter, PR_MIN(quarter, src_length)); michael@0: len = SHA384_FlattenSize(cx); michael@0: cxbytes = PORT_Alloc(len); michael@0: SHA384_Flatten(cx, cxbytes); michael@0: cx_cpy = SHA384_Resurrect(cxbytes, NULL); michael@0: if (!cx_cpy) { michael@0: PR_fprintf(PR_STDERR, "%s: SHA384_Resurrect failed!\n", progName); michael@0: rv = SECFailure; michael@0: goto finish; michael@0: } michael@0: rv = PORT_Memcmp(cx, cx_cpy, len); michael@0: if (rv) { michael@0: SHA384_DestroyContext(cx_cpy, PR_TRUE); michael@0: PR_fprintf(PR_STDERR, "%s: SHA384_restart failed!\n", progName); michael@0: goto finish; michael@0: } michael@0: SHA384_DestroyContext(cx_cpy, PR_TRUE); michael@0: PORT_Free(cxbytes); michael@0: src_length -= quarter; michael@0: } michael@0: SHA384_End(cx, dest, &len, MD5_LENGTH); michael@0: finish: michael@0: SHA384_DestroyContext(cx, PR_TRUE); michael@0: return rv; michael@0: } michael@0: michael@0: SECStatus michael@0: SHA512_restart(unsigned char *dest, const unsigned char *src, PRUint32 src_length) michael@0: { michael@0: SECStatus rv = SECSuccess; michael@0: SHA512Context *cx, *cx_cpy; michael@0: unsigned char *cxbytes; michael@0: unsigned int len; michael@0: unsigned int i, quarter; michael@0: cx = SHA512_NewContext(); michael@0: SHA512_Begin(cx); michael@0: /* divide message by 4, restarting 3 times */ michael@0: quarter = (src_length + 3)/ 4; michael@0: for (i=0; i < 4 && src_length > 0; i++) { michael@0: SHA512_Update(cx, src + i*quarter, PR_MIN(quarter, src_length)); michael@0: len = SHA512_FlattenSize(cx); michael@0: cxbytes = PORT_Alloc(len); michael@0: SHA512_Flatten(cx, cxbytes); michael@0: cx_cpy = SHA512_Resurrect(cxbytes, NULL); michael@0: if (!cx_cpy) { michael@0: PR_fprintf(PR_STDERR, "%s: SHA512_Resurrect failed!\n", progName); michael@0: rv = SECFailure; michael@0: goto finish; michael@0: } michael@0: rv = PORT_Memcmp(cx, cx_cpy, len); michael@0: if (rv) { michael@0: SHA512_DestroyContext(cx_cpy, PR_TRUE); michael@0: PR_fprintf(PR_STDERR, "%s: SHA512_restart failed!\n", progName); michael@0: goto finish; michael@0: } michael@0: SHA512_DestroyContext(cx_cpy, PR_TRUE); michael@0: PORT_Free(cxbytes); michael@0: src_length -= quarter; michael@0: } michael@0: SHA512_End(cx, dest, &len, MD5_LENGTH); michael@0: finish: michael@0: SHA512_DestroyContext(cx, PR_TRUE); michael@0: return rv; michael@0: } michael@0: michael@0: SECStatus michael@0: pubkeyInitKey(bltestCipherInfo *cipherInfo, PRFileDesc *file, michael@0: #ifndef NSS_DISABLE_ECC michael@0: int keysize, int exponent, char *curveName) michael@0: #else michael@0: int keysize, int exponent) michael@0: #endif michael@0: { michael@0: int i; michael@0: SECStatus rv = SECSuccess; michael@0: bltestAsymKeyParams *asymk = &cipherInfo->params.asymk; michael@0: bltestRSAParams *rsap; michael@0: RSAPrivateKey **rsaKey = NULL; michael@0: bltestDSAParams *dsap; michael@0: DSAPrivateKey **dsaKey = NULL; michael@0: #ifndef NSS_DISABLE_ECC michael@0: SECItem *tmpECParamsDER; michael@0: ECParams *tmpECParams = NULL; michael@0: SECItem ecSerialize[3]; michael@0: ECPrivateKey **ecKey = NULL; michael@0: #endif michael@0: switch (cipherInfo->mode) { michael@0: case bltestRSA: michael@0: case bltestRSA_PSS: michael@0: case bltestRSA_OAEP: michael@0: rsap = &asymk->cipherParams.rsa; michael@0: rsaKey = (RSAPrivateKey **)&asymk->privKey; michael@0: if (keysize > 0) { michael@0: SECItem expitem = { 0, 0, 0 }; michael@0: SECITEM_AllocItem(cipherInfo->arena, &expitem, sizeof(int)); michael@0: for (i = 1; i <= sizeof(int); i++) michael@0: expitem.data[i-1] = exponent >> (8*(sizeof(int) - i)); michael@0: *rsaKey = RSA_NewKey(keysize * 8, &expitem); michael@0: serialize_key(&(*rsaKey)->version, 9, file); michael@0: rsap->keysizeInBits = keysize * 8; michael@0: } else { michael@0: setupIO(cipherInfo->arena, &asymk->key, file, NULL, 0); michael@0: *rsaKey = rsakey_from_filedata(&asymk->key.buf); michael@0: rsap->keysizeInBits = (*rsaKey)->modulus.len * 8; michael@0: } michael@0: break; michael@0: case bltestDSA: michael@0: dsap = &asymk->cipherParams.dsa; michael@0: dsaKey = (DSAPrivateKey **)&asymk->privKey; michael@0: if (keysize > 0) { michael@0: dsap->keysize = keysize*8; michael@0: if (!dsap->pqg) michael@0: bltest_pqg_init(dsap); michael@0: rv = DSA_NewKey(dsap->pqg, dsaKey); michael@0: CHECKERROR(rv, __LINE__); michael@0: serialize_key(&(*dsaKey)->params.prime, 5, file); michael@0: } else { michael@0: setupIO(cipherInfo->arena, &asymk->key, file, NULL, 0); michael@0: *dsaKey = dsakey_from_filedata(&asymk->key.buf); michael@0: dsap->keysize = (*dsaKey)->params.prime.len*8; michael@0: } michael@0: break; michael@0: #ifndef NSS_DISABLE_ECC michael@0: case bltestECDSA: michael@0: ecKey = (ECPrivateKey **)&asymk->privKey; michael@0: if (curveName != NULL) { michael@0: tmpECParamsDER = getECParams(curveName); michael@0: rv = SECOID_Init(); michael@0: CHECKERROR(rv, __LINE__); michael@0: rv = EC_DecodeParams(tmpECParamsDER, &tmpECParams) == SECFailure; michael@0: CHECKERROR(rv, __LINE__); michael@0: rv = EC_NewKey(tmpECParams, ecKey); michael@0: CHECKERROR(rv, __LINE__); michael@0: ecSerialize[0].type = tmpECParamsDER->type; michael@0: ecSerialize[0].data = tmpECParamsDER->data; michael@0: ecSerialize[0].len = tmpECParamsDER->len; michael@0: ecSerialize[1].type = (*ecKey)->publicValue.type; michael@0: ecSerialize[1].data = (*ecKey)->publicValue.data; michael@0: ecSerialize[1].len = (*ecKey)->publicValue.len; michael@0: ecSerialize[2].type = (*ecKey)->privateValue.type; michael@0: ecSerialize[2].data = (*ecKey)->privateValue.data; michael@0: ecSerialize[2].len = (*ecKey)->privateValue.len; michael@0: serialize_key(&(ecSerialize[0]), 3, file); michael@0: SECITEM_FreeItem(tmpECParamsDER, PR_TRUE); michael@0: PORT_FreeArena(tmpECParams->arena, PR_TRUE); michael@0: rv = SECOID_Shutdown(); michael@0: CHECKERROR(rv, __LINE__); michael@0: } else { michael@0: setupIO(cipherInfo->arena, &asymk->key, file, NULL, 0); michael@0: *ecKey = eckey_from_filedata(&asymk->key.buf); michael@0: } michael@0: break; michael@0: #endif michael@0: default: michael@0: return SECFailure; michael@0: } michael@0: return SECSuccess; michael@0: } michael@0: michael@0: SECStatus michael@0: cipherInit(bltestCipherInfo *cipherInfo, PRBool encrypt) michael@0: { michael@0: PRBool restart; michael@0: int outlen; michael@0: switch (cipherInfo->mode) { michael@0: case bltestDES_ECB: michael@0: case bltestDES_CBC: michael@0: case bltestDES_EDE_ECB: michael@0: case bltestDES_EDE_CBC: michael@0: SECITEM_AllocItem(cipherInfo->arena, &cipherInfo->output.buf, michael@0: cipherInfo->input.pBuf.len); michael@0: return bltest_des_init(cipherInfo, encrypt); michael@0: break; michael@0: case bltestRC2_ECB: michael@0: case bltestRC2_CBC: michael@0: SECITEM_AllocItem(cipherInfo->arena, &cipherInfo->output.buf, michael@0: cipherInfo->input.pBuf.len); michael@0: return bltest_rc2_init(cipherInfo, encrypt); michael@0: break; michael@0: case bltestRC4: michael@0: SECITEM_AllocItem(cipherInfo->arena, &cipherInfo->output.buf, michael@0: cipherInfo->input.pBuf.len); michael@0: return bltest_rc4_init(cipherInfo, encrypt); michael@0: break; michael@0: #ifdef NSS_SOFTOKEN_DOES_RC5 michael@0: case bltestRC5_ECB: michael@0: case bltestRC5_CBC: michael@0: SECITEM_AllocItem(cipherInfo->arena, &cipherInfo->output.buf, michael@0: cipherInfo->input.pBuf.len); michael@0: #endif michael@0: return bltest_rc5_init(cipherInfo, encrypt); michael@0: break; michael@0: case bltestAES_ECB: michael@0: case bltestAES_CBC: michael@0: case bltestAES_CTS: michael@0: case bltestAES_CTR: michael@0: case bltestAES_GCM: michael@0: outlen = cipherInfo->input.pBuf.len; michael@0: if (cipherInfo->mode == bltestAES_GCM && encrypt) { michael@0: outlen += 16; michael@0: } michael@0: SECITEM_AllocItem(cipherInfo->arena, &cipherInfo->output.buf, outlen); michael@0: return bltest_aes_init(cipherInfo, encrypt); michael@0: break; michael@0: case bltestCAMELLIA_ECB: michael@0: case bltestCAMELLIA_CBC: michael@0: SECITEM_AllocItem(cipherInfo->arena, &cipherInfo->output.buf, michael@0: cipherInfo->input.pBuf.len); michael@0: return bltest_camellia_init(cipherInfo, encrypt); michael@0: break; michael@0: case bltestSEED_ECB: michael@0: case bltestSEED_CBC: michael@0: SECITEM_AllocItem(cipherInfo->arena, &cipherInfo->output.buf, michael@0: cipherInfo->input.pBuf.len); michael@0: return bltest_seed_init(cipherInfo, encrypt); michael@0: break; michael@0: case bltestRSA: michael@0: case bltestRSA_OAEP: michael@0: case bltestRSA_PSS: michael@0: if (encrypt || cipherInfo->mode != bltestRSA_PSS) { michael@0: /* Don't allocate a buffer for PSS in verify mode, as no actual michael@0: * output is produced. */ michael@0: SECITEM_AllocItem(cipherInfo->arena, &cipherInfo->output.buf, michael@0: RSA_MAX_MODULUS_BITS / 8); michael@0: } michael@0: return bltest_rsa_init(cipherInfo, encrypt); michael@0: break; michael@0: case bltestDSA: michael@0: if (encrypt) { michael@0: SECITEM_AllocItem(cipherInfo->arena, &cipherInfo->output.buf, michael@0: DSA_MAX_SIGNATURE_LEN); michael@0: } michael@0: return bltest_dsa_init(cipherInfo, encrypt); michael@0: break; michael@0: #ifndef NSS_DISABLE_ECC michael@0: case bltestECDSA: michael@0: if (encrypt) { michael@0: SECITEM_AllocItem(cipherInfo->arena, &cipherInfo->output.buf, michael@0: 2 * MAX_ECKEY_LEN); michael@0: } michael@0: return bltest_ecdsa_init(cipherInfo, encrypt); michael@0: break; michael@0: #endif michael@0: case bltestMD2: michael@0: restart = cipherInfo->params.hash.restart; michael@0: SECITEM_AllocItem(cipherInfo->arena, &cipherInfo->output.buf, michael@0: MD2_LENGTH); michael@0: cipherInfo->cipher.hashCipher = (restart) ? md2_restart : md2_HashBuf; michael@0: return SECSuccess; michael@0: break; michael@0: case bltestMD5: michael@0: restart = cipherInfo->params.hash.restart; michael@0: SECITEM_AllocItem(cipherInfo->arena, &cipherInfo->output.buf, michael@0: MD5_LENGTH); michael@0: cipherInfo->cipher.hashCipher = (restart) ? md5_restart : MD5_HashBuf; michael@0: return SECSuccess; michael@0: break; michael@0: case bltestSHA1: michael@0: restart = cipherInfo->params.hash.restart; michael@0: SECITEM_AllocItem(cipherInfo->arena, &cipherInfo->output.buf, michael@0: SHA1_LENGTH); michael@0: cipherInfo->cipher.hashCipher = (restart) ? sha1_restart : SHA1_HashBuf; michael@0: return SECSuccess; michael@0: break; michael@0: case bltestSHA224: michael@0: restart = cipherInfo->params.hash.restart; michael@0: SECITEM_AllocItem(cipherInfo->arena, &cipherInfo->output.buf, michael@0: SHA224_LENGTH); michael@0: cipherInfo->cipher.hashCipher = (restart) ? SHA224_restart michael@0: : SHA224_HashBuf; michael@0: return SECSuccess; michael@0: break; michael@0: case bltestSHA256: michael@0: restart = cipherInfo->params.hash.restart; michael@0: SECITEM_AllocItem(cipherInfo->arena, &cipherInfo->output.buf, michael@0: SHA256_LENGTH); michael@0: cipherInfo->cipher.hashCipher = (restart) ? SHA256_restart michael@0: : SHA256_HashBuf; michael@0: return SECSuccess; michael@0: break; michael@0: case bltestSHA384: michael@0: restart = cipherInfo->params.hash.restart; michael@0: SECITEM_AllocItem(cipherInfo->arena, &cipherInfo->output.buf, michael@0: SHA384_LENGTH); michael@0: cipherInfo->cipher.hashCipher = (restart) ? SHA384_restart michael@0: : SHA384_HashBuf; michael@0: return SECSuccess; michael@0: break; michael@0: case bltestSHA512: michael@0: restart = cipherInfo->params.hash.restart; michael@0: SECITEM_AllocItem(cipherInfo->arena, &cipherInfo->output.buf, michael@0: SHA512_LENGTH); michael@0: cipherInfo->cipher.hashCipher = (restart) ? SHA512_restart michael@0: : SHA512_HashBuf; michael@0: return SECSuccess; michael@0: break; michael@0: default: michael@0: return SECFailure; michael@0: } michael@0: return SECSuccess; michael@0: } michael@0: michael@0: SECStatus michael@0: cipherDoOp(bltestCipherInfo *cipherInfo) michael@0: { michael@0: PRIntervalTime time1, time2; michael@0: SECStatus rv = SECSuccess; michael@0: int i; michael@0: unsigned int len; michael@0: unsigned int maxLen = cipherInfo->output.pBuf.len; michael@0: unsigned char *dummyOut; michael@0: dummyOut = PORT_Alloc(maxLen); michael@0: if (is_symmkeyCipher(cipherInfo->mode)) { michael@0: const unsigned char *input = cipherInfo->input.pBuf.data; michael@0: unsigned int inputLen = is_singleShotCipher(cipherInfo->mode) ? michael@0: cipherInfo->input.pBuf.len : michael@0: PR_MIN(cipherInfo->input.pBuf.len, 16); michael@0: unsigned char *output = cipherInfo->output.pBuf.data; michael@0: unsigned int outputLen = maxLen; michael@0: unsigned int totalOutputLen = 0; michael@0: TIMESTART(); michael@0: rv = (*cipherInfo->cipher.symmkeyCipher)(cipherInfo->cx, michael@0: output, &len, outputLen, michael@0: input, inputLen); michael@0: CHECKERROR(rv, __LINE__); michael@0: totalOutputLen += len; michael@0: if (cipherInfo->input.pBuf.len > inputLen) { michael@0: input += inputLen; michael@0: inputLen = cipherInfo->input.pBuf.len - inputLen; michael@0: output += len; michael@0: outputLen -= len; michael@0: rv = (*cipherInfo->cipher.symmkeyCipher)(cipherInfo->cx, michael@0: output, &len, outputLen, michael@0: input, inputLen); michael@0: CHECKERROR(rv, __LINE__); michael@0: totalOutputLen += len; michael@0: } michael@0: cipherInfo->output.pBuf.len = totalOutputLen; michael@0: TIMEFINISH(cipherInfo->optime, 1.0); michael@0: cipherInfo->repetitions = 0; michael@0: if (cipherInfo->repetitionsToPerfom != 0) { michael@0: TIMESTART(); michael@0: for (i=0; irepetitionsToPerfom; i++, michael@0: cipherInfo->repetitions++) { michael@0: (*cipherInfo->cipher.symmkeyCipher)(cipherInfo->cx, dummyOut, michael@0: &len, maxLen, michael@0: cipherInfo->input.pBuf.data, michael@0: cipherInfo->input.pBuf.len); michael@0: michael@0: CHECKERROR(rv, __LINE__); michael@0: } michael@0: } else { michael@0: int opsBetweenChecks = 0; michael@0: TIMEMARK(cipherInfo->seconds); michael@0: while (! (TIMETOFINISH())) { michael@0: int j = 0; michael@0: for (;j < opsBetweenChecks;j++) { michael@0: (*cipherInfo->cipher.symmkeyCipher)( michael@0: cipherInfo->cx, dummyOut, &len, maxLen, michael@0: cipherInfo->input.pBuf.data, michael@0: cipherInfo->input.pBuf.len); michael@0: } michael@0: cipherInfo->repetitions += j; michael@0: } michael@0: } michael@0: TIMEFINISH(cipherInfo->optime, 1.0); michael@0: } else if (is_pubkeyCipher(cipherInfo->mode)) { michael@0: TIMESTART(); michael@0: rv = (*cipherInfo->cipher.pubkeyCipher)(cipherInfo->cx, michael@0: &cipherInfo->output.pBuf, michael@0: &cipherInfo->input.pBuf); michael@0: TIMEFINISH(cipherInfo->optime, 1.0); michael@0: CHECKERROR(rv, __LINE__); michael@0: cipherInfo->repetitions = 0; michael@0: if (cipherInfo->repetitionsToPerfom != 0) { michael@0: TIMESTART(); michael@0: for (i=0; irepetitionsToPerfom; michael@0: i++, cipherInfo->repetitions++) { michael@0: SECItem dummy; michael@0: dummy.data = dummyOut; michael@0: dummy.len = maxLen; michael@0: (*cipherInfo->cipher.pubkeyCipher)(cipherInfo->cx, &dummy, michael@0: &cipherInfo->input.pBuf); michael@0: CHECKERROR(rv, __LINE__); michael@0: } michael@0: } else { michael@0: int opsBetweenChecks = 0; michael@0: TIMEMARK(cipherInfo->seconds); michael@0: while (! (TIMETOFINISH())) { michael@0: int j = 0; michael@0: for (;j < opsBetweenChecks;j++) { michael@0: SECItem dummy; michael@0: dummy.data = dummyOut; michael@0: dummy.len = maxLen; michael@0: (*cipherInfo->cipher.pubkeyCipher)(cipherInfo->cx, &dummy, michael@0: &cipherInfo->input.pBuf); michael@0: CHECKERROR(rv, __LINE__); michael@0: } michael@0: cipherInfo->repetitions += j; michael@0: } michael@0: } michael@0: TIMEFINISH(cipherInfo->optime, 1.0); michael@0: } else if (is_hashCipher(cipherInfo->mode)) { michael@0: TIMESTART(); michael@0: rv = (*cipherInfo->cipher.hashCipher)(cipherInfo->output.pBuf.data, michael@0: cipherInfo->input.pBuf.data, michael@0: cipherInfo->input.pBuf.len); michael@0: TIMEFINISH(cipherInfo->optime, 1.0); michael@0: CHECKERROR(rv, __LINE__); michael@0: cipherInfo->repetitions = 0; michael@0: if (cipherInfo->repetitionsToPerfom != 0) { michael@0: TIMESTART(); michael@0: for (i=0; irepetitionsToPerfom; michael@0: i++, cipherInfo->repetitions++) { michael@0: (*cipherInfo->cipher.hashCipher)(dummyOut, michael@0: cipherInfo->input.pBuf.data, michael@0: cipherInfo->input.pBuf.len); michael@0: CHECKERROR(rv, __LINE__); michael@0: } michael@0: } else { michael@0: int opsBetweenChecks = 0; michael@0: TIMEMARK(cipherInfo->seconds); michael@0: while (! (TIMETOFINISH())) { michael@0: int j = 0; michael@0: for (;j < opsBetweenChecks;j++) { michael@0: bltestIO *input = &cipherInfo->input; michael@0: (*cipherInfo->cipher.hashCipher)(dummyOut, michael@0: input->pBuf.data, michael@0: input->pBuf.len); michael@0: CHECKERROR(rv, __LINE__); michael@0: } michael@0: cipherInfo->repetitions += j; michael@0: } michael@0: } michael@0: TIMEFINISH(cipherInfo->optime, 1.0); michael@0: } michael@0: PORT_Free(dummyOut); michael@0: return rv; michael@0: } michael@0: michael@0: SECStatus michael@0: cipherFinish(bltestCipherInfo *cipherInfo) michael@0: { michael@0: SECStatus rv = SECSuccess; michael@0: michael@0: switch (cipherInfo->mode) { michael@0: case bltestDES_ECB: michael@0: case bltestDES_CBC: michael@0: case bltestDES_EDE_ECB: michael@0: case bltestDES_EDE_CBC: michael@0: DES_DestroyContext((DESContext *)cipherInfo->cx, PR_TRUE); michael@0: break; michael@0: case bltestAES_GCM: michael@0: case bltestAES_ECB: michael@0: case bltestAES_CBC: michael@0: case bltestAES_CTS: michael@0: case bltestAES_CTR: michael@0: AES_DestroyContext((AESContext *)cipherInfo->cx, PR_TRUE); michael@0: break; michael@0: case bltestCAMELLIA_ECB: michael@0: case bltestCAMELLIA_CBC: michael@0: Camellia_DestroyContext((CamelliaContext *)cipherInfo->cx, PR_TRUE); michael@0: break; michael@0: case bltestSEED_ECB: michael@0: case bltestSEED_CBC: michael@0: SEED_DestroyContext((SEEDContext *)cipherInfo->cx, PR_TRUE); michael@0: break; michael@0: case bltestRC2_ECB: michael@0: case bltestRC2_CBC: michael@0: RC2_DestroyContext((RC2Context *)cipherInfo->cx, PR_TRUE); michael@0: break; michael@0: case bltestRC4: michael@0: RC4_DestroyContext((RC4Context *)cipherInfo->cx, PR_TRUE); michael@0: break; michael@0: #ifdef NSS_SOFTOKEN_DOES_RC5 michael@0: case bltestRC5_ECB: michael@0: case bltestRC5_CBC: michael@0: RC5_DestroyContext((RC5Context *)cipherInfo->cx, PR_TRUE); michael@0: break; michael@0: #endif michael@0: case bltestRSA: /* keys are alloc'ed within cipherInfo's arena, */ michael@0: case bltestRSA_PSS: /* will be freed with it. */ michael@0: case bltestRSA_OAEP: michael@0: case bltestDSA: michael@0: #ifndef NSS_DISABLE_ECC michael@0: case bltestECDSA: michael@0: #endif michael@0: case bltestMD2: /* hash contexts are ephemeral */ michael@0: case bltestMD5: michael@0: case bltestSHA1: michael@0: case bltestSHA224: michael@0: case bltestSHA256: michael@0: case bltestSHA384: michael@0: case bltestSHA512: michael@0: return SECSuccess; michael@0: break; michael@0: default: michael@0: return SECFailure; michael@0: } michael@0: return rv; michael@0: } michael@0: michael@0: void michael@0: print_exponent(SECItem *exp) michael@0: { michael@0: int i; michael@0: int e = 0; michael@0: if (exp->len <= 4) { michael@0: for (i=exp->len; i >=0; --i) e |= exp->data[exp->len-i] << 8*(i-1); michael@0: fprintf(stdout, "%12d", e); michael@0: } else { michael@0: e = 8*exp->len; michael@0: fprintf(stdout, "~2**%-8d", e); michael@0: } michael@0: } michael@0: michael@0: static void michael@0: splitToReportUnit(PRInt64 res, int *resArr, int *del, int size) michael@0: { michael@0: PRInt64 remaining = res, tmp = 0; michael@0: PRInt64 Ldel; michael@0: int i = -1; michael@0: michael@0: while (remaining > 0 && ++i < size) { michael@0: LL_I2L(Ldel, del[i]); michael@0: LL_MOD(tmp, remaining, Ldel); michael@0: LL_L2I(resArr[i], tmp); michael@0: LL_DIV(remaining, remaining, Ldel); michael@0: } michael@0: } michael@0: michael@0: static char* michael@0: getHighUnitBytes(PRInt64 res) michael@0: { michael@0: int spl[] = {0, 0, 0, 0}; michael@0: int del[] = {1024, 1024, 1024, 1024}; michael@0: char *marks[] = {"b", "Kb", "Mb", "Gb"}; michael@0: int i = 3; michael@0: michael@0: splitToReportUnit(res, spl, del, 4); michael@0: michael@0: for (;i>0;i--) { michael@0: if (spl[i] != 0) { michael@0: break; michael@0: } michael@0: } michael@0: michael@0: return PR_smprintf("%d%s", spl[i], marks[i]); michael@0: } michael@0: michael@0: michael@0: static void michael@0: printPR_smpString(const char *sformat, char *reportStr, michael@0: const char *nformat, PRInt64 rNum) michael@0: { michael@0: if (reportStr) { michael@0: fprintf(stdout, sformat, reportStr); michael@0: PR_smprintf_free(reportStr); michael@0: } else { michael@0: int prnRes; michael@0: LL_L2I(prnRes, rNum); michael@0: fprintf(stdout, nformat, rNum); michael@0: } michael@0: } michael@0: michael@0: static char* michael@0: getHighUnitOps(PRInt64 res) michael@0: { michael@0: int spl[] = {0, 0, 0, 0}; michael@0: int del[] = {1000, 1000, 1000, 1000}; michael@0: char *marks[] = {"", "T", "M", "B"}; michael@0: int i = 3; michael@0: michael@0: splitToReportUnit(res, spl, del, 4); michael@0: michael@0: for (;i>0;i--) { michael@0: if (spl[i] != 0) { michael@0: break; michael@0: } michael@0: } michael@0: michael@0: return PR_smprintf("%d%s", spl[i], marks[i]); michael@0: } michael@0: michael@0: void michael@0: dump_performance_info(bltestCipherInfo *infoList, double totalTimeInt, michael@0: PRBool encrypt, PRBool cxonly) michael@0: { michael@0: bltestCipherInfo *info = infoList; michael@0: michael@0: PRInt64 totalIn = 0; michael@0: PRBool td = PR_TRUE; michael@0: michael@0: int repetitions = 0; michael@0: int cxreps = 0; michael@0: double cxtime = 0; michael@0: double optime = 0; michael@0: while (info != NULL) { michael@0: repetitions += info->repetitions; michael@0: cxreps += info->cxreps; michael@0: cxtime += info->cxtime; michael@0: optime += info->optime; michael@0: totalIn += (PRInt64) info->input.buf.len * (PRInt64) info->repetitions; michael@0: michael@0: info = info->next; michael@0: } michael@0: info = infoList; michael@0: michael@0: fprintf(stdout, "#%9s", "mode"); michael@0: fprintf(stdout, "%12s", "in"); michael@0: print_td: michael@0: switch (info->mode) { michael@0: case bltestDES_ECB: michael@0: case bltestDES_CBC: michael@0: case bltestDES_EDE_ECB: michael@0: case bltestDES_EDE_CBC: michael@0: case bltestAES_ECB: michael@0: case bltestAES_CBC: michael@0: case bltestAES_CTS: michael@0: case bltestAES_CTR: michael@0: case bltestAES_GCM: michael@0: case bltestCAMELLIA_ECB: michael@0: case bltestCAMELLIA_CBC: michael@0: case bltestSEED_ECB: michael@0: case bltestSEED_CBC: michael@0: case bltestRC2_ECB: michael@0: case bltestRC2_CBC: michael@0: case bltestRC4: michael@0: if (td) michael@0: fprintf(stdout, "%8s", "symmkey"); michael@0: else michael@0: fprintf(stdout, "%8d", 8*info->params.sk.key.buf.len); michael@0: break; michael@0: #ifdef NSS_SOFTOKEN_DOES_RC5 michael@0: case bltestRC5_ECB: michael@0: case bltestRC5_CBC: michael@0: if (info->params.sk.key.buf.len > 0) michael@0: printf("symmetric key(bytes)=%d,", info->params.sk.key.buf.len); michael@0: if (info->rounds > 0) michael@0: printf("rounds=%d,", info->params.rc5.rounds); michael@0: if (info->wordsize > 0) michael@0: printf("wordsize(bytes)=%d,", info->params.rc5.wordsize); michael@0: break; michael@0: #endif michael@0: case bltestRSA: michael@0: case bltestRSA_PSS: michael@0: case bltestRSA_OAEP: michael@0: if (td) { michael@0: fprintf(stdout, "%8s", "rsa_mod"); michael@0: fprintf(stdout, "%12s", "rsa_pe"); michael@0: } else { michael@0: bltestAsymKeyParams *asymk = &info->params.asymk; michael@0: fprintf(stdout, "%8d", asymk->cipherParams.rsa.keysizeInBits); michael@0: print_exponent( michael@0: &((RSAPrivateKey *)asymk->privKey)->publicExponent); michael@0: } michael@0: break; michael@0: case bltestDSA: michael@0: if (td) { michael@0: fprintf(stdout, "%8s", "pqg_mod"); michael@0: } else { michael@0: fprintf(stdout, "%8d", info->params.asymk.cipherParams.dsa.keysize); michael@0: } michael@0: break; michael@0: #ifndef NSS_DISABLE_ECC michael@0: case bltestECDSA: michael@0: if (td) { michael@0: fprintf(stdout, "%12s", "ec_curve"); michael@0: } else { michael@0: ECPrivateKey *key = (ECPrivateKey*)info->params.asymk.privKey; michael@0: ECCurveName curveName = key->ecParams.name; michael@0: fprintf(stdout, "%12s", michael@0: ecCurve_map[curveName]? ecCurve_map[curveName]->text: michael@0: "Unsupported curve"); michael@0: } michael@0: break; michael@0: #endif michael@0: case bltestMD2: michael@0: case bltestMD5: michael@0: case bltestSHA1: michael@0: case bltestSHA256: michael@0: case bltestSHA384: michael@0: case bltestSHA512: michael@0: default: michael@0: break; michael@0: } michael@0: if (!td) { michael@0: PRInt64 totalThroughPut; michael@0: michael@0: printPR_smpString("%8s", getHighUnitOps(repetitions), michael@0: "%8d", repetitions); michael@0: michael@0: printPR_smpString("%8s", getHighUnitOps(cxreps), "%8d", cxreps); michael@0: michael@0: fprintf(stdout, "%12.3f", cxtime); michael@0: fprintf(stdout, "%12.3f", optime); michael@0: fprintf(stdout, "%12.03f", totalTimeInt / 1000); michael@0: michael@0: totalThroughPut = (PRInt64)(totalIn / totalTimeInt * 1000); michael@0: printPR_smpString("%12s", getHighUnitBytes(totalThroughPut), michael@0: "%12d", totalThroughPut); michael@0: michael@0: fprintf(stdout, "\n"); michael@0: return; michael@0: } michael@0: michael@0: fprintf(stdout, "%8s", "opreps"); michael@0: fprintf(stdout, "%8s", "cxreps"); michael@0: fprintf(stdout, "%12s", "context"); michael@0: fprintf(stdout, "%12s", "op"); michael@0: fprintf(stdout, "%12s", "time(sec)"); michael@0: fprintf(stdout, "%12s", "thrgput"); michael@0: fprintf(stdout, "\n"); michael@0: fprintf(stdout, "%8s", mode_strings[info->mode]); michael@0: fprintf(stdout, "_%c", (cxonly) ? 'c' : (encrypt) ? 'e' : 'd'); michael@0: printPR_smpString("%12s", getHighUnitBytes(totalIn), "%12d", totalIn); michael@0: michael@0: td = !td; michael@0: goto print_td; michael@0: } michael@0: michael@0: void michael@0: printmodes() michael@0: { michael@0: bltestCipherMode mode; michael@0: int nummodes = sizeof(mode_strings) / sizeof(char *); michael@0: fprintf(stderr, "%s: Available modes (specify with -m):\n", progName); michael@0: for (mode=0; modemode = ioMode; michael@0: data->file = NULL; /* don't use -- not saving anything */ michael@0: data->pBuf.data = NULL; michael@0: data->pBuf.len = 0; michael@0: file = PR_Open(fn, PR_RDONLY, 00660); michael@0: if (file) { michael@0: setupIO(arena, data, file, NULL, 0); michael@0: PR_Close(file); michael@0: } michael@0: } michael@0: michael@0: HASH_HashType michael@0: mode_str_to_hash_alg(const SECItem *modeStr) michael@0: { michael@0: bltestCipherMode mode; michael@0: char* tempModeStr = NULL; michael@0: if (!modeStr || modeStr->len == 0) michael@0: return HASH_AlgNULL; michael@0: tempModeStr = PORT_Alloc(modeStr->len + 1); michael@0: if (!tempModeStr) michael@0: return HASH_AlgNULL; michael@0: memcpy(tempModeStr, modeStr->data, modeStr->len); michael@0: tempModeStr[modeStr->len] = '\0'; michael@0: mode = get_mode(tempModeStr); michael@0: PORT_Free(tempModeStr); michael@0: switch (mode) { michael@0: case bltestMD2: return HASH_AlgMD2; michael@0: case bltestMD5: return HASH_AlgMD5; michael@0: case bltestSHA1: return HASH_AlgSHA1; michael@0: case bltestSHA224: return HASH_AlgSHA224; michael@0: case bltestSHA256: return HASH_AlgSHA256; michael@0: case bltestSHA384: return HASH_AlgSHA384; michael@0: case bltestSHA512: return HASH_AlgSHA512; michael@0: } michael@0: return HASH_AlgNULL; michael@0: } michael@0: michael@0: void michael@0: get_params(PLArenaPool *arena, bltestParams *params, michael@0: bltestCipherMode mode, int j) michael@0: { michael@0: char filename[256]; michael@0: char *modestr = mode_strings[mode]; michael@0: bltestIO tempIO; michael@0: michael@0: #ifdef NSS_SOFTOKEN_DOES_RC5 michael@0: FILE *file; michael@0: char *mark, *param, *val; michael@0: int index = 0; michael@0: #endif michael@0: switch (mode) { michael@0: case bltestAES_GCM: michael@0: sprintf(filename, "%s/tests/%s/%s%d", testdir, modestr, "aad", j); michael@0: load_file_data(arena, ¶ms->ask.aad, filename, bltestBinary); michael@0: case bltestDES_CBC: michael@0: case bltestDES_EDE_CBC: michael@0: case bltestRC2_CBC: michael@0: case bltestAES_CBC: michael@0: case bltestAES_CTS: michael@0: case bltestAES_CTR: michael@0: case bltestCAMELLIA_CBC: michael@0: case bltestSEED_CBC: michael@0: sprintf(filename, "%s/tests/%s/%s%d", testdir, modestr, "iv", j); michael@0: load_file_data(arena, ¶ms->sk.iv, filename, bltestBinary); michael@0: case bltestDES_ECB: michael@0: case bltestDES_EDE_ECB: michael@0: case bltestRC2_ECB: michael@0: case bltestRC4: michael@0: case bltestAES_ECB: michael@0: case bltestCAMELLIA_ECB: michael@0: case bltestSEED_ECB: michael@0: sprintf(filename, "%s/tests/%s/%s%d", testdir, modestr, "key", j); michael@0: load_file_data(arena, ¶ms->sk.key, filename, bltestBinary); michael@0: break; michael@0: #ifdef NSS_SOFTOKEN_DOES_RC5 michael@0: case bltestRC5_ECB: michael@0: case bltestRC5_CBC: michael@0: sprintf(filename, "%s/tests/%s/%s%d", testdir, modestr, "iv", j); michael@0: load_file_data(arena, ¶ms->sk.iv, filename, bltestBinary); michael@0: sprintf(filename, "%s/tests/%s/%s%d", testdir, modestr, "key", j); michael@0: load_file_data(arena, ¶ms->sk.key, filename, bltestBinary); michael@0: sprintf(filename, "%s/tests/%s/%s%d", testdir, modestr, michael@0: "params", j); michael@0: file = fopen(filename, "r"); michael@0: if (!file) return; michael@0: param = malloc(100); michael@0: len = fread(param, 1, 100, file); michael@0: while (index < len) { michael@0: mark = PL_strchr(param, '='); michael@0: *mark = '\0'; michael@0: val = mark + 1; michael@0: mark = PL_strchr(val, '\n'); michael@0: *mark = '\0'; michael@0: if (PL_strcmp(param, "rounds") == 0) { michael@0: params->rc5.rounds = atoi(val); michael@0: } else if (PL_strcmp(param, "wordsize") == 0) { michael@0: params->rc5.wordsize = atoi(val); michael@0: } michael@0: index += PL_strlen(param) + PL_strlen(val) + 2; michael@0: param = mark + 1; michael@0: } michael@0: break; michael@0: #endif michael@0: case bltestRSA_PSS: michael@0: sprintf(filename, "%s/tests/%s/%s%d", testdir, modestr, "ciphertext", j); michael@0: load_file_data(arena, ¶ms->asymk.sig, filename, bltestBase64Encoded); michael@0: /* fall through */ michael@0: case bltestRSA_OAEP: michael@0: sprintf(filename, "%s/tests/%s/%s%d", testdir, modestr, "seed", j); michael@0: load_file_data(arena, ¶ms->asymk.cipherParams.rsa.seed, michael@0: filename, bltestBase64Encoded); michael@0: michael@0: sprintf(filename, "%s/tests/%s/%s%d", testdir, modestr, "hash", j); michael@0: load_file_data(arena, &tempIO, filename, bltestBinary); michael@0: params->asymk.cipherParams.rsa.hashAlg = michael@0: mode_str_to_hash_alg(&tempIO.buf); michael@0: michael@0: sprintf(filename, "%s/tests/%s/%s%d", testdir, modestr, "maskhash", j); michael@0: load_file_data(arena, &tempIO, filename, bltestBinary); michael@0: params->asymk.cipherParams.rsa.maskHashAlg = michael@0: mode_str_to_hash_alg(&tempIO.buf); michael@0: /* fall through */ michael@0: case bltestRSA: michael@0: sprintf(filename, "%s/tests/%s/%s%d", testdir, modestr, "key", j); michael@0: load_file_data(arena, ¶ms->asymk.key, filename, michael@0: bltestBase64Encoded); michael@0: params->asymk.privKey = michael@0: (void *)rsakey_from_filedata(¶ms->asymk.key.buf); michael@0: break; michael@0: case bltestDSA: michael@0: sprintf(filename, "%s/tests/%s/%s%d", testdir, modestr, "key", j); michael@0: load_file_data(arena, ¶ms->asymk.key, filename, bltestBase64Encoded); michael@0: params->asymk.privKey = michael@0: (void *)dsakey_from_filedata(¶ms->asymk.key.buf); michael@0: sprintf(filename, "%s/tests/%s/%s%d", testdir, modestr, "pqg", j); michael@0: load_file_data(arena, ¶ms->asymk.cipherParams.dsa.pqgdata, filename, michael@0: bltestBase64Encoded); michael@0: params->asymk.cipherParams.dsa.pqg = michael@0: pqg_from_filedata(¶ms->asymk.cipherParams.dsa.pqgdata.buf); michael@0: sprintf(filename, "%s/tests/%s/%s%d", testdir, modestr, "keyseed", j); michael@0: load_file_data(arena, ¶ms->asymk.cipherParams.dsa.keyseed, filename, michael@0: bltestBase64Encoded); michael@0: sprintf(filename, "%s/tests/%s/%s%d", testdir, modestr, "sigseed", j); michael@0: load_file_data(arena, ¶ms->asymk.cipherParams.dsa.sigseed, filename, michael@0: bltestBase64Encoded); michael@0: sprintf(filename, "%s/tests/%s/%s%d", testdir, modestr, "ciphertext",j); michael@0: load_file_data(arena, ¶ms->asymk.sig, filename, bltestBase64Encoded); michael@0: break; michael@0: #ifndef NSS_DISABLE_ECC michael@0: case bltestECDSA: michael@0: sprintf(filename, "%s/tests/%s/%s%d", testdir, modestr, "key", j); michael@0: load_file_data(arena, ¶ms->asymk.key, filename, bltestBase64Encoded); michael@0: params->asymk.privKey = michael@0: (void *)eckey_from_filedata(¶ms->asymk.key.buf); michael@0: sprintf(filename, "%s/tests/%s/%s%d", testdir, modestr, "sigseed", j); michael@0: load_file_data(arena, ¶ms->asymk.cipherParams.ecdsa.sigseed, michael@0: filename, bltestBase64Encoded); michael@0: sprintf(filename, "%s/tests/%s/%s%d", testdir, modestr, "ciphertext",j); michael@0: load_file_data(arena, ¶ms->asymk.sig, filename, bltestBase64Encoded); michael@0: break; michael@0: #endif michael@0: case bltestMD2: michael@0: case bltestMD5: michael@0: case bltestSHA1: michael@0: case bltestSHA224: michael@0: case bltestSHA256: michael@0: case bltestSHA384: michael@0: case bltestSHA512: michael@0: /*params->hash.restart = PR_TRUE;*/ michael@0: params->hash.restart = PR_FALSE; michael@0: break; michael@0: default: michael@0: break; michael@0: } michael@0: } michael@0: michael@0: SECStatus michael@0: verify_self_test(bltestIO *result, bltestIO *cmp, bltestCipherMode mode, michael@0: PRBool forward, SECStatus sigstatus) michael@0: { michael@0: PRBool equal; michael@0: char *modestr = mode_strings[mode]; michael@0: equal = SECITEM_ItemsAreEqual(&result->pBuf, &cmp->buf); michael@0: if (is_sigCipher(mode)) { michael@0: if (forward) { michael@0: if (equal) { michael@0: printf("Signature self-test for %s passed.\n", modestr); michael@0: } else { michael@0: printf("Signature self-test for %s failed!\n", modestr); michael@0: } michael@0: return equal ? SECSuccess : SECFailure; michael@0: } else { michael@0: if (sigstatus == SECSuccess) { michael@0: printf("Verification self-test for %s passed.\n", modestr); michael@0: } else { michael@0: printf("Verification self-test for %s failed!\n", modestr); michael@0: } michael@0: return sigstatus; michael@0: } michael@0: } else if (is_hashCipher(mode)) { michael@0: if (equal) { michael@0: printf("Hash self-test for %s passed.\n", modestr); michael@0: } else { michael@0: printf("Hash self-test for %s failed!\n", modestr); michael@0: } michael@0: } else { michael@0: if (forward) { michael@0: if (equal) { michael@0: printf("Encryption self-test for %s passed.\n", modestr); michael@0: } else { michael@0: printf("Encryption self-test for %s failed!\n", modestr); michael@0: } michael@0: } else { michael@0: if (equal) { michael@0: printf("Decryption self-test for %s passed.\n", modestr); michael@0: } else { michael@0: printf("Decryption self-test for %s failed!\n", modestr); michael@0: } michael@0: } michael@0: } michael@0: return equal ? SECSuccess : SECFailure; michael@0: } michael@0: michael@0: static SECStatus michael@0: ReadFileToItem(SECItem *dst, const char *filename) michael@0: { michael@0: PRFileDesc *file; michael@0: SECStatus rv; michael@0: michael@0: file = PR_Open(filename, PR_RDONLY, 00660); michael@0: if (!file) { michael@0: return SECFailure; michael@0: } michael@0: rv = SECU_FileToItem(dst, file); michael@0: PR_Close(file); michael@0: return rv; michael@0: } michael@0: michael@0: static SECStatus michael@0: blapi_selftest(bltestCipherMode *modes, int numModes, int inoff, int outoff, michael@0: PRBool encrypt, PRBool decrypt) michael@0: { michael@0: bltestCipherInfo cipherInfo; michael@0: bltestIO pt, ct; michael@0: bltestCipherMode mode; michael@0: bltestParams *params; michael@0: int i, j, nummodes, numtests; michael@0: char *modestr; michael@0: char filename[256]; michael@0: PLArenaPool *arena; michael@0: SECItem item; michael@0: SECStatus rv = SECSuccess, srv; michael@0: michael@0: PORT_Memset(&cipherInfo, 0, sizeof(cipherInfo)); michael@0: arena = PORT_NewArena(BLTEST_DEFAULT_CHUNKSIZE); michael@0: cipherInfo.arena = arena; michael@0: michael@0: nummodes = (numModes == 0) ? NUMMODES : numModes; michael@0: for (i=0; i < nummodes; i++) { michael@0: if (numModes > 0) michael@0: mode = modes[i]; michael@0: else michael@0: mode = i; michael@0: if (mode == bltestINVALID) { michael@0: fprintf(stderr, "%s: Skipping invalid mode.\n",progName); michael@0: continue; michael@0: } michael@0: modestr = mode_strings[mode]; michael@0: cipherInfo.mode = mode; michael@0: params = &cipherInfo.params; michael@0: /* get the number of tests in the directory */ michael@0: sprintf(filename, "%s/tests/%s/%s", testdir, modestr, "numtests"); michael@0: if (ReadFileToItem(&item, filename) != SECSuccess) { michael@0: fprintf(stderr, "%s: Cannot read file %s.\n", progName, filename); michael@0: rv = SECFailure; michael@0: continue; michael@0: } michael@0: /* loop over the tests in the directory */ michael@0: numtests = 0; michael@0: for (j=0; jasymk.sig, &cipherInfo.output); michael@0: } michael@0: } michael@0: if (!decrypt) michael@0: continue; michael@0: /* Reverse Operation (Decrypt/Verify) michael@0: ** Align the input buffer (ciphertext) according to request michael@0: ** then perform operation and compare to plaintext michael@0: */ michael@0: if (is_sigCipher(mode)) { michael@0: bltestCopyIO(arena, &cipherInfo.input, &pt); michael@0: bltestCopyIO(arena, &cipherInfo.output, ¶ms->asymk.sig); michael@0: } else { michael@0: bltestCopyIO(arena, &cipherInfo.input, &ct); michael@0: memset(&cipherInfo.output.buf, 0, sizeof cipherInfo.output.buf); michael@0: } michael@0: misalignBuffer(arena, &cipherInfo.input, inoff); michael@0: rv |= cipherInit(&cipherInfo, PR_FALSE); michael@0: misalignBuffer(arena, &cipherInfo.output, outoff); michael@0: srv = SECSuccess; michael@0: srv |= cipherDoOp(&cipherInfo); michael@0: rv |= cipherFinish(&cipherInfo); michael@0: rv |= verify_self_test(&cipherInfo.output, michael@0: &pt, mode, PR_FALSE, srv); michael@0: } michael@0: } michael@0: return rv; michael@0: } michael@0: michael@0: SECStatus michael@0: dump_file(bltestCipherMode mode, char *filename) michael@0: { michael@0: bltestIO keydata; michael@0: PLArenaPool *arena = NULL; michael@0: arena = PORT_NewArena(BLTEST_DEFAULT_CHUNKSIZE); michael@0: if (mode == bltestRSA || mode == bltestRSA_PSS || mode == bltestRSA_OAEP) { michael@0: RSAPrivateKey *key; michael@0: load_file_data(arena, &keydata, filename, bltestBase64Encoded); michael@0: key = rsakey_from_filedata(&keydata.buf); michael@0: dump_rsakey(key); michael@0: } else if (mode == bltestDSA) { michael@0: #if 0 michael@0: PQGParams *pqg; michael@0: get_file_data(filename, &item, PR_TRUE); michael@0: pqg = pqg_from_filedata(&item); michael@0: dump_pqg(pqg); michael@0: #endif michael@0: DSAPrivateKey *key; michael@0: load_file_data(arena, &keydata, filename, bltestBase64Encoded); michael@0: key = dsakey_from_filedata(&keydata.buf); michael@0: dump_dsakey(key); michael@0: #ifndef NSS_DISABLE_ECC michael@0: } else if (mode == bltestECDSA) { michael@0: ECPrivateKey *key; michael@0: load_file_data(arena, &keydata, filename, bltestBase64Encoded); michael@0: key = eckey_from_filedata(&keydata.buf); michael@0: dump_eckey(key); michael@0: #endif michael@0: } michael@0: PORT_FreeArena(arena, PR_FALSE); michael@0: return SECFailure; michael@0: } michael@0: michael@0: void ThreadExecTest(void *data) michael@0: { michael@0: bltestCipherInfo *cipherInfo = (bltestCipherInfo*)data; michael@0: michael@0: if (cipherInfo->mCarlo == PR_TRUE) { michael@0: int mciter; michael@0: for (mciter=0; mciter<10000; mciter++) { michael@0: cipherDoOp(cipherInfo); michael@0: memcpy(cipherInfo->input.buf.data, michael@0: cipherInfo->output.buf.data, michael@0: cipherInfo->input.buf.len); michael@0: } michael@0: } else { michael@0: cipherDoOp(cipherInfo); michael@0: } michael@0: cipherFinish(cipherInfo); michael@0: } michael@0: michael@0: static void rsaPrivKeyReset(RSAPrivateKey *tstKey) michael@0: { michael@0: PLArenaPool *arena; michael@0: michael@0: tstKey->version.data = NULL; michael@0: tstKey->version.len = 0; michael@0: tstKey->modulus.data = NULL; michael@0: tstKey->modulus.len = 0; michael@0: tstKey->publicExponent.data = NULL; michael@0: tstKey->publicExponent.len = 0; michael@0: tstKey->privateExponent.data = NULL; michael@0: tstKey->privateExponent.len = 0; michael@0: tstKey->prime1.data = NULL; michael@0: tstKey->prime1.len = 0; michael@0: tstKey->prime2.data = NULL; michael@0: tstKey->prime2.len = 0; michael@0: tstKey->exponent1.data = NULL; michael@0: tstKey->exponent1.len = 0; michael@0: tstKey->exponent2.data = NULL; michael@0: tstKey->exponent2.len = 0; michael@0: tstKey->coefficient.data = NULL; michael@0: tstKey->coefficient.len = 0; michael@0: michael@0: arena = tstKey->arena; michael@0: tstKey->arena = NULL; michael@0: if (arena) { michael@0: PORT_FreeArena(arena, PR_TRUE); michael@0: } michael@0: } michael@0: michael@0: michael@0: #define RSA_TEST_EQUAL(comp) \ michael@0: if (!SECITEM_ItemsAreEqual(&(src->comp),&(dest->comp))) { \ michael@0: fprintf(stderr, "key->" #comp " not equal"); \ michael@0: if (src->comp.len != dest->comp.len) { \ michael@0: fprintf(stderr, "src_len = %d, dest_len = %d", \ michael@0: src->comp.len, dest->comp.len); \ michael@0: } \ michael@0: fprintf(stderr, "\n"); \ michael@0: areEqual = PR_FALSE; \ michael@0: } michael@0: michael@0: michael@0: static PRBool rsaPrivKeysAreEqual(RSAPrivateKey *src, RSAPrivateKey *dest) michael@0: { michael@0: PRBool areEqual = PR_TRUE; michael@0: RSA_TEST_EQUAL(modulus) michael@0: RSA_TEST_EQUAL(publicExponent) michael@0: RSA_TEST_EQUAL(privateExponent) michael@0: RSA_TEST_EQUAL(prime1) michael@0: RSA_TEST_EQUAL(prime2) michael@0: RSA_TEST_EQUAL(exponent1) michael@0: RSA_TEST_EQUAL(exponent2) michael@0: RSA_TEST_EQUAL(coefficient) michael@0: if (!areEqual) { michael@0: fprintf(stderr, "original key:\n"); michael@0: dump_rsakey(src); michael@0: fprintf(stderr, "recreated key:\n"); michael@0: dump_rsakey(dest); michael@0: } michael@0: return areEqual; michael@0: } michael@0: michael@0: /* michael@0: * Test the RSA populate command to see that it can really build michael@0: * keys from it's components. michael@0: */ michael@0: static int doRSAPopulateTest(unsigned int keySize, unsigned long exponent) michael@0: { michael@0: RSAPrivateKey *srcKey; michael@0: RSAPrivateKey tstKey = { 0 }; michael@0: SECItem expitem = { 0, 0, 0 }; michael@0: SECStatus rv; michael@0: unsigned char pubExp[4]; michael@0: int expLen = 0; michael@0: int failed = 0; michael@0: int i; michael@0: michael@0: for (i=0; i < sizeof(unsigned long); i++) { michael@0: int shift = (sizeof(unsigned long) - i -1 ) * 8; michael@0: if (expLen || (exponent && ((unsigned long)0xffL << shift))) { michael@0: pubExp[expLen] = (unsigned char) ((exponent >> shift) & 0xff); michael@0: expLen++; michael@0: } michael@0: } michael@0: michael@0: expitem.data = pubExp; michael@0: expitem.len = expLen; michael@0: michael@0: srcKey = RSA_NewKey(keySize, &expitem); michael@0: if (srcKey == NULL) { michael@0: fprintf(stderr, "RSA Key Gen failed"); michael@0: return -1; michael@0: } michael@0: michael@0: /* test the basic case - most common, public exponent, modulus, prime */ michael@0: tstKey.arena = NULL; michael@0: rsaPrivKeyReset(&tstKey); michael@0: michael@0: tstKey.publicExponent = srcKey->publicExponent; michael@0: tstKey.modulus = srcKey->modulus; michael@0: tstKey.prime1 = srcKey->prime1; michael@0: michael@0: rv = RSA_PopulatePrivateKey(&tstKey); michael@0: if (rv != SECSuccess) { michael@0: fprintf(stderr, "RSA Populate failed: pubExp mod p\n"); michael@0: failed = 1; michael@0: } else if (!rsaPrivKeysAreEqual(&tstKey, srcKey)) { michael@0: fprintf(stderr, "RSA Populate key mismatch: pubExp mod p\n"); michael@0: failed = 1; michael@0: } michael@0: michael@0: /* test the basic2 case, public exponent, modulus, prime2 */ michael@0: rsaPrivKeyReset(&tstKey); michael@0: michael@0: tstKey.publicExponent = srcKey->publicExponent; michael@0: tstKey.modulus = srcKey->modulus; michael@0: tstKey.prime1 = srcKey->prime2; /* test with q in the prime1 position */ michael@0: michael@0: rv = RSA_PopulatePrivateKey(&tstKey); michael@0: if (rv != SECSuccess) { michael@0: fprintf(stderr, "RSA Populate failed: pubExp mod q\n"); michael@0: failed = 1; michael@0: } else if (!rsaPrivKeysAreEqual(&tstKey, srcKey)) { michael@0: fprintf(stderr, "RSA Populate key mismatch: pubExp mod q\n"); michael@0: failed = 1; michael@0: } michael@0: michael@0: /* test the medium case, private exponent, prime1, prime2 */ michael@0: rsaPrivKeyReset(&tstKey); michael@0: michael@0: tstKey.privateExponent = srcKey->privateExponent; michael@0: tstKey.prime1 = srcKey->prime2; /* purposefully swap them to make */ michael@0: tstKey.prime2 = srcKey->prime1; /* sure populated swaps them back */ michael@0: michael@0: rv = RSA_PopulatePrivateKey(&tstKey); michael@0: if (rv != SECSuccess) { michael@0: fprintf(stderr, "RSA Populate failed: privExp p q\n"); michael@0: failed = 1; michael@0: } else if (!rsaPrivKeysAreEqual(&tstKey, srcKey)) { michael@0: fprintf(stderr, "RSA Populate key mismatch: privExp p q\n"); michael@0: failed = 1; michael@0: } michael@0: michael@0: /* test the advanced case, public exponent, private exponent, prime2 */ michael@0: rsaPrivKeyReset(&tstKey); michael@0: michael@0: tstKey.privateExponent = srcKey->privateExponent; michael@0: tstKey.publicExponent = srcKey->publicExponent; michael@0: tstKey.prime2 = srcKey->prime2; /* use q in the prime2 position */ michael@0: michael@0: rv = RSA_PopulatePrivateKey(&tstKey); michael@0: if (rv != SECSuccess) { michael@0: fprintf(stderr, "RSA Populate failed: pubExp privExp q\n"); michael@0: fprintf(stderr, " - not fatal\n"); michael@0: /* it's possible that we can't uniquely determine the original key michael@0: * from just the exponents and prime. Populate returns an error rather michael@0: * than return the wrong key. */ michael@0: } else if (!rsaPrivKeysAreEqual(&tstKey, srcKey)) { michael@0: /* if we returned a key, it *must* be correct */ michael@0: fprintf(stderr, "RSA Populate key mismatch: pubExp privExp q\n"); michael@0: rv = RSA_PrivateKeyCheck(&tstKey); michael@0: failed = 1; michael@0: } michael@0: michael@0: /* test the advanced case2, public exponent, private exponent, modulus */ michael@0: rsaPrivKeyReset(&tstKey); michael@0: michael@0: tstKey.privateExponent = srcKey->privateExponent; michael@0: tstKey.publicExponent = srcKey->publicExponent; michael@0: tstKey.modulus = srcKey->modulus; michael@0: michael@0: rv = RSA_PopulatePrivateKey(&tstKey); michael@0: if (rv != SECSuccess) { michael@0: fprintf(stderr, "RSA Populate failed: pubExp privExp mod\n"); michael@0: failed = 1; michael@0: } else if (!rsaPrivKeysAreEqual(&tstKey, srcKey)) { michael@0: fprintf(stderr, "RSA Populate key mismatch: pubExp privExp mod\n"); michael@0: failed = 1; michael@0: } michael@0: michael@0: return failed ? -1 : 0; michael@0: } michael@0: michael@0: michael@0: michael@0: /* bltest commands */ michael@0: enum { michael@0: cmd_Decrypt = 0, michael@0: cmd_Encrypt, michael@0: cmd_FIPS, michael@0: cmd_Hash, michael@0: cmd_Nonce, michael@0: cmd_Dump, michael@0: cmd_RSAPopulate, michael@0: cmd_Sign, michael@0: cmd_SelfTest, michael@0: cmd_Verify michael@0: }; michael@0: michael@0: /* bltest options */ michael@0: enum { michael@0: opt_B64 = 0, michael@0: opt_BufSize, michael@0: opt_Restart, michael@0: opt_SelfTestDir, michael@0: opt_Exponent, michael@0: opt_SigFile, michael@0: opt_KeySize, michael@0: opt_Hex, michael@0: opt_Input, michael@0: opt_PQGFile, michael@0: opt_Key, michael@0: opt_HexWSpc, michael@0: opt_Mode, michael@0: #ifndef NSS_DISABLE_ECC michael@0: opt_CurveName, michael@0: #endif michael@0: opt_Output, michael@0: opt_Repetitions, michael@0: opt_ZeroBuf, michael@0: opt_Rounds, michael@0: opt_Seed, michael@0: opt_SigSeedFile, michael@0: opt_CXReps, michael@0: opt_IV, michael@0: opt_WordSize, michael@0: opt_UseSeed, michael@0: opt_UseSigSeed, michael@0: opt_SeedFile, michael@0: opt_AAD, michael@0: opt_InputOffset, michael@0: opt_OutputOffset, michael@0: opt_MonteCarlo, michael@0: opt_ThreadNum, michael@0: opt_SecondsToRun, michael@0: opt_CmdLine michael@0: }; michael@0: michael@0: static secuCommandFlag bltest_commands[] = michael@0: { michael@0: { /* cmd_Decrypt */ 'D', PR_FALSE, 0, PR_FALSE }, michael@0: { /* cmd_Encrypt */ 'E', PR_FALSE, 0, PR_FALSE }, michael@0: { /* cmd_FIPS */ 'F', PR_FALSE, 0, PR_FALSE }, michael@0: { /* cmd_Hash */ 'H', PR_FALSE, 0, PR_FALSE }, michael@0: { /* cmd_Nonce */ 'N', PR_FALSE, 0, PR_FALSE }, michael@0: { /* cmd_Dump */ 'P', PR_FALSE, 0, PR_FALSE }, michael@0: { /* cmd_RSAPopulate*/ 'R', PR_FALSE, 0, PR_FALSE }, michael@0: { /* cmd_Sign */ 'S', PR_FALSE, 0, PR_FALSE }, michael@0: { /* cmd_SelfTest */ 'T', PR_FALSE, 0, PR_FALSE }, michael@0: { /* cmd_Verify */ 'V', PR_FALSE, 0, PR_FALSE } michael@0: }; michael@0: michael@0: static secuCommandFlag bltest_options[] = michael@0: { michael@0: { /* opt_B64 */ 'a', PR_FALSE, 0, PR_FALSE }, michael@0: { /* opt_BufSize */ 'b', PR_TRUE, 0, PR_FALSE }, michael@0: { /* opt_Restart */ 'c', PR_FALSE, 0, PR_FALSE }, michael@0: { /* opt_SelfTestDir */ 'd', PR_TRUE, 0, PR_FALSE }, michael@0: { /* opt_Exponent */ 'e', PR_TRUE, 0, PR_FALSE }, michael@0: { /* opt_SigFile */ 'f', PR_TRUE, 0, PR_FALSE }, michael@0: { /* opt_KeySize */ 'g', PR_TRUE, 0, PR_FALSE }, michael@0: { /* opt_Hex */ 'h', PR_FALSE, 0, PR_FALSE }, michael@0: { /* opt_Input */ 'i', PR_TRUE, 0, PR_FALSE }, michael@0: { /* opt_PQGFile */ 'j', PR_TRUE, 0, PR_FALSE }, michael@0: { /* opt_Key */ 'k', PR_TRUE, 0, PR_FALSE }, michael@0: { /* opt_HexWSpc */ 'l', PR_FALSE, 0, PR_FALSE }, michael@0: { /* opt_Mode */ 'm', PR_TRUE, 0, PR_FALSE }, michael@0: #ifndef NSS_DISABLE_ECC michael@0: { /* opt_CurveName */ 'n', PR_TRUE, 0, PR_FALSE }, michael@0: #endif michael@0: { /* opt_Output */ 'o', PR_TRUE, 0, PR_FALSE }, michael@0: { /* opt_Repetitions */ 'p', PR_TRUE, 0, PR_FALSE }, michael@0: { /* opt_ZeroBuf */ 'q', PR_FALSE, 0, PR_FALSE }, michael@0: { /* opt_Rounds */ 'r', PR_TRUE, 0, PR_FALSE }, michael@0: { /* opt_Seed */ 's', PR_TRUE, 0, PR_FALSE }, michael@0: { /* opt_SigSeedFile */ 't', PR_TRUE, 0, PR_FALSE }, michael@0: { /* opt_CXReps */ 'u', PR_TRUE, 0, PR_FALSE }, michael@0: { /* opt_IV */ 'v', PR_TRUE, 0, PR_FALSE }, michael@0: { /* opt_WordSize */ 'w', PR_TRUE, 0, PR_FALSE }, michael@0: { /* opt_UseSeed */ 'x', PR_FALSE, 0, PR_FALSE }, michael@0: { /* opt_UseSigSeed */ 'y', PR_FALSE, 0, PR_FALSE }, michael@0: { /* opt_SeedFile */ 'z', PR_FALSE, 0, PR_FALSE }, michael@0: { /* opt_AAD */ 0 , PR_TRUE, 0, PR_FALSE, "aad" }, michael@0: { /* opt_InputOffset */ '1', PR_TRUE, 0, PR_FALSE }, michael@0: { /* opt_OutputOffset */ '2', PR_TRUE, 0, PR_FALSE }, michael@0: { /* opt_MonteCarlo */ '3', PR_FALSE, 0, PR_FALSE }, michael@0: { /* opt_ThreadNum */ '4', PR_TRUE, 0, PR_FALSE }, michael@0: { /* opt_SecondsToRun */ '5', PR_TRUE, 0, PR_FALSE }, michael@0: { /* opt_CmdLine */ '-', PR_FALSE, 0, PR_FALSE } michael@0: }; michael@0: michael@0: int main(int argc, char **argv) michael@0: { michael@0: char *infileName, *outfileName, *keyfileName, *ivfileName; michael@0: SECStatus rv = SECFailure; michael@0: michael@0: double totalTime; michael@0: PRIntervalTime time1, time2; michael@0: PRFileDesc *outfile = NULL; michael@0: bltestCipherInfo *cipherInfoListHead, *cipherInfo; michael@0: bltestIOMode ioMode; michael@0: int bufsize, exponent, curThrdNum; michael@0: #ifndef NSS_DISABLE_ECC michael@0: char *curveName = NULL; michael@0: #endif michael@0: int i, commandsEntered; michael@0: int inoff, outoff; michael@0: int threads = 1; michael@0: michael@0: secuCommand bltest; michael@0: bltest.numCommands = sizeof(bltest_commands) / sizeof(secuCommandFlag); michael@0: bltest.numOptions = sizeof(bltest_options) / sizeof(secuCommandFlag); michael@0: bltest.commands = bltest_commands; michael@0: bltest.options = bltest_options; michael@0: michael@0: progName = strrchr(argv[0], '/'); michael@0: if (!progName) michael@0: progName = strrchr(argv[0], '\\'); michael@0: progName = progName ? progName+1 : argv[0]; michael@0: michael@0: rv = NSS_InitializePRErrorTable(); michael@0: if (rv != SECSuccess) { michael@0: SECU_PrintPRandOSError(progName); michael@0: return -1; michael@0: } michael@0: rv = RNG_RNGInit(); michael@0: if (rv != SECSuccess) { michael@0: SECU_PrintPRandOSError(progName); michael@0: return -1; michael@0: } michael@0: rv = BL_Init(); michael@0: if (rv != SECSuccess) { michael@0: SECU_PrintPRandOSError(progName); michael@0: return -1; michael@0: } michael@0: RNG_SystemInfoForRNG(); michael@0: michael@0: michael@0: rv = SECU_ParseCommandLine(argc, argv, progName, &bltest); michael@0: if (rv == SECFailure) { michael@0: fprintf(stderr, "%s: command line parsing error!\n", progName); michael@0: goto print_usage; michael@0: } michael@0: rv = SECFailure; michael@0: michael@0: cipherInfo = PORT_ZNew(bltestCipherInfo); michael@0: cipherInfoListHead = cipherInfo; michael@0: /* set some defaults */ michael@0: infileName = outfileName = keyfileName = ivfileName = NULL; michael@0: michael@0: /* Check the number of commands entered on the command line. */ michael@0: commandsEntered = 0; michael@0: for (i=0; i 1 && michael@0: !(commandsEntered == 2 && bltest.commands[cmd_SelfTest].activated)) { michael@0: fprintf(stderr, "%s: one command at a time!\n", progName); michael@0: goto print_usage; michael@0: } michael@0: michael@0: if (commandsEntered == 0) { michael@0: fprintf(stderr, "%s: you must enter a command!\n", progName); michael@0: goto print_usage; michael@0: } michael@0: michael@0: michael@0: if (bltest.commands[cmd_Sign].activated) michael@0: bltest.commands[cmd_Encrypt].activated = PR_TRUE; michael@0: if (bltest.commands[cmd_Verify].activated) michael@0: bltest.commands[cmd_Decrypt].activated = PR_TRUE; michael@0: if (bltest.commands[cmd_Hash].activated) michael@0: bltest.commands[cmd_Encrypt].activated = PR_TRUE; michael@0: michael@0: inoff = outoff = 0; michael@0: if (bltest.options[opt_InputOffset].activated) michael@0: inoff = PORT_Atoi(bltest.options[opt_InputOffset].arg); michael@0: if (bltest.options[opt_OutputOffset].activated) michael@0: outoff = PORT_Atoi(bltest.options[opt_OutputOffset].arg); michael@0: michael@0: testdir = (bltest.options[opt_SelfTestDir].activated) ? michael@0: strdup(bltest.options[opt_SelfTestDir].arg) : "."; michael@0: michael@0: /* michael@0: * Handle three simple cases first michael@0: */ michael@0: michael@0: /* test the RSA_PopulatePrivateKey function */ michael@0: if (bltest.commands[cmd_RSAPopulate].activated) { michael@0: unsigned int keySize = 1024; michael@0: unsigned long exponent = 65537; michael@0: int rounds = 1; michael@0: int ret; michael@0: michael@0: if (bltest.options[opt_KeySize].activated) { michael@0: keySize = PORT_Atoi(bltest.options[opt_KeySize].arg); michael@0: } michael@0: if (bltest.options[opt_Rounds].activated) { michael@0: rounds = PORT_Atoi(bltest.options[opt_Rounds].arg); michael@0: } michael@0: if (bltest.options[opt_Exponent].activated) { michael@0: exponent = PORT_Atoi(bltest.options[opt_Exponent].arg); michael@0: } michael@0: michael@0: for (i=0; i < rounds; i++) { michael@0: printf("Running RSA Populate test round %d\n",i); michael@0: ret = doRSAPopulateTest(keySize,exponent); michael@0: if (ret != 0) { michael@0: break; michael@0: } michael@0: } michael@0: if (ret != 0) { michael@0: fprintf(stderr,"RSA Populate test round %d: FAILED\n",i); michael@0: } michael@0: return ret; michael@0: } michael@0: michael@0: /* Do BLAPI self-test */ michael@0: if (bltest.commands[cmd_SelfTest].activated) { michael@0: PRBool encrypt = PR_TRUE, decrypt = PR_TRUE; michael@0: /* user may specified a set of ciphers to test. parse them. */ michael@0: bltestCipherMode modesToTest[NUMMODES]; michael@0: int numModesToTest = 0; michael@0: char *tok, *str; michael@0: str = bltest.options[opt_Mode].arg; michael@0: while (str) { michael@0: tok = strchr(str, ','); michael@0: if (tok) *tok = '\0'; michael@0: modesToTest[numModesToTest++] = get_mode(str); michael@0: if (tok) { michael@0: *tok = ','; michael@0: str = tok + 1; michael@0: } else { michael@0: break; michael@0: } michael@0: } michael@0: if (bltest.commands[cmd_Decrypt].activated && michael@0: !bltest.commands[cmd_Encrypt].activated) michael@0: encrypt = PR_FALSE; michael@0: if (bltest.commands[cmd_Encrypt].activated && michael@0: !bltest.commands[cmd_Decrypt].activated) michael@0: decrypt = PR_FALSE; michael@0: rv = blapi_selftest(modesToTest, numModesToTest, inoff, outoff, michael@0: encrypt, decrypt); michael@0: PORT_Free(cipherInfo); michael@0: return rv == SECSuccess ? 0 : 1; michael@0: } michael@0: michael@0: /* Do FIPS self-test */ michael@0: if (bltest.commands[cmd_FIPS].activated) { michael@0: CK_RV ckrv = sftk_fipsPowerUpSelfTest(); michael@0: fprintf(stdout, "CK_RV: %ld.\n", ckrv); michael@0: PORT_Free(cipherInfo); michael@0: if (ckrv == CKR_OK) michael@0: return SECSuccess; michael@0: return SECFailure; michael@0: } michael@0: michael@0: /* michael@0: * Check command line arguments for Encrypt/Decrypt/Hash/Sign/Verify michael@0: */ michael@0: michael@0: if ((bltest.commands[cmd_Decrypt].activated || michael@0: bltest.commands[cmd_Verify].activated) && michael@0: bltest.options[opt_BufSize].activated) { michael@0: fprintf(stderr, "%s: Cannot use a nonce as input to decrypt/verify.\n", michael@0: progName); michael@0: goto print_usage; michael@0: } michael@0: michael@0: if (bltest.options[opt_Mode].activated) { michael@0: cipherInfo->mode = get_mode(bltest.options[opt_Mode].arg); michael@0: if (cipherInfo->mode == bltestINVALID) { michael@0: goto print_usage; michael@0: } michael@0: } else { michael@0: fprintf(stderr, "%s: You must specify a cipher mode with -m.\n", michael@0: progName); michael@0: goto print_usage; michael@0: } michael@0: michael@0: michael@0: if (bltest.options[opt_Repetitions].activated && michael@0: bltest.options[opt_SecondsToRun].activated) { michael@0: fprintf(stderr, "%s: Operation time should be defined in either " michael@0: "repetitions(-p) or seconds(-5) not both", michael@0: progName); michael@0: goto print_usage; michael@0: } michael@0: michael@0: if (bltest.options[opt_Repetitions].activated) { michael@0: cipherInfo->repetitionsToPerfom = michael@0: PORT_Atoi(bltest.options[opt_Repetitions].arg); michael@0: } else { michael@0: cipherInfo->repetitionsToPerfom = 0; michael@0: } michael@0: michael@0: if (bltest.options[opt_SecondsToRun].activated) { michael@0: cipherInfo->seconds = PORT_Atoi(bltest.options[opt_SecondsToRun].arg); michael@0: } else { michael@0: cipherInfo->seconds = 0; michael@0: } michael@0: michael@0: michael@0: if (bltest.options[opt_CXReps].activated) { michael@0: cipherInfo->cxreps = PORT_Atoi(bltest.options[opt_CXReps].arg); michael@0: } else { michael@0: cipherInfo->cxreps = 0; michael@0: } michael@0: michael@0: if (bltest.options[opt_ThreadNum].activated) { michael@0: threads = PORT_Atoi(bltest.options[opt_ThreadNum].arg); michael@0: if (threads <= 0) { michael@0: threads = 1; michael@0: } michael@0: } michael@0: michael@0: /* Dump a file (rsakey, dsakey, etc.) */ michael@0: if (bltest.commands[cmd_Dump].activated) { michael@0: rv = dump_file(cipherInfo->mode, bltest.options[opt_Input].arg); michael@0: PORT_Free(cipherInfo); michael@0: return rv; michael@0: } michael@0: michael@0: /* default input mode is binary */ michael@0: ioMode = (bltest.options[opt_B64].activated) ? bltestBase64Encoded : michael@0: (bltest.options[opt_Hex].activated) ? bltestHexStream : michael@0: (bltest.options[opt_HexWSpc].activated) ? bltestHexSpaceDelim : michael@0: bltestBinary; michael@0: michael@0: if (bltest.options[opt_Exponent].activated) michael@0: exponent = PORT_Atoi(bltest.options[opt_Exponent].arg); michael@0: else michael@0: exponent = 65537; michael@0: michael@0: #ifndef NSS_DISABLE_ECC michael@0: if (bltest.options[opt_CurveName].activated) michael@0: curveName = PORT_Strdup(bltest.options[opt_CurveName].arg); michael@0: else michael@0: curveName = NULL; michael@0: #endif michael@0: michael@0: if (bltest.commands[cmd_Verify].activated && michael@0: !bltest.options[opt_SigFile].activated) { michael@0: fprintf(stderr, "%s: You must specify a signature file with -f.\n", michael@0: progName); michael@0: michael@0: print_usage: michael@0: PORT_Free(cipherInfo); michael@0: Usage(); michael@0: } michael@0: michael@0: if (bltest.options[opt_MonteCarlo].activated) { michael@0: cipherInfo->mCarlo = PR_TRUE; michael@0: } else { michael@0: cipherInfo->mCarlo = PR_FALSE; michael@0: } michael@0: michael@0: for (curThrdNum = 0;curThrdNum < threads;curThrdNum++) { michael@0: int keysize = 0; michael@0: PRFileDesc *file = NULL, *infile; michael@0: bltestParams *params; michael@0: char *instr = NULL; michael@0: PLArenaPool *arena; michael@0: michael@0: if (curThrdNum > 0) { michael@0: bltestCipherInfo *newCInfo = PORT_ZNew(bltestCipherInfo); michael@0: if (!newCInfo) { michael@0: fprintf(stderr, "%s: Can not allocate memory.\n", progName); michael@0: goto exit_point; michael@0: } michael@0: newCInfo->mode = cipherInfo->mode; michael@0: newCInfo->mCarlo = cipherInfo->mCarlo; michael@0: newCInfo->repetitionsToPerfom = michael@0: cipherInfo->repetitionsToPerfom; michael@0: newCInfo->seconds = cipherInfo->seconds; michael@0: newCInfo->cxreps = cipherInfo->cxreps; michael@0: cipherInfo->next = newCInfo; michael@0: cipherInfo = newCInfo; michael@0: } michael@0: arena = PORT_NewArena(BLTEST_DEFAULT_CHUNKSIZE); michael@0: if (!arena) { michael@0: fprintf(stderr, "%s: Can not allocate memory.\n", progName); michael@0: goto exit_point; michael@0: } michael@0: cipherInfo->arena = arena; michael@0: params = &cipherInfo->params; michael@0: michael@0: /* Set up an encryption key. */ michael@0: keysize = 0; michael@0: file = NULL; michael@0: if (is_symmkeyCipher(cipherInfo->mode)) { michael@0: char *keystr = NULL; /* if key is on command line */ michael@0: if (bltest.options[opt_Key].activated) { michael@0: if (bltest.options[opt_CmdLine].activated) { michael@0: keystr = bltest.options[opt_Key].arg; michael@0: } else { michael@0: file = PR_Open(bltest.options[opt_Key].arg, michael@0: PR_RDONLY, 00660); michael@0: } michael@0: } else { michael@0: if (bltest.options[opt_KeySize].activated) michael@0: keysize = PORT_Atoi(bltest.options[opt_KeySize].arg); michael@0: else michael@0: keysize = 8; /* use 64-bit default (DES) */ michael@0: /* save the random key for reference */ michael@0: file = PR_Open("tmp.key", PR_WRONLY|PR_CREATE_FILE, 00660); michael@0: } michael@0: params->key.mode = ioMode; michael@0: setupIO(cipherInfo->arena, ¶ms->key, file, keystr, keysize); michael@0: if (file) michael@0: PR_Close(file); michael@0: } else if (is_pubkeyCipher(cipherInfo->mode)) { michael@0: if (bltest.options[opt_Key].activated) { michael@0: file = PR_Open(bltest.options[opt_Key].arg, PR_RDONLY, 00660); michael@0: } else { michael@0: if (bltest.options[opt_KeySize].activated) michael@0: keysize = PORT_Atoi(bltest.options[opt_KeySize].arg); michael@0: else michael@0: keysize = 64; /* use 512-bit default */ michael@0: file = PR_Open("tmp.key", PR_WRONLY|PR_CREATE_FILE, 00660); michael@0: } michael@0: params->key.mode = bltestBase64Encoded; michael@0: #ifndef NSS_DISABLE_ECC michael@0: pubkeyInitKey(cipherInfo, file, keysize, exponent, curveName); michael@0: #else michael@0: pubkeyInitKey(cipherInfo, file, keysize, exponent); michael@0: #endif michael@0: PR_Close(file); michael@0: } michael@0: michael@0: /* set up an initialization vector. */ michael@0: if (cipher_requires_IV(cipherInfo->mode)) { michael@0: char *ivstr = NULL; michael@0: bltestSymmKeyParams *skp; michael@0: file = NULL; michael@0: #ifdef NSS_SOFTOKEN_DOES_RC5 michael@0: if (cipherInfo->mode == bltestRC5_CBC) michael@0: skp = (bltestSymmKeyParams *)¶ms->rc5; michael@0: else michael@0: #endif michael@0: skp = ¶ms->sk; michael@0: if (bltest.options[opt_IV].activated) { michael@0: if (bltest.options[opt_CmdLine].activated) { michael@0: ivstr = bltest.options[opt_IV].arg; michael@0: } else { michael@0: file = PR_Open(bltest.options[opt_IV].arg, michael@0: PR_RDONLY, 00660); michael@0: } michael@0: } else { michael@0: /* save the random iv for reference */ michael@0: file = PR_Open("tmp.iv", PR_WRONLY|PR_CREATE_FILE, 00660); michael@0: } michael@0: memset(&skp->iv, 0, sizeof skp->iv); michael@0: skp->iv.mode = ioMode; michael@0: setupIO(cipherInfo->arena, &skp->iv, file, ivstr, keysize); michael@0: if (file) { michael@0: PR_Close(file); michael@0: } michael@0: } michael@0: michael@0: /* set up an initialization vector. */ michael@0: if (is_authCipher(cipherInfo->mode)) { michael@0: char *aadstr = NULL; michael@0: bltestAuthSymmKeyParams *askp; michael@0: file = NULL; michael@0: askp = ¶ms->ask; michael@0: if (bltest.options[opt_AAD].activated) { michael@0: if (bltest.options[opt_CmdLine].activated) { michael@0: aadstr = bltest.options[opt_AAD].arg; michael@0: } else { michael@0: file = PR_Open(bltest.options[opt_AAD].arg, michael@0: PR_RDONLY, 00660); michael@0: } michael@0: } else { michael@0: file = NULL; michael@0: } michael@0: memset(&askp->aad, 0, sizeof askp->aad); michael@0: askp->aad.mode = ioMode; michael@0: setupIO(cipherInfo->arena, &askp->aad, file, aadstr, 0); michael@0: if (file) { michael@0: PR_Close(file); michael@0: } michael@0: } michael@0: michael@0: if (bltest.commands[cmd_Verify].activated) { michael@0: file = PR_Open(bltest.options[opt_SigFile].arg, PR_RDONLY, 00660); michael@0: if (is_sigCipher(cipherInfo->mode)) { michael@0: memset(¶ms->asymk.sig, 0, sizeof(bltestIO)); michael@0: params->asymk.sig.mode = ioMode; michael@0: setupIO(cipherInfo->arena, ¶ms->asymk.sig, file, NULL, 0); michael@0: } michael@0: if (file) { michael@0: PR_Close(file); michael@0: } michael@0: } michael@0: michael@0: if (bltest.options[opt_PQGFile].activated) { michael@0: file = PR_Open(bltest.options[opt_PQGFile].arg, PR_RDONLY, 00660); michael@0: params->asymk.cipherParams.dsa.pqgdata.mode = bltestBase64Encoded; michael@0: setupIO(cipherInfo->arena, ¶ms->asymk.cipherParams.dsa.pqgdata, michael@0: file, NULL, 0); michael@0: if (file) { michael@0: PR_Close(file); michael@0: } michael@0: } michael@0: michael@0: /* Set up the input buffer */ michael@0: if (bltest.options[opt_Input].activated) { michael@0: if (bltest.options[opt_CmdLine].activated) { michael@0: instr = bltest.options[opt_Input].arg; michael@0: infile = NULL; michael@0: } else { michael@0: /* form file name from testdir and input arg. */ michael@0: char * filename = bltest.options[opt_Input].arg; michael@0: if (bltest.options[opt_SelfTestDir].activated && michael@0: testdir && filename && filename[0] != '/') { michael@0: filename = PR_smprintf("%s/tests/%s/%s", testdir, michael@0: mode_strings[cipherInfo->mode], michael@0: filename); michael@0: if (!filename) { michael@0: fprintf(stderr, "%s: Can not allocate memory.\n", michael@0: progName); michael@0: goto exit_point; michael@0: } michael@0: infile = PR_Open(filename, PR_RDONLY, 00660); michael@0: PR_smprintf_free(filename); michael@0: } else { michael@0: infile = PR_Open(filename, PR_RDONLY, 00660); michael@0: } michael@0: } michael@0: } else if (bltest.options[opt_BufSize].activated) { michael@0: /* save the random plaintext for reference */ michael@0: char *tmpFName = PR_smprintf("tmp.in.%d", curThrdNum); michael@0: if (!tmpFName) { michael@0: fprintf(stderr, "%s: Can not allocate memory.\n", progName); michael@0: goto exit_point; michael@0: } michael@0: infile = PR_Open(tmpFName, PR_WRONLY|PR_CREATE_FILE, 00660); michael@0: PR_smprintf_free(tmpFName); michael@0: } else { michael@0: infile = PR_STDIN; michael@0: } michael@0: if (!infile) { michael@0: fprintf(stderr, "%s: Failed to open input file.\n", progName); michael@0: goto exit_point; michael@0: } michael@0: cipherInfo->input.mode = ioMode; michael@0: michael@0: /* Set up the output stream */ michael@0: if (bltest.options[opt_Output].activated) { michael@0: /* form file name from testdir and input arg. */ michael@0: char * filename = bltest.options[opt_Output].arg; michael@0: if (bltest.options[opt_SelfTestDir].activated && michael@0: testdir && filename && filename[0] != '/') { michael@0: filename = PR_smprintf("%s/tests/%s/%s", testdir, michael@0: mode_strings[cipherInfo->mode], michael@0: filename); michael@0: if (!filename) { michael@0: fprintf(stderr, "%s: Can not allocate memory.\n", progName); michael@0: goto exit_point; michael@0: } michael@0: outfile = PR_Open(filename, PR_WRONLY|PR_CREATE_FILE, 00660); michael@0: PR_smprintf_free(filename); michael@0: } else { michael@0: outfile = PR_Open(filename, PR_WRONLY|PR_CREATE_FILE, 00660); michael@0: } michael@0: } else { michael@0: outfile = PR_STDOUT; michael@0: } michael@0: if (!outfile) { michael@0: fprintf(stderr, "%s: Failed to open output file.\n", progName); michael@0: rv = SECFailure; michael@0: goto exit_point; michael@0: } michael@0: cipherInfo->output.mode = ioMode; michael@0: if (bltest.options[opt_SelfTestDir].activated && ioMode == bltestBinary) michael@0: cipherInfo->output.mode = bltestBase64Encoded; michael@0: michael@0: if (is_hashCipher(cipherInfo->mode)) michael@0: cipherInfo->params.hash.restart = michael@0: bltest.options[opt_Restart].activated; michael@0: michael@0: bufsize = 0; michael@0: if (bltest.options[opt_BufSize].activated) michael@0: bufsize = PORT_Atoi(bltest.options[opt_BufSize].arg); michael@0: michael@0: /*infile = NULL;*/ michael@0: setupIO(cipherInfo->arena, &cipherInfo->input, infile, instr, bufsize); michael@0: if (infile && infile != PR_STDIN) michael@0: PR_Close(infile); michael@0: misalignBuffer(cipherInfo->arena, &cipherInfo->input, inoff); michael@0: michael@0: cipherInit(cipherInfo, bltest.commands[cmd_Encrypt].activated); michael@0: misalignBuffer(cipherInfo->arena, &cipherInfo->output, outoff); michael@0: } michael@0: michael@0: if (!bltest.commands[cmd_Nonce].activated) { michael@0: TIMESTART(); michael@0: cipherInfo = cipherInfoListHead; michael@0: while (cipherInfo != NULL) { michael@0: cipherInfo->cipherThread = michael@0: PR_CreateThread(PR_USER_THREAD, michael@0: ThreadExecTest, michael@0: cipherInfo, michael@0: PR_PRIORITY_NORMAL, michael@0: PR_GLOBAL_THREAD, michael@0: PR_JOINABLE_THREAD, michael@0: 0); michael@0: cipherInfo = cipherInfo->next; michael@0: } michael@0: michael@0: cipherInfo = cipherInfoListHead; michael@0: while (cipherInfo != NULL) { michael@0: PR_JoinThread(cipherInfo->cipherThread); michael@0: finishIO(&cipherInfo->output, outfile); michael@0: cipherInfo = cipherInfo->next; michael@0: } michael@0: TIMEFINISH(totalTime, 1); michael@0: } michael@0: michael@0: cipherInfo = cipherInfoListHead; michael@0: if (cipherInfo->repetitions > 0 || cipherInfo->cxreps > 0 || michael@0: threads > 1) michael@0: dump_performance_info(cipherInfoListHead, totalTime, michael@0: bltest.commands[cmd_Encrypt].activated, michael@0: (cipherInfo->repetitions == 0)); michael@0: michael@0: rv = SECSuccess; michael@0: michael@0: exit_point: michael@0: if (outfile && outfile != PR_STDOUT) michael@0: PR_Close(outfile); michael@0: cipherInfo = cipherInfoListHead; michael@0: while (cipherInfo != NULL) { michael@0: bltestCipherInfo *tmpInfo = cipherInfo; michael@0: michael@0: if (cipherInfo->arena) michael@0: PORT_FreeArena(cipherInfo->arena, PR_TRUE); michael@0: cipherInfo = cipherInfo->next; michael@0: PORT_Free(tmpInfo); michael@0: } michael@0: michael@0: /*NSS_Shutdown();*/ michael@0: michael@0: return SECSuccess; michael@0: } michael@0: