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