2
* The contents of this file are subject to the Mozilla Public
3
* License Version 1.1 (the "License"); you may not use this file
4
* except in compliance with the License. You may obtain a copy of
5
* the License at http://www.mozilla.org/MPL/
7
* Software distributed under the License is distributed on an "AS
8
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
9
* implied. See the License for the specific language governing
10
* rights and limitations under the License.
12
* The Original Code is the Netscape security libraries.
14
* The Initial Developer of the Original Code is Netscape
15
* Communications Corporation. Portions created by Netscape are
16
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
20
* Douglas Stebila <douglas@stebila.ca>, Sun Microsystems Laboratories
22
* Alternatively, the contents of this file may be used under the
23
* terms of the GNU General Public License Version 2 or later (the
24
* "GPL"), in which case the provisions of the GPL are applicable
25
* instead of those above. If you wish to allow use of your
26
* version of this file only under the terms of the GPL and not to
27
* allow others to use your version of this file under the MPL,
28
* indicate your decision by deleting the provisions above and
29
* replace them with the notice and other provisions required by
30
* the GPL. If you do not delete the provisions above, a recipient
31
* may use your version of this file under either the MPL or the
52
#include "ecl-curve.h"
53
SECStatus EC_DecodeParams(const SECItem *encodedParams,
55
SECStatus EC_CopyParams(PRArenaPool *arena, ECParams *dstParams,
56
const ECParams *srcParams);
57
SECStatus secoid_Init(void);
60
/* Temporary - add debugging ouput on windows for RSA to track QA failure */
62
#define TRACK_BLTEST_BUG
63
char __bltDBG[] = "BLTEST DEBUG";
69
#define BLTEST_DEFAULT_CHUNKSIZE 4096
71
#define WORDSIZE sizeof(unsigned long)
73
#define CHECKERROR(rv, ln) \
75
PRErrorCode prerror = PR_GetError(); \
76
PR_fprintf(PR_STDERR, "%s: ERR %d (%s) at line %d.\n", progName, \
77
prerror, SECU_Strerror(prerror), ln); \
81
/* Macros for performance timing. */
83
time1 = PR_IntervalNow();
85
#define TIMEFINISH(time, reps) \
86
time2 = (PRIntervalTime)(PR_IntervalNow() - time1); \
87
time1 = PR_IntervalToMilliseconds(time2); \
88
time = ((double)(time1))/reps;
92
#define PRINTUSAGE(subject, option, predicate) \
93
fprintf(stderr, "%10s %s\t%s\n", subject, option, predicate);
94
fprintf(stderr, "\n");
95
PRINTUSAGE(progName, "[-DEHSV]", "List available cipher modes"); /* XXX */
96
fprintf(stderr, "\n");
97
PRINTUSAGE(progName, "-E -m mode ", "Encrypt a buffer");
98
PRINTUSAGE("", "", "[-i plaintext] [-o ciphertext] [-k key] [-v iv]");
99
PRINTUSAGE("", "", "[-b bufsize] [-g keysize] [-e exp] [-r rounds]");
100
PRINTUSAGE("", "", "[-w wordsize] [-p repetitions]");
101
PRINTUSAGE("", "-m", "cipher mode to use");
102
PRINTUSAGE("", "-i", "file which contains input buffer");
103
PRINTUSAGE("", "-o", "file for output buffer");
104
PRINTUSAGE("", "-k", "file which contains key");
105
PRINTUSAGE("", "-v", "file which contains initialization vector");
106
PRINTUSAGE("", "-b", "size of input buffer");
107
PRINTUSAGE("", "-g", "key size (in bytes)");
108
PRINTUSAGE("", "-p", "do performance test");
109
PRINTUSAGE("(rsa)", "-e", "rsa public exponent");
110
PRINTUSAGE("(rc5)", "-r", "number of rounds");
111
PRINTUSAGE("(rc5)", "-w", "wordsize (32 or 64)");
112
fprintf(stderr, "\n");
113
PRINTUSAGE(progName, "-D -m mode", "Decrypt a buffer");
114
PRINTUSAGE("", "", "[-i plaintext] [-o ciphertext] [-k key] [-v iv]");
115
PRINTUSAGE("", "", "[-p repetitions]");
116
PRINTUSAGE("", "-m", "cipher mode to use");
117
PRINTUSAGE("", "-i", "file which contains input buffer");
118
PRINTUSAGE("", "-o", "file for output buffer");
119
PRINTUSAGE("", "-k", "file which contains key");
120
PRINTUSAGE("", "-v", "file which contains initialization vector");
121
PRINTUSAGE("", "-p", "do performance test");
122
fprintf(stderr, "\n");
123
PRINTUSAGE(progName, "-H -m mode", "Hash a buffer");
124
PRINTUSAGE("", "", "[-i plaintext] [-o hash]");
125
PRINTUSAGE("", "", "[-b bufsize]");
126
PRINTUSAGE("", "", "[-p repetitions]");
127
PRINTUSAGE("", "-m", "cipher mode to use");
128
PRINTUSAGE("", "-i", "file which contains input buffer");
129
PRINTUSAGE("", "-o", "file for hash");
130
PRINTUSAGE("", "-b", "size of input buffer");
131
PRINTUSAGE("", "-p", "do performance test");
132
fprintf(stderr, "\n");
133
PRINTUSAGE(progName, "-S -m mode", "Sign a buffer");
134
PRINTUSAGE("", "", "[-i plaintext] [-o signature] [-k key]");
135
PRINTUSAGE("", "", "[-b bufsize]");
136
#ifdef NSS_ENABLE_ECC
137
PRINTUSAGE("", "", "[-n curvename]");
139
PRINTUSAGE("", "", "[-p repetitions]");
140
PRINTUSAGE("", "-m", "cipher mode to use");
141
PRINTUSAGE("", "-i", "file which contains input buffer");
142
PRINTUSAGE("", "-o", "file for signature");
143
PRINTUSAGE("", "-k", "file which contains key");
144
#ifdef NSS_ENABLE_ECC
145
PRINTUSAGE("", "-n", "name of curve for EC key generation; one of:");
146
PRINTUSAGE("", "", " sect163k1, nistk163, sect163r1, sect163r2,");
147
PRINTUSAGE("", "", " nistb163, sect193r1, sect193r2, sect233k1, nistk233,");
148
PRINTUSAGE("", "", " sect233r1, nistb233, sect239k1, sect283k1, nistk283,");
149
PRINTUSAGE("", "", " sect283r1, nistb283, sect409k1, nistk409, sect409r1,");
150
PRINTUSAGE("", "", " nistb409, sect571k1, nistk571, sect571r1, nistb571,");
151
PRINTUSAGE("", "", " secp169k1, secp160r1, secp160r2, secp192k1, secp192r1,");
152
PRINTUSAGE("", "", " nistp192, secp224k1, secp224r1, nistp224, secp256k1,");
153
PRINTUSAGE("", "", " secp256r1, nistp256, secp384r1, nistp384, secp521r1,");
154
PRINTUSAGE("", "", " nistp521, prime192v1, prime192v2, prime192v3,");
155
PRINTUSAGE("", "", " prime239v1, prime239v2, prime239v3, c2pnb163v1,");
156
PRINTUSAGE("", "", " c2pnb163v2, c2pnb163v3, c2pnb176v1, c2tnb191v1,");
157
PRINTUSAGE("", "", " c2tnb191v2, c2tnb191v3, c2onb191v4, c2onb191v5,");
158
PRINTUSAGE("", "", " c2pnb208w1, c2tnb239v1, c2tnb239v2, c2tnb239v3,");
159
PRINTUSAGE("", "", " c2onb239v4, c2onb239v5, c2pnb272w1, c2pnb304w1,");
160
PRINTUSAGE("", "", " c2tnb359w1, c2pnb368w1, c2tnb431r1, secp112r1,");
161
PRINTUSAGE("", "", " secp112r2, secp128r1, secp128r2, sect113r1, sect113r2,");
162
PRINTUSAGE("", "", " sect131r1, sect131r2");
164
PRINTUSAGE("", "-p", "do performance test");
165
fprintf(stderr, "\n");
166
PRINTUSAGE(progName, "-V -m mode", "Verify a signed buffer");
167
PRINTUSAGE("", "", "[-i plaintext] [-s signature] [-k key]");
168
PRINTUSAGE("", "", "[-p repetitions]");
169
PRINTUSAGE("", "-m", "cipher mode to use");
170
PRINTUSAGE("", "-i", "file which contains input buffer");
171
PRINTUSAGE("", "-s", "file which contains signature of input buffer");
172
PRINTUSAGE("", "-k", "file which contains key");
173
PRINTUSAGE("", "-p", "do performance test");
174
fprintf(stderr, "\n");
175
PRINTUSAGE(progName, "-N -m mode -b bufsize",
176
"Create a nonce plaintext and key");
177
PRINTUSAGE("", "", "[-g keysize] [-u cxreps]");
178
PRINTUSAGE("", "-g", "key size (in bytes)");
179
PRINTUSAGE("", "-u", "number of repetitions of context creation");
180
fprintf(stderr, "\n");
181
PRINTUSAGE(progName, "-F", "Run the FIPS self-test");
182
fprintf(stderr, "\n");
183
PRINTUSAGE(progName, "-T [-m mode1,mode2...]", "Run the BLAPI self-test");
184
fprintf(stderr, "\n");
188
/* Helper functions for ascii<-->binary conversion/reading/writing */
191
struct item_with_arena {
197
get_binary(void *arg, const unsigned char *ibuf, PRInt32 size)
199
struct item_with_arena *it = arg;
200
SECItem *binary = it->item;
203
if (binary->data == NULL) {
204
tmp = SECITEM_AllocItem(it->arena, NULL, size);
205
binary->data = tmp->data;
206
binary->len = tmp->len;
209
SECITEM_ReallocItem(NULL, binary, binary->len, binary->len + size);
212
PORT_Memcpy(&binary->data[index], ibuf, size);
217
atob(SECItem *ascii, SECItem *binary, PRArenaPool *arena)
220
NSSBase64Decoder *cx;
221
struct item_with_arena it;
227
len = (strcmp(&ascii->data[ascii->len-2],"\r\n")) ?
228
ascii->len : ascii->len-2;
229
cx = NSSBase64Decoder_Create(get_binary, &it);
230
status = NSSBase64Decoder_Update(cx, (const char *)ascii->data, len);
231
status = NSSBase64Decoder_Destroy(cx, PR_FALSE);
236
output_ascii(void *arg, const char *obuf, PRInt32 size)
238
PRFileDesc *outfile = arg;
239
PRInt32 nb = PR_Write(outfile, obuf, size);
241
PORT_SetError(SEC_ERROR_IO);
248
btoa_file(SECItem *binary, PRFileDesc *outfile)
251
NSSBase64Encoder *cx;
255
if (binary->len == 0)
257
cx = NSSBase64Encoder_Create(output_ascii, outfile);
258
status = NSSBase64Encoder_Update(cx, binary->data, binary->len);
259
status = NSSBase64Encoder_Destroy(cx, PR_FALSE);
260
status = PR_Write(outfile, "\r\n", 2);
265
hex_from_2char(unsigned char *c2, unsigned char *byteval)
268
unsigned char offset;
270
for (i=0; i<2; i++) {
271
if (c2[i] >= '0' && c2[i] <= '9') {
272
offset = c2[i] - '0';
273
*byteval |= offset << 4*(1-i);
274
} else if (c2[i] >= 'a' && c2[i] <= 'f') {
275
offset = c2[i] - 'a';
276
*byteval |= (offset + 10) << 4*(1-i);
277
} else if (c2[i] >= 'A' && c2[i] <= 'F') {
278
offset = c2[i] - 'A';
279
*byteval |= (offset + 10) << 4*(1-i);
288
char2_from_hex(unsigned char byteval, unsigned char *c2)
291
unsigned char offset;
292
for (i=0; i<2; i++) {
293
offset = (byteval >> 4*(1-i)) & 0x0f;
295
c2[i] = '0' + offset;
297
c2[i] = 'A' + offset - 10;
304
serialize_key(SECItem *it, int ni, PRFileDesc *file)
306
unsigned char len[4];
309
NSSBase64Encoder *cx;
313
cx = NSSBase64Encoder_Create(output_ascii, file);
314
for (i=0; i<ni; i++, it++) {
315
len[0] = (it->len >> 24) & 0xff;
316
len[1] = (it->len >> 16) & 0xff;
317
len[2] = (it->len >> 8) & 0xff;
318
len[3] = (it->len & 0xff);
319
status = NSSBase64Encoder_Update(cx, len, 4);
320
status = NSSBase64Encoder_Update(cx, it->data, it->len);
322
status = NSSBase64Encoder_Destroy(cx, PR_FALSE);
323
status = PR_Write(file, "\r\n", 2);
327
key_from_filedata(PRArenaPool *arena, SECItem *it, int ns, int ni, SECItem *filedata)
331
unsigned char *buf = filedata->data;
332
for (i=0; i<ni; i++) {
333
len = (buf[fpos++] & 0xff) << 24;
334
len |= (buf[fpos++] & 0xff) << 16;
335
len |= (buf[fpos++] & 0xff) << 8;
336
len |= (buf[fpos++] & 0xff);
340
it->data = PORT_ArenaAlloc(arena, it->len);
341
PORT_Memcpy(it->data, &buf[fpos], it->len);
352
static RSAPrivateKey *
353
rsakey_from_filedata(SECItem *filedata)
357
arena = PORT_NewArena(BLTEST_DEFAULT_CHUNKSIZE);
358
key = (RSAPrivateKey *)PORT_ArenaZAlloc(arena, sizeof(RSAPrivateKey));
360
key_from_filedata(arena, &key->version, 0, 9, filedata);
365
pqg_from_filedata(SECItem *filedata)
369
arena = PORT_NewArena(BLTEST_DEFAULT_CHUNKSIZE);
370
pqg = (PQGParams *)PORT_ArenaZAlloc(arena, sizeof(PQGParams));
372
key_from_filedata(arena, &pqg->prime, 0, 3, filedata);
376
static DSAPrivateKey *
377
dsakey_from_filedata(SECItem *filedata)
381
arena = PORT_NewArena(BLTEST_DEFAULT_CHUNKSIZE);
382
key = (DSAPrivateKey *)PORT_ArenaZAlloc(arena, sizeof(DSAPrivateKey));
383
key->params.arena = arena;
384
key_from_filedata(arena, &key->params.prime, 0, 5, filedata);
388
#ifdef NSS_ENABLE_ECC
389
static ECPrivateKey *
390
eckey_from_filedata(SECItem *filedata)
395
ECParams *tmpECParams = NULL;
396
arena = PORT_NewArena(BLTEST_DEFAULT_CHUNKSIZE);
397
key = (ECPrivateKey *)PORT_ArenaZAlloc(arena, sizeof(ECPrivateKey));
398
/* read and convert params */
399
key->ecParams.arena = arena;
400
key_from_filedata(arena, &key->ecParams.DEREncoding, 0, 1, filedata);
402
CHECKERROR(rv, __LINE__);
403
rv = EC_DecodeParams(&key->ecParams.DEREncoding, &tmpECParams);
404
CHECKERROR(rv, __LINE__);
405
rv = EC_CopyParams(key->ecParams.arena, &key->ecParams, tmpECParams);
406
CHECKERROR(rv, __LINE__);
407
rv = SECOID_Shutdown();
408
CHECKERROR(rv, __LINE__);
409
PORT_FreeArena(tmpECParams->arena, PR_TRUE);
411
key_from_filedata(arena, &key->publicValue, 1, 3, filedata);
415
typedef struct curveNameTagPairStr {
417
SECOidTag curveOidTag;
420
#define DEFAULT_CURVE_OID_TAG SEC_OID_SECG_EC_SECP192R1
421
/* #define DEFAULT_CURVE_OID_TAG SEC_OID_SECG_EC_SECP160R1 */
423
static CurveNameTagPair nameTagPair[] =
425
{ "sect163k1", SEC_OID_SECG_EC_SECT163K1},
426
{ "nistk163", SEC_OID_SECG_EC_SECT163K1},
427
{ "sect163r1", SEC_OID_SECG_EC_SECT163R1},
428
{ "sect163r2", SEC_OID_SECG_EC_SECT163R2},
429
{ "nistb163", SEC_OID_SECG_EC_SECT163R2},
430
{ "sect193r1", SEC_OID_SECG_EC_SECT193R1},
431
{ "sect193r2", SEC_OID_SECG_EC_SECT193R2},
432
{ "sect233k1", SEC_OID_SECG_EC_SECT233K1},
433
{ "nistk233", SEC_OID_SECG_EC_SECT233K1},
434
{ "sect233r1", SEC_OID_SECG_EC_SECT233R1},
435
{ "nistb233", SEC_OID_SECG_EC_SECT233R1},
436
{ "sect239k1", SEC_OID_SECG_EC_SECT239K1},
437
{ "sect283k1", SEC_OID_SECG_EC_SECT283K1},
438
{ "nistk283", SEC_OID_SECG_EC_SECT283K1},
439
{ "sect283r1", SEC_OID_SECG_EC_SECT283R1},
440
{ "nistb283", SEC_OID_SECG_EC_SECT283R1},
441
{ "sect409k1", SEC_OID_SECG_EC_SECT409K1},
442
{ "nistk409", SEC_OID_SECG_EC_SECT409K1},
443
{ "sect409r1", SEC_OID_SECG_EC_SECT409R1},
444
{ "nistb409", SEC_OID_SECG_EC_SECT409R1},
445
{ "sect571k1", SEC_OID_SECG_EC_SECT571K1},
446
{ "nistk571", SEC_OID_SECG_EC_SECT571K1},
447
{ "sect571r1", SEC_OID_SECG_EC_SECT571R1},
448
{ "nistb571", SEC_OID_SECG_EC_SECT571R1},
449
{ "secp160k1", SEC_OID_SECG_EC_SECP160K1},
450
{ "secp160r1", SEC_OID_SECG_EC_SECP160R1},
451
{ "secp160r2", SEC_OID_SECG_EC_SECP160R2},
452
{ "secp192k1", SEC_OID_SECG_EC_SECP192K1},
453
{ "secp192r1", SEC_OID_SECG_EC_SECP192R1},
454
{ "nistp192", SEC_OID_SECG_EC_SECP192R1},
455
{ "secp224k1", SEC_OID_SECG_EC_SECP224K1},
456
{ "secp224r1", SEC_OID_SECG_EC_SECP224R1},
457
{ "nistp224", SEC_OID_SECG_EC_SECP224R1},
458
{ "secp256k1", SEC_OID_SECG_EC_SECP256K1},
459
{ "secp256r1", SEC_OID_SECG_EC_SECP256R1},
460
{ "nistp256", SEC_OID_SECG_EC_SECP256R1},
461
{ "secp384r1", SEC_OID_SECG_EC_SECP384R1},
462
{ "nistp384", SEC_OID_SECG_EC_SECP384R1},
463
{ "secp521r1", SEC_OID_SECG_EC_SECP521R1},
464
{ "nistp521", SEC_OID_SECG_EC_SECP521R1},
466
{ "prime192v1", SEC_OID_ANSIX962_EC_PRIME192V1 },
467
{ "prime192v2", SEC_OID_ANSIX962_EC_PRIME192V2 },
468
{ "prime192v3", SEC_OID_ANSIX962_EC_PRIME192V3 },
469
{ "prime239v1", SEC_OID_ANSIX962_EC_PRIME239V1 },
470
{ "prime239v2", SEC_OID_ANSIX962_EC_PRIME239V2 },
471
{ "prime239v3", SEC_OID_ANSIX962_EC_PRIME239V3 },
473
{ "c2pnb163v1", SEC_OID_ANSIX962_EC_C2PNB163V1 },
474
{ "c2pnb163v2", SEC_OID_ANSIX962_EC_C2PNB163V2 },
475
{ "c2pnb163v3", SEC_OID_ANSIX962_EC_C2PNB163V3 },
476
{ "c2pnb176v1", SEC_OID_ANSIX962_EC_C2PNB176V1 },
477
{ "c2tnb191v1", SEC_OID_ANSIX962_EC_C2TNB191V1 },
478
{ "c2tnb191v2", SEC_OID_ANSIX962_EC_C2TNB191V2 },
479
{ "c2tnb191v3", SEC_OID_ANSIX962_EC_C2TNB191V3 },
480
{ "c2onb191v4", SEC_OID_ANSIX962_EC_C2ONB191V4 },
481
{ "c2onb191v5", SEC_OID_ANSIX962_EC_C2ONB191V5 },
482
{ "c2pnb208w1", SEC_OID_ANSIX962_EC_C2PNB208W1 },
483
{ "c2tnb239v1", SEC_OID_ANSIX962_EC_C2TNB239V1 },
484
{ "c2tnb239v2", SEC_OID_ANSIX962_EC_C2TNB239V2 },
485
{ "c2tnb239v3", SEC_OID_ANSIX962_EC_C2TNB239V3 },
486
{ "c2onb239v4", SEC_OID_ANSIX962_EC_C2ONB239V4 },
487
{ "c2onb239v5", SEC_OID_ANSIX962_EC_C2ONB239V5 },
488
{ "c2pnb272w1", SEC_OID_ANSIX962_EC_C2PNB272W1 },
489
{ "c2pnb304w1", SEC_OID_ANSIX962_EC_C2PNB304W1 },
490
{ "c2tnb359v1", SEC_OID_ANSIX962_EC_C2TNB359V1 },
491
{ "c2pnb368w1", SEC_OID_ANSIX962_EC_C2PNB368W1 },
492
{ "c2tnb431r1", SEC_OID_ANSIX962_EC_C2TNB431R1 },
494
{ "secp112r1", SEC_OID_SECG_EC_SECP112R1},
495
{ "secp112r2", SEC_OID_SECG_EC_SECP112R2},
496
{ "secp128r1", SEC_OID_SECG_EC_SECP128R1},
497
{ "secp128r2", SEC_OID_SECG_EC_SECP128R2},
499
{ "sect113r1", SEC_OID_SECG_EC_SECT113R1},
500
{ "sect113r2", SEC_OID_SECG_EC_SECT113R2},
501
{ "sect131r1", SEC_OID_SECG_EC_SECT131R1},
502
{ "sect131r2", SEC_OID_SECG_EC_SECT131R2},
505
static SECKEYECParams *
506
getECParams(char *curve)
508
SECKEYECParams *ecparams;
509
SECOidData *oidData = NULL;
510
SECOidTag curveOidTag = SEC_OID_UNKNOWN; /* default */
514
numCurves = sizeof(nameTagPair)/sizeof(CurveNameTagPair);
515
for (i = 0; ((i < numCurves) && (curveOidTag == SEC_OID_UNKNOWN));
517
if (PL_strcmp(curve, nameTagPair[i].curveName) == 0)
518
curveOidTag = nameTagPair[i].curveOidTag;
522
/* Return NULL if curve name is not recognized */
523
if ((curveOidTag == SEC_OID_UNKNOWN) ||
524
(oidData = SECOID_FindOIDByTag(curveOidTag)) == NULL) {
525
fprintf(stderr, "Unrecognized elliptic curve %s\n", curve);
529
ecparams = SECITEM_AllocItem(NULL, NULL, (2 + oidData->oid.len));
532
* ecparams->data needs to contain the ASN encoding of an object ID (OID)
533
* representing the named curve. The actual OID is in
534
* oidData->oid.data so we simply prepend 0x06 and OID length
536
ecparams->data[0] = SEC_ASN1_OBJECT_ID;
537
ecparams->data[1] = oidData->oid.len;
538
memcpy(ecparams->data + 2, oidData->oid.data, oidData->oid.len);
542
#endif /* NSS_ENABLE_ECC */
545
dump_pqg(PQGParams *pqg)
547
SECU_PrintInteger(stdout, &pqg->prime, "PRIME:", 0);
548
SECU_PrintInteger(stdout, &pqg->subPrime, "SUBPRIME:", 0);
549
SECU_PrintInteger(stdout, &pqg->base, "BASE:", 0);
553
dump_dsakey(DSAPrivateKey *key)
555
dump_pqg(&key->params);
556
SECU_PrintInteger(stdout, &key->publicValue, "PUBLIC VALUE:", 0);
557
SECU_PrintInteger(stdout, &key->privateValue, "PRIVATE VALUE:", 0);
560
#ifdef NSS_ENABLE_ECC
562
dump_ecp(ECParams *ecp)
564
/* TODO other fields */
565
SECU_PrintInteger(stdout, &ecp->base, "BASE POINT:", 0);
569
dump_eckey(ECPrivateKey *key)
571
dump_ecp(&key->ecParams);
572
SECU_PrintInteger(stdout, &key->publicValue, "PUBLIC VALUE:", 0);
573
SECU_PrintInteger(stdout, &key->privateValue, "PRIVATE VALUE:", 0);
578
dump_rsakey(RSAPrivateKey *key)
580
SECU_PrintInteger(stdout, &key->version, "VERSION:", 0);
581
SECU_PrintInteger(stdout, &key->modulus, "MODULUS:", 0);
582
SECU_PrintInteger(stdout, &key->publicExponent, "PUBLIC EXP:", 0);
583
SECU_PrintInteger(stdout, &key->privateExponent, "PRIVATE EXP:", 0);
584
SECU_PrintInteger(stdout, &key->prime1, "CRT PRIME 1:", 0);
585
SECU_PrintInteger(stdout, &key->prime2, "CRT PRIME 2:", 0);
586
SECU_PrintInteger(stdout, &key->exponent1, "CRT EXP 1:", 0);
587
SECU_PrintInteger(stdout, &key->exponent2, "CRT EXP 2:", 0);
588
SECU_PrintInteger(stdout, &key->coefficient, "CRT COEFFICIENT:", 0);
592
bltestBase64Encoded, /* Base64 encoded ASCII */
593
bltestBinary, /* straight binary */
594
bltestHexSpaceDelim, /* 0x12 0x34 0xab 0xCD ... */
595
bltestHexStream /* 1234abCD ... */
606
typedef SECStatus (* bltestSymmCipherFn)(void *cx,
607
unsigned char *output,
608
unsigned int *outputLen,
609
unsigned int maxOutputLen,
610
const unsigned char *input,
611
unsigned int inputLen);
613
typedef SECStatus (* bltestPubKeyCipherFn)(void *key,
615
const SECItem *input);
617
typedef SECStatus (* bltestHashCipherFn)(unsigned char *dest,
618
const unsigned char *src,
623
bltestDES_ECB, /* Symmetric Key Ciphers */
624
bltestDES_CBC, /* . */
625
bltestDES_EDE_ECB, /* . */
626
bltestDES_EDE_CBC, /* . */
627
bltestRC2_ECB, /* . */
628
bltestRC2_CBC, /* . */
630
bltestRC5_ECB, /* . */
631
bltestRC5_CBC, /* . */
632
bltestAES_ECB, /* . */
633
bltestAES_CBC, /* . */
634
bltestRSA, /* Public Key Ciphers */
635
#ifdef NSS_ENABLE_ECC
636
bltestECDSA, /* . (Public Key Sig.) */
639
bltestMD2, /* Hash algorithms */
642
bltestSHA256, /* . */
643
bltestSHA384, /* . */
644
bltestSHA512, /* . */
648
static char *mode_strings[] =
662
#ifdef NSS_ENABLE_ECC
679
} bltestSymmKeyParams;
693
RSAPrivateKey *rsakey;
703
bltestIO sig; /* if doing verify, have additional input */
705
DSAPrivateKey *dsakey;
708
#ifdef NSS_ENABLE_ECC
714
bltestIO sig; /* if doing verify, have additional input */
721
bltestIO key; /* unused */
728
bltestSymmKeyParams sk;
732
#ifdef NSS_ENABLE_ECC
733
bltestECDSAParams ecdsa;
735
bltestHashParams hash;
746
/* Cipher-specific parameters */
749
bltestCipherMode mode;
750
/* Cipher function (encrypt/decrypt/sign/verify/hash) */
752
bltestSymmCipherFn symmkeyCipher;
753
bltestPubKeyCipherFn pubkeyCipher;
754
bltestHashCipherFn hashCipher;
756
/* performance testing */
764
is_symmkeyCipher(bltestCipherMode mode)
766
/* change as needed! */
767
if (mode >= bltestDES_ECB && mode <= bltestAES_CBC)
773
is_pubkeyCipher(bltestCipherMode mode)
775
/* change as needed! */
776
if (mode >= bltestRSA && mode <= bltestDSA)
782
is_hashCipher(bltestCipherMode mode)
784
/* change as needed! */
785
if (mode >= bltestMD2 && mode <= bltestSHA512)
791
is_sigCipher(bltestCipherMode mode)
793
/* change as needed! */
794
#ifdef NSS_ENABLE_ECC
795
if (mode >= bltestECDSA && mode <= bltestDSA)
797
if (mode >= bltestDSA && mode <= bltestDSA)
804
cipher_requires_IV(bltestCipherMode mode)
806
/* change as needed! */
807
if (mode == bltestDES_CBC || mode == bltestDES_EDE_CBC ||
808
mode == bltestRC2_CBC || mode == bltestRC5_CBC ||
809
mode == bltestAES_CBC)
814
SECStatus finishIO(bltestIO *output, PRFileDesc *file);
817
setupIO(PRArenaPool *arena, bltestIO *input, PRFileDesc *file,
818
char *str, int numBytes)
820
SECStatus rv = SECSuccess;
826
if (file && (numBytes == 0 || file == PR_STDIN)) {
827
/* grabbing data from a file */
828
rv = SECU_FileToItem(&fileData, file);
829
if (rv != SECSuccess) {
835
/* grabbing data from command line */
837
fileData.len = PL_strlen(str);
841
SECITEM_AllocItem(arena, &input->buf, numBytes);
842
RNG_GenerateGlobalRandomBytes(input->buf.data, numBytes);
843
return finishIO(input, file);
848
switch (input->mode) {
849
case bltestBase64Encoded:
850
rv = atob(in, &input->buf, arena);
853
if (in->data[in->len-1] == '\n') --in->len;
854
if (in->data[in->len-1] == '\r') --in->len;
855
SECITEM_CopyItem(arena, &input->buf, in);
857
case bltestHexSpaceDelim:
858
SECITEM_AllocItem(arena, &input->buf, in->len/5);
859
for (i=0, j=0; i<in->len; i+=5, j++) {
861
if (tok[0] != '0' || tok[1] != 'x' || tok[4] != ' ')
865
rv = hex_from_2char(&tok[2], input->buf.data + j);
870
case bltestHexStream:
871
SECITEM_AllocItem(arena, &input->buf, in->len/2);
872
for (i=0, j=0; i<in->len; i+=2, j++) {
874
rv = hex_from_2char(tok, input->buf.data + j);
882
SECITEM_FreeItem(&fileData, PR_FALSE);
887
finishIO(bltestIO *output, PRFileDesc *file)
889
SECStatus rv = SECSuccess;
891
unsigned char byteval;
895
if (output->pBuf.len > 0) {
900
switch (output->mode) {
901
case bltestBase64Encoded:
902
rv = btoa_file(it, file);
905
nb = PR_Write(file, it->data, it->len);
906
rv = (nb == (PRInt32)it->len) ? SECSuccess : SECFailure;
908
case bltestHexSpaceDelim:
912
for (i=0; i<it->len; i++) {
913
byteval = it->data[i];
914
rv = char2_from_hex(byteval, hexstr + 2);
915
nb = PR_Write(file, hexstr, 5);
919
PR_Write(file, "\n", 1);
921
case bltestHexStream:
922
for (i=0; i<it->len; i++) {
923
byteval = it->data[i];
924
rv = char2_from_hex(byteval, hexstr);
927
nb = PR_Write(file, hexstr, 2);
929
PR_Write(file, "\n", 1);
936
bltestCopyIO(PRArenaPool *arena, bltestIO *dest, bltestIO *src)
938
SECITEM_CopyItem(arena, &dest->buf, &src->buf);
939
if (src->pBuf.len > 0) {
940
dest->pBuf.len = src->pBuf.len;
941
dest->pBuf.data = dest->buf.data + (src->pBuf.data - src->buf.data);
943
dest->mode = src->mode;
944
dest->file = src->file;
948
misalignBuffer(PRArenaPool *arena, bltestIO *io, int off)
950
ptrdiff_t offset = (ptrdiff_t)io->buf.data % WORDSIZE;
951
int length = io->buf.len;
953
SECITEM_ReallocItem(arena, &io->buf, length, length + 2*WORDSIZE);
954
io->buf.len = length + 2*WORDSIZE; /* why doesn't realloc do this? */
955
/* offset may have changed? */
956
offset = (ptrdiff_t)io->buf.data % WORDSIZE;
958
memmove(io->buf.data + off, io->buf.data, length);
959
io->pBuf.data = io->buf.data + off;
960
io->pBuf.len = length;
962
io->pBuf.data = io->buf.data;
963
io->pBuf.len = length;
966
io->pBuf.data = io->buf.data;
967
io->pBuf.len = length;
972
des_Encrypt(void *cx, unsigned char *output, unsigned int *outputLen,
973
unsigned int maxOutputLen, const unsigned char *input,
974
unsigned int inputLen)
976
return DES_Encrypt((DESContext *)cx, output, outputLen, maxOutputLen,
981
des_Decrypt(void *cx, unsigned char *output, unsigned int *outputLen,
982
unsigned int maxOutputLen, const unsigned char *input,
983
unsigned int inputLen)
985
return DES_Decrypt((DESContext *)cx, output, outputLen, maxOutputLen,
990
rc2_Encrypt(void *cx, unsigned char *output, unsigned int *outputLen,
991
unsigned int maxOutputLen, const unsigned char *input,
992
unsigned int inputLen)
994
return RC2_Encrypt((RC2Context *)cx, output, outputLen, maxOutputLen,
999
rc2_Decrypt(void *cx, unsigned char *output, unsigned int *outputLen,
1000
unsigned int maxOutputLen, const unsigned char *input,
1001
unsigned int inputLen)
1003
return RC2_Decrypt((RC2Context *)cx, output, outputLen, maxOutputLen,
1008
rc4_Encrypt(void *cx, unsigned char *output, unsigned int *outputLen,
1009
unsigned int maxOutputLen, const unsigned char *input,
1010
unsigned int inputLen)
1012
return RC4_Encrypt((RC4Context *)cx, output, outputLen, maxOutputLen,
1017
rc4_Decrypt(void *cx, unsigned char *output, unsigned int *outputLen,
1018
unsigned int maxOutputLen, const unsigned char *input,
1019
unsigned int inputLen)
1021
return RC4_Decrypt((RC4Context *)cx, output, outputLen, maxOutputLen,
1026
aes_Encrypt(void *cx, unsigned char *output, unsigned int *outputLen,
1027
unsigned int maxOutputLen, const unsigned char *input,
1028
unsigned int inputLen)
1030
return AES_Encrypt((AESContext *)cx, output, outputLen, maxOutputLen,
1035
aes_Decrypt(void *cx, unsigned char *output, unsigned int *outputLen,
1036
unsigned int maxOutputLen, const unsigned char *input,
1037
unsigned int inputLen)
1039
return AES_Decrypt((AESContext *)cx, output, outputLen, maxOutputLen,
1044
rsa_PublicKeyOp(void *key, SECItem *output, const SECItem *input)
1046
return RSA_PublicKeyOp((RSAPublicKey *)key, output->data, input->data);
1050
rsa_PrivateKeyOp(void *key, SECItem *output, const SECItem *input)
1052
return RSA_PrivateKeyOp((RSAPrivateKey *)key, output->data, input->data);
1056
dsa_signDigest(void *key, SECItem *output, const SECItem *input)
1058
return DSA_SignDigest((DSAPrivateKey *)key, output, input);
1062
dsa_verifyDigest(void *key, SECItem *output, const SECItem *input)
1064
return DSA_VerifyDigest((DSAPublicKey *)key, output, input);
1067
#ifdef NSS_ENABLE_ECC
1069
ecdsa_signDigest(void *key, SECItem *output, const SECItem *input)
1071
return ECDSA_SignDigest((ECPrivateKey *)key, output, input);
1075
ecdsa_verifyDigest(void *key, SECItem *output, const SECItem *input)
1077
return ECDSA_VerifyDigest((ECPublicKey *)key, output, input);
1082
bltest_des_init(bltestCipherInfo *cipherInfo, PRBool encrypt)
1084
PRIntervalTime time1, time2;
1085
bltestSymmKeyParams *desp = &cipherInfo->params.sk;
1088
switch (cipherInfo->mode) {
1089
case bltestDES_ECB: minorMode = NSS_DES; break;
1090
case bltestDES_CBC: minorMode = NSS_DES_CBC; break;
1091
case bltestDES_EDE_ECB: minorMode = NSS_DES_EDE3; break;
1092
case bltestDES_EDE_CBC: minorMode = NSS_DES_EDE3_CBC; break;
1096
cipherInfo->cx = (void*)DES_CreateContext(desp->key.buf.data,
1098
minorMode, encrypt);
1099
if (cipherInfo->cxreps > 0) {
1100
DESContext **dummycx;
1101
dummycx = PORT_Alloc(cipherInfo->cxreps * sizeof(DESContext *));
1103
for (i=0; i<cipherInfo->cxreps; i++) {
1104
dummycx[i] = (void*)DES_CreateContext(desp->key.buf.data,
1106
minorMode, encrypt);
1108
TIMEFINISH(cipherInfo->cxtime, 1.0);
1109
for (i=0; i<cipherInfo->cxreps; i++) {
1110
DES_DestroyContext(dummycx[i], PR_TRUE);
1115
cipherInfo->cipher.symmkeyCipher = des_Encrypt;
1117
cipherInfo->cipher.symmkeyCipher = des_Decrypt;
1122
bltest_rc2_init(bltestCipherInfo *cipherInfo, PRBool encrypt)
1124
PRIntervalTime time1, time2;
1125
bltestSymmKeyParams *rc2p = &cipherInfo->params.sk;
1128
switch (cipherInfo->mode) {
1129
case bltestRC2_ECB: minorMode = NSS_RC2; break;
1130
case bltestRC2_CBC: minorMode = NSS_RC2_CBC; break;
1134
cipherInfo->cx = (void*)RC2_CreateContext(rc2p->key.buf.data,
1139
if (cipherInfo->cxreps > 0) {
1140
RC2Context **dummycx;
1141
dummycx = PORT_Alloc(cipherInfo->cxreps * sizeof(RC2Context *));
1143
for (i=0; i<cipherInfo->cxreps; i++) {
1144
dummycx[i] = (void*)RC2_CreateContext(rc2p->key.buf.data,
1150
TIMEFINISH(cipherInfo->cxtime, 1.0);
1151
for (i=0; i<cipherInfo->cxreps; i++) {
1152
RC2_DestroyContext(dummycx[i], PR_TRUE);
1157
cipherInfo->cipher.symmkeyCipher = rc2_Encrypt;
1159
cipherInfo->cipher.symmkeyCipher = rc2_Decrypt;
1164
bltest_rc4_init(bltestCipherInfo *cipherInfo, PRBool encrypt)
1166
PRIntervalTime time1, time2;
1168
bltestSymmKeyParams *rc4p = &cipherInfo->params.sk;
1169
cipherInfo->cx = (void*)RC4_CreateContext(rc4p->key.buf.data,
1171
if (cipherInfo->cxreps > 0) {
1172
RC4Context **dummycx;
1173
dummycx = PORT_Alloc(cipherInfo->cxreps * sizeof(RC4Context *));
1175
for (i=0; i<cipherInfo->cxreps; i++) {
1176
dummycx[i] = (void*)RC4_CreateContext(rc4p->key.buf.data,
1179
TIMEFINISH(cipherInfo->cxtime, 1.0);
1180
for (i=0; i<cipherInfo->cxreps; i++) {
1181
RC4_DestroyContext(dummycx[i], PR_TRUE);
1186
cipherInfo->cipher.symmkeyCipher = rc4_Encrypt;
1188
cipherInfo->cipher.symmkeyCipher = rc4_Decrypt;
1193
bltest_rc5_init(bltestCipherInfo *cipherInfo, PRBool encrypt)
1195
#if NSS_SOFTOKEN_DOES_RC5
1196
PRIntervalTime time1, time2;
1197
bltestRC5Params *rc5p = &cipherInfo->params.rc5;
1199
switch (cipherInfo->mode) {
1200
case bltestRC5_ECB: minorMode = NSS_RC5; break;
1201
case bltestRC5_CBC: minorMode = NSS_RC5_CBC; break;
1206
cipherInfo->cx = (void*)RC5_CreateContext(&rc5p->key.buf,
1207
rc5p->rounds, rc5p->wordsize,
1208
rc5p->iv.buf.data, minorMode);
1209
TIMEFINISH(cipherInfo->cxtime, 1.0);
1211
cipherInfo->cipher.symmkeyCipher = RC5_Encrypt;
1213
cipherInfo->cipher.symmkeyCipher = RC5_Decrypt;
1221
bltest_aes_init(bltestCipherInfo *cipherInfo, PRBool encrypt)
1223
PRIntervalTime time1, time2;
1224
bltestSymmKeyParams *aesp = &cipherInfo->params.sk;
1227
/* XXX */ int keylen, blocklen;
1228
keylen = aesp->key.buf.len;
1229
blocklen = cipherInfo->input.pBuf.len;
1230
switch (cipherInfo->mode) {
1231
case bltestAES_ECB: minorMode = NSS_AES; break;
1232
case bltestAES_CBC: minorMode = NSS_AES_CBC; break;
1236
cipherInfo->cx = (void*)AES_CreateContext(aesp->key.buf.data,
1240
if (cipherInfo->cxreps > 0) {
1241
AESContext **dummycx;
1242
dummycx = PORT_Alloc(cipherInfo->cxreps * sizeof(AESContext *));
1244
for (i=0; i<cipherInfo->cxreps; i++) {
1245
dummycx[i] = (void*)AES_CreateContext(aesp->key.buf.data,
1250
TIMEFINISH(cipherInfo->cxtime, 1.0);
1251
for (i=0; i<cipherInfo->cxreps; i++) {
1252
AES_DestroyContext(dummycx[i], PR_TRUE);
1257
cipherInfo->cipher.symmkeyCipher = aes_Encrypt;
1259
cipherInfo->cipher.symmkeyCipher = aes_Decrypt;
1264
bltest_rsa_init(bltestCipherInfo *cipherInfo, PRBool encrypt)
1267
RSAPrivateKey **dummyKey;
1268
PRIntervalTime time1, time2;
1269
bltestRSAParams *rsap = &cipherInfo->params.rsa;
1270
/* RSA key gen was done during parameter setup */
1271
cipherInfo->cx = cipherInfo->params.rsa.rsakey;
1272
/* For performance testing */
1273
if (cipherInfo->cxreps > 0) {
1274
/* Create space for n private key objects */
1275
dummyKey = (RSAPrivateKey **)PORT_Alloc(cipherInfo->cxreps *
1276
sizeof(RSAPrivateKey *));
1277
/* Time n keygens, storing in the array */
1279
for (i=0; i<cipherInfo->cxreps; i++)
1280
dummyKey[i] = RSA_NewKey(rsap->keysizeInBits,
1281
&rsap->rsakey->publicExponent);
1282
TIMEFINISH(cipherInfo->cxtime, cipherInfo->cxreps);
1283
/* Free the n key objects */
1284
for (i=0; i<cipherInfo->cxreps; i++)
1285
PORT_FreeArena(dummyKey[i]->arena, PR_TRUE);
1286
PORT_Free(dummyKey);
1289
/* Have to convert private key to public key. Memory
1290
* is freed with private key's arena */
1291
RSAPublicKey *pubkey;
1292
RSAPrivateKey *key = (RSAPrivateKey *)cipherInfo->cx;
1293
pubkey = (RSAPublicKey *)PORT_ArenaAlloc(key->arena,
1294
sizeof(RSAPublicKey));
1295
pubkey->modulus.len = key->modulus.len;
1296
pubkey->modulus.data = key->modulus.data;
1297
pubkey->publicExponent.len = key->publicExponent.len;
1298
pubkey->publicExponent.data = key->publicExponent.data;
1299
cipherInfo->cx = (void *)pubkey;
1300
cipherInfo->cipher.pubkeyCipher = rsa_PublicKeyOp;
1302
cipherInfo->cipher.pubkeyCipher = rsa_PrivateKeyOp;
1308
bltest_pqg_init(bltestDSAParams *dsap)
1311
PQGVerify *vfy = NULL;
1312
rv = PQG_ParamGen(dsap->j, &dsap->pqg, &vfy);
1313
CHECKERROR(rv, __LINE__);
1314
rv = PQG_VerifyParams(dsap->pqg, vfy, &res);
1315
CHECKERROR(res, __LINE__);
1316
CHECKERROR(rv, __LINE__);
1321
bltest_dsa_init(bltestCipherInfo *cipherInfo, PRBool encrypt)
1324
DSAPrivateKey **dummyKey;
1325
PQGParams *dummypqg;
1326
PRIntervalTime time1, time2;
1327
bltestDSAParams *dsap = &cipherInfo->params.dsa;
1328
PQGVerify *ignore = NULL;
1329
/* DSA key gen was done during parameter setup */
1330
cipherInfo->cx = cipherInfo->params.dsa.dsakey;
1331
/* For performance testing */
1332
if (cipherInfo->cxreps > 0) {
1333
/* Create space for n private key objects */
1334
dummyKey = (DSAPrivateKey **)PORT_ZAlloc(cipherInfo->cxreps *
1335
sizeof(DSAPrivateKey *));
1336
/* Time n keygens, storing in the array */
1338
for (i=0; i<cipherInfo->cxreps; i++) {
1340
PQG_ParamGen(dsap->j, &dummypqg, &ignore);
1341
DSA_NewKey(dummypqg, &dummyKey[i]);
1343
TIMEFINISH(cipherInfo->cxtime, cipherInfo->cxreps);
1344
/* Free the n key objects */
1345
for (i=0; i<cipherInfo->cxreps; i++)
1346
PORT_FreeArena(dummyKey[i]->params.arena, PR_TRUE);
1347
PORT_Free(dummyKey);
1349
if (!dsap->pqg && dsap->pqgdata.buf.len > 0) {
1350
dsap->pqg = pqg_from_filedata(&dsap->pqgdata.buf);
1352
if (!cipherInfo->cx && dsap->key.buf.len > 0) {
1353
cipherInfo->cx = dsakey_from_filedata(&dsap->key.buf);
1356
cipherInfo->cipher.pubkeyCipher = dsa_signDigest;
1358
/* Have to convert private key to public key. Memory
1359
* is freed with private key's arena */
1360
DSAPublicKey *pubkey;
1361
DSAPrivateKey *key = (DSAPrivateKey *)cipherInfo->cx;
1362
pubkey = (DSAPublicKey *)PORT_ArenaZAlloc(key->params.arena,
1363
sizeof(DSAPublicKey));
1364
pubkey->params.prime.len = key->params.prime.len;
1365
pubkey->params.prime.data = key->params.prime.data;
1366
pubkey->params.subPrime.len = key->params.subPrime.len;
1367
pubkey->params.subPrime.data = key->params.subPrime.data;
1368
pubkey->params.base.len = key->params.base.len;
1369
pubkey->params.base.data = key->params.base.data;
1370
pubkey->publicValue.len = key->publicValue.len;
1371
pubkey->publicValue.data = key->publicValue.data;
1372
cipherInfo->cipher.pubkeyCipher = dsa_verifyDigest;
1377
#ifdef NSS_ENABLE_ECC
1379
bltest_ecdsa_init(bltestCipherInfo *cipherInfo, PRBool encrypt)
1382
ECPrivateKey **dummyKey;
1383
PRIntervalTime time1, time2;
1384
bltestECDSAParams *ecdsap = &cipherInfo->params.ecdsa;
1385
/* ECDSA key gen was done during parameter setup */
1386
cipherInfo->cx = cipherInfo->params.ecdsa.eckey;
1387
/* For performance testing */
1388
if (cipherInfo->cxreps > 0) {
1389
/* Create space for n private key objects */
1390
dummyKey = (ECPrivateKey **)PORT_ZAlloc(cipherInfo->cxreps *
1391
sizeof(ECPrivateKey *));
1392
/* Time n keygens, storing in the array */
1394
for (i=0; i<cipherInfo->cxreps; i++) {
1395
EC_NewKey(&ecdsap->eckey->ecParams, &dummyKey[i]);
1397
TIMEFINISH(cipherInfo->cxtime, cipherInfo->cxreps);
1398
/* Free the n key objects */
1399
for (i=0; i<cipherInfo->cxreps; i++)
1400
PORT_FreeArena(dummyKey[i]->ecParams.arena, PR_TRUE);
1401
PORT_Free(dummyKey);
1403
if (!cipherInfo->cx && ecdsap->key.buf.len > 0) {
1404
cipherInfo->cx = eckey_from_filedata(&ecdsap->key.buf);
1407
cipherInfo->cipher.pubkeyCipher = ecdsa_signDigest;
1409
/* Have to convert private key to public key. Memory
1410
* is freed with private key's arena */
1411
ECPublicKey *pubkey;
1412
ECPrivateKey *key = (ECPrivateKey *)cipherInfo->cx;
1413
pubkey = (ECPublicKey *)PORT_ArenaZAlloc(key->ecParams.arena,
1414
sizeof(ECPublicKey));
1415
pubkey->ecParams.type = key->ecParams.type;
1416
pubkey->ecParams.fieldID.size = key->ecParams.fieldID.size;
1417
pubkey->ecParams.fieldID.type = key->ecParams.fieldID.type;
1418
pubkey->ecParams.fieldID.u.prime.len = key->ecParams.fieldID.u.prime.len;
1419
pubkey->ecParams.fieldID.u.prime.data = key->ecParams.fieldID.u.prime.data;
1420
pubkey->ecParams.fieldID.k1 = key->ecParams.fieldID.k1;
1421
pubkey->ecParams.fieldID.k2 = key->ecParams.fieldID.k2;
1422
pubkey->ecParams.fieldID.k3 = key->ecParams.fieldID.k3;
1423
pubkey->ecParams.curve.a.len = key->ecParams.curve.a.len;
1424
pubkey->ecParams.curve.a.data = key->ecParams.curve.a.data;
1425
pubkey->ecParams.curve.b.len = key->ecParams.curve.b.len;
1426
pubkey->ecParams.curve.b.data = key->ecParams.curve.b.data;
1427
pubkey->ecParams.curve.seed.len = key->ecParams.curve.seed.len;
1428
pubkey->ecParams.curve.seed.data = key->ecParams.curve.seed.data;
1429
pubkey->ecParams.base.len = key->ecParams.base.len;
1430
pubkey->ecParams.base.data = key->ecParams.base.data;
1431
pubkey->ecParams.order.len = key->ecParams.order.len;
1432
pubkey->ecParams.order.data = key->ecParams.order.data;
1433
pubkey->ecParams.cofactor = key->ecParams.cofactor;
1434
pubkey->ecParams.DEREncoding.len = key->ecParams.DEREncoding.len;
1435
pubkey->ecParams.DEREncoding.data = key->ecParams.DEREncoding.data;
1436
pubkey->ecParams.name= key->ecParams.name;
1437
pubkey->publicValue.len = key->publicValue.len;
1438
pubkey->publicValue.data = key->publicValue.data;
1439
cipherInfo->cipher.pubkeyCipher = ecdsa_verifyDigest;
1445
/* XXX unfortunately, this is not defined in blapi.h */
1447
md2_HashBuf(unsigned char *dest, const unsigned char *src, uint32 src_length)
1450
MD2Context *cx = MD2_NewContext();
1451
if (cx == NULL) return SECFailure;
1453
MD2_Update(cx, src, src_length);
1454
MD2_End(cx, dest, &len, MD2_LENGTH);
1455
MD2_DestroyContext(cx, PR_TRUE);
1460
md2_restart(unsigned char *dest, const unsigned char *src, uint32 src_length)
1462
MD2Context *cx, *cx_cpy;
1463
unsigned char *cxbytes;
1465
unsigned int i, quarter;
1466
SECStatus rv = SECSuccess;
1467
cx = MD2_NewContext();
1469
/* divide message by 4, restarting 3 times */
1470
quarter = (src_length + 3)/ 4;
1471
for (i=0; i < 4 && src_length > 0; i++) {
1472
MD2_Update(cx, src + i*quarter, PR_MIN(quarter, src_length));
1473
len = MD2_FlattenSize(cx);
1474
cxbytes = PORT_Alloc(len);
1475
MD2_Flatten(cx, cxbytes);
1476
cx_cpy = MD2_Resurrect(cxbytes, NULL);
1478
PR_fprintf(PR_STDERR, "%s: MD2_Resurrect failed!\n", progName);
1481
rv = PORT_Memcmp(cx, cx_cpy, len);
1483
MD2_DestroyContext(cx_cpy, PR_TRUE);
1484
PR_fprintf(PR_STDERR, "%s: MD2_restart failed!\n", progName);
1487
MD2_DestroyContext(cx_cpy, PR_TRUE);
1489
src_length -= quarter;
1491
MD2_End(cx, dest, &len, MD2_LENGTH);
1493
MD2_DestroyContext(cx, PR_TRUE);
1498
md5_restart(unsigned char *dest, const unsigned char *src, uint32 src_length)
1500
SECStatus rv = SECSuccess;
1501
MD5Context *cx, *cx_cpy;
1502
unsigned char *cxbytes;
1504
unsigned int i, quarter;
1505
cx = MD5_NewContext();
1507
/* divide message by 4, restarting 3 times */
1508
quarter = (src_length + 3)/ 4;
1509
for (i=0; i < 4 && src_length > 0; i++) {
1510
MD5_Update(cx, src + i*quarter, PR_MIN(quarter, src_length));
1511
len = MD5_FlattenSize(cx);
1512
cxbytes = PORT_Alloc(len);
1513
MD5_Flatten(cx, cxbytes);
1514
cx_cpy = MD5_Resurrect(cxbytes, NULL);
1516
PR_fprintf(PR_STDERR, "%s: MD5_Resurrect failed!\n", progName);
1520
rv = PORT_Memcmp(cx, cx_cpy, len);
1522
MD5_DestroyContext(cx_cpy, PR_TRUE);
1523
PR_fprintf(PR_STDERR, "%s: MD5_restart failed!\n", progName);
1526
MD5_DestroyContext(cx_cpy, PR_TRUE);
1528
src_length -= quarter;
1530
MD5_End(cx, dest, &len, MD5_LENGTH);
1532
MD5_DestroyContext(cx, PR_TRUE);
1537
sha1_restart(unsigned char *dest, const unsigned char *src, uint32 src_length)
1539
SECStatus rv = SECSuccess;
1540
SHA1Context *cx, *cx_cpy;
1541
unsigned char *cxbytes;
1543
unsigned int i, quarter;
1544
cx = SHA1_NewContext();
1546
/* divide message by 4, restarting 3 times */
1547
quarter = (src_length + 3)/ 4;
1548
for (i=0; i < 4 && src_length > 0; i++) {
1549
SHA1_Update(cx, src + i*quarter, PR_MIN(quarter, src_length));
1550
len = SHA1_FlattenSize(cx);
1551
cxbytes = PORT_Alloc(len);
1552
SHA1_Flatten(cx, cxbytes);
1553
cx_cpy = SHA1_Resurrect(cxbytes, NULL);
1555
PR_fprintf(PR_STDERR, "%s: SHA1_Resurrect failed!\n", progName);
1559
rv = PORT_Memcmp(cx, cx_cpy, len);
1561
SHA1_DestroyContext(cx_cpy, PR_TRUE);
1562
PR_fprintf(PR_STDERR, "%s: SHA1_restart failed!\n", progName);
1565
SHA1_DestroyContext(cx_cpy, PR_TRUE);
1567
src_length -= quarter;
1569
SHA1_End(cx, dest, &len, MD5_LENGTH);
1571
SHA1_DestroyContext(cx, PR_TRUE);
1576
SHA256_restart(unsigned char *dest, const unsigned char *src, uint32 src_length)
1578
SECStatus rv = SECSuccess;
1579
SHA256Context *cx, *cx_cpy;
1580
unsigned char *cxbytes;
1582
unsigned int i, quarter;
1583
cx = SHA256_NewContext();
1585
/* divide message by 4, restarting 3 times */
1586
quarter = (src_length + 3)/ 4;
1587
for (i=0; i < 4 && src_length > 0; i++) {
1588
SHA256_Update(cx, src + i*quarter, PR_MIN(quarter, src_length));
1589
len = SHA256_FlattenSize(cx);
1590
cxbytes = PORT_Alloc(len);
1591
SHA256_Flatten(cx, cxbytes);
1592
cx_cpy = SHA256_Resurrect(cxbytes, NULL);
1594
PR_fprintf(PR_STDERR, "%s: SHA256_Resurrect failed!\n", progName);
1598
rv = PORT_Memcmp(cx, cx_cpy, len);
1600
SHA256_DestroyContext(cx_cpy, PR_TRUE);
1601
PR_fprintf(PR_STDERR, "%s: SHA256_restart failed!\n", progName);
1604
SHA256_DestroyContext(cx_cpy, PR_TRUE);
1606
src_length -= quarter;
1608
SHA256_End(cx, dest, &len, MD5_LENGTH);
1610
SHA256_DestroyContext(cx, PR_TRUE);
1615
SHA384_restart(unsigned char *dest, const unsigned char *src, uint32 src_length)
1617
SECStatus rv = SECSuccess;
1618
SHA384Context *cx, *cx_cpy;
1619
unsigned char *cxbytes;
1621
unsigned int i, quarter;
1622
cx = SHA384_NewContext();
1624
/* divide message by 4, restarting 3 times */
1625
quarter = (src_length + 3)/ 4;
1626
for (i=0; i < 4 && src_length > 0; i++) {
1627
SHA384_Update(cx, src + i*quarter, PR_MIN(quarter, src_length));
1628
len = SHA384_FlattenSize(cx);
1629
cxbytes = PORT_Alloc(len);
1630
SHA384_Flatten(cx, cxbytes);
1631
cx_cpy = SHA384_Resurrect(cxbytes, NULL);
1633
PR_fprintf(PR_STDERR, "%s: SHA384_Resurrect failed!\n", progName);
1637
rv = PORT_Memcmp(cx, cx_cpy, len);
1639
SHA384_DestroyContext(cx_cpy, PR_TRUE);
1640
PR_fprintf(PR_STDERR, "%s: SHA384_restart failed!\n", progName);
1643
SHA384_DestroyContext(cx_cpy, PR_TRUE);
1645
src_length -= quarter;
1647
SHA384_End(cx, dest, &len, MD5_LENGTH);
1649
SHA384_DestroyContext(cx, PR_TRUE);
1654
SHA512_restart(unsigned char *dest, const unsigned char *src, uint32 src_length)
1656
SECStatus rv = SECSuccess;
1657
SHA512Context *cx, *cx_cpy;
1658
unsigned char *cxbytes;
1660
unsigned int i, quarter;
1661
cx = SHA512_NewContext();
1663
/* divide message by 4, restarting 3 times */
1664
quarter = (src_length + 3)/ 4;
1665
for (i=0; i < 4 && src_length > 0; i++) {
1666
SHA512_Update(cx, src + i*quarter, PR_MIN(quarter, src_length));
1667
len = SHA512_FlattenSize(cx);
1668
cxbytes = PORT_Alloc(len);
1669
SHA512_Flatten(cx, cxbytes);
1670
cx_cpy = SHA512_Resurrect(cxbytes, NULL);
1672
PR_fprintf(PR_STDERR, "%s: SHA512_Resurrect failed!\n", progName);
1676
rv = PORT_Memcmp(cx, cx_cpy, len);
1678
SHA512_DestroyContext(cx_cpy, PR_TRUE);
1679
PR_fprintf(PR_STDERR, "%s: SHA512_restart failed!\n", progName);
1682
SHA512_DestroyContext(cx_cpy, PR_TRUE);
1684
src_length -= quarter;
1686
SHA512_End(cx, dest, &len, MD5_LENGTH);
1688
SHA512_DestroyContext(cx, PR_TRUE);
1693
pubkeyInitKey(bltestCipherInfo *cipherInfo, PRFileDesc *file,
1694
#ifdef NSS_ENABLE_ECC
1695
int keysize, int exponent, char *curveName)
1697
int keysize, int exponent)
1701
SECStatus rv = SECSuccess;
1702
bltestRSAParams *rsap;
1703
bltestDSAParams *dsap;
1704
#ifdef NSS_ENABLE_ECC
1705
bltestECDSAParams *ecdsap;
1706
SECItem *tmpECParamsDER;
1707
ECParams *tmpECParams = NULL;
1708
SECItem ecSerialize[3];
1710
switch (cipherInfo->mode) {
1712
rsap = &cipherInfo->params.rsa;
1714
SECItem expitem = { 0, 0, 0 };
1715
SECITEM_AllocItem(cipherInfo->arena, &expitem, sizeof(int));
1716
for (i = 1; i <= sizeof(int); i++)
1717
expitem.data[i-1] = exponent >> (8*(sizeof(int) - i));
1718
rsap->rsakey = RSA_NewKey(keysize * 8, &expitem);
1719
serialize_key(&rsap->rsakey->version, 9, file);
1720
rsap->keysizeInBits = keysize * 8;
1722
setupIO(cipherInfo->arena, &cipherInfo->params.key, file, NULL, 0);
1723
rsap->rsakey = rsakey_from_filedata(&cipherInfo->params.key.buf);
1724
rsap->keysizeInBits = rsap->rsakey->modulus.len * 8;
1728
dsap = &cipherInfo->params.dsa;
1730
dsap->j = PQG_PBITS_TO_INDEX(8*keysize);
1732
bltest_pqg_init(dsap);
1733
rv = DSA_NewKey(dsap->pqg, &dsap->dsakey);
1734
CHECKERROR(rv, __LINE__);
1735
serialize_key(&dsap->dsakey->params.prime, 5, file);
1737
setupIO(cipherInfo->arena, &cipherInfo->params.key, file, NULL, 0);
1738
dsap->dsakey = dsakey_from_filedata(&cipherInfo->params.key.buf);
1739
dsap->j = PQG_PBITS_TO_INDEX(8*dsap->dsakey->params.prime.len);
1742
#ifdef NSS_ENABLE_ECC
1744
ecdsap = &cipherInfo->params.ecdsa;
1745
if (curveName != NULL) {
1746
tmpECParamsDER = getECParams(curveName);
1748
CHECKERROR(rv, __LINE__);
1749
rv = EC_DecodeParams(tmpECParamsDER, &tmpECParams) == SECFailure;
1750
CHECKERROR(rv, __LINE__);
1751
rv = EC_NewKey(tmpECParams, &ecdsap->eckey);
1752
CHECKERROR(rv, __LINE__);
1753
ecSerialize[0].type = tmpECParamsDER->type;
1754
ecSerialize[0].data = tmpECParamsDER->data;
1755
ecSerialize[0].len = tmpECParamsDER->len;
1756
ecSerialize[1].type = ecdsap->eckey->publicValue.type;
1757
ecSerialize[1].data = ecdsap->eckey->publicValue.data;
1758
ecSerialize[1].len = ecdsap->eckey->publicValue.len;
1759
ecSerialize[2].type = ecdsap->eckey->privateValue.type;
1760
ecSerialize[2].data = ecdsap->eckey->privateValue.data;
1761
ecSerialize[2].len = ecdsap->eckey->privateValue.len;
1762
serialize_key(&(ecSerialize[0]), 3, file);
1763
free(tmpECParamsDER);
1764
PORT_FreeArena(tmpECParams->arena, PR_TRUE);
1765
rv = SECOID_Shutdown();
1766
CHECKERROR(rv, __LINE__);
1768
setupIO(cipherInfo->arena, &cipherInfo->params.key, file, NULL, 0);
1769
ecdsap->eckey = eckey_from_filedata(&cipherInfo->params.key.buf);
1780
cipherInit(bltestCipherInfo *cipherInfo, PRBool encrypt)
1783
switch (cipherInfo->mode) {
1786
case bltestDES_EDE_ECB:
1787
case bltestDES_EDE_CBC:
1788
SECITEM_AllocItem(cipherInfo->arena, &cipherInfo->output.buf,
1789
cipherInfo->input.pBuf.len);
1790
return bltest_des_init(cipherInfo, encrypt);
1794
SECITEM_AllocItem(cipherInfo->arena, &cipherInfo->output.buf,
1795
cipherInfo->input.pBuf.len);
1796
return bltest_rc2_init(cipherInfo, encrypt);
1799
SECITEM_AllocItem(cipherInfo->arena, &cipherInfo->output.buf,
1800
cipherInfo->input.pBuf.len);
1801
return bltest_rc4_init(cipherInfo, encrypt);
1805
#if NSS_SOFTOKEN_DOES_RC5
1806
SECITEM_AllocItem(cipherInfo->arena, &cipherInfo->output.buf,
1807
cipherInfo->input.pBuf.len);
1809
return bltest_rc5_init(cipherInfo, encrypt);
1813
SECITEM_AllocItem(cipherInfo->arena, &cipherInfo->output.buf,
1814
cipherInfo->input.pBuf.len);
1815
return bltest_aes_init(cipherInfo, encrypt);
1818
SECITEM_AllocItem(cipherInfo->arena, &cipherInfo->output.buf,
1819
cipherInfo->input.pBuf.len);
1820
return bltest_rsa_init(cipherInfo, encrypt);
1823
SECITEM_AllocItem(cipherInfo->arena, &cipherInfo->output.buf,
1825
return bltest_dsa_init(cipherInfo, encrypt);
1827
#ifdef NSS_ENABLE_ECC
1829
SECITEM_AllocItem(cipherInfo->arena, &cipherInfo->output.buf,
1831
return bltest_ecdsa_init(cipherInfo, encrypt);
1835
restart = cipherInfo->params.hash.restart;
1836
SECITEM_AllocItem(cipherInfo->arena, &cipherInfo->output.buf,
1838
cipherInfo->cipher.hashCipher = (restart) ? md2_restart : md2_HashBuf;
1842
restart = cipherInfo->params.hash.restart;
1843
SECITEM_AllocItem(cipherInfo->arena, &cipherInfo->output.buf,
1845
cipherInfo->cipher.hashCipher = (restart) ? md5_restart : MD5_HashBuf;
1849
restart = cipherInfo->params.hash.restart;
1850
SECITEM_AllocItem(cipherInfo->arena, &cipherInfo->output.buf,
1852
cipherInfo->cipher.hashCipher = (restart) ? sha1_restart : SHA1_HashBuf;
1856
restart = cipherInfo->params.hash.restart;
1857
SECITEM_AllocItem(cipherInfo->arena, &cipherInfo->output.buf,
1859
cipherInfo->cipher.hashCipher = (restart) ? SHA256_restart
1864
restart = cipherInfo->params.hash.restart;
1865
SECITEM_AllocItem(cipherInfo->arena, &cipherInfo->output.buf,
1867
cipherInfo->cipher.hashCipher = (restart) ? SHA384_restart
1872
restart = cipherInfo->params.hash.restart;
1873
SECITEM_AllocItem(cipherInfo->arena, &cipherInfo->output.buf,
1875
cipherInfo->cipher.hashCipher = (restart) ? SHA512_restart
1886
dsaOp(bltestCipherInfo *cipherInfo)
1888
PRIntervalTime time1, time2;
1889
SECStatus rv = SECSuccess;
1891
int maxLen = cipherInfo->output.pBuf.len;
1892
SECItem dummyOut = { 0, 0, 0 };
1893
SECITEM_AllocItem(NULL, &dummyOut, maxLen);
1894
if (cipherInfo->cipher.pubkeyCipher == dsa_signDigest) {
1895
if (cipherInfo->params.dsa.sigseed.buf.len > 0) {
1896
rv = DSA_SignDigestWithSeed((DSAPrivateKey *)cipherInfo->cx,
1897
&cipherInfo->output.pBuf,
1898
&cipherInfo->input.pBuf,
1899
cipherInfo->params.dsa.sigseed.buf.data);
1900
CHECKERROR(rv, __LINE__);
1902
for (i=0; i<cipherInfo->repetitions; i++) {
1903
rv |= DSA_SignDigestWithSeed((DSAPrivateKey *)cipherInfo->cx,
1905
&cipherInfo->input.pBuf,
1906
cipherInfo->params.dsa.sigseed.buf.data);
1908
TIMEFINISH(cipherInfo->optime, 1.0);
1909
CHECKERROR(rv, __LINE__);
1911
rv = DSA_SignDigest((DSAPrivateKey *)cipherInfo->cx,
1912
&cipherInfo->output.pBuf,
1913
&cipherInfo->input.pBuf);
1914
CHECKERROR(rv, __LINE__);
1916
for (i=0; i<cipherInfo->repetitions; i++) {
1917
DSA_SignDigest((DSAPrivateKey *)cipherInfo->cx, &dummyOut,
1918
&cipherInfo->input.pBuf);
1920
TIMEFINISH(cipherInfo->optime, 1.0);
1922
bltestCopyIO(cipherInfo->arena, &cipherInfo->params.dsa.sig,
1923
&cipherInfo->output);
1925
rv = DSA_VerifyDigest((DSAPublicKey *)cipherInfo->cx,
1926
&cipherInfo->params.dsa.sig.buf,
1927
&cipherInfo->input.pBuf);
1928
CHECKERROR(rv, __LINE__);
1930
for (i=0; i<cipherInfo->repetitions; i++) {
1931
DSA_VerifyDigest((DSAPublicKey *)cipherInfo->cx,
1932
&cipherInfo->params.dsa.sig.buf,
1933
&cipherInfo->input.pBuf);
1935
TIMEFINISH(cipherInfo->optime, 1.0);
1937
SECITEM_FreeItem(&dummyOut, PR_FALSE);
1941
#ifdef NSS_ENABLE_ECC
1943
ecdsaOp(bltestCipherInfo *cipherInfo)
1945
PRIntervalTime time1, time2;
1946
SECStatus rv = SECSuccess;
1948
int maxLen = cipherInfo->output.pBuf.len;
1949
SECItem dummyOut = { 0, 0, 0 };
1950
SECITEM_AllocItem(NULL, &dummyOut, maxLen);
1951
if (cipherInfo->cipher.pubkeyCipher == ecdsa_signDigest) {
1952
if (cipherInfo->params.ecdsa.sigseed.buf.len > 0) {
1953
rv = ECDSA_SignDigestWithSeed((ECPrivateKey *)cipherInfo->cx,
1954
&cipherInfo->output.pBuf,
1955
&cipherInfo->input.pBuf,
1956
cipherInfo->params.ecdsa.sigseed.buf.data,
1957
cipherInfo->params.ecdsa.sigseed.buf.len);
1958
CHECKERROR(rv, __LINE__);
1960
for (i=0; i<cipherInfo->repetitions; i++) {
1961
rv |= ECDSA_SignDigestWithSeed((ECPrivateKey *)cipherInfo->cx,
1963
&cipherInfo->input.pBuf,
1964
cipherInfo->params.ecdsa.sigseed.buf.data,
1965
cipherInfo->params.ecdsa.sigseed.buf.len);
1967
TIMEFINISH(cipherInfo->optime, 1.0);
1968
CHECKERROR(rv, __LINE__);
1970
rv = ECDSA_SignDigest((ECPrivateKey *)cipherInfo->cx,
1971
&cipherInfo->output.pBuf,
1972
&cipherInfo->input.pBuf);
1973
CHECKERROR(rv, __LINE__);
1975
for (i=0; i<cipherInfo->repetitions; i++) {
1976
ECDSA_SignDigest((ECPrivateKey *)cipherInfo->cx, &dummyOut,
1977
&cipherInfo->input.pBuf);
1979
TIMEFINISH(cipherInfo->optime, 1.0);
1981
bltestCopyIO(cipherInfo->arena, &cipherInfo->params.ecdsa.sig,
1982
&cipherInfo->output);
1984
rv = ECDSA_VerifyDigest((ECPublicKey *)cipherInfo->cx,
1985
&cipherInfo->params.ecdsa.sig.buf,
1986
&cipherInfo->input.pBuf);
1987
CHECKERROR(rv, __LINE__);
1989
for (i=0; i<cipherInfo->repetitions; i++) {
1990
ECDSA_VerifyDigest((ECPublicKey *)cipherInfo->cx,
1991
&cipherInfo->params.ecdsa.sig.buf,
1992
&cipherInfo->input.pBuf);
1994
TIMEFINISH(cipherInfo->optime, 1.0);
1996
SECITEM_FreeItem(&dummyOut, PR_FALSE);
2002
cipherDoOp(bltestCipherInfo *cipherInfo)
2004
PRIntervalTime time1, time2;
2005
SECStatus rv = SECSuccess;
2007
int maxLen = cipherInfo->output.pBuf.len;
2008
unsigned char *dummyOut;
2009
if (cipherInfo->mode == bltestDSA)
2010
return dsaOp(cipherInfo);
2011
#ifdef NSS_ENABLE_ECC
2012
else if (cipherInfo->mode == bltestECDSA)
2013
return ecdsaOp(cipherInfo);
2015
dummyOut = PORT_Alloc(maxLen);
2016
if (is_symmkeyCipher(cipherInfo->mode)) {
2017
rv = (*cipherInfo->cipher.symmkeyCipher)(cipherInfo->cx,
2018
cipherInfo->output.pBuf.data,
2020
cipherInfo->input.pBuf.data,
2021
cipherInfo->input.pBuf.len);
2023
for (i=0; i<cipherInfo->repetitions; i++) {
2024
(*cipherInfo->cipher.symmkeyCipher)(cipherInfo->cx, dummyOut,
2026
cipherInfo->input.pBuf.data,
2027
cipherInfo->input.pBuf.len);
2030
TIMEFINISH(cipherInfo->optime, 1.0);
2031
} else if (is_pubkeyCipher(cipherInfo->mode)) {
2032
rv = (*cipherInfo->cipher.pubkeyCipher)(cipherInfo->cx,
2033
&cipherInfo->output.pBuf,
2034
&cipherInfo->input.pBuf);
2036
for (i=0; i<cipherInfo->repetitions; i++) {
2038
dummy.data = dummyOut;
2040
(*cipherInfo->cipher.pubkeyCipher)(cipherInfo->cx, &dummy,
2041
&cipherInfo->input.pBuf);
2043
TIMEFINISH(cipherInfo->optime, 1.0);
2044
} else if (is_hashCipher(cipherInfo->mode)) {
2045
rv = (*cipherInfo->cipher.hashCipher)(cipherInfo->output.pBuf.data,
2046
cipherInfo->input.pBuf.data,
2047
cipherInfo->input.pBuf.len);
2049
for (i=0; i<cipherInfo->repetitions; i++) {
2050
(*cipherInfo->cipher.hashCipher)(dummyOut,
2051
cipherInfo->input.pBuf.data,
2052
cipherInfo->input.pBuf.len);
2054
TIMEFINISH(cipherInfo->optime, 1.0);
2056
PORT_Free(dummyOut);
2061
cipherFinish(bltestCipherInfo *cipherInfo)
2063
switch (cipherInfo->mode) {
2066
case bltestDES_EDE_ECB:
2067
case bltestDES_EDE_CBC:
2068
DES_DestroyContext((DESContext *)cipherInfo->cx, PR_TRUE);
2072
AES_DestroyContext((AESContext *)cipherInfo->cx, PR_TRUE);
2076
RC2_DestroyContext((RC2Context *)cipherInfo->cx, PR_TRUE);
2079
RC4_DestroyContext((RC4Context *)cipherInfo->cx, PR_TRUE);
2081
#if NSS_SOFTOKEN_DOES_RC5
2084
RC5_DestroyContext((RC5Context *)cipherInfo->cx, PR_TRUE);
2087
case bltestRSA: /* keys are alloc'ed within cipherInfo's arena, */
2088
case bltestDSA: /* will be freed with it. */
2089
#ifdef NSS_ENABLE_ECC
2092
case bltestMD2: /* hash contexts are ephemeral */
2107
print_exponent(SECItem *exp)
2111
if (exp->len <= 4) {
2112
for (i=exp->len; i >=0; --i) e |= exp->data[exp->len-i] << 8*(i-1);
2113
fprintf(stdout, "%12d", e);
2116
fprintf(stdout, "~2**%-8d", e);
2121
dump_performance_info(bltestCipherInfo *info, PRBool encrypt, PRBool cxonly)
2123
PRBool td = PR_TRUE;
2124
fprintf(stdout, "#%9s", "mode");
2125
fprintf(stdout, "%12s", "in");
2127
switch (info->mode) {
2130
case bltestDES_EDE_ECB:
2131
case bltestDES_EDE_CBC:
2138
fprintf(stdout, "%8s", "symmkey");
2140
fprintf(stdout, "%8d", 8*info->params.sk.key.buf.len);
2142
#if NSS_SOFTOKEN_DOES_RC5
2145
if (info->params.sk.key.buf.len > 0)
2146
printf("symmetric key(bytes)=%d,", info->params.sk.key.buf.len);
2147
if (info->rounds > 0)
2148
printf("rounds=%d,", info->params.rc5.rounds);
2149
if (info->wordsize > 0)
2150
printf("wordsize(bytes)=%d,", info->params.rc5.wordsize);
2155
fprintf(stdout, "%8s", "rsa_mod");
2156
fprintf(stdout, "%12s", "rsa_pe");
2158
fprintf(stdout, "%8d", info->params.rsa.keysizeInBits);
2159
print_exponent(&info->params.rsa.rsakey->publicExponent);
2164
fprintf(stdout, "%8s", "pqg_mod");
2166
fprintf(stdout, "%8d", PQG_INDEX_TO_PBITS(info->params.dsa.j));
2168
#ifdef NSS_ENABLE_ECC
2171
fprintf(stdout, "%12s", "ec_curve");
2173
fprintf(stdout, "%12s", ecCurve_map[info->params.ecdsa.eckey->ecParams.name]->text);
2186
fprintf(stdout, "%8d", info->repetitions);
2187
fprintf(stdout, "%8d", info->cxreps);
2188
fprintf(stdout, "%12.3f", info->cxtime);
2189
fprintf(stdout, "%12.3f", info->optime);
2190
fprintf(stdout, "\n");
2194
fprintf(stdout, "%8s", "opreps");
2195
fprintf(stdout, "%8s", "cxreps");
2196
fprintf(stdout, "%12s", "context");
2197
fprintf(stdout, "%12s", "op");
2198
fprintf(stdout, "\n");
2199
fprintf(stdout, "%8s", mode_strings[info->mode]);
2200
fprintf(stdout, "_%c", (cxonly) ? 'c' : (encrypt) ? 'e' : 'd');
2201
fprintf(stdout, "%12d", info->input.buf.len * info->repetitions);
2210
bltestCipherMode mode;
2211
int nummodes = sizeof(mode_strings) / sizeof(char *);
2212
fprintf(stderr, "%s: Available modes (specify with -m):\n", progName);
2213
for (mode=0; mode<nummodes; mode++)
2214
fprintf(stderr, "%s\n", mode_strings[mode]);
2218
get_mode(const char *modestring)
2220
bltestCipherMode mode;
2221
int nummodes = sizeof(mode_strings) / sizeof(char *);
2222
for (mode=0; mode<nummodes; mode++)
2223
if (PL_strcmp(modestring, mode_strings[mode]) == 0)
2225
fprintf(stderr, "%s: invalid mode: %s\n", progName, modestring);
2226
return bltestINVALID;
2230
load_file_data(PRArenaPool *arena, bltestIO *data,
2231
char *fn, bltestIOMode ioMode)
2234
data->mode = ioMode;
2235
data->file = NULL; /* don't use -- not saving anything */
2236
data->pBuf.data = NULL;
2238
file = PR_Open(fn, PR_RDONLY, 00660);
2240
setupIO(arena, data, file, NULL, 0);
2244
get_params(PRArenaPool *arena, bltestParams *params,
2245
bltestCipherMode mode, int j)
2248
char *modestr = mode_strings[mode];
2249
#if NSS_SOFTOKEN_DOES_RC5
2251
char *mark, *param, *val;
2256
case bltestDES_EDE_CBC:
2259
sprintf(filename, "%s/tests/%s/%s%d", testdir, modestr, "iv", j);
2260
load_file_data(arena, ¶ms->sk.iv, filename, bltestBinary);
2262
case bltestDES_EDE_ECB:
2266
sprintf(filename, "%s/tests/%s/%s%d", testdir, modestr, "key", j);
2267
load_file_data(arena, ¶ms->sk.key, filename, bltestBinary);
2269
#if NSS_SOFTOKEN_DOES_RC5
2272
sprintf(filename, "%s/tests/%s/%s%d", testdir, modestr, "iv", j);
2273
load_file_data(arena, ¶ms->sk.iv, filename, bltestBinary);
2274
sprintf(filename, "%s/tests/%s/%s%d", testdir, modestr, "key", j);
2275
load_file_data(arena, ¶ms->sk.key, filename, bltestBinary);
2276
sprintf(filename, "%s/tests/%s/%s%d", testdir, modestr,
2278
file = fopen(filename, "r");
2280
param = malloc(100);
2281
len = fread(param, 1, 100, file);
2282
while (index < len) {
2283
mark = PL_strchr(param, '=');
2286
mark = PL_strchr(val, '\n');
2288
if (PL_strcmp(param, "rounds") == 0) {
2289
params->rc5.rounds = atoi(val);
2290
} else if (PL_strcmp(param, "wordsize") == 0) {
2291
params->rc5.wordsize = atoi(val);
2293
index += PL_strlen(param) + PL_strlen(val) + 2;
2299
sprintf(filename, "%s/tests/%s/%s%d", testdir, modestr, "key", j);
2300
load_file_data(arena, ¶ms->rsa.key, filename, bltestBase64Encoded);
2301
params->rsa.rsakey = rsakey_from_filedata(¶ms->key.buf);
2304
sprintf(filename, "%s/tests/%s/%s%d", testdir, modestr, "key", j);
2305
load_file_data(arena, ¶ms->dsa.key, filename, bltestBase64Encoded);
2306
params->dsa.dsakey = dsakey_from_filedata(¶ms->key.buf);
2307
sprintf(filename, "%s/tests/%s/%s%d", testdir, modestr, "pqg", j);
2308
load_file_data(arena, ¶ms->dsa.pqgdata, filename,
2309
bltestBase64Encoded);
2310
params->dsa.pqg = pqg_from_filedata(¶ms->dsa.pqgdata.buf);
2311
sprintf(filename, "%s/tests/%s/%s%d", testdir, modestr, "keyseed", j);
2312
load_file_data(arena, ¶ms->dsa.keyseed, filename,
2313
bltestBase64Encoded);
2314
sprintf(filename, "%s/tests/%s/%s%d", testdir, modestr, "sigseed", j);
2315
load_file_data(arena, ¶ms->dsa.sigseed, filename,
2316
bltestBase64Encoded);
2317
sprintf(filename, "%s/tests/%s/%s%d", testdir, modestr, "ciphertext",j);
2318
load_file_data(arena, ¶ms->dsa.sig, filename, bltestBase64Encoded);
2320
#ifdef NSS_ENABLE_ECC
2322
sprintf(filename, "%s/tests/%s/%s%d", testdir, modestr, "key", j);
2323
load_file_data(arena, ¶ms->ecdsa.key, filename, bltestBase64Encoded);
2324
params->ecdsa.eckey = eckey_from_filedata(¶ms->key.buf);
2325
sprintf(filename, "%s/tests/%s/%s%d", testdir, modestr, "sigseed", j);
2326
load_file_data(arena, ¶ms->ecdsa.sigseed, filename,
2327
bltestBase64Encoded);
2328
sprintf(filename, "%s/tests/%s/%s%d", testdir, modestr, "ciphertext",j);
2329
load_file_data(arena, ¶ms->ecdsa.sig, filename, bltestBase64Encoded);
2338
/*params->hash.restart = PR_TRUE;*/
2339
params->hash.restart = PR_FALSE;
2347
verify_self_test(bltestIO *result, bltestIO *cmp, bltestCipherMode mode,
2348
PRBool forward, SECStatus sigstatus)
2351
char *modestr = mode_strings[mode];
2352
res = SECITEM_CompareItem(&result->pBuf, &cmp->buf);
2353
if (is_sigCipher(mode)) {
2356
printf("Signature self-test for %s passed.\n", modestr);
2358
printf("Signature self-test for %s failed!\n", modestr);
2361
if (sigstatus == SECSuccess) {
2362
printf("Verification self-test for %s passed.\n", modestr);
2364
printf("Verification self-test for %s failed!\n", modestr);
2368
} else if (is_hashCipher(mode)) {
2370
printf("Hash self-test for %s passed.\n", modestr);
2372
printf("Hash self-test for %s failed!\n", modestr);
2377
printf("Encryption self-test for %s passed.\n", modestr);
2379
printf("Encryption self-test for %s failed!\n", modestr);
2383
printf("Decryption self-test for %s passed.\n", modestr);
2385
printf("Decryption self-test for %s failed!\n", modestr);
2393
blapi_selftest(bltestCipherMode *modes, int numModes, int inoff, int outoff,
2394
PRBool encrypt, PRBool decrypt)
2396
bltestCipherInfo cipherInfo;
2398
bltestCipherMode mode;
2399
bltestParams *params;
2400
int i, j, nummodes, numtests;
2407
SECStatus rv = SECSuccess, srv;
2409
PORT_Memset(&cipherInfo, 0, sizeof(cipherInfo));
2410
arena = PORT_NewArena(BLTEST_DEFAULT_CHUNKSIZE);
2411
cipherInfo.arena = arena;
2413
finished = PR_FALSE;
2414
nummodes = (numModes == 0) ? NUMMODES : numModes;
2415
for (i=0; i < nummodes && !finished; i++) {
2416
if (i == bltestRC5_ECB || i == bltestRC5_CBC) continue;
2421
if (mode == bltestINVALID) {
2422
fprintf(stderr, "%s: Skipping invalid mode.\n",progName);
2425
modestr = mode_strings[mode];
2426
cipherInfo.mode = mode;
2427
params = &cipherInfo.params;
2428
#ifdef TRACK_BLTEST_BUG
2429
if (mode == bltestRSA) {
2430
fprintf(stderr, "[%s] Self-Testing RSA\n", __bltDBG);
2433
/* get the number of tests in the directory */
2434
sprintf(filename, "%s/tests/%s/%s", testdir, modestr, "numtests");
2435
file = PR_Open(filename, PR_RDONLY, 00660);
2437
fprintf(stderr, "%s: File %s does not exist.\n", progName,filename);
2440
rv = SECU_FileToItem(&item, file);
2441
#ifdef TRACK_BLTEST_BUG
2442
if (mode == bltestRSA) {
2443
fprintf(stderr, "[%s] Loaded data from %s\n", __bltDBG, filename);
2447
/* loop over the tests in the directory */
2448
numtests = (int) (item.data[0] - '0');
2449
for (j=1; j<item.len - 1; j++) {
2451
numtests += (int) (item.data[j] - '0');
2453
for (j=0; j<numtests; j++) {
2454
#ifdef TRACK_BLTEST_BUG
2455
if (mode == bltestRSA) {
2456
fprintf(stderr, "[%s] Executing self-test #%d\n", __bltDBG, j);
2459
sprintf(filename, "%s/tests/%s/%s%d", testdir, modestr,
2461
load_file_data(arena, &pt, filename,
2462
#ifdef NSS_ENABLE_ECC
2463
((mode == bltestDSA) || (mode == bltestECDSA))
2467
? bltestBase64Encoded : bltestBinary);
2468
sprintf(filename, "%s/tests/%s/%s%d", testdir, modestr,
2470
load_file_data(arena, &ct, filename, bltestBase64Encoded);
2471
#ifdef TRACK_BLTEST_BUG
2472
if (mode == bltestRSA) {
2473
fprintf(stderr, "[%s] Loaded data for self-test #%d\n", __bltDBG, j);
2476
get_params(arena, params, mode, j);
2477
#ifdef TRACK_BLTEST_BUG
2478
if (mode == bltestRSA) {
2479
fprintf(stderr, "[%s] Got parameters for #%d\n", __bltDBG, j);
2482
/* Forward Operation (Encrypt/Sign/Hash)
2483
** Align the input buffer (plaintext) according to request
2484
** then perform operation and compare to ciphertext
2489
bltestCopyIO(arena, &cipherInfo.input, &pt);
2490
misalignBuffer(arena, &cipherInfo.input, inoff);
2491
memset(&cipherInfo.output.buf, 0, sizeof cipherInfo.output.buf);
2492
rv |= cipherInit(&cipherInfo, PR_TRUE);
2493
misalignBuffer(arena, &cipherInfo.output, outoff);
2494
#ifdef TRACK_BLTEST_BUG
2495
if (mode == bltestRSA) {
2496
fprintf(stderr, "[%s] Inited cipher context and buffers for #%d\n", __bltDBG, j);
2499
rv |= cipherDoOp(&cipherInfo);
2500
#ifdef TRACK_BLTEST_BUG
2501
if (mode == bltestRSA) {
2502
fprintf(stderr, "[%s] Performed encrypt for #%d\n", __bltDBG, j);
2505
rv |= cipherFinish(&cipherInfo);
2506
#ifdef TRACK_BLTEST_BUG
2507
if (mode == bltestRSA) {
2508
fprintf(stderr, "[%s] Finished encrypt for #%d\n", __bltDBG, j);
2511
rv |= verify_self_test(&cipherInfo.output,
2512
&ct, mode, PR_TRUE, 0);
2513
#ifdef TRACK_BLTEST_BUG
2514
if (mode == bltestRSA) {
2515
fprintf(stderr, "[%s] Verified self-test for #%d\n", __bltDBG, j);
2518
/* If testing hash, only one op to test */
2519
if (is_hashCipher(mode))
2521
/*if (rv) return rv;*/
2527
/* Reverse Operation (Decrypt/Verify)
2528
** Align the input buffer (ciphertext) according to request
2529
** then perform operation and compare to plaintext
2531
#ifdef NSS_ENABLE_ECC
2532
if ((mode != bltestDSA) && (mode != bltestECDSA))
2534
if (mode != bltestDSA)
2536
bltestCopyIO(arena, &cipherInfo.input, &ct);
2538
bltestCopyIO(arena, &cipherInfo.input, &pt);
2539
misalignBuffer(arena, &cipherInfo.input, inoff);
2540
memset(&cipherInfo.output.buf, 0, sizeof cipherInfo.output.buf);
2541
rv |= cipherInit(&cipherInfo, PR_FALSE);
2542
misalignBuffer(arena, &cipherInfo.output, outoff);
2543
#ifdef TRACK_BLTEST_BUG
2544
if (mode == bltestRSA) {
2545
fprintf(stderr, "[%s] Inited cipher context and buffers for #%d\n", __bltDBG, j);
2549
srv |= cipherDoOp(&cipherInfo);
2550
#ifdef TRACK_BLTEST_BUG
2551
if (mode == bltestRSA) {
2552
fprintf(stderr, "[%s] Performed decrypt for #%d\n", __bltDBG, j);
2555
rv |= cipherFinish(&cipherInfo);
2556
#ifdef TRACK_BLTEST_BUG
2557
if (mode == bltestRSA) {
2558
fprintf(stderr, "[%s] Finished decrypt for #%d\n", __bltDBG, j);
2561
rv |= verify_self_test(&cipherInfo.output,
2562
&pt, mode, PR_FALSE, srv);
2563
#ifdef TRACK_BLTEST_BUG
2564
if (mode == bltestRSA) {
2565
fprintf(stderr, "[%s] Verified self-test for #%d\n", __bltDBG, j);
2568
/*if (rv) return rv;*/
2575
dump_file(bltestCipherMode mode, char *filename)
2578
PRArenaPool *arena = NULL;
2579
arena = PORT_NewArena(BLTEST_DEFAULT_CHUNKSIZE);
2580
if (mode == bltestRSA) {
2582
load_file_data(arena, &keydata, filename, bltestBase64Encoded);
2583
key = rsakey_from_filedata(&keydata.buf);
2585
} else if (mode == bltestDSA) {
2588
get_file_data(filename, &item, PR_TRUE);
2589
pqg = pqg_from_filedata(&item);
2593
load_file_data(arena, &keydata, filename, bltestBase64Encoded);
2594
key = dsakey_from_filedata(&keydata.buf);
2596
#ifdef NSS_ENABLE_ECC
2597
} else if (mode == bltestECDSA) {
2599
load_file_data(arena, &keydata, filename, bltestBase64Encoded);
2600
key = eckey_from_filedata(&keydata.buf);
2604
PORT_FreeArena(arena, PR_FALSE);
2608
/* bltest commands */
2621
/* bltest options */
2636
#ifdef NSS_ENABLE_ECC
2657
static secuCommandFlag bltest_commands[] =
2659
{ /* cmd_Decrypt */ 'D', PR_FALSE, 0, PR_FALSE },
2660
{ /* cmd_Encrypt */ 'E', PR_FALSE, 0, PR_FALSE },
2661
{ /* cmd_FIPS */ 'F', PR_FALSE, 0, PR_FALSE },
2662
{ /* cmd_Hash */ 'H', PR_FALSE, 0, PR_FALSE },
2663
{ /* cmd_Nonce */ 'N', PR_FALSE, 0, PR_FALSE },
2664
{ /* cmd_Dump */ 'P', PR_FALSE, 0, PR_FALSE },
2665
{ /* cmd_Sign */ 'S', PR_FALSE, 0, PR_FALSE },
2666
{ /* cmd_SelfTest */ 'T', PR_FALSE, 0, PR_FALSE },
2667
{ /* cmd_Verify */ 'V', PR_FALSE, 0, PR_FALSE }
2670
static secuCommandFlag bltest_options[] =
2672
{ /* opt_B64 */ 'a', PR_FALSE, 0, PR_FALSE },
2673
{ /* opt_BufSize */ 'b', PR_TRUE, 0, PR_FALSE },
2674
{ /* opt_Restart */ 'c', PR_FALSE, 0, PR_FALSE },
2675
{ /* opt_SelfTestDir */ 'd', PR_TRUE, 0, PR_FALSE },
2676
{ /* opt_Exponent */ 'e', PR_TRUE, 0, PR_FALSE },
2677
{ /* opt_SigFile */ 'f', PR_TRUE, 0, PR_FALSE },
2678
{ /* opt_KeySize */ 'g', PR_TRUE, 0, PR_FALSE },
2679
{ /* opt_Hex */ 'h', PR_FALSE, 0, PR_FALSE },
2680
{ /* opt_Input */ 'i', PR_TRUE, 0, PR_FALSE },
2681
{ /* opt_PQGFile */ 'j', PR_TRUE, 0, PR_FALSE },
2682
{ /* opt_Key */ 'k', PR_TRUE, 0, PR_FALSE },
2683
{ /* opt_HexWSpc */ 'l', PR_FALSE, 0, PR_FALSE },
2684
{ /* opt_Mode */ 'm', PR_TRUE, 0, PR_FALSE },
2685
#ifdef NSS_ENABLE_ECC
2686
{ /* opt_CurveName */ 'n', PR_TRUE, 0, PR_FALSE },
2688
{ /* opt_Output */ 'o', PR_TRUE, 0, PR_FALSE },
2689
{ /* opt_Repetitions */ 'p', PR_TRUE, 0, PR_FALSE },
2690
{ /* opt_ZeroBuf */ 'q', PR_FALSE, 0, PR_FALSE },
2691
{ /* opt_Rounds */ 'r', PR_TRUE, 0, PR_FALSE },
2692
{ /* opt_Seed */ 's', PR_TRUE, 0, PR_FALSE },
2693
{ /* opt_SigSeedFile */ 't', PR_TRUE, 0, PR_FALSE },
2694
{ /* opt_CXReps */ 'u', PR_TRUE, 0, PR_FALSE },
2695
{ /* opt_IV */ 'v', PR_TRUE, 0, PR_FALSE },
2696
{ /* opt_WordSize */ 'w', PR_TRUE, 0, PR_FALSE },
2697
{ /* opt_UseSeed */ 'x', PR_FALSE, 0, PR_FALSE },
2698
{ /* opt_UseSigSeed */ 'y', PR_FALSE, 0, PR_FALSE },
2699
{ /* opt_SeedFile */ 'z', PR_FALSE, 0, PR_FALSE },
2700
{ /* opt_InputOffset */ '1', PR_TRUE, 0, PR_FALSE },
2701
{ /* opt_OutputOffset */ '2', PR_TRUE, 0, PR_FALSE },
2702
{ /* opt_MonteCarlo */ '3', PR_FALSE, 0, PR_FALSE },
2703
{ /* opt_CmdLine */ '-', PR_FALSE, 0, PR_FALSE }
2706
int main(int argc, char **argv)
2708
char *infileName, *outfileName, *keyfileName, *ivfileName;
2711
bltestCipherInfo cipherInfo;
2712
bltestParams *params;
2713
PRFileDesc *file, *infile, *outfile;
2716
bltestIOMode ioMode;
2717
int keysize, bufsize, exponent;
2718
#ifdef NSS_ENABLE_ECC
2719
char *curveName = NULL;
2721
int i, commandsEntered;
2725
bltest.numCommands = sizeof(bltest_commands) / sizeof(secuCommandFlag);
2726
bltest.numOptions = sizeof(bltest_options) / sizeof(secuCommandFlag);
2727
bltest.commands = bltest_commands;
2728
bltest.options = bltest_options;
2730
progName = strrchr(argv[0], '/');
2732
progName = strrchr(argv[0], '\\');
2733
progName = progName ? progName+1 : argv[0];
2736
if (rv != SECSuccess) {
2737
SECU_PrintPRandOSError(progName);
2740
RNG_SystemInfoForRNG();
2742
rv = SECU_ParseCommandLine(argc, argv, progName, &bltest);
2744
PORT_Memset(&cipherInfo, 0, sizeof(cipherInfo));
2745
arena = PORT_NewArena(BLTEST_DEFAULT_CHUNKSIZE);
2746
cipherInfo.arena = arena;
2747
params = &cipherInfo.params;
2748
/* set some defaults */
2749
infileName = outfileName = keyfileName = ivfileName = NULL;
2751
/* Check the number of commands entered on the command line. */
2752
commandsEntered = 0;
2753
for (i=0; i<bltest.numCommands; i++)
2754
if (bltest.commands[i].activated)
2757
if (commandsEntered > 1 &&
2758
!(commandsEntered == 2 && bltest.commands[cmd_SelfTest].activated)) {
2759
fprintf(stderr, "%s: one command at a time!\n", progName);
2762
if (commandsEntered == 0) {
2763
fprintf(stderr, "%s: you must enter a command!\n", progName);
2767
if (bltest.commands[cmd_Sign].activated)
2768
bltest.commands[cmd_Encrypt].activated = PR_TRUE;
2769
if (bltest.commands[cmd_Verify].activated)
2770
bltest.commands[cmd_Decrypt].activated = PR_TRUE;
2771
if (bltest.commands[cmd_Hash].activated)
2772
bltest.commands[cmd_Encrypt].activated = PR_TRUE;
2775
if (bltest.options[opt_InputOffset].activated)
2776
inoff = PORT_Atoi(bltest.options[opt_InputOffset].arg);
2777
if (bltest.options[opt_OutputOffset].activated)
2778
outoff = PORT_Atoi(bltest.options[opt_OutputOffset].arg);
2780
testdir = (bltest.options[opt_SelfTestDir].activated) ?
2781
strdup(bltest.options[opt_SelfTestDir].arg) : ".";
2784
* Handle three simple cases first
2787
/* Do BLAPI self-test */
2788
if (bltest.commands[cmd_SelfTest].activated) {
2789
PRBool encrypt = PR_TRUE, decrypt = PR_TRUE;
2790
/* user may specified a set of ciphers to test. parse them. */
2791
bltestCipherMode modesToTest[NUMMODES];
2792
int numModesToTest = 0;
2794
str = bltest.options[opt_Mode].arg;
2796
tok = strchr(str, ',');
2797
if (tok) *tok = '\0';
2798
modesToTest[numModesToTest++] = get_mode(str);
2806
if (bltest.commands[cmd_Decrypt].activated &&
2807
!bltest.commands[cmd_Encrypt].activated)
2809
if (bltest.commands[cmd_Encrypt].activated &&
2810
!bltest.commands[cmd_Decrypt].activated)
2812
return blapi_selftest(modesToTest, numModesToTest, inoff, outoff,
2816
/* Do FIPS self-test */
2817
if (bltest.commands[cmd_FIPS].activated) {
2818
CK_RV ckrv = pk11_fipsPowerUpSelfTest();
2819
fprintf(stdout, "CK_RV: %ld.\n", ckrv);
2824
* Check command line arguments for Encrypt/Decrypt/Hash/Sign/Verify
2827
if ((bltest.commands[cmd_Decrypt].activated ||
2828
bltest.commands[cmd_Verify].activated) &&
2829
bltest.options[opt_BufSize].activated) {
2830
fprintf(stderr, "%s: cannot use a nonce as input to decrypt/verify.\n",
2835
if (bltest.options[opt_Mode].activated) {
2836
cipherInfo.mode = get_mode(bltest.options[opt_Mode].arg);
2837
if (cipherInfo.mode == bltestINVALID) {
2838
fprintf(stderr, "%s: Invalid mode \"%s\"\n", progName,
2839
bltest.options[opt_Mode].arg);
2843
fprintf(stderr, "%s: You must specify a cipher mode with -m.\n",
2848
if (bltest.options[opt_Repetitions].activated) {
2849
cipherInfo.repetitions = PORT_Atoi(bltest.options[opt_Repetitions].arg);
2851
cipherInfo.repetitions = 0;
2855
if (bltest.options[opt_CXReps].activated) {
2856
cipherInfo.cxreps = PORT_Atoi(bltest.options[opt_CXReps].arg);
2858
cipherInfo.cxreps = 0;
2861
/* Dump a file (rsakey, dsakey, etc.) */
2862
if (bltest.commands[cmd_Dump].activated) {
2863
return dump_file(cipherInfo.mode, bltest.options[opt_Input].arg);
2866
/* default input mode is binary */
2867
ioMode = (bltest.options[opt_B64].activated) ? bltestBase64Encoded :
2868
(bltest.options[opt_Hex].activated) ? bltestHexStream :
2869
(bltest.options[opt_HexWSpc].activated) ? bltestHexSpaceDelim :
2872
if (bltest.options[opt_KeySize].activated)
2873
keysize = PORT_Atoi(bltest.options[opt_KeySize].arg);
2877
if (bltest.options[opt_Exponent].activated)
2878
exponent = PORT_Atoi(bltest.options[opt_Exponent].arg);
2882
#ifdef NSS_ENABLE_ECC
2883
if (bltest.options[opt_CurveName].activated)
2884
curveName = PORT_Strdup(bltest.options[opt_CurveName].arg);
2889
/* Set up an encryption key. */
2892
if (is_symmkeyCipher(cipherInfo.mode)) {
2893
char *keystr = NULL; /* if key is on command line */
2894
if (bltest.options[opt_Key].activated) {
2895
if (bltest.options[opt_CmdLine].activated) {
2896
keystr = bltest.options[opt_Key].arg;
2898
file = PR_Open(bltest.options[opt_Key].arg, PR_RDONLY, 00660);
2901
if (bltest.options[opt_KeySize].activated)
2902
keysize = PORT_Atoi(bltest.options[opt_KeySize].arg);
2904
keysize = 8; /* use 64-bit default (DES) */
2905
/* save the random key for reference */
2906
file = PR_Open("tmp.key", PR_WRONLY|PR_CREATE_FILE, 00660);
2908
params->key.mode = ioMode;
2909
setupIO(cipherInfo.arena, ¶ms->key, file, keystr, keysize);
2912
} else if (is_pubkeyCipher(cipherInfo.mode)) {
2913
if (bltest.options[opt_Key].activated) {
2914
file = PR_Open(bltest.options[opt_Key].arg, PR_RDONLY, 00660);
2916
if (bltest.options[opt_KeySize].activated)
2917
keysize = PORT_Atoi(bltest.options[opt_KeySize].arg);
2919
keysize = 64; /* use 512-bit default */
2920
file = PR_Open("tmp.key", PR_WRONLY|PR_CREATE_FILE, 00660);
2922
params->key.mode = bltestBase64Encoded;
2923
#ifdef NSS_ENABLE_ECC
2924
pubkeyInitKey(&cipherInfo, file, keysize, exponent, curveName);
2926
pubkeyInitKey(&cipherInfo, file, keysize, exponent);
2931
/* set up an initialization vector. */
2932
if (cipher_requires_IV(cipherInfo.mode)) {
2934
bltestSymmKeyParams *skp;
2936
if (cipherInfo.mode == bltestRC5_CBC)
2937
skp = (bltestSymmKeyParams *)¶ms->rc5;
2940
if (bltest.options[opt_IV].activated) {
2941
if (bltest.options[opt_CmdLine].activated) {
2942
ivstr = bltest.options[opt_IV].arg;
2944
file = PR_Open(bltest.options[opt_IV].arg, PR_RDONLY, 00660);
2947
/* save the random iv for reference */
2948
file = PR_Open("tmp.iv", PR_WRONLY|PR_CREATE_FILE, 00660);
2950
memset(&skp->iv, 0, sizeof skp->iv);
2951
skp->iv.mode = ioMode;
2952
setupIO(cipherInfo.arena, &skp->iv, file, ivstr, keysize);
2957
if (bltest.commands[cmd_Verify].activated) {
2958
if (!bltest.options[opt_SigFile].activated) {
2959
fprintf(stderr, "%s: You must specify a signature file with -f.\n",
2963
file = PR_Open(bltest.options[opt_SigFile].arg, PR_RDONLY, 00660);
2964
if (cipherInfo.mode == bltestDSA) {
2965
memset(&cipherInfo.params.dsa.sig, 0, sizeof(bltestIO));
2966
cipherInfo.params.dsa.sig.mode = ioMode;
2967
setupIO(cipherInfo.arena, &cipherInfo.params.dsa.sig, file, NULL, 0);
2968
#ifdef NSS_ENABLE_ECC
2969
} else if (cipherInfo.mode == bltestECDSA) {
2970
memset(&cipherInfo.params.ecdsa.sig, 0, sizeof(bltestIO));
2971
cipherInfo.params.ecdsa.sig.mode = ioMode;
2972
setupIO(cipherInfo.arena, &cipherInfo.params.ecdsa.sig, file, NULL, 0);
2977
if (bltest.options[opt_PQGFile].activated) {
2978
file = PR_Open(bltest.options[opt_PQGFile].arg, PR_RDONLY, 00660);
2979
params->dsa.pqgdata.mode = bltestBase64Encoded;
2980
setupIO(cipherInfo.arena, ¶ms->dsa.pqgdata, file, NULL, 0);
2983
/* Set up the input buffer */
2984
if (bltest.options[opt_Input].activated) {
2985
if (bltest.options[opt_CmdLine].activated) {
2986
instr = bltest.options[opt_Input].arg;
2989
/* form file name from testdir and input arg. */
2990
char * filename = bltest.options[opt_Input].arg;
2991
if (bltest.options[opt_SelfTestDir].activated &&
2992
testdir && filename && filename[0] != '/')
2993
filename = PR_smprintf("%s/tests/%s/%s", testdir,
2994
mode_strings[cipherInfo.mode], filename);
2995
infile = PR_Open(filename, PR_RDONLY, 00660);
2997
} else if (bltest.options[opt_BufSize].activated) {
2998
/* save the random plaintext for reference */
2999
infile = PR_Open("tmp.in", PR_WRONLY|PR_CREATE_FILE, 00660);
3004
fprintf(stderr, "%s: Failed to open input file.\n", progName);
3007
cipherInfo.input.mode = ioMode;
3009
/* Set up the output stream */
3010
if (bltest.options[opt_Output].activated) {
3011
/* form file name from testdir and input arg. */
3012
char * filename = bltest.options[opt_Output].arg;
3013
if (bltest.options[opt_SelfTestDir].activated &&
3014
testdir && filename && filename[0] != '/')
3015
filename = PR_smprintf("%s/tests/%s/%s", testdir,
3016
mode_strings[cipherInfo.mode], filename);
3017
outfile = PR_Open(filename, PR_WRONLY|PR_CREATE_FILE, 00660);
3019
outfile = PR_STDOUT;
3022
fprintf(stderr, "%s: Failed to open output file.\n", progName);
3025
cipherInfo.output.mode = ioMode;
3026
if (bltest.options[opt_SelfTestDir].activated && ioMode == bltestBinary)
3027
cipherInfo.output.mode = bltestBase64Encoded;
3029
if (is_hashCipher(cipherInfo.mode))
3030
cipherInfo.params.hash.restart = bltest.options[opt_Restart].activated;
3033
if (bltest.options[opt_BufSize].activated)
3034
bufsize = PORT_Atoi(bltest.options[opt_BufSize].arg);
3037
setupIO(cipherInfo.arena, &cipherInfo.input, infile, instr, bufsize);
3038
misalignBuffer(cipherInfo.arena, &cipherInfo.input, inoff);
3040
cipherInit(&cipherInfo, bltest.commands[cmd_Encrypt].activated);
3041
misalignBuffer(cipherInfo.arena, &cipherInfo.output, outoff);
3043
if (!bltest.commands[cmd_Nonce].activated) {
3044
if (bltest.options[opt_MonteCarlo].activated) {
3046
for (mciter=0; mciter<10000; mciter++) {
3047
cipherDoOp(&cipherInfo);
3048
memcpy(cipherInfo.input.buf.data,
3049
cipherInfo.output.buf.data,
3050
cipherInfo.input.buf.len);
3053
cipherDoOp(&cipherInfo);
3055
cipherFinish(&cipherInfo);
3056
finishIO(&cipherInfo.output, outfile);
3059
if (cipherInfo.repetitions > 0 || cipherInfo.cxreps > 0)
3060
dump_performance_info(&cipherInfo,
3061
bltest.commands[cmd_Encrypt].activated,
3062
(cipherInfo.repetitions == 0));
3064
if (infile && infile != PR_STDIN)
3066
if (outfile && outfile != PR_STDOUT)
3068
PORT_FreeArena(cipherInfo.arena, PR_TRUE);