blapitest.c
上传用户:lyxiangda
上传日期:2007-01-12
资源大小:3042k
文件大小:53k
源码类别:

CA认证

开发平台:

WINDOWS

  1. /*
  2.  * The contents of this file are subject to the Mozilla Public
  3.  * License Version 1.1 (the "License"); you may not use this file
  4.  * except in compliance with the License. You may obtain a copy of
  5.  * the License at http://www.mozilla.org/MPL/
  6.  * 
  7.  * Software distributed under the License is distributed on an "AS
  8.  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
  9.  * implied. See the License for the specific language governing
  10.  * rights and limitations under the License.
  11.  * 
  12.  * The Original Code is the Netscape security libraries.
  13.  * 
  14.  * The Initial Developer of the Original Code is Netscape
  15.  * Communications Corporation.  Portions created by Netscape are 
  16.  * Copyright (C) 1994-2000 Netscape Communications Corporation.  All
  17.  * Rights Reserved.
  18.  * 
  19.  * Contributor(s):
  20.  * 
  21.  * Alternatively, the contents of this file may be used under the
  22.  * terms of the GNU General Public License Version 2 or later (the
  23.  * "GPL"), in which case the provisions of the GPL are applicable 
  24.  * instead of those above.  If you wish to allow use of your 
  25.  * version of this file only under the terms of the GPL and not to
  26.  * allow others to use your version of this file under the MPL,
  27.  * indicate your decision by deleting the provisions above and
  28.  * replace them with the notice and other provisions required by
  29.  * the GPL.  If you do not delete the provisions above, a recipient
  30.  * may use your version of this file under either the MPL or the
  31.  * GPL.
  32.  */
  33. #include <stdio.h>
  34. #include <stdlib.h>
  35. #include "blapi.h"
  36. #include "prmem.h"
  37. #include "prprf.h"
  38. #include "prtime.h"
  39. #include "prsystem.h"
  40. #include "plstr.h"
  41. #include "nssb64.h"
  42. #include "secutil.h"
  43. #include "plgetopt.h"
  44. #include "softoken.h"
  45. char *progName;
  46. char *testdir = ".";
  47. #define CHECKERROR(rv, ln) 
  48. if (rv) { 
  49. char *errtxt = NULL; 
  50. if (PR_GetError() != 0) { 
  51. errtxt = PORT_Alloc(PR_GetErrorTextLength()); 
  52. PR_GetErrorText(errtxt); 
  53. PR_fprintf(PR_STDERR, "%s: ERR (%s) at line %d.n", progName, 
  54.                        (errtxt) ? "" : errtxt, ln); 
  55. exit(-1); 
  56. }
  57. static void Usage()
  58. {
  59. #define PRINTUSAGE(subject, option, predicate) 
  60. fprintf(stderr, "%10s %st%sn", subject, option, predicate);
  61. fprintf(stderr, "n");
  62. PRINTUSAGE(progName, "[-DEHSV] -m", "List available cipher modes.");
  63. fprintf(stderr, "n");
  64. PRINTUSAGE(progName, "-E -m mode ", "Encrypt a buffer.");
  65. PRINTUSAGE("",      "", "[-i plaintext] [-o ciphertext] [-k key] [-v iv]");
  66. PRINTUSAGE("",      "", "[-b bufsize] [-g keysize] [-erw]");
  67. PRINTUSAGE("",      "", "[-p repetitions]");
  68. PRINTUSAGE("",      "-m", "cipher mode to use.");
  69. PRINTUSAGE("",      "-i", "file which contains input buffer.");
  70. PRINTUSAGE("",      "-o", "file for output buffer.");
  71. PRINTUSAGE("",      "-k", "file which contains key.");
  72. PRINTUSAGE("",      "-v", "file which contains initialization vector.");
  73. PRINTUSAGE("",      "-b", "size of input buffer.");
  74. PRINTUSAGE("",      "-g", "key size (in bytes).");
  75. PRINTUSAGE("",      "-p", "do performance test.");
  76. PRINTUSAGE("(rsa)", "-e", "rsa public exponent.");
  77. #if NSS_SOFTOKEN_DOES_RC5
  78. PRINTUSAGE("(rc5)", "-r", "number of rounds.");
  79. PRINTUSAGE("(rc5)", "-w", "wordsize (32 or 64).");
  80. #endif
  81. fprintf(stderr, "n");
  82. PRINTUSAGE(progName, "-D -m mode", "Decrypt a buffer.");
  83. PRINTUSAGE("",      "", "[-i plaintext] [-o ciphertext] [-k key] [-v iv]");
  84. PRINTUSAGE("",      "", "[-p repetitions]");
  85. PRINTUSAGE("",      "-m", "cipher mode to use.");
  86. PRINTUSAGE("",      "-i", "file which contains input buffer.");
  87. PRINTUSAGE("",      "-o", "file for output buffer.");
  88. PRINTUSAGE("",      "-k", "file which contains key.");
  89. PRINTUSAGE("",      "-v", "file which contains initialization vector.");
  90. PRINTUSAGE("",      "-p", "do performance test.");
  91. fprintf(stderr, "n");
  92. PRINTUSAGE(progName, "-H -m mode", "Hash a buffer.");
  93. PRINTUSAGE("",      "", "[-i plaintext] [-o hash]");
  94. PRINTUSAGE("",      "", "[-b bufsize]");
  95. PRINTUSAGE("",      "", "[-p repetitions]");
  96. PRINTUSAGE("",      "-m", "cipher mode to use.");
  97. PRINTUSAGE("",      "-i", "file which contains input buffer.");
  98. PRINTUSAGE("",      "-o", "file for hash.");
  99. PRINTUSAGE("",      "-b", "size of input buffer.");
  100. PRINTUSAGE("",      "-p", "do performance test.");
  101. fprintf(stderr, "n");
  102. PRINTUSAGE(progName, "-S -m mode", "Sign a buffer.");
  103. PRINTUSAGE("",      "", "[-i plaintext] [-o signature] [-k key]");
  104. PRINTUSAGE("",      "", "[-b bufsize]");
  105. PRINTUSAGE("",      "", "[-p repetitions]");
  106. PRINTUSAGE("",      "-m", "cipher mode to use.");
  107. PRINTUSAGE("",      "-i", "file which contains input buffer.");
  108. PRINTUSAGE("",      "-o", "file for signature.");
  109. PRINTUSAGE("",      "-k", "file which contains key.");
  110. PRINTUSAGE("",      "-p", "do performance test.");
  111. fprintf(stderr, "n");
  112. PRINTUSAGE(progName, "-V -m mode", "Verify a signed buffer.");
  113. PRINTUSAGE("",      "", "[-i plaintext] [-s signature] [-k key]");
  114. PRINTUSAGE("",      "", "[-p repetitions]");
  115. PRINTUSAGE("",      "-m", "cipher mode to use.");
  116. PRINTUSAGE("",      "-i", "file which contains input buffer.");
  117. PRINTUSAGE("",      "-s", "file which contains signature of input buffer.");
  118. PRINTUSAGE("",      "-k", "file which contains key.");
  119. PRINTUSAGE("",      "-p", "do performance test.");
  120. fprintf(stderr, "n");
  121. PRINTUSAGE(progName, "-F", "Run the FIPS self-test.");
  122. fprintf(stderr, "n");
  123. PRINTUSAGE(progName, "-T [mode1 mode2 ...]", "Run the BLAPI self-test.");
  124. fprintf(stderr, "n");
  125. exit(1);
  126. }
  127. /*  Helper functions for ascii<-->binary conversion/reading/writing */
  128. static PRInt32
  129. get_binary(void *arg, const unsigned char *ibuf, PRInt32 size)
  130. {
  131. SECItem *binary = arg;
  132. SECItem *tmp;
  133. int index;
  134. if (binary->data == NULL) {
  135. tmp = SECITEM_AllocItem(NULL, NULL, size);
  136. binary->data = tmp->data;
  137. binary->len = tmp->len;
  138. index = 0;
  139. } else {
  140. SECITEM_ReallocItem(NULL, binary, binary->len, binary->len + size);
  141. index = binary->len;
  142. }
  143. PORT_Memcpy(&binary->data[index], ibuf, size);
  144. return binary->len;
  145. }
  146. static PRInt32
  147. get_ascii(void *arg, const char *ibuf, PRInt32 size)
  148. {
  149. SECItem *ascii = arg;
  150. SECItem *tmp;
  151. int index;
  152. if (ascii->data == NULL) {
  153. tmp = SECITEM_AllocItem(NULL, NULL, size);
  154. ascii->data = tmp->data;
  155. ascii->len = tmp->len;
  156. index = 0;
  157. } else {
  158. SECITEM_ReallocItem(NULL, ascii, ascii->len, ascii->len + size);
  159. index = ascii->len;
  160. }
  161. PORT_Memcpy(&ascii->data[index], ibuf, size);
  162. return ascii->len;
  163. }
  164. static SECStatus
  165. atob(SECItem *ascii, SECItem *binary)
  166. {
  167. SECStatus status;
  168. NSSBase64Decoder *cx;
  169. int len;
  170. binary->data = NULL; 
  171. binary->len = 0;
  172. len = (strcmp(&ascii->data[ascii->len-2],"rn"))?ascii->len:ascii->len-2;
  173. cx = NSSBase64Decoder_Create(get_binary, binary);
  174. status = NSSBase64Decoder_Update(cx, (const char *)ascii->data, len);
  175. status = NSSBase64Decoder_Destroy(cx, PR_FALSE);
  176. return status;
  177. }
  178. static PRInt32
  179. output_ascii(void *arg, const char *obuf, PRInt32 size)
  180. {
  181. PRFileDesc *outfile = arg;
  182. PRInt32 nb = PR_Write(outfile, obuf, size);
  183. if (nb != size) {
  184. PORT_SetError(SEC_ERROR_IO);
  185. return -1;
  186. }
  187. return nb;
  188. }
  189. static SECStatus
  190. btoa(SECItem *binary, SECItem *ascii)
  191. {
  192. SECStatus status;
  193. NSSBase64Encoder *cx;
  194. ascii->data = NULL;
  195. ascii->len = 0;
  196. cx = NSSBase64Encoder_Create(get_ascii, ascii);
  197. status = NSSBase64Encoder_Update(cx, binary->data, binary->len);
  198. status = NSSBase64Encoder_Destroy(cx, PR_FALSE);
  199. return status;
  200. }
  201. static SECStatus
  202. btoa_file(SECItem *binary, PRFileDesc *outfile)
  203. {
  204. SECStatus status;
  205. NSSBase64Encoder *cx;
  206. SECItem ascii;
  207. ascii.data = NULL; 
  208. ascii.len = 0;
  209. if (binary->len == 0) 
  210. return SECSuccess;
  211. cx = NSSBase64Encoder_Create(output_ascii, outfile);
  212. status = NSSBase64Encoder_Update(cx, binary->data, binary->len);
  213. status = NSSBase64Encoder_Destroy(cx, PR_FALSE);
  214. status = PR_Write(outfile, "rn", 2);
  215. return status;
  216. }
  217. static SECStatus
  218. get_and_write_random_bytes(SECItem *item, PRInt32 numbytes, char *filename)
  219. {
  220. SECStatus rv;
  221. PRFileDesc *file;
  222. item->len = numbytes;
  223. item->data = (unsigned char *)PORT_ZAlloc(numbytes);
  224. RNG_GenerateGlobalRandomBytes(item->data + 1, numbytes - 1);
  225. file = PR_Open(filename, PR_WRONLY|PR_CREATE_FILE, 00660);
  226. rv = btoa_file(item, file);
  227. CHECKERROR((rv < 0), __LINE__);
  228. return (rv < 0);
  229. }
  230. static RSAPrivateKey *
  231. rsakey_from_filedata(SECItem *filedata)
  232. {
  233. PRArenaPool *arena;
  234. RSAPrivateKey *key;
  235. unsigned char *buf = filedata->data;
  236. int fpos = 0;
  237. int i;
  238. SECItem *item;
  239. /*  Allocate space for key structure. */
  240. arena = PORT_NewArena(2048);
  241. key = (RSAPrivateKey *)PORT_ArenaZAlloc(arena, sizeof(RSAPrivateKey));
  242. key->arena = arena;
  243. item = &key->version;
  244. for (i=0; i<9; i++) {
  245. item->len  = (buf[fpos++] & 0xff) << 24;
  246. item->len |= (buf[fpos++] & 0xff) << 16;
  247. item->len |= (buf[fpos++] & 0xff) <<  8;
  248. item->len |= (buf[fpos++] & 0xff);
  249. if (item->len > 0) {
  250. item->data = PORT_ArenaAlloc(arena, item->len);
  251. PORT_Memcpy(item->data, &buf[fpos], item->len);
  252. } else {
  253. item->data = NULL;
  254. }
  255. fpos += item->len;
  256. item++;
  257. }
  258. return key;
  259. }
  260. static void
  261. rsakey_to_file(RSAPrivateKey *key, char *filename)
  262. {
  263. PRFileDesc *file;
  264. SECItem *item;
  265. unsigned char len[4];
  266. int i;
  267. SECStatus status;
  268. NSSBase64Encoder *cx;
  269. SECItem ascii;
  270. ascii.data = NULL; 
  271. ascii.len = 0;
  272. file  = PR_Open(filename, PR_WRONLY|PR_CREATE_FILE, 00660);
  273. cx = NSSBase64Encoder_Create(output_ascii, file);
  274. item = &key->version;
  275. for (i=0; i<9; i++) {
  276. len[0] = (item->len >> 24) & 0xff;
  277. len[1] = (item->len >> 16) & 0xff;
  278. len[2] = (item->len >>  8) & 0xff;
  279. len[3] = (item->len & 0xff);
  280. status = NSSBase64Encoder_Update(cx, len, 4);
  281. status = NSSBase64Encoder_Update(cx, item->data, item->len);
  282. item++;
  283. }
  284. status = NSSBase64Encoder_Destroy(cx, PR_FALSE);
  285. status = PR_Write(file, "rn", 2);
  286. PR_Close(file);
  287. }
  288. static PQGParams *
  289. pqg_from_filedata(SECItem *filedata)
  290. {
  291. PRArenaPool *arena;
  292. PQGParams *pqg;
  293. unsigned char *buf = filedata->data;
  294. int fpos = 0;
  295. int i;
  296. SECItem *item;
  297. /*  Allocate space for key structure. */
  298. arena = PORT_NewArena(2048);
  299. pqg = (PQGParams *)PORT_ArenaZAlloc(arena, sizeof(PQGParams));
  300. pqg->arena = arena;
  301. item = &pqg->prime;
  302. for (i=0; i<3; i++) {
  303. item->len  = (buf[fpos++] & 0xff) << 24;
  304. item->len |= (buf[fpos++] & 0xff) << 16;
  305. item->len |= (buf[fpos++] & 0xff) <<  8;
  306. item->len |= (buf[fpos++] & 0xff);
  307. if (item->len > 0) {
  308. item->data = PORT_ArenaAlloc(arena, item->len);
  309. PORT_Memcpy(item->data, &buf[fpos], item->len);
  310. } else {
  311. item->data = NULL;
  312. }
  313. fpos += item->len;
  314. item++;
  315. }
  316. return pqg;
  317. }
  318. static DSAPrivateKey *
  319. dsakey_from_filedata(SECItem *filedata)
  320. {
  321. PRArenaPool *arena;
  322. DSAPrivateKey *key;
  323. unsigned char *buf = filedata->data;
  324. int fpos = 0;
  325. int i;
  326. SECItem *item;
  327. /*  Allocate space for key structure. */
  328. arena = PORT_NewArena(2048);
  329. key = (DSAPrivateKey *)PORT_ArenaZAlloc(arena, sizeof(DSAPrivateKey));
  330. key->params.arena = arena;
  331. item = &key->params.prime;
  332. for (i=0; i<5; i++) {
  333. item->len  = (buf[fpos++] & 0xff) << 24;
  334. item->len |= (buf[fpos++] & 0xff) << 16;
  335. item->len |= (buf[fpos++] & 0xff) <<  8;
  336. item->len |= (buf[fpos++] & 0xff);
  337. if (item->len > 0) {
  338. item->data = PORT_ArenaAlloc(arena, item->len);
  339. PORT_Memcpy(item->data, &buf[fpos], item->len);
  340. } else {
  341. item->data = NULL;
  342. }
  343. fpos += item->len;
  344. item++;
  345. }
  346. return key;
  347. }
  348. static void
  349. pqg_to_file(PQGParams *params, char *filename)
  350. {
  351. PRFileDesc *file;
  352. SECItem *item;
  353. unsigned char len[4];
  354. int i;
  355. SECStatus status;
  356. NSSBase64Encoder *cx;
  357. SECItem ascii;
  358. ascii.data = NULL; 
  359. ascii.len = 0;
  360. file  = PR_Open(filename, PR_WRONLY|PR_CREATE_FILE, 00660);
  361. cx = NSSBase64Encoder_Create(output_ascii, file);
  362. item = &params->prime;
  363. for (i=0; i<3; i++) {
  364. len[0] = (item->len >> 24) & 0xff;
  365. len[1] = (item->len >> 16) & 0xff;
  366. len[2] = (item->len >>  8) & 0xff;
  367. len[3] = (item->len & 0xff);
  368. status = NSSBase64Encoder_Update(cx, len, 4);
  369. status = NSSBase64Encoder_Update(cx, item->data, item->len);
  370. item++;
  371. }
  372. status = NSSBase64Encoder_Destroy(cx, PR_FALSE);
  373. status = PR_Write(file, "rn", 2);
  374. }
  375. static void
  376. dsakey_to_file(DSAPrivateKey *key, char *filename)
  377. {
  378. PRFileDesc *file;
  379. SECItem *item;
  380. unsigned char len[4];
  381. int i;
  382. SECStatus status;
  383. NSSBase64Encoder *cx;
  384. SECItem ascii;
  385. ascii.data = NULL; 
  386. ascii.len = 0;
  387. file  = PR_Open(filename, PR_WRONLY|PR_CREATE_FILE, 00660);
  388. cx = NSSBase64Encoder_Create(output_ascii, file);
  389. item = &key->params.prime;
  390. for (i=0; i<5; i++) {
  391. len[0] = (item->len >> 24) & 0xff;
  392. len[1] = (item->len >> 16) & 0xff;
  393. len[2] = (item->len >>  8) & 0xff;
  394. len[3] = (item->len & 0xff);
  395. status = NSSBase64Encoder_Update(cx, len, 4);
  396. status = NSSBase64Encoder_Update(cx, item->data, item->len);
  397. item++;
  398. }
  399. status = NSSBase64Encoder_Destroy(cx, PR_FALSE);
  400. status = PR_Write(file, "rn", 2);
  401. }
  402. static void
  403. dump_pqg(PQGParams *pqg)
  404. {
  405. SECU_PrintInteger(stdout, &pqg->prime, "PRIME:", 0);
  406. SECU_PrintInteger(stdout, &pqg->subPrime, "SUBPRIME:", 0);
  407. SECU_PrintInteger(stdout, &pqg->base, "BASE:", 0);
  408. }
  409. static void
  410. dump_dsakey(DSAPrivateKey *key)
  411. {
  412. dump_pqg(&key->params);
  413. SECU_PrintInteger(stdout, &key->publicValue, "PUBLIC VALUE:", 0);
  414. SECU_PrintInteger(stdout, &key->privateValue, "PRIVATE VALUE:", 0);
  415. }
  416. /*  Multi-purpose crypto information */
  417. typedef struct 
  418. {
  419. PRBool  encrypt;
  420. PRBool  decrypt;
  421. PRBool  sign;
  422. PRBool  verify;
  423. PRBool  hash;
  424. SECItem seed;
  425. SECItem pqg;
  426. SECItem key;
  427.     SECItem iv;
  428.     SECItem in;
  429.     SECItem out;
  430. SECItem sigseed;
  431. PRInt32 keysize;
  432. PRInt32 bufsize;
  433. PRBool  useseed;
  434. PRBool  usesigseed;
  435. PRBool  performance;
  436. PRBool  multihash;
  437. PQGParams *params;      /* DSA only */
  438. unsigned int rounds;    /* RC5 only */
  439. unsigned int wordsize;  /* RC5 only */
  440. unsigned int rsapubexp; /* RSA only */
  441. unsigned int repetitions; /* performance tests only */
  442. } blapitestInfo;
  443. /* Macros for performance timing. */
  444. #define TIMESTART() 
  445. if (info->performance) 
  446. time1 = PR_IntervalNow();
  447. #define TIMEFINISH(mode, nb) 
  448. if (info->performance) { 
  449. time2 = (PRIntervalTime)(PR_IntervalNow() - time1); 
  450. time1 = PR_IntervalToMilliseconds(time2); 
  451. printf("%s,%d,%.3fn", mode, nb, ((float)(time1))/info->repetitions); 
  452. }
  453. SECStatus
  454. fillitem(SECItem *item, int numbytes, char *filename)
  455. {
  456. if (item->len == 0)
  457. return get_and_write_random_bytes(item, numbytes, filename);
  458. return SECSuccess;
  459. }
  460. /************************
  461. **  DES 
  462. ************************/
  463. /*  encrypt/decrypt for all DES */
  464. static SECStatus
  465. des_common(DESContext *descx, blapitestInfo *info)
  466. {
  467. PRInt32 maxsize;
  468. SECStatus rv;
  469. PRIntervalTime time1, time2;
  470. int i, numiter;
  471. numiter = info->repetitions;
  472. maxsize = info->in.len;
  473. info->out.data = (unsigned char *)PORT_ZAlloc(maxsize);
  474. if (info->encrypt) {
  475. TIMESTART();
  476. for (i=0; i<numiter; i++)
  477. rv = DES_Encrypt(descx, info->out.data, &info->out.len, maxsize,
  478.                  info->in.data, info->in.len);
  479. TIMEFINISH("DES ENCRYPT", maxsize);
  480. if (rv) {
  481. fprintf(stderr, "%s:  Failed to encrypt!n", progName);
  482. CHECKERROR(rv, __LINE__);
  483. }
  484. } else {
  485. TIMESTART();
  486. for (i=0; i<numiter; i++)
  487. rv = DES_Decrypt(descx, info->out.data, &info->out.len, maxsize,
  488.                  info->in.data, info->in.len);
  489. TIMEFINISH("DES DECRYPT", maxsize);
  490. if (rv) {
  491. fprintf(stderr, "%s:  Failed to decrypt!n", progName);
  492. CHECKERROR(rv, __LINE__);
  493. }
  494. }
  495. return rv;
  496. }
  497. /*  DES codebook mode */
  498. static SECStatus
  499. des_ecb_test(blapitestInfo *info)
  500. {
  501. SECStatus rv;
  502. DESContext *descx;
  503. PRIntervalTime time1, time2;
  504. int i, numiter = info->repetitions;
  505. fillitem(&info->key, DES_KEY_LENGTH, "tmp.key");
  506. fillitem(&info->in, info->bufsize, "tmp.pt");
  507. TIMESTART();
  508. for (i=0; i<numiter-1; i++) {
  509. descx = DES_CreateContext(info->key.data, NULL, NSS_DES, info->encrypt);
  510. DES_DestroyContext(descx, PR_TRUE);
  511. }
  512. descx = DES_CreateContext(info->key.data, NULL, NSS_DES, info->encrypt);
  513. TIMEFINISH("DES ECB CONTEXT CREATE", info->key.len);
  514. if (!descx) {
  515. fprintf(stderr,"%s:  Failed to create encryption context!n", progName);
  516. return SECFailure;
  517. }
  518. rv = des_common(descx, info);
  519. CHECKERROR(rv, __LINE__);
  520. DES_DestroyContext(descx, PR_TRUE);
  521. return rv;
  522. }
  523. /*  DES chaining mode */
  524. static SECStatus
  525. des_cbc_test(blapitestInfo *info)
  526. {
  527. SECStatus rv;
  528. DESContext *descx;
  529. PRIntervalTime time1, time2;
  530. int i, numiter = info->repetitions;
  531. fillitem(&info->key, DES_KEY_LENGTH, "tmp.key");
  532. fillitem(&info->in, info->bufsize, "tmp.pt");
  533. fillitem(&info->iv, DES_KEY_LENGTH, "tmp.iv");
  534. TIMESTART();
  535. for (i=0; i<numiter-1; i++) {
  536. descx = DES_CreateContext(info->key.data, info->iv.data, NSS_DES_CBC, 
  537.                           info->encrypt);
  538. DES_DestroyContext(descx, PR_TRUE);
  539. }
  540. descx = DES_CreateContext(info->key.data, info->iv.data, NSS_DES_CBC, 
  541.                           info->encrypt);
  542. TIMEFINISH("DES CBC CONTEXT CREATE", info->key.len);
  543. if (!descx) {
  544. PR_fprintf(PR_STDERR, 
  545.   "%s:  Failed to create encryption context!n", progName);
  546. return SECFailure;
  547. }
  548. if (info->performance) {
  549. /*  In chaining mode, repeated iterations of the encryption
  550.  *  function using the same context will alter the final output.
  551.  *  So, once the performance test is done, reset the context
  552.  *  and perform a single iteration to obtain the correct result.
  553.  */
  554. int tmp = info->repetitions;
  555. rv = des_common(descx, info);
  556. DES_DestroyContext(descx, PR_TRUE);
  557. descx = DES_CreateContext(info->key.data, info->iv.data, NSS_DES_CBC, 
  558.                           info->encrypt);
  559. info->performance = PR_FALSE;
  560. info->repetitions = 1;
  561. rv = des_common(descx, info);
  562. info->performance = PR_TRUE;
  563. info->repetitions = tmp;
  564. } else {
  565. rv = des_common(descx, info);
  566. }
  567. CHECKERROR(rv, __LINE__);
  568. DES_DestroyContext(descx, PR_TRUE);
  569. return rv;
  570. }
  571. /*  3-key Triple-DES codebook mode */
  572. static SECStatus
  573. des_ede_ecb_test(blapitestInfo *info)
  574. {
  575. SECStatus rv;
  576. DESContext *descx;
  577. PRIntervalTime time1, time2;
  578. int i, numiter = info->repetitions;
  579. fillitem(&info->key, 3*DES_KEY_LENGTH, "tmp.key");
  580. fillitem(&info->in, info->bufsize, "tmp.pt");
  581. TIMESTART();
  582. for (i=0; i<numiter-1; i++) {
  583. descx = DES_CreateContext(info->key.data, NULL, NSS_DES_EDE3,
  584.                           info->encrypt);
  585. DES_DestroyContext(descx, PR_TRUE);
  586. }
  587. descx = DES_CreateContext(info->key.data, NULL, NSS_DES_EDE3,
  588.                           info->encrypt);
  589. TIMEFINISH("3DES ECB CONTEXT CREATE", info->key.len);
  590. if (!descx) {
  591. fprintf(stderr,"%s:  Failed to create encryption context!n", progName);
  592. return SECFailure;
  593. }
  594. rv = des_common(descx, info);
  595. CHECKERROR(rv, __LINE__);
  596. DES_DestroyContext(descx, PR_TRUE);
  597. return rv;
  598. }
  599. /*  3-key Triple-DES chaining mode */
  600. static SECStatus
  601. des_ede_cbc_test(blapitestInfo *info)
  602. {
  603. SECStatus rv;
  604. DESContext *descx;
  605. PRIntervalTime time1, time2;
  606. int i, numiter = info->repetitions;
  607. fillitem(&info->key, 3*DES_KEY_LENGTH, "tmp.key");
  608. fillitem(&info->in, info->bufsize, "tmp.pt");
  609. fillitem(&info->iv, DES_KEY_LENGTH, "tmp.iv");
  610. TIMESTART();
  611. for (i=0; i<numiter-1; i++) {
  612. descx = DES_CreateContext(info->key.data, info->iv.data, 
  613.                           NSS_DES_EDE3_CBC, info->encrypt);
  614. DES_DestroyContext(descx, PR_TRUE);
  615. }
  616. descx = DES_CreateContext(info->key.data, info->iv.data, NSS_DES_EDE3_CBC, 
  617.                           info->encrypt);
  618. TIMEFINISH("3DES CBC CONTEXT CREATE", info->key.len);
  619. if (!descx) {
  620. fprintf(stderr,"%s:  Failed to create encryption context!n", progName);
  621. return SECFailure;
  622. }
  623. if (info->performance) {
  624. /*  In chaining mode, repeated iterations of the encryption
  625.  *  function using the same context will alter the final output.
  626.  *  So, once the performance test is done, reset the context
  627.  *  and perform a single iteration to obtain the correct result.
  628.  */
  629. int tmp = info->repetitions;
  630. rv = des_common(descx, info);
  631. DES_DestroyContext(descx, PR_TRUE);
  632. descx = DES_CreateContext(info->key.data, info->iv.data, 
  633.                           NSS_DES_EDE3_CBC, info->encrypt);
  634. info->performance = PR_FALSE;
  635. info->repetitions = 1;
  636. rv = des_common(descx, info);
  637. info->performance = PR_TRUE;
  638. info->repetitions = tmp;
  639. } else {
  640. rv = des_common(descx, info);
  641. }
  642. CHECKERROR(rv, __LINE__);
  643. DES_DestroyContext(descx, PR_TRUE);
  644. return rv;
  645. }
  646. /************************
  647. **  RC2 
  648. ************************/
  649. /*  RC2 ECB */
  650. static SECStatus
  651. rc2_ecb_test(blapitestInfo *info)
  652. {
  653. SECStatus rv;
  654. RC2Context *rc2cx;
  655. PRIntervalTime time1, time2;
  656. int i, numiter = info->repetitions;
  657. fillitem(&info->key, info->keysize, "tmp.key");
  658. fillitem(&info->in, info->bufsize, "tmp.pt");
  659. TIMESTART();
  660. for (i=0; i<numiter-1; i++) {
  661. rc2cx = RC2_CreateContext(info->key.data, info->key.len, NULL, 
  662.                           NSS_RC2, info->key.len);
  663. RC2_DestroyContext(rc2cx, PR_TRUE);
  664. }
  665. rc2cx = RC2_CreateContext(info->key.data, info->key.len, NULL, 
  666.                           NSS_RC2, info->key.len);
  667. TIMEFINISH("RC2 ECB CONTEXT CREATE", info->key.len);
  668. if (!rc2cx) {
  669. fprintf(stderr,"%s:  Failed to create encryption context!n", progName);
  670. return SECFailure;
  671. }
  672. info->out.len = 2*info->in.len;
  673. info->out.data = (unsigned char *)PORT_ZAlloc(info->out.len);
  674. if (info->encrypt) {
  675. TIMESTART();
  676. for (i=0; i<numiter; i++)
  677. rv = RC2_Encrypt(rc2cx, info->out.data, &info->out.len, 
  678.                  info->out.len, info->in.data, info->in.len);
  679. TIMEFINISH("RC2 ECB ENCRYPT", info->in.len);
  680. CHECKERROR(rv, __LINE__);
  681. } else {
  682. TIMESTART();
  683. for (i=0; i<numiter; i++)
  684. rv = RC2_Decrypt(rc2cx, info->out.data, &info->out.len, 
  685.                  info->out.len, info->in.data, info->in.len);
  686. TIMEFINISH("RC2 ECB DECRYPT", info->in.len);
  687. CHECKERROR(rv, __LINE__);
  688. }
  689. RC2_DestroyContext(rc2cx, PR_TRUE);
  690. return rv;
  691. }
  692. /*  RC2 CBC */
  693. static SECStatus
  694. rc2_cbc_test(blapitestInfo *info)
  695. {
  696. SECStatus rv;
  697. RC2Context *rc2cx;
  698. PRIntervalTime time1, time2;
  699. int i, numiter = info->repetitions;
  700. fillitem(&info->key, info->keysize, "tmp.key");
  701. fillitem(&info->in, info->bufsize, "tmp.pt");
  702. fillitem(&info->iv, info->bufsize, "tmp.iv");
  703. TIMESTART();
  704. for (i=0; i<numiter-1; i++) {
  705. rc2cx = RC2_CreateContext(info->key.data, info->key.len, info->iv.data, 
  706.                           NSS_RC2_CBC, info->key.len);
  707. RC2_DestroyContext(rc2cx, PR_TRUE);
  708. }
  709. rc2cx = RC2_CreateContext(info->key.data, info->key.len, info->iv.data, 
  710.                           NSS_RC2_CBC, info->key.len);
  711. TIMEFINISH("RC2 CBC CONTEXT CREATE", info->key.len);
  712. if (!rc2cx) {
  713. fprintf(stderr,"%s:  Failed to create encryption context!n", progName);
  714. return SECFailure;
  715. }
  716. info->out.len = 2*info->in.len;
  717. info->out.data = (unsigned char *)PORT_ZAlloc(info->out.len);
  718. if (info->encrypt) {
  719. TIMESTART();
  720. for (i=0; i<numiter; i++)
  721. rv = RC2_Encrypt(rc2cx, info->out.data, &info->out.len, 
  722.                  info->out.len, info->in.data, info->in.len);
  723. TIMEFINISH("RC2 CBC ENCRYPT", info->in.len);
  724. if (info->performance) {
  725. /*  reset the context */
  726. RC2_DestroyContext(rc2cx, PR_TRUE);
  727. rc2cx = RC2_CreateContext(info->key.data, info->key.len, 
  728.                          info->iv.data, NSS_RC2_CBC, info->key.len);
  729. rv = RC2_Encrypt(rc2cx, info->out.data, &info->out.len, 
  730.                  info->out.len, info->in.data, info->in.len);
  731. }
  732. CHECKERROR(rv, __LINE__);
  733. if (rv) {
  734. fprintf(stderr, "%s:  Failed to encrypt!n", progName);
  735. CHECKERROR(rv, __LINE__);
  736. }
  737. } else {
  738. TIMESTART();
  739. for (i=0; i<numiter; i++)
  740. rv = RC2_Decrypt(rc2cx, info->out.data, &info->out.len, 
  741.                  info->out.len, info->in.data, info->in.len);
  742. TIMEFINISH("RC2 CBC DECRYPT", info->in.len);
  743. if (info->performance) {
  744. /*  reset the context */
  745. RC2_DestroyContext(rc2cx, PR_TRUE);
  746. rc2cx = RC2_CreateContext(info->key.data, info->key.len, 
  747.                          info->iv.data, NSS_RC2_CBC, info->key.len);
  748. rv = RC2_Decrypt(rc2cx, info->out.data, &info->out.len, 
  749.                  info->out.len, info->in.data, info->in.len);
  750. }
  751. if (rv) {
  752. fprintf(stderr, "%s:  Failed to decrypt!n", progName);
  753. CHECKERROR(rv, __LINE__);
  754. }
  755. }
  756. RC2_DestroyContext(rc2cx, PR_TRUE);
  757. return rv;
  758. }
  759. /************************
  760. **  RC4 
  761. ************************/
  762. static SECStatus
  763. rc4_test(blapitestInfo *info)
  764. {
  765. SECStatus rv;
  766. RC4Context *rc4cx;
  767. PRIntervalTime time1, time2;
  768. int i, numiter;
  769. numiter = info->repetitions;
  770. fillitem(&info->key, info->keysize, "tmp.key");
  771. fillitem(&info->in, info->bufsize, "tmp.pt");
  772. TIMESTART();
  773. for (i=0; i<numiter-1; i++) {
  774. rc4cx = RC4_CreateContext(info->key.data, info->key.len);
  775. RC4_DestroyContext(rc4cx, PR_TRUE);
  776. }
  777. rc4cx = RC4_CreateContext(info->key.data, info->key.len);
  778. TIMEFINISH("RC4 CONTEXT CREATE", info->key.len);
  779. if (!rc4cx) {
  780. fprintf(stderr,"%s:  Failed to create encryption context!n", progName);
  781. return SECFailure;
  782. }
  783. info->out.len = 2*info->in.len;
  784. info->out.data = (unsigned char *)PORT_ZAlloc(info->out.len);
  785. if (info->encrypt) {
  786. TIMESTART();
  787. for (i=0; i<numiter; i++)
  788. rv = RC4_Encrypt(rc4cx, info->out.data, &info->out.len, 
  789.                  info->out.len, info->in.data, info->in.len);
  790. TIMEFINISH("RC4 ENCRYPT", info->in.len);
  791. if (info->performance) {
  792. /*  reset the context */
  793. RC4_DestroyContext(rc4cx, PR_TRUE);
  794. rc4cx = RC4_CreateContext(info->key.data, info->key.len);
  795. rv = RC4_Encrypt(rc4cx, info->out.data, &info->out.len, 
  796.                  info->out.len, info->in.data, info->in.len);
  797. }
  798. if (rv) {
  799. fprintf(stderr, "%s:  Failed to encrypt!n", progName);
  800. CHECKERROR(rv, __LINE__);
  801. }
  802. } else {
  803. TIMESTART();
  804. for (i=0; i<numiter; i++)
  805. rv = RC4_Decrypt(rc4cx, info->out.data, &info->out.len, 
  806.                  info->out.len, info->in.data, info->in.len);
  807. TIMEFINISH("RC4 DECRYPT", info->in.len);
  808. if (info->performance) {
  809. /*  reset the context */
  810. RC4_DestroyContext(rc4cx, PR_TRUE);
  811. rc4cx = RC4_CreateContext(info->key.data, info->key.len);
  812. rv = RC4_Decrypt(rc4cx, info->out.data, &info->out.len, 
  813.                  info->out.len, info->in.data, info->in.len);
  814. }
  815. if (rv) {
  816. fprintf(stderr, "%s:  Failed to decrypt!n", progName);
  817. CHECKERROR(rv, __LINE__);
  818. }
  819. }
  820. RC4_DestroyContext(rc4cx, PR_TRUE);
  821. return rv;
  822. }
  823. #if NSS_SOFTOKEN_DOES_RC5
  824. /************************
  825. **  RC5 
  826. ************************/
  827. /*  RC5 ECB */
  828. static SECStatus
  829. rc5_ecb_test(blapitestInfo *info)
  830. {
  831. SECStatus rv;
  832. RC5Context *rc5cx;
  833. PRIntervalTime time1, time2;
  834. int i, numiter;
  835. numiter = info->repetitions;
  836. fillitem(&info->key, info->keysize, "tmp.key");
  837. fillitem(&info->in, info->bufsize, "tmp.pt");
  838. TIMESTART();
  839. for (i=0; i<numiter-1; i++) {
  840. rc5cx = RC5_CreateContext(&info->key, info->rounds, info->wordsize, 
  841.                           NULL, NSS_RC5);
  842. RC5_DestroyContext(rc5cx, PR_TRUE);
  843. }
  844. rc5cx = RC5_CreateContext(&info->key, info->rounds, info->wordsize, 
  845.                           NULL, NSS_RC5);
  846. TIMEFINISH("RC5 ECB CONTEXT CREATE", info->key.len);
  847. if (!rc5cx) {
  848. fprintf(stderr,"%s:  Failed to create encryption context!n", progName);
  849. return SECFailure;
  850. }
  851. info->out.len = 2*info->in.len;
  852. info->out.data = (unsigned char *)PORT_ZAlloc(info->out.len);
  853. if (info->encrypt) {
  854. TIMESTART();
  855. for (i=0; i<numiter; i++)
  856. rv = RC5_Encrypt(rc5cx, info->out.data, &info->out.len, 
  857.                  info->out.len, info->in.data, info->in.len);
  858. TIMEFINISH("RC5 ECB ENCRYPT", info->in.len);
  859. if (rv) {
  860. fprintf(stderr, "%s:  Failed to encrypt!n", progName);
  861. CHECKERROR(rv, __LINE__);
  862. }
  863. } else {
  864. TIMESTART();
  865. for (i=0; i<numiter; i++)
  866. rv = RC5_Decrypt(rc5cx, info->out.data, &info->out.len, 
  867.                  info->out.len, info->in.data, info->in.len);
  868. TIMEFINISH("RC5 ECB ENCRYPT", info->in.len);
  869. if (rv) {
  870. fprintf(stderr, "%s:  Failed to decrypt!n", progName);
  871. CHECKERROR(rv, __LINE__);
  872. }
  873. }
  874. RC5_DestroyContext(rc5cx, PR_TRUE);
  875. return rv;
  876. }
  877. /*  RC5 CBC */
  878. static SECStatus
  879. rc5_cbc_test(blapitestInfo *info)
  880. {
  881. SECStatus rv;
  882. RC5Context *rc5cx;
  883. PRIntervalTime time1, time2;
  884. int i, numiter;
  885. numiter = info->repetitions;
  886. fillitem(&info->key, info->keysize, "tmp.key");
  887. fillitem(&info->in, info->bufsize, "tmp.pt");
  888. fillitem(&info->iv, info->bufsize, "tmp.iv");
  889. TIMESTART();
  890. for (i=0; i<numiter-1; i++) {
  891. rc5cx = RC5_CreateContext(&info->key, info->rounds, info->wordsize, 
  892.                           info->iv.data, NSS_RC5_CBC);
  893. RC5_DestroyContext(rc5cx, PR_TRUE);
  894. }
  895. rc5cx = RC5_CreateContext(&info->key, info->rounds, info->wordsize, 
  896.                           info->iv.data, NSS_RC5_CBC);
  897. TIMEFINISH("RC5 CBC CONTEXT CREATE", info->key.len);
  898. if (!rc5cx) {
  899. fprintf(stderr,"%s:  Failed to create encryption context!n", progName);
  900. return SECFailure;
  901. }
  902. info->out.len = 2*info->in.len;
  903. info->out.data = (unsigned char *)PORT_ZAlloc(info->out.len);
  904. if (info->encrypt) {
  905. TIMESTART();
  906. for (i=0; i<numiter; i++)
  907. rv = RC5_Encrypt(rc5cx, info->out.data, &info->out.len, 
  908.                  info->out.len, info->in.data, info->in.len);
  909. TIMEFINISH("RC5 CBC ENCRYPT", info->in.len);
  910. if (info->performance) {
  911. /*  reset the context */
  912. RC5_DestroyContext(rc5cx, PR_TRUE);
  913. rc5cx = RC5_CreateContext(&info->key, info->rounds, info->wordsize, 
  914.                           info->iv.data, NSS_RC5_CBC);
  915. rv = RC5_Encrypt(rc5cx, info->out.data, &info->out.len, 
  916.                  info->out.len, info->in.data, info->in.len);
  917. }
  918. if (rv) {
  919. fprintf(stderr, "%s:  Failed to encrypt!n", progName);
  920. CHECKERROR(rv, __LINE__);
  921. }
  922. } else {
  923. TIMESTART();
  924. for (i=0; i<numiter; i++)
  925. rv = RC5_Decrypt(rc5cx, info->out.data, &info->out.len, 
  926.                  info->out.len, info->in.data, info->in.len);
  927. TIMEFINISH("RC5 CBC DECRYPT", info->in.len);
  928. if (info->performance) {
  929. /*  reset the context */
  930. RC5_DestroyContext(rc5cx, PR_TRUE);
  931. rc5cx = RC5_CreateContext(&info->key, info->rounds, info->wordsize, 
  932.                           info->iv.data, NSS_RC5_CBC);
  933. rv = RC5_Decrypt(rc5cx, info->out.data, &info->out.len, 
  934.                  info->out.len, info->in.data, info->in.len);
  935. }
  936. if (rv) {
  937. fprintf(stderr, "%s:  Failed to decrypt!n", progName);
  938. CHECKERROR(rv, __LINE__);
  939. }
  940. }
  941. RC5_DestroyContext(rc5cx, PR_TRUE);
  942. return rv;
  943. }
  944. #endif
  945. static SECStatus
  946. rsa_test(blapitestInfo *info)
  947. {
  948. RSAPrivateKey *key;
  949. SECItem expitem;
  950. SECStatus rv;
  951. PRIntervalTime time1, time2;
  952. int i, j, numiter;
  953. unsigned int modLen;
  954. numiter = info->repetitions;
  955. fillitem(&info->in, info->bufsize, "tmp.pt");
  956. if (info->key.len > 0) {
  957. key = rsakey_from_filedata(&info->key);
  958. } else {
  959. expitem.len = 4;
  960. expitem.data = (unsigned char *)PORT_ZAlloc(4);
  961. expitem.data[0] = (info->rsapubexp >> 24) & 0xff;
  962. expitem.data[1] = (info->rsapubexp >> 16) & 0xff;
  963. expitem.data[2] = (info->rsapubexp >>  8) & 0xff;
  964. expitem.data[3] = (info->rsapubexp & 0xff);
  965. TIMESTART();
  966. for (i=0; i<numiter-1; i++) {
  967. key = RSA_NewKey(info->keysize*8, &expitem);
  968. PORT_FreeArena(key->arena, PR_TRUE);
  969. }
  970. key = RSA_NewKey(info->keysize*8, &expitem);
  971. TIMEFINISH("RSA KEY GEN", info->keysize);
  972. rsakey_to_file(key, "tmp.key");
  973. }
  974. if (key->modulus.data[0] == 0) {
  975. /* integer value of input must be less than modulus */
  976. if (info->in.data[0] >= key->modulus.data[1])
  977. return SECFailure;
  978. } else {
  979. if (info->in.data[0] >= key->modulus.data[0])
  980. return SECFailure;
  981. }
  982. modLen = key->modulus.len - !key->modulus.data[0];
  983. if (info->in.len % modLen != 0) {
  984. fprintf(stderr, "Input buffer must be a multiple of modulus length!n");
  985. return SECFailure;
  986. }
  987. info->out.len = info->in.len; 
  988. info->out.data = (unsigned char *)PORT_ZAlloc(info->out.len);
  989. if (info->encrypt) {
  990. RSAPublicKey pubkey;
  991. SECITEM_CopyItem(key->arena, &pubkey.modulus, &key->modulus);
  992. SECITEM_CopyItem(key->arena, &pubkey.publicExponent, 
  993.                              &key->publicExponent);
  994. TIMESTART();
  995. for (i=0; i<numiter; i++) {
  996. for (j=0; j<info->in.len; j+=pubkey.modulus.len) {
  997. rv = RSA_PublicKeyOp(&pubkey, &info->out.data[j], 
  998.                               &info->in.data[j]);
  999. }
  1000. }
  1001. TIMEFINISH("RSA ENCRYPT", info->in.len);
  1002. CHECKERROR(rv, __LINE__);
  1003. } else {
  1004. TIMESTART();
  1005. for (i=info->repetitions; i>0; i--) {
  1006. for (j=0; j<info->in.len; j+=key->modulus.len) {
  1007. rv = RSA_PrivateKeyOp(key, &info->out.data[j], 
  1008.                            &info->in.data[j]);
  1009. }
  1010. }
  1011. TIMEFINISH("RSA DECRYPT", info->in.len);
  1012. CHECKERROR(rv, __LINE__);
  1013. }
  1014. PORT_FreeArena(key->arena, PR_TRUE);
  1015. return SECSuccess;
  1016. }
  1017. static SECStatus
  1018. pqg_test(blapitestInfo *info)
  1019. {
  1020. SECStatus rv = SECSuccess;
  1021. PQGVerify *verify;
  1022. PRIntervalTime time1, time2;
  1023. int i, numiter;
  1024. numiter = info->repetitions;
  1025. if (info->pqg.len > 0) {
  1026. info->params = pqg_from_filedata(&info->pqg);
  1027. } else {
  1028. TIMESTART();
  1029. for (i=0; i<numiter-1; i++) {
  1030. rv = PQG_ParamGen(info->keysize, &info->params, &verify);
  1031. PORT_FreeArena(info->params->arena, PR_TRUE);
  1032. }
  1033. rv = PQG_ParamGen(info->keysize, &info->params, &verify);
  1034. TIMEFINISH("PQG PARAM GEN", info->keysize);
  1035. pqg_to_file(info->params, "tmp.pqg");
  1036. }
  1037. CHECKERROR(rv, __LINE__);
  1038. return rv;
  1039. }
  1040. static SECStatus
  1041. dsa_test(blapitestInfo *info)
  1042. {
  1043. DSAPrivateKey *key;
  1044. SECStatus rv = SECSuccess;
  1045. PRIntervalTime time1, time2;
  1046. int i, numiter;
  1047. numiter = info->repetitions;
  1048. fillitem(&info->in, info->bufsize, "tmp.pt");
  1049. if (info->key.len > 0) {
  1050. key = dsakey_from_filedata(&info->key);
  1051. } else {
  1052. pqg_test(info);
  1053. if (info->useseed) {
  1054. if (info->seed.len == 0)
  1055. get_and_write_random_bytes(&info->seed, DSA_SUBPRIME_LEN, 
  1056.                            "tmp.seed");
  1057. rv = DSA_NewKeyFromSeed(info->params, info->seed.data, &key);
  1058. } else {
  1059. rv = DSA_NewKey(info->params, &key);
  1060. }
  1061. CHECKERROR(rv, __LINE__);
  1062. dsakey_to_file(key, "tmp.key");
  1063. }
  1064. if (info->sign) {
  1065. info->out.len = DSA_SIGNATURE_LEN;
  1066. info->out.data = (unsigned char *)PORT_ZAlloc(info->out.len);
  1067. if (info->usesigseed) {
  1068. if (info->sigseed.len == 0)
  1069. get_and_write_random_bytes(&info->sigseed, DSA_SUBPRIME_LEN,
  1070.                            "tmp.sigseed");
  1071. TIMESTART();
  1072. rv = DSA_SignDigestWithSeed(key, &info->out, &info->in, 
  1073.                             info->sigseed.data);
  1074. TIMEFINISH("DSA SIGN", info->in.len);
  1075. } else {
  1076. TIMESTART();
  1077. for (i=0; i<numiter; i++)
  1078. rv = DSA_SignDigest(key, &info->out, &info->in);
  1079. TIMEFINISH("DSA SIGN", info->in.len);
  1080. }
  1081. CHECKERROR(rv, __LINE__);
  1082. } else {
  1083. DSAPublicKey pubkey;
  1084. PRArenaPool *arena;
  1085. arena = key->params.arena;
  1086. SECITEM_CopyItem(arena, &pubkey.params.prime, &key->params.prime);
  1087. SECITEM_CopyItem(arena, &pubkey.params.subPrime, &key->params.subPrime);
  1088. SECITEM_CopyItem(arena, &pubkey.params.base, &key->params.base);
  1089. SECITEM_CopyItem(arena, &pubkey.publicValue, &key->publicValue);
  1090. TIMESTART();
  1091. for (i=0; i<numiter; i++)
  1092. rv = DSA_VerifyDigest(&pubkey, &info->out, &info->in);
  1093. TIMEFINISH("DSA VERIFY", info->in.len);
  1094. if (rv != SECSuccess) {
  1095. PR_fprintf(PR_STDOUT, "Signature failed verification!n");
  1096. CHECKERROR(rv, __LINE__);
  1097. } /*else {
  1098. PR_fprintf(PR_STDOUT, "Signature verified.n");
  1099. }*/
  1100. }
  1101. PORT_FreeArena(key->params.arena, PR_TRUE);
  1102. return SECSuccess;
  1103. }
  1104. static SECStatus
  1105. md5_multi_test(blapitestInfo *info)
  1106. {
  1107. SECStatus rv = SECSuccess;
  1108. MD5Context *md5cx;
  1109. unsigned int len;
  1110. MD5Context *foomd5cx;
  1111. unsigned char *foomd5;
  1112. int i;
  1113. if (info->in.len == 0) {
  1114. rv = get_and_write_random_bytes(&info->in, info->bufsize, "tmp.pt");
  1115. CHECKERROR(rv, __LINE__);
  1116. }
  1117. md5cx = MD5_NewContext();
  1118. if (!md5cx) {
  1119. PR_fprintf(PR_STDERR, 
  1120.    "%s:  Failed to create hash context!n", progName);
  1121. return SECFailure;
  1122. }
  1123. info->out.len = MD5_LENGTH;
  1124. info->out.data = (unsigned char *)PORT_ZAlloc(info->out.len);
  1125. MD5_Begin(md5cx);
  1126. for (i=0; i<info->bufsize/8; i++) {
  1127. MD5_Update(md5cx, &info->in.data[i*8], 8);
  1128. len = MD5_FlattenSize(md5cx);
  1129. foomd5 = PORT_Alloc(len);
  1130. MD5_Flatten(md5cx, foomd5);
  1131. foomd5cx = MD5_Resurrect(foomd5, NULL);
  1132. rv = PORT_Memcmp(foomd5cx, md5cx, len);
  1133. if (rv != SECSuccess)
  1134. PR_fprintf(PR_STDERR, "%s:  MD5_Resurrect failed!n", progName);
  1135. MD5_DestroyContext(foomd5cx, PR_TRUE);
  1136. PORT_Free(foomd5);
  1137. }
  1138. MD5_End(md5cx, info->out.data, &len, MD5_LENGTH);
  1139. if (len != MD5_LENGTH)
  1140. PR_fprintf(PR_STDERR, "%s: Bad hash size %d.n", progName, len);
  1141. MD5_DestroyContext(md5cx, PR_TRUE);
  1142. return rv;
  1143. }
  1144. static SECStatus
  1145. md5_test(blapitestInfo *info)
  1146. {
  1147. SECStatus rv = SECSuccess;
  1148. PRIntervalTime time1, time2;
  1149. int i;
  1150. if (!info->hash) return SECFailure;
  1151. if (info->multihash) return md5_multi_test(info);
  1152. if (info->in.len == 0) {
  1153. rv = get_and_write_random_bytes(&info->in, info->bufsize, "tmp.pt");
  1154. CHECKERROR(rv, __LINE__);
  1155. }
  1156. info->out.len = MD5_LENGTH;
  1157. info->out.data = (unsigned char *)PORT_ZAlloc(info->out.len);
  1158. TIMESTART();
  1159. for (i=info->repetitions; i>0; i--) {
  1160. MD5_HashBuf(info->out.data, info->in.data, info->in.len);
  1161. }
  1162. TIMEFINISH("MD5 HASH", info->in.len);
  1163. return rv;
  1164. }
  1165. static SECStatus
  1166. md2_multi_test(blapitestInfo *info)
  1167. {
  1168. SECStatus rv = SECSuccess;
  1169. MD2Context *md2cx;
  1170. unsigned int len;
  1171. MD2Context *foomd2cx;
  1172. unsigned char *foomd2;
  1173. int i;
  1174. if (!info->hash) return SECFailure;
  1175. if (info->in.len == 0) {
  1176. rv = get_and_write_random_bytes(&info->in, info->bufsize, "tmp.pt");
  1177. CHECKERROR(rv, __LINE__);
  1178. }
  1179. md2cx = MD2_NewContext();
  1180. if (!md2cx) {
  1181. PR_fprintf(PR_STDERR, 
  1182.    "%s:  Failed to create hash context!n", progName);
  1183. return SECFailure;
  1184. }
  1185. info->out.len = MD2_LENGTH;
  1186. info->out.data = (unsigned char *)PORT_ZAlloc(info->out.len);
  1187. MD2_Begin(md2cx);
  1188. for (i=0; i<info->bufsize/8; i++) {
  1189. MD2_Update(md2cx, &info->in.data[i*8], 8);
  1190. len = MD2_FlattenSize(md2cx);
  1191. foomd2 = PORT_Alloc(len);
  1192. MD2_Flatten(md2cx, foomd2);
  1193. foomd2cx = MD2_Resurrect(foomd2, NULL);
  1194. rv = PORT_Memcmp(foomd2cx, md2cx, len);
  1195. if (rv != SECSuccess)
  1196. PR_fprintf(PR_STDERR, "%s:  MD2_Resurrect failed!n", progName);
  1197. MD2_DestroyContext(foomd2cx, PR_TRUE);
  1198. PORT_Free(foomd2);
  1199. }
  1200. MD2_End(md2cx, info->out.data, &len, MD2_LENGTH);
  1201. if (len != MD2_LENGTH)
  1202. PR_fprintf(PR_STDERR, "%s: Bad hash size %d.n", progName, len);
  1203. MD2_DestroyContext(md2cx, PR_TRUE);
  1204. return rv;
  1205. }
  1206. static SECStatus
  1207. md2_test(blapitestInfo *info)
  1208. {
  1209. unsigned int len;
  1210. MD2Context *cx = MD2_NewContext();
  1211. SECStatus rv = SECSuccess;
  1212. PRIntervalTime time1, time2;
  1213. int i;
  1214. if (!info->hash) return SECFailure;
  1215. if (info->multihash) return md2_multi_test(info);
  1216. if (info->in.len == 0) {
  1217. rv = get_and_write_random_bytes(&info->in, info->bufsize, "tmp.pt");
  1218. CHECKERROR(rv, __LINE__);
  1219. }
  1220. info->out.len = 16;
  1221. info->out.data = (unsigned char *)PORT_ZAlloc(info->out.len);
  1222. info->in.data[info->in.len] = '';
  1223. TIMESTART();
  1224. for (i=0; i<info->repetitions; i++) {
  1225. MD2_Begin(cx);
  1226. MD2_Update(cx, info->in.data, info->in.len);
  1227. MD2_End(cx, info->out.data, &len, 16);
  1228. }
  1229. TIMEFINISH("MD2 HASH", info->in.len);
  1230. MD2_DestroyContext(cx, PR_TRUE);
  1231. return rv;
  1232. }
  1233. static SECStatus
  1234. sha1_multi_test(blapitestInfo *info)
  1235. {
  1236. SECStatus rv = SECSuccess;
  1237. SHA1Context *sha1cx;
  1238. unsigned int len;
  1239. SHA1Context *foosha1cx;
  1240. unsigned char *foosha1;
  1241. int i;
  1242. if (info->in.len == 0) {
  1243. rv = get_and_write_random_bytes(&info->in, info->bufsize, "tmp.pt");
  1244. CHECKERROR(rv, __LINE__);
  1245. }
  1246. sha1cx = SHA1_NewContext();
  1247. if (!sha1cx) {
  1248. PR_fprintf(PR_STDERR, 
  1249.    "%s:  Failed to create hash context!n", progName);
  1250. return SECFailure;
  1251. }
  1252. info->out.len = SHA1_LENGTH;
  1253. info->out.data = (unsigned char *)PORT_ZAlloc(info->out.len);
  1254. SHA1_Begin(sha1cx);
  1255. for (i=0; i<info->bufsize/8; i++) {
  1256. SHA1_Update(sha1cx, &info->in.data[i*8], 8);
  1257. len = SHA1_FlattenSize(sha1cx);
  1258. foosha1 = PORT_Alloc(len);
  1259. SHA1_Flatten(sha1cx, foosha1);
  1260. foosha1cx = SHA1_Resurrect(foosha1, NULL);
  1261. rv = PORT_Memcmp(foosha1cx, sha1cx, len);
  1262. if (rv != SECSuccess)
  1263. PR_fprintf(PR_STDERR, "%s:  SHA1_Resurrect failed!n", progName);
  1264. SHA1_DestroyContext(foosha1cx, PR_TRUE);
  1265. PORT_Free(foosha1);
  1266. }
  1267. SHA1_End(sha1cx, info->out.data, &len, SHA1_LENGTH);
  1268. if (len != SHA1_LENGTH)
  1269. PR_fprintf(PR_STDERR, "%s: Bad hash size %d.n", progName, len);
  1270. SHA1_DestroyContext(sha1cx, PR_TRUE);
  1271. return rv;
  1272. }
  1273. static SECStatus
  1274. sha1_test(blapitestInfo *info)
  1275. {
  1276. unsigned int len;
  1277. SHA1Context *cx = SHA1_NewContext();
  1278. SECStatus rv = SECSuccess;
  1279. PRIntervalTime time1, time2;
  1280. int i;
  1281. if (!info->hash) return SECFailure;
  1282. if (info->multihash) return sha1_multi_test(info);
  1283. if (info->in.len == 0) {
  1284. rv = get_and_write_random_bytes(&info->in, info->bufsize, "tmp.pt");
  1285. CHECKERROR(rv, __LINE__);
  1286. }
  1287. info->out.len = SHA1_LENGTH;
  1288. info->out.data = (unsigned char *)PORT_ZAlloc(info->out.len);
  1289. info->in.data[info->in.len] = '';
  1290. TIMESTART();
  1291. for (i=info->repetitions; i>0; i--) {
  1292. SHA1_Begin(cx);
  1293. SHA1_Update(cx, info->in.data, info->in.len);
  1294. SHA1_End(cx, info->out.data, &len, SHA1_LENGTH);
  1295. }
  1296. TIMEFINISH("SHA1 HASH", info->in.len);
  1297. SHA1_DestroyContext(cx, PR_TRUE);
  1298. return rv;
  1299. }
  1300. typedef SECStatus (* blapitestCryptoFn)(blapitestInfo *);
  1301. static blapitestCryptoFn crypto_fns[] =
  1302. {
  1303. des_ecb_test,
  1304. des_cbc_test,
  1305. des_ede_ecb_test,
  1306. des_ede_cbc_test,
  1307. rc2_ecb_test,
  1308. rc2_cbc_test,
  1309. rc4_test,
  1310. #if NSS_SOFTOKEN_DOES_RC5
  1311. rc5_ecb_test,
  1312. rc5_cbc_test,
  1313. #endif
  1314. rsa_test,
  1315. NULL,
  1316. pqg_test,
  1317. dsa_test,
  1318. NULL,
  1319. md5_test,
  1320. md2_test,
  1321. sha1_test,
  1322. NULL
  1323. };
  1324. static char *mode_strings[] =
  1325. {
  1326. "des_ecb",
  1327. "des_cbc",
  1328. "des3_ecb",
  1329. "des3_cbc",
  1330. "rc2_ecb",
  1331. "rc2_cbc",
  1332. "rc4",
  1333. #if NSS_SOFTOKEN_DOES_RC5
  1334. "rc5_ecb",
  1335. "rc5_cbc",
  1336. #endif
  1337. "rsa",
  1338. "#endencrypt",
  1339. "pqg",
  1340. "dsa",
  1341. "#endsign",
  1342. "md5",
  1343. "md2",
  1344. "sha1",
  1345. "#endhash"
  1346. };
  1347. static void
  1348. printmodes(blapitestInfo *info)
  1349. {
  1350. int i = 0;
  1351. char *mode = mode_strings[0];
  1352. PR_fprintf(PR_STDERR, "Available modes: (specify with -m)n", progName);
  1353. while (mode[0] != '#') {
  1354. if (info->encrypt || info->decrypt)
  1355. fprintf(stderr, "%sn", mode);
  1356. mode = mode_strings[++i];
  1357. }
  1358. mode = mode_strings[++i];
  1359. while (mode[0] != '#') {
  1360. if (info->sign || info->verify)
  1361. fprintf(stderr, "%sn", mode);
  1362. mode = mode_strings[++i];
  1363. }
  1364. mode = mode_strings[++i];
  1365. while (mode[0] != '#') {
  1366. if (info->hash)
  1367. fprintf(stderr, "%sn", mode);
  1368. mode = mode_strings[++i];
  1369. }
  1370. }
  1371. static blapitestCryptoFn
  1372. get_test_mode(const char *modestring)
  1373. {
  1374. int i;
  1375. int nummodes = sizeof(mode_strings) / sizeof(char *);
  1376. for (i=0; i<nummodes; i++)
  1377. if (PL_strcmp(modestring, mode_strings[i]) == 0)
  1378. return crypto_fns[i];
  1379. PR_fprintf(PR_STDERR, "%s: invalid mode: %sn", progName, modestring);
  1380. return NULL;
  1381. }
  1382. static void
  1383. get_params(blapitestInfo *info, char *mode, int num)
  1384. {
  1385. SECItem *item;
  1386. /* XXX
  1387.  * this should use NSPR, but the string functions (strchr and atoi)
  1388.  * barf when the commented code below is used.
  1389. PRFileDesc *file;
  1390. */
  1391. FILE *file;
  1392. char filename[256];
  1393. char *mark, *param, *val;
  1394. int index = 0;
  1395. int len;
  1396. sprintf(filename, "%s/tests/%s/params%d", testdir, mode, num);
  1397. /*
  1398. file = PR_Open(filename, PR_RDONLY, 00440);
  1399. if (file)
  1400. SECU_FileToItem(item, file);
  1401. else
  1402. return;
  1403. param = (char *)item->data;
  1404. */
  1405. file = fopen(filename, "r");
  1406. if (!file) return;
  1407. param = malloc(100);
  1408. len = fread(param, 1, 100, file);
  1409. while (index < len) {
  1410. mark = PL_strchr(param, '=');
  1411. *mark = '';
  1412. val = mark + 1;
  1413. mark = PL_strchr(val, 'n');
  1414. *mark = '';
  1415. if (PL_strcmp(param, "rounds") == 0) {
  1416. info->rounds = atoi(val);
  1417. } else if (PL_strcmp(param, "wordsize") == 0) {
  1418. info->wordsize = atoi(val);
  1419. }
  1420. index += PL_strlen(param) + PL_strlen(val) + 2;
  1421. param = mark + 1;
  1422. }
  1423. }
  1424. static SECStatus
  1425. get_ascii_file_data(SECItem *item, char *mode, char *type, int num)
  1426. {
  1427. char filename[256];
  1428. PRFileDesc *file;
  1429. SECStatus rv;
  1430. sprintf(filename, "%s/tests/%s/%s%d", testdir, mode, type, num);
  1431. file = PR_Open(filename, PR_RDONLY, 00440);
  1432. if (!file) {
  1433. /* Not a failure if "mode" does not need "type". */
  1434. return SECSuccess;
  1435. }
  1436. if (((PL_strcmp(mode, "rsa") == 0 || PL_strcmp(mode, "dsa") == 0) && 
  1437.       PL_strcmp(type, "key") == 0) ||
  1438.    (PL_strcmp(mode, "dsa") == 0 && PL_strcmp(type, "plaintext") == 0)) {
  1439. rv = SECU_FileToItem(item, file);
  1440. atob(SECITEM_DupItem(item), item);
  1441. } else {
  1442. rv = SECU_TextFileToItem(item, file);
  1443. }
  1444. PR_Close(file);
  1445. return rv;
  1446. }
  1447. static SECStatus
  1448. blapi_selftest(char **modesToTest, int numModesToTest, 
  1449.                PRBool encrypt, PRBool decrypt)
  1450. {
  1451. blapitestCryptoFn cryptofn;
  1452. blapitestInfo info;
  1453. SECItem output = { 0, 0, 0 };
  1454. SECItem asciiOut = { 0, 0, 0 };
  1455. SECItem inpCopy = { 0, 0, 0 };
  1456. SECItem item = { 0, 0, 0 };
  1457. SECStatus rv;
  1458. char filename[256];
  1459. PRFileDesc *file;
  1460. char *mode;
  1461. int i, j, nummodes;
  1462. PORT_Memset(&info, 0, sizeof(info));
  1463. info.repetitions = 1;
  1464. info.useseed = PR_TRUE;
  1465. info.usesigseed = PR_TRUE;
  1466. if (modesToTest) {
  1467. /* user gave a list of modes to test */
  1468. nummodes = numModesToTest;
  1469. } else {
  1470. /* test all modes */
  1471. nummodes = sizeof(mode_strings) / sizeof(char *);
  1472. }
  1473. for (i=0; i<nummodes; i++) {
  1474. if (modesToTest) {
  1475. mode = modesToTest[i];
  1476. } else {
  1477. mode = mode_strings[i];
  1478. }
  1479. /* skip pqg - nothing to do for self-test. */
  1480. if (PL_strcmp(mode, "pqg") == 0)
  1481. continue;
  1482. cryptofn = get_test_mode(mode);
  1483. if (mode[0] == '#') continue;
  1484. /* get the number of tests in the directory */
  1485. sprintf(filename, "%s/tests/%s/%s", testdir, mode, "numtests");
  1486. file = PR_Open(filename, PR_RDONLY, 00440);
  1487. if (!file) {
  1488. fprintf(stderr, "File %s does not exist.n", filename);
  1489. return SECFailure;
  1490. }
  1491. memset(&item, 0, sizeof(item));
  1492. rv = SECU_FileToItem(&item, file);
  1493. PR_Close(file);
  1494. /* loop over the tests in the directory */
  1495. for (j=0; j<(int)(item.data[0] - '0'); j++) {
  1496. memset(&info.key, 0, sizeof(info.key));
  1497. memset(&info.iv, 0, sizeof(info.iv));
  1498. memset(&info.in, 0, sizeof(info.in));
  1499. memset(&info.seed, 0, sizeof(info.seed));
  1500. memset(&info.sigseed, 0, sizeof(info.sigseed));
  1501. rv = get_ascii_file_data(&info.key, mode, "key", j);
  1502. rv = get_ascii_file_data(&info.iv, mode, "iv", j);
  1503. rv = get_ascii_file_data(&info.in, mode, "plaintext", j);
  1504. #if 0
  1505. rv = get_ascii_file_data(&info.seed, mode, "keyseed", j);
  1506. #endif
  1507. rv = get_ascii_file_data(&info.sigseed, mode, "sigseed", j);
  1508. SECITEM_CopyItem(NULL, &inpCopy, &info.in);
  1509. get_params(&info, mode, j);
  1510. sprintf(filename, "%s/tests/%s/%s%d", testdir, mode, 
  1511.         "ciphertext", j);
  1512. file = PR_Open(filename, PR_RDONLY, 00440);
  1513. memset(&asciiOut, 0, sizeof(asciiOut));
  1514. rv = SECU_FileToItem(&asciiOut, file);
  1515. PR_Close(file);
  1516. rv = atob(&asciiOut, &output);
  1517. if (!encrypt) goto decrypt;
  1518. info.encrypt = info.hash = info.sign = PR_TRUE;
  1519. (*cryptofn)(&info);
  1520. if (SECITEM_CompareItem(&output, &info.out) != 0) {
  1521. printf("encrypt self-test for %s failed!n", mode);
  1522. } /*else {
  1523. printf("encrypt self-test for %s passed.n", mode);
  1524. }*/
  1525. decrypt:
  1526. if (!decrypt) continue;
  1527. if (PL_strcmp(mode, "md2") == 0 ||
  1528.     PL_strcmp(mode, "md5") == 0 ||
  1529.     PL_strcmp(mode, "sha1") == 0) {
  1530. continue; /* hashes only go once */
  1531. }
  1532. info.encrypt = info.hash = info.sign = PR_FALSE;
  1533. info.decrypt = info.verify = PR_TRUE;
  1534. if (PL_strcmp(mode, "dsa") == 0) {
  1535. if (info.out.len == 0)
  1536.     SECITEM_CopyItem(NULL, &info.out, &output);
  1537. rv = (*cryptofn)(&info);
  1538. if (rv != SECSuccess) {
  1539. printf("signature self-test for %s failed!n", mode);
  1540. } /*else {
  1541. printf("signature self-test for %s passed.n", mode);
  1542. }*/
  1543. } else {
  1544. SECITEM_ZfreeItem(&info.in, PR_FALSE);
  1545. SECITEM_ZfreeItem(&info.out, PR_FALSE);
  1546. SECITEM_CopyItem(NULL, &info.in, &output);
  1547. info.out.len = 0;
  1548. rv = (*cryptofn)(&info);
  1549. if (rv == SECSuccess) {
  1550. if (SECITEM_CompareItem(&inpCopy, &info.out) != 0) {
  1551. printf("decrypt self-test for %s failed!n", mode);
  1552. } /*else {
  1553. printf("decrypt self-test for %s passed.n", mode);
  1554. }*/
  1555. }
  1556. }
  1557. }
  1558. }
  1559. return SECSuccess;
  1560. }
  1561. static SECStatus
  1562. get_file_data(char *filename, SECItem *item, PRBool b64) 
  1563. {
  1564. SECStatus rv = SECSuccess;
  1565. PRFileDesc *file = PR_Open(filename, PR_RDONLY, 006600);
  1566. if (file) {
  1567. if (b64) {
  1568. SECItem asciiItem = { 0, 0, 0 };
  1569. rv = SECU_FileToItem(&asciiItem, file);
  1570. CHECKERROR(rv, __LINE__);
  1571. rv = atob(&asciiItem, item);
  1572. } else {
  1573. rv = SECU_FileToItem(item, file);
  1574. CHECKERROR(rv, __LINE__);
  1575. }
  1576. CHECKERROR(rv, __LINE__);
  1577. PR_Close(file);
  1578. }
  1579. return rv;
  1580. }
  1581. SECStatus
  1582. dump_file(char *mode, char *filename)
  1583. {
  1584. SECItem item;
  1585. if (PL_strcmp(mode, "rsa") == 0) {
  1586. } else if (PL_strcmp(mode, "pqg") == 0) {
  1587. PQGParams *pqg;
  1588. get_file_data(filename, &item, PR_TRUE);
  1589. pqg = pqg_from_filedata(&item);
  1590. dump_pqg(pqg);
  1591. } else if (PL_strcmp(mode, "dsa") == 0) {
  1592. DSAPrivateKey *key;
  1593. get_file_data(filename, &item, PR_TRUE);
  1594. key = dsakey_from_filedata(&item);
  1595. dump_dsakey(key);
  1596. }
  1597. return SECFailure;
  1598. }
  1599. int main(int argc, char **argv) 
  1600. {
  1601. char *infile, *outfile, *keyfile, *ivfile, *sigfile, *seedfile,
  1602.      *sigseedfile, *pqgfile;
  1603. PRBool b64 = PR_TRUE;
  1604. blapitestInfo info;
  1605. blapitestCryptoFn cryptofn = NULL;
  1606. PLOptState *optstate;
  1607. PLOptStatus status;
  1608. PRBool dofips = PR_FALSE;
  1609. PRBool doselftest = PR_FALSE;
  1610. PRBool zerobuffer = PR_FALSE;
  1611. char *dumpfile = NULL;
  1612. char *mode = NULL;
  1613. char *modesToTest[20];
  1614. int numModesToTest = 0;
  1615. SECStatus rv;
  1616. PORT_Memset(&info, 0, sizeof(info));
  1617. info.bufsize = 8;
  1618. info.keysize = DES_KEY_LENGTH;
  1619. info.rsapubexp = 17;
  1620. info.rounds = 10;
  1621. info.wordsize = 4;
  1622. infile=outfile=keyfile=pqgfile=ivfile=sigfile=seedfile=sigseedfile=NULL;
  1623. info.repetitions = 1;
  1624.     progName = strrchr(argv[0], '/');
  1625.     progName = progName ? progName+1 : argv[0];
  1626. optstate = PL_CreateOptState(argc, argv, 
  1627.     "DEFHP:STVab:d:ce:g:j:i:o:p:k:m:t:qr:s:v:w:xyz:");
  1628. while ((status = PL_GetNextOpt(optstate)) == PL_OPT_OK) {
  1629. switch (optstate->option) {
  1630. case 'D':  info.decrypt = PR_TRUE; break;
  1631. case 'E':  info.encrypt = PR_TRUE; break;
  1632. case 'F':  dofips = PR_TRUE; break;
  1633. case 'H':  info.hash = PR_TRUE; break;
  1634. case 'P':  dumpfile = PL_strdup(optstate->value); break;
  1635. case 'S':  info.sign = PR_TRUE; break;
  1636. case 'T':  doselftest = PR_TRUE; break;
  1637. case 'V':  info.verify = PR_TRUE; break;
  1638. case 'a':  b64 = PR_FALSE; break;
  1639. case 'b':  info.bufsize = PORT_Atoi(optstate->value); break;
  1640. case 'c':  info.multihash = PR_TRUE; break;
  1641. case 'd':  testdir = PL_strdup(optstate->value); break;
  1642. case 'e':  info.rsapubexp = PORT_Atoi(optstate->value); break;
  1643. case 'g':  info.keysize = PORT_Atoi(optstate->value); break;
  1644. case 'i':  infile  = PL_strdup(optstate->value); break;
  1645. case 'j':  pqgfile = PL_strdup(optstate->value); break;
  1646. case 'k':  keyfile = PL_strdup(optstate->value); break;
  1647. case 'm':  cryptofn = get_test_mode(optstate->value);
  1648.            mode = PL_strdup(optstate->value); 
  1649.            break;
  1650. case 'o':  outfile = PL_strdup(optstate->value); break;
  1651. case 'p':  info.performance = PR_TRUE; 
  1652.    info.repetitions = PORT_Atoi(optstate->value); 
  1653.    break;
  1654. case 'q':  zerobuffer = PR_TRUE; break;
  1655. case 'r':  info.rounds = PORT_Atoi(optstate->value); break;
  1656. case 's':  sigfile  = PL_strdup(optstate->value); break;
  1657. case 't':  sigseedfile = PL_strdup(optstate->value); break;
  1658. case 'v':  ivfile  = PL_strdup(optstate->value); break;
  1659. case 'w':  info.wordsize = PORT_Atoi(optstate->value); break;
  1660. case 'x':  info.useseed = PR_TRUE; break;
  1661. case 'y':  info.usesigseed = PR_TRUE; break;
  1662. case 'z':  seedfile  = PL_strdup(optstate->value); break;
  1663. case '': if (optstate->value[0] != '-')
  1664.    modesToTest[numModesToTest++] = 
  1665. PL_strdup(optstate->value);
  1666.    break;
  1667. default: break;
  1668. }
  1669. }
  1670. if (dumpfile)
  1671. return dump_file(mode, dumpfile);
  1672. if (doselftest) {
  1673. if (!info.encrypt && !info.decrypt) {
  1674. info.encrypt = info.decrypt = PR_TRUE;  /* do both */
  1675. }
  1676. if (numModesToTest > 0) {
  1677. return blapi_selftest(modesToTest, numModesToTest,
  1678.                       info.encrypt, info.decrypt);
  1679. } else {
  1680. return blapi_selftest(NULL, 0, info.encrypt, info.decrypt);
  1681. }
  1682. }
  1683. if (dofips) {
  1684. CK_RV foo = pk11_fipsPowerUpSelfTest();
  1685. PR_fprintf(PR_STDOUT, "CK_RV: %d.n", foo);
  1686. return 0;
  1687. }
  1688. if (!info.encrypt && !info.decrypt && !info.hash && 
  1689.     !info.sign && !info.verify)
  1690. Usage();
  1691. if (!cryptofn) {
  1692. printmodes(&info);
  1693. return -1;
  1694. }
  1695. if (info.decrypt && !infile)
  1696. Usage();
  1697. if (info.performance) {
  1698. char buf[256];
  1699. PRStatus stat;
  1700. stat = PR_GetSystemInfo(PR_SI_HOSTNAME, buf, sizeof(buf));
  1701. printf("HOST: %sn", buf);
  1702. stat = PR_GetSystemInfo(PR_SI_SYSNAME, buf, sizeof(buf));
  1703. printf("SYSTEM: %sn", buf);
  1704. stat = PR_GetSystemInfo(PR_SI_RELEASE, buf, sizeof(buf));
  1705. printf("RELEASE: %sn", buf);
  1706. stat = PR_GetSystemInfo(PR_SI_ARCHITECTURE, buf, sizeof(buf));
  1707. printf("ARCH: %sn", buf);
  1708. }
  1709. RNG_RNGInit();
  1710. RNG_SystemInfoForRNG();
  1711. if (keyfile) {
  1712. /* RSA and DSA keys are always b64 encoded. */
  1713. if (b64 || PL_strcmp(mode,"rsa")==0 || PL_strcmp(mode,"dsa")==0)
  1714. get_file_data(keyfile, &info.key, PR_TRUE);
  1715. else
  1716. get_file_data(keyfile, &info.key, b64);
  1717. }
  1718. if (ivfile)
  1719. get_file_data(ivfile, &info.iv, b64);
  1720. if (infile)
  1721. get_file_data(infile, &info.in, b64);
  1722. if (sigfile)
  1723. get_file_data(sigfile, &info.out, PR_TRUE);
  1724. if (seedfile) {
  1725. get_file_data(seedfile, &info.seed, b64);
  1726. info.useseed = PR_TRUE;
  1727. }
  1728. if (sigseedfile) {
  1729. get_file_data(sigseedfile, &info.sigseed, b64);
  1730. info.usesigseed = PR_TRUE;
  1731. }
  1732. if (pqgfile)
  1733. get_file_data(pqgfile, &info.pqg, PR_TRUE);
  1734. if (zerobuffer) {
  1735. PRFileDesc *ifile;
  1736. info.in.len = info.bufsize;
  1737. info.in.data = PORT_ZAlloc(info.in.len);
  1738. ifile = PR_Open("tmp.pt", PR_WRONLY|PR_CREATE_FILE, 00660);
  1739. rv = btoa_file(&info.in, ifile);
  1740. CHECKERROR((rv < 0), __LINE__);
  1741. PR_Close(ifile);
  1742. }
  1743. rv = (*cryptofn)(&info);
  1744. CHECKERROR(rv, __LINE__);
  1745. if (!sigfile && info.out.len > 0) {
  1746. PRFileDesc *ofile;
  1747. if (!outfile)
  1748. ofile = PR_Open("tmp.out", PR_WRONLY|PR_CREATE_FILE, 00660);
  1749. else
  1750. ofile = PR_Open(outfile, PR_WRONLY|PR_CREATE_FILE, 00660);
  1751. rv = btoa_file(&info.out, ofile);
  1752. PR_Close(ofile);
  1753. CHECKERROR((rv < 0), __LINE__);
  1754. }
  1755. RNG_RNGShutdown();
  1756. return SECSuccess;
  1757. }