nss: import at 3.0.1 beta 1
[mozilla-nss.git] / security / nss / cmd / bltest / blapitest.c
blob223c39a659f4e7ba857fd3c7e70edf4a638dc747
1 /* ***** BEGIN LICENSE BLOCK *****
2 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
4 * The contents of this file are subject to the Mozilla Public License Version
5 * 1.1 (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 * http://www.mozilla.org/MPL/
9 * Software distributed under the License is distributed on an "AS IS" basis,
10 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
11 * for the specific language governing rights and limitations under the
12 * License.
14 * The Original Code is the Netscape security libraries.
16 * The Initial Developer of the Original Code is
17 * Netscape Communications Corporation.
18 * Portions created by the Initial Developer are Copyright (C) 1994-2000
19 * the Initial Developer. All Rights Reserved.
21 * Contributor(s):
22 * Douglas Stebila <douglas@stebila.ca>, Sun Microsystems Laboratories
24 * Alternatively, the contents of this file may be used under the terms of
25 * either the GNU General Public License Version 2 or later (the "GPL"), or
26 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
27 * in which case the provisions of the GPL or the LGPL are applicable instead
28 * of those above. If you wish to allow use of your version of this file only
29 * under the terms of either the GPL or the LGPL, and not to allow others to
30 * use your version of this file under the terms of the MPL, indicate your
31 * decision by deleting the provisions above and replace them with the notice
32 * and other provisions required by the GPL or the LGPL. If you do not delete
33 * the provisions above, a recipient may use your version of this file under
34 * the terms of any one of the MPL, the GPL or the LGPL.
36 * ***** END LICENSE BLOCK ***** */
38 #include <stdio.h>
39 #include <stdlib.h>
41 #include "blapi.h"
42 #include "secrng.h"
43 #include "prmem.h"
44 #include "prprf.h"
45 #include "prtime.h"
46 #include "prsystem.h"
47 #include "plstr.h"
48 #include "nssb64.h"
49 #include "secutil.h"
50 #include "plgetopt.h"
51 #include "softoken.h"
52 #include "nspr.h"
53 #include "nss.h"
54 #include "secoid.h"
56 #ifdef NSS_ENABLE_ECC
57 #include "ecl-curve.h"
58 SECStatus EC_DecodeParams(const SECItem *encodedParams,
59 ECParams **ecparams);
60 SECStatus EC_CopyParams(PRArenaPool *arena, ECParams *dstParams,
61 const ECParams *srcParams);
62 #endif
64 /* Temporary - add debugging ouput on windows for RSA to track QA failure */
65 #ifdef _WIN32
66 #define TRACK_BLTEST_BUG
67 char __bltDBG[] = "BLTEST DEBUG";
68 #endif
70 char *progName;
71 char *testdir = NULL;
73 #define BLTEST_DEFAULT_CHUNKSIZE 4096
75 #define WORDSIZE sizeof(unsigned long)
77 #define CHECKERROR(rv, ln) \
78 if (rv) { \
79 PRErrorCode prerror = PR_GetError(); \
80 PR_fprintf(PR_STDERR, "%s: ERR %d (%s) at line %d.\n", progName, \
81 prerror, SECU_Strerror(prerror), ln); \
82 exit(-1); \
85 /* Macros for performance timing. */
86 #define TIMESTART() \
87 time1 = PR_IntervalNow();
89 #define TIMEFINISH(time, reps) \
90 time2 = (PRIntervalTime)(PR_IntervalNow() - time1); \
91 time1 = PR_IntervalToMilliseconds(time2); \
92 time = ((double)(time1))/reps;
94 #define TIMEMARK(seconds) \
95 time1 = PR_SecondsToInterval(seconds); \
96 { \
97 PRInt64 tmp, L100; \
98 LL_I2L(L100, 100); \
99 if (time2 == 0) { \
100 time2 = 1; \
102 LL_DIV(tmp, time1, time2); \
103 if (tmp < 10) { \
104 if (tmp == 0) { \
105 opsBetweenChecks = 1; \
106 } else { \
107 LL_L2I(opsBetweenChecks, tmp); \
109 } else { \
110 opsBetweenChecks = 10; \
113 time2 = time1; \
114 time1 = PR_IntervalNow();
116 #define TIMETOFINISH() \
117 PR_IntervalNow() - time1 >= time2
119 static void Usage()
121 #define PRINTUSAGE(subject, option, predicate) \
122 fprintf(stderr, "%10s %s\t%s\n", subject, option, predicate);
123 fprintf(stderr, "\n");
124 PRINTUSAGE(progName, "[-DEHSV]", "List available cipher modes"); /* XXX */
125 fprintf(stderr, "\n");
126 PRINTUSAGE(progName, "-E -m mode ", "Encrypt a buffer");
127 PRINTUSAGE("", "", "[-i plaintext] [-o ciphertext] [-k key] [-v iv]");
128 PRINTUSAGE("", "", "[-b bufsize] [-g keysize] [-e exp] [-r rounds]");
129 PRINTUSAGE("", "", "[-w wordsize] [-p repetitions | -5 time_interval]");
130 PRINTUSAGE("", "", "[-4 th_num]");
131 PRINTUSAGE("", "-m", "cipher mode to use");
132 PRINTUSAGE("", "-i", "file which contains input buffer");
133 PRINTUSAGE("", "-o", "file for output buffer");
134 PRINTUSAGE("", "-k", "file which contains key");
135 PRINTUSAGE("", "-v", "file which contains initialization vector");
136 PRINTUSAGE("", "-b", "size of input buffer");
137 PRINTUSAGE("", "-g", "key size (in bytes)");
138 PRINTUSAGE("", "-p", "do performance test");
139 PRINTUSAGE("", "-4", "run test in multithread mode. th_num number of parallel threads");
140 PRINTUSAGE("", "-5", "run test for specified time interval(in seconds)");
141 PRINTUSAGE("(rsa)", "-e", "rsa public exponent");
142 PRINTUSAGE("(rc5)", "-r", "number of rounds");
143 PRINTUSAGE("(rc5)", "-w", "wordsize (32 or 64)");
144 fprintf(stderr, "\n");
145 PRINTUSAGE(progName, "-D -m mode", "Decrypt a buffer");
146 PRINTUSAGE("", "", "[-i plaintext] [-o ciphertext] [-k key] [-v iv]");
147 PRINTUSAGE("", "", "[-p repetitions | -5 time_interval] [-4 th_num]");
148 PRINTUSAGE("", "-m", "cipher mode to use");
149 PRINTUSAGE("", "-i", "file which contains input buffer");
150 PRINTUSAGE("", "-o", "file for output buffer");
151 PRINTUSAGE("", "-k", "file which contains key");
152 PRINTUSAGE("", "-v", "file which contains initialization vector");
153 PRINTUSAGE("", "-p", "do performance test");
154 PRINTUSAGE("", "-4", "run test in multithread mode. th_num number of parallel threads");
155 PRINTUSAGE("", "-5", "run test for specified time interval(in seconds)");
156 fprintf(stderr, "\n");
157 PRINTUSAGE(progName, "-H -m mode", "Hash a buffer");
158 PRINTUSAGE("", "", "[-i plaintext] [-o hash]");
159 PRINTUSAGE("", "", "[-b bufsize]");
160 PRINTUSAGE("", "", "[-p repetitions | -5 time_interval] [-4 th_num]");
161 PRINTUSAGE("", "-m", "cipher mode to use");
162 PRINTUSAGE("", "-i", "file which contains input buffer");
163 PRINTUSAGE("", "-o", "file for hash");
164 PRINTUSAGE("", "-b", "size of input buffer");
165 PRINTUSAGE("", "-p", "do performance test");
166 PRINTUSAGE("", "-4", "run test in multithread mode. th_num number of parallel threads");
167 PRINTUSAGE("", "-5", "run test for specified time interval(in seconds)");
168 fprintf(stderr, "\n");
169 PRINTUSAGE(progName, "-S -m mode", "Sign a buffer");
170 PRINTUSAGE("", "", "[-i plaintext] [-o signature] [-k key]");
171 PRINTUSAGE("", "", "[-b bufsize]");
172 #ifdef NSS_ENABLE_ECC
173 PRINTUSAGE("", "", "[-n curvename]");
174 #endif
175 PRINTUSAGE("", "", "[-p repetitions | -5 time_interval] [-4 th_num]");
176 PRINTUSAGE("", "-m", "cipher mode to use");
177 PRINTUSAGE("", "-i", "file which contains input buffer");
178 PRINTUSAGE("", "-o", "file for signature");
179 PRINTUSAGE("", "-k", "file which contains key");
180 #ifdef NSS_ENABLE_ECC
181 PRINTUSAGE("", "-n", "name of curve for EC key generation; one of:");
182 PRINTUSAGE("", "", " sect163k1, nistk163, sect163r1, sect163r2,");
183 PRINTUSAGE("", "", " nistb163, sect193r1, sect193r2, sect233k1, nistk233,");
184 PRINTUSAGE("", "", " sect233r1, nistb233, sect239k1, sect283k1, nistk283,");
185 PRINTUSAGE("", "", " sect283r1, nistb283, sect409k1, nistk409, sect409r1,");
186 PRINTUSAGE("", "", " nistb409, sect571k1, nistk571, sect571r1, nistb571,");
187 PRINTUSAGE("", "", " secp160k1, secp160r1, secp160r2, secp192k1, secp192r1,");
188 PRINTUSAGE("", "", " nistp192, secp224k1, secp224r1, nistp224, secp256k1,");
189 PRINTUSAGE("", "", " secp256r1, nistp256, secp384r1, nistp384, secp521r1,");
190 PRINTUSAGE("", "", " nistp521, prime192v1, prime192v2, prime192v3,");
191 PRINTUSAGE("", "", " prime239v1, prime239v2, prime239v3, c2pnb163v1,");
192 PRINTUSAGE("", "", " c2pnb163v2, c2pnb163v3, c2pnb176v1, c2tnb191v1,");
193 PRINTUSAGE("", "", " c2tnb191v2, c2tnb191v3, c2onb191v4, c2onb191v5,");
194 PRINTUSAGE("", "", " c2pnb208w1, c2tnb239v1, c2tnb239v2, c2tnb239v3,");
195 PRINTUSAGE("", "", " c2onb239v4, c2onb239v5, c2pnb272w1, c2pnb304w1,");
196 PRINTUSAGE("", "", " c2tnb359w1, c2pnb368w1, c2tnb431r1, secp112r1,");
197 PRINTUSAGE("", "", " secp112r2, secp128r1, secp128r2, sect113r1, sect113r2,");
198 PRINTUSAGE("", "", " sect131r1, sect131r2");
199 #endif
200 PRINTUSAGE("", "-p", "do performance test");
201 PRINTUSAGE("", "-4", "run test in multithread mode. th_num number of parallel threads");
202 PRINTUSAGE("", "-5", "run test for specified time interval(in seconds)");
203 fprintf(stderr, "\n");
204 PRINTUSAGE(progName, "-V -m mode", "Verify a signed buffer");
205 PRINTUSAGE("", "", "[-i plaintext] [-s signature] [-k key]");
206 PRINTUSAGE("", "", "[-p repetitions | -5 time_interval] [-4 th_num]");
207 PRINTUSAGE("", "-m", "cipher mode to use");
208 PRINTUSAGE("", "-i", "file which contains input buffer");
209 PRINTUSAGE("", "-s", "file which contains signature of input buffer");
210 PRINTUSAGE("", "-k", "file which contains key");
211 PRINTUSAGE("", "-p", "do performance test");
212 PRINTUSAGE("", "-4", "run test in multithread mode. th_num number of parallel threads");
213 PRINTUSAGE("", "-5", "run test for specified time interval(in seconds)");
214 fprintf(stderr, "\n");
215 PRINTUSAGE(progName, "-N -m mode -b bufsize",
216 "Create a nonce plaintext and key");
217 PRINTUSAGE("", "", "[-g keysize] [-u cxreps]");
218 PRINTUSAGE("", "-g", "key size (in bytes)");
219 PRINTUSAGE("", "-u", "number of repetitions of context creation");
220 fprintf(stderr, "\n");
221 PRINTUSAGE(progName, "-F", "Run the FIPS self-test");
222 fprintf(stderr, "\n");
223 PRINTUSAGE(progName, "-T [-m mode1,mode2...]", "Run the BLAPI self-test");
224 fprintf(stderr, "\n");
225 exit(1);
228 /* Helper functions for ascii<-->binary conversion/reading/writing */
230 /* XXX argh */
231 struct item_with_arena {
232 SECItem *item;
233 PRArenaPool *arena;
236 static PRInt32
237 get_binary(void *arg, const unsigned char *ibuf, PRInt32 size)
239 struct item_with_arena *it = arg;
240 SECItem *binary = it->item;
241 SECItem *tmp;
242 int index;
243 if (binary->data == NULL) {
244 tmp = SECITEM_AllocItem(it->arena, NULL, size);
245 binary->data = tmp->data;
246 binary->len = tmp->len;
247 index = 0;
248 } else {
249 SECITEM_ReallocItem(NULL, binary, binary->len, binary->len + size);
250 index = binary->len;
252 PORT_Memcpy(&binary->data[index], ibuf, size);
253 return binary->len;
256 static SECStatus
257 atob(SECItem *ascii, SECItem *binary, PRArenaPool *arena)
259 SECStatus status;
260 NSSBase64Decoder *cx;
261 struct item_with_arena it;
262 int len;
263 binary->data = NULL;
264 binary->len = 0;
265 it.item = binary;
266 it.arena = arena;
267 len = (strncmp(&ascii->data[ascii->len-2],"\r\n",2)) ?
268 ascii->len : ascii->len-2;
269 cx = NSSBase64Decoder_Create(get_binary, &it);
270 status = NSSBase64Decoder_Update(cx, (const char *)ascii->data, len);
271 status = NSSBase64Decoder_Destroy(cx, PR_FALSE);
272 return status;
275 static PRInt32
276 output_ascii(void *arg, const char *obuf, PRInt32 size)
278 PRFileDesc *outfile = arg;
279 PRInt32 nb = PR_Write(outfile, obuf, size);
280 if (nb != size) {
281 PORT_SetError(SEC_ERROR_IO);
282 return -1;
284 return nb;
287 static SECStatus
288 btoa_file(SECItem *binary, PRFileDesc *outfile)
290 SECStatus status;
291 NSSBase64Encoder *cx;
292 SECItem ascii;
293 ascii.data = NULL;
294 ascii.len = 0;
295 if (binary->len == 0)
296 return SECSuccess;
297 cx = NSSBase64Encoder_Create(output_ascii, outfile);
298 status = NSSBase64Encoder_Update(cx, binary->data, binary->len);
299 status = NSSBase64Encoder_Destroy(cx, PR_FALSE);
300 status = PR_Write(outfile, "\r\n", 2);
301 return status;
304 SECStatus
305 hex_from_2char(unsigned char *c2, unsigned char *byteval)
307 int i;
308 unsigned char offset;
309 *byteval = 0;
310 for (i=0; i<2; i++) {
311 if (c2[i] >= '0' && c2[i] <= '9') {
312 offset = c2[i] - '0';
313 *byteval |= offset << 4*(1-i);
314 } else if (c2[i] >= 'a' && c2[i] <= 'f') {
315 offset = c2[i] - 'a';
316 *byteval |= (offset + 10) << 4*(1-i);
317 } else if (c2[i] >= 'A' && c2[i] <= 'F') {
318 offset = c2[i] - 'A';
319 *byteval |= (offset + 10) << 4*(1-i);
320 } else {
321 return SECFailure;
324 return SECSuccess;
327 SECStatus
328 char2_from_hex(unsigned char byteval, unsigned char *c2)
330 int i;
331 unsigned char offset;
332 for (i=0; i<2; i++) {
333 offset = (byteval >> 4*(1-i)) & 0x0f;
334 if (offset < 10) {
335 c2[i] = '0' + offset;
336 } else {
337 c2[i] = 'A' + offset - 10;
340 return SECSuccess;
343 void
344 serialize_key(SECItem *it, int ni, PRFileDesc *file)
346 unsigned char len[4];
347 int i;
348 SECStatus status;
349 NSSBase64Encoder *cx;
350 SECItem ascii;
351 ascii.data = NULL;
352 ascii.len = 0;
353 cx = NSSBase64Encoder_Create(output_ascii, file);
354 for (i=0; i<ni; i++, it++) {
355 len[0] = (it->len >> 24) & 0xff;
356 len[1] = (it->len >> 16) & 0xff;
357 len[2] = (it->len >> 8) & 0xff;
358 len[3] = (it->len & 0xff);
359 status = NSSBase64Encoder_Update(cx, len, 4);
360 status = NSSBase64Encoder_Update(cx, it->data, it->len);
362 status = NSSBase64Encoder_Destroy(cx, PR_FALSE);
363 status = PR_Write(file, "\r\n", 2);
366 void
367 key_from_filedata(PRArenaPool *arena, SECItem *it, int ns, int ni, SECItem *filedata)
369 int fpos = 0;
370 int i, len;
371 unsigned char *buf = filedata->data;
372 for (i=0; i<ni; i++) {
373 len = (buf[fpos++] & 0xff) << 24;
374 len |= (buf[fpos++] & 0xff) << 16;
375 len |= (buf[fpos++] & 0xff) << 8;
376 len |= (buf[fpos++] & 0xff);
377 if (ns <= i) {
378 if (len > 0) {
379 it->len = len;
380 it->data = PORT_ArenaAlloc(arena, it->len);
381 PORT_Memcpy(it->data, &buf[fpos], it->len);
382 } else {
383 it->len = 0;
384 it->data = NULL;
386 it++;
388 fpos += len;
392 static RSAPrivateKey *
393 rsakey_from_filedata(SECItem *filedata)
395 RSAPrivateKey *key;
396 PRArenaPool *arena;
397 arena = PORT_NewArena(BLTEST_DEFAULT_CHUNKSIZE);
398 key = (RSAPrivateKey *)PORT_ArenaZAlloc(arena, sizeof(RSAPrivateKey));
399 key->arena = arena;
400 key_from_filedata(arena, &key->version, 0, 9, filedata);
401 return key;
404 static PQGParams *
405 pqg_from_filedata(SECItem *filedata)
407 PQGParams *pqg;
408 PRArenaPool *arena;
409 arena = PORT_NewArena(BLTEST_DEFAULT_CHUNKSIZE);
410 pqg = (PQGParams *)PORT_ArenaZAlloc(arena, sizeof(PQGParams));
411 pqg->arena = arena;
412 key_from_filedata(arena, &pqg->prime, 0, 3, filedata);
413 return pqg;
416 static DSAPrivateKey *
417 dsakey_from_filedata(SECItem *filedata)
419 DSAPrivateKey *key;
420 PRArenaPool *arena;
421 arena = PORT_NewArena(BLTEST_DEFAULT_CHUNKSIZE);
422 key = (DSAPrivateKey *)PORT_ArenaZAlloc(arena, sizeof(DSAPrivateKey));
423 key->params.arena = arena;
424 key_from_filedata(arena, &key->params.prime, 0, 5, filedata);
425 return key;
428 #ifdef NSS_ENABLE_ECC
429 static ECPrivateKey *
430 eckey_from_filedata(SECItem *filedata)
432 ECPrivateKey *key;
433 PRArenaPool *arena;
434 SECStatus rv;
435 ECParams *tmpECParams = NULL;
436 arena = PORT_NewArena(BLTEST_DEFAULT_CHUNKSIZE);
437 key = (ECPrivateKey *)PORT_ArenaZAlloc(arena, sizeof(ECPrivateKey));
438 /* read and convert params */
439 key->ecParams.arena = arena;
440 key_from_filedata(arena, &key->ecParams.DEREncoding, 0, 1, filedata);
441 rv = SECOID_Init();
442 CHECKERROR(rv, __LINE__);
443 rv = EC_DecodeParams(&key->ecParams.DEREncoding, &tmpECParams);
444 CHECKERROR(rv, __LINE__);
445 rv = EC_CopyParams(key->ecParams.arena, &key->ecParams, tmpECParams);
446 CHECKERROR(rv, __LINE__);
447 rv = SECOID_Shutdown();
448 CHECKERROR(rv, __LINE__);
449 PORT_FreeArena(tmpECParams->arena, PR_TRUE);
450 /* read key */
451 key_from_filedata(arena, &key->publicValue, 1, 3, filedata);
452 return key;
455 typedef struct curveNameTagPairStr {
456 char *curveName;
457 SECOidTag curveOidTag;
458 } CurveNameTagPair;
460 #define DEFAULT_CURVE_OID_TAG SEC_OID_SECG_EC_SECP192R1
461 /* #define DEFAULT_CURVE_OID_TAG SEC_OID_SECG_EC_SECP160R1 */
463 static CurveNameTagPair nameTagPair[] =
465 { "sect163k1", SEC_OID_SECG_EC_SECT163K1},
466 { "nistk163", SEC_OID_SECG_EC_SECT163K1},
467 { "sect163r1", SEC_OID_SECG_EC_SECT163R1},
468 { "sect163r2", SEC_OID_SECG_EC_SECT163R2},
469 { "nistb163", SEC_OID_SECG_EC_SECT163R2},
470 { "sect193r1", SEC_OID_SECG_EC_SECT193R1},
471 { "sect193r2", SEC_OID_SECG_EC_SECT193R2},
472 { "sect233k1", SEC_OID_SECG_EC_SECT233K1},
473 { "nistk233", SEC_OID_SECG_EC_SECT233K1},
474 { "sect233r1", SEC_OID_SECG_EC_SECT233R1},
475 { "nistb233", SEC_OID_SECG_EC_SECT233R1},
476 { "sect239k1", SEC_OID_SECG_EC_SECT239K1},
477 { "sect283k1", SEC_OID_SECG_EC_SECT283K1},
478 { "nistk283", SEC_OID_SECG_EC_SECT283K1},
479 { "sect283r1", SEC_OID_SECG_EC_SECT283R1},
480 { "nistb283", SEC_OID_SECG_EC_SECT283R1},
481 { "sect409k1", SEC_OID_SECG_EC_SECT409K1},
482 { "nistk409", SEC_OID_SECG_EC_SECT409K1},
483 { "sect409r1", SEC_OID_SECG_EC_SECT409R1},
484 { "nistb409", SEC_OID_SECG_EC_SECT409R1},
485 { "sect571k1", SEC_OID_SECG_EC_SECT571K1},
486 { "nistk571", SEC_OID_SECG_EC_SECT571K1},
487 { "sect571r1", SEC_OID_SECG_EC_SECT571R1},
488 { "nistb571", SEC_OID_SECG_EC_SECT571R1},
489 { "secp160k1", SEC_OID_SECG_EC_SECP160K1},
490 { "secp160r1", SEC_OID_SECG_EC_SECP160R1},
491 { "secp160r2", SEC_OID_SECG_EC_SECP160R2},
492 { "secp192k1", SEC_OID_SECG_EC_SECP192K1},
493 { "secp192r1", SEC_OID_SECG_EC_SECP192R1},
494 { "nistp192", SEC_OID_SECG_EC_SECP192R1},
495 { "secp224k1", SEC_OID_SECG_EC_SECP224K1},
496 { "secp224r1", SEC_OID_SECG_EC_SECP224R1},
497 { "nistp224", SEC_OID_SECG_EC_SECP224R1},
498 { "secp256k1", SEC_OID_SECG_EC_SECP256K1},
499 { "secp256r1", SEC_OID_SECG_EC_SECP256R1},
500 { "nistp256", SEC_OID_SECG_EC_SECP256R1},
501 { "secp384r1", SEC_OID_SECG_EC_SECP384R1},
502 { "nistp384", SEC_OID_SECG_EC_SECP384R1},
503 { "secp521r1", SEC_OID_SECG_EC_SECP521R1},
504 { "nistp521", SEC_OID_SECG_EC_SECP521R1},
506 { "prime192v1", SEC_OID_ANSIX962_EC_PRIME192V1 },
507 { "prime192v2", SEC_OID_ANSIX962_EC_PRIME192V2 },
508 { "prime192v3", SEC_OID_ANSIX962_EC_PRIME192V3 },
509 { "prime239v1", SEC_OID_ANSIX962_EC_PRIME239V1 },
510 { "prime239v2", SEC_OID_ANSIX962_EC_PRIME239V2 },
511 { "prime239v3", SEC_OID_ANSIX962_EC_PRIME239V3 },
513 { "c2pnb163v1", SEC_OID_ANSIX962_EC_C2PNB163V1 },
514 { "c2pnb163v2", SEC_OID_ANSIX962_EC_C2PNB163V2 },
515 { "c2pnb163v3", SEC_OID_ANSIX962_EC_C2PNB163V3 },
516 { "c2pnb176v1", SEC_OID_ANSIX962_EC_C2PNB176V1 },
517 { "c2tnb191v1", SEC_OID_ANSIX962_EC_C2TNB191V1 },
518 { "c2tnb191v2", SEC_OID_ANSIX962_EC_C2TNB191V2 },
519 { "c2tnb191v3", SEC_OID_ANSIX962_EC_C2TNB191V3 },
520 { "c2onb191v4", SEC_OID_ANSIX962_EC_C2ONB191V4 },
521 { "c2onb191v5", SEC_OID_ANSIX962_EC_C2ONB191V5 },
522 { "c2pnb208w1", SEC_OID_ANSIX962_EC_C2PNB208W1 },
523 { "c2tnb239v1", SEC_OID_ANSIX962_EC_C2TNB239V1 },
524 { "c2tnb239v2", SEC_OID_ANSIX962_EC_C2TNB239V2 },
525 { "c2tnb239v3", SEC_OID_ANSIX962_EC_C2TNB239V3 },
526 { "c2onb239v4", SEC_OID_ANSIX962_EC_C2ONB239V4 },
527 { "c2onb239v5", SEC_OID_ANSIX962_EC_C2ONB239V5 },
528 { "c2pnb272w1", SEC_OID_ANSIX962_EC_C2PNB272W1 },
529 { "c2pnb304w1", SEC_OID_ANSIX962_EC_C2PNB304W1 },
530 { "c2tnb359v1", SEC_OID_ANSIX962_EC_C2TNB359V1 },
531 { "c2pnb368w1", SEC_OID_ANSIX962_EC_C2PNB368W1 },
532 { "c2tnb431r1", SEC_OID_ANSIX962_EC_C2TNB431R1 },
534 { "secp112r1", SEC_OID_SECG_EC_SECP112R1},
535 { "secp112r2", SEC_OID_SECG_EC_SECP112R2},
536 { "secp128r1", SEC_OID_SECG_EC_SECP128R1},
537 { "secp128r2", SEC_OID_SECG_EC_SECP128R2},
539 { "sect113r1", SEC_OID_SECG_EC_SECT113R1},
540 { "sect113r2", SEC_OID_SECG_EC_SECT113R2},
541 { "sect131r1", SEC_OID_SECG_EC_SECT131R1},
542 { "sect131r2", SEC_OID_SECG_EC_SECT131R2},
545 static SECKEYECParams *
546 getECParams(const char *curve)
548 SECKEYECParams *ecparams;
549 SECOidData *oidData = NULL;
550 SECOidTag curveOidTag = SEC_OID_UNKNOWN; /* default */
551 int i, numCurves;
553 if (curve != NULL) {
554 numCurves = sizeof(nameTagPair)/sizeof(CurveNameTagPair);
555 for (i = 0; ((i < numCurves) && (curveOidTag == SEC_OID_UNKNOWN));
556 i++) {
557 if (PL_strcmp(curve, nameTagPair[i].curveName) == 0)
558 curveOidTag = nameTagPair[i].curveOidTag;
562 /* Return NULL if curve name is not recognized */
563 if ((curveOidTag == SEC_OID_UNKNOWN) ||
564 (oidData = SECOID_FindOIDByTag(curveOidTag)) == NULL) {
565 fprintf(stderr, "Unrecognized elliptic curve %s\n", curve);
566 return NULL;
569 ecparams = SECITEM_AllocItem(NULL, NULL, (2 + oidData->oid.len));
572 * ecparams->data needs to contain the ASN encoding of an object ID (OID)
573 * representing the named curve. The actual OID is in
574 * oidData->oid.data so we simply prepend 0x06 and OID length
576 ecparams->data[0] = SEC_ASN1_OBJECT_ID;
577 ecparams->data[1] = oidData->oid.len;
578 memcpy(ecparams->data + 2, oidData->oid.data, oidData->oid.len);
580 return ecparams;
582 #endif /* NSS_ENABLE_ECC */
584 static void
585 dump_pqg(PQGParams *pqg)
587 SECU_PrintInteger(stdout, &pqg->prime, "PRIME:", 0);
588 SECU_PrintInteger(stdout, &pqg->subPrime, "SUBPRIME:", 0);
589 SECU_PrintInteger(stdout, &pqg->base, "BASE:", 0);
592 static void
593 dump_dsakey(DSAPrivateKey *key)
595 dump_pqg(&key->params);
596 SECU_PrintInteger(stdout, &key->publicValue, "PUBLIC VALUE:", 0);
597 SECU_PrintInteger(stdout, &key->privateValue, "PRIVATE VALUE:", 0);
600 #ifdef NSS_ENABLE_ECC
601 static void
602 dump_ecp(ECParams *ecp)
604 /* TODO other fields */
605 SECU_PrintInteger(stdout, &ecp->base, "BASE POINT:", 0);
608 static void
609 dump_eckey(ECPrivateKey *key)
611 dump_ecp(&key->ecParams);
612 SECU_PrintInteger(stdout, &key->publicValue, "PUBLIC VALUE:", 0);
613 SECU_PrintInteger(stdout, &key->privateValue, "PRIVATE VALUE:", 0);
615 #endif
617 static void
618 dump_rsakey(RSAPrivateKey *key)
620 SECU_PrintInteger(stdout, &key->version, "VERSION:", 0);
621 SECU_PrintInteger(stdout, &key->modulus, "MODULUS:", 0);
622 SECU_PrintInteger(stdout, &key->publicExponent, "PUBLIC EXP:", 0);
623 SECU_PrintInteger(stdout, &key->privateExponent, "PRIVATE EXP:", 0);
624 SECU_PrintInteger(stdout, &key->prime1, "CRT PRIME 1:", 0);
625 SECU_PrintInteger(stdout, &key->prime2, "CRT PRIME 2:", 0);
626 SECU_PrintInteger(stdout, &key->exponent1, "CRT EXP 1:", 0);
627 SECU_PrintInteger(stdout, &key->exponent2, "CRT EXP 2:", 0);
628 SECU_PrintInteger(stdout, &key->coefficient, "CRT COEFFICIENT:", 0);
631 typedef enum {
632 bltestBase64Encoded, /* Base64 encoded ASCII */
633 bltestBinary, /* straight binary */
634 bltestHexSpaceDelim, /* 0x12 0x34 0xab 0xCD ... */
635 bltestHexStream /* 1234abCD ... */
636 } bltestIOMode;
638 typedef struct
640 SECItem buf;
641 SECItem pBuf;
642 bltestIOMode mode;
643 PRFileDesc* file;
644 } bltestIO;
646 typedef SECStatus (* bltestSymmCipherFn)(void *cx,
647 unsigned char *output,
648 unsigned int *outputLen,
649 unsigned int maxOutputLen,
650 const unsigned char *input,
651 unsigned int inputLen);
653 typedef SECStatus (* bltestPubKeyCipherFn)(void *key,
654 SECItem *output,
655 const SECItem *input);
657 typedef SECStatus (* bltestHashCipherFn)(unsigned char *dest,
658 const unsigned char *src,
659 uint32 src_length);
661 typedef enum {
662 bltestINVALID = -1,
663 bltestDES_ECB, /* Symmetric Key Ciphers */
664 bltestDES_CBC, /* . */
665 bltestDES_EDE_ECB, /* . */
666 bltestDES_EDE_CBC, /* . */
667 bltestRC2_ECB, /* . */
668 bltestRC2_CBC, /* . */
669 bltestRC4, /* . */
670 bltestRC5_ECB, /* . */
671 bltestRC5_CBC, /* . */
672 bltestAES_ECB, /* . */
673 bltestAES_CBC, /* . */
674 bltestCAMELLIA_ECB, /* . */
675 bltestCAMELLIA_CBC, /* . */
676 bltestRSA, /* Public Key Ciphers */
677 #ifdef NSS_ENABLE_ECC
678 bltestECDSA, /* . (Public Key Sig.) */
679 #endif
680 bltestDSA, /* . */
681 bltestMD2, /* Hash algorithms */
682 bltestMD5, /* . */
683 bltestSHA1, /* . */
684 bltestSHA256, /* . */
685 bltestSHA384, /* . */
686 bltestSHA512, /* . */
687 NUMMODES
688 } bltestCipherMode;
690 static char *mode_strings[] =
692 "des_ecb",
693 "des_cbc",
694 "des3_ecb",
695 "des3_cbc",
696 "rc2_ecb",
697 "rc2_cbc",
698 "rc4",
699 "rc5_ecb",
700 "rc5_cbc",
701 "aes_ecb",
702 "aes_cbc",
703 "camellia_ecb",
704 "camellia_cbc",
705 "rsa",
706 #ifdef NSS_ENABLE_ECC
707 "ecdsa",
708 #endif
709 /*"pqg",*/
710 "dsa",
711 "md2",
712 "md5",
713 "sha1",
714 "sha256",
715 "sha384",
716 "sha512",
719 typedef struct
721 bltestIO key;
722 bltestIO iv;
723 } bltestSymmKeyParams;
725 typedef struct
727 bltestIO key;
728 bltestIO iv;
729 int rounds;
730 int wordsize;
731 } bltestRC5Params;
733 typedef struct
735 bltestIO key;
736 int keysizeInBits;
737 RSAPrivateKey *rsakey;
738 } bltestRSAParams;
740 typedef struct
742 bltestIO key;
743 bltestIO pqgdata;
744 unsigned int j;
745 bltestIO keyseed;
746 bltestIO sigseed;
747 bltestIO sig; /* if doing verify, have additional input */
748 PQGParams *pqg;
749 DSAPrivateKey *dsakey;
750 } bltestDSAParams;
752 #ifdef NSS_ENABLE_ECC
753 typedef struct
755 bltestIO key;
756 char *curveName;
757 bltestIO sigseed;
758 bltestIO sig; /* if doing verify, have additional input */
759 ECPrivateKey *eckey;
760 } bltestECDSAParams;
761 #endif
763 typedef struct
765 bltestIO key; /* unused */
766 PRBool restart;
767 } bltestHashParams;
769 typedef union
771 bltestIO key;
772 bltestSymmKeyParams sk;
773 bltestRC5Params rc5;
774 bltestRSAParams rsa;
775 bltestDSAParams dsa;
776 #ifdef NSS_ENABLE_ECC
777 bltestECDSAParams ecdsa;
778 #endif
779 bltestHashParams hash;
780 } bltestParams;
782 typedef struct bltestCipherInfoStr bltestCipherInfo;
784 struct bltestCipherInfoStr {
785 PRArenaPool *arena;
786 /* link to next in multithreaded test */
787 bltestCipherInfo *next;
788 PRThread *cipherThread;
790 /* MonteCarlo test flag*/
791 PRBool mCarlo;
792 /* cipher context */
793 void *cx;
794 /* I/O streams */
795 bltestIO input;
796 bltestIO output;
797 /* Cipher-specific parameters */
798 bltestParams params;
799 /* Cipher mode */
800 bltestCipherMode mode;
801 /* Cipher function (encrypt/decrypt/sign/verify/hash) */
802 union {
803 bltestSymmCipherFn symmkeyCipher;
804 bltestPubKeyCipherFn pubkeyCipher;
805 bltestHashCipherFn hashCipher;
806 } cipher;
807 /* performance testing */
808 int repetitionsToPerfom;
809 int seconds;
810 int repetitions;
811 int cxreps;
812 double cxtime;
813 double optime;
816 PRBool
817 is_symmkeyCipher(bltestCipherMode mode)
819 /* change as needed! */
820 if (mode >= bltestDES_ECB && mode <= bltestCAMELLIA_CBC)
821 return PR_TRUE;
822 return PR_FALSE;
825 PRBool
826 is_pubkeyCipher(bltestCipherMode mode)
828 /* change as needed! */
829 if (mode >= bltestRSA && mode <= bltestDSA)
830 return PR_TRUE;
831 return PR_FALSE;
834 PRBool
835 is_hashCipher(bltestCipherMode mode)
837 /* change as needed! */
838 if (mode >= bltestMD2 && mode <= bltestSHA512)
839 return PR_TRUE;
840 return PR_FALSE;
843 PRBool
844 is_sigCipher(bltestCipherMode mode)
846 /* change as needed! */
847 #ifdef NSS_ENABLE_ECC
848 if (mode >= bltestECDSA && mode <= bltestDSA)
849 #else
850 if (mode >= bltestDSA && mode <= bltestDSA)
851 #endif
852 return PR_TRUE;
853 return PR_FALSE;
856 PRBool
857 cipher_requires_IV(bltestCipherMode mode)
859 /* change as needed! */
860 if (mode == bltestDES_CBC || mode == bltestDES_EDE_CBC ||
861 mode == bltestRC2_CBC || mode == bltestRC5_CBC ||
862 mode == bltestAES_CBC || mode == bltestCAMELLIA_CBC)
863 return PR_TRUE;
864 return PR_FALSE;
867 SECStatus finishIO(bltestIO *output, PRFileDesc *file);
869 SECStatus
870 setupIO(PRArenaPool *arena, bltestIO *input, PRFileDesc *file,
871 char *str, int numBytes)
873 SECStatus rv = SECSuccess;
874 SECItem fileData;
875 SECItem *in;
876 unsigned char *tok;
877 unsigned int i, j;
879 if (file && (numBytes == 0 || file == PR_STDIN)) {
880 /* grabbing data from a file */
881 rv = SECU_FileToItem(&fileData, file);
882 if (rv != SECSuccess) {
883 PR_Close(file);
884 return SECFailure;
886 in = &fileData;
887 } else if (str) {
888 /* grabbing data from command line */
889 fileData.data = str;
890 fileData.len = PL_strlen(str);
891 in = &fileData;
892 } else if (file) {
893 /* create nonce */
894 SECITEM_AllocItem(arena, &input->buf, numBytes);
895 RNG_GenerateGlobalRandomBytes(input->buf.data, numBytes);
896 return finishIO(input, file);
897 } else {
898 return SECFailure;
901 switch (input->mode) {
902 case bltestBase64Encoded:
903 rv = atob(in, &input->buf, arena);
904 break;
905 case bltestBinary:
906 if (in->data[in->len-1] == '\n') --in->len;
907 if (in->data[in->len-1] == '\r') --in->len;
908 SECITEM_CopyItem(arena, &input->buf, in);
909 break;
910 case bltestHexSpaceDelim:
911 SECITEM_AllocItem(arena, &input->buf, in->len/5);
912 for (i=0, j=0; i<in->len; i+=5, j++) {
913 tok = &in->data[i];
914 if (tok[0] != '0' || tok[1] != 'x' || tok[4] != ' ')
915 /* bad hex token */
916 break;
918 rv = hex_from_2char(&tok[2], input->buf.data + j);
919 if (rv)
920 break;
922 break;
923 case bltestHexStream:
924 SECITEM_AllocItem(arena, &input->buf, in->len/2);
925 for (i=0, j=0; i<in->len; i+=2, j++) {
926 tok = &in->data[i];
927 rv = hex_from_2char(tok, input->buf.data + j);
928 if (rv)
929 break;
931 break;
934 if (file)
935 SECITEM_FreeItem(&fileData, PR_FALSE);
936 return rv;
939 SECStatus
940 finishIO(bltestIO *output, PRFileDesc *file)
942 SECStatus rv = SECSuccess;
943 PRInt32 nb;
944 unsigned char byteval;
945 SECItem *it;
946 char hexstr[5];
947 unsigned int i;
948 if (output->pBuf.len > 0) {
949 it = &output->pBuf;
950 } else {
951 it = &output->buf;
953 switch (output->mode) {
954 case bltestBase64Encoded:
955 rv = btoa_file(it, file);
956 break;
957 case bltestBinary:
958 nb = PR_Write(file, it->data, it->len);
959 rv = (nb == (PRInt32)it->len) ? SECSuccess : SECFailure;
960 break;
961 case bltestHexSpaceDelim:
962 hexstr[0] = '0';
963 hexstr[1] = 'x';
964 hexstr[4] = ' ';
965 for (i=0; i<it->len; i++) {
966 byteval = it->data[i];
967 rv = char2_from_hex(byteval, hexstr + 2);
968 nb = PR_Write(file, hexstr, 5);
969 if (rv)
970 break;
972 PR_Write(file, "\n", 1);
973 break;
974 case bltestHexStream:
975 for (i=0; i<it->len; i++) {
976 byteval = it->data[i];
977 rv = char2_from_hex(byteval, hexstr);
978 if (rv)
979 break;
980 nb = PR_Write(file, hexstr, 2);
982 PR_Write(file, "\n", 1);
983 break;
985 return rv;
988 void
989 bltestCopyIO(PRArenaPool *arena, bltestIO *dest, bltestIO *src)
991 SECITEM_CopyItem(arena, &dest->buf, &src->buf);
992 if (src->pBuf.len > 0) {
993 dest->pBuf.len = src->pBuf.len;
994 dest->pBuf.data = dest->buf.data + (src->pBuf.data - src->buf.data);
996 dest->mode = src->mode;
997 dest->file = src->file;
1000 void
1001 misalignBuffer(PRArenaPool *arena, bltestIO *io, int off)
1003 ptrdiff_t offset = (ptrdiff_t)io->buf.data % WORDSIZE;
1004 int length = io->buf.len;
1005 if (offset != off) {
1006 SECITEM_ReallocItem(arena, &io->buf, length, length + 2*WORDSIZE);
1007 io->buf.len = length + 2*WORDSIZE; /* why doesn't realloc do this? */
1008 /* offset may have changed? */
1009 offset = (ptrdiff_t)io->buf.data % WORDSIZE;
1010 if (offset != off) {
1011 memmove(io->buf.data + off, io->buf.data, length);
1012 io->pBuf.data = io->buf.data + off;
1013 io->pBuf.len = length;
1014 } else {
1015 io->pBuf.data = io->buf.data;
1016 io->pBuf.len = length;
1018 } else {
1019 io->pBuf.data = io->buf.data;
1020 io->pBuf.len = length;
1024 SECStatus
1025 des_Encrypt(void *cx, unsigned char *output, unsigned int *outputLen,
1026 unsigned int maxOutputLen, const unsigned char *input,
1027 unsigned int inputLen)
1029 return DES_Encrypt((DESContext *)cx, output, outputLen, maxOutputLen,
1030 input, inputLen);
1033 SECStatus
1034 des_Decrypt(void *cx, unsigned char *output, unsigned int *outputLen,
1035 unsigned int maxOutputLen, const unsigned char *input,
1036 unsigned int inputLen)
1038 return DES_Decrypt((DESContext *)cx, output, outputLen, maxOutputLen,
1039 input, inputLen);
1042 SECStatus
1043 rc2_Encrypt(void *cx, unsigned char *output, unsigned int *outputLen,
1044 unsigned int maxOutputLen, const unsigned char *input,
1045 unsigned int inputLen)
1047 return RC2_Encrypt((RC2Context *)cx, output, outputLen, maxOutputLen,
1048 input, inputLen);
1051 SECStatus
1052 rc2_Decrypt(void *cx, unsigned char *output, unsigned int *outputLen,
1053 unsigned int maxOutputLen, const unsigned char *input,
1054 unsigned int inputLen)
1056 return RC2_Decrypt((RC2Context *)cx, output, outputLen, maxOutputLen,
1057 input, inputLen);
1060 SECStatus
1061 rc4_Encrypt(void *cx, unsigned char *output, unsigned int *outputLen,
1062 unsigned int maxOutputLen, const unsigned char *input,
1063 unsigned int inputLen)
1065 return RC4_Encrypt((RC4Context *)cx, output, outputLen, maxOutputLen,
1066 input, inputLen);
1069 SECStatus
1070 rc4_Decrypt(void *cx, unsigned char *output, unsigned int *outputLen,
1071 unsigned int maxOutputLen, const unsigned char *input,
1072 unsigned int inputLen)
1074 return RC4_Decrypt((RC4Context *)cx, output, outputLen, maxOutputLen,
1075 input, inputLen);
1078 SECStatus
1079 aes_Encrypt(void *cx, unsigned char *output, unsigned int *outputLen,
1080 unsigned int maxOutputLen, const unsigned char *input,
1081 unsigned int inputLen)
1083 return AES_Encrypt((AESContext *)cx, output, outputLen, maxOutputLen,
1084 input, inputLen);
1087 SECStatus
1088 aes_Decrypt(void *cx, unsigned char *output, unsigned int *outputLen,
1089 unsigned int maxOutputLen, const unsigned char *input,
1090 unsigned int inputLen)
1092 return AES_Decrypt((AESContext *)cx, output, outputLen, maxOutputLen,
1093 input, inputLen);
1096 SECStatus
1097 camellia_Encrypt(void *cx, unsigned char *output, unsigned int *outputLen,
1098 unsigned int maxOutputLen, const unsigned char *input,
1099 unsigned int inputLen)
1101 return Camellia_Encrypt((CamelliaContext *)cx, output, outputLen,
1102 maxOutputLen,
1103 input, inputLen);
1106 SECStatus
1107 camellia_Decrypt(void *cx, unsigned char *output, unsigned int *outputLen,
1108 unsigned int maxOutputLen, const unsigned char *input,
1109 unsigned int inputLen)
1111 return Camellia_Decrypt((CamelliaContext *)cx, output, outputLen,
1112 maxOutputLen,
1113 input, inputLen);
1116 SECStatus
1117 rsa_PublicKeyOp(void *key, SECItem *output, const SECItem *input)
1119 return RSA_PublicKeyOp((RSAPublicKey *)key, output->data, input->data);
1122 SECStatus
1123 rsa_PrivateKeyOp(void *key, SECItem *output, const SECItem *input)
1125 return RSA_PrivateKeyOp((RSAPrivateKey *)key, output->data, input->data);
1128 SECStatus
1129 dsa_signDigest(void *key, SECItem *output, const SECItem *input)
1131 return DSA_SignDigest((DSAPrivateKey *)key, output, input);
1134 SECStatus
1135 dsa_verifyDigest(void *key, SECItem *output, const SECItem *input)
1137 return DSA_VerifyDigest((DSAPublicKey *)key, output, input);
1140 #ifdef NSS_ENABLE_ECC
1141 SECStatus
1142 ecdsa_signDigest(void *key, SECItem *output, const SECItem *input)
1144 return ECDSA_SignDigest((ECPrivateKey *)key, output, input);
1147 SECStatus
1148 ecdsa_verifyDigest(void *key, SECItem *output, const SECItem *input)
1150 return ECDSA_VerifyDigest((ECPublicKey *)key, output, input);
1152 #endif
1154 SECStatus
1155 bltest_des_init(bltestCipherInfo *cipherInfo, PRBool encrypt)
1157 PRIntervalTime time1, time2;
1158 bltestSymmKeyParams *desp = &cipherInfo->params.sk;
1159 int minorMode;
1160 int i;
1161 switch (cipherInfo->mode) {
1162 case bltestDES_ECB: minorMode = NSS_DES; break;
1163 case bltestDES_CBC: minorMode = NSS_DES_CBC; break;
1164 case bltestDES_EDE_ECB: minorMode = NSS_DES_EDE3; break;
1165 case bltestDES_EDE_CBC: minorMode = NSS_DES_EDE3_CBC; break;
1166 default:
1167 return SECFailure;
1169 cipherInfo->cx = (void*)DES_CreateContext(desp->key.buf.data,
1170 desp->iv.buf.data,
1171 minorMode, encrypt);
1172 if (cipherInfo->cxreps > 0) {
1173 DESContext **dummycx;
1174 dummycx = PORT_Alloc(cipherInfo->cxreps * sizeof(DESContext *));
1175 TIMESTART();
1176 for (i=0; i<cipherInfo->cxreps; i++) {
1177 dummycx[i] = (void*)DES_CreateContext(desp->key.buf.data,
1178 desp->iv.buf.data,
1179 minorMode, encrypt);
1181 TIMEFINISH(cipherInfo->cxtime, 1.0);
1182 for (i=0; i<cipherInfo->cxreps; i++) {
1183 DES_DestroyContext(dummycx[i], PR_TRUE);
1185 PORT_Free(dummycx);
1187 if (encrypt)
1188 cipherInfo->cipher.symmkeyCipher = des_Encrypt;
1189 else
1190 cipherInfo->cipher.symmkeyCipher = des_Decrypt;
1191 return SECSuccess;
1194 SECStatus
1195 bltest_rc2_init(bltestCipherInfo *cipherInfo, PRBool encrypt)
1197 PRIntervalTime time1, time2;
1198 bltestSymmKeyParams *rc2p = &cipherInfo->params.sk;
1199 int minorMode;
1200 int i;
1201 switch (cipherInfo->mode) {
1202 case bltestRC2_ECB: minorMode = NSS_RC2; break;
1203 case bltestRC2_CBC: minorMode = NSS_RC2_CBC; break;
1204 default:
1205 return SECFailure;
1207 cipherInfo->cx = (void*)RC2_CreateContext(rc2p->key.buf.data,
1208 rc2p->key.buf.len,
1209 rc2p->iv.buf.data,
1210 minorMode,
1211 rc2p->key.buf.len);
1212 if (cipherInfo->cxreps > 0) {
1213 RC2Context **dummycx;
1214 dummycx = PORT_Alloc(cipherInfo->cxreps * sizeof(RC2Context *));
1215 TIMESTART();
1216 for (i=0; i<cipherInfo->cxreps; i++) {
1217 dummycx[i] = (void*)RC2_CreateContext(rc2p->key.buf.data,
1218 rc2p->key.buf.len,
1219 rc2p->iv.buf.data,
1220 minorMode,
1221 rc2p->key.buf.len);
1223 TIMEFINISH(cipherInfo->cxtime, 1.0);
1224 for (i=0; i<cipherInfo->cxreps; i++) {
1225 RC2_DestroyContext(dummycx[i], PR_TRUE);
1227 PORT_Free(dummycx);
1229 if (encrypt)
1230 cipherInfo->cipher.symmkeyCipher = rc2_Encrypt;
1231 else
1232 cipherInfo->cipher.symmkeyCipher = rc2_Decrypt;
1233 return SECSuccess;
1236 SECStatus
1237 bltest_rc4_init(bltestCipherInfo *cipherInfo, PRBool encrypt)
1239 PRIntervalTime time1, time2;
1240 int i;
1241 bltestSymmKeyParams *rc4p = &cipherInfo->params.sk;
1242 cipherInfo->cx = (void*)RC4_CreateContext(rc4p->key.buf.data,
1243 rc4p->key.buf.len);
1244 if (cipherInfo->cxreps > 0) {
1245 RC4Context **dummycx;
1246 dummycx = PORT_Alloc(cipherInfo->cxreps * sizeof(RC4Context *));
1247 TIMESTART();
1248 for (i=0; i<cipherInfo->cxreps; i++) {
1249 dummycx[i] = (void*)RC4_CreateContext(rc4p->key.buf.data,
1250 rc4p->key.buf.len);
1252 TIMEFINISH(cipherInfo->cxtime, 1.0);
1253 for (i=0; i<cipherInfo->cxreps; i++) {
1254 RC4_DestroyContext(dummycx[i], PR_TRUE);
1256 PORT_Free(dummycx);
1258 if (encrypt)
1259 cipherInfo->cipher.symmkeyCipher = rc4_Encrypt;
1260 else
1261 cipherInfo->cipher.symmkeyCipher = rc4_Decrypt;
1262 return SECSuccess;
1265 SECStatus
1266 bltest_rc5_init(bltestCipherInfo *cipherInfo, PRBool encrypt)
1268 #if NSS_SOFTOKEN_DOES_RC5
1269 PRIntervalTime time1, time2;
1270 bltestRC5Params *rc5p = &cipherInfo->params.rc5;
1271 int minorMode;
1272 switch (cipherInfo->mode) {
1273 case bltestRC5_ECB: minorMode = NSS_RC5; break;
1274 case bltestRC5_CBC: minorMode = NSS_RC5_CBC; break;
1275 default:
1276 return SECFailure;
1278 TIMESTART();
1279 cipherInfo->cx = (void*)RC5_CreateContext(&rc5p->key.buf,
1280 rc5p->rounds, rc5p->wordsize,
1281 rc5p->iv.buf.data, minorMode);
1282 TIMEFINISH(cipherInfo->cxtime, 1.0);
1283 if (encrypt)
1284 cipherInfo->cipher.symmkeyCipher = RC5_Encrypt;
1285 else
1286 cipherInfo->cipher.symmkeyCipher = RC5_Decrypt;
1287 return SECSuccess;
1288 #else
1289 return SECFailure;
1290 #endif
1293 SECStatus
1294 bltest_aes_init(bltestCipherInfo *cipherInfo, PRBool encrypt)
1296 bltestSymmKeyParams *aesp = &cipherInfo->params.sk;
1297 int minorMode;
1298 int i;
1299 int keylen = aesp->key.buf.len;
1300 int blocklen = AES_BLOCK_SIZE;
1301 PRIntervalTime time1, time2;
1303 switch (cipherInfo->mode) {
1304 case bltestAES_ECB: minorMode = NSS_AES; break;
1305 case bltestAES_CBC: minorMode = NSS_AES_CBC; break;
1306 default:
1307 return SECFailure;
1309 cipherInfo->cx = (void*)AES_CreateContext(aesp->key.buf.data,
1310 aesp->iv.buf.data,
1311 minorMode, encrypt,
1312 keylen, blocklen);
1313 if (cipherInfo->cxreps > 0) {
1314 AESContext **dummycx;
1315 dummycx = PORT_Alloc(cipherInfo->cxreps * sizeof(AESContext *));
1316 TIMESTART();
1317 for (i=0; i<cipherInfo->cxreps; i++) {
1318 dummycx[i] = (void*)AES_CreateContext(aesp->key.buf.data,
1319 aesp->iv.buf.data,
1320 minorMode, encrypt,
1321 keylen, blocklen);
1323 TIMEFINISH(cipherInfo->cxtime, 1.0);
1324 for (i=0; i<cipherInfo->cxreps; i++) {
1325 AES_DestroyContext(dummycx[i], PR_TRUE);
1327 PORT_Free(dummycx);
1329 if (encrypt)
1330 cipherInfo->cipher.symmkeyCipher = aes_Encrypt;
1331 else
1332 cipherInfo->cipher.symmkeyCipher = aes_Decrypt;
1333 return SECSuccess;
1336 SECStatus
1337 bltest_camellia_init(bltestCipherInfo *cipherInfo, PRBool encrypt)
1339 bltestSymmKeyParams *camelliap = &cipherInfo->params.sk;
1340 int minorMode;
1341 int i;
1342 int keylen = camelliap->key.buf.len;
1343 int blocklen = CAMELLIA_BLOCK_SIZE;
1344 PRIntervalTime time1, time2;
1346 switch (cipherInfo->mode) {
1347 case bltestCAMELLIA_ECB: minorMode = NSS_CAMELLIA; break;
1348 case bltestCAMELLIA_CBC: minorMode = NSS_CAMELLIA_CBC; break;
1349 default:
1350 return SECFailure;
1352 cipherInfo->cx = (void*)Camellia_CreateContext(camelliap->key.buf.data,
1353 camelliap->iv.buf.data,
1354 minorMode, encrypt,
1355 keylen);
1356 if (cipherInfo->cxreps > 0) {
1357 CamelliaContext **dummycx;
1358 dummycx = PORT_Alloc(cipherInfo->cxreps * sizeof(CamelliaContext *));
1359 TIMESTART();
1360 for (i=0; i<cipherInfo->cxreps; i++) {
1361 dummycx[i] = (void*)Camellia_CreateContext(camelliap->key.buf.data,
1362 camelliap->iv.buf.data,
1363 minorMode, encrypt,
1364 keylen);
1366 TIMEFINISH(cipherInfo->cxtime, 1.0);
1367 for (i=0; i<cipherInfo->cxreps; i++) {
1368 Camellia_DestroyContext(dummycx[i], PR_TRUE);
1370 PORT_Free(dummycx);
1372 if (encrypt)
1373 cipherInfo->cipher.symmkeyCipher = camellia_Encrypt;
1374 else
1375 cipherInfo->cipher.symmkeyCipher = camellia_Decrypt;
1376 return SECSuccess;
1379 SECStatus
1380 bltest_rsa_init(bltestCipherInfo *cipherInfo, PRBool encrypt)
1382 int i;
1383 RSAPrivateKey **dummyKey;
1384 PRIntervalTime time1, time2;
1385 bltestRSAParams *rsap = &cipherInfo->params.rsa;
1386 /* RSA key gen was done during parameter setup */
1387 cipherInfo->cx = cipherInfo->params.rsa.rsakey;
1388 /* For performance testing */
1389 if (cipherInfo->cxreps > 0) {
1390 /* Create space for n private key objects */
1391 dummyKey = (RSAPrivateKey **)PORT_Alloc(cipherInfo->cxreps *
1392 sizeof(RSAPrivateKey *));
1393 /* Time n keygens, storing in the array */
1394 TIMESTART();
1395 for (i=0; i<cipherInfo->cxreps; i++)
1396 dummyKey[i] = RSA_NewKey(rsap->keysizeInBits,
1397 &rsap->rsakey->publicExponent);
1398 TIMEFINISH(cipherInfo->cxtime, cipherInfo->cxreps);
1399 /* Free the n key objects */
1400 for (i=0; i<cipherInfo->cxreps; i++)
1401 PORT_FreeArena(dummyKey[i]->arena, PR_TRUE);
1402 PORT_Free(dummyKey);
1404 if (encrypt) {
1405 /* Have to convert private key to public key. Memory
1406 * is freed with private key's arena */
1407 RSAPublicKey *pubkey;
1408 RSAPrivateKey *key = (RSAPrivateKey *)cipherInfo->cx;
1409 pubkey = (RSAPublicKey *)PORT_ArenaAlloc(key->arena,
1410 sizeof(RSAPublicKey));
1411 pubkey->modulus.len = key->modulus.len;
1412 pubkey->modulus.data = key->modulus.data;
1413 pubkey->publicExponent.len = key->publicExponent.len;
1414 pubkey->publicExponent.data = key->publicExponent.data;
1415 cipherInfo->cx = (void *)pubkey;
1416 cipherInfo->cipher.pubkeyCipher = rsa_PublicKeyOp;
1417 } else {
1418 cipherInfo->cipher.pubkeyCipher = rsa_PrivateKeyOp;
1420 return SECSuccess;
1423 SECStatus
1424 bltest_pqg_init(bltestDSAParams *dsap)
1426 SECStatus rv, res;
1427 PQGVerify *vfy = NULL;
1428 rv = PQG_ParamGen(dsap->j, &dsap->pqg, &vfy);
1429 CHECKERROR(rv, __LINE__);
1430 rv = PQG_VerifyParams(dsap->pqg, vfy, &res);
1431 CHECKERROR(res, __LINE__);
1432 CHECKERROR(rv, __LINE__);
1433 return rv;
1436 SECStatus
1437 bltest_dsa_init(bltestCipherInfo *cipherInfo, PRBool encrypt)
1439 int i;
1440 DSAPrivateKey **dummyKey;
1441 PQGParams *dummypqg;
1442 PRIntervalTime time1, time2;
1443 bltestDSAParams *dsap = &cipherInfo->params.dsa;
1444 PQGVerify *ignore = NULL;
1445 /* DSA key gen was done during parameter setup */
1446 cipherInfo->cx = cipherInfo->params.dsa.dsakey;
1447 /* For performance testing */
1448 if (cipherInfo->cxreps > 0) {
1449 /* Create space for n private key objects */
1450 dummyKey = (DSAPrivateKey **)PORT_ZAlloc(cipherInfo->cxreps *
1451 sizeof(DSAPrivateKey *));
1452 /* Time n keygens, storing in the array */
1453 TIMESTART();
1454 for (i=0; i<cipherInfo->cxreps; i++) {
1455 dummypqg = NULL;
1456 PQG_ParamGen(dsap->j, &dummypqg, &ignore);
1457 DSA_NewKey(dummypqg, &dummyKey[i]);
1459 TIMEFINISH(cipherInfo->cxtime, cipherInfo->cxreps);
1460 /* Free the n key objects */
1461 for (i=0; i<cipherInfo->cxreps; i++)
1462 PORT_FreeArena(dummyKey[i]->params.arena, PR_TRUE);
1463 PORT_Free(dummyKey);
1465 if (!dsap->pqg && dsap->pqgdata.buf.len > 0) {
1466 dsap->pqg = pqg_from_filedata(&dsap->pqgdata.buf);
1468 if (!cipherInfo->cx && dsap->key.buf.len > 0) {
1469 cipherInfo->cx = dsakey_from_filedata(&dsap->key.buf);
1471 if (encrypt) {
1472 cipherInfo->cipher.pubkeyCipher = dsa_signDigest;
1473 } else {
1474 /* Have to convert private key to public key. Memory
1475 * is freed with private key's arena */
1476 DSAPublicKey *pubkey;
1477 DSAPrivateKey *key = (DSAPrivateKey *)cipherInfo->cx;
1478 pubkey = (DSAPublicKey *)PORT_ArenaZAlloc(key->params.arena,
1479 sizeof(DSAPublicKey));
1480 pubkey->params.prime.len = key->params.prime.len;
1481 pubkey->params.prime.data = key->params.prime.data;
1482 pubkey->params.subPrime.len = key->params.subPrime.len;
1483 pubkey->params.subPrime.data = key->params.subPrime.data;
1484 pubkey->params.base.len = key->params.base.len;
1485 pubkey->params.base.data = key->params.base.data;
1486 pubkey->publicValue.len = key->publicValue.len;
1487 pubkey->publicValue.data = key->publicValue.data;
1488 cipherInfo->cipher.pubkeyCipher = dsa_verifyDigest;
1490 return SECSuccess;
1493 #ifdef NSS_ENABLE_ECC
1494 SECStatus
1495 bltest_ecdsa_init(bltestCipherInfo *cipherInfo, PRBool encrypt)
1497 int i;
1498 ECPrivateKey **dummyKey;
1499 PRIntervalTime time1, time2;
1500 bltestECDSAParams *ecdsap = &cipherInfo->params.ecdsa;
1501 /* ECDSA key gen was done during parameter setup */
1502 cipherInfo->cx = cipherInfo->params.ecdsa.eckey;
1503 /* For performance testing */
1504 if (cipherInfo->cxreps > 0) {
1505 /* Create space for n private key objects */
1506 dummyKey = (ECPrivateKey **)PORT_ZAlloc(cipherInfo->cxreps *
1507 sizeof(ECPrivateKey *));
1508 /* Time n keygens, storing in the array */
1509 TIMESTART();
1510 for (i=0; i<cipherInfo->cxreps; i++) {
1511 EC_NewKey(&ecdsap->eckey->ecParams, &dummyKey[i]);
1513 TIMEFINISH(cipherInfo->cxtime, cipherInfo->cxreps);
1514 /* Free the n key objects */
1515 for (i=0; i<cipherInfo->cxreps; i++)
1516 PORT_FreeArena(dummyKey[i]->ecParams.arena, PR_TRUE);
1517 PORT_Free(dummyKey);
1519 if (!cipherInfo->cx && ecdsap->key.buf.len > 0) {
1520 cipherInfo->cx = eckey_from_filedata(&ecdsap->key.buf);
1522 if (encrypt) {
1523 cipherInfo->cipher.pubkeyCipher = ecdsa_signDigest;
1524 } else {
1525 /* Have to convert private key to public key. Memory
1526 * is freed with private key's arena */
1527 ECPublicKey *pubkey;
1528 ECPrivateKey *key = (ECPrivateKey *)cipherInfo->cx;
1529 pubkey = (ECPublicKey *)PORT_ArenaZAlloc(key->ecParams.arena,
1530 sizeof(ECPublicKey));
1531 pubkey->ecParams.type = key->ecParams.type;
1532 pubkey->ecParams.fieldID.size = key->ecParams.fieldID.size;
1533 pubkey->ecParams.fieldID.type = key->ecParams.fieldID.type;
1534 pubkey->ecParams.fieldID.u.prime.len = key->ecParams.fieldID.u.prime.len;
1535 pubkey->ecParams.fieldID.u.prime.data = key->ecParams.fieldID.u.prime.data;
1536 pubkey->ecParams.fieldID.k1 = key->ecParams.fieldID.k1;
1537 pubkey->ecParams.fieldID.k2 = key->ecParams.fieldID.k2;
1538 pubkey->ecParams.fieldID.k3 = key->ecParams.fieldID.k3;
1539 pubkey->ecParams.curve.a.len = key->ecParams.curve.a.len;
1540 pubkey->ecParams.curve.a.data = key->ecParams.curve.a.data;
1541 pubkey->ecParams.curve.b.len = key->ecParams.curve.b.len;
1542 pubkey->ecParams.curve.b.data = key->ecParams.curve.b.data;
1543 pubkey->ecParams.curve.seed.len = key->ecParams.curve.seed.len;
1544 pubkey->ecParams.curve.seed.data = key->ecParams.curve.seed.data;
1545 pubkey->ecParams.base.len = key->ecParams.base.len;
1546 pubkey->ecParams.base.data = key->ecParams.base.data;
1547 pubkey->ecParams.order.len = key->ecParams.order.len;
1548 pubkey->ecParams.order.data = key->ecParams.order.data;
1549 pubkey->ecParams.cofactor = key->ecParams.cofactor;
1550 pubkey->ecParams.DEREncoding.len = key->ecParams.DEREncoding.len;
1551 pubkey->ecParams.DEREncoding.data = key->ecParams.DEREncoding.data;
1552 pubkey->ecParams.name= key->ecParams.name;
1553 pubkey->publicValue.len = key->publicValue.len;
1554 pubkey->publicValue.data = key->publicValue.data;
1555 cipherInfo->cipher.pubkeyCipher = ecdsa_verifyDigest;
1557 return SECSuccess;
1559 #endif
1561 /* XXX unfortunately, this is not defined in blapi.h */
1562 SECStatus
1563 md2_HashBuf(unsigned char *dest, const unsigned char *src, uint32 src_length)
1565 unsigned int len;
1566 MD2Context *cx = MD2_NewContext();
1567 if (cx == NULL) return SECFailure;
1568 MD2_Begin(cx);
1569 MD2_Update(cx, src, src_length);
1570 MD2_End(cx, dest, &len, MD2_LENGTH);
1571 MD2_DestroyContext(cx, PR_TRUE);
1572 return SECSuccess;
1575 SECStatus
1576 md2_restart(unsigned char *dest, const unsigned char *src, uint32 src_length)
1578 MD2Context *cx, *cx_cpy;
1579 unsigned char *cxbytes;
1580 unsigned int len;
1581 unsigned int i, quarter;
1582 SECStatus rv = SECSuccess;
1583 cx = MD2_NewContext();
1584 MD2_Begin(cx);
1585 /* divide message by 4, restarting 3 times */
1586 quarter = (src_length + 3)/ 4;
1587 for (i=0; i < 4 && src_length > 0; i++) {
1588 MD2_Update(cx, src + i*quarter, PR_MIN(quarter, src_length));
1589 len = MD2_FlattenSize(cx);
1590 cxbytes = PORT_Alloc(len);
1591 MD2_Flatten(cx, cxbytes);
1592 cx_cpy = MD2_Resurrect(cxbytes, NULL);
1593 if (!cx_cpy) {
1594 PR_fprintf(PR_STDERR, "%s: MD2_Resurrect failed!\n", progName);
1595 goto finish;
1597 rv = PORT_Memcmp(cx, cx_cpy, len);
1598 if (rv) {
1599 MD2_DestroyContext(cx_cpy, PR_TRUE);
1600 PR_fprintf(PR_STDERR, "%s: MD2_restart failed!\n", progName);
1601 goto finish;
1603 MD2_DestroyContext(cx_cpy, PR_TRUE);
1604 PORT_Free(cxbytes);
1605 src_length -= quarter;
1607 MD2_End(cx, dest, &len, MD2_LENGTH);
1608 finish:
1609 MD2_DestroyContext(cx, PR_TRUE);
1610 return rv;
1613 SECStatus
1614 md5_restart(unsigned char *dest, const unsigned char *src, uint32 src_length)
1616 SECStatus rv = SECSuccess;
1617 MD5Context *cx, *cx_cpy;
1618 unsigned char *cxbytes;
1619 unsigned int len;
1620 unsigned int i, quarter;
1621 cx = MD5_NewContext();
1622 MD5_Begin(cx);
1623 /* divide message by 4, restarting 3 times */
1624 quarter = (src_length + 3)/ 4;
1625 for (i=0; i < 4 && src_length > 0; i++) {
1626 MD5_Update(cx, src + i*quarter, PR_MIN(quarter, src_length));
1627 len = MD5_FlattenSize(cx);
1628 cxbytes = PORT_Alloc(len);
1629 MD5_Flatten(cx, cxbytes);
1630 cx_cpy = MD5_Resurrect(cxbytes, NULL);
1631 if (!cx_cpy) {
1632 PR_fprintf(PR_STDERR, "%s: MD5_Resurrect failed!\n", progName);
1633 rv = SECFailure;
1634 goto finish;
1636 rv = PORT_Memcmp(cx, cx_cpy, len);
1637 if (rv) {
1638 MD5_DestroyContext(cx_cpy, PR_TRUE);
1639 PR_fprintf(PR_STDERR, "%s: MD5_restart failed!\n", progName);
1640 goto finish;
1642 MD5_DestroyContext(cx_cpy, PR_TRUE);
1643 PORT_Free(cxbytes);
1644 src_length -= quarter;
1646 MD5_End(cx, dest, &len, MD5_LENGTH);
1647 finish:
1648 MD5_DestroyContext(cx, PR_TRUE);
1649 return rv;
1652 SECStatus
1653 sha1_restart(unsigned char *dest, const unsigned char *src, uint32 src_length)
1655 SECStatus rv = SECSuccess;
1656 SHA1Context *cx, *cx_cpy;
1657 unsigned char *cxbytes;
1658 unsigned int len;
1659 unsigned int i, quarter;
1660 cx = SHA1_NewContext();
1661 SHA1_Begin(cx);
1662 /* divide message by 4, restarting 3 times */
1663 quarter = (src_length + 3)/ 4;
1664 for (i=0; i < 4 && src_length > 0; i++) {
1665 SHA1_Update(cx, src + i*quarter, PR_MIN(quarter, src_length));
1666 len = SHA1_FlattenSize(cx);
1667 cxbytes = PORT_Alloc(len);
1668 SHA1_Flatten(cx, cxbytes);
1669 cx_cpy = SHA1_Resurrect(cxbytes, NULL);
1670 if (!cx_cpy) {
1671 PR_fprintf(PR_STDERR, "%s: SHA1_Resurrect failed!\n", progName);
1672 rv = SECFailure;
1673 goto finish;
1675 rv = PORT_Memcmp(cx, cx_cpy, len);
1676 if (rv) {
1677 SHA1_DestroyContext(cx_cpy, PR_TRUE);
1678 PR_fprintf(PR_STDERR, "%s: SHA1_restart failed!\n", progName);
1679 goto finish;
1681 SHA1_DestroyContext(cx_cpy, PR_TRUE);
1682 PORT_Free(cxbytes);
1683 src_length -= quarter;
1685 SHA1_End(cx, dest, &len, MD5_LENGTH);
1686 finish:
1687 SHA1_DestroyContext(cx, PR_TRUE);
1688 return rv;
1691 SECStatus
1692 SHA256_restart(unsigned char *dest, const unsigned char *src, uint32 src_length)
1694 SECStatus rv = SECSuccess;
1695 SHA256Context *cx, *cx_cpy;
1696 unsigned char *cxbytes;
1697 unsigned int len;
1698 unsigned int i, quarter;
1699 cx = SHA256_NewContext();
1700 SHA256_Begin(cx);
1701 /* divide message by 4, restarting 3 times */
1702 quarter = (src_length + 3)/ 4;
1703 for (i=0; i < 4 && src_length > 0; i++) {
1704 SHA256_Update(cx, src + i*quarter, PR_MIN(quarter, src_length));
1705 len = SHA256_FlattenSize(cx);
1706 cxbytes = PORT_Alloc(len);
1707 SHA256_Flatten(cx, cxbytes);
1708 cx_cpy = SHA256_Resurrect(cxbytes, NULL);
1709 if (!cx_cpy) {
1710 PR_fprintf(PR_STDERR, "%s: SHA256_Resurrect failed!\n", progName);
1711 rv = SECFailure;
1712 goto finish;
1714 rv = PORT_Memcmp(cx, cx_cpy, len);
1715 if (rv) {
1716 SHA256_DestroyContext(cx_cpy, PR_TRUE);
1717 PR_fprintf(PR_STDERR, "%s: SHA256_restart failed!\n", progName);
1718 goto finish;
1720 SHA256_DestroyContext(cx_cpy, PR_TRUE);
1721 PORT_Free(cxbytes);
1722 src_length -= quarter;
1724 SHA256_End(cx, dest, &len, MD5_LENGTH);
1725 finish:
1726 SHA256_DestroyContext(cx, PR_TRUE);
1727 return rv;
1730 SECStatus
1731 SHA384_restart(unsigned char *dest, const unsigned char *src, uint32 src_length)
1733 SECStatus rv = SECSuccess;
1734 SHA384Context *cx, *cx_cpy;
1735 unsigned char *cxbytes;
1736 unsigned int len;
1737 unsigned int i, quarter;
1738 cx = SHA384_NewContext();
1739 SHA384_Begin(cx);
1740 /* divide message by 4, restarting 3 times */
1741 quarter = (src_length + 3)/ 4;
1742 for (i=0; i < 4 && src_length > 0; i++) {
1743 SHA384_Update(cx, src + i*quarter, PR_MIN(quarter, src_length));
1744 len = SHA384_FlattenSize(cx);
1745 cxbytes = PORT_Alloc(len);
1746 SHA384_Flatten(cx, cxbytes);
1747 cx_cpy = SHA384_Resurrect(cxbytes, NULL);
1748 if (!cx_cpy) {
1749 PR_fprintf(PR_STDERR, "%s: SHA384_Resurrect failed!\n", progName);
1750 rv = SECFailure;
1751 goto finish;
1753 rv = PORT_Memcmp(cx, cx_cpy, len);
1754 if (rv) {
1755 SHA384_DestroyContext(cx_cpy, PR_TRUE);
1756 PR_fprintf(PR_STDERR, "%s: SHA384_restart failed!\n", progName);
1757 goto finish;
1759 SHA384_DestroyContext(cx_cpy, PR_TRUE);
1760 PORT_Free(cxbytes);
1761 src_length -= quarter;
1763 SHA384_End(cx, dest, &len, MD5_LENGTH);
1764 finish:
1765 SHA384_DestroyContext(cx, PR_TRUE);
1766 return rv;
1769 SECStatus
1770 SHA512_restart(unsigned char *dest, const unsigned char *src, uint32 src_length)
1772 SECStatus rv = SECSuccess;
1773 SHA512Context *cx, *cx_cpy;
1774 unsigned char *cxbytes;
1775 unsigned int len;
1776 unsigned int i, quarter;
1777 cx = SHA512_NewContext();
1778 SHA512_Begin(cx);
1779 /* divide message by 4, restarting 3 times */
1780 quarter = (src_length + 3)/ 4;
1781 for (i=0; i < 4 && src_length > 0; i++) {
1782 SHA512_Update(cx, src + i*quarter, PR_MIN(quarter, src_length));
1783 len = SHA512_FlattenSize(cx);
1784 cxbytes = PORT_Alloc(len);
1785 SHA512_Flatten(cx, cxbytes);
1786 cx_cpy = SHA512_Resurrect(cxbytes, NULL);
1787 if (!cx_cpy) {
1788 PR_fprintf(PR_STDERR, "%s: SHA512_Resurrect failed!\n", progName);
1789 rv = SECFailure;
1790 goto finish;
1792 rv = PORT_Memcmp(cx, cx_cpy, len);
1793 if (rv) {
1794 SHA512_DestroyContext(cx_cpy, PR_TRUE);
1795 PR_fprintf(PR_STDERR, "%s: SHA512_restart failed!\n", progName);
1796 goto finish;
1798 SHA512_DestroyContext(cx_cpy, PR_TRUE);
1799 PORT_Free(cxbytes);
1800 src_length -= quarter;
1802 SHA512_End(cx, dest, &len, MD5_LENGTH);
1803 finish:
1804 SHA512_DestroyContext(cx, PR_TRUE);
1805 return rv;
1808 SECStatus
1809 pubkeyInitKey(bltestCipherInfo *cipherInfo, PRFileDesc *file,
1810 #ifdef NSS_ENABLE_ECC
1811 int keysize, int exponent, char *curveName)
1812 #else
1813 int keysize, int exponent)
1814 #endif
1816 int i;
1817 SECStatus rv = SECSuccess;
1818 bltestRSAParams *rsap;
1819 bltestDSAParams *dsap;
1820 #ifdef NSS_ENABLE_ECC
1821 bltestECDSAParams *ecdsap;
1822 SECItem *tmpECParamsDER;
1823 ECParams *tmpECParams = NULL;
1824 SECItem ecSerialize[3];
1825 #endif
1826 switch (cipherInfo->mode) {
1827 case bltestRSA:
1828 rsap = &cipherInfo->params.rsa;
1829 if (keysize > 0) {
1830 SECItem expitem = { 0, 0, 0 };
1831 SECITEM_AllocItem(cipherInfo->arena, &expitem, sizeof(int));
1832 for (i = 1; i <= sizeof(int); i++)
1833 expitem.data[i-1] = exponent >> (8*(sizeof(int) - i));
1834 rsap->rsakey = RSA_NewKey(keysize * 8, &expitem);
1835 serialize_key(&rsap->rsakey->version, 9, file);
1836 rsap->keysizeInBits = keysize * 8;
1837 } else {
1838 setupIO(cipherInfo->arena, &cipherInfo->params.key, file, NULL, 0);
1839 rsap->rsakey = rsakey_from_filedata(&cipherInfo->params.key.buf);
1840 rsap->keysizeInBits = rsap->rsakey->modulus.len * 8;
1842 break;
1843 case bltestDSA:
1844 dsap = &cipherInfo->params.dsa;
1845 if (keysize > 0) {
1846 dsap->j = PQG_PBITS_TO_INDEX(8*keysize);
1847 if (!dsap->pqg)
1848 bltest_pqg_init(dsap);
1849 rv = DSA_NewKey(dsap->pqg, &dsap->dsakey);
1850 CHECKERROR(rv, __LINE__);
1851 serialize_key(&dsap->dsakey->params.prime, 5, file);
1852 } else {
1853 setupIO(cipherInfo->arena, &cipherInfo->params.key, file, NULL, 0);
1854 dsap->dsakey = dsakey_from_filedata(&cipherInfo->params.key.buf);
1855 dsap->j = PQG_PBITS_TO_INDEX(8*dsap->dsakey->params.prime.len);
1857 break;
1858 #ifdef NSS_ENABLE_ECC
1859 case bltestECDSA:
1860 ecdsap = &cipherInfo->params.ecdsa;
1861 if (curveName != NULL) {
1862 tmpECParamsDER = getECParams(curveName);
1863 rv = SECOID_Init();
1864 CHECKERROR(rv, __LINE__);
1865 rv = EC_DecodeParams(tmpECParamsDER, &tmpECParams) == SECFailure;
1866 CHECKERROR(rv, __LINE__);
1867 rv = EC_NewKey(tmpECParams, &ecdsap->eckey);
1868 CHECKERROR(rv, __LINE__);
1869 ecSerialize[0].type = tmpECParamsDER->type;
1870 ecSerialize[0].data = tmpECParamsDER->data;
1871 ecSerialize[0].len = tmpECParamsDER->len;
1872 ecSerialize[1].type = ecdsap->eckey->publicValue.type;
1873 ecSerialize[1].data = ecdsap->eckey->publicValue.data;
1874 ecSerialize[1].len = ecdsap->eckey->publicValue.len;
1875 ecSerialize[2].type = ecdsap->eckey->privateValue.type;
1876 ecSerialize[2].data = ecdsap->eckey->privateValue.data;
1877 ecSerialize[2].len = ecdsap->eckey->privateValue.len;
1878 serialize_key(&(ecSerialize[0]), 3, file);
1879 SECITEM_FreeItem(tmpECParamsDER, PR_TRUE);
1880 PORT_FreeArena(tmpECParams->arena, PR_TRUE);
1881 rv = SECOID_Shutdown();
1882 CHECKERROR(rv, __LINE__);
1883 } else {
1884 setupIO(cipherInfo->arena, &cipherInfo->params.key, file, NULL, 0);
1885 ecdsap->eckey = eckey_from_filedata(&cipherInfo->params.key.buf);
1887 break;
1888 #endif
1889 default:
1890 return SECFailure;
1892 return SECSuccess;
1895 SECStatus
1896 cipherInit(bltestCipherInfo *cipherInfo, PRBool encrypt)
1898 PRBool restart;
1899 switch (cipherInfo->mode) {
1900 case bltestDES_ECB:
1901 case bltestDES_CBC:
1902 case bltestDES_EDE_ECB:
1903 case bltestDES_EDE_CBC:
1904 SECITEM_AllocItem(cipherInfo->arena, &cipherInfo->output.buf,
1905 cipherInfo->input.pBuf.len);
1906 return bltest_des_init(cipherInfo, encrypt);
1907 break;
1908 case bltestRC2_ECB:
1909 case bltestRC2_CBC:
1910 SECITEM_AllocItem(cipherInfo->arena, &cipherInfo->output.buf,
1911 cipherInfo->input.pBuf.len);
1912 return bltest_rc2_init(cipherInfo, encrypt);
1913 break;
1914 case bltestRC4:
1915 SECITEM_AllocItem(cipherInfo->arena, &cipherInfo->output.buf,
1916 cipherInfo->input.pBuf.len);
1917 return bltest_rc4_init(cipherInfo, encrypt);
1918 break;
1919 case bltestRC5_ECB:
1920 case bltestRC5_CBC:
1921 #if NSS_SOFTOKEN_DOES_RC5
1922 SECITEM_AllocItem(cipherInfo->arena, &cipherInfo->output.buf,
1923 cipherInfo->input.pBuf.len);
1924 #endif
1925 return bltest_rc5_init(cipherInfo, encrypt);
1926 break;
1927 case bltestAES_ECB:
1928 case bltestAES_CBC:
1929 SECITEM_AllocItem(cipherInfo->arena, &cipherInfo->output.buf,
1930 cipherInfo->input.pBuf.len);
1931 return bltest_aes_init(cipherInfo, encrypt);
1932 break;
1933 case bltestCAMELLIA_ECB:
1934 case bltestCAMELLIA_CBC:
1935 SECITEM_AllocItem(cipherInfo->arena, &cipherInfo->output.buf,
1936 cipherInfo->input.pBuf.len);
1937 return bltest_camellia_init(cipherInfo, encrypt);
1938 break;
1939 case bltestRSA:
1940 SECITEM_AllocItem(cipherInfo->arena, &cipherInfo->output.buf,
1941 cipherInfo->input.pBuf.len);
1942 return bltest_rsa_init(cipherInfo, encrypt);
1943 break;
1944 case bltestDSA:
1945 SECITEM_AllocItem(cipherInfo->arena, &cipherInfo->output.buf,
1946 DSA_SIGNATURE_LEN);
1947 return bltest_dsa_init(cipherInfo, encrypt);
1948 break;
1949 #ifdef NSS_ENABLE_ECC
1950 case bltestECDSA:
1951 SECITEM_AllocItem(cipherInfo->arena, &cipherInfo->output.buf,
1952 2 * MAX_ECKEY_LEN);
1953 return bltest_ecdsa_init(cipherInfo, encrypt);
1954 break;
1955 #endif
1956 case bltestMD2:
1957 restart = cipherInfo->params.hash.restart;
1958 SECITEM_AllocItem(cipherInfo->arena, &cipherInfo->output.buf,
1959 MD2_LENGTH);
1960 cipherInfo->cipher.hashCipher = (restart) ? md2_restart : md2_HashBuf;
1961 return SECSuccess;
1962 break;
1963 case bltestMD5:
1964 restart = cipherInfo->params.hash.restart;
1965 SECITEM_AllocItem(cipherInfo->arena, &cipherInfo->output.buf,
1966 MD5_LENGTH);
1967 cipherInfo->cipher.hashCipher = (restart) ? md5_restart : MD5_HashBuf;
1968 return SECSuccess;
1969 break;
1970 case bltestSHA1:
1971 restart = cipherInfo->params.hash.restart;
1972 SECITEM_AllocItem(cipherInfo->arena, &cipherInfo->output.buf,
1973 SHA1_LENGTH);
1974 cipherInfo->cipher.hashCipher = (restart) ? sha1_restart : SHA1_HashBuf;
1975 return SECSuccess;
1976 break;
1977 case bltestSHA256:
1978 restart = cipherInfo->params.hash.restart;
1979 SECITEM_AllocItem(cipherInfo->arena, &cipherInfo->output.buf,
1980 SHA256_LENGTH);
1981 cipherInfo->cipher.hashCipher = (restart) ? SHA256_restart
1982 : SHA256_HashBuf;
1983 return SECSuccess;
1984 break;
1985 case bltestSHA384:
1986 restart = cipherInfo->params.hash.restart;
1987 SECITEM_AllocItem(cipherInfo->arena, &cipherInfo->output.buf,
1988 SHA384_LENGTH);
1989 cipherInfo->cipher.hashCipher = (restart) ? SHA384_restart
1990 : SHA384_HashBuf;
1991 return SECSuccess;
1992 break;
1993 case bltestSHA512:
1994 restart = cipherInfo->params.hash.restart;
1995 SECITEM_AllocItem(cipherInfo->arena, &cipherInfo->output.buf,
1996 SHA512_LENGTH);
1997 cipherInfo->cipher.hashCipher = (restart) ? SHA512_restart
1998 : SHA512_HashBuf;
1999 return SECSuccess;
2000 break;
2001 default:
2002 return SECFailure;
2004 return SECSuccess;
2007 SECStatus
2008 dsaOp(bltestCipherInfo *cipherInfo)
2010 PRIntervalTime time1, time2;
2011 SECStatus rv = SECSuccess;
2012 int i;
2013 int maxLen = cipherInfo->output.pBuf.len;
2014 SECItem dummyOut = { 0, 0, 0 };
2015 SECITEM_AllocItem(NULL, &dummyOut, maxLen);
2016 if (cipherInfo->cipher.pubkeyCipher == dsa_signDigest) {
2017 if (cipherInfo->params.dsa.sigseed.buf.len > 0) {
2018 bltestDSAParams *dsa = &cipherInfo->params.dsa;
2019 DSAPrivateKey *key = (DSAPrivateKey *)cipherInfo->cx;
2021 TIMESTART();
2022 rv = DSA_SignDigestWithSeed(key,
2023 &cipherInfo->output.pBuf,
2024 &cipherInfo->input.pBuf,
2025 dsa->sigseed.buf.data);
2026 TIMEFINISH(cipherInfo->optime, 1.0);
2027 CHECKERROR(rv, __LINE__);
2028 cipherInfo->repetitions = 0;
2029 if (cipherInfo->repetitionsToPerfom != 0) {
2030 TIMESTART();
2031 for (i=0; i<cipherInfo->repetitionsToPerfom;
2032 i++, cipherInfo->repetitions++) {
2033 rv = DSA_SignDigestWithSeed(key, &dummyOut,
2034 &cipherInfo->input.pBuf,
2035 dsa->sigseed.buf.data);
2036 CHECKERROR(rv, __LINE__);
2038 } else {
2039 int opsBetweenChecks = 0;
2040 TIMEMARK(cipherInfo->seconds);
2041 while (! (TIMETOFINISH())) {
2042 int j = 0;
2043 for (;j < opsBetweenChecks;j++) {
2044 rv = DSA_SignDigestWithSeed(key, &dummyOut,
2045 &cipherInfo->input.pBuf,
2046 dsa->sigseed.buf.data);
2047 CHECKERROR(rv, __LINE__);
2049 cipherInfo->repetitions += j;
2052 TIMEFINISH(cipherInfo->optime, 1.0);
2053 } else {
2054 TIMESTART();
2055 rv = DSA_SignDigest((DSAPrivateKey *)cipherInfo->cx,
2056 &cipherInfo->output.pBuf,
2057 &cipherInfo->input.pBuf);
2058 TIMEFINISH(cipherInfo->optime, 1.0);
2059 CHECKERROR(rv, __LINE__);
2060 cipherInfo->repetitions = 0;
2061 if (cipherInfo->repetitionsToPerfom != 0) {
2062 TIMESTART();
2063 for (i=0; i<cipherInfo->repetitionsToPerfom;
2064 i++, cipherInfo->repetitions++) {
2065 rv = DSA_SignDigest((DSAPrivateKey *)cipherInfo->cx,
2066 &dummyOut,
2067 &cipherInfo->input.pBuf);
2068 CHECKERROR(rv, __LINE__);
2070 } else {
2071 int opsBetweenChecks = 0;
2072 TIMEMARK(cipherInfo->seconds);
2073 while (! (TIMETOFINISH())) {
2074 int j = 0;
2075 for (;j < opsBetweenChecks;j++) {
2076 rv = DSA_SignDigest((DSAPrivateKey *)cipherInfo->cx,
2077 &dummyOut,
2078 &cipherInfo->input.pBuf);
2079 CHECKERROR(rv, __LINE__);
2081 cipherInfo->repetitions += j;
2084 TIMEFINISH(cipherInfo->optime, 1.0);
2086 bltestCopyIO(cipherInfo->arena, &cipherInfo->params.dsa.sig,
2087 &cipherInfo->output);
2088 } else {
2089 TIMESTART();
2090 rv = DSA_VerifyDigest((DSAPublicKey *)cipherInfo->cx,
2091 &cipherInfo->params.dsa.sig.buf,
2092 &cipherInfo->input.pBuf);
2093 TIMEFINISH(cipherInfo->optime, 1.0);
2094 CHECKERROR(rv, __LINE__);
2095 cipherInfo->repetitions = 0;
2096 if (cipherInfo->repetitionsToPerfom != 0) {
2097 TIMESTART();
2098 for (i=0; i<cipherInfo->repetitionsToPerfom;
2099 i++, cipherInfo->repetitions++) {
2100 rv = DSA_VerifyDigest((DSAPublicKey *)cipherInfo->cx,
2101 &cipherInfo->params.dsa.sig.buf,
2102 &cipherInfo->input.pBuf);
2103 CHECKERROR(rv, __LINE__);
2105 } else {
2106 int opsBetweenChecks = 0;
2107 TIMEMARK(cipherInfo->seconds);
2108 while (! (TIMETOFINISH())) {
2109 int j = 0;
2110 for (;j < opsBetweenChecks;j++) {
2111 rv = DSA_VerifyDigest((DSAPublicKey *)cipherInfo->cx,
2112 &cipherInfo->params.dsa.sig.buf,
2113 &cipherInfo->input.pBuf);
2114 CHECKERROR(rv, __LINE__);
2116 cipherInfo->repetitions += j;
2119 TIMEFINISH(cipherInfo->optime, 1.0);
2121 SECITEM_FreeItem(&dummyOut, PR_FALSE);
2122 return rv;
2125 #ifdef NSS_ENABLE_ECC
2126 SECStatus
2127 ecdsaOp(bltestCipherInfo *cipherInfo)
2129 PRIntervalTime time1, time2;
2130 SECStatus rv = SECSuccess;
2131 int i;
2132 int maxLen = cipherInfo->output.pBuf.len;
2133 SECItem dummyOut = { 0, 0, 0 };
2134 SECITEM_AllocItem(NULL, &dummyOut, maxLen);
2135 if (cipherInfo->cipher.pubkeyCipher == ecdsa_signDigest) {
2136 if (cipherInfo->params.ecdsa.sigseed.buf.len > 0) {
2137 ECPrivateKey *key = (ECPrivateKey *)cipherInfo->cx;
2138 bltestECDSAParams *ecdsa = &cipherInfo->params.ecdsa;
2140 TIMESTART();
2141 rv = ECDSA_SignDigestWithSeed(key,
2142 &cipherInfo->output.pBuf,
2143 &cipherInfo->input.pBuf,
2144 ecdsa->sigseed.buf.data,
2145 ecdsa->sigseed.buf.len);
2146 TIMEFINISH(cipherInfo->optime, 1.0);
2147 CHECKERROR(rv, __LINE__);
2148 cipherInfo->repetitions = 0;
2149 if (cipherInfo->repetitionsToPerfom != 0) {
2150 TIMESTART();
2151 for (i=0; i<cipherInfo->repetitionsToPerfom;
2152 i++, cipherInfo->repetitions++) {
2153 rv = ECDSA_SignDigestWithSeed(key, &dummyOut,
2154 &cipherInfo->input.pBuf,
2155 ecdsa->sigseed.buf.data,
2156 ecdsa->sigseed.buf.len);
2157 CHECKERROR(rv, __LINE__);
2159 } else {
2160 int opsBetweenChecks = 0;
2161 TIMEMARK(cipherInfo->seconds);
2162 while (! (TIMETOFINISH())) {
2163 int j = 0;
2164 for (;j < opsBetweenChecks;j++) {
2165 rv = ECDSA_SignDigestWithSeed(key, &dummyOut,
2166 &cipherInfo->input.pBuf,
2167 ecdsa->sigseed.buf.data,
2168 ecdsa->sigseed.buf.len);
2169 CHECKERROR(rv, __LINE__);
2171 cipherInfo->repetitions += j;
2174 TIMEFINISH(cipherInfo->optime, 1.0);
2175 } else {
2176 TIMESTART();
2177 rv = ECDSA_SignDigest((ECPrivateKey *)cipherInfo->cx,
2178 &cipherInfo->output.pBuf,
2179 &cipherInfo->input.pBuf);
2180 TIMEFINISH(cipherInfo->optime, 1.0);
2181 CHECKERROR(rv, __LINE__);
2182 cipherInfo->repetitions = 0;
2183 if (cipherInfo->repetitionsToPerfom != 0) {
2184 TIMESTART();
2185 for (i=0; i<cipherInfo->repetitionsToPerfom;
2186 i++, cipherInfo->repetitions++) {
2187 rv = ECDSA_SignDigest((ECPrivateKey *)cipherInfo->cx,
2188 &dummyOut,
2189 &cipherInfo->input.pBuf);
2190 CHECKERROR(rv, __LINE__);
2192 } else {
2193 int opsBetweenChecks = 0;
2194 TIMEMARK(cipherInfo->seconds);
2195 while (! (TIMETOFINISH())) {
2196 int j = 0;
2197 for (;j < opsBetweenChecks;j++) {
2198 rv = ECDSA_SignDigest((ECPrivateKey *)cipherInfo->cx,
2199 &dummyOut,
2200 &cipherInfo->input.pBuf);
2201 CHECKERROR(rv, __LINE__);
2203 cipherInfo->repetitions += j;
2206 TIMEFINISH(cipherInfo->optime, 1.0);
2208 bltestCopyIO(cipherInfo->arena, &cipherInfo->params.ecdsa.sig,
2209 &cipherInfo->output);
2210 } else {
2211 TIMESTART();
2212 rv = ECDSA_VerifyDigest((ECPublicKey *)cipherInfo->cx,
2213 &cipherInfo->params.ecdsa.sig.buf,
2214 &cipherInfo->input.pBuf);
2215 TIMEFINISH(cipherInfo->optime, 1.0);
2216 CHECKERROR(rv, __LINE__);
2217 cipherInfo->repetitions = 0;
2218 if (cipherInfo->repetitionsToPerfom != 0) {
2219 TIMESTART();
2220 for (i=0; i<cipherInfo->repetitionsToPerfom;
2221 i++, cipherInfo->repetitions++) {
2222 rv = ECDSA_VerifyDigest((ECPublicKey *)cipherInfo->cx,
2223 &cipherInfo->params.ecdsa.sig.buf,
2224 &cipherInfo->input.pBuf);
2225 CHECKERROR(rv, __LINE__);
2227 } else {
2228 int opsBetweenChecks = 0;
2229 TIMEMARK(cipherInfo->seconds);
2230 while (! (TIMETOFINISH())) {
2231 int j = 0;
2232 for (;j < opsBetweenChecks;j++) {
2233 rv = ECDSA_VerifyDigest((ECPublicKey *)cipherInfo->cx,
2234 &cipherInfo->params.ecdsa.sig.buf,
2235 &cipherInfo->input.pBuf);
2236 CHECKERROR(rv, __LINE__);
2238 cipherInfo->repetitions += j;
2241 TIMEFINISH(cipherInfo->optime, 1.0);
2243 SECITEM_FreeItem(&dummyOut, PR_FALSE);
2244 return rv;
2246 #endif
2248 SECStatus
2249 cipherDoOp(bltestCipherInfo *cipherInfo)
2251 PRIntervalTime time1, time2;
2252 SECStatus rv = SECSuccess;
2253 int i, len;
2254 int maxLen = cipherInfo->output.pBuf.len;
2255 unsigned char *dummyOut;
2256 if (cipherInfo->mode == bltestDSA)
2257 return dsaOp(cipherInfo);
2258 #ifdef NSS_ENABLE_ECC
2259 else if (cipherInfo->mode == bltestECDSA)
2260 return ecdsaOp(cipherInfo);
2261 #endif
2262 dummyOut = PORT_Alloc(maxLen);
2263 if (is_symmkeyCipher(cipherInfo->mode)) {
2264 TIMESTART();
2265 rv = (*cipherInfo->cipher.symmkeyCipher)(cipherInfo->cx,
2266 cipherInfo->output.pBuf.data,
2267 &len, maxLen,
2268 cipherInfo->input.pBuf.data,
2269 cipherInfo->input.pBuf.len);
2270 TIMEFINISH(cipherInfo->optime, 1.0);
2271 CHECKERROR(rv, __LINE__);
2272 cipherInfo->repetitions = 0;
2273 if (cipherInfo->repetitionsToPerfom != 0) {
2274 TIMESTART();
2275 for (i=0; i<cipherInfo->repetitionsToPerfom; i++,
2276 cipherInfo->repetitions++) {
2277 (*cipherInfo->cipher.symmkeyCipher)(cipherInfo->cx, dummyOut,
2278 &len, maxLen,
2279 cipherInfo->input.pBuf.data,
2280 cipherInfo->input.pBuf.len);
2282 CHECKERROR(rv, __LINE__);
2284 } else {
2285 int opsBetweenChecks = 0;
2286 bltestIO *input = &cipherInfo->input;
2287 TIMEMARK(cipherInfo->seconds);
2288 while (! (TIMETOFINISH())) {
2289 int j = 0;
2290 for (;j < opsBetweenChecks;j++) {
2291 (*cipherInfo->cipher.symmkeyCipher)(cipherInfo->cx,
2292 dummyOut,
2293 &len, maxLen,
2294 input->pBuf.data,
2295 input->pBuf.len);
2297 cipherInfo->repetitions += j;
2300 TIMEFINISH(cipherInfo->optime, 1.0);
2301 } else if (is_pubkeyCipher(cipherInfo->mode)) {
2302 TIMESTART();
2303 rv = (*cipherInfo->cipher.pubkeyCipher)(cipherInfo->cx,
2304 &cipherInfo->output.pBuf,
2305 &cipherInfo->input.pBuf);
2306 TIMEFINISH(cipherInfo->optime, 1.0);
2307 CHECKERROR(rv, __LINE__);
2308 cipherInfo->repetitions = 0;
2309 if (cipherInfo->repetitionsToPerfom != 0) {
2310 TIMESTART();
2311 for (i=0; i<cipherInfo->repetitionsToPerfom;
2312 i++, cipherInfo->repetitions++) {
2313 SECItem dummy;
2314 dummy.data = dummyOut;
2315 dummy.len = maxLen;
2316 (*cipherInfo->cipher.pubkeyCipher)(cipherInfo->cx, &dummy,
2317 &cipherInfo->input.pBuf);
2318 CHECKERROR(rv, __LINE__);
2320 } else {
2321 int opsBetweenChecks = 0;
2322 TIMEMARK(cipherInfo->seconds);
2323 while (! (TIMETOFINISH())) {
2324 int j = 0;
2325 for (;j < opsBetweenChecks;j++) {
2326 SECItem dummy;
2327 dummy.data = dummyOut;
2328 dummy.len = maxLen;
2329 (*cipherInfo->cipher.pubkeyCipher)(cipherInfo->cx, &dummy,
2330 &cipherInfo->input.pBuf);
2331 CHECKERROR(rv, __LINE__);
2333 cipherInfo->repetitions += j;
2336 TIMEFINISH(cipherInfo->optime, 1.0);
2337 } else if (is_hashCipher(cipherInfo->mode)) {
2338 TIMESTART();
2339 rv = (*cipherInfo->cipher.hashCipher)(cipherInfo->output.pBuf.data,
2340 cipherInfo->input.pBuf.data,
2341 cipherInfo->input.pBuf.len);
2342 TIMEFINISH(cipherInfo->optime, 1.0);
2343 CHECKERROR(rv, __LINE__);
2344 cipherInfo->repetitions = 0;
2345 if (cipherInfo->repetitionsToPerfom != 0) {
2346 TIMESTART();
2347 for (i=0; i<cipherInfo->repetitionsToPerfom;
2348 i++, cipherInfo->repetitions++) {
2349 (*cipherInfo->cipher.hashCipher)(dummyOut,
2350 cipherInfo->input.pBuf.data,
2351 cipherInfo->input.pBuf.len);
2352 CHECKERROR(rv, __LINE__);
2354 } else {
2355 int opsBetweenChecks = 0;
2356 TIMEMARK(cipherInfo->seconds);
2357 while (! (TIMETOFINISH())) {
2358 int j = 0;
2359 for (;j < opsBetweenChecks;j++) {
2360 bltestIO *input = &cipherInfo->input;
2361 (*cipherInfo->cipher.hashCipher)(dummyOut,
2362 input->pBuf.data,
2363 input->pBuf.len);
2364 CHECKERROR(rv, __LINE__);
2366 cipherInfo->repetitions += j;
2369 TIMEFINISH(cipherInfo->optime, 1.0);
2371 PORT_Free(dummyOut);
2372 return rv;
2375 SECStatus
2376 cipherFinish(bltestCipherInfo *cipherInfo)
2378 switch (cipherInfo->mode) {
2379 case bltestDES_ECB:
2380 case bltestDES_CBC:
2381 case bltestDES_EDE_ECB:
2382 case bltestDES_EDE_CBC:
2383 DES_DestroyContext((DESContext *)cipherInfo->cx, PR_TRUE);
2384 break;
2385 case bltestAES_ECB:
2386 case bltestAES_CBC:
2387 AES_DestroyContext((AESContext *)cipherInfo->cx, PR_TRUE);
2388 break;
2389 case bltestCAMELLIA_ECB:
2390 case bltestCAMELLIA_CBC:
2391 Camellia_DestroyContext((CamelliaContext *)cipherInfo->cx, PR_TRUE);
2392 break;
2393 case bltestRC2_ECB:
2394 case bltestRC2_CBC:
2395 RC2_DestroyContext((RC2Context *)cipherInfo->cx, PR_TRUE);
2396 break;
2397 case bltestRC4:
2398 RC4_DestroyContext((RC4Context *)cipherInfo->cx, PR_TRUE);
2399 break;
2400 #if NSS_SOFTOKEN_DOES_RC5
2401 case bltestRC5_ECB:
2402 case bltestRC5_CBC:
2403 RC5_DestroyContext((RC5Context *)cipherInfo->cx, PR_TRUE);
2404 break;
2405 #endif
2406 case bltestRSA: /* keys are alloc'ed within cipherInfo's arena, */
2407 case bltestDSA: /* will be freed with it. */
2408 #ifdef NSS_ENABLE_ECC
2409 case bltestECDSA:
2410 #endif
2411 case bltestMD2: /* hash contexts are ephemeral */
2412 case bltestMD5:
2413 case bltestSHA1:
2414 case bltestSHA256:
2415 case bltestSHA384:
2416 case bltestSHA512:
2417 return SECSuccess;
2418 break;
2419 default:
2420 return SECFailure;
2422 return SECSuccess;
2425 void
2426 print_exponent(SECItem *exp)
2428 int i;
2429 int e = 0;
2430 if (exp->len <= 4) {
2431 for (i=exp->len; i >=0; --i) e |= exp->data[exp->len-i] << 8*(i-1);
2432 fprintf(stdout, "%12d", e);
2433 } else {
2434 e = 8*exp->len;
2435 fprintf(stdout, "~2**%-8d", e);
2439 static void
2440 splitToReportUnit(PRInt64 res, int *resArr, int *del, int size)
2442 PRInt64 remaining = res, tmp = 0;
2443 PRInt64 Ldel;
2444 int i = -1;
2446 while (remaining > 0 && ++i < size) {
2447 LL_I2L(Ldel, del[i]);
2448 LL_MOD(tmp, remaining, Ldel);
2449 LL_L2I(resArr[i], tmp);
2450 LL_DIV(remaining, remaining, Ldel);
2454 static char*
2455 getHighUnitBytes(PRInt64 res)
2457 int spl[] = {0, 0, 0, 0};
2458 int del[] = {1024, 1024, 1024, 1024};
2459 char *marks[] = {"b", "Kb", "Mb", "Gb"};
2460 int i = 3;
2462 splitToReportUnit(res, spl, del, 4);
2464 for (;i>0;i--) {
2465 if (spl[i] != 0) {
2466 break;
2470 return PR_smprintf("%d%s", spl[i], marks[i]);
2474 static void
2475 printPR_smpString(const char *sformat, char *reportStr,
2476 const char *nformat, PRInt64 rNum)
2478 if (reportStr) {
2479 fprintf(stdout, sformat, reportStr);
2480 PR_smprintf_free(reportStr);
2481 } else {
2482 int prnRes;
2483 LL_L2I(prnRes, rNum);
2484 fprintf(stdout, nformat, rNum);
2488 static char*
2489 getHighUnitOps(PRInt64 res)
2491 int spl[] = {0, 0, 0, 0};
2492 int del[] = {1000, 1000, 1000, 1000};
2493 char *marks[] = {"", "T", "M", "B"};
2494 int i = 3;
2496 splitToReportUnit(res, spl, del, 4);
2498 for (;i>0;i--) {
2499 if (spl[i] != 0) {
2500 break;
2504 return PR_smprintf("%d%s", spl[i], marks[i]);
2507 void
2508 dump_performance_info(bltestCipherInfo *infoList, double totalTimeInt,
2509 PRBool encrypt, PRBool cxonly)
2511 bltestCipherInfo *info = infoList;
2513 PRInt64 totalIn = 0;
2514 PRBool td = PR_TRUE;
2516 int repetitions = 0;
2517 int cxreps = 0;
2518 double cxtime = 0;
2519 double optime = 0;
2520 while (info != NULL) {
2521 repetitions += info->repetitions;
2522 cxreps += info->cxreps;
2523 cxtime += info->cxtime;
2524 optime += info->optime;
2525 totalIn += (PRInt64) info->input.buf.len * (PRInt64) info->repetitions;
2527 info = info->next;
2529 info = infoList;
2531 fprintf(stdout, "#%9s", "mode");
2532 fprintf(stdout, "%12s", "in");
2533 print_td:
2534 switch (info->mode) {
2535 case bltestDES_ECB:
2536 case bltestDES_CBC:
2537 case bltestDES_EDE_ECB:
2538 case bltestDES_EDE_CBC:
2539 case bltestAES_ECB:
2540 case bltestAES_CBC:
2541 case bltestCAMELLIA_ECB:
2542 case bltestCAMELLIA_CBC:
2543 case bltestRC2_ECB:
2544 case bltestRC2_CBC:
2545 case bltestRC4:
2546 if (td)
2547 fprintf(stdout, "%8s", "symmkey");
2548 else
2549 fprintf(stdout, "%8d", 8*info->params.sk.key.buf.len);
2550 break;
2551 #if NSS_SOFTOKEN_DOES_RC5
2552 case bltestRC5_ECB:
2553 case bltestRC5_CBC:
2554 if (info->params.sk.key.buf.len > 0)
2555 printf("symmetric key(bytes)=%d,", info->params.sk.key.buf.len);
2556 if (info->rounds > 0)
2557 printf("rounds=%d,", info->params.rc5.rounds);
2558 if (info->wordsize > 0)
2559 printf("wordsize(bytes)=%d,", info->params.rc5.wordsize);
2560 break;
2561 #endif
2562 case bltestRSA:
2563 if (td) {
2564 fprintf(stdout, "%8s", "rsa_mod");
2565 fprintf(stdout, "%12s", "rsa_pe");
2566 } else {
2567 fprintf(stdout, "%8d", info->params.rsa.keysizeInBits);
2568 print_exponent(&info->params.rsa.rsakey->publicExponent);
2570 break;
2571 case bltestDSA:
2572 if (td)
2573 fprintf(stdout, "%8s", "pqg_mod");
2574 else
2575 fprintf(stdout, "%8d", PQG_INDEX_TO_PBITS(info->params.dsa.j));
2576 break;
2577 #ifdef NSS_ENABLE_ECC
2578 case bltestECDSA:
2579 if (td)
2580 fprintf(stdout, "%12s", "ec_curve");
2581 else {
2582 ECCurveName curveName = info->params.ecdsa.eckey->ecParams.name;
2583 fprintf(stdout, "%12s",
2584 ecCurve_map[curveName]? ecCurve_map[curveName]->text:
2585 "Unsupported curve");
2587 break;
2588 #endif
2589 case bltestMD2:
2590 case bltestMD5:
2591 case bltestSHA1:
2592 case bltestSHA256:
2593 case bltestSHA384:
2594 case bltestSHA512:
2595 default:
2596 break;
2598 if (!td) {
2599 PRInt64 totalThroughPut;
2601 printPR_smpString("%8s", getHighUnitOps(repetitions),
2602 "%8d", repetitions);
2604 printPR_smpString("%8s", getHighUnitOps(cxreps), "%8d", cxreps);
2606 fprintf(stdout, "%12.3f", cxtime);
2607 fprintf(stdout, "%12.3f", optime);
2608 fprintf(stdout, "%12.03f", totalTimeInt / 1000);
2610 totalThroughPut = (PRInt64)(totalIn / totalTimeInt * 1000);
2611 printPR_smpString("%12s", getHighUnitBytes(totalThroughPut),
2612 "%12d", totalThroughPut);
2614 fprintf(stdout, "\n");
2615 return;
2618 fprintf(stdout, "%8s", "opreps");
2619 fprintf(stdout, "%8s", "cxreps");
2620 fprintf(stdout, "%12s", "context");
2621 fprintf(stdout, "%12s", "op");
2622 fprintf(stdout, "%12s", "time(sec)");
2623 fprintf(stdout, "%12s", "thrgput");
2624 fprintf(stdout, "\n");
2625 fprintf(stdout, "%8s", mode_strings[info->mode]);
2626 fprintf(stdout, "_%c", (cxonly) ? 'c' : (encrypt) ? 'e' : 'd');
2627 printPR_smpString("%12s", getHighUnitBytes(totalIn), "%12d", totalIn);
2629 td = !td;
2630 goto print_td;
2633 void
2634 printmodes()
2636 bltestCipherMode mode;
2637 int nummodes = sizeof(mode_strings) / sizeof(char *);
2638 fprintf(stderr, "%s: Available modes (specify with -m):\n", progName);
2639 for (mode=0; mode<nummodes; mode++)
2640 fprintf(stderr, "%s\n", mode_strings[mode]);
2643 bltestCipherMode
2644 get_mode(const char *modestring)
2646 bltestCipherMode mode;
2647 int nummodes = sizeof(mode_strings) / sizeof(char *);
2648 for (mode=0; mode<nummodes; mode++)
2649 if (PL_strcmp(modestring, mode_strings[mode]) == 0)
2650 return mode;
2651 fprintf(stderr, "%s: invalid mode: %s\n", progName, modestring);
2652 return bltestINVALID;
2655 void
2656 load_file_data(PRArenaPool *arena, bltestIO *data,
2657 char *fn, bltestIOMode ioMode)
2659 PRFileDesc *file;
2660 data->mode = ioMode;
2661 data->file = NULL; /* don't use -- not saving anything */
2662 data->pBuf.data = NULL;
2663 data->pBuf.len = 0;
2664 file = PR_Open(fn, PR_RDONLY, 00660);
2665 if (file)
2666 setupIO(arena, data, file, NULL, 0);
2669 void
2670 get_params(PRArenaPool *arena, bltestParams *params,
2671 bltestCipherMode mode, int j)
2673 char filename[256];
2674 char *modestr = mode_strings[mode];
2675 #if NSS_SOFTOKEN_DOES_RC5
2676 FILE *file;
2677 char *mark, *param, *val;
2678 int index = 0;
2679 #endif
2680 switch (mode) {
2681 case bltestDES_CBC:
2682 case bltestDES_EDE_CBC:
2683 case bltestRC2_CBC:
2684 case bltestAES_CBC:
2685 case bltestCAMELLIA_CBC:
2686 sprintf(filename, "%s/tests/%s/%s%d", testdir, modestr, "iv", j);
2687 load_file_data(arena, &params->sk.iv, filename, bltestBinary);
2688 case bltestDES_ECB:
2689 case bltestDES_EDE_ECB:
2690 case bltestRC2_ECB:
2691 case bltestRC4:
2692 case bltestAES_ECB:
2693 case bltestCAMELLIA_ECB:
2694 sprintf(filename, "%s/tests/%s/%s%d", testdir, modestr, "key", j);
2695 load_file_data(arena, &params->sk.key, filename, bltestBinary);
2696 break;
2697 #if NSS_SOFTOKEN_DOES_RC5
2698 case bltestRC5_ECB:
2699 case bltestRC5_CBC:
2700 sprintf(filename, "%s/tests/%s/%s%d", testdir, modestr, "iv", j);
2701 load_file_data(arena, &params->sk.iv, filename, bltestBinary);
2702 sprintf(filename, "%s/tests/%s/%s%d", testdir, modestr, "key", j);
2703 load_file_data(arena, &params->sk.key, filename, bltestBinary);
2704 sprintf(filename, "%s/tests/%s/%s%d", testdir, modestr,
2705 "params", j);
2706 file = fopen(filename, "r");
2707 if (!file) return;
2708 param = malloc(100);
2709 len = fread(param, 1, 100, file);
2710 while (index < len) {
2711 mark = PL_strchr(param, '=');
2712 *mark = '\0';
2713 val = mark + 1;
2714 mark = PL_strchr(val, '\n');
2715 *mark = '\0';
2716 if (PL_strcmp(param, "rounds") == 0) {
2717 params->rc5.rounds = atoi(val);
2718 } else if (PL_strcmp(param, "wordsize") == 0) {
2719 params->rc5.wordsize = atoi(val);
2721 index += PL_strlen(param) + PL_strlen(val) + 2;
2722 param = mark + 1;
2724 break;
2725 #endif
2726 case bltestRSA:
2727 sprintf(filename, "%s/tests/%s/%s%d", testdir, modestr, "key", j);
2728 load_file_data(arena, &params->rsa.key, filename, bltestBase64Encoded);
2729 params->rsa.rsakey = rsakey_from_filedata(&params->key.buf);
2730 break;
2731 case bltestDSA:
2732 sprintf(filename, "%s/tests/%s/%s%d", testdir, modestr, "key", j);
2733 load_file_data(arena, &params->dsa.key, filename, bltestBase64Encoded);
2734 params->dsa.dsakey = dsakey_from_filedata(&params->key.buf);
2735 sprintf(filename, "%s/tests/%s/%s%d", testdir, modestr, "pqg", j);
2736 load_file_data(arena, &params->dsa.pqgdata, filename,
2737 bltestBase64Encoded);
2738 params->dsa.pqg = pqg_from_filedata(&params->dsa.pqgdata.buf);
2739 sprintf(filename, "%s/tests/%s/%s%d", testdir, modestr, "keyseed", j);
2740 load_file_data(arena, &params->dsa.keyseed, filename,
2741 bltestBase64Encoded);
2742 sprintf(filename, "%s/tests/%s/%s%d", testdir, modestr, "sigseed", j);
2743 load_file_data(arena, &params->dsa.sigseed, filename,
2744 bltestBase64Encoded);
2745 sprintf(filename, "%s/tests/%s/%s%d", testdir, modestr, "ciphertext",j);
2746 load_file_data(arena, &params->dsa.sig, filename, bltestBase64Encoded);
2747 break;
2748 #ifdef NSS_ENABLE_ECC
2749 case bltestECDSA:
2750 sprintf(filename, "%s/tests/%s/%s%d", testdir, modestr, "key", j);
2751 load_file_data(arena, &params->ecdsa.key, filename, bltestBase64Encoded);
2752 params->ecdsa.eckey = eckey_from_filedata(&params->key.buf);
2753 sprintf(filename, "%s/tests/%s/%s%d", testdir, modestr, "sigseed", j);
2754 load_file_data(arena, &params->ecdsa.sigseed, filename,
2755 bltestBase64Encoded);
2756 sprintf(filename, "%s/tests/%s/%s%d", testdir, modestr, "ciphertext",j);
2757 load_file_data(arena, &params->ecdsa.sig, filename, bltestBase64Encoded);
2758 break;
2759 #endif
2760 case bltestMD2:
2761 case bltestMD5:
2762 case bltestSHA1:
2763 case bltestSHA256:
2764 case bltestSHA384:
2765 case bltestSHA512:
2766 /*params->hash.restart = PR_TRUE;*/
2767 params->hash.restart = PR_FALSE;
2768 break;
2769 default:
2770 break;
2774 SECStatus
2775 verify_self_test(bltestIO *result, bltestIO *cmp, bltestCipherMode mode,
2776 PRBool forward, SECStatus sigstatus)
2778 int res;
2779 char *modestr = mode_strings[mode];
2780 res = SECITEM_CompareItem(&result->pBuf, &cmp->buf);
2781 if (is_sigCipher(mode)) {
2782 if (forward) {
2783 if (res == 0) {
2784 printf("Signature self-test for %s passed.\n", modestr);
2785 } else {
2786 printf("Signature self-test for %s failed!\n", modestr);
2788 } else {
2789 if (sigstatus == SECSuccess) {
2790 printf("Verification self-test for %s passed.\n", modestr);
2791 } else {
2792 printf("Verification self-test for %s failed!\n", modestr);
2795 return sigstatus;
2796 } else if (is_hashCipher(mode)) {
2797 if (res == 0) {
2798 printf("Hash self-test for %s passed.\n", modestr);
2799 } else {
2800 printf("Hash self-test for %s failed!\n", modestr);
2802 } else {
2803 if (forward) {
2804 if (res == 0) {
2805 printf("Encryption self-test for %s passed.\n", modestr);
2806 } else {
2807 printf("Encryption self-test for %s failed!\n", modestr);
2809 } else {
2810 if (res == 0) {
2811 printf("Decryption self-test for %s passed.\n", modestr);
2812 } else {
2813 printf("Decryption self-test for %s failed!\n", modestr);
2817 return (res != 0);
2820 static SECStatus
2821 blapi_selftest(bltestCipherMode *modes, int numModes, int inoff, int outoff,
2822 PRBool encrypt, PRBool decrypt)
2824 bltestCipherInfo cipherInfo;
2825 bltestIO pt, ct;
2826 bltestCipherMode mode;
2827 bltestParams *params;
2828 int i, j, nummodes, numtests;
2829 char *modestr;
2830 char filename[256];
2831 PRFileDesc *file;
2832 PRArenaPool *arena;
2833 SECItem item;
2834 PRBool finished;
2835 SECStatus rv = SECSuccess, srv;
2837 PORT_Memset(&cipherInfo, 0, sizeof(cipherInfo));
2838 arena = PORT_NewArena(BLTEST_DEFAULT_CHUNKSIZE);
2839 cipherInfo.arena = arena;
2841 finished = PR_FALSE;
2842 nummodes = (numModes == 0) ? NUMMODES : numModes;
2843 for (i=0; i < nummodes && !finished; i++) {
2844 if (i == bltestRC5_ECB || i == bltestRC5_CBC) continue;
2845 if (numModes > 0)
2846 mode = modes[i];
2847 else
2848 mode = i;
2849 if (mode == bltestINVALID) {
2850 fprintf(stderr, "%s: Skipping invalid mode.\n",progName);
2851 continue;
2853 modestr = mode_strings[mode];
2854 cipherInfo.mode = mode;
2855 params = &cipherInfo.params;
2856 #ifdef TRACK_BLTEST_BUG
2857 if (mode == bltestRSA) {
2858 fprintf(stderr, "[%s] Self-Testing RSA\n", __bltDBG);
2860 #endif
2861 /* get the number of tests in the directory */
2862 sprintf(filename, "%s/tests/%s/%s", testdir, modestr, "numtests");
2863 file = PR_Open(filename, PR_RDONLY, 00660);
2864 if (!file) {
2865 fprintf(stderr, "%s: File %s does not exist.\n", progName,filename);
2866 return SECFailure;
2868 rv = SECU_FileToItem(&item, file);
2869 #ifdef TRACK_BLTEST_BUG
2870 if (mode == bltestRSA) {
2871 fprintf(stderr, "[%s] Loaded data from %s\n", __bltDBG, filename);
2873 #endif
2874 PR_Close(file);
2875 /* loop over the tests in the directory */
2876 numtests = 0;
2877 for (j=0; j<item.len; j++) {
2878 if (!isdigit(item.data[j])) {
2879 break;
2881 numtests *= 10;
2882 numtests += (int) (item.data[j] - '0');
2884 for (j=0; j<numtests; j++) {
2885 #ifdef TRACK_BLTEST_BUG
2886 if (mode == bltestRSA) {
2887 fprintf(stderr, "[%s] Executing self-test #%d\n", __bltDBG, j);
2889 #endif
2890 sprintf(filename, "%s/tests/%s/%s%d", testdir, modestr,
2891 "plaintext", j);
2892 load_file_data(arena, &pt, filename,
2893 #ifdef NSS_ENABLE_ECC
2894 ((mode == bltestDSA) || (mode == bltestECDSA))
2895 #else
2896 (mode == bltestDSA)
2897 #endif
2898 ? bltestBase64Encoded : bltestBinary);
2899 sprintf(filename, "%s/tests/%s/%s%d", testdir, modestr,
2900 "ciphertext", j);
2901 load_file_data(arena, &ct, filename, bltestBase64Encoded);
2902 #ifdef TRACK_BLTEST_BUG
2903 if (mode == bltestRSA) {
2904 fprintf(stderr, "[%s] Loaded data for self-test #%d\n", __bltDBG, j);
2906 #endif
2907 get_params(arena, params, mode, j);
2908 #ifdef TRACK_BLTEST_BUG
2909 if (mode == bltestRSA) {
2910 fprintf(stderr, "[%s] Got parameters for #%d\n", __bltDBG, j);
2912 #endif
2913 /* Forward Operation (Encrypt/Sign/Hash)
2914 ** Align the input buffer (plaintext) according to request
2915 ** then perform operation and compare to ciphertext
2917 /* XXX for now */
2918 rv = SECSuccess;
2919 if (encrypt) {
2920 bltestCopyIO(arena, &cipherInfo.input, &pt);
2921 misalignBuffer(arena, &cipherInfo.input, inoff);
2922 memset(&cipherInfo.output.buf, 0, sizeof cipherInfo.output.buf);
2923 rv |= cipherInit(&cipherInfo, PR_TRUE);
2924 misalignBuffer(arena, &cipherInfo.output, outoff);
2925 #ifdef TRACK_BLTEST_BUG
2926 if (mode == bltestRSA) {
2927 fprintf(stderr, "[%s] Inited cipher context and buffers for #%d\n", __bltDBG, j);
2929 #endif
2930 rv |= cipherDoOp(&cipherInfo);
2931 #ifdef TRACK_BLTEST_BUG
2932 if (mode == bltestRSA) {
2933 fprintf(stderr, "[%s] Performed encrypt for #%d\n", __bltDBG, j);
2935 #endif
2936 rv |= cipherFinish(&cipherInfo);
2937 #ifdef TRACK_BLTEST_BUG
2938 if (mode == bltestRSA) {
2939 fprintf(stderr, "[%s] Finished encrypt for #%d\n", __bltDBG, j);
2941 #endif
2942 rv |= verify_self_test(&cipherInfo.output,
2943 &ct, mode, PR_TRUE, 0);
2944 #ifdef TRACK_BLTEST_BUG
2945 if (mode == bltestRSA) {
2946 fprintf(stderr, "[%s] Verified self-test for #%d\n", __bltDBG, j);
2948 #endif
2949 /* If testing hash, only one op to test */
2950 if (is_hashCipher(mode))
2951 continue;
2952 /*if (rv) return rv;*/
2954 if (!decrypt)
2955 continue;
2956 /* XXX for now */
2957 rv = SECSuccess;
2958 /* Reverse Operation (Decrypt/Verify)
2959 ** Align the input buffer (ciphertext) according to request
2960 ** then perform operation and compare to plaintext
2962 #ifdef NSS_ENABLE_ECC
2963 if ((mode != bltestDSA) && (mode != bltestECDSA))
2964 #else
2965 if (mode != bltestDSA)
2966 #endif
2967 bltestCopyIO(arena, &cipherInfo.input, &ct);
2968 else
2969 bltestCopyIO(arena, &cipherInfo.input, &pt);
2970 misalignBuffer(arena, &cipherInfo.input, inoff);
2971 memset(&cipherInfo.output.buf, 0, sizeof cipherInfo.output.buf);
2972 rv |= cipherInit(&cipherInfo, PR_FALSE);
2973 misalignBuffer(arena, &cipherInfo.output, outoff);
2974 #ifdef TRACK_BLTEST_BUG
2975 if (mode == bltestRSA) {
2976 fprintf(stderr, "[%s] Inited cipher context and buffers for #%d\n", __bltDBG, j);
2978 #endif
2979 srv = SECSuccess;
2980 srv |= cipherDoOp(&cipherInfo);
2981 #ifdef TRACK_BLTEST_BUG
2982 if (mode == bltestRSA) {
2983 fprintf(stderr, "[%s] Performed decrypt for #%d\n", __bltDBG, j);
2985 #endif
2986 rv |= cipherFinish(&cipherInfo);
2987 #ifdef TRACK_BLTEST_BUG
2988 if (mode == bltestRSA) {
2989 fprintf(stderr, "[%s] Finished decrypt for #%d\n", __bltDBG, j);
2991 #endif
2992 rv |= verify_self_test(&cipherInfo.output,
2993 &pt, mode, PR_FALSE, srv);
2994 #ifdef TRACK_BLTEST_BUG
2995 if (mode == bltestRSA) {
2996 fprintf(stderr, "[%s] Verified self-test for #%d\n", __bltDBG, j);
2998 #endif
2999 /*if (rv) return rv;*/
3002 return rv;
3005 SECStatus
3006 dump_file(bltestCipherMode mode, char *filename)
3008 bltestIO keydata;
3009 PRArenaPool *arena = NULL;
3010 arena = PORT_NewArena(BLTEST_DEFAULT_CHUNKSIZE);
3011 if (mode == bltestRSA) {
3012 RSAPrivateKey *key;
3013 load_file_data(arena, &keydata, filename, bltestBase64Encoded);
3014 key = rsakey_from_filedata(&keydata.buf);
3015 dump_rsakey(key);
3016 } else if (mode == bltestDSA) {
3017 #if 0
3018 PQGParams *pqg;
3019 get_file_data(filename, &item, PR_TRUE);
3020 pqg = pqg_from_filedata(&item);
3021 dump_pqg(pqg);
3022 #endif
3023 DSAPrivateKey *key;
3024 load_file_data(arena, &keydata, filename, bltestBase64Encoded);
3025 key = dsakey_from_filedata(&keydata.buf);
3026 dump_dsakey(key);
3027 #ifdef NSS_ENABLE_ECC
3028 } else if (mode == bltestECDSA) {
3029 ECPrivateKey *key;
3030 load_file_data(arena, &keydata, filename, bltestBase64Encoded);
3031 key = eckey_from_filedata(&keydata.buf);
3032 dump_eckey(key);
3033 #endif
3035 PORT_FreeArena(arena, PR_FALSE);
3036 return SECFailure;
3039 void ThreadExecTest(void *data)
3041 bltestCipherInfo *cipherInfo = (bltestCipherInfo*)data;
3043 if (cipherInfo->mCarlo == PR_TRUE) {
3044 int mciter;
3045 for (mciter=0; mciter<10000; mciter++) {
3046 cipherDoOp(cipherInfo);
3047 memcpy(cipherInfo->input.buf.data,
3048 cipherInfo->output.buf.data,
3049 cipherInfo->input.buf.len);
3051 } else {
3052 cipherDoOp(cipherInfo);
3054 cipherFinish(cipherInfo);
3057 /* bltest commands */
3058 enum {
3059 cmd_Decrypt = 0,
3060 cmd_Encrypt,
3061 cmd_FIPS,
3062 cmd_Hash,
3063 cmd_Nonce,
3064 cmd_Dump,
3065 cmd_Sign,
3066 cmd_SelfTest,
3067 cmd_Verify
3070 /* bltest options */
3071 enum {
3072 opt_B64 = 0,
3073 opt_BufSize,
3074 opt_Restart,
3075 opt_SelfTestDir,
3076 opt_Exponent,
3077 opt_SigFile,
3078 opt_KeySize,
3079 opt_Hex,
3080 opt_Input,
3081 opt_PQGFile,
3082 opt_Key,
3083 opt_HexWSpc,
3084 opt_Mode,
3085 #ifdef NSS_ENABLE_ECC
3086 opt_CurveName,
3087 #endif
3088 opt_Output,
3089 opt_Repetitions,
3090 opt_ZeroBuf,
3091 opt_Rounds,
3092 opt_Seed,
3093 opt_SigSeedFile,
3094 opt_CXReps,
3095 opt_IV,
3096 opt_WordSize,
3097 opt_UseSeed,
3098 opt_UseSigSeed,
3099 opt_SeedFile,
3100 opt_InputOffset,
3101 opt_OutputOffset,
3102 opt_MonteCarlo,
3103 opt_ThreadNum,
3104 opt_SecondsToRun,
3105 opt_CmdLine
3108 static secuCommandFlag bltest_commands[] =
3110 { /* cmd_Decrypt */ 'D', PR_FALSE, 0, PR_FALSE },
3111 { /* cmd_Encrypt */ 'E', PR_FALSE, 0, PR_FALSE },
3112 { /* cmd_FIPS */ 'F', PR_FALSE, 0, PR_FALSE },
3113 { /* cmd_Hash */ 'H', PR_FALSE, 0, PR_FALSE },
3114 { /* cmd_Nonce */ 'N', PR_FALSE, 0, PR_FALSE },
3115 { /* cmd_Dump */ 'P', PR_FALSE, 0, PR_FALSE },
3116 { /* cmd_Sign */ 'S', PR_FALSE, 0, PR_FALSE },
3117 { /* cmd_SelfTest */ 'T', PR_FALSE, 0, PR_FALSE },
3118 { /* cmd_Verify */ 'V', PR_FALSE, 0, PR_FALSE }
3121 static secuCommandFlag bltest_options[] =
3123 { /* opt_B64 */ 'a', PR_FALSE, 0, PR_FALSE },
3124 { /* opt_BufSize */ 'b', PR_TRUE, 0, PR_FALSE },
3125 { /* opt_Restart */ 'c', PR_FALSE, 0, PR_FALSE },
3126 { /* opt_SelfTestDir */ 'd', PR_TRUE, 0, PR_FALSE },
3127 { /* opt_Exponent */ 'e', PR_TRUE, 0, PR_FALSE },
3128 { /* opt_SigFile */ 'f', PR_TRUE, 0, PR_FALSE },
3129 { /* opt_KeySize */ 'g', PR_TRUE, 0, PR_FALSE },
3130 { /* opt_Hex */ 'h', PR_FALSE, 0, PR_FALSE },
3131 { /* opt_Input */ 'i', PR_TRUE, 0, PR_FALSE },
3132 { /* opt_PQGFile */ 'j', PR_TRUE, 0, PR_FALSE },
3133 { /* opt_Key */ 'k', PR_TRUE, 0, PR_FALSE },
3134 { /* opt_HexWSpc */ 'l', PR_FALSE, 0, PR_FALSE },
3135 { /* opt_Mode */ 'm', PR_TRUE, 0, PR_FALSE },
3136 #ifdef NSS_ENABLE_ECC
3137 { /* opt_CurveName */ 'n', PR_TRUE, 0, PR_FALSE },
3138 #endif
3139 { /* opt_Output */ 'o', PR_TRUE, 0, PR_FALSE },
3140 { /* opt_Repetitions */ 'p', PR_TRUE, 0, PR_FALSE },
3141 { /* opt_ZeroBuf */ 'q', PR_FALSE, 0, PR_FALSE },
3142 { /* opt_Rounds */ 'r', PR_TRUE, 0, PR_FALSE },
3143 { /* opt_Seed */ 's', PR_TRUE, 0, PR_FALSE },
3144 { /* opt_SigSeedFile */ 't', PR_TRUE, 0, PR_FALSE },
3145 { /* opt_CXReps */ 'u', PR_TRUE, 0, PR_FALSE },
3146 { /* opt_IV */ 'v', PR_TRUE, 0, PR_FALSE },
3147 { /* opt_WordSize */ 'w', PR_TRUE, 0, PR_FALSE },
3148 { /* opt_UseSeed */ 'x', PR_FALSE, 0, PR_FALSE },
3149 { /* opt_UseSigSeed */ 'y', PR_FALSE, 0, PR_FALSE },
3150 { /* opt_SeedFile */ 'z', PR_FALSE, 0, PR_FALSE },
3151 { /* opt_InputOffset */ '1', PR_TRUE, 0, PR_FALSE },
3152 { /* opt_OutputOffset */ '2', PR_TRUE, 0, PR_FALSE },
3153 { /* opt_MonteCarlo */ '3', PR_FALSE, 0, PR_FALSE },
3154 { /* opt_ThreadNum */ '4', PR_TRUE, 0, PR_FALSE },
3155 { /* opt_SecondsToRun */ '5', PR_TRUE, 0, PR_FALSE },
3156 { /* opt_CmdLine */ '-', PR_FALSE, 0, PR_FALSE }
3159 int main(int argc, char **argv)
3161 char *infileName, *outfileName, *keyfileName, *ivfileName;
3162 SECStatus rv = SECFailure;
3164 double totalTime;
3165 PRIntervalTime time1, time2;
3166 PRFileDesc *outfile;
3167 bltestCipherInfo *cipherInfoListHead, *cipherInfo;
3168 bltestIOMode ioMode;
3169 int bufsize, exponent, curThrdNum;
3170 #ifdef NSS_ENABLE_ECC
3171 char *curveName = NULL;
3172 #endif
3173 int i, commandsEntered;
3174 int inoff, outoff;
3175 int threads = 1;
3177 secuCommand bltest;
3178 bltest.numCommands = sizeof(bltest_commands) / sizeof(secuCommandFlag);
3179 bltest.numOptions = sizeof(bltest_options) / sizeof(secuCommandFlag);
3180 bltest.commands = bltest_commands;
3181 bltest.options = bltest_options;
3183 progName = strrchr(argv[0], '/');
3184 if (!progName)
3185 progName = strrchr(argv[0], '\\');
3186 progName = progName ? progName+1 : argv[0];
3188 rv = RNG_RNGInit();
3189 if (rv != SECSuccess) {
3190 SECU_PrintPRandOSError(progName);
3191 return -1;
3193 RNG_SystemInfoForRNG();
3195 rv = SECU_ParseCommandLine(argc, argv, progName, &bltest);
3196 if (rv == SECFailure) {
3197 fprintf(stderr, "%s: command line parsing error!\n", progName);
3198 goto print_usage;
3200 rv = SECFailure;
3202 cipherInfo = PORT_ZNew(bltestCipherInfo);
3203 cipherInfoListHead = cipherInfo;
3204 /* set some defaults */
3205 infileName = outfileName = keyfileName = ivfileName = NULL;
3207 /* Check the number of commands entered on the command line. */
3208 commandsEntered = 0;
3209 for (i=0; i<bltest.numCommands; i++)
3210 if (bltest.commands[i].activated)
3211 commandsEntered++;
3213 if (commandsEntered > 1 &&
3214 !(commandsEntered == 2 && bltest.commands[cmd_SelfTest].activated)) {
3215 fprintf(stderr, "%s: one command at a time!\n", progName);
3216 goto print_usage;
3219 if (commandsEntered == 0) {
3220 fprintf(stderr, "%s: you must enter a command!\n", progName);
3221 goto print_usage;
3224 if (bltest.commands[cmd_Sign].activated)
3225 bltest.commands[cmd_Encrypt].activated = PR_TRUE;
3226 if (bltest.commands[cmd_Verify].activated)
3227 bltest.commands[cmd_Decrypt].activated = PR_TRUE;
3228 if (bltest.commands[cmd_Hash].activated)
3229 bltest.commands[cmd_Encrypt].activated = PR_TRUE;
3231 inoff = outoff = 0;
3232 if (bltest.options[opt_InputOffset].activated)
3233 inoff = PORT_Atoi(bltest.options[opt_InputOffset].arg);
3234 if (bltest.options[opt_OutputOffset].activated)
3235 outoff = PORT_Atoi(bltest.options[opt_OutputOffset].arg);
3237 testdir = (bltest.options[opt_SelfTestDir].activated) ?
3238 strdup(bltest.options[opt_SelfTestDir].arg) : ".";
3241 * Handle three simple cases first
3244 /* Do BLAPI self-test */
3245 if (bltest.commands[cmd_SelfTest].activated) {
3246 PRBool encrypt = PR_TRUE, decrypt = PR_TRUE;
3247 /* user may specified a set of ciphers to test. parse them. */
3248 bltestCipherMode modesToTest[NUMMODES];
3249 int numModesToTest = 0;
3250 char *tok, *str;
3251 str = bltest.options[opt_Mode].arg;
3252 while (str) {
3253 tok = strchr(str, ',');
3254 if (tok) *tok = '\0';
3255 modesToTest[numModesToTest++] = get_mode(str);
3256 if (tok) {
3257 *tok = ',';
3258 str = tok + 1;
3259 } else {
3260 break;
3263 if (bltest.commands[cmd_Decrypt].activated &&
3264 !bltest.commands[cmd_Encrypt].activated)
3265 encrypt = PR_FALSE;
3266 if (bltest.commands[cmd_Encrypt].activated &&
3267 !bltest.commands[cmd_Decrypt].activated)
3268 decrypt = PR_FALSE;
3269 rv = blapi_selftest(modesToTest, numModesToTest, inoff, outoff,
3270 encrypt, decrypt);
3271 PORT_Free(cipherInfo);
3272 return rv;
3275 /* Do FIPS self-test */
3276 if (bltest.commands[cmd_FIPS].activated) {
3277 CK_RV ckrv = sftk_fipsPowerUpSelfTest();
3278 fprintf(stdout, "CK_RV: %ld.\n", ckrv);
3279 PORT_Free(cipherInfo);
3280 if (ckrv == CKR_OK)
3281 return SECSuccess;
3282 return SECFailure;
3286 * Check command line arguments for Encrypt/Decrypt/Hash/Sign/Verify
3289 if ((bltest.commands[cmd_Decrypt].activated ||
3290 bltest.commands[cmd_Verify].activated) &&
3291 bltest.options[opt_BufSize].activated) {
3292 fprintf(stderr, "%s: Cannot use a nonce as input to decrypt/verify.\n",
3293 progName);
3294 goto print_usage;
3297 if (bltest.options[opt_Mode].activated) {
3298 cipherInfo->mode = get_mode(bltest.options[opt_Mode].arg);
3299 if (cipherInfo->mode == bltestINVALID) {
3300 goto print_usage;
3302 } else {
3303 fprintf(stderr, "%s: You must specify a cipher mode with -m.\n",
3304 progName);
3305 goto print_usage;
3309 if (bltest.options[opt_Repetitions].activated &&
3310 bltest.options[opt_SecondsToRun].activated) {
3311 fprintf(stderr, "%s: Operation time should be defined in either "
3312 "repetitions(-p) or seconds(-5) not both",
3313 progName);
3314 goto print_usage;
3317 if (bltest.options[opt_Repetitions].activated) {
3318 cipherInfo->repetitionsToPerfom =
3319 PORT_Atoi(bltest.options[opt_Repetitions].arg);
3320 } else {
3321 cipherInfo->repetitionsToPerfom = 0;
3324 if (bltest.options[opt_SecondsToRun].activated) {
3325 cipherInfo->seconds = PORT_Atoi(bltest.options[opt_SecondsToRun].arg);
3326 } else {
3327 cipherInfo->seconds = 0;
3331 if (bltest.options[opt_CXReps].activated) {
3332 cipherInfo->cxreps = PORT_Atoi(bltest.options[opt_CXReps].arg);
3333 } else {
3334 cipherInfo->cxreps = 0;
3337 if (bltest.options[opt_ThreadNum].activated) {
3338 threads = PORT_Atoi(bltest.options[opt_ThreadNum].arg);
3339 if (threads <= 0) {
3340 threads = 1;
3344 /* Dump a file (rsakey, dsakey, etc.) */
3345 if (bltest.commands[cmd_Dump].activated) {
3346 rv = dump_file(cipherInfo->mode, bltest.options[opt_Input].arg);
3347 PORT_Free(cipherInfo);
3348 return rv;
3351 /* default input mode is binary */
3352 ioMode = (bltest.options[opt_B64].activated) ? bltestBase64Encoded :
3353 (bltest.options[opt_Hex].activated) ? bltestHexStream :
3354 (bltest.options[opt_HexWSpc].activated) ? bltestHexSpaceDelim :
3355 bltestBinary;
3357 if (bltest.options[opt_Exponent].activated)
3358 exponent = PORT_Atoi(bltest.options[opt_Exponent].arg);
3359 else
3360 exponent = 65537;
3362 #ifdef NSS_ENABLE_ECC
3363 if (bltest.options[opt_CurveName].activated)
3364 curveName = PORT_Strdup(bltest.options[opt_CurveName].arg);
3365 else
3366 curveName = NULL;
3367 #endif
3369 if (bltest.commands[cmd_Verify].activated &&
3370 !bltest.options[opt_SigFile].activated) {
3371 fprintf(stderr, "%s: You must specify a signature file with -f.\n",
3372 progName);
3374 print_usage:
3375 PORT_Free(cipherInfo);
3376 Usage();
3379 if (bltest.options[opt_MonteCarlo].activated) {
3380 cipherInfo->mCarlo = PR_TRUE;
3381 } else {
3382 cipherInfo->mCarlo = PR_FALSE;
3385 for (curThrdNum = 0;curThrdNum < threads;curThrdNum++) {
3386 int keysize = 0;
3387 PRFileDesc *file = NULL, *infile;
3388 bltestParams *params;
3389 char *instr = NULL;
3390 PRArenaPool *arena;
3392 if (curThrdNum > 0) {
3393 bltestCipherInfo *newCInfo = PORT_ZNew(bltestCipherInfo);
3394 if (!newCInfo) {
3395 fprintf(stderr, "%s: Can not allocate memory.\n", progName);
3396 goto exit_point;
3398 newCInfo->mode = cipherInfo->mode;
3399 newCInfo->mCarlo = cipherInfo->mCarlo;
3400 newCInfo->repetitionsToPerfom =
3401 cipherInfo->repetitionsToPerfom;
3402 newCInfo->seconds = cipherInfo->seconds;
3403 newCInfo->cxreps = cipherInfo->cxreps;
3404 cipherInfo->next = newCInfo;
3405 cipherInfo = newCInfo;
3407 arena = PORT_NewArena(BLTEST_DEFAULT_CHUNKSIZE);
3408 if (!arena) {
3409 fprintf(stderr, "%s: Can not allocate memory.\n", progName);
3410 goto exit_point;
3412 cipherInfo->arena = arena;
3413 params = &cipherInfo->params;
3415 /* Set up an encryption key. */
3416 keysize = 0;
3417 file = NULL;
3418 if (is_symmkeyCipher(cipherInfo->mode)) {
3419 char *keystr = NULL; /* if key is on command line */
3420 if (bltest.options[opt_Key].activated) {
3421 if (bltest.options[opt_CmdLine].activated) {
3422 keystr = bltest.options[opt_Key].arg;
3423 } else {
3424 file = PR_Open(bltest.options[opt_Key].arg,
3425 PR_RDONLY, 00660);
3427 } else {
3428 if (bltest.options[opt_KeySize].activated)
3429 keysize = PORT_Atoi(bltest.options[opt_KeySize].arg);
3430 else
3431 keysize = 8; /* use 64-bit default (DES) */
3432 /* save the random key for reference */
3433 file = PR_Open("tmp.key", PR_WRONLY|PR_CREATE_FILE, 00660);
3435 params->key.mode = ioMode;
3436 setupIO(cipherInfo->arena, &params->key, file, keystr, keysize);
3437 if (file)
3438 PR_Close(file);
3439 } else if (is_pubkeyCipher(cipherInfo->mode)) {
3440 if (bltest.options[opt_Key].activated) {
3441 file = PR_Open(bltest.options[opt_Key].arg, PR_RDONLY, 00660);
3442 } else {
3443 if (bltest.options[opt_KeySize].activated)
3444 keysize = PORT_Atoi(bltest.options[opt_KeySize].arg);
3445 else
3446 keysize = 64; /* use 512-bit default */
3447 file = PR_Open("tmp.key", PR_WRONLY|PR_CREATE_FILE, 00660);
3449 params->key.mode = bltestBase64Encoded;
3450 #ifdef NSS_ENABLE_ECC
3451 pubkeyInitKey(cipherInfo, file, keysize, exponent, curveName);
3452 #else
3453 pubkeyInitKey(cipherInfo, file, keysize, exponent);
3454 #endif
3455 PR_Close(file);
3458 /* set up an initialization vector. */
3459 if (cipher_requires_IV(cipherInfo->mode)) {
3460 char *ivstr = NULL;
3461 bltestSymmKeyParams *skp;
3462 file = NULL;
3463 if (cipherInfo->mode == bltestRC5_CBC)
3464 skp = (bltestSymmKeyParams *)&params->rc5;
3465 else
3466 skp = &params->sk;
3467 if (bltest.options[opt_IV].activated) {
3468 if (bltest.options[opt_CmdLine].activated) {
3469 ivstr = bltest.options[opt_IV].arg;
3470 } else {
3471 file = PR_Open(bltest.options[opt_IV].arg,
3472 PR_RDONLY, 00660);
3474 } else {
3475 /* save the random iv for reference */
3476 file = PR_Open("tmp.iv", PR_WRONLY|PR_CREATE_FILE, 00660);
3478 memset(&skp->iv, 0, sizeof skp->iv);
3479 skp->iv.mode = ioMode;
3480 setupIO(cipherInfo->arena, &skp->iv, file, ivstr, keysize);
3481 if (file) {
3482 PR_Close(file);
3486 if (bltest.commands[cmd_Verify].activated) {
3487 file = PR_Open(bltest.options[opt_SigFile].arg, PR_RDONLY, 00660);
3488 if (cipherInfo->mode == bltestDSA) {
3489 memset(&cipherInfo->params.dsa.sig, 0, sizeof(bltestIO));
3490 cipherInfo->params.dsa.sig.mode = ioMode;
3491 setupIO(cipherInfo->arena, &cipherInfo->params.dsa.sig,
3492 file, NULL, 0);
3493 #ifdef NSS_ENABLE_ECC
3494 } else if (cipherInfo->mode == bltestECDSA) {
3495 memset(&cipherInfo->params.ecdsa.sig, 0, sizeof(bltestIO));
3496 cipherInfo->params.ecdsa.sig.mode = ioMode;
3497 setupIO(cipherInfo->arena, &cipherInfo->params.ecdsa.sig,
3498 file, NULL, 0);
3499 #endif
3501 if (file) {
3502 PR_Close(file);
3506 if (bltest.options[opt_PQGFile].activated) {
3507 file = PR_Open(bltest.options[opt_PQGFile].arg, PR_RDONLY, 00660);
3508 params->dsa.pqgdata.mode = bltestBase64Encoded;
3509 setupIO(cipherInfo->arena, &params->dsa.pqgdata, file, NULL, 0);
3510 if (file) {
3511 PR_Close(file);
3515 /* Set up the input buffer */
3516 if (bltest.options[opt_Input].activated) {
3517 if (bltest.options[opt_CmdLine].activated) {
3518 instr = bltest.options[opt_Input].arg;
3519 infile = NULL;
3520 } else {
3521 /* form file name from testdir and input arg. */
3522 char * filename = bltest.options[opt_Input].arg;
3523 if (bltest.options[opt_SelfTestDir].activated &&
3524 testdir && filename && filename[0] != '/') {
3525 filename = PR_smprintf("%s/tests/%s/%s", testdir,
3526 mode_strings[cipherInfo->mode],
3527 filename);
3528 if (!filename) {
3529 fprintf(stderr, "%s: Can not allocate memory.\n",
3530 progName);
3531 goto exit_point;
3533 infile = PR_Open(filename, PR_RDONLY, 00660);
3534 PR_smprintf_free(filename);
3535 } else {
3536 infile = PR_Open(filename, PR_RDONLY, 00660);
3539 } else if (bltest.options[opt_BufSize].activated) {
3540 /* save the random plaintext for reference */
3541 char *tmpFName = PR_smprintf("tmp.in.%d", curThrdNum);
3542 if (!tmpFName) {
3543 fprintf(stderr, "%s: Can not allocate memory.\n", progName);
3544 goto exit_point;
3546 infile = PR_Open(tmpFName, PR_WRONLY|PR_CREATE_FILE, 00660);
3547 PR_smprintf_free(tmpFName);
3548 } else {
3549 infile = PR_STDIN;
3551 if (!infile) {
3552 fprintf(stderr, "%s: Failed to open input file.\n", progName);
3553 goto exit_point;
3555 cipherInfo->input.mode = ioMode;
3557 /* Set up the output stream */
3558 if (bltest.options[opt_Output].activated) {
3559 /* form file name from testdir and input arg. */
3560 char * filename = bltest.options[opt_Output].arg;
3561 if (bltest.options[opt_SelfTestDir].activated &&
3562 testdir && filename && filename[0] != '/') {
3563 filename = PR_smprintf("%s/tests/%s/%s", testdir,
3564 mode_strings[cipherInfo->mode],
3565 filename);
3566 if (!filename) {
3567 fprintf(stderr, "%s: Can not allocate memory.\n", progName);
3568 goto exit_point;
3570 outfile = PR_Open(filename, PR_WRONLY|PR_CREATE_FILE, 00660);
3571 PR_smprintf_free(filename);
3572 } else {
3573 outfile = PR_Open(filename, PR_WRONLY|PR_CREATE_FILE, 00660);
3575 } else {
3576 outfile = PR_STDOUT;
3578 if (!outfile) {
3579 fprintf(stderr, "%s: Failed to open output file.\n", progName);
3580 rv = SECFailure;
3581 goto exit_point;
3583 cipherInfo->output.mode = ioMode;
3584 if (bltest.options[opt_SelfTestDir].activated && ioMode == bltestBinary)
3585 cipherInfo->output.mode = bltestBase64Encoded;
3587 if (is_hashCipher(cipherInfo->mode))
3588 cipherInfo->params.hash.restart =
3589 bltest.options[opt_Restart].activated;
3591 bufsize = 0;
3592 if (bltest.options[opt_BufSize].activated)
3593 bufsize = PORT_Atoi(bltest.options[opt_BufSize].arg);
3595 /*infile = NULL;*/
3596 setupIO(cipherInfo->arena, &cipherInfo->input, infile, instr, bufsize);
3597 if (infile && infile != PR_STDIN)
3598 PR_Close(infile);
3599 misalignBuffer(cipherInfo->arena, &cipherInfo->input, inoff);
3601 cipherInit(cipherInfo, bltest.commands[cmd_Encrypt].activated);
3602 misalignBuffer(cipherInfo->arena, &cipherInfo->output, outoff);
3605 if (!bltest.commands[cmd_Nonce].activated) {
3606 TIMESTART();
3607 cipherInfo = cipherInfoListHead;
3608 while (cipherInfo != NULL) {
3609 cipherInfo->cipherThread =
3610 PR_CreateThread(PR_USER_THREAD,
3611 ThreadExecTest,
3612 cipherInfo,
3613 PR_PRIORITY_NORMAL,
3614 PR_GLOBAL_THREAD,
3615 PR_JOINABLE_THREAD,
3617 cipherInfo = cipherInfo->next;
3620 cipherInfo = cipherInfoListHead;
3621 while (cipherInfo != NULL) {
3622 PR_JoinThread(cipherInfo->cipherThread);
3623 finishIO(&cipherInfo->output, outfile);
3624 cipherInfo = cipherInfo->next;
3626 TIMEFINISH(totalTime, 1);
3629 cipherInfo = cipherInfoListHead;
3630 if (cipherInfo->repetitions > 0 || cipherInfo->cxreps > 0 ||
3631 threads > 1)
3632 dump_performance_info(cipherInfoListHead, totalTime,
3633 bltest.commands[cmd_Encrypt].activated,
3634 (cipherInfo->repetitions == 0));
3636 rv = SECSuccess;
3638 exit_point:
3639 if (outfile && outfile != PR_STDOUT)
3640 PR_Close(outfile);
3641 cipherInfo = cipherInfoListHead;
3642 while (cipherInfo != NULL) {
3643 bltestCipherInfo *tmpInfo = cipherInfo;
3645 if (cipherInfo->arena)
3646 PORT_FreeArena(cipherInfo->arena, PR_TRUE);
3647 cipherInfo = cipherInfo->next;
3648 PORT_Free(tmpInfo);
3651 /*NSS_Shutdown();*/
3653 return SECSuccess;