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 = &params->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 = &params->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 = &params->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 = &params->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, &params->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, &params->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, &params->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, &params->sk.iv, filename, bltestBinary);
3049             sprintf(filename, "%s/tests/%s/%s%d", testdir, modestr, "key", j);
3050             load_file_data(arena, &params->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, &params->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, &params->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, &params->asymk.key, filename,
3096                            bltestBase64Encoded);
3097             params->asymk.privKey =
3098                 (void *)rsakey_from_filedata(arena, &params->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, &params->asymk.key, filename, bltestBase64Encoded);
3103             params->asymk.privKey =
3104                 (void *)dsakey_from_filedata(arena, &params->asymk.key.buf);
3105             sprintf(filename, "%s/tests/%s/%s%d", testdir, modestr, "pqg", j);
3106             load_file_data(arena, &params->asymk.cipherParams.dsa.pqgdata, filename,
3107                            bltestBase64Encoded);
3108             params->asymk.cipherParams.dsa.pqg =
3109                 pqg_from_filedata(arena, &params->asymk.cipherParams.dsa.pqgdata.buf);
3110             sprintf(filename, "%s/tests/%s/%s%d", testdir, modestr, "keyseed", j);
3111             load_file_data(arena, &params->asymk.cipherParams.dsa.keyseed, filename,
3112                            bltestBase64Encoded);
3113             sprintf(filename, "%s/tests/%s/%s%d", testdir, modestr, "sigseed", j);
3114             load_file_data(arena, &params->asymk.cipherParams.dsa.sigseed, filename,
3115                            bltestBase64Encoded);
3116             sprintf(filename, "%s/tests/%s/%s%d", testdir, modestr, "ciphertext", j);
3117             load_file_data(arena, &params->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, &params->asymk.key, filename, bltestBase64Encoded);
3122             params->asymk.privKey =
3123                 (void *)eckey_from_filedata(arena, &params->asymk.key.buf);
3124             sprintf(filename, "%s/tests/%s/%s%d", testdir, modestr, "sigseed", j);
3125             load_file_data(arena, &params->asymk.cipherParams.ecdsa.sigseed,
3126                            filename, bltestBase64Encoded);
3127             sprintf(filename, "%s/tests/%s/%s%d", testdir, modestr, "ciphertext", j);
3128             load_file_data(arena, &params->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, &params->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, &params->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, &params->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 *)&params->rc5;
4064             else
4065 #endif
4066                 skp = &params->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 = &params->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(&params->asymk.sig, 0, sizeof(bltestIO));
4114                 params->asymk.sig.mode = ioMode;
4115                 setupIO(cipherInfo->arena, &params->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, &params->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