|
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 #include "plgetopt.h" |
|
8 #include "nss.h" |
|
9 #include "secutil.h" |
|
10 #include "pk11table.h" |
|
11 #include "secmodt.h" |
|
12 #include "pk11pub.h" |
|
13 |
|
14 |
|
15 struct test_args { |
|
16 char *arg; |
|
17 int mask_value; |
|
18 char *description; |
|
19 }; |
|
20 |
|
21 static const struct test_args test_array[] = { |
|
22 {"all", 0x1f, "run all the tests" }, |
|
23 {"e_n_p", 0x01, "public exponent, modulus, prime1"}, |
|
24 {"d_n_q", 0x02, "private exponent, modulus, prime2"}, |
|
25 {"d_p_q", 0x04, "private exponent, prime1, prime2"}, |
|
26 {"e_d_q", 0x08, "public exponent, private exponent, prime2"}, |
|
27 {"e_d_n", 0x10, "public exponent, private exponent, moduls"} |
|
28 }; |
|
29 static const int test_array_size = |
|
30 (sizeof(test_array)/sizeof(struct test_args)); |
|
31 |
|
32 static void Usage(char *progName) |
|
33 { |
|
34 int i; |
|
35 #define PRINTUSAGE(subject, option, predicate) \ |
|
36 fprintf(stderr, "%10s %s\t%s\n", subject, option, predicate); |
|
37 fprintf(stderr, "%s [-k keysize] [-e exp] [-r rounds] [-t tests]\n " |
|
38 "Test creating RSA private keys from Partial components\n", |
|
39 progName); |
|
40 PRINTUSAGE("", "-k", "key size (in bit)"); |
|
41 PRINTUSAGE("", "-e", "rsa public exponent"); |
|
42 PRINTUSAGE("", "-r", "number times to repeat the test"); |
|
43 PRINTUSAGE("", "-t", "run the specified tests"); |
|
44 for (i=0; i < test_array_size; i++) { |
|
45 PRINTUSAGE("", test_array[i].arg, test_array[i].description); |
|
46 } |
|
47 fprintf(stderr,"\n"); |
|
48 } |
|
49 |
|
50 /* |
|
51 * Test the RSA populate command to see that it can really build |
|
52 * keys from it's components. |
|
53 */ |
|
54 |
|
55 const static CK_ATTRIBUTE rsaTemplate[] = { |
|
56 {CKA_CLASS, NULL, 0 }, |
|
57 {CKA_KEY_TYPE, NULL, 0 }, |
|
58 {CKA_TOKEN, NULL, 0 }, |
|
59 {CKA_SENSITIVE, NULL, 0 }, |
|
60 {CKA_PRIVATE, NULL, 0 }, |
|
61 {CKA_MODULUS, NULL, 0 }, |
|
62 {CKA_PUBLIC_EXPONENT, NULL, 0 }, |
|
63 {CKA_PRIVATE_EXPONENT, NULL, 0 }, |
|
64 {CKA_PRIME_1, NULL, 0 }, |
|
65 {CKA_PRIME_2, NULL, 0 }, |
|
66 {CKA_EXPONENT_1, NULL, 0 }, |
|
67 {CKA_EXPONENT_2, NULL, 0 }, |
|
68 {CKA_COEFFICIENT, NULL, 0 }, |
|
69 }; |
|
70 |
|
71 #define RSA_SIZE (sizeof(rsaTemplate)) |
|
72 #define RSA_ATTRIBUTES (sizeof(rsaTemplate)/sizeof(CK_ATTRIBUTE)) |
|
73 |
|
74 static void |
|
75 resetTemplate(CK_ATTRIBUTE *attribute, int start, int end) |
|
76 { |
|
77 int i; |
|
78 for (i=start; i < end; i++) { |
|
79 if (attribute[i].pValue) { |
|
80 PORT_Free(attribute[i].pValue); |
|
81 } |
|
82 attribute[i].pValue = NULL; |
|
83 attribute[i].ulValueLen = 0; |
|
84 } |
|
85 } |
|
86 |
|
87 static SECStatus |
|
88 copyAttribute(PK11ObjectType objType, void *object, CK_ATTRIBUTE *template, |
|
89 int offset, CK_ATTRIBUTE_TYPE attrType) |
|
90 { |
|
91 SECItem attributeItem = {0, 0, 0}; |
|
92 SECStatus rv; |
|
93 |
|
94 rv = PK11_ReadRawAttribute(objType, object, attrType, &attributeItem); |
|
95 if (rv != SECSuccess) { |
|
96 return rv; |
|
97 } |
|
98 template[offset].type = attrType; |
|
99 template[offset].pValue = attributeItem.data; |
|
100 template[offset].ulValueLen = attributeItem.len; |
|
101 return SECSuccess; |
|
102 } |
|
103 |
|
104 static SECStatus |
|
105 readKey(PK11ObjectType objType, void *object, CK_ATTRIBUTE *template, |
|
106 int start, int end) |
|
107 { |
|
108 int i; |
|
109 SECStatus rv; |
|
110 |
|
111 for (i=start; i < end; i++) { |
|
112 rv = copyAttribute(objType, object, template, i, template[i].type); |
|
113 if (rv != SECSuccess) { |
|
114 goto fail; |
|
115 } |
|
116 } |
|
117 return SECSuccess; |
|
118 |
|
119 fail: |
|
120 resetTemplate(template, start, i); |
|
121 return rv; |
|
122 } |
|
123 |
|
124 #define ATTR_STRING(x) getNameFromAttribute(x) |
|
125 |
|
126 void |
|
127 dumpTemplate(CK_ATTRIBUTE *template, int start, int end) |
|
128 { |
|
129 int i,j; |
|
130 for (i=0; i < end; i++) { |
|
131 unsigned char cval; |
|
132 CK_ULONG ulval; |
|
133 unsigned char *cpval; |
|
134 |
|
135 fprintf(stderr, "%s:", ATTR_STRING(template[i].type)); |
|
136 switch (template[i].ulValueLen) { |
|
137 case 1: |
|
138 cval =*(unsigned char *)template[i].pValue; |
|
139 switch(cval) { |
|
140 case 0: fprintf(stderr, " false"); break; |
|
141 case 1: fprintf(stderr, " true"); break; |
|
142 default: |
|
143 fprintf(stderr, " %d (=0x%02x,'%c')",cval,cval,cval); |
|
144 break; |
|
145 } |
|
146 break; |
|
147 case sizeof(CK_ULONG): |
|
148 ulval = *(CK_ULONG *)template[i].pValue; |
|
149 fprintf(stderr," %ld (=0x%04lx)", ulval, ulval); |
|
150 break; |
|
151 default: |
|
152 cpval = (unsigned char *)template[i].pValue; |
|
153 for (j=0; j < template[i].ulValueLen; j++) { |
|
154 if ((j % 16) == 0) fprintf(stderr, "\n "); |
|
155 fprintf(stderr," %02x",cpval[j]); |
|
156 } |
|
157 break; |
|
158 } |
|
159 fprintf(stderr,"\n"); |
|
160 } |
|
161 } |
|
162 |
|
163 PRBool |
|
164 rsaKeysAreEqual(PK11ObjectType srcType, void *src, |
|
165 PK11ObjectType destType, void *dest) |
|
166 { |
|
167 |
|
168 CK_ATTRIBUTE srcTemplate[RSA_ATTRIBUTES]; |
|
169 CK_ATTRIBUTE destTemplate[RSA_ATTRIBUTES]; |
|
170 PRBool areEqual = PR_TRUE; |
|
171 SECStatus rv; |
|
172 int i; |
|
173 |
|
174 memcpy(srcTemplate, rsaTemplate, RSA_SIZE); |
|
175 memcpy(destTemplate, rsaTemplate, RSA_SIZE); |
|
176 |
|
177 rv = readKey(srcType, src, srcTemplate, 0, RSA_ATTRIBUTES); |
|
178 if (rv != SECSuccess) { |
|
179 printf("Could read source key\n"); |
|
180 return PR_FALSE; |
|
181 } |
|
182 readKey(destType, dest, destTemplate, 0, RSA_ATTRIBUTES); |
|
183 if (rv != SECSuccess) { |
|
184 printf("Could read dest key\n"); |
|
185 return PR_FALSE; |
|
186 } |
|
187 |
|
188 for (i=0; i < RSA_ATTRIBUTES; i++) { |
|
189 if (srcTemplate[i].ulValueLen != destTemplate[i].ulValueLen) { |
|
190 printf("key->%s not equal src_len = %ld, dest_len=%ld\n", |
|
191 ATTR_STRING(srcTemplate[i].type), |
|
192 srcTemplate[i].ulValueLen, destTemplate[i].ulValueLen); |
|
193 areEqual = 0; |
|
194 } else if (memcmp(srcTemplate[i].pValue, destTemplate[i].pValue, |
|
195 destTemplate[i].ulValueLen) != 0) { |
|
196 printf("key->%s not equal.\n", ATTR_STRING(srcTemplate[i].type)); |
|
197 areEqual = 0; |
|
198 } |
|
199 } |
|
200 if (!areEqual) { |
|
201 fprintf(stderr, "original key:\n"); |
|
202 dumpTemplate(srcTemplate,0, RSA_ATTRIBUTES); |
|
203 fprintf(stderr, "created key:\n"); |
|
204 dumpTemplate(destTemplate,0, RSA_ATTRIBUTES); |
|
205 } |
|
206 return areEqual; |
|
207 } |
|
208 |
|
209 static int exp_exp_prime_fail_count = 0; |
|
210 |
|
211 static int |
|
212 doRSAPopulateTest(unsigned int keySize, unsigned long exponent, |
|
213 int mask, void *pwarg) |
|
214 { |
|
215 SECKEYPrivateKey *rsaPrivKey; |
|
216 SECKEYPublicKey *rsaPubKey; |
|
217 PK11GenericObject *tstPrivKey; |
|
218 CK_ATTRIBUTE tstTemplate[RSA_ATTRIBUTES]; |
|
219 int tstHeaderCount; |
|
220 PK11SlotInfo *slot = NULL; |
|
221 PK11RSAGenParams rsaParams; |
|
222 CK_OBJECT_CLASS obj_class = CKO_PRIVATE_KEY; |
|
223 CK_KEY_TYPE key_type = CKK_RSA; |
|
224 CK_BBOOL ck_false = CK_FALSE; |
|
225 int failed = 0; |
|
226 |
|
227 rsaParams.pe = exponent; |
|
228 rsaParams.keySizeInBits = keySize; |
|
229 |
|
230 slot = PK11_GetInternalSlot(); |
|
231 if (slot == NULL) { |
|
232 fprintf(stderr, "Couldn't get the internal slot for the test \n"); |
|
233 return -1; |
|
234 } |
|
235 |
|
236 rsaPrivKey = PK11_GenerateKeyPair(slot, CKM_RSA_PKCS_KEY_PAIR_GEN, |
|
237 &rsaParams, &rsaPubKey, PR_FALSE, |
|
238 PR_FALSE, pwarg); |
|
239 if (rsaPrivKey == NULL) { |
|
240 fprintf(stderr, "RSA Key Gen failed"); |
|
241 PK11_FreeSlot(slot); |
|
242 return -1; |
|
243 } |
|
244 |
|
245 memcpy(tstTemplate, rsaTemplate, RSA_SIZE); |
|
246 |
|
247 tstTemplate[0].pValue = &obj_class; |
|
248 tstTemplate[0].ulValueLen = sizeof(obj_class); |
|
249 tstTemplate[1].pValue = &key_type; |
|
250 tstTemplate[1].ulValueLen = sizeof(key_type); |
|
251 tstTemplate[2].pValue = &ck_false; |
|
252 tstTemplate[2].ulValueLen = sizeof(ck_false); |
|
253 tstTemplate[3].pValue = &ck_false; |
|
254 tstTemplate[3].ulValueLen = sizeof(ck_false); |
|
255 tstTemplate[4].pValue = &ck_false; |
|
256 tstTemplate[4].ulValueLen = sizeof(ck_false); |
|
257 tstHeaderCount = 5; |
|
258 |
|
259 if (mask & 1) { |
|
260 printf("%s\n",test_array[1].description); |
|
261 resetTemplate(tstTemplate, tstHeaderCount, RSA_ATTRIBUTES); |
|
262 copyAttribute(PK11_TypePrivKey, rsaPrivKey, tstTemplate, |
|
263 tstHeaderCount, CKA_PUBLIC_EXPONENT); |
|
264 copyAttribute(PK11_TypePrivKey, rsaPrivKey, tstTemplate, |
|
265 tstHeaderCount+1, CKA_MODULUS); |
|
266 copyAttribute(PK11_TypePrivKey, rsaPrivKey, tstTemplate, |
|
267 tstHeaderCount+2, CKA_PRIME_1); |
|
268 |
|
269 tstPrivKey = PK11_CreateGenericObject(slot, tstTemplate, |
|
270 tstHeaderCount+3, PR_FALSE); |
|
271 if (tstPrivKey == NULL) { |
|
272 fprintf(stderr, "RSA Populate failed: pubExp mod p\n"); |
|
273 failed = 1; |
|
274 } else if (!rsaKeysAreEqual(PK11_TypePrivKey, rsaPrivKey, |
|
275 PK11_TypeGeneric, tstPrivKey)) { |
|
276 fprintf(stderr, "RSA Populate key mismatch: pubExp mod p\n"); |
|
277 failed = 1; |
|
278 } |
|
279 if (tstPrivKey) PK11_DestroyGenericObject(tstPrivKey); |
|
280 } |
|
281 if (mask & 2) { |
|
282 printf("%s\n",test_array[2].description); |
|
283 /* test the basic2 case, public exponent, modulus, prime2 */ |
|
284 resetTemplate(tstTemplate, tstHeaderCount, RSA_ATTRIBUTES); |
|
285 copyAttribute(PK11_TypePrivKey, rsaPrivKey, tstTemplate, |
|
286 tstHeaderCount, CKA_PUBLIC_EXPONENT); |
|
287 copyAttribute(PK11_TypePrivKey, rsaPrivKey, tstTemplate, |
|
288 tstHeaderCount+1, CKA_MODULUS); |
|
289 copyAttribute(PK11_TypePrivKey, rsaPrivKey, tstTemplate, |
|
290 tstHeaderCount+2, CKA_PRIME_2); |
|
291 /* test with q in the prime1 position */ |
|
292 tstTemplate[tstHeaderCount+2].type = CKA_PRIME_1; |
|
293 |
|
294 tstPrivKey = PK11_CreateGenericObject(slot, tstTemplate, |
|
295 tstHeaderCount+3, PR_FALSE); |
|
296 if (tstPrivKey == NULL) { |
|
297 fprintf(stderr, "RSA Populate failed: pubExp mod q\n"); |
|
298 failed = 1; |
|
299 } else if (!rsaKeysAreEqual(PK11_TypePrivKey, rsaPrivKey, |
|
300 PK11_TypeGeneric, tstPrivKey)) { |
|
301 fprintf(stderr, "RSA Populate key mismatch: pubExp mod q\n"); |
|
302 failed = 1; |
|
303 } |
|
304 if (tstPrivKey) PK11_DestroyGenericObject(tstPrivKey); |
|
305 } |
|
306 if (mask & 4) { |
|
307 printf("%s\n",test_array[3].description); |
|
308 /* test the medium case, private exponent, prime1, prime2 */ |
|
309 resetTemplate(tstTemplate, tstHeaderCount, RSA_ATTRIBUTES); |
|
310 |
|
311 copyAttribute(PK11_TypePrivKey, rsaPrivKey, tstTemplate, |
|
312 tstHeaderCount, CKA_PRIVATE_EXPONENT); |
|
313 copyAttribute(PK11_TypePrivKey, rsaPrivKey, tstTemplate, |
|
314 tstHeaderCount+1, CKA_PRIME_1); |
|
315 copyAttribute(PK11_TypePrivKey, rsaPrivKey, tstTemplate, |
|
316 tstHeaderCount+2, CKA_PRIME_2); |
|
317 /* test with p & q swapped. Underlying code should swap these back */ |
|
318 tstTemplate[tstHeaderCount+2].type = CKA_PRIME_1; |
|
319 tstTemplate[tstHeaderCount+1].type = CKA_PRIME_2; |
|
320 |
|
321 tstPrivKey = PK11_CreateGenericObject(slot, tstTemplate, |
|
322 tstHeaderCount+3, PR_FALSE); |
|
323 if (tstPrivKey == NULL) { |
|
324 fprintf(stderr, "RSA Populate failed: privExp p q\n"); |
|
325 failed = 1; |
|
326 } else if (!rsaKeysAreEqual(PK11_TypePrivKey, rsaPrivKey, |
|
327 PK11_TypeGeneric, tstPrivKey)) { |
|
328 fprintf(stderr, "RSA Populate key mismatch: privExp p q\n"); |
|
329 failed = 1; |
|
330 } |
|
331 if (tstPrivKey) PK11_DestroyGenericObject(tstPrivKey); |
|
332 } |
|
333 if (mask & 8) { |
|
334 printf("%s\n",test_array[4].description); |
|
335 /* test the advanced case, public exponent, private exponent, prime2 */ |
|
336 resetTemplate(tstTemplate, tstHeaderCount, RSA_ATTRIBUTES); |
|
337 copyAttribute(PK11_TypePrivKey, rsaPrivKey, tstTemplate, |
|
338 tstHeaderCount, CKA_PRIVATE_EXPONENT); |
|
339 copyAttribute(PK11_TypePrivKey, rsaPrivKey, tstTemplate, |
|
340 tstHeaderCount+1, CKA_PUBLIC_EXPONENT); |
|
341 copyAttribute(PK11_TypePrivKey, rsaPrivKey, tstTemplate, |
|
342 tstHeaderCount+2, CKA_PRIME_2); |
|
343 |
|
344 tstPrivKey = PK11_CreateGenericObject(slot, tstTemplate, |
|
345 tstHeaderCount+3, PR_FALSE); |
|
346 if (tstPrivKey == NULL) { |
|
347 fprintf(stderr, "RSA Populate failed: pubExp privExp q\n"); |
|
348 fprintf(stderr, " this is expected periodically. It means we\n"); |
|
349 fprintf(stderr, " had more than one key that meets the " |
|
350 "specification\n"); |
|
351 exp_exp_prime_fail_count++; |
|
352 } else if (!rsaKeysAreEqual(PK11_TypePrivKey, rsaPrivKey, |
|
353 PK11_TypeGeneric, tstPrivKey)) { |
|
354 fprintf(stderr, "RSA Populate key mismatch: pubExp privExp q\n"); |
|
355 failed = 1; |
|
356 } |
|
357 if (tstPrivKey) PK11_DestroyGenericObject(tstPrivKey); |
|
358 } |
|
359 if (mask & 16) { |
|
360 printf("%s\n",test_array[5].description); |
|
361 /* test the advanced case2, public exponent, private exponent, modulus |
|
362 */ |
|
363 resetTemplate(tstTemplate, tstHeaderCount, RSA_ATTRIBUTES); |
|
364 |
|
365 copyAttribute(PK11_TypePrivKey, rsaPrivKey, tstTemplate, |
|
366 tstHeaderCount, CKA_PRIVATE_EXPONENT); |
|
367 copyAttribute(PK11_TypePrivKey, rsaPrivKey, tstTemplate, |
|
368 tstHeaderCount+1, CKA_PUBLIC_EXPONENT); |
|
369 copyAttribute(PK11_TypePrivKey, rsaPrivKey, tstTemplate, |
|
370 tstHeaderCount+2, CKA_MODULUS); |
|
371 |
|
372 tstPrivKey = PK11_CreateGenericObject(slot, tstTemplate, |
|
373 tstHeaderCount+3, PR_FALSE); |
|
374 if (tstPrivKey == NULL) { |
|
375 fprintf(stderr, "RSA Populate failed: pubExp privExp mod\n"); |
|
376 failed = 1; |
|
377 } else if (!rsaKeysAreEqual(PK11_TypePrivKey, rsaPrivKey, |
|
378 PK11_TypeGeneric, tstPrivKey)) { |
|
379 fprintf(stderr, "RSA Populate key mismatch: pubExp privExp mod\n"); |
|
380 failed = 1; |
|
381 } |
|
382 if (tstPrivKey) PK11_DestroyGenericObject(tstPrivKey); |
|
383 } |
|
384 |
|
385 |
|
386 PK11_FreeSlot(slot); |
|
387 return failed ? -1 : 0; |
|
388 } |
|
389 |
|
390 /* populate options */ |
|
391 enum { |
|
392 opt_Exponent = 0, |
|
393 opt_KeySize, |
|
394 opt_Repeat, |
|
395 opt_Tests |
|
396 }; |
|
397 |
|
398 static secuCommandFlag populate_options[] = |
|
399 { |
|
400 { /* opt_Exponent */ 'e', PR_TRUE, 0, PR_FALSE }, |
|
401 { /* opt_KeySize */ 'k', PR_TRUE, 0, PR_FALSE }, |
|
402 { /* opt_Repeat */ 'r', PR_TRUE, 0, PR_FALSE }, |
|
403 { /* opt_Tests */ 't', PR_TRUE, 0, PR_FALSE }, |
|
404 }; |
|
405 |
|
406 int |
|
407 is_delimiter(char c) |
|
408 { |
|
409 if ((c=='+') || (c==',') || (c=='|')) { |
|
410 return 1; |
|
411 } |
|
412 return 0; |
|
413 } |
|
414 |
|
415 int |
|
416 parse_tests(char *test_string) |
|
417 { |
|
418 int mask = 0; |
|
419 int i; |
|
420 |
|
421 while (*test_string) { |
|
422 if (is_delimiter(*test_string)) { |
|
423 test_string++; |
|
424 } |
|
425 for (i=0; i < test_array_size; i++) { |
|
426 char *arg = test_array[i].arg; |
|
427 int len = strlen(arg); |
|
428 if (strncmp(test_string,arg,len) == 0) { |
|
429 test_string += len; |
|
430 mask |= test_array[i].mask_value; |
|
431 break; |
|
432 } |
|
433 } |
|
434 if (i == test_array_size) { |
|
435 break; |
|
436 } |
|
437 } |
|
438 return mask; |
|
439 } |
|
440 |
|
441 int main(int argc, char **argv) |
|
442 { |
|
443 unsigned int keySize = 1024; |
|
444 unsigned long exponent = 65537; |
|
445 int i, repeat = 1, ret = 0; |
|
446 SECStatus rv = SECFailure; |
|
447 secuCommand populateArgs; |
|
448 char *progName; |
|
449 int mask = 0xff; |
|
450 |
|
451 populateArgs.numCommands = 0; |
|
452 populateArgs.numOptions = sizeof(populate_options) / |
|
453 sizeof(secuCommandFlag); |
|
454 populateArgs.commands = NULL; |
|
455 populateArgs.options = populate_options; |
|
456 |
|
457 progName = strrchr(argv[0], '/'); |
|
458 if (!progName) |
|
459 progName = strrchr(argv[0], '\\'); |
|
460 progName = progName ? progName+1 : argv[0]; |
|
461 |
|
462 rv = NSS_NoDB_Init(NULL); |
|
463 if (rv != SECSuccess) { |
|
464 SECU_PrintPRandOSError(progName); |
|
465 return -1; |
|
466 } |
|
467 |
|
468 rv = SECU_ParseCommandLine(argc, argv, progName, &populateArgs); |
|
469 if (rv == SECFailure) { |
|
470 fprintf(stderr, "%s: command line parsing error!\n", progName); |
|
471 Usage(progName); |
|
472 return -1; |
|
473 } |
|
474 rv = SECFailure; |
|
475 |
|
476 |
|
477 if (populateArgs.options[opt_KeySize].activated) { |
|
478 keySize = PORT_Atoi(populateArgs.options[opt_KeySize].arg); |
|
479 } |
|
480 if (populateArgs.options[opt_Repeat].activated) { |
|
481 repeat = PORT_Atoi(populateArgs.options[opt_Repeat].arg); |
|
482 } |
|
483 if (populateArgs.options[opt_Exponent].activated) { |
|
484 exponent = PORT_Atoi(populateArgs.options[opt_Exponent].arg); |
|
485 } |
|
486 if (populateArgs.options[opt_Tests].activated) { |
|
487 char * test_string = populateArgs.options[opt_Tests].arg; |
|
488 mask = PORT_Atoi(test_string); |
|
489 if (mask == 0) { |
|
490 mask = parse_tests(test_string); |
|
491 } |
|
492 if (mask == 0) { |
|
493 Usage(progName); |
|
494 return -1; |
|
495 } |
|
496 } |
|
497 |
|
498 exp_exp_prime_fail_count = 0; |
|
499 for (i=0; i < repeat; i++) { |
|
500 printf("Running RSA Populate test run %d\n",i); |
|
501 ret = doRSAPopulateTest(keySize, exponent, mask, NULL); |
|
502 if (ret != 0) { |
|
503 i++; |
|
504 break; |
|
505 } |
|
506 } |
|
507 if (ret != 0) { |
|
508 fprintf(stderr,"RSA Populate test round %d: FAILED\n",i); |
|
509 } |
|
510 if (repeat > 1) { |
|
511 printf(" pub priv prime test: %d failures out of %d runs (%f %%)\n", |
|
512 exp_exp_prime_fail_count, i, |
|
513 (((double)exp_exp_prime_fail_count) * 100.0)/(double) i); |
|
514 } |
|
515 return ret; |
|
516 } |