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