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