PageRenderTime 93ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 0ms

/security/nss/cmd/fipstest/fipstest.c

http://github.com/zpao/v8monkey
C | 5071 lines | 3945 code | 380 blank | 746 comment | 1501 complexity | 8a4f52b3f88f2fb370afaaa2e856fe85 MD5 | raw file
Possible License(s): MPL-2.0-no-copyleft-exception, LGPL-3.0, AGPL-1.0, LGPL-2.1, BSD-3-Clause, GPL-2.0, JSON, Apache-2.0, 0BSD
  1. /* ***** BEGIN LICENSE BLOCK *****
  2. * Version: MPL 1.1/GPL 2.0/LGPL 2.1
  3. *
  4. * The contents of this file are subject to the Mozilla Public License Version
  5. * 1.1 (the "License"); you may not use this file except in compliance with
  6. * the License. You may obtain a copy of the License at
  7. * http://www.mozilla.org/MPL/
  8. *
  9. * Software distributed under the License is distributed on an "AS IS" basis,
  10. * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
  11. * for the specific language governing rights and limitations under the
  12. * License.
  13. *
  14. * The Original Code is the Netscape security libraries.
  15. *
  16. * The Initial Developer of the Original Code is
  17. * Netscape Communications Corporation.
  18. * Portions created by the Initial Developer are Copyright (C) 1994-2000
  19. * the Initial Developer. All Rights Reserved.
  20. *
  21. * Contributor(s):
  22. *
  23. * Alternatively, the contents of this file may be used under the terms of
  24. * either the GNU General Public License Version 2 or later (the "GPL"), or
  25. * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
  26. * in which case the provisions of the GPL or the LGPL are applicable instead
  27. * of those above. If you wish to allow use of your version of this file only
  28. * under the terms of either the GPL or the LGPL, and not to allow others to
  29. * use your version of this file under the terms of the MPL, indicate your
  30. * decision by deleting the provisions above and replace them with the notice
  31. * and other provisions required by the GPL or the LGPL. If you do not delete
  32. * the provisions above, a recipient may use your version of this file under
  33. * the terms of any one of the MPL, the GPL or the LGPL.
  34. *
  35. * ***** END LICENSE BLOCK ***** */
  36. #include <stdio.h>
  37. #include <stdlib.h>
  38. #include <ctype.h>
  39. #include "secitem.h"
  40. #include "blapi.h"
  41. #include "nssutil.h"
  42. #include "secerr.h"
  43. #include "secder.h"
  44. #include "secdig.h"
  45. #include "secoid.h"
  46. #include "ec.h"
  47. #include "hasht.h"
  48. #include "lowkeyi.h"
  49. #include "softoken.h"
  50. #if 0
  51. #include "../../lib/freebl/mpi/mpi.h"
  52. #endif
  53. #ifdef NSS_ENABLE_ECC
  54. extern SECStatus
  55. EC_DecodeParams(const SECItem *encodedParams, ECParams **ecparams);
  56. extern SECStatus
  57. EC_CopyParams(PRArenaPool *arena, ECParams *dstParams,
  58. const ECParams *srcParams);
  59. #endif
  60. #define ENCRYPT 1
  61. #define DECRYPT 0
  62. #define BYTE unsigned char
  63. #define DEFAULT_RSA_PUBLIC_EXPONENT 0x10001
  64. #define RSA_MAX_TEST_MODULUS_BITS 4096
  65. #define RSA_MAX_TEST_MODULUS_BYTES RSA_MAX_TEST_MODULUS_BITS/8
  66. #define RSA_MAX_TEST_EXPONENT_BYTES 8
  67. #define PQG_TEST_SEED_BYTES 20
  68. SECStatus
  69. hex_to_byteval(const char *c2, unsigned char *byteval)
  70. {
  71. int i;
  72. unsigned char offset;
  73. *byteval = 0;
  74. for (i=0; i<2; i++) {
  75. if (c2[i] >= '0' && c2[i] <= '9') {
  76. offset = c2[i] - '0';
  77. *byteval |= offset << 4*(1-i);
  78. } else if (c2[i] >= 'a' && c2[i] <= 'f') {
  79. offset = c2[i] - 'a';
  80. *byteval |= (offset + 10) << 4*(1-i);
  81. } else if (c2[i] >= 'A' && c2[i] <= 'F') {
  82. offset = c2[i] - 'A';
  83. *byteval |= (offset + 10) << 4*(1-i);
  84. } else {
  85. return SECFailure;
  86. }
  87. }
  88. return SECSuccess;
  89. }
  90. SECStatus
  91. byteval_to_hex(unsigned char byteval, char *c2, char a)
  92. {
  93. int i;
  94. unsigned char offset;
  95. for (i=0; i<2; i++) {
  96. offset = (byteval >> 4*(1-i)) & 0x0f;
  97. if (offset < 10) {
  98. c2[i] = '0' + offset;
  99. } else {
  100. c2[i] = a + offset - 10;
  101. }
  102. }
  103. return SECSuccess;
  104. }
  105. void
  106. to_hex_str(char *str, const unsigned char *buf, unsigned int len)
  107. {
  108. unsigned int i;
  109. for (i=0; i<len; i++) {
  110. byteval_to_hex(buf[i], &str[2*i], 'a');
  111. }
  112. str[2*len] = '\0';
  113. }
  114. void
  115. to_hex_str_cap(char *str, const unsigned char *buf, unsigned int len)
  116. {
  117. unsigned int i;
  118. for (i=0; i<len; i++) {
  119. byteval_to_hex(buf[i], &str[2*i], 'A');
  120. }
  121. str[2*len] = '\0';
  122. }
  123. /*
  124. * Convert a string of hex digits (str) to an array (buf) of len bytes.
  125. * Return PR_TRUE if the hex string can fit in the byte array. Return
  126. * PR_FALSE if the hex string is empty or is too long.
  127. */
  128. PRBool
  129. from_hex_str(unsigned char *buf, unsigned int len, const char *str)
  130. {
  131. unsigned int nxdigit; /* number of hex digits in str */
  132. unsigned int i; /* index into buf */
  133. unsigned int j; /* index into str */
  134. /* count the hex digits */
  135. nxdigit = 0;
  136. for (nxdigit = 0; isxdigit(str[nxdigit]); nxdigit++) {
  137. /* empty body */
  138. }
  139. if (nxdigit == 0) {
  140. return PR_FALSE;
  141. }
  142. if (nxdigit > 2*len) {
  143. /*
  144. * The input hex string is too long, but we allow it if the
  145. * extra digits are leading 0's.
  146. */
  147. for (j = 0; j < nxdigit-2*len; j++) {
  148. if (str[j] != '0') {
  149. return PR_FALSE;
  150. }
  151. }
  152. /* skip leading 0's */
  153. str += nxdigit-2*len;
  154. nxdigit = 2*len;
  155. }
  156. for (i=0, j=0; i< len; i++) {
  157. if (2*i < 2*len-nxdigit) {
  158. /* Handle a short input as if we padded it with leading 0's. */
  159. if (2*i+1 < 2*len-nxdigit) {
  160. buf[i] = 0;
  161. } else {
  162. char tmp[2];
  163. tmp[0] = '0';
  164. tmp[1] = str[j];
  165. hex_to_byteval(tmp, &buf[i]);
  166. j++;
  167. }
  168. } else {
  169. hex_to_byteval(&str[j], &buf[i]);
  170. j += 2;
  171. }
  172. }
  173. return PR_TRUE;
  174. }
  175. SECStatus
  176. tdea_encrypt_buf(
  177. int mode,
  178. const unsigned char *key,
  179. const unsigned char *iv,
  180. unsigned char *output, unsigned int *outputlen, unsigned int maxoutputlen,
  181. const unsigned char *input, unsigned int inputlen)
  182. {
  183. SECStatus rv = SECFailure;
  184. DESContext *cx;
  185. unsigned char doublecheck[8*20]; /* 1 to 20 blocks */
  186. unsigned int doublechecklen = 0;
  187. cx = DES_CreateContext(key, iv, mode, PR_TRUE);
  188. if (cx == NULL) {
  189. goto loser;
  190. }
  191. rv = DES_Encrypt(cx, output, outputlen, maxoutputlen, input, inputlen);
  192. if (rv != SECSuccess) {
  193. goto loser;
  194. }
  195. if (*outputlen != inputlen) {
  196. goto loser;
  197. }
  198. DES_DestroyContext(cx, PR_TRUE);
  199. cx = NULL;
  200. /*
  201. * Doublecheck our result by decrypting the ciphertext and
  202. * compare the output with the input plaintext.
  203. */
  204. cx = DES_CreateContext(key, iv, mode, PR_FALSE);
  205. if (cx == NULL) {
  206. goto loser;
  207. }
  208. rv = DES_Decrypt(cx, doublecheck, &doublechecklen, sizeof doublecheck,
  209. output, *outputlen);
  210. if (rv != SECSuccess) {
  211. goto loser;
  212. }
  213. if (doublechecklen != *outputlen) {
  214. goto loser;
  215. }
  216. DES_DestroyContext(cx, PR_TRUE);
  217. cx = NULL;
  218. if (memcmp(doublecheck, input, inputlen) != 0) {
  219. goto loser;
  220. }
  221. rv = SECSuccess;
  222. loser:
  223. if (cx != NULL) {
  224. DES_DestroyContext(cx, PR_TRUE);
  225. }
  226. return rv;
  227. }
  228. SECStatus
  229. tdea_decrypt_buf(
  230. int mode,
  231. const unsigned char *key,
  232. const unsigned char *iv,
  233. unsigned char *output, unsigned int *outputlen, unsigned int maxoutputlen,
  234. const unsigned char *input, unsigned int inputlen)
  235. {
  236. SECStatus rv = SECFailure;
  237. DESContext *cx;
  238. unsigned char doublecheck[8*20]; /* 1 to 20 blocks */
  239. unsigned int doublechecklen = 0;
  240. cx = DES_CreateContext(key, iv, mode, PR_FALSE);
  241. if (cx == NULL) {
  242. goto loser;
  243. }
  244. rv = DES_Decrypt(cx, output, outputlen, maxoutputlen,
  245. input, inputlen);
  246. if (rv != SECSuccess) {
  247. goto loser;
  248. }
  249. if (*outputlen != inputlen) {
  250. goto loser;
  251. }
  252. DES_DestroyContext(cx, PR_TRUE);
  253. cx = NULL;
  254. /*
  255. * Doublecheck our result by encrypting the plaintext and
  256. * compare the output with the input ciphertext.
  257. */
  258. cx = DES_CreateContext(key, iv, mode, PR_TRUE);
  259. if (cx == NULL) {
  260. goto loser;
  261. }
  262. rv = DES_Encrypt(cx, doublecheck, &doublechecklen, sizeof doublecheck,
  263. output, *outputlen);
  264. if (rv != SECSuccess) {
  265. goto loser;
  266. }
  267. if (doublechecklen != *outputlen) {
  268. goto loser;
  269. }
  270. DES_DestroyContext(cx, PR_TRUE);
  271. cx = NULL;
  272. if (memcmp(doublecheck, input, inputlen) != 0) {
  273. goto loser;
  274. }
  275. rv = SECSuccess;
  276. loser:
  277. if (cx != NULL) {
  278. DES_DestroyContext(cx, PR_TRUE);
  279. }
  280. return rv;
  281. }
  282. /*
  283. * Perform the TDEA Known Answer Test (KAT) or Multi-block Message
  284. * Test (MMT) in ECB or CBC mode. The KAT (there are five types)
  285. * and MMT have the same structure: given the key and IV (CBC mode
  286. * only), encrypt the given plaintext or decrypt the given ciphertext.
  287. * So we can handle them the same way.
  288. *
  289. * reqfn is the pathname of the REQUEST file.
  290. *
  291. * The output RESPONSE file is written to stdout.
  292. */
  293. void
  294. tdea_kat_mmt(char *reqfn)
  295. {
  296. char buf[180]; /* holds one line from the input REQUEST file.
  297. * needs to be large enough to hold the longest
  298. * line "CIPHERTEXT = <180 hex digits>\n".
  299. */
  300. FILE *req; /* input stream from the REQUEST file */
  301. FILE *resp; /* output stream to the RESPONSE file */
  302. int i, j;
  303. int mode; /* NSS_DES_EDE3 (ECB) or NSS_DES_EDE3_CBC */
  304. int crypt = DECRYPT; /* 1 means encrypt, 0 means decrypt */
  305. unsigned char key[24]; /* TDEA 3 key bundle */
  306. unsigned int numKeys = 0;
  307. unsigned char iv[8]; /* for all modes except ECB */
  308. unsigned char plaintext[8*20]; /* 1 to 20 blocks */
  309. unsigned int plaintextlen;
  310. unsigned char ciphertext[8*20]; /* 1 to 20 blocks */
  311. unsigned int ciphertextlen;
  312. SECStatus rv;
  313. req = fopen(reqfn, "r");
  314. resp = stdout;
  315. while (fgets(buf, sizeof buf, req) != NULL) {
  316. /* a comment or blank line */
  317. if (buf[0] == '#' || buf[0] == '\n') {
  318. fputs(buf, resp);
  319. continue;
  320. }
  321. /* [ENCRYPT] or [DECRYPT] */
  322. if (buf[0] == '[') {
  323. if (strncmp(&buf[1], "ENCRYPT", 7) == 0) {
  324. crypt = ENCRYPT;
  325. } else {
  326. crypt = DECRYPT;
  327. }
  328. fputs(buf, resp);
  329. continue;
  330. }
  331. /* NumKeys */
  332. if (strncmp(&buf[0], "NumKeys", 7) == 0) {
  333. i = 7;
  334. while (isspace(buf[i]) || buf[i] == '=') {
  335. i++;
  336. }
  337. numKeys = buf[i];
  338. fputs(buf, resp);
  339. continue;
  340. }
  341. /* "COUNT = x" begins a new data set */
  342. if (strncmp(buf, "COUNT", 5) == 0) {
  343. /* mode defaults to ECB, if dataset has IV mode will be set CBC */
  344. mode = NSS_DES_EDE3;
  345. /* zeroize the variables for the test with this data set */
  346. memset(key, 0, sizeof key);
  347. memset(iv, 0, sizeof iv);
  348. memset(plaintext, 0, sizeof plaintext);
  349. plaintextlen = 0;
  350. memset(ciphertext, 0, sizeof ciphertext);
  351. ciphertextlen = 0;
  352. fputs(buf, resp);
  353. continue;
  354. }
  355. if (numKeys == 0) {
  356. if (strncmp(buf, "KEYs", 4) == 0) {
  357. i = 4;
  358. while (isspace(buf[i]) || buf[i] == '=') {
  359. i++;
  360. }
  361. for (j=0; isxdigit(buf[i]); i+=2,j++) {
  362. hex_to_byteval(&buf[i], &key[j]);
  363. key[j+8] = key[j];
  364. key[j+16] = key[j];
  365. }
  366. fputs(buf, resp);
  367. continue;
  368. }
  369. } else {
  370. /* KEY1 = ... */
  371. if (strncmp(buf, "KEY1", 4) == 0) {
  372. i = 4;
  373. while (isspace(buf[i]) || buf[i] == '=') {
  374. i++;
  375. }
  376. for (j=0; isxdigit(buf[i]); i+=2,j++) {
  377. hex_to_byteval(&buf[i], &key[j]);
  378. }
  379. fputs(buf, resp);
  380. continue;
  381. }
  382. /* KEY2 = ... */
  383. if (strncmp(buf, "KEY2", 4) == 0) {
  384. i = 4;
  385. while (isspace(buf[i]) || buf[i] == '=') {
  386. i++;
  387. }
  388. for (j=8; isxdigit(buf[i]); i+=2,j++) {
  389. hex_to_byteval(&buf[i], &key[j]);
  390. }
  391. fputs(buf, resp);
  392. continue;
  393. }
  394. /* KEY3 = ... */
  395. if (strncmp(buf, "KEY3", 4) == 0) {
  396. i = 4;
  397. while (isspace(buf[i]) || buf[i] == '=') {
  398. i++;
  399. }
  400. for (j=16; isxdigit(buf[i]); i+=2,j++) {
  401. hex_to_byteval(&buf[i], &key[j]);
  402. }
  403. fputs(buf, resp);
  404. continue;
  405. }
  406. }
  407. /* IV = ... */
  408. if (strncmp(buf, "IV", 2) == 0) {
  409. mode = NSS_DES_EDE3_CBC;
  410. i = 2;
  411. while (isspace(buf[i]) || buf[i] == '=') {
  412. i++;
  413. }
  414. for (j=0; j<sizeof iv; i+=2,j++) {
  415. hex_to_byteval(&buf[i], &iv[j]);
  416. }
  417. fputs(buf, resp);
  418. continue;
  419. }
  420. /* PLAINTEXT = ... */
  421. if (strncmp(buf, "PLAINTEXT", 9) == 0) {
  422. /* sanity check */
  423. if (crypt != ENCRYPT) {
  424. goto loser;
  425. }
  426. i = 9;
  427. while (isspace(buf[i]) || buf[i] == '=') {
  428. i++;
  429. }
  430. for (j=0; isxdigit(buf[i]); i+=2,j++) {
  431. hex_to_byteval(&buf[i], &plaintext[j]);
  432. }
  433. plaintextlen = j;
  434. rv = tdea_encrypt_buf(mode, key,
  435. (mode == NSS_DES_EDE3) ? NULL : iv,
  436. ciphertext, &ciphertextlen, sizeof ciphertext,
  437. plaintext, plaintextlen);
  438. if (rv != SECSuccess) {
  439. goto loser;
  440. }
  441. fputs(buf, resp);
  442. fputs("CIPHERTEXT = ", resp);
  443. to_hex_str(buf, ciphertext, ciphertextlen);
  444. fputs(buf, resp);
  445. fputc('\n', resp);
  446. continue;
  447. }
  448. /* CIPHERTEXT = ... */
  449. if (strncmp(buf, "CIPHERTEXT", 10) == 0) {
  450. /* sanity check */
  451. if (crypt != DECRYPT) {
  452. goto loser;
  453. }
  454. i = 10;
  455. while (isspace(buf[i]) || buf[i] == '=') {
  456. i++;
  457. }
  458. for (j=0; isxdigit(buf[i]); i+=2,j++) {
  459. hex_to_byteval(&buf[i], &ciphertext[j]);
  460. }
  461. ciphertextlen = j;
  462. rv = tdea_decrypt_buf(mode, key,
  463. (mode == NSS_DES_EDE3) ? NULL : iv,
  464. plaintext, &plaintextlen, sizeof plaintext,
  465. ciphertext, ciphertextlen);
  466. if (rv != SECSuccess) {
  467. goto loser;
  468. }
  469. fputs(buf, resp);
  470. fputs("PLAINTEXT = ", resp);
  471. to_hex_str(buf, plaintext, plaintextlen);
  472. fputs(buf, resp);
  473. fputc('\n', resp);
  474. continue;
  475. }
  476. }
  477. loser:
  478. fclose(req);
  479. }
  480. /*
  481. * Set the parity bit for the given byte
  482. */
  483. BYTE odd_parity( BYTE in)
  484. {
  485. BYTE out = in;
  486. in ^= in >> 4;
  487. in ^= in >> 2;
  488. in ^= in >> 1;
  489. return (BYTE)(out ^ !(in & 1));
  490. }
  491. /*
  492. * Generate Keys [i+1] from Key[i], PT/CT[j-2], PT/CT[j-1], and PT/CT[j]
  493. * for TDEA Monte Carlo Test (MCT) in ECB and CBC modes.
  494. */
  495. void
  496. tdea_mct_next_keys(unsigned char *key,
  497. const unsigned char *text_2, const unsigned char *text_1,
  498. const unsigned char *text, unsigned int numKeys)
  499. {
  500. int k;
  501. /* key1[i+1] = key1[i] xor PT/CT[j] */
  502. for (k=0; k<8; k++) {
  503. key[k] ^= text[k];
  504. }
  505. /* key2 */
  506. if (numKeys == 2 || numKeys == 3) {
  507. /* key2 independent */
  508. for (k=8; k<16; k++) {
  509. /* key2[i+1] = KEY2[i] xor PT/CT[j-1] */
  510. key[k] ^= text_1[k-8];
  511. }
  512. } else {
  513. /* key2 == key 1 */
  514. for (k=8; k<16; k++) {
  515. /* key2[i+1] = KEY2[i] xor PT/CT[j] */
  516. key[k] = key[k-8];
  517. }
  518. }
  519. /* key3 */
  520. if (numKeys == 1 || numKeys == 2) {
  521. /* key3 == key 1 */
  522. for (k=16; k<24; k++) {
  523. /* key3[i+1] = KEY3[i] xor PT/CT[j] */
  524. key[k] = key[k-16];
  525. }
  526. } else {
  527. /* key3 independent */
  528. for (k=16; k<24; k++) {
  529. /* key3[i+1] = KEY3[i] xor PT/CT[j-2] */
  530. key[k] ^= text_2[k-16];
  531. }
  532. }
  533. /* set the parity bits */
  534. for (k=0; k<24; k++) {
  535. key[k] = odd_parity(key[k]);
  536. }
  537. }
  538. /*
  539. * Perform the Monte Carlo Test
  540. *
  541. * mode = NSS_DES_EDE3 or NSS_DES_EDE3_CBC
  542. * crypt = ENCRYPT || DECRYPT
  543. * inputtext = plaintext or Cyphertext depending on the value of crypt
  544. * inputlength is expected to be size 8 bytes
  545. * iv = needs to be set for NSS_DES_EDE3_CBC mode
  546. * resp = is the output response file.
  547. */
  548. void
  549. tdea_mct_test(int mode, unsigned char* key, unsigned int numKeys,
  550. unsigned int crypt, unsigned char* inputtext,
  551. unsigned int inputlength, unsigned char* iv, FILE *resp) {
  552. int i, j;
  553. unsigned char outputtext_1[8]; /* PT/CT[j-1] */
  554. unsigned char outputtext_2[8]; /* PT/CT[j-2] */
  555. char buf[80]; /* holds one line from the input REQUEST file. */
  556. unsigned int outputlen;
  557. unsigned char outputtext[8];
  558. SECStatus rv;
  559. if (mode == NSS_DES_EDE3 && iv != NULL) {
  560. printf("IV must be NULL for NSS_DES_EDE3 mode");
  561. goto loser;
  562. } else if (mode == NSS_DES_EDE3_CBC && iv == NULL) {
  563. printf("IV must not be NULL for NSS_DES_EDE3_CBC mode");
  564. goto loser;
  565. }
  566. /* loop 400 times */
  567. for (i=0; i<400; i++) {
  568. /* if i == 0 CV[0] = IV not necessary */
  569. /* record the count and key values and plainText */
  570. sprintf(buf, "COUNT = %d\n", i);
  571. fputs(buf, resp);
  572. /* Output KEY1[i] */
  573. fputs("KEY1 = ", resp);
  574. to_hex_str(buf, key, 8);
  575. fputs(buf, resp);
  576. fputc('\n', resp);
  577. /* Output KEY2[i] */
  578. fputs("KEY2 = ", resp);
  579. to_hex_str(buf, &key[8], 8);
  580. fputs(buf, resp);
  581. fputc('\n', resp);
  582. /* Output KEY3[i] */
  583. fputs("KEY3 = ", resp);
  584. to_hex_str(buf, &key[16], 8);
  585. fputs(buf, resp);
  586. fputc('\n', resp);
  587. if (mode == NSS_DES_EDE3_CBC) {
  588. /* Output CV[i] */
  589. fputs("IV = ", resp);
  590. to_hex_str(buf, iv, 8);
  591. fputs(buf, resp);
  592. fputc('\n', resp);
  593. }
  594. if (crypt == ENCRYPT) {
  595. /* Output PT[0] */
  596. fputs("PLAINTEXT = ", resp);
  597. } else {
  598. /* Output CT[0] */
  599. fputs("CIPHERTEXT = ", resp);
  600. }
  601. to_hex_str(buf, inputtext, inputlength);
  602. fputs(buf, resp);
  603. fputc('\n', resp);
  604. /* loop 10,000 times */
  605. for (j=0; j<10000; j++) {
  606. outputlen = 0;
  607. if (crypt == ENCRYPT) {
  608. /* inputtext == ciphertext outputtext == plaintext*/
  609. rv = tdea_encrypt_buf(mode, key,
  610. (mode == NSS_DES_EDE3) ? NULL : iv,
  611. outputtext, &outputlen, 8,
  612. inputtext, 8);
  613. } else {
  614. /* inputtext == plaintext outputtext == ciphertext */
  615. rv = tdea_decrypt_buf(mode, key,
  616. (mode == NSS_DES_EDE3) ? NULL : iv,
  617. outputtext, &outputlen, 8,
  618. inputtext, 8);
  619. }
  620. if (rv != SECSuccess) {
  621. goto loser;
  622. }
  623. if (outputlen != inputlength) {
  624. goto loser;
  625. }
  626. if (mode == NSS_DES_EDE3_CBC) {
  627. if (crypt == ENCRYPT) {
  628. if (j == 0) {
  629. /*P[j+1] = CV[0] */
  630. memcpy(inputtext, iv, 8);
  631. } else {
  632. /* p[j+1] = C[j-1] */
  633. memcpy(inputtext, outputtext_1, 8);
  634. }
  635. /* CV[j+1] = C[j] */
  636. memcpy(iv, outputtext, 8);
  637. if (j != 9999) {
  638. /* save C[j-1] */
  639. memcpy(outputtext_1, outputtext, 8);
  640. }
  641. } else { /* DECRYPT */
  642. /* CV[j+1] = C[j] */
  643. memcpy(iv, inputtext, 8);
  644. /* C[j+1] = P[j] */
  645. memcpy(inputtext, outputtext, 8);
  646. }
  647. } else {
  648. /* ECB mode PT/CT[j+1] = CT/PT[j] */
  649. memcpy(inputtext, outputtext, 8);
  650. }
  651. /* Save PT/CT[j-2] and PT/CT[j-1] */
  652. if (j==9997) memcpy(outputtext_2, outputtext, 8);
  653. if (j==9998) memcpy(outputtext_1, outputtext, 8);
  654. /* done at the end of the for(j) loop */
  655. }
  656. if (crypt == ENCRYPT) {
  657. /* Output CT[j] */
  658. fputs("CIPHERTEXT = ", resp);
  659. } else {
  660. /* Output PT[j] */
  661. fputs("PLAINTEXT = ", resp);
  662. }
  663. to_hex_str(buf, outputtext, 8);
  664. fputs(buf, resp);
  665. fputc('\n', resp);
  666. /* Key[i+1] = Key[i] xor ... outputtext_2 == PT/CT[j-2]
  667. * outputtext_1 == PT/CT[j-1] outputtext == PT/CT[j]
  668. */
  669. tdea_mct_next_keys(key, outputtext_2,
  670. outputtext_1, outputtext, numKeys);
  671. if (mode == NSS_DES_EDE3_CBC) {
  672. /* taken care of in the j=9999 iteration */
  673. if (crypt == ENCRYPT) {
  674. /* P[i] = C[j-1] */
  675. /* CV[i] = C[j] */
  676. } else {
  677. /* taken care of in the j=9999 iteration */
  678. /* CV[i] = C[j] */
  679. /* C[i] = P[j] */
  680. }
  681. } else {
  682. /* ECB PT/CT[i] = PT/CT[j] */
  683. memcpy(inputtext, outputtext, 8);
  684. }
  685. /* done at the end of the for(i) loop */
  686. fputc('\n', resp);
  687. }
  688. loser:
  689. return;
  690. }
  691. /*
  692. * Perform the TDEA Monte Carlo Test (MCT) in ECB/CBC modes.
  693. * by gathering the input from the request file, and then
  694. * calling tdea_mct_test.
  695. *
  696. * reqfn is the pathname of the input REQUEST file.
  697. *
  698. * The output RESPONSE file is written to stdout.
  699. */
  700. void
  701. tdea_mct(int mode, char *reqfn)
  702. {
  703. int i, j;
  704. char buf[80]; /* holds one line from the input REQUEST file. */
  705. FILE *req; /* input stream from the REQUEST file */
  706. FILE *resp; /* output stream to the RESPONSE file */
  707. unsigned int crypt = 0; /* 1 means encrypt, 0 means decrypt */
  708. unsigned char key[24]; /* TDEA 3 key bundle */
  709. unsigned int numKeys = 0;
  710. unsigned char plaintext[8]; /* PT[j] */
  711. unsigned char ciphertext[8]; /* CT[j] */
  712. unsigned char iv[8];
  713. /* zeroize the variables for the test with this data set */
  714. memset(key, 0, sizeof key);
  715. memset(plaintext, 0, sizeof plaintext);
  716. memset(ciphertext, 0, sizeof ciphertext);
  717. memset(iv, 0, sizeof iv);
  718. req = fopen(reqfn, "r");
  719. resp = stdout;
  720. while (fgets(buf, sizeof buf, req) != NULL) {
  721. /* a comment or blank line */
  722. if (buf[0] == '#' || buf[0] == '\n') {
  723. fputs(buf, resp);
  724. continue;
  725. }
  726. /* [ENCRYPT] or [DECRYPT] */
  727. if (buf[0] == '[') {
  728. if (strncmp(&buf[1], "ENCRYPT", 7) == 0) {
  729. crypt = ENCRYPT;
  730. } else {
  731. crypt = DECRYPT;
  732. }
  733. fputs(buf, resp);
  734. continue;
  735. }
  736. /* NumKeys */
  737. if (strncmp(&buf[0], "NumKeys", 7) == 0) {
  738. i = 7;
  739. while (isspace(buf[i]) || buf[i] == '=') {
  740. i++;
  741. }
  742. numKeys = atoi(&buf[i]);
  743. continue;
  744. }
  745. /* KEY1 = ... */
  746. if (strncmp(buf, "KEY1", 4) == 0) {
  747. i = 4;
  748. while (isspace(buf[i]) || buf[i] == '=') {
  749. i++;
  750. }
  751. for (j=0; isxdigit(buf[i]); i+=2,j++) {
  752. hex_to_byteval(&buf[i], &key[j]);
  753. }
  754. continue;
  755. }
  756. /* KEY2 = ... */
  757. if (strncmp(buf, "KEY2", 4) == 0) {
  758. i = 4;
  759. while (isspace(buf[i]) || buf[i] == '=') {
  760. i++;
  761. }
  762. for (j=8; isxdigit(buf[i]); i+=2,j++) {
  763. hex_to_byteval(&buf[i], &key[j]);
  764. }
  765. continue;
  766. }
  767. /* KEY3 = ... */
  768. if (strncmp(buf, "KEY3", 4) == 0) {
  769. i = 4;
  770. while (isspace(buf[i]) || buf[i] == '=') {
  771. i++;
  772. }
  773. for (j=16; isxdigit(buf[i]); i+=2,j++) {
  774. hex_to_byteval(&buf[i], &key[j]);
  775. }
  776. continue;
  777. }
  778. /* IV = ... */
  779. if (strncmp(buf, "IV", 2) == 0) {
  780. i = 2;
  781. while (isspace(buf[i]) || buf[i] == '=') {
  782. i++;
  783. }
  784. for (j=0; j<sizeof iv; i+=2,j++) {
  785. hex_to_byteval(&buf[i], &iv[j]);
  786. }
  787. continue;
  788. }
  789. /* PLAINTEXT = ... */
  790. if (strncmp(buf, "PLAINTEXT", 9) == 0) {
  791. /* sanity check */
  792. if (crypt != ENCRYPT) {
  793. goto loser;
  794. }
  795. /* PT[0] = PT */
  796. i = 9;
  797. while (isspace(buf[i]) || buf[i] == '=') {
  798. i++;
  799. }
  800. for (j=0; j<sizeof plaintext; i+=2,j++) {
  801. hex_to_byteval(&buf[i], &plaintext[j]);
  802. }
  803. /* do the Monte Carlo test */
  804. if (mode==NSS_DES_EDE3) {
  805. tdea_mct_test(NSS_DES_EDE3, key, numKeys, crypt, plaintext, sizeof plaintext, NULL, resp);
  806. } else {
  807. tdea_mct_test(NSS_DES_EDE3_CBC, key, numKeys, crypt, plaintext, sizeof plaintext, iv, resp);
  808. }
  809. continue;
  810. }
  811. /* CIPHERTEXT = ... */
  812. if (strncmp(buf, "CIPHERTEXT", 10) == 0) {
  813. /* sanity check */
  814. if (crypt != DECRYPT) {
  815. goto loser;
  816. }
  817. /* CT[0] = CT */
  818. i = 10;
  819. while (isspace(buf[i]) || buf[i] == '=') {
  820. i++;
  821. }
  822. for (j=0; isxdigit(buf[i]); i+=2,j++) {
  823. hex_to_byteval(&buf[i], &ciphertext[j]);
  824. }
  825. /* do the Monte Carlo test */
  826. if (mode==NSS_DES_EDE3) {
  827. tdea_mct_test(NSS_DES_EDE3, key, numKeys, crypt, ciphertext, sizeof ciphertext, NULL, resp);
  828. } else {
  829. tdea_mct_test(NSS_DES_EDE3_CBC, key, numKeys, crypt, ciphertext, sizeof ciphertext, iv, resp);
  830. }
  831. continue;
  832. }
  833. }
  834. loser:
  835. fclose(req);
  836. }
  837. SECStatus
  838. aes_encrypt_buf(
  839. int mode,
  840. const unsigned char *key, unsigned int keysize,
  841. const unsigned char *iv,
  842. unsigned char *output, unsigned int *outputlen, unsigned int maxoutputlen,
  843. const unsigned char *input, unsigned int inputlen)
  844. {
  845. SECStatus rv = SECFailure;
  846. AESContext *cx;
  847. unsigned char doublecheck[10*16]; /* 1 to 10 blocks */
  848. unsigned int doublechecklen = 0;
  849. cx = AES_CreateContext(key, iv, mode, PR_TRUE, keysize, 16);
  850. if (cx == NULL) {
  851. goto loser;
  852. }
  853. rv = AES_Encrypt(cx, output, outputlen, maxoutputlen, input, inputlen);
  854. if (rv != SECSuccess) {
  855. goto loser;
  856. }
  857. if (*outputlen != inputlen) {
  858. goto loser;
  859. }
  860. AES_DestroyContext(cx, PR_TRUE);
  861. cx = NULL;
  862. /*
  863. * Doublecheck our result by decrypting the ciphertext and
  864. * compare the output with the input plaintext.
  865. */
  866. cx = AES_CreateContext(key, iv, mode, PR_FALSE, keysize, 16);
  867. if (cx == NULL) {
  868. goto loser;
  869. }
  870. rv = AES_Decrypt(cx, doublecheck, &doublechecklen, sizeof doublecheck,
  871. output, *outputlen);
  872. if (rv != SECSuccess) {
  873. goto loser;
  874. }
  875. if (doublechecklen != *outputlen) {
  876. goto loser;
  877. }
  878. AES_DestroyContext(cx, PR_TRUE);
  879. cx = NULL;
  880. if (memcmp(doublecheck, input, inputlen) != 0) {
  881. goto loser;
  882. }
  883. rv = SECSuccess;
  884. loser:
  885. if (cx != NULL) {
  886. AES_DestroyContext(cx, PR_TRUE);
  887. }
  888. return rv;
  889. }
  890. SECStatus
  891. aes_decrypt_buf(
  892. int mode,
  893. const unsigned char *key, unsigned int keysize,
  894. const unsigned char *iv,
  895. unsigned char *output, unsigned int *outputlen, unsigned int maxoutputlen,
  896. const unsigned char *input, unsigned int inputlen)
  897. {
  898. SECStatus rv = SECFailure;
  899. AESContext *cx;
  900. unsigned char doublecheck[10*16]; /* 1 to 10 blocks */
  901. unsigned int doublechecklen = 0;
  902. cx = AES_CreateContext(key, iv, mode, PR_FALSE, keysize, 16);
  903. if (cx == NULL) {
  904. goto loser;
  905. }
  906. rv = AES_Decrypt(cx, output, outputlen, maxoutputlen,
  907. input, inputlen);
  908. if (rv != SECSuccess) {
  909. goto loser;
  910. }
  911. if (*outputlen != inputlen) {
  912. goto loser;
  913. }
  914. AES_DestroyContext(cx, PR_TRUE);
  915. cx = NULL;
  916. /*
  917. * Doublecheck our result by encrypting the plaintext and
  918. * compare the output with the input ciphertext.
  919. */
  920. cx = AES_CreateContext(key, iv, mode, PR_TRUE, keysize, 16);
  921. if (cx == NULL) {
  922. goto loser;
  923. }
  924. rv = AES_Encrypt(cx, doublecheck, &doublechecklen, sizeof doublecheck,
  925. output, *outputlen);
  926. if (rv != SECSuccess) {
  927. goto loser;
  928. }
  929. if (doublechecklen != *outputlen) {
  930. goto loser;
  931. }
  932. AES_DestroyContext(cx, PR_TRUE);
  933. cx = NULL;
  934. if (memcmp(doublecheck, input, inputlen) != 0) {
  935. goto loser;
  936. }
  937. rv = SECSuccess;
  938. loser:
  939. if (cx != NULL) {
  940. AES_DestroyContext(cx, PR_TRUE);
  941. }
  942. return rv;
  943. }
  944. /*
  945. * Perform the AES Known Answer Test (KAT) or Multi-block Message
  946. * Test (MMT) in ECB or CBC mode. The KAT (there are four types)
  947. * and MMT have the same structure: given the key and IV (CBC mode
  948. * only), encrypt the given plaintext or decrypt the given ciphertext.
  949. * So we can handle them the same way.
  950. *
  951. * reqfn is the pathname of the REQUEST file.
  952. *
  953. * The output RESPONSE file is written to stdout.
  954. */
  955. void
  956. aes_kat_mmt(char *reqfn)
  957. {
  958. char buf[512]; /* holds one line from the input REQUEST file.
  959. * needs to be large enough to hold the longest
  960. * line "CIPHERTEXT = <320 hex digits>\n".
  961. */
  962. FILE *aesreq; /* input stream from the REQUEST file */
  963. FILE *aesresp; /* output stream to the RESPONSE file */
  964. int i, j;
  965. int mode; /* NSS_AES (ECB) or NSS_AES_CBC */
  966. int encrypt = 0; /* 1 means encrypt, 0 means decrypt */
  967. unsigned char key[32]; /* 128, 192, or 256 bits */
  968. unsigned int keysize;
  969. unsigned char iv[16]; /* for all modes except ECB */
  970. unsigned char plaintext[10*16]; /* 1 to 10 blocks */
  971. unsigned int plaintextlen;
  972. unsigned char ciphertext[10*16]; /* 1 to 10 blocks */
  973. unsigned int ciphertextlen;
  974. SECStatus rv;
  975. aesreq = fopen(reqfn, "r");
  976. aesresp = stdout;
  977. while (fgets(buf, sizeof buf, aesreq) != NULL) {
  978. /* a comment or blank line */
  979. if (buf[0] == '#' || buf[0] == '\n') {
  980. fputs(buf, aesresp);
  981. continue;
  982. }
  983. /* [ENCRYPT] or [DECRYPT] */
  984. if (buf[0] == '[') {
  985. if (strncmp(&buf[1], "ENCRYPT", 7) == 0) {
  986. encrypt = 1;
  987. } else {
  988. encrypt = 0;
  989. }
  990. fputs(buf, aesresp);
  991. continue;
  992. }
  993. /* "COUNT = x" begins a new data set */
  994. if (strncmp(buf, "COUNT", 5) == 0) {
  995. mode = NSS_AES;
  996. /* zeroize the variables for the test with this data set */
  997. memset(key, 0, sizeof key);
  998. keysize = 0;
  999. memset(iv, 0, sizeof iv);
  1000. memset(plaintext, 0, sizeof plaintext);
  1001. plaintextlen = 0;
  1002. memset(ciphertext, 0, sizeof ciphertext);
  1003. ciphertextlen = 0;
  1004. fputs(buf, aesresp);
  1005. continue;
  1006. }
  1007. /* KEY = ... */
  1008. if (strncmp(buf, "KEY", 3) == 0) {
  1009. i = 3;
  1010. while (isspace(buf[i]) || buf[i] == '=') {
  1011. i++;
  1012. }
  1013. for (j=0; isxdigit(buf[i]); i+=2,j++) {
  1014. hex_to_byteval(&buf[i], &key[j]);
  1015. }
  1016. keysize = j;
  1017. fputs(buf, aesresp);
  1018. continue;
  1019. }
  1020. /* IV = ... */
  1021. if (strncmp(buf, "IV", 2) == 0) {
  1022. mode = NSS_AES_CBC;
  1023. i = 2;
  1024. while (isspace(buf[i]) || buf[i] == '=') {
  1025. i++;
  1026. }
  1027. for (j=0; j<sizeof iv; i+=2,j++) {
  1028. hex_to_byteval(&buf[i], &iv[j]);
  1029. }
  1030. fputs(buf, aesresp);
  1031. continue;
  1032. }
  1033. /* PLAINTEXT = ... */
  1034. if (strncmp(buf, "PLAINTEXT", 9) == 0) {
  1035. /* sanity check */
  1036. if (!encrypt) {
  1037. goto loser;
  1038. }
  1039. i = 9;
  1040. while (isspace(buf[i]) || buf[i] == '=') {
  1041. i++;
  1042. }
  1043. for (j=0; isxdigit(buf[i]); i+=2,j++) {
  1044. hex_to_byteval(&buf[i], &plaintext[j]);
  1045. }
  1046. plaintextlen = j;
  1047. rv = aes_encrypt_buf(mode, key, keysize,
  1048. (mode == NSS_AES) ? NULL : iv,
  1049. ciphertext, &ciphertextlen, sizeof ciphertext,
  1050. plaintext, plaintextlen);
  1051. if (rv != SECSuccess) {
  1052. goto loser;
  1053. }
  1054. fputs(buf, aesresp);
  1055. fputs("CIPHERTEXT = ", aesresp);
  1056. to_hex_str(buf, ciphertext, ciphertextlen);
  1057. fputs(buf, aesresp);
  1058. fputc('\n', aesresp);
  1059. continue;
  1060. }
  1061. /* CIPHERTEXT = ... */
  1062. if (strncmp(buf, "CIPHERTEXT", 10) == 0) {
  1063. /* sanity check */
  1064. if (encrypt) {
  1065. goto loser;
  1066. }
  1067. i = 10;
  1068. while (isspace(buf[i]) || buf[i] == '=') {
  1069. i++;
  1070. }
  1071. for (j=0; isxdigit(buf[i]); i+=2,j++) {
  1072. hex_to_byteval(&buf[i], &ciphertext[j]);
  1073. }
  1074. ciphertextlen = j;
  1075. rv = aes_decrypt_buf(mode, key, keysize,
  1076. (mode == NSS_AES) ? NULL : iv,
  1077. plaintext, &plaintextlen, sizeof plaintext,
  1078. ciphertext, ciphertextlen);
  1079. if (rv != SECSuccess) {
  1080. goto loser;
  1081. }
  1082. fputs(buf, aesresp);
  1083. fputs("PLAINTEXT = ", aesresp);
  1084. to_hex_str(buf, plaintext, plaintextlen);
  1085. fputs(buf, aesresp);
  1086. fputc('\n', aesresp);
  1087. continue;
  1088. }
  1089. }
  1090. loser:
  1091. fclose(aesreq);
  1092. }
  1093. /*
  1094. * Generate Key[i+1] from Key[i], CT[j-1], and CT[j] for AES Monte Carlo
  1095. * Test (MCT) in ECB and CBC modes.
  1096. */
  1097. void
  1098. aes_mct_next_key(unsigned char *key, unsigned int keysize,
  1099. const unsigned char *ciphertext_1, const unsigned char *ciphertext)
  1100. {
  1101. int k;
  1102. switch (keysize) {
  1103. case 16: /* 128-bit key */
  1104. /* Key[i+1] = Key[i] xor CT[j] */
  1105. for (k=0; k<16; k++) {
  1106. key[k] ^= ciphertext[k];
  1107. }
  1108. break;
  1109. case 24: /* 192-bit key */
  1110. /*
  1111. * Key[i+1] = Key[i] xor (last 64-bits of
  1112. * CT[j-1] || CT[j])
  1113. */
  1114. for (k=0; k<8; k++) {
  1115. key[k] ^= ciphertext_1[k+8];
  1116. }
  1117. for (k=8; k<24; k++) {
  1118. key[k] ^= ciphertext[k-8];
  1119. }
  1120. break;
  1121. case 32: /* 256-bit key */
  1122. /* Key[i+1] = Key[i] xor (CT[j-1] || CT[j]) */
  1123. for (k=0; k<16; k++) {
  1124. key[k] ^= ciphertext_1[k];
  1125. }
  1126. for (k=16; k<32; k++) {
  1127. key[k] ^= ciphertext[k-16];
  1128. }
  1129. break;
  1130. }
  1131. }
  1132. /*
  1133. * Perform the AES Monte Carlo Test (MCT) in ECB mode. MCT exercises
  1134. * our AES code in streaming mode because the plaintext or ciphertext
  1135. * is generated block by block as we go, so we can't collect all the
  1136. * plaintext or ciphertext in one buffer and encrypt or decrypt it in
  1137. * one shot.
  1138. *
  1139. * reqfn is the pathname of the input REQUEST file.
  1140. *
  1141. * The output RESPONSE file is written to stdout.
  1142. */
  1143. void
  1144. aes_ecb_mct(char *reqfn)
  1145. {
  1146. char buf[80]; /* holds one line from the input REQUEST file.
  1147. * needs to be large enough to hold the longest
  1148. * line "KEY = <64 hex digits>\n".
  1149. */
  1150. FILE *aesreq; /* input stream from the REQUEST file */
  1151. FILE *aesresp; /* output stream to the RESPONSE file */
  1152. int i, j;
  1153. int encrypt = 0; /* 1 means encrypt, 0 means decrypt */
  1154. unsigned char key[32]; /* 128, 192, or 256 bits */
  1155. unsigned int keysize;
  1156. unsigned char plaintext[16]; /* PT[j] */
  1157. unsigned char plaintext_1[16]; /* PT[j-1] */
  1158. unsigned char ciphertext[16]; /* CT[j] */
  1159. unsigned char ciphertext_1[16]; /* CT[j-1] */
  1160. unsigned char doublecheck[16];
  1161. unsigned int outputlen;
  1162. AESContext *cx = NULL; /* the operation being tested */
  1163. AESContext *cx2 = NULL; /* the inverse operation done in parallel
  1164. * to doublecheck our result.
  1165. */
  1166. SECStatus rv;
  1167. aesreq = fopen(reqfn, "r");
  1168. aesresp = stdout;
  1169. while (fgets(buf, sizeof buf, aesreq) != NULL) {
  1170. /* a comment or blank line */
  1171. if (buf[0] == '#' || buf[0] == '\n') {
  1172. fputs(buf, aesresp);
  1173. continue;
  1174. }
  1175. /* [ENCRYPT] or [DECRYPT] */
  1176. if (buf[0] == '[') {
  1177. if (strncmp(&buf[1], "ENCRYPT", 7) == 0) {
  1178. encrypt = 1;
  1179. } else {
  1180. encrypt = 0;
  1181. }
  1182. fputs(buf, aesresp);
  1183. continue;
  1184. }
  1185. /* "COUNT = x" begins a new data set */
  1186. if (strncmp(buf, "COUNT", 5) == 0) {
  1187. /* zeroize the variables for the test with this data set */
  1188. memset(key, 0, sizeof key);
  1189. keysize = 0;
  1190. memset(plaintext, 0, sizeof plaintext);
  1191. memset(ciphertext, 0, sizeof ciphertext);
  1192. continue;
  1193. }
  1194. /* KEY = ... */
  1195. if (strncmp(buf, "KEY", 3) == 0) {
  1196. /* Key[0] = Key */
  1197. i = 3;
  1198. while (isspace(buf[i]) || buf[i] == '=') {
  1199. i++;
  1200. }
  1201. for (j=0; isxdigit(buf[i]); i+=2,j++) {
  1202. hex_to_byteval(&buf[i], &key[j]);
  1203. }
  1204. keysize = j;
  1205. continue;
  1206. }
  1207. /* PLAINTEXT = ... */
  1208. if (strncmp(buf, "PLAINTEXT", 9) == 0) {
  1209. /* sanity check */
  1210. if (!encrypt) {
  1211. goto loser;
  1212. }
  1213. /* PT[0] = PT */
  1214. i = 9;
  1215. while (isspace(buf[i]) || buf[i] == '=') {
  1216. i++;
  1217. }
  1218. for (j=0; j<sizeof plaintext; i+=2,j++) {
  1219. hex_to_byteval(&buf[i], &plaintext[j]);
  1220. }
  1221. for (i=0; i<100; i++) {
  1222. sprintf(buf, "COUNT = %d\n", i);
  1223. fputs(buf, aesresp);
  1224. /* Output Key[i] */
  1225. fputs("KEY = ", aesresp);
  1226. to_hex_str(buf, key, keysize);
  1227. fputs(buf, aesresp);
  1228. fputc('\n', aesresp);
  1229. /* Output PT[0] */
  1230. fputs("PLAINTEXT = ", aesresp);
  1231. to_hex_str(buf, plaintext, sizeof plaintext);
  1232. fputs(buf, aesresp);
  1233. fputc('\n', aesresp);
  1234. cx = AES_CreateContext(key, NULL, NSS_AES,
  1235. PR_TRUE, keysize, 16);
  1236. if (cx == NULL) {
  1237. goto loser;
  1238. }
  1239. /*
  1240. * doublecheck our result by decrypting the result
  1241. * and comparing the output with the plaintext.
  1242. */
  1243. cx2 = AES_CreateContext(key, NULL, NSS_AES,
  1244. PR_FALSE, keysize, 16);
  1245. if (cx2 == NULL) {
  1246. goto loser;
  1247. }
  1248. for (j=0; j<1000; j++) {
  1249. /* Save CT[j-1] */
  1250. memcpy(ciphertext_1, ciphertext, sizeof ciphertext);
  1251. /* CT[j] = AES(Key[i], PT[j]) */
  1252. outputlen = 0;
  1253. rv = AES_Encrypt(cx,
  1254. ciphertext, &outputlen, sizeof ciphertext,
  1255. plaintext, sizeof plaintext);
  1256. if (rv != SECSuccess) {
  1257. goto loser;
  1258. }
  1259. if (outputlen != sizeof plaintext) {
  1260. goto loser;
  1261. }
  1262. /* doublecheck our result */
  1263. outputlen = 0;
  1264. rv = AES_Decrypt(cx2,
  1265. doublecheck, &outputlen, sizeof doublecheck,
  1266. ciphertext, sizeof ciphertext);
  1267. if (rv != SECSuccess) {
  1268. goto loser;
  1269. }
  1270. if (outputlen != sizeof ciphertext) {
  1271. goto loser;
  1272. }
  1273. if (memcmp(doublecheck, plaintext, sizeof plaintext)) {
  1274. goto loser;
  1275. }
  1276. /* PT[j+1] = CT[j] */
  1277. memcpy(plaintext, ciphertext, sizeof plaintext);
  1278. }
  1279. AES_DestroyContext(cx, PR_TRUE);
  1280. cx = NULL;
  1281. AES_DestroyContext(cx2, PR_TRUE);
  1282. cx2 = NULL;
  1283. /* Output CT[j] */
  1284. fputs("CIPHERTEXT = ", aesresp);
  1285. to_hex_str(buf, ciphertext, sizeof ciphertext);
  1286. fputs(buf, aesresp);
  1287. fputc('\n', aesresp);
  1288. /* Key[i+1] = Key[i] xor ... */
  1289. aes_mct_next_key(key, keysize, ciphertext_1, ciphertext);
  1290. /* PT[0] = CT[j] */
  1291. /* done at the end of the for(j) loop */
  1292. fputc('\n', aesresp);
  1293. }
  1294. continue;
  1295. }
  1296. /* CIPHERTEXT = ... */
  1297. if (strncmp(buf, "CIPHERTEXT", 10) == 0) {
  1298. /* sanity check */
  1299. if (encrypt) {
  1300. goto loser;
  1301. }
  1302. /* CT[0] = CT */
  1303. i = 10;
  1304. while (isspace(buf[i]) || buf[i] == '=') {
  1305. i++;
  1306. }
  1307. for (j=0; isxdigit(buf[i]); i+=2,j++) {
  1308. hex_to_byteval(&buf[i], &ciphertext[j]);
  1309. }
  1310. for (i=0; i<100; i++) {
  1311. sprintf(buf, "COUNT = %d\n", i);
  1312. fputs(buf, aesresp);
  1313. /* Output Key[i] */
  1314. fputs("KEY = ", aesresp);
  1315. to_hex_str(buf, key, keysize);
  1316. fputs(buf, aesresp);
  1317. fputc('\n', aesresp);
  1318. /* Output CT[0] */
  1319. fputs("CIPHERTEXT = ", aesresp);
  1320. to_hex_str(buf, ciphertext, sizeof ciphertext);
  1321. fputs(buf, aesresp);
  1322. fputc('\n', aesresp);
  1323. cx = AES_CreateContext(key, NULL, NSS_AES,
  1324. PR_FALSE, keysize, 16);
  1325. if (cx == NULL) {
  1326. goto loser;
  1327. }
  1328. /*
  1329. * doublecheck our result by encrypting the result
  1330. * and comparing the output with the ciphertext.
  1331. */
  1332. cx2 = AES_CreateContext(key, NULL, NSS_AES,
  1333. PR_TRUE, keysize, 16);
  1334. if (cx2 == NULL) {
  1335. goto loser;
  1336. }
  1337. for (j=0; j<1000; j++) {
  1338. /* Save PT[j-1] */
  1339. memcpy(plaintext_1, plaintext, sizeof plaintext);
  1340. /* PT[j] = AES(Key[i], CT[j]) */
  1341. outputlen = 0;
  1342. rv = AES_Decrypt(cx,
  1343. plaintext, &outputlen, sizeof plaintext,
  1344. ciphertext, sizeof ciphertext);
  1345. if (rv != SECSuccess) {
  1346. goto loser;
  1347. }
  1348. if (outputlen != sizeof ciphertext) {
  1349. goto loser;
  1350. }
  1351. /* doublecheck our result */
  1352. outputlen = 0;
  1353. rv = AES_Encrypt(cx2,
  1354. doublecheck, &outputlen, sizeof doublecheck,
  1355. plaintext, sizeof plaintext);
  1356. if (rv != SECSuccess) {
  1357. goto loser;
  1358. }
  1359. if (outputlen != sizeof plaintext) {
  1360. goto loser;
  1361. }
  1362. if (memcmp(doublecheck, ciphertext, sizeof ciphertext)) {
  1363. goto loser;
  1364. }
  1365. /* CT[j+1] = PT[j] */
  1366. memcpy(ciphertext, plaintext, sizeof ciphertext);
  1367. }
  1368. AES_DestroyContext(cx, PR_TRUE);
  1369. cx = NULL;
  1370. AES_DestroyContext(cx2, PR_TRUE);
  1371. cx2 = NULL;
  1372. /* Output PT[j] */
  1373. fputs("PLAINTEXT = ", aesresp);
  1374. to_hex_str(buf, plaintext, sizeof plaintext);
  1375. fputs(buf, aesresp);
  1376. fputc('\n', aesresp);
  1377. /* Key[i+1] = Key[i] xor ... */
  1378. aes_mct_next_key(key, keysize, plaintext_1, plaintext);
  1379. /* CT[0] = PT[j] */
  1380. /* done at the end of the for(j) loop */
  1381. fputc('\n', aesresp);
  1382. }
  1383. continue;
  1384. }
  1385. }
  1386. loser:
  1387. if (cx != NULL) {
  1388. AES_DestroyContext(cx, PR_TRUE);
  1389. }
  1390. if (cx2 != NULL) {
  1391. AES_DestroyContext(cx2, PR_TRUE);
  1392. }
  1393. fclose(aesreq);
  1394. }
  1395. /*
  1396. * Perform the AES Monte Carlo Test (MCT) in CBC mode. MCT exercises
  1397. * our AES code in streaming mode because the plaintext or ciphertext
  1398. * is generated block by block as we go, so we can't collect all the
  1399. * plaintext or ciphertext in one buffer and encrypt or decrypt it in
  1400. * one shot.
  1401. *
  1402. * reqfn is the pathname of the input REQUEST file.
  1403. *
  1404. * The output RESPONSE file is written to stdout.
  1405. */
  1406. void
  1407. aes_cbc_mct(char *reqfn)
  1408. {
  1409. char buf[80]; /* holds one line from the input REQUEST file.
  1410. * needs to be large enough to hold the longest
  1411. * line "KEY = <64 hex digits>\n".
  1412. */
  1413. FILE *aesreq; /* input stream from the REQUEST file */
  1414. FILE *aesresp; /* output stream to the RESPONSE file */
  1415. int i, j;
  1416. int encrypt = 0; /* 1 means encrypt, 0 means decrypt */
  1417. unsigned char key[32]; /* 128, 192, or 256 bits */
  1418. unsigned int keysize;
  1419. unsigned char iv[16];
  1420. unsigned char plaintext[16]; /* PT[j] */
  1421. unsigned char plaintext_1[16]; /* PT[j-1] */
  1422. unsigned char ciphertext[16]; /* CT[j] */
  1423. unsigned char ciphertext_1[16]; /* CT[j-1] */
  1424. unsigned char doublecheck[16];
  1425. unsigned int outputlen;
  1426. AESContext *cx = NULL; /* the operation being tested */
  1427. AESContext *cx2 = NULL; /* the inverse operation done in parallel
  1428. * to doublecheck our result.
  1429. */
  1430. SECStatus rv;
  1431. aesreq = fopen(reqfn, "r");
  1432. aesresp = stdout;
  1433. while (fgets(buf, sizeof buf, aesreq) != NULL) {
  1434. /* a comment or blank line */
  1435. if (buf[0] == '#' || buf[0] == '\n') {
  1436. fputs(buf, aesresp);
  1437. continue;
  1438. }
  1439. /* [ENCRYPT] or [DECRYPT] */
  1440. if (buf[0] == '[') {
  1441. if (strncmp(&buf[1], "ENCRYPT", 7) == 0) {
  1442. encrypt = 1;
  1443. } else {
  1444. encrypt = 0;
  1445. }
  1446. fputs(buf, aesresp);
  1447. continue;
  1448. }
  1449. /* "COUNT = x" begins a new data set */
  1450. if (strncmp(buf, "COUNT", 5) == 0) {
  1451. /* zeroize the variables for the test with this data set */
  1452. memset(key, 0, sizeof key);
  1453. keysize = 0;
  1454. memset(iv, 0, sizeof iv);
  1455. memset(plaintext, 0, sizeof plaintext);
  1456. memset(ciphertext, 0, sizeof ciphertext);
  1457. continue;
  1458. }
  1459. /* KEY = ... */
  1460. if (strncmp(buf, "KEY", 3) == 0) {
  1461. /* Key[0] = Key */
  1462. i = 3;
  1463. while (isspace(buf[i]) || buf[i] == '=') {
  1464. i++;
  1465. }
  1466. for (j=0; isxdigit(buf[i]); i+=2,j++) {
  1467. hex_to_byteval(&buf[i], &key[j]);
  1468. }
  1469. keysize = j;
  1470. continue;
  1471. }
  1472. /* IV = ... */
  1473. if (strncmp(buf, "IV", 2) == 0) {
  1474. /* IV[0] = IV */
  1475. i = 2;
  1476. while (isspace(buf[i]) || buf[i] == '=') {
  1477. i++;
  1478. }
  1479. for (j=0; j<sizeof iv; i+=2,j++) {
  1480. hex_to_byteval(&buf[i], &iv[j]);
  1481. }
  1482. continue;
  1483. }
  1484. /* PLAINTEXT = ... */
  1485. if (strncmp(buf, "PLAINTEXT", 9) == 0) {
  1486. /* sanity check */
  1487. if (!encrypt) {
  1488. goto loser;
  1489. }
  1490. /* PT[0] = PT */
  1491. i = 9;
  1492. while (isspace(buf[i]) || buf[i] == '=') {
  1493. i++;
  1494. }
  1495. for (j=0; j<sizeof plaintext; i+=2,j++) {
  1496. hex_to_byteval(&buf[i], &plaintext[j]);
  1497. }
  1498. for (i=0; i<100; i++) {
  1499. sprintf(buf, "COUNT = %d\n", i);
  1500. fputs(buf, aesresp);
  1501. /* Output Key[i] */
  1502. fputs("KEY = ", aesresp);
  1503. to_hex_str(buf, key, keysize);
  1504. fputs(buf, aesresp);
  1505. fputc('\n', aesresp);
  1506. /* Output IV[i] */
  1507. fputs("IV = ", aesresp);
  1508. to_hex_str(buf, iv, sizeof iv);
  1509. fputs(buf, aesresp);
  1510. fputc('\n', aesresp);
  1511. /* Output PT[0] */
  1512. fputs("PLAINTEXT = ", aesresp);
  1513. to_hex_str(buf, plaintext, sizeof plaintext);
  1514. fputs(buf, aesresp);
  1515. fputc('\n', aesresp);
  1516. cx = AES_CreateContext(key, iv, NSS_AES_CBC,
  1517. PR_TRUE, keysize, 16);
  1518. if (cx == NULL) {
  1519. goto loser;
  1520. }
  1521. /*
  1522. * doublecheck our result by decrypting the result
  1523. * and comparing the output with the plaintext.
  1524. */
  1525. cx2 = AES_CreateContext(key, iv, NSS_AES_CBC,
  1526. PR_FALSE, keysize, 16);
  1527. if (cx2 == NULL) {
  1528. goto loser;
  1529. }
  1530. /* CT[-1] = IV[i] */
  1531. memcpy(ciphertext, iv, sizeof ciphertext);
  1532. for (j=0; j<1000; j++) {
  1533. /* Save CT[j-1] */
  1534. memcpy(ciphertext_1, ciphertext, sizeof ciphertext);
  1535. /*
  1536. * If ( j=0 )
  1537. * CT[j] = AES(Key[i], IV[i], PT[j])
  1538. * PT[j+1] = IV[i] (= CT[j-1])
  1539. * Else
  1540. * CT[j] = AES(Key[i], PT[j])
  1541. * PT[j+1] = CT[j-1]
  1542. */
  1543. outputlen = 0;
  1544. rv = AES_Encrypt(cx,
  1545. ciphertext, &outputlen, sizeof ciphertext,
  1546. plaintext, sizeof plaintext);
  1547. if (rv != SECSuccess) {
  1548. goto loser;
  1549. }
  1550. if (outputlen != sizeof plaintext) {
  1551. goto loser;
  1552. }
  1553. /* doublecheck our result */
  1554. outputlen = 0;
  1555. rv = AES_Decrypt(cx2,
  1556. doublecheck, &outputlen, sizeof doublecheck,
  1557. ciphertext, sizeof ciphertext);
  1558. if (rv != SECSuccess) {
  1559. goto loser;
  1560. }
  1561. if (outputlen != sizeof ciphertext) {
  1562. goto loser;
  1563. }
  1564. if (memcmp(doublecheck, plaintext, sizeof plaintext)) {
  1565. goto loser;
  1566. }
  1567. memcpy(plaintext, ciphertext_1, sizeof plaintext);
  1568. }
  1569. AES_DestroyContext(cx, PR_TRUE);
  1570. cx = NULL;
  1571. AES_DestroyContext(cx2, PR_TRUE);
  1572. cx2 = NULL;
  1573. /* Output CT[j] */
  1574. fputs("CIPHERTEXT = ", aesresp);
  1575. to_hex_str(buf, ciphertext, sizeof ciphertext);
  1576. fputs(buf, aesresp);
  1577. fputc('\n', aesresp);
  1578. /* Key[i+1] = Key[i] xor ... */
  1579. aes_mct_next_key(key, keysize, ciphertext_1, ciphertext);
  1580. /* IV[i+1] = CT[j] */
  1581. memcpy(iv, ciphertext, sizeof iv);
  1582. /* PT[0] = CT[j-1] */
  1583. /* done at the end of the for(j) loop */
  1584. fputc('\n', aesresp);
  1585. }
  1586. continue;
  1587. }
  1588. /* CIPHERTEXT = ... */
  1589. if (strncmp(buf, "CIPHERTEXT", 10) == 0) {
  1590. /* sanity check */
  1591. if (encrypt) {
  1592. goto loser;
  1593. }
  1594. /* CT[0] = CT */
  1595. i = 10;
  1596. while (isspace(buf[i]) || buf[i] == '=') {
  1597. i++;
  1598. }
  1599. for (j=0; isxdigit(buf[i]); i+=2,j++) {
  1600. hex_to_byteval(&buf[i], &ciphertext[j]);
  1601. }
  1602. for (i=0; i<100; i++) {
  1603. sprintf(buf, "COUNT = %d\n", i);
  1604. fputs(buf, aesresp);
  1605. /* Output Key[i] */
  1606. fputs("KEY = ", aesresp);
  1607. to_hex_str(buf, key, keysize);
  1608. fputs(buf, aesresp);
  1609. fputc('\n', aesresp);
  1610. /* Output IV[i] */
  1611. fputs("IV = ", aesresp);
  1612. to_hex_str(buf, iv, sizeof iv);
  1613. fputs(buf, aesresp);
  1614. fputc('\n', aesresp);
  1615. /* Output CT[0] */
  1616. fputs("CIPHERTEXT = ", aesresp);
  1617. to_hex_str(buf, ciphertext, sizeof ciphertext);
  1618. fputs(buf, aesresp);
  1619. fputc('\n', aesresp);
  1620. cx = AES_CreateContext(key, iv, NSS_AES_CBC,
  1621. PR_FALSE, keysize, 16);
  1622. if (cx == NULL) {
  1623. goto loser;
  1624. }
  1625. /*
  1626. * doublecheck our result by encrypting the result
  1627. * and comparing the output with the ciphertext.
  1628. */
  1629. cx2 = AES_CreateContext(key, iv, NSS_AES_CBC,
  1630. PR_TRUE, keysize, 16);
  1631. if (cx2 == NULL) {
  1632. goto loser;
  1633. }
  1634. /* PT[-1] = IV[i] */
  1635. memcpy(plaintext, iv, sizeof plaintext);
  1636. for (j=0; j<1000; j++) {
  1637. /* Save PT[j-1] */
  1638. memcpy(plaintext_1, plaintext, sizeof plaintext);
  1639. /*
  1640. * If ( j=0 )
  1641. * PT[j] = AES(Key[i], IV[i], CT[j])
  1642. * CT[j+1] = IV[i] (= PT[j-1])
  1643. * Else
  1644. * PT[j] = AES(Key[i], CT[j])
  1645. * CT[j+1] = PT[j-1]
  1646. */
  1647. outputlen = 0;
  1648. rv = AES_Decrypt(cx,
  1649. plaintext, &outputlen, sizeof plaintext,
  1650. ciphertext, sizeof ciphertext);
  1651. if (rv != SECSuccess) {
  1652. goto loser;
  1653. }
  1654. if (outputlen != sizeof ciphertext) {
  1655. goto loser;
  1656. }
  1657. /* doublecheck our result */
  1658. outputlen = 0;
  1659. rv = AES_Encrypt(cx2,
  1660. doublecheck, &outputlen, sizeof doublecheck,
  1661. plaintext, sizeof plaintext);
  1662. if (rv != SECSuccess) {
  1663. goto loser;
  1664. }
  1665. if (outputlen != sizeof plaintext) {
  1666. goto loser;
  1667. }
  1668. if (memcmp(doublecheck, ciphertext, sizeof ciphertext)) {
  1669. goto loser;
  1670. }
  1671. memcpy(ciphertext, plaintext_1, sizeof ciphertext);
  1672. }
  1673. AES_DestroyContext(cx, PR_TRUE);
  1674. cx = NULL;
  1675. AES_DestroyContext(cx2, PR_TRUE);
  1676. cx2 = NULL;
  1677. /* Output PT[j] */
  1678. fputs("PLAINTEXT = ", aesresp);
  1679. to_hex_str(buf, plaintext, sizeof plaintext);
  1680. fputs(buf, aesresp);
  1681. fputc('\n', aesresp);
  1682. /* Key[i+1] = Key[i] xor ... */
  1683. aes_mct_next_key(key, keysize, plaintext_1, plaintext);
  1684. /* IV[i+1] = PT[j] */
  1685. memcpy(iv, plaintext, sizeof iv);
  1686. /* CT[0] = PT[j-1] */
  1687. /* done at the end of the for(j) loop */
  1688. fputc('\n', aesresp);
  1689. }
  1690. continue;
  1691. }
  1692. }
  1693. loser:
  1694. if (cx != NULL) {
  1695. AES_DestroyContext(cx, PR_TRUE);
  1696. }
  1697. if (cx2 != NULL) {
  1698. AES_DestroyContext(cx2, PR_TRUE);
  1699. }
  1700. fclose(aesreq);
  1701. }
  1702. void write_compact_string(FILE *out, unsigned char *hash, unsigned int len)
  1703. {
  1704. unsigned int i;
  1705. int j, count = 0, last = -1, z = 0;
  1706. long start = ftell(out);
  1707. for (i=0; i<len; i++) {
  1708. for (j=7; j>=0; j--) {
  1709. if (last < 0) {
  1710. last = (hash[i] & (1 << j)) ? 1 : 0;
  1711. fprintf(out, "%d ", last);
  1712. count = 1;
  1713. } else if (hash[i] & (1 << j)) {
  1714. if (last) {
  1715. count++;
  1716. } else {
  1717. last = 0;
  1718. fprintf(out, "%d ", count);
  1719. count = 1;
  1720. z++;
  1721. }
  1722. } else {
  1723. if (!last) {
  1724. count++;
  1725. } else {
  1726. last = 1;
  1727. fprintf(out, "%d ", count);
  1728. count = 1;
  1729. z++;
  1730. }
  1731. }
  1732. }
  1733. }
  1734. fprintf(out, "^\n");
  1735. fseek(out, start, SEEK_SET);
  1736. fprintf(out, "%d ", z);
  1737. fseek(out, 0, SEEK_END);
  1738. }
  1739. int get_next_line(FILE *req, char *key, char *val, FILE *rsp)
  1740. {
  1741. int ignore = 0;
  1742. char *writeto = key;
  1743. int w = 0;
  1744. int c;
  1745. while ((c = fgetc(req)) != EOF) {
  1746. if (ignore) {
  1747. fprintf(rsp, "%c", c);
  1748. if (c == '\n') return ignore;
  1749. } else if (c == '\n') {
  1750. break;
  1751. } else if (c == '#') {
  1752. ignore = 1;
  1753. fprintf(rsp, "%c", c);
  1754. } else if (c == '=') {
  1755. writeto[w] = '\0';
  1756. w = 0;
  1757. writeto = val;
  1758. } else if (c == ' ' || c == '[' || c == ']') {
  1759. continue;
  1760. } else {
  1761. writeto[w++] = c;
  1762. }
  1763. }
  1764. writeto[w] = '\0';
  1765. return (c == EOF) ? -1 : ignore;
  1766. }
  1767. #ifdef NSS_ENABLE_ECC
  1768. typedef struct curveNameTagPairStr {
  1769. char *curveName;
  1770. SECOidTag curveOidTag;
  1771. } CurveNameTagPair;
  1772. #define DEFAULT_CURVE_OID_TAG SEC_OID_SECG_EC_SECP192R1
  1773. /* #define DEFAULT_CURVE_OID_TAG SEC_OID_SECG_EC_SECP160R1 */
  1774. static CurveNameTagPair nameTagPair[] =
  1775. {
  1776. { "sect163k1", SEC_OID_SECG_EC_SECT163K1},
  1777. { "nistk163", SEC_OID_SECG_EC_SECT163K1},
  1778. { "sect163r1", SEC_OID_SECG_EC_SECT163R1},
  1779. { "sect163r2", SEC_OID_SECG_EC_SECT163R2},
  1780. { "nistb163", SEC_OID_SECG_EC_SECT163R2},
  1781. { "sect193r1", SEC_OID_SECG_EC_SECT193R1},
  1782. { "sect193r2", SEC_OID_SECG_EC_SECT193R2},
  1783. { "sect233k1", SEC_OID_SECG_EC_SECT233K1},
  1784. { "nistk233", SEC_OID_SECG_EC_SECT233K1},
  1785. { "sect233r1", SEC_OID_SECG_EC_SECT233R1},
  1786. { "nistb233", SEC_OID_SECG_EC_SECT233R1},
  1787. { "sect239k1", SEC_OID_SECG_EC_SECT239K1},
  1788. { "sect283k1", SEC_OID_SECG_EC_SECT283K1},
  1789. { "nistk283", SEC_OID_SECG_EC_SECT283K1},
  1790. { "sect283r1", SEC_OID_SECG_EC_SECT283R1},
  1791. { "nistb283", SEC_OID_SECG_EC_SECT283R1},
  1792. { "sect409k1", SEC_OID_SECG_EC_SECT409K1},
  1793. { "nistk409", SEC_OID_SECG_EC_SECT409K1},
  1794. { "sect409r1", SEC_OID_SECG_EC_SECT409R1},
  1795. { "nistb409", SEC_OID_SECG_EC_SECT409R1},
  1796. { "sect571k1", SEC_OID_SECG_EC_SECT571K1},
  1797. { "nistk571", SEC_OID_SECG_EC_SECT571K1},
  1798. { "sect571r1", SEC_OID_SECG_EC_SECT571R1},
  1799. { "nistb571", SEC_OID_SECG_EC_SECT571R1},
  1800. { "secp160k1", SEC_OID_SECG_EC_SECP160K1},
  1801. { "secp160r1", SEC_OID_SECG_EC_SECP160R1},
  1802. { "secp160r2", SEC_OID_SECG_EC_SECP160R2},
  1803. { "secp192k1", SEC_OID_SECG_EC_SECP192K1},
  1804. { "secp192r1", SEC_OID_SECG_EC_SECP192R1},
  1805. { "nistp192", SEC_OID_SECG_EC_SECP192R1},
  1806. { "secp224k1", SEC_OID_SECG_EC_SECP224K1},
  1807. { "secp224r1", SEC_OID_SECG_EC_SECP224R1},
  1808. { "nistp224", SEC_OID_SECG_EC_SECP224R1},
  1809. { "secp256k1", SEC_OID_SECG_EC_SECP256K1},
  1810. { "secp256r1", SEC_OID_SECG_EC_SECP256R1},
  1811. { "nistp256", SEC_OID_SECG_EC_SECP256R1},
  1812. { "secp384r1", SEC_OID_SECG_EC_SECP384R1},
  1813. { "nistp384", SEC_OID_SECG_EC_SECP384R1},
  1814. { "secp521r1", SEC_OID_SECG_EC_SECP521R1},
  1815. { "nistp521", SEC_OID_SECG_EC_SECP521R1},
  1816. { "prime192v1", SEC_OID_ANSIX962_EC_PRIME192V1 },
  1817. { "prime192v2", SEC_OID_ANSIX962_EC_PRIME192V2 },
  1818. { "prime192v3", SEC_OID_ANSIX962_EC_PRIME192V3 },
  1819. { "prime239v1", SEC_OID_ANSIX962_EC_PRIME239V1 },
  1820. { "prime239v2", SEC_OID_ANSIX962_EC_PRIME239V2 },
  1821. { "prime239v3", SEC_OID_ANSIX962_EC_PRIME239V3 },
  1822. { "c2pnb163v1", SEC_OID_ANSIX962_EC_C2PNB163V1 },
  1823. { "c2pnb163v2", SEC_OID_ANSIX962_EC_C2PNB163V2 },
  1824. { "c2pnb163v3", SEC_OID_ANSIX962_EC_C2PNB163V3 },
  1825. { "c2pnb176v1", SEC_OID_ANSIX962_EC_C2PNB176V1 },
  1826. { "c2tnb191v1", SEC_OID_ANSIX962_EC_C2TNB191V1 },
  1827. { "c2tnb191v2", SEC_OID_ANSIX962_EC_C2TNB191V2 },
  1828. { "c2tnb191v3", SEC_OID_ANSIX962_EC_C2TNB191V3 },
  1829. { "c2onb191v4", SEC_OID_ANSIX962_EC_C2ONB191V4 },
  1830. { "c2onb191v5", SEC_OID_ANSIX962_EC_C2ONB191V5 },
  1831. { "c2pnb208w1", SEC_OID_ANSIX962_EC_C2PNB208W1 },
  1832. { "c2tnb239v1", SEC_OID_ANSIX962_EC_C2TNB239V1 },
  1833. { "c2tnb239v2", SEC_OID_ANSIX962_EC_C2TNB239V2 },
  1834. { "c2tnb239v3", SEC_OID_ANSIX962_EC_C2TNB239V3 },
  1835. { "c2onb239v4", SEC_OID_ANSIX962_EC_C2ONB239V4 },
  1836. { "c2onb239v5", SEC_OID_ANSIX962_EC_C2ONB239V5 },
  1837. { "c2pnb272w1", SEC_OID_ANSIX962_EC_C2PNB272W1 },
  1838. { "c2pnb304w1", SEC_OID_ANSIX962_EC_C2PNB304W1 },
  1839. { "c2tnb359v1", SEC_OID_ANSIX962_EC_C2TNB359V1 },
  1840. { "c2pnb368w1", SEC_OID_ANSIX962_EC_C2PNB368W1 },
  1841. { "c2tnb431r1", SEC_OID_ANSIX962_EC_C2TNB431R1 },
  1842. { "secp112r1", SEC_OID_SECG_EC_SECP112R1},
  1843. { "secp112r2", SEC_OID_SECG_EC_SECP112R2},
  1844. { "secp128r1", SEC_OID_SECG_EC_SECP128R1},
  1845. { "secp128r2", SEC_OID_SECG_EC_SECP128R2},
  1846. { "sect113r1", SEC_OID_SECG_EC_SECT113R1},
  1847. { "sect113r2", SEC_OID_SECG_EC_SECT113R2},
  1848. { "sect131r1", SEC_OID_SECG_EC_SECT131R1},
  1849. { "sect131r2", SEC_OID_SECG_EC_SECT131R2},
  1850. };
  1851. static SECItem *
  1852. getECParams(const char *curve)
  1853. {
  1854. SECItem *ecparams;
  1855. SECOidData *oidData = NULL;
  1856. SECOidTag curveOidTag = SEC_OID_UNKNOWN; /* default */
  1857. int i, numCurves;
  1858. if (curve != NULL) {
  1859. numCurves = sizeof(nameTagPair)/sizeof(CurveNameTagPair);
  1860. for (i = 0; ((i < numCurves) && (curveOidTag == SEC_OID_UNKNOWN));
  1861. i++) {
  1862. if (PL_strcmp(curve, nameTagPair[i].curveName) == 0)
  1863. curveOidTag = nameTagPair[i].curveOidTag;
  1864. }
  1865. }
  1866. /* Return NULL if curve name is not recognized */
  1867. if ((curveOidTag == SEC_OID_UNKNOWN) ||
  1868. (oidData = SECOID_FindOIDByTag(curveOidTag)) == NULL) {
  1869. fprintf(stderr, "Unrecognized elliptic curve %s\n", curve);
  1870. return NULL;
  1871. }
  1872. ecparams = SECITEM_AllocItem(NULL, NULL, (2 + oidData->oid.len));
  1873. /*
  1874. * ecparams->data needs to contain the ASN encoding of an object ID (OID)
  1875. * representing the named curve. The actual OID is in
  1876. * oidData->oid.data so we simply prepend 0x06 and OID length
  1877. */
  1878. ecparams->data[0] = SEC_ASN1_OBJECT_ID;
  1879. ecparams->data[1] = oidData->oid.len;
  1880. memcpy(ecparams->data + 2, oidData->oid.data, oidData->oid.len);
  1881. return ecparams;
  1882. }
  1883. /*
  1884. * Perform the ECDSA Key Pair Generation Test.
  1885. *
  1886. * reqfn is the pathname of the REQUEST file.
  1887. *
  1888. * The output RESPONSE file is written to stdout.
  1889. */
  1890. void
  1891. ecdsa_keypair_test(char *reqfn)
  1892. {
  1893. char buf[256]; /* holds one line from the input REQUEST file
  1894. * or to the output RESPONSE file.
  1895. * needs to be large enough to hold the longest
  1896. * line "Qx = <144 hex digits>\n".
  1897. */
  1898. FILE *ecdsareq; /* input stream from the REQUEST file */
  1899. FILE *ecdsaresp; /* output stream to the RESPONSE file */
  1900. char curve[16]; /* "nistxddd" */
  1901. ECParams *ecparams;
  1902. int N;
  1903. int i;
  1904. unsigned int len;
  1905. ecdsareq = fopen(reqfn, "r");
  1906. ecdsaresp = stdout;
  1907. strcpy(curve, "nist");
  1908. while (fgets(buf, sizeof buf, ecdsareq) != NULL) {
  1909. /* a comment or blank line */
  1910. if (buf[0] == '#' || buf[0] == '\n') {
  1911. fputs(buf, ecdsaresp);
  1912. continue;
  1913. }
  1914. /* [X-ddd] */
  1915. if (buf[0] == '[') {
  1916. const char *src;
  1917. char *dst;
  1918. SECItem *encodedparams;
  1919. src = &buf[1];
  1920. dst = &curve[4];
  1921. *dst++ = tolower(*src);
  1922. src += 2; /* skip the hyphen */
  1923. *dst++ = *src++;
  1924. *dst++ = *src++;
  1925. *dst++ = *src++;
  1926. *dst = '\0';
  1927. encodedparams = getECParams(curve);
  1928. if (encodedparams == NULL) {
  1929. goto loser;
  1930. }
  1931. if (EC_DecodeParams(encodedparams, &ecparams) != SECSuccess) {
  1932. goto loser;
  1933. }
  1934. SECITEM_FreeItem(encodedparams, PR_TRUE);
  1935. fputs(buf, ecdsaresp);
  1936. continue;
  1937. }
  1938. /* N = x */
  1939. if (buf[0] == 'N') {
  1940. if (sscanf(buf, "N = %d", &N) != 1) {
  1941. goto loser;
  1942. }
  1943. for (i = 0; i < N; i++) {
  1944. ECPrivateKey *ecpriv;
  1945. if (EC_NewKey(ecparams, &ecpriv) != SECSuccess) {
  1946. goto loser;
  1947. }
  1948. fputs("d = ", ecdsaresp);
  1949. to_hex_str(buf, ecpriv->privateValue.data,
  1950. ecpriv->privateValue.len);
  1951. fputs(buf, ecdsaresp);
  1952. fputc('\n', ecdsaresp);
  1953. if (EC_ValidatePublicKey(ecparams, &ecpriv->publicValue)
  1954. != SECSuccess) {
  1955. goto loser;
  1956. }
  1957. len = ecpriv->publicValue.len;
  1958. if (len%2 == 0) {
  1959. goto loser;
  1960. }
  1961. len = (len-1)/2;
  1962. if (ecpriv->publicValue.data[0]
  1963. != EC_POINT_FORM_UNCOMPRESSED) {
  1964. goto loser;
  1965. }
  1966. fputs("Qx = ", ecdsaresp);
  1967. to_hex_str(buf, &ecpriv->publicValue.data[1], len);
  1968. fputs(buf, ecdsaresp);
  1969. fputc('\n', ecdsaresp);
  1970. fputs("Qy = ", ecdsaresp);
  1971. to_hex_str(buf, &ecpriv->publicValue.data[1+len], len);
  1972. fputs(buf, ecdsaresp);
  1973. fputc('\n', ecdsaresp);
  1974. fputc('\n', ecdsaresp);
  1975. PORT_FreeArena(ecpriv->ecParams.arena, PR_TRUE);
  1976. }
  1977. PORT_FreeArena(ecparams->arena, PR_FALSE);
  1978. continue;
  1979. }
  1980. }
  1981. loser:
  1982. fclose(ecdsareq);
  1983. }
  1984. /*
  1985. * Perform the ECDSA Public Key Validation Test.
  1986. *
  1987. * reqfn is the pathname of the REQUEST file.
  1988. *
  1989. * The output RESPONSE file is written to stdout.
  1990. */
  1991. void
  1992. ecdsa_pkv_test(char *reqfn)
  1993. {
  1994. char buf[256]; /* holds one line from the input REQUEST file.
  1995. * needs to be large enough to hold the longest
  1996. * line "Qx = <144 hex digits>\n".
  1997. */
  1998. FILE *ecdsareq; /* input stream from the REQUEST file */
  1999. FILE *ecdsaresp; /* output stream to the RESPONSE file */
  2000. char curve[16]; /* "nistxddd" */
  2001. ECParams *ecparams = NULL;
  2002. SECItem pubkey;
  2003. unsigned int i;
  2004. unsigned int len;
  2005. PRBool keyvalid = PR_TRUE;
  2006. ecdsareq = fopen(reqfn, "r");
  2007. ecdsaresp = stdout;
  2008. strcpy(curve, "nist");
  2009. pubkey.data = NULL;
  2010. while (fgets(buf, sizeof buf, ecdsareq) != NULL) {
  2011. /* a comment or blank line */
  2012. if (buf[0] == '#' || buf[0] == '\n') {
  2013. fputs(buf, ecdsaresp);
  2014. continue;
  2015. }
  2016. /* [X-ddd] */
  2017. if (buf[0] == '[') {
  2018. const char *src;
  2019. char *dst;
  2020. SECItem *encodedparams;
  2021. src = &buf[1];
  2022. dst = &curve[4];
  2023. *dst++ = tolower(*src);
  2024. src += 2; /* skip the hyphen */
  2025. *dst++ = *src++;
  2026. *dst++ = *src++;
  2027. *dst++ = *src++;
  2028. *dst = '\0';
  2029. if (ecparams != NULL) {
  2030. PORT_FreeArena(ecparams->arena, PR_FALSE);
  2031. ecparams = NULL;
  2032. }
  2033. encodedparams = getECParams(curve);
  2034. if (encodedparams == NULL) {
  2035. goto loser;
  2036. }
  2037. if (EC_DecodeParams(encodedparams, &ecparams) != SECSuccess) {
  2038. goto loser;
  2039. }
  2040. SECITEM_FreeItem(encodedparams, PR_TRUE);
  2041. len = (ecparams->fieldID.size + 7) >> 3;
  2042. if (pubkey.data != NULL) {
  2043. PORT_Free(pubkey.data);
  2044. pubkey.data = NULL;
  2045. }
  2046. SECITEM_AllocItem(NULL, &pubkey, 2*len+1);
  2047. if (pubkey.data == NULL) {
  2048. goto loser;
  2049. }
  2050. pubkey.data[0] = EC_POINT_FORM_UNCOMPRESSED;
  2051. fputs(buf, ecdsaresp);
  2052. continue;
  2053. }
  2054. /* Qx = ... */
  2055. if (strncmp(buf, "Qx", 2) == 0) {
  2056. fputs(buf, ecdsaresp);
  2057. i = 2;
  2058. while (isspace(buf[i]) || buf[i] == '=') {
  2059. i++;
  2060. }
  2061. keyvalid = from_hex_str(&pubkey.data[1], len, &buf[i]);
  2062. continue;
  2063. }
  2064. /* Qy = ... */
  2065. if (strncmp(buf, "Qy", 2) == 0) {
  2066. fputs(buf, ecdsaresp);
  2067. if (!keyvalid) {
  2068. fputs("Result = F\n", ecdsaresp);
  2069. continue;
  2070. }
  2071. i = 2;
  2072. while (isspace(buf[i]) || buf[i] == '=') {
  2073. i++;
  2074. }
  2075. keyvalid = from_hex_str(&pubkey.data[1+len], len, &buf[i]);
  2076. if (!keyvalid) {
  2077. fputs("Result = F\n", ecdsaresp);
  2078. continue;
  2079. }
  2080. if (EC_ValidatePublicKey(ecparams, &pubkey) == SECSuccess) {
  2081. fputs("Result = P\n", ecdsaresp);
  2082. } else if (PORT_GetError() == SEC_ERROR_BAD_KEY) {
  2083. fputs("Result = F\n", ecdsaresp);
  2084. } else {
  2085. goto loser;
  2086. }
  2087. continue;
  2088. }
  2089. }
  2090. loser:
  2091. if (ecparams != NULL) {
  2092. PORT_FreeArena(ecparams->arena, PR_FALSE);
  2093. }
  2094. if (pubkey.data != NULL) {
  2095. PORT_Free(pubkey.data);
  2096. }
  2097. fclose(ecdsareq);
  2098. }
  2099. /*
  2100. * Perform the ECDSA Signature Generation Test.
  2101. *
  2102. * reqfn is the pathname of the REQUEST file.
  2103. *
  2104. * The output RESPONSE file is written to stdout.
  2105. */
  2106. void
  2107. ecdsa_siggen_test(char *reqfn)
  2108. {
  2109. char buf[1024]; /* holds one line from the input REQUEST file
  2110. * or to the output RESPONSE file.
  2111. * needs to be large enough to hold the longest
  2112. * line "Msg = <256 hex digits>\n".
  2113. */
  2114. FILE *ecdsareq; /* input stream from the REQUEST file */
  2115. FILE *ecdsaresp; /* output stream to the RESPONSE file */
  2116. char curve[16]; /* "nistxddd" */
  2117. ECParams *ecparams = NULL;
  2118. int i, j;
  2119. unsigned int len;
  2120. unsigned char msg[512]; /* message to be signed (<= 128 bytes) */
  2121. unsigned int msglen;
  2122. unsigned char sha1[20]; /* SHA-1 hash (160 bits) */
  2123. unsigned char sig[2*MAX_ECKEY_LEN];
  2124. SECItem signature, digest;
  2125. ecdsareq = fopen(reqfn, "r");
  2126. ecdsaresp = stdout;
  2127. strcpy(curve, "nist");
  2128. while (fgets(buf, sizeof buf, ecdsareq) != NULL) {
  2129. /* a comment or blank line */
  2130. if (buf[0] == '#' || buf[0] == '\n') {
  2131. fputs(buf, ecdsaresp);
  2132. continue;
  2133. }
  2134. /* [X-ddd] */
  2135. if (buf[0] == '[') {
  2136. const char *src;
  2137. char *dst;
  2138. SECItem *encodedparams;
  2139. src = &buf[1];
  2140. dst = &curve[4];
  2141. *dst++ = tolower(*src);
  2142. src += 2; /* skip the hyphen */
  2143. *dst++ = *src++;
  2144. *dst++ = *src++;
  2145. *dst++ = *src++;
  2146. *dst = '\0';
  2147. if (ecparams != NULL) {
  2148. PORT_FreeArena(ecparams->arena, PR_FALSE);
  2149. ecparams = NULL;
  2150. }
  2151. encodedparams = getECParams(curve);
  2152. if (encodedparams == NULL) {
  2153. goto loser;
  2154. }
  2155. if (EC_DecodeParams(encodedparams, &ecparams) != SECSuccess) {
  2156. goto loser;
  2157. }
  2158. SECITEM_FreeItem(encodedparams, PR_TRUE);
  2159. fputs(buf, ecdsaresp);
  2160. continue;
  2161. }
  2162. /* Msg = ... */
  2163. if (strncmp(buf, "Msg", 3) == 0) {
  2164. ECPrivateKey *ecpriv;
  2165. i = 3;
  2166. while (isspace(buf[i]) || buf[i] == '=') {
  2167. i++;
  2168. }
  2169. for (j=0; isxdigit(buf[i]); i+=2,j++) {
  2170. hex_to_byteval(&buf[i], &msg[j]);
  2171. }
  2172. msglen = j;
  2173. if (SHA1_HashBuf(sha1, msg, msglen) != SECSuccess) {
  2174. goto loser;
  2175. }
  2176. fputs(buf, ecdsaresp);
  2177. if (EC_NewKey(ecparams, &ecpriv) != SECSuccess) {
  2178. goto loser;
  2179. }
  2180. if (EC_ValidatePublicKey(ecparams, &ecpriv->publicValue)
  2181. != SECSuccess) {
  2182. goto loser;
  2183. }
  2184. len = ecpriv->publicValue.len;
  2185. if (len%2 == 0) {
  2186. goto loser;
  2187. }
  2188. len = (len-1)/2;
  2189. if (ecpriv->publicValue.data[0] != EC_POINT_FORM_UNCOMPRESSED) {
  2190. goto loser;
  2191. }
  2192. fputs("Qx = ", ecdsaresp);
  2193. to_hex_str(buf, &ecpriv->publicValue.data[1], len);
  2194. fputs(buf, ecdsaresp);
  2195. fputc('\n', ecdsaresp);
  2196. fputs("Qy = ", ecdsaresp);
  2197. to_hex_str(buf, &ecpriv->publicValue.data[1+len], len);
  2198. fputs(buf, ecdsaresp);
  2199. fputc('\n', ecdsaresp);
  2200. digest.type = siBuffer;
  2201. digest.data = sha1;
  2202. digest.len = sizeof sha1;
  2203. signature.type = siBuffer;
  2204. signature.data = sig;
  2205. signature.len = sizeof sig;
  2206. if (ECDSA_SignDigest(ecpriv, &signature, &digest) != SECSuccess) {
  2207. goto loser;
  2208. }
  2209. len = signature.len;
  2210. if (len%2 != 0) {
  2211. goto loser;
  2212. }
  2213. len = len/2;
  2214. fputs("R = ", ecdsaresp);
  2215. to_hex_str(buf, &signature.data[0], len);
  2216. fputs(buf, ecdsaresp);
  2217. fputc('\n', ecdsaresp);
  2218. fputs("S = ", ecdsaresp);
  2219. to_hex_str(buf, &signature.data[len], len);
  2220. fputs(buf, ecdsaresp);
  2221. fputc('\n', ecdsaresp);
  2222. PORT_FreeArena(ecpriv->ecParams.arena, PR_TRUE);
  2223. continue;
  2224. }
  2225. }
  2226. loser:
  2227. if (ecparams != NULL) {
  2228. PORT_FreeArena(ecparams->arena, PR_FALSE);
  2229. }
  2230. fclose(ecdsareq);
  2231. }
  2232. /*
  2233. * Perform the ECDSA Signature Verification Test.
  2234. *
  2235. * reqfn is the pathname of the REQUEST file.
  2236. *
  2237. * The output RESPONSE file is written to stdout.
  2238. */
  2239. void
  2240. ecdsa_sigver_test(char *reqfn)
  2241. {
  2242. char buf[1024]; /* holds one line from the input REQUEST file.
  2243. * needs to be large enough to hold the longest
  2244. * line "Msg = <256 hex digits>\n".
  2245. */
  2246. FILE *ecdsareq; /* input stream from the REQUEST file */
  2247. FILE *ecdsaresp; /* output stream to the RESPONSE file */
  2248. char curve[16]; /* "nistxddd" */
  2249. ECPublicKey ecpub;
  2250. unsigned int i, j;
  2251. unsigned int flen; /* length in bytes of the field size */
  2252. unsigned int olen; /* length in bytes of the base point order */
  2253. unsigned char msg[512]; /* message that was signed (<= 128 bytes) */
  2254. unsigned int msglen;
  2255. unsigned char sha1[20]; /* SHA-1 hash (160 bits) */
  2256. unsigned char sig[2*MAX_ECKEY_LEN];
  2257. SECItem signature, digest;
  2258. PRBool keyvalid = PR_TRUE;
  2259. PRBool sigvalid = PR_TRUE;
  2260. ecdsareq = fopen(reqfn, "r");
  2261. ecdsaresp = stdout;
  2262. ecpub.ecParams.arena = NULL;
  2263. strcpy(curve, "nist");
  2264. while (fgets(buf, sizeof buf, ecdsareq) != NULL) {
  2265. /* a comment or blank line */
  2266. if (buf[0] == '#' || buf[0] == '\n') {
  2267. fputs(buf, ecdsaresp);
  2268. continue;
  2269. }
  2270. /* [X-ddd] */
  2271. if (buf[0] == '[') {
  2272. const char *src;
  2273. char *dst;
  2274. SECItem *encodedparams;
  2275. ECParams *ecparams;
  2276. src = &buf[1];
  2277. dst = &curve[4];
  2278. *dst++ = tolower(*src);
  2279. src += 2; /* skip the hyphen */
  2280. *dst++ = *src++;
  2281. *dst++ = *src++;
  2282. *dst++ = *src++;
  2283. *dst = '\0';
  2284. encodedparams = getECParams(curve);
  2285. if (encodedparams == NULL) {
  2286. goto loser;
  2287. }
  2288. if (EC_DecodeParams(encodedparams, &ecparams) != SECSuccess) {
  2289. goto loser;
  2290. }
  2291. SECITEM_FreeItem(encodedparams, PR_TRUE);
  2292. if (ecpub.ecParams.arena != NULL) {
  2293. PORT_FreeArena(ecpub.ecParams.arena, PR_FALSE);
  2294. }
  2295. ecpub.ecParams.arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
  2296. if (ecpub.ecParams.arena == NULL) {
  2297. goto loser;
  2298. }
  2299. if (EC_CopyParams(ecpub.ecParams.arena, &ecpub.ecParams, ecparams)
  2300. != SECSuccess) {
  2301. goto loser;
  2302. }
  2303. PORT_FreeArena(ecparams->arena, PR_FALSE);
  2304. flen = (ecpub.ecParams.fieldID.size + 7) >> 3;
  2305. olen = ecpub.ecParams.order.len;
  2306. if (2*olen > sizeof sig) {
  2307. goto loser;
  2308. }
  2309. ecpub.publicValue.type = siBuffer;
  2310. ecpub.publicValue.data = NULL;
  2311. ecpub.publicValue.len = 0;
  2312. SECITEM_AllocItem(ecpub.ecParams.arena,
  2313. &ecpub.publicValue, 2*flen+1);
  2314. if (ecpub.publicValue.data == NULL) {
  2315. goto loser;
  2316. }
  2317. ecpub.publicValue.data[0] = EC_POINT_FORM_UNCOMPRESSED;
  2318. fputs(buf, ecdsaresp);
  2319. continue;
  2320. }
  2321. /* Msg = ... */
  2322. if (strncmp(buf, "Msg", 3) == 0) {
  2323. i = 3;
  2324. while (isspace(buf[i]) || buf[i] == '=') {
  2325. i++;
  2326. }
  2327. for (j=0; isxdigit(buf[i]); i+=2,j++) {
  2328. hex_to_byteval(&buf[i], &msg[j]);
  2329. }
  2330. msglen = j;
  2331. if (SHA1_HashBuf(sha1, msg, msglen) != SECSuccess) {
  2332. goto loser;
  2333. }
  2334. fputs(buf, ecdsaresp);
  2335. digest.type = siBuffer;
  2336. digest.data = sha1;
  2337. digest.len = sizeof sha1;
  2338. continue;
  2339. }
  2340. /* Qx = ... */
  2341. if (strncmp(buf, "Qx", 2) == 0) {
  2342. fputs(buf, ecdsaresp);
  2343. i = 2;
  2344. while (isspace(buf[i]) || buf[i] == '=') {
  2345. i++;
  2346. }
  2347. keyvalid = from_hex_str(&ecpub.publicValue.data[1], flen,
  2348. &buf[i]);
  2349. continue;
  2350. }
  2351. /* Qy = ... */
  2352. if (strncmp(buf, "Qy", 2) == 0) {
  2353. fputs(buf, ecdsaresp);
  2354. if (!keyvalid) {
  2355. continue;
  2356. }
  2357. i = 2;
  2358. while (isspace(buf[i]) || buf[i] == '=') {
  2359. i++;
  2360. }
  2361. keyvalid = from_hex_str(&ecpub.publicValue.data[1+flen], flen,
  2362. &buf[i]);
  2363. if (!keyvalid) {
  2364. continue;
  2365. }
  2366. if (EC_ValidatePublicKey(&ecpub.ecParams, &ecpub.publicValue)
  2367. != SECSuccess) {
  2368. if (PORT_GetError() == SEC_ERROR_BAD_KEY) {
  2369. keyvalid = PR_FALSE;
  2370. } else {
  2371. goto loser;
  2372. }
  2373. }
  2374. continue;
  2375. }
  2376. /* R = ... */
  2377. if (buf[0] == 'R') {
  2378. fputs(buf, ecdsaresp);
  2379. i = 1;
  2380. while (isspace(buf[i]) || buf[i] == '=') {
  2381. i++;
  2382. }
  2383. sigvalid = from_hex_str(sig, olen, &buf[i]);
  2384. continue;
  2385. }
  2386. /* S = ... */
  2387. if (buf[0] == 'S') {
  2388. fputs(buf, ecdsaresp);
  2389. i = 1;
  2390. while (isspace(buf[i]) || buf[i] == '=') {
  2391. i++;
  2392. }
  2393. if (sigvalid) {
  2394. sigvalid = from_hex_str(&sig[olen], olen, &buf[i]);
  2395. }
  2396. signature.type = siBuffer;
  2397. signature.data = sig;
  2398. signature.len = 2*olen;
  2399. if (!keyvalid || !sigvalid) {
  2400. fputs("Result = F\n", ecdsaresp);
  2401. } else if (ECDSA_VerifyDigest(&ecpub, &signature, &digest)
  2402. == SECSuccess) {
  2403. fputs("Result = P\n", ecdsaresp);
  2404. } else {
  2405. fputs("Result = F\n", ecdsaresp);
  2406. }
  2407. continue;
  2408. }
  2409. }
  2410. loser:
  2411. if (ecpub.ecParams.arena != NULL) {
  2412. PORT_FreeArena(ecpub.ecParams.arena, PR_FALSE);
  2413. }
  2414. fclose(ecdsareq);
  2415. }
  2416. #endif /* NSS_ENABLE_ECC */
  2417. /*
  2418. * Read a value from the test and allocate the result.
  2419. */
  2420. static unsigned char *
  2421. alloc_value(char *buf, int *len)
  2422. {
  2423. unsigned char * value;
  2424. int i, count;
  2425. if (strncmp(buf, "<None>", 6) == 0) {
  2426. *len = 0;
  2427. return NULL;
  2428. }
  2429. /* find the length of the number */
  2430. for (count = 0; isxdigit(buf[count]); count++);
  2431. *len = count/2;
  2432. if (*len == 0) {
  2433. return NULL;
  2434. }
  2435. value = PORT_Alloc(*len);
  2436. if (!value) {
  2437. *len = 0;
  2438. return NULL;
  2439. }
  2440. for (i=0; i<*len; buf+=2 , i++) {
  2441. hex_to_byteval(buf, &value[i]);
  2442. }
  2443. return value;
  2444. }
  2445. PRBool
  2446. isblankline(char *b)
  2447. {
  2448. while (isspace(*b)) b++;
  2449. if ((*b == '\n') || (*b == 0)) {
  2450. return PR_TRUE;
  2451. }
  2452. return PR_FALSE;
  2453. }
  2454. static int debug = 0;
  2455. /*
  2456. * Perform the Hash_DRBG (CAVS) for the RNG algorithm
  2457. *
  2458. * reqfn is the pathname of the REQUEST file.
  2459. *
  2460. * The output RESPONSE file is written to stdout.
  2461. */
  2462. void
  2463. drbg(char *reqfn)
  2464. {
  2465. char buf[2000]; /* test case has some very long lines, returned bits
  2466. * as high as 800 bytes (6400 bits). That 1600 byte
  2467. * plus a tag */
  2468. char buf2[2000];
  2469. FILE *rngreq; /* input stream from the REQUEST file */
  2470. FILE *rngresp; /* output stream to the RESPONSE file */
  2471. unsigned int i, j;
  2472. PRBool predictionResistance = PR_FALSE;
  2473. unsigned char *nonce = NULL;
  2474. int nonceLen = 0;
  2475. unsigned char *personalizationString = NULL;
  2476. int personalizationStringLen = 0;
  2477. unsigned char *additionalInput = NULL;
  2478. int additionalInputLen = 0;
  2479. unsigned char *entropyInput = NULL;
  2480. int entropyInputLen = 0;
  2481. unsigned char predictedreturn_bytes[SHA256_LENGTH];
  2482. unsigned char return_bytes[SHA256_LENGTH];
  2483. int return_bytes_len = SHA256_LENGTH;
  2484. enum { NONE, INSTANTIATE, GENERATE, RESEED, RESULT } command =
  2485. NONE;
  2486. PRBool genResult = PR_FALSE;
  2487. SECStatus rv;
  2488. rngreq = fopen(reqfn, "r");
  2489. rngresp = stdout;
  2490. while (fgets(buf, sizeof buf, rngreq) != NULL) {
  2491. switch (command) {
  2492. case INSTANTIATE:
  2493. if (debug) {
  2494. fputs("# PRNGTEST_Instantiate(",rngresp);
  2495. to_hex_str(buf2,entropyInput, entropyInputLen);
  2496. fputs(buf2,rngresp);
  2497. fprintf(rngresp,",%d,",entropyInputLen);
  2498. to_hex_str(buf2,nonce, nonceLen);
  2499. fputs(buf2,rngresp);
  2500. fprintf(rngresp,",%d,",nonceLen);
  2501. to_hex_str(buf2,personalizationString,
  2502. personalizationStringLen);
  2503. fputs(buf2,rngresp);
  2504. fprintf(rngresp,",%d)\n", personalizationStringLen);
  2505. }
  2506. rv = PRNGTEST_Instantiate(entropyInput, entropyInputLen,
  2507. nonce, nonceLen,
  2508. personalizationString,
  2509. personalizationStringLen);
  2510. if (rv != SECSuccess) {
  2511. goto loser;
  2512. }
  2513. break;
  2514. case GENERATE:
  2515. case RESULT:
  2516. memset(return_bytes, 0, return_bytes_len);
  2517. if (debug) {
  2518. fputs("# PRNGTEST_Generate(returnbytes",rngresp);
  2519. fprintf(rngresp,",%d,", return_bytes_len);
  2520. to_hex_str(buf2,additionalInput, additionalInputLen);
  2521. fputs(buf2,rngresp);
  2522. fprintf(rngresp,",%d)\n",additionalInputLen);
  2523. }
  2524. rv = PRNGTEST_Generate((PRUint8 *) return_bytes,
  2525. return_bytes_len,
  2526. (PRUint8 *) additionalInput,
  2527. additionalInputLen);
  2528. if (rv != SECSuccess) {
  2529. goto loser;
  2530. }
  2531. if (command == RESULT) {
  2532. fputs("ReturnedBits = ", rngresp);
  2533. to_hex_str(buf2, return_bytes, return_bytes_len);
  2534. fputs(buf2, rngresp);
  2535. fputc('\n', rngresp);
  2536. if (debug) {
  2537. fputs("# PRNGTEST_Uninstantiate()\n",rngresp);
  2538. }
  2539. rv = PRNGTEST_Uninstantiate();
  2540. if (rv != SECSuccess) {
  2541. goto loser;
  2542. }
  2543. } else if (debug) {
  2544. fputs("#ReturnedBits = ", rngresp);
  2545. to_hex_str(buf2, return_bytes, return_bytes_len);
  2546. fputs(buf2, rngresp);
  2547. fputc('\n', rngresp);
  2548. }
  2549. memset(additionalInput, 0, additionalInputLen);
  2550. break;
  2551. case RESEED:
  2552. if (entropyInput || additionalInput) {
  2553. if (debug) {
  2554. fputs("# PRNGTEST_Reseed(",rngresp);
  2555. fprintf(rngresp,",%d,", return_bytes_len);
  2556. to_hex_str(buf2,entropyInput, entropyInputLen);
  2557. fputs(buf2,rngresp);
  2558. fprintf(rngresp,",%d,", entropyInputLen);
  2559. to_hex_str(buf2,additionalInput, additionalInputLen);
  2560. fputs(buf2,rngresp);
  2561. fprintf(rngresp,",%d)\n",additionalInputLen);
  2562. }
  2563. rv = PRNGTEST_Reseed(entropyInput, entropyInputLen,
  2564. additionalInput, additionalInputLen);
  2565. if (rv != SECSuccess) {
  2566. goto loser;
  2567. }
  2568. }
  2569. memset(entropyInput, 0, entropyInputLen);
  2570. memset(additionalInput, 0, additionalInputLen);
  2571. break;
  2572. case NONE:
  2573. break;
  2574. }
  2575. command = NONE;
  2576. /* a comment or blank line */
  2577. if (buf[0] == '#' || buf[0] == '\n' || buf[0] == '\r' ) {
  2578. fputs(buf, rngresp);
  2579. continue;
  2580. }
  2581. /* [Hash - SHA256] */
  2582. if (strncmp(buf, "[SHA-256]", 9) == 0) {
  2583. fputs(buf, rngresp);
  2584. continue;
  2585. }
  2586. if (strncmp(buf, "[PredictionResistance", 21) == 0) {
  2587. i = 21;
  2588. while (isspace(buf[i]) || buf[i] == '=') {
  2589. i++;
  2590. }
  2591. if (strncmp(buf, "False", 5) == 0) {
  2592. predictionResistance = PR_FALSE;
  2593. } else {
  2594. predictionResistance = PR_TRUE;
  2595. }
  2596. fputs(buf, rngresp);
  2597. continue;
  2598. }
  2599. if (strncmp(buf, "[EntropyInputLen", 16) == 0) {
  2600. if (entropyInput) {
  2601. PORT_ZFree(entropyInput, entropyInputLen);
  2602. entropyInput = NULL;
  2603. entropyInputLen = 0;
  2604. }
  2605. if (sscanf(buf, "[EntropyInputLen = %d]", &entropyInputLen) != 1) {
  2606. goto loser;
  2607. }
  2608. entropyInputLen = entropyInputLen/8;
  2609. if (entropyInputLen > 0) {
  2610. entropyInput = PORT_Alloc(entropyInputLen);
  2611. }
  2612. fputs(buf, rngresp);
  2613. continue;
  2614. }
  2615. if (strncmp(buf, "[NonceLen", 9) == 0) {
  2616. if (nonce) {
  2617. PORT_ZFree(nonce, nonceLen);
  2618. nonce = NULL;
  2619. nonceLen = 0;
  2620. }
  2621. if (sscanf(buf, "[NonceLen = %d]", &nonceLen) != 1) {
  2622. goto loser;
  2623. }
  2624. nonceLen = nonceLen/8;
  2625. if (nonceLen > 0) {
  2626. nonce = PORT_Alloc(nonceLen);
  2627. }
  2628. fputs(buf, rngresp);
  2629. continue;
  2630. }
  2631. if (strncmp(buf, "[PersonalizationStringLen", 16) == 0) {
  2632. if (personalizationString) {
  2633. PORT_ZFree(personalizationString, personalizationStringLen);
  2634. personalizationString = NULL;
  2635. personalizationStringLen = 0;
  2636. }
  2637. if (sscanf(buf, "[PersonalizationStringLen = %d]", &personalizationStringLen) != 1) {
  2638. goto loser;
  2639. }
  2640. personalizationStringLen = personalizationStringLen / 8;
  2641. if (personalizationStringLen > 0) {
  2642. personalizationString = PORT_Alloc(personalizationStringLen);
  2643. }
  2644. fputs(buf, rngresp);
  2645. continue;
  2646. }
  2647. if (strncmp(buf, "[AdditionalInputLen", 16) == 0) {
  2648. if (additionalInput) {
  2649. PORT_ZFree(additionalInput, additionalInputLen);
  2650. additionalInput = NULL;
  2651. additionalInputLen = 0;
  2652. }
  2653. if (sscanf(buf, "[AdditionalInputLen = %d]", &additionalInputLen) != 1) {
  2654. goto loser;
  2655. }
  2656. additionalInputLen = additionalInputLen/8;
  2657. if (additionalInputLen > 0) {
  2658. additionalInput = PORT_Alloc(additionalInputLen);
  2659. }
  2660. fputs(buf, rngresp);
  2661. continue;
  2662. }
  2663. if (strncmp(buf, "COUNT", 5) == 0) {
  2664. /* zeroize the variables for the test with this data set */
  2665. if (entropyInput) {
  2666. memset(entropyInput, 0, entropyInputLen);
  2667. }
  2668. if (nonce) {
  2669. memset(nonce, 0, nonceLen);
  2670. }
  2671. if (personalizationString) {
  2672. memset(personalizationString, 0, personalizationStringLen);
  2673. }
  2674. if (additionalInput) {
  2675. memset(additionalInput, 0, additionalInputLen);
  2676. }
  2677. genResult = PR_FALSE;
  2678. fputs(buf, rngresp);
  2679. continue;
  2680. }
  2681. /* EntropyInputReseed = ... */
  2682. if (strncmp(buf, "EntropyInputReseed", 18) == 0) {
  2683. if (entropyInput) {
  2684. memset(entropyInput, 0, entropyInputLen);
  2685. i = 18;
  2686. while (isspace(buf[i]) || buf[i] == '=') {
  2687. i++;
  2688. }
  2689. for (j=0; isxdigit(buf[i]); i+=2,j++) { /*j<entropyInputLen*/
  2690. hex_to_byteval(&buf[i], &entropyInput[j]);
  2691. }
  2692. }
  2693. fputs(buf, rngresp);
  2694. continue;
  2695. }
  2696. /* AttionalInputReseed = ... */
  2697. if (strncmp(buf, "AdditionalInputReseed", 21) == 0) {
  2698. if (additionalInput) {
  2699. memset(additionalInput, 0, additionalInputLen);
  2700. i = 21;
  2701. while (isspace(buf[i]) || buf[i] == '=') {
  2702. i++;
  2703. }
  2704. for (j=0; isxdigit(buf[i]); i+=2,j++) { /*j<additionalInputLen*/
  2705. hex_to_byteval(&buf[i], &additionalInput[j]);
  2706. }
  2707. }
  2708. command = RESEED;
  2709. fputs(buf, rngresp);
  2710. continue;
  2711. }
  2712. /* Entropy input = ... */
  2713. if (strncmp(buf, "EntropyInput", 12) == 0) {
  2714. i = 12;
  2715. while (isspace(buf[i]) || buf[i] == '=') {
  2716. i++;
  2717. }
  2718. for (j=0; isxdigit(buf[i]); i+=2,j++) { /*j<entropyInputLen*/
  2719. hex_to_byteval(&buf[i], &entropyInput[j]);
  2720. }
  2721. fputs(buf, rngresp);
  2722. continue;
  2723. }
  2724. /* nouce = ... */
  2725. if (strncmp(buf, "Nonce", 5) == 0) {
  2726. i = 5;
  2727. while (isspace(buf[i]) || buf[i] == '=') {
  2728. i++;
  2729. }
  2730. for (j=0; isxdigit(buf[i]); i+=2,j++) { /*j<nonceLen*/
  2731. hex_to_byteval(&buf[i], &nonce[j]);
  2732. }
  2733. fputs(buf, rngresp);
  2734. continue;
  2735. }
  2736. /* Personalization string = ... */
  2737. if (strncmp(buf, "PersonalizationString", 21) == 0) {
  2738. if (personalizationString) {
  2739. i = 21;
  2740. while (isspace(buf[i]) || buf[i] == '=') {
  2741. i++;
  2742. }
  2743. for (j=0; isxdigit(buf[i]); i+=2,j++) { /*j<personalizationStringLen*/
  2744. hex_to_byteval(&buf[i], &personalizationString[j]);
  2745. }
  2746. }
  2747. fputs(buf, rngresp);
  2748. command = INSTANTIATE;
  2749. continue;
  2750. }
  2751. /* Additional input = ... */
  2752. if (strncmp(buf, "AdditionalInput", 15) == 0) {
  2753. if (additionalInput) {
  2754. i = 15;
  2755. while (isspace(buf[i]) || buf[i] == '=') {
  2756. i++;
  2757. }
  2758. for (j=0; isxdigit(buf[i]); i+=2,j++) { /*j<additionalInputLen*/
  2759. hex_to_byteval(&buf[i], &additionalInput[j]);
  2760. }
  2761. }
  2762. if (genResult) {
  2763. command = RESULT;
  2764. } else {
  2765. command = GENERATE;
  2766. genResult = PR_TRUE; /* next time generate result */
  2767. }
  2768. fputs(buf, rngresp);
  2769. continue;
  2770. }
  2771. /* Returned bits = ... */
  2772. if (strncmp(buf, "ReturnedBits", 12) == 0) {
  2773. i = 12;
  2774. while (isspace(buf[i]) || buf[i] == '=') {
  2775. i++;
  2776. }
  2777. for (j=0; isxdigit(buf[i]); i+=2,j++) { /*j<additionalInputLen*/
  2778. hex_to_byteval(&buf[i], &predictedreturn_bytes[j]);
  2779. }
  2780. if (memcmp(return_bytes,
  2781. predictedreturn_bytes, return_bytes_len) != 0) {
  2782. if (debug) {
  2783. fprintf(rngresp, "# Generate failed:\n");
  2784. fputs( "# predicted=", rngresp);
  2785. to_hex_str(buf, predictedreturn_bytes,
  2786. return_bytes_len);
  2787. fputs(buf, rngresp);
  2788. fputs("\n# actual = ", rngresp);
  2789. fputs(buf2, rngresp);
  2790. fputc('\n', rngresp);
  2791. } else {
  2792. fprintf(stderr, "Generate failed:\n");
  2793. fputs( " predicted=", stderr);
  2794. to_hex_str(buf, predictedreturn_bytes,
  2795. return_bytes_len);
  2796. fputs(buf, stderr);
  2797. fputs("\n actual = ", stderr);
  2798. fputs(buf2, stderr);
  2799. fputc('\n', stderr);
  2800. }
  2801. }
  2802. memset(predictedreturn_bytes, 0 , sizeof predictedreturn_bytes);
  2803. continue;
  2804. }
  2805. }
  2806. loser:
  2807. fclose(rngreq);
  2808. }
  2809. /*
  2810. * Perform the RNG Variable Seed Test (VST) for the RNG algorithm
  2811. * "DSA - Generation of X", used both as specified and as a generic
  2812. * purpose RNG. The presence of "Q = ..." in the REQUEST file
  2813. * indicates we are using the algorithm as specified.
  2814. *
  2815. * reqfn is the pathname of the REQUEST file.
  2816. *
  2817. * The output RESPONSE file is written to stdout.
  2818. */
  2819. void
  2820. rng_vst(char *reqfn)
  2821. {
  2822. char buf[256]; /* holds one line from the input REQUEST file.
  2823. * needs to be large enough to hold the longest
  2824. * line "XSeed = <128 hex digits>\n".
  2825. */
  2826. FILE *rngreq; /* input stream from the REQUEST file */
  2827. FILE *rngresp; /* output stream to the RESPONSE file */
  2828. unsigned int i, j;
  2829. unsigned char Q[DSA_SUBPRIME_LEN];
  2830. PRBool hasQ = PR_FALSE;
  2831. unsigned int b; /* 160 <= b <= 512, b is a multiple of 8 */
  2832. unsigned char XKey[512/8];
  2833. unsigned char XSeed[512/8];
  2834. unsigned char GENX[2*SHA1_LENGTH];
  2835. unsigned char DSAX[DSA_SUBPRIME_LEN];
  2836. SECStatus rv;
  2837. rngreq = fopen(reqfn, "r");
  2838. rngresp = stdout;
  2839. while (fgets(buf, sizeof buf, rngreq) != NULL) {
  2840. /* a comment or blank line */
  2841. if (buf[0] == '#' || buf[0] == '\n') {
  2842. fputs(buf, rngresp);
  2843. continue;
  2844. }
  2845. /* [Xchange - SHA1] */
  2846. if (buf[0] == '[') {
  2847. fputs(buf, rngresp);
  2848. continue;
  2849. }
  2850. /* Q = ... */
  2851. if (buf[0] == 'Q') {
  2852. i = 1;
  2853. while (isspace(buf[i]) || buf[i] == '=') {
  2854. i++;
  2855. }
  2856. for (j=0; j<sizeof Q; i+=2,j++) {
  2857. hex_to_byteval(&buf[i], &Q[j]);
  2858. }
  2859. fputs(buf, rngresp);
  2860. hasQ = PR_TRUE;
  2861. continue;
  2862. }
  2863. /* "COUNT = x" begins a new data set */
  2864. if (strncmp(buf, "COUNT", 5) == 0) {
  2865. /* zeroize the variables for the test with this data set */
  2866. b = 0;
  2867. memset(XKey, 0, sizeof XKey);
  2868. memset(XSeed, 0, sizeof XSeed);
  2869. fputs(buf, rngresp);
  2870. continue;
  2871. }
  2872. /* b = ... */
  2873. if (buf[0] == 'b') {
  2874. i = 1;
  2875. while (isspace(buf[i]) || buf[i] == '=') {
  2876. i++;
  2877. }
  2878. b = atoi(&buf[i]);
  2879. if (b < 160 || b > 512 || b%8 != 0) {
  2880. goto loser;
  2881. }
  2882. fputs(buf, rngresp);
  2883. continue;
  2884. }
  2885. /* XKey = ... */
  2886. if (strncmp(buf, "XKey", 4) == 0) {
  2887. i = 4;
  2888. while (isspace(buf[i]) || buf[i] == '=') {
  2889. i++;
  2890. }
  2891. for (j=0; j<b/8; i+=2,j++) {
  2892. hex_to_byteval(&buf[i], &XKey[j]);
  2893. }
  2894. fputs(buf, rngresp);
  2895. continue;
  2896. }
  2897. /* XSeed = ... */
  2898. if (strncmp(buf, "XSeed", 5) == 0) {
  2899. i = 5;
  2900. while (isspace(buf[i]) || buf[i] == '=') {
  2901. i++;
  2902. }
  2903. for (j=0; j<b/8; i+=2,j++) {
  2904. hex_to_byteval(&buf[i], &XSeed[j]);
  2905. }
  2906. fputs(buf, rngresp);
  2907. rv = FIPS186Change_GenerateX(XKey, XSeed, GENX);
  2908. if (rv != SECSuccess) {
  2909. goto loser;
  2910. }
  2911. fputs("X = ", rngresp);
  2912. if (hasQ) {
  2913. rv = FIPS186Change_ReduceModQForDSA(GENX, Q, DSAX);
  2914. if (rv != SECSuccess) {
  2915. goto loser;
  2916. }
  2917. to_hex_str(buf, DSAX, sizeof DSAX);
  2918. } else {
  2919. to_hex_str(buf, GENX, sizeof GENX);
  2920. }
  2921. fputs(buf, rngresp);
  2922. fputc('\n', rngresp);
  2923. continue;
  2924. }
  2925. }
  2926. loser:
  2927. fclose(rngreq);
  2928. }
  2929. /*
  2930. * Perform the RNG Monte Carlo Test (MCT) for the RNG algorithm
  2931. * "DSA - Generation of X", used both as specified and as a generic
  2932. * purpose RNG. The presence of "Q = ..." in the REQUEST file
  2933. * indicates we are using the algorithm as specified.
  2934. *
  2935. * reqfn is the pathname of the REQUEST file.
  2936. *
  2937. * The output RESPONSE file is written to stdout.
  2938. */
  2939. void
  2940. rng_mct(char *reqfn)
  2941. {
  2942. char buf[256]; /* holds one line from the input REQUEST file.
  2943. * needs to be large enough to hold the longest
  2944. * line "XSeed = <128 hex digits>\n".
  2945. */
  2946. FILE *rngreq; /* input stream from the REQUEST file */
  2947. FILE *rngresp; /* output stream to the RESPONSE file */
  2948. unsigned int i, j;
  2949. unsigned char Q[DSA_SUBPRIME_LEN];
  2950. PRBool hasQ = PR_FALSE;
  2951. unsigned int b; /* 160 <= b <= 512, b is a multiple of 8 */
  2952. unsigned char XKey[512/8];
  2953. unsigned char XSeed[512/8];
  2954. unsigned char GENX[2*SHA1_LENGTH];
  2955. unsigned char DSAX[DSA_SUBPRIME_LEN];
  2956. SECStatus rv;
  2957. rngreq = fopen(reqfn, "r");
  2958. rngresp = stdout;
  2959. while (fgets(buf, sizeof buf, rngreq) != NULL) {
  2960. /* a comment or blank line */
  2961. if (buf[0] == '#' || buf[0] == '\n') {
  2962. fputs(buf, rngresp);
  2963. continue;
  2964. }
  2965. /* [Xchange - SHA1] */
  2966. if (buf[0] == '[') {
  2967. fputs(buf, rngresp);
  2968. continue;
  2969. }
  2970. /* Q = ... */
  2971. if (buf[0] == 'Q') {
  2972. i = 1;
  2973. while (isspace(buf[i]) || buf[i] == '=') {
  2974. i++;
  2975. }
  2976. for (j=0; j<sizeof Q; i+=2,j++) {
  2977. hex_to_byteval(&buf[i], &Q[j]);
  2978. }
  2979. fputs(buf, rngresp);
  2980. hasQ = PR_TRUE;
  2981. continue;
  2982. }
  2983. /* "COUNT = x" begins a new data set */
  2984. if (strncmp(buf, "COUNT", 5) == 0) {
  2985. /* zeroize the variables for the test with this data set */
  2986. b = 0;
  2987. memset(XKey, 0, sizeof XKey);
  2988. memset(XSeed, 0, sizeof XSeed);
  2989. fputs(buf, rngresp);
  2990. continue;
  2991. }
  2992. /* b = ... */
  2993. if (buf[0] == 'b') {
  2994. i = 1;
  2995. while (isspace(buf[i]) || buf[i] == '=') {
  2996. i++;
  2997. }
  2998. b = atoi(&buf[i]);
  2999. if (b < 160 || b > 512 || b%8 != 0) {
  3000. goto loser;
  3001. }
  3002. fputs(buf, rngresp);
  3003. continue;
  3004. }
  3005. /* XKey = ... */
  3006. if (strncmp(buf, "XKey", 4) == 0) {
  3007. i = 4;
  3008. while (isspace(buf[i]) || buf[i] == '=') {
  3009. i++;
  3010. }
  3011. for (j=0; j<b/8; i+=2,j++) {
  3012. hex_to_byteval(&buf[i], &XKey[j]);
  3013. }
  3014. fputs(buf, rngresp);
  3015. continue;
  3016. }
  3017. /* XSeed = ... */
  3018. if (strncmp(buf, "XSeed", 5) == 0) {
  3019. unsigned int k;
  3020. i = 5;
  3021. while (isspace(buf[i]) || buf[i] == '=') {
  3022. i++;
  3023. }
  3024. for (j=0; j<b/8; i+=2,j++) {
  3025. hex_to_byteval(&buf[i], &XSeed[j]);
  3026. }
  3027. fputs(buf, rngresp);
  3028. for (k = 0; k < 10000; k++) {
  3029. rv = FIPS186Change_GenerateX(XKey, XSeed, GENX);
  3030. if (rv != SECSuccess) {
  3031. goto loser;
  3032. }
  3033. }
  3034. fputs("X = ", rngresp);
  3035. if (hasQ) {
  3036. rv = FIPS186Change_ReduceModQForDSA(GENX, Q, DSAX);
  3037. if (rv != SECSuccess) {
  3038. goto loser;
  3039. }
  3040. to_hex_str(buf, DSAX, sizeof DSAX);
  3041. } else {
  3042. to_hex_str(buf, GENX, sizeof GENX);
  3043. }
  3044. fputs(buf, rngresp);
  3045. fputc('\n', rngresp);
  3046. continue;
  3047. }
  3048. }
  3049. loser:
  3050. fclose(rngreq);
  3051. }
  3052. /*
  3053. * Calculate the SHA Message Digest
  3054. *
  3055. * MD = Message digest
  3056. * MDLen = length of Message Digest and SHA_Type
  3057. * msg = message to digest
  3058. * msgLen = length of message to digest
  3059. */
  3060. SECStatus sha_calcMD(unsigned char *MD, unsigned int MDLen, unsigned char *msg, unsigned int msgLen)
  3061. {
  3062. SECStatus sha_status = SECFailure;
  3063. if (MDLen == SHA1_LENGTH) {
  3064. sha_status = SHA1_HashBuf(MD, msg, msgLen);
  3065. } else if (MDLen == SHA256_LENGTH) {
  3066. sha_status = SHA256_HashBuf(MD, msg, msgLen);
  3067. } else if (MDLen == SHA384_LENGTH) {
  3068. sha_status = SHA384_HashBuf(MD, msg, msgLen);
  3069. } else if (MDLen == SHA512_LENGTH) {
  3070. sha_status = SHA512_HashBuf(MD, msg, msgLen);
  3071. }
  3072. return sha_status;
  3073. }
  3074. /*
  3075. * Perform the SHA Monte Carlo Test
  3076. *
  3077. * MDLen = length of Message Digest and SHA_Type
  3078. * seed = input seed value
  3079. * resp = is the output response file.
  3080. */
  3081. SECStatus sha_mct_test(unsigned int MDLen, unsigned char *seed, FILE *resp)
  3082. {
  3083. int i, j;
  3084. unsigned int msgLen = MDLen*3;
  3085. unsigned char MD_i3[HASH_LENGTH_MAX]; /* MD[i-3] */
  3086. unsigned char MD_i2[HASH_LENGTH_MAX]; /* MD[i-2] */
  3087. unsigned char MD_i1[HASH_LENGTH_MAX]; /* MD[i-1] */
  3088. unsigned char MD_i[HASH_LENGTH_MAX]; /* MD[i] */
  3089. unsigned char msg[HASH_LENGTH_MAX*3];
  3090. char buf[HASH_LENGTH_MAX*2 + 1]; /* MAX buf MD_i as a hex string */
  3091. for (j=0; j<100; j++) {
  3092. /* MD_0 = MD_1 = MD_2 = seed */
  3093. memcpy(MD_i3, seed, MDLen);
  3094. memcpy(MD_i2, seed, MDLen);
  3095. memcpy(MD_i1, seed, MDLen);
  3096. for (i=3; i < 1003; i++) {
  3097. /* Mi = MD[i-3] || MD [i-2] || MD [i-1] */
  3098. memcpy(msg, MD_i3, MDLen);
  3099. memcpy(&msg[MDLen], MD_i2, MDLen);
  3100. memcpy(&msg[MDLen*2], MD_i1,MDLen);
  3101. /* MDi = SHA(Msg) */
  3102. if (sha_calcMD(MD_i, MDLen,
  3103. msg, msgLen) != SECSuccess) {
  3104. return SECFailure;
  3105. }
  3106. /* save MD[i-3] MD[i-2] MD[i-1] */
  3107. memcpy(MD_i3, MD_i2, MDLen);
  3108. memcpy(MD_i2, MD_i1, MDLen);
  3109. memcpy(MD_i1, MD_i, MDLen);
  3110. }
  3111. /* seed = MD_i */
  3112. memcpy(seed, MD_i, MDLen);
  3113. sprintf(buf, "COUNT = %d\n", j);
  3114. fputs(buf, resp);
  3115. /* output MD_i */
  3116. fputs("MD = ", resp);
  3117. to_hex_str(buf, MD_i, MDLen);
  3118. fputs(buf, resp);
  3119. fputc('\n', resp);
  3120. }
  3121. return SECSuccess;
  3122. }
  3123. /*
  3124. * Perform the SHA Tests.
  3125. *
  3126. * reqfn is the pathname of the input REQUEST file.
  3127. *
  3128. * The output RESPONSE file is written to stdout.
  3129. */
  3130. void sha_test(char *reqfn)
  3131. {
  3132. unsigned int i, j;
  3133. unsigned int MDlen; /* the length of the Message Digest in Bytes */
  3134. unsigned int msgLen; /* the length of the input Message in Bytes */
  3135. unsigned char *msg = NULL; /* holds the message to digest.*/
  3136. size_t bufSize = 25608; /*MAX buffer size */
  3137. char *buf = NULL; /* holds one line from the input REQUEST file.*/
  3138. unsigned char seed[HASH_LENGTH_MAX]; /* max size of seed 64 bytes */
  3139. unsigned char MD[HASH_LENGTH_MAX]; /* message digest */
  3140. FILE *req = NULL; /* input stream from the REQUEST file */
  3141. FILE *resp; /* output stream to the RESPONSE file */
  3142. buf = PORT_ZAlloc(bufSize);
  3143. if (buf == NULL) {
  3144. goto loser;
  3145. }
  3146. /* zeroize the variables for the test with this data set */
  3147. memset(seed, 0, sizeof seed);
  3148. req = fopen(reqfn, "r");
  3149. resp = stdout;
  3150. while (fgets(buf, bufSize, req) != NULL) {
  3151. /* a comment or blank line */
  3152. if (buf[0] == '#' || buf[0] == '\n') {
  3153. fputs(buf, resp);
  3154. continue;
  3155. }
  3156. /* [L = Length of the Message Digest and sha_type */
  3157. if (buf[0] == '[') {
  3158. if (strncmp(&buf[1], "L ", 1) == 0) {
  3159. i = 2;
  3160. while (isspace(buf[i]) || buf[i] == '=') {
  3161. i++;
  3162. }
  3163. MDlen = atoi(&buf[i]);
  3164. fputs(buf, resp);
  3165. continue;
  3166. }
  3167. }
  3168. /* Len = Length of the Input Message Length ... */
  3169. if (strncmp(buf, "Len", 3) == 0) {
  3170. i = 3;
  3171. while (isspace(buf[i]) || buf[i] == '=') {
  3172. i++;
  3173. }
  3174. if (msg) {
  3175. PORT_ZFree(msg,msgLen);
  3176. msg = NULL;
  3177. }
  3178. msgLen = atoi(&buf[i]); /* in bits */
  3179. if (msgLen%8 != 0) {
  3180. fprintf(stderr, "SHA tests are incorrectly configured for "
  3181. "BIT oriented implementations\n");
  3182. goto loser;
  3183. }
  3184. msgLen = msgLen/8; /* convert to bytes */
  3185. fputs(buf, resp);
  3186. msg = PORT_ZAlloc(msgLen);
  3187. if (msg == NULL && msgLen != 0) {
  3188. goto loser;
  3189. }
  3190. continue;
  3191. }
  3192. /* MSG = ... */
  3193. if (strncmp(buf, "Msg", 3) == 0) {
  3194. i = 3;
  3195. while (isspace(buf[i]) || buf[i] == '=') {
  3196. i++;
  3197. }
  3198. for (j=0; j< msgLen; i+=2,j++) {
  3199. hex_to_byteval(&buf[i], &msg[j]);
  3200. }
  3201. fputs(buf, resp);
  3202. /* calculate the Message Digest */
  3203. memset(MD, 0, sizeof MD);
  3204. if (sha_calcMD(MD, MDlen,
  3205. msg, msgLen) != SECSuccess) {
  3206. goto loser;
  3207. }
  3208. fputs("MD = ", resp);
  3209. to_hex_str(buf, MD, MDlen);
  3210. fputs(buf, resp);
  3211. fputc('\n', resp);
  3212. continue;
  3213. }
  3214. /* Seed = ... */
  3215. if (strncmp(buf, "Seed", 4) == 0) {
  3216. i = 4;
  3217. while (isspace(buf[i]) || buf[i] == '=') {
  3218. i++;
  3219. }
  3220. for (j=0; j<sizeof seed; i+=2,j++) {
  3221. hex_to_byteval(&buf[i], &seed[j]);
  3222. }
  3223. fputs(buf, resp);
  3224. fputc('\n', resp);
  3225. /* do the Monte Carlo test */
  3226. if (sha_mct_test(MDlen, seed, resp) != SECSuccess) {
  3227. goto loser;
  3228. }
  3229. continue;
  3230. }
  3231. }
  3232. loser:
  3233. if (req) {
  3234. fclose(req);
  3235. }
  3236. if (buf) {
  3237. PORT_ZFree(buf, bufSize);
  3238. }
  3239. if (msg) {
  3240. PORT_ZFree(msg, msgLen);
  3241. }
  3242. }
  3243. /****************************************************/
  3244. /* HMAC SHA-X calc */
  3245. /* hmac_computed - the computed HMAC */
  3246. /* hmac_length - the length of the computed HMAC */
  3247. /* secret_key - secret key to HMAC */
  3248. /* secret_key_length - length of secret key, */
  3249. /* message - message to HMAC */
  3250. /* message_length - length ofthe message */
  3251. /****************************************************/
  3252. static SECStatus
  3253. hmac_calc(unsigned char *hmac_computed,
  3254. const unsigned int hmac_length,
  3255. const unsigned char *secret_key,
  3256. const unsigned int secret_key_length,
  3257. const unsigned char *message,
  3258. const unsigned int message_length,
  3259. const HASH_HashType hashAlg )
  3260. {
  3261. SECStatus hmac_status = SECFailure;
  3262. HMACContext *cx = NULL;
  3263. SECHashObject *hashObj = NULL;
  3264. unsigned int bytes_hashed = 0;
  3265. hashObj = (SECHashObject *) HASH_GetRawHashObject(hashAlg);
  3266. if (!hashObj)
  3267. return( SECFailure );
  3268. cx = HMAC_Create(hashObj, secret_key,
  3269. secret_key_length,
  3270. PR_TRUE); /* PR_TRUE for in FIPS mode */
  3271. if (cx == NULL)
  3272. return( SECFailure );
  3273. HMAC_Begin(cx);
  3274. HMAC_Update(cx, message, message_length);
  3275. hmac_status = HMAC_Finish(cx, hmac_computed, &bytes_hashed,
  3276. hmac_length);
  3277. HMAC_Destroy(cx, PR_TRUE);
  3278. return( hmac_status );
  3279. }
  3280. /*
  3281. * Perform the HMAC Tests.
  3282. *
  3283. * reqfn is the pathname of the input REQUEST file.
  3284. *
  3285. * The output RESPONSE file is written to stdout.
  3286. */
  3287. void hmac_test(char *reqfn)
  3288. {
  3289. unsigned int i, j;
  3290. size_t bufSize = 400; /* MAX buffer size */
  3291. char *buf = NULL; /* holds one line from the input REQUEST file.*/
  3292. unsigned int keyLen; /* Key Length */
  3293. unsigned char key[200]; /* key MAX size = 184 */
  3294. unsigned int msgLen = 128; /* the length of the input */
  3295. /* Message is always 128 Bytes */
  3296. unsigned char *msg = NULL; /* holds the message to digest.*/
  3297. unsigned int HMACLen; /* the length of the HMAC Bytes */
  3298. unsigned int TLen; /* the length of the requested */
  3299. /* truncated HMAC Bytes */
  3300. unsigned char HMAC[HASH_LENGTH_MAX]; /* computed HMAC */
  3301. unsigned char expectedHMAC[HASH_LENGTH_MAX]; /* for .fax files that have */
  3302. /* supplied known answer */
  3303. HASH_HashType hash_alg; /* HMAC type */
  3304. FILE *req = NULL; /* input stream from the REQUEST file */
  3305. FILE *resp; /* output stream to the RESPONSE file */
  3306. buf = PORT_ZAlloc(bufSize);
  3307. if (buf == NULL) {
  3308. goto loser;
  3309. }
  3310. msg = PORT_ZAlloc(msgLen);
  3311. memset(msg, 0, msgLen);
  3312. if (msg == NULL) {
  3313. goto loser;
  3314. }
  3315. req = fopen(reqfn, "r");
  3316. resp = stdout;
  3317. while (fgets(buf, bufSize, req) != NULL) {
  3318. if (strncmp(buf, "Mac", 3) == 0) {
  3319. i = 3;
  3320. while (isspace(buf[i]) || buf[i] == '=') {
  3321. i++;
  3322. }
  3323. memset(expectedHMAC, 0, HASH_LENGTH_MAX);
  3324. for (j=0; isxdigit(buf[i]); i+=2,j++) {
  3325. hex_to_byteval(&buf[i], &expectedHMAC[j]);
  3326. }
  3327. if (memcmp(HMAC, expectedHMAC, TLen) != 0) {
  3328. fprintf(stderr, "Generate failed:\n");
  3329. fputs( " expected=", stderr);
  3330. to_hex_str(buf, expectedHMAC,
  3331. TLen);
  3332. fputs(buf, stderr);
  3333. fputs("\n generated=", stderr);
  3334. to_hex_str(buf, HMAC,
  3335. TLen);
  3336. fputs(buf, stderr);
  3337. fputc('\n', stderr);
  3338. }
  3339. }
  3340. /* a comment or blank line */
  3341. if (buf[0] == '#' || buf[0] == '\n') {
  3342. fputs(buf, resp);
  3343. continue;
  3344. }
  3345. /* [L = Length of the MAC and HASH_type */
  3346. if (buf[0] == '[') {
  3347. if (strncmp(&buf[1], "L ", 1) == 0) {
  3348. i = 2;
  3349. while (isspace(buf[i]) || buf[i] == '=') {
  3350. i++;
  3351. }
  3352. /* HMACLen will get reused for Tlen */
  3353. HMACLen = atoi(&buf[i]);
  3354. /* set the HASH algorithm for HMAC */
  3355. if (HMACLen == SHA1_LENGTH) {
  3356. hash_alg = HASH_AlgSHA1;
  3357. } else if (HMACLen == SHA256_LENGTH) {
  3358. hash_alg = HASH_AlgSHA256;
  3359. } else if (HMACLen == SHA384_LENGTH) {
  3360. hash_alg = HASH_AlgSHA384;
  3361. } else if (HMACLen == SHA512_LENGTH) {
  3362. hash_alg = HASH_AlgSHA512;
  3363. } else {
  3364. goto loser;
  3365. }
  3366. fputs(buf, resp);
  3367. continue;
  3368. }
  3369. }
  3370. /* Count = test iteration number*/
  3371. if (strncmp(buf, "Count ", 5) == 0) {
  3372. /* count can just be put into resp file */
  3373. fputs(buf, resp);
  3374. /* zeroize the variables for the test with this data set */
  3375. keyLen = 0;
  3376. TLen = 0;
  3377. memset(key, 0, sizeof key);
  3378. memset(msg, 0, sizeof msg);
  3379. memset(HMAC, 0, sizeof HMAC);
  3380. continue;
  3381. }
  3382. /* KLen = Length of the Input Secret Key ... */
  3383. if (strncmp(buf, "Klen", 4) == 0) {
  3384. i = 4;
  3385. while (isspace(buf[i]) || buf[i] == '=') {
  3386. i++;
  3387. }
  3388. keyLen = atoi(&buf[i]); /* in bytes */
  3389. fputs(buf, resp);
  3390. continue;
  3391. }
  3392. /* key = the secret key for the key to MAC */
  3393. if (strncmp(buf, "Key", 3) == 0) {
  3394. i = 3;
  3395. while (isspace(buf[i]) || buf[i] == '=') {
  3396. i++;
  3397. }
  3398. for (j=0; j< keyLen; i+=2,j++) {
  3399. hex_to_byteval(&buf[i], &key[j]);
  3400. }
  3401. fputs(buf, resp);
  3402. }
  3403. /* TLen = Length of the calculated HMAC */
  3404. if (strncmp(buf, "Tlen", 4) == 0) {
  3405. i = 4;
  3406. while (isspace(buf[i]) || buf[i] == '=') {
  3407. i++;
  3408. }
  3409. TLen = atoi(&buf[i]); /* in bytes */
  3410. fputs(buf, resp);
  3411. continue;
  3412. }
  3413. /* MSG = to HMAC always 128 bytes for these tests */
  3414. if (strncmp(buf, "Msg", 3) == 0) {
  3415. i = 3;
  3416. while (isspace(buf[i]) || buf[i] == '=') {
  3417. i++;
  3418. }
  3419. for (j=0; j< msgLen; i+=2,j++) {
  3420. hex_to_byteval(&buf[i], &msg[j]);
  3421. }
  3422. fputs(buf, resp);
  3423. /* calculate the HMAC and output */
  3424. if (hmac_calc(HMAC, HMACLen, key, keyLen,
  3425. msg, msgLen, hash_alg) != SECSuccess) {
  3426. goto loser;
  3427. }
  3428. fputs("MAC = ", resp);
  3429. to_hex_str(buf, HMAC, TLen);
  3430. fputs(buf, resp);
  3431. fputc('\n', resp);
  3432. continue;
  3433. }
  3434. }
  3435. loser:
  3436. if (req) {
  3437. fclose(req);
  3438. }
  3439. if (buf) {
  3440. PORT_ZFree(buf, bufSize);
  3441. }
  3442. if (msg) {
  3443. PORT_ZFree(msg, msgLen);
  3444. }
  3445. }
  3446. /*
  3447. * Perform the DSA Key Pair Generation Test.
  3448. *
  3449. * reqfn is the pathname of the REQUEST file.
  3450. *
  3451. * The output RESPONSE file is written to stdout.
  3452. */
  3453. void
  3454. dsa_keypair_test(char *reqfn)
  3455. {
  3456. char buf[260]; /* holds one line from the input REQUEST file
  3457. * or to the output RESPONSE file.
  3458. * 257 to hold (128 public key (x2 for HEX) + 1'\n'
  3459. */
  3460. FILE *dsareq; /* input stream from the REQUEST file */
  3461. FILE *dsaresp; /* output stream to the RESPONSE file */
  3462. int N; /* number of time to generate key pair */
  3463. int modulus;
  3464. int i;
  3465. PQGParams *pqg = NULL;
  3466. PQGVerify *vfy = NULL;
  3467. int keySizeIndex; /* index for valid key sizes */
  3468. dsareq = fopen(reqfn, "r");
  3469. dsaresp = stdout;
  3470. while (fgets(buf, sizeof buf, dsareq) != NULL) {
  3471. /* a comment or blank line */
  3472. if (buf[0] == '#' || buf[0] == '\n') {
  3473. fputs(buf, dsaresp);
  3474. continue;
  3475. }
  3476. /* [Mod = x] */
  3477. if (buf[0] == '[') {
  3478. if(pqg!=NULL) {
  3479. PQG_DestroyParams(pqg);
  3480. pqg = NULL;
  3481. }
  3482. if(vfy!=NULL) {
  3483. PQG_DestroyVerify(vfy);
  3484. vfy = NULL;
  3485. }
  3486. if (sscanf(buf, "[mod = %d]", &modulus) != 1) {
  3487. goto loser;
  3488. }
  3489. fputs(buf, dsaresp);
  3490. fputc('\n', dsaresp);
  3491. /*****************************************************************
  3492. * PQG_ParamGenSeedLen doesn't take a key size, it takes an index
  3493. * that points to a valid key size.
  3494. */
  3495. keySizeIndex = PQG_PBITS_TO_INDEX(modulus);
  3496. if(keySizeIndex == -1 || modulus<512 || modulus>1024) {
  3497. fprintf(dsaresp,
  3498. "DSA key size must be a multiple of 64 between 512 "
  3499. "and 1024, inclusive");
  3500. goto loser;
  3501. }
  3502. /* Generate the parameters P, Q, and G */
  3503. if (PQG_ParamGenSeedLen(keySizeIndex, PQG_TEST_SEED_BYTES,
  3504. &pqg, &vfy) != SECSuccess) {
  3505. fprintf(dsaresp, "ERROR: Unable to generate PQG parameters");
  3506. goto loser;
  3507. }
  3508. /* output P, Q, and G */
  3509. to_hex_str(buf, pqg->prime.data, pqg->prime.len);
  3510. fprintf(dsaresp, "P = %s\n", buf);
  3511. to_hex_str(buf, pqg->subPrime.data, pqg->subPrime.len);
  3512. fprintf(dsaresp, "Q = %s\n", buf);
  3513. to_hex_str(buf, pqg->base.data, pqg->base.len);
  3514. fprintf(dsaresp, "G = %s\n\n", buf);
  3515. continue;
  3516. }
  3517. /* N = ...*/
  3518. if (buf[0] == 'N') {
  3519. if (sscanf(buf, "N = %d", &N) != 1) {
  3520. goto loser;
  3521. }
  3522. /* Generate a DSA key, and output the key pair for N times */
  3523. for (i = 0; i < N; i++) {
  3524. DSAPrivateKey *dsakey = NULL;
  3525. if (DSA_NewKey(pqg, &dsakey) != SECSuccess) {
  3526. fprintf(dsaresp, "ERROR: Unable to generate DSA key");
  3527. goto loser;
  3528. }
  3529. to_hex_str(buf, dsakey->privateValue.data,
  3530. dsakey->privateValue.len);
  3531. fprintf(dsaresp, "X = %s\n", buf);
  3532. to_hex_str(buf, dsakey->publicValue.data,
  3533. dsakey->publicValue.len);
  3534. fprintf(dsaresp, "Y = %s\n\n", buf);
  3535. PORT_FreeArena(dsakey->params.arena, PR_TRUE);
  3536. dsakey = NULL;
  3537. }
  3538. continue;
  3539. }
  3540. }
  3541. loser:
  3542. fclose(dsareq);
  3543. }
  3544. /*
  3545. * Perform the DSA Domain Parameter Validation Test.
  3546. *
  3547. * reqfn is the pathname of the REQUEST file.
  3548. *
  3549. * The output RESPONSE file is written to stdout.
  3550. */
  3551. void
  3552. dsa_pqgver_test(char *reqfn)
  3553. {
  3554. char buf[263]; /* holds one line from the input REQUEST file
  3555. * or to the output RESPONSE file.
  3556. * 260 to hold (128 public key (x2 for HEX) + P = ...
  3557. */
  3558. FILE *dsareq; /* input stream from the REQUEST file */
  3559. FILE *dsaresp; /* output stream to the RESPONSE file */
  3560. int modulus;
  3561. unsigned int i, j;
  3562. PQGParams pqg;
  3563. PQGVerify vfy;
  3564. unsigned int pghSize; /* size for p, g, and h */
  3565. dsareq = fopen(reqfn, "r");
  3566. dsaresp = stdout;
  3567. memset(&pqg, 0, sizeof(pqg));
  3568. memset(&vfy, 0, sizeof(vfy));
  3569. while (fgets(buf, sizeof buf, dsareq) != NULL) {
  3570. /* a comment or blank line */
  3571. if (buf[0] == '#' || buf[0] == '\n') {
  3572. fputs(buf, dsaresp);
  3573. continue;
  3574. }
  3575. /* [Mod = x] */
  3576. if (buf[0] == '[') {
  3577. if (sscanf(buf, "[mod = %d]", &modulus) != 1) {
  3578. goto loser;
  3579. }
  3580. if (pqg.prime.data) { /* P */
  3581. SECITEM_ZfreeItem(&pqg.prime, PR_FALSE);
  3582. }
  3583. if (pqg.subPrime.data) { /* Q */
  3584. SECITEM_ZfreeItem(&pqg.subPrime, PR_FALSE);
  3585. }
  3586. if (pqg.base.data) { /* G */
  3587. SECITEM_ZfreeItem(&pqg.base, PR_FALSE);
  3588. }
  3589. if (vfy.seed.data) { /* seed */
  3590. SECITEM_ZfreeItem(&vfy.seed, PR_FALSE);
  3591. }
  3592. if (vfy.h.data) { /* H */
  3593. SECITEM_ZfreeItem(&vfy.h, PR_FALSE);
  3594. }
  3595. fputs(buf, dsaresp);
  3596. /*calculate the size of p, g, and h then allocate items */
  3597. pghSize = modulus/8;
  3598. SECITEM_AllocItem(NULL, &pqg.prime, pghSize);
  3599. SECITEM_AllocItem(NULL, &pqg.base, pghSize);
  3600. SECITEM_AllocItem(NULL, &vfy.h, pghSize);
  3601. pqg.prime.len = pqg.base.len = vfy.h.len = pghSize;
  3602. /* seed and q are always 20 bytes */
  3603. SECITEM_AllocItem(NULL, &vfy.seed, 20);
  3604. SECITEM_AllocItem(NULL, &pqg.subPrime, 20);
  3605. vfy.seed.len = pqg.subPrime.len = 20;
  3606. vfy.counter = 0;
  3607. continue;
  3608. }
  3609. /* P = ... */
  3610. if (buf[0] == 'P') {
  3611. i = 1;
  3612. while (isspace(buf[i]) || buf[i] == '=') {
  3613. i++;
  3614. }
  3615. for (j=0; j< pqg.prime.len; i+=2,j++) {
  3616. hex_to_byteval(&buf[i], &pqg.prime.data[j]);
  3617. }
  3618. fputs(buf, dsaresp);
  3619. continue;
  3620. }
  3621. /* Q = ... */
  3622. if (buf[0] == 'Q') {
  3623. i = 1;
  3624. while (isspace(buf[i]) || buf[i] == '=') {
  3625. i++;
  3626. }
  3627. for (j=0; j< pqg.subPrime.len; i+=2,j++) {
  3628. hex_to_byteval(&buf[i], &pqg.subPrime.data[j]);
  3629. }
  3630. fputs(buf, dsaresp);
  3631. continue;
  3632. }
  3633. /* G = ... */
  3634. if (buf[0] == 'G') {
  3635. i = 1;
  3636. while (isspace(buf[i]) || buf[i] == '=') {
  3637. i++;
  3638. }
  3639. for (j=0; j< pqg.base.len; i+=2,j++) {
  3640. hex_to_byteval(&buf[i], &pqg.base.data[j]);
  3641. }
  3642. fputs(buf, dsaresp);
  3643. continue;
  3644. }
  3645. /* Seed = ... */
  3646. if (strncmp(buf, "Seed", 4) == 0) {
  3647. i = 4;
  3648. while (isspace(buf[i]) || buf[i] == '=') {
  3649. i++;
  3650. }
  3651. for (j=0; j< vfy.seed.len; i+=2,j++) {
  3652. hex_to_byteval(&buf[i], &vfy.seed.data[j]);
  3653. }
  3654. fputs(buf, dsaresp);
  3655. continue;
  3656. }
  3657. /* c = ... */
  3658. if (buf[0] == 'c') {
  3659. if (sscanf(buf, "c = %u", &vfy.counter) != 1) {
  3660. goto loser;
  3661. }
  3662. fputs(buf, dsaresp);
  3663. continue;
  3664. }
  3665. /* H = ... */
  3666. if (buf[0] == 'H') {
  3667. SECStatus rv, result = SECFailure;
  3668. i = 1;
  3669. while (isspace(buf[i]) || buf[i] == '=') {
  3670. i++;
  3671. }
  3672. for (j=0; j< vfy.h.len; i+=2,j++) {
  3673. hex_to_byteval(&buf[i], &vfy.h.data[j]);
  3674. }
  3675. fputs(buf, dsaresp);
  3676. /* Verify the Parameters */
  3677. rv = PQG_VerifyParams(&pqg, &vfy, &result);
  3678. if (rv != SECSuccess) {
  3679. goto loser;
  3680. }
  3681. if (result == SECSuccess) {
  3682. fprintf(dsaresp, "Result = P\n");
  3683. } else {
  3684. fprintf(dsaresp, "Result = F\n");
  3685. }
  3686. continue;
  3687. }
  3688. }
  3689. loser:
  3690. fclose(dsareq);
  3691. if (pqg.prime.data) { /* P */
  3692. SECITEM_ZfreeItem(&pqg.prime, PR_FALSE);
  3693. }
  3694. if (pqg.subPrime.data) { /* Q */
  3695. SECITEM_ZfreeItem(&pqg.subPrime, PR_FALSE);
  3696. }
  3697. if (pqg.base.data) { /* G */
  3698. SECITEM_ZfreeItem(&pqg.base, PR_FALSE);
  3699. }
  3700. if (vfy.seed.data) { /* seed */
  3701. SECITEM_ZfreeItem(&vfy.seed, PR_FALSE);
  3702. }
  3703. if (vfy.h.data) { /* H */
  3704. SECITEM_ZfreeItem(&vfy.h, PR_FALSE);
  3705. }
  3706. }
  3707. /*
  3708. * Perform the DSA Public Key Validation Test.
  3709. *
  3710. * reqfn is the pathname of the REQUEST file.
  3711. *
  3712. * The output RESPONSE file is written to stdout.
  3713. */
  3714. void
  3715. dsa_pqggen_test(char *reqfn)
  3716. {
  3717. char buf[263]; /* holds one line from the input REQUEST file
  3718. * or to the output RESPONSE file.
  3719. * 263 to hold seed = (128 public key (x2 for HEX)
  3720. */
  3721. FILE *dsareq; /* input stream from the REQUEST file */
  3722. FILE *dsaresp; /* output stream to the RESPONSE file */
  3723. int N; /* number of times to generate parameters */
  3724. int modulus;
  3725. int i;
  3726. unsigned int j;
  3727. PQGParams *pqg = NULL;
  3728. PQGVerify *vfy = NULL;
  3729. unsigned int keySizeIndex;
  3730. dsareq = fopen(reqfn, "r");
  3731. dsaresp = stdout;
  3732. while (fgets(buf, sizeof buf, dsareq) != NULL) {
  3733. /* a comment or blank line */
  3734. if (buf[0] == '#' || buf[0] == '\n') {
  3735. fputs(buf, dsaresp);
  3736. continue;
  3737. }
  3738. /* [Mod = ... ] */
  3739. if (buf[0] == '[') {
  3740. if (sscanf(buf, "[mod = %d]", &modulus) != 1) {
  3741. goto loser;
  3742. }
  3743. fputs(buf, dsaresp);
  3744. fputc('\n', dsaresp);
  3745. /****************************************************************
  3746. * PQG_ParamGenSeedLen doesn't take a key size, it takes an index
  3747. * that points to a valid key size.
  3748. */
  3749. keySizeIndex = PQG_PBITS_TO_INDEX(modulus);
  3750. if(keySizeIndex == -1 || modulus<512 || modulus>1024) {
  3751. fprintf(dsaresp,
  3752. "DSA key size must be a multiple of 64 between 512 "
  3753. "and 1024, inclusive");
  3754. goto loser;
  3755. }
  3756. continue;
  3757. }
  3758. /* N = ... */
  3759. if (buf[0] == 'N') {
  3760. if (sscanf(buf, "N = %d", &N) != 1) {
  3761. goto loser;
  3762. }
  3763. for (i = 0; i < N; i++) {
  3764. if (PQG_ParamGenSeedLen(keySizeIndex, PQG_TEST_SEED_BYTES,
  3765. &pqg, &vfy) != SECSuccess) {
  3766. fprintf(dsaresp,
  3767. "ERROR: Unable to generate PQG parameters");
  3768. goto loser;
  3769. }
  3770. to_hex_str(buf, pqg->prime.data, pqg->prime.len);
  3771. fprintf(dsaresp, "P = %s\n", buf);
  3772. to_hex_str(buf, pqg->subPrime.data, pqg->subPrime.len);
  3773. fprintf(dsaresp, "Q = %s\n", buf);
  3774. to_hex_str(buf, pqg->base.data, pqg->base.len);
  3775. fprintf(dsaresp, "G = %s\n", buf);
  3776. to_hex_str(buf, vfy->seed.data, vfy->seed.len);
  3777. fprintf(dsaresp, "Seed = %s\n", buf);
  3778. fprintf(dsaresp, "c = %d\n", vfy->counter);
  3779. to_hex_str(buf, vfy->h.data, vfy->h.len);
  3780. fputs("H = ", dsaresp);
  3781. for (j=vfy->h.len; j<pqg->prime.len; j++) {
  3782. fprintf(dsaresp, "00");
  3783. }
  3784. fprintf(dsaresp, "%s\n", buf);
  3785. fputc('\n', dsaresp);
  3786. if(pqg!=NULL) {
  3787. PQG_DestroyParams(pqg);
  3788. pqg = NULL;
  3789. }
  3790. if(vfy!=NULL) {
  3791. PQG_DestroyVerify(vfy);
  3792. vfy = NULL;
  3793. }
  3794. }
  3795. continue;
  3796. }
  3797. }
  3798. loser:
  3799. fclose(dsareq);
  3800. if(pqg!=NULL) {
  3801. PQG_DestroyParams(pqg);
  3802. }
  3803. if(vfy!=NULL) {
  3804. PQG_DestroyVerify(vfy);
  3805. }
  3806. }
  3807. /*
  3808. * Perform the DSA Signature Generation Test.
  3809. *
  3810. * reqfn is the pathname of the REQUEST file.
  3811. *
  3812. * The output RESPONSE file is written to stdout.
  3813. */
  3814. void
  3815. dsa_siggen_test(char *reqfn)
  3816. {
  3817. char buf[263]; /* holds one line from the input REQUEST file
  3818. * or to the output RESPONSE file.
  3819. * max for Msg = ....
  3820. */
  3821. FILE *dsareq; /* input stream from the REQUEST file */
  3822. FILE *dsaresp; /* output stream to the RESPONSE file */
  3823. int modulus;
  3824. int i, j;
  3825. PQGParams *pqg = NULL;
  3826. PQGVerify *vfy = NULL;
  3827. DSAPrivateKey *dsakey = NULL;
  3828. int keySizeIndex; /* index for valid key sizes */
  3829. unsigned char sha1[20]; /* SHA-1 hash (160 bits) */
  3830. unsigned char sig[DSA_SIGNATURE_LEN];
  3831. SECItem digest, signature;
  3832. dsareq = fopen(reqfn, "r");
  3833. dsaresp = stdout;
  3834. while (fgets(buf, sizeof buf, dsareq) != NULL) {
  3835. /* a comment or blank line */
  3836. if (buf[0] == '#' || buf[0] == '\n') {
  3837. fputs(buf, dsaresp);
  3838. continue;
  3839. }
  3840. /* [Mod = x] */
  3841. if (buf[0] == '[') {
  3842. if(pqg!=NULL) {
  3843. PQG_DestroyParams(pqg);
  3844. pqg = NULL;
  3845. }
  3846. if(vfy!=NULL) {
  3847. PQG_DestroyVerify(vfy);
  3848. vfy = NULL;
  3849. }
  3850. if (dsakey != NULL) {
  3851. PORT_FreeArena(dsakey->params.arena, PR_TRUE);
  3852. dsakey = NULL;
  3853. }
  3854. if (sscanf(buf, "[mod = %d]", &modulus) != 1) {
  3855. goto loser;
  3856. }
  3857. fputs(buf, dsaresp);
  3858. fputc('\n', dsaresp);
  3859. /****************************************************************
  3860. * PQG_ParamGenSeedLen doesn't take a key size, it takes an index
  3861. * that points to a valid key size.
  3862. */
  3863. keySizeIndex = PQG_PBITS_TO_INDEX(modulus);
  3864. if(keySizeIndex == -1 || modulus<512 || modulus>1024) {
  3865. fprintf(dsaresp,
  3866. "DSA key size must be a multiple of 64 between 512 "
  3867. "and 1024, inclusive");
  3868. goto loser;
  3869. }
  3870. /* Generate PQG and output PQG */
  3871. if (PQG_ParamGenSeedLen(keySizeIndex, PQG_TEST_SEED_BYTES,
  3872. &pqg, &vfy) != SECSuccess) {
  3873. fprintf(dsaresp, "ERROR: Unable to generate PQG parameters");
  3874. goto loser;
  3875. }
  3876. to_hex_str(buf, pqg->prime.data, pqg->prime.len);
  3877. fprintf(dsaresp, "P = %s\n", buf);
  3878. to_hex_str(buf, pqg->subPrime.data, pqg->subPrime.len);
  3879. fprintf(dsaresp, "Q = %s\n", buf);
  3880. to_hex_str(buf, pqg->base.data, pqg->base.len);
  3881. fprintf(dsaresp, "G = %s\n", buf);
  3882. /* create DSA Key */
  3883. if (DSA_NewKey(pqg, &dsakey) != SECSuccess) {
  3884. fprintf(dsaresp, "ERROR: Unable to generate DSA key");
  3885. goto loser;
  3886. }
  3887. continue;
  3888. }
  3889. /* Msg = ... */
  3890. if (strncmp(buf, "Msg", 3) == 0) {
  3891. unsigned char msg[128]; /* MAX msg 128 */
  3892. unsigned int len = 0;
  3893. memset(sha1, 0, sizeof sha1);
  3894. memset(sig, 0, sizeof sig);
  3895. i = 3;
  3896. while (isspace(buf[i]) || buf[i] == '=') {
  3897. i++;
  3898. }
  3899. for (j=0; isxdigit(buf[i]); i+=2,j++) {
  3900. hex_to_byteval(&buf[i], &msg[j]);
  3901. }
  3902. if (SHA1_HashBuf(sha1, msg, j) != SECSuccess) {
  3903. fprintf(dsaresp, "ERROR: Unable to generate SHA1 digest");
  3904. goto loser;
  3905. }
  3906. digest.type = siBuffer;
  3907. digest.data = sha1;
  3908. digest.len = sizeof sha1;
  3909. signature.type = siBuffer;
  3910. signature.data = sig;
  3911. signature.len = sizeof sig;
  3912. if (DSA_SignDigest(dsakey, &signature, &digest) != SECSuccess) {
  3913. fprintf(dsaresp, "ERROR: Unable to generate DSA signature");
  3914. goto loser;
  3915. }
  3916. len = signature.len;
  3917. if (len%2 != 0) {
  3918. goto loser;
  3919. }
  3920. len = len/2;
  3921. /* output the orginal Msg, and generated Y, R, and S */
  3922. fputs(buf, dsaresp);
  3923. fputc('\n', dsaresp);
  3924. to_hex_str(buf, dsakey->publicValue.data,
  3925. dsakey->publicValue.len);
  3926. fprintf(dsaresp, "Y = %s\n", buf);
  3927. to_hex_str(buf, &signature.data[0], len);
  3928. fprintf(dsaresp, "R = %s\n", buf);
  3929. to_hex_str(buf, &signature.data[len], len);
  3930. fprintf(dsaresp, "S = %s\n", buf);
  3931. continue;
  3932. }
  3933. }
  3934. loser:
  3935. fclose(dsareq);
  3936. if(pqg != NULL) {
  3937. PQG_DestroyParams(pqg);
  3938. pqg = NULL;
  3939. }
  3940. if(vfy != NULL) {
  3941. PQG_DestroyVerify(vfy);
  3942. vfy = NULL;
  3943. }
  3944. if (dsakey) {
  3945. PORT_FreeArena(dsakey->params.arena, PR_TRUE);
  3946. dsakey = NULL;
  3947. }
  3948. }
  3949. /*
  3950. * Perform the DSA Signature Verification Test.
  3951. *
  3952. * reqfn is the pathname of the REQUEST file.
  3953. *
  3954. * The output RESPONSE file is written to stdout.
  3955. */
  3956. void
  3957. dsa_sigver_test(char *reqfn)
  3958. {
  3959. char buf[263]; /* holds one line from the input REQUEST file
  3960. * or to the output RESPONSE file.
  3961. * max for Msg = ....
  3962. */
  3963. FILE *dsareq; /* input stream from the REQUEST file */
  3964. FILE *dsaresp; /* output stream to the RESPONSE file */
  3965. int modulus;
  3966. unsigned int i, j;
  3967. SECItem digest, signature;
  3968. DSAPublicKey pubkey;
  3969. unsigned int pgySize; /* size for p, g, and y */
  3970. unsigned char sha1[20]; /* SHA-1 hash (160 bits) */
  3971. unsigned char sig[DSA_SIGNATURE_LEN];
  3972. dsareq = fopen(reqfn, "r");
  3973. dsaresp = stdout;
  3974. memset(&pubkey, 0, sizeof(pubkey));
  3975. while (fgets(buf, sizeof buf, dsareq) != NULL) {
  3976. /* a comment or blank line */
  3977. if (buf[0] == '#' || buf[0] == '\n') {
  3978. fputs(buf, dsaresp);
  3979. continue;
  3980. }
  3981. /* [Mod = x] */
  3982. if (buf[0] == '[') {
  3983. if (sscanf(buf, "[mod = %d]", &modulus) != 1) {
  3984. goto loser;
  3985. }
  3986. if (pubkey.params.prime.data) { /* P */
  3987. SECITEM_ZfreeItem(&pubkey.params.prime, PR_FALSE);
  3988. }
  3989. if (pubkey.params.subPrime.data) { /* Q */
  3990. SECITEM_ZfreeItem(&pubkey.params.subPrime, PR_FALSE);
  3991. }
  3992. if (pubkey.params.base.data) { /* G */
  3993. SECITEM_ZfreeItem(&pubkey.params.base, PR_FALSE);
  3994. }
  3995. if (pubkey.publicValue.data) { /* Y */
  3996. SECITEM_ZfreeItem(&pubkey.publicValue, PR_FALSE);
  3997. }
  3998. fputs(buf, dsaresp);
  3999. /* calculate the size of p, g, and y then allocate items */
  4000. pgySize = modulus/8;
  4001. SECITEM_AllocItem(NULL, &pubkey.params.prime, pgySize);
  4002. SECITEM_AllocItem(NULL, &pubkey.params.base, pgySize);
  4003. SECITEM_AllocItem(NULL, &pubkey.publicValue, pgySize);
  4004. pubkey.params.prime.len = pubkey.params.base.len = pgySize;
  4005. pubkey.publicValue.len = pgySize;
  4006. /* q always 20 bytes */
  4007. SECITEM_AllocItem(NULL, &pubkey.params.subPrime, 20);
  4008. pubkey.params.subPrime.len = 20;
  4009. continue;
  4010. }
  4011. /* P = ... */
  4012. if (buf[0] == 'P') {
  4013. i = 1;
  4014. while (isspace(buf[i]) || buf[i] == '=') {
  4015. i++;
  4016. }
  4017. memset(pubkey.params.prime.data, 0, pubkey.params.prime.len);
  4018. for (j=0; j< pubkey.params.prime.len; i+=2,j++) {
  4019. hex_to_byteval(&buf[i], &pubkey.params.prime.data[j]);
  4020. }
  4021. fputs(buf, dsaresp);
  4022. continue;
  4023. }
  4024. /* Q = ... */
  4025. if (buf[0] == 'Q') {
  4026. i = 1;
  4027. while (isspace(buf[i]) || buf[i] == '=') {
  4028. i++;
  4029. }
  4030. memset(pubkey.params.subPrime.data, 0, pubkey.params.subPrime.len);
  4031. for (j=0; j< pubkey.params.subPrime.len; i+=2,j++) {
  4032. hex_to_byteval(&buf[i], &pubkey.params.subPrime.data[j]);
  4033. }
  4034. fputs(buf, dsaresp);
  4035. continue;
  4036. }
  4037. /* G = ... */
  4038. if (buf[0] == 'G') {
  4039. i = 1;
  4040. while (isspace(buf[i]) || buf[i] == '=') {
  4041. i++;
  4042. }
  4043. memset(pubkey.params.base.data, 0, pubkey.params.base.len);
  4044. for (j=0; j< pubkey.params.base.len; i+=2,j++) {
  4045. hex_to_byteval(&buf[i], &pubkey.params.base.data[j]);
  4046. }
  4047. fputs(buf, dsaresp);
  4048. continue;
  4049. }
  4050. /* Msg = ... */
  4051. if (strncmp(buf, "Msg", 3) == 0) {
  4052. unsigned char msg[128]; /* MAX msg 128 */
  4053. memset(sha1, 0, sizeof sha1);
  4054. i = 3;
  4055. while (isspace(buf[i]) || buf[i] == '=') {
  4056. i++;
  4057. }
  4058. for (j=0; isxdigit(buf[i]); i+=2,j++) {
  4059. hex_to_byteval(&buf[i], &msg[j]);
  4060. }
  4061. if (SHA1_HashBuf(sha1, msg, j) != SECSuccess) {
  4062. fprintf(dsaresp, "ERROR: Unable to generate SHA1 digest");
  4063. goto loser;
  4064. }
  4065. fputs(buf, dsaresp);
  4066. continue;
  4067. }
  4068. /* Y = ... */
  4069. if (buf[0] == 'Y') {
  4070. i = 1;
  4071. while (isspace(buf[i]) || buf[i] == '=') {
  4072. i++;
  4073. }
  4074. memset(pubkey.publicValue.data, 0, pubkey.params.subPrime.len);
  4075. for (j=0; j< pubkey.publicValue.len; i+=2,j++) {
  4076. hex_to_byteval(&buf[i], &pubkey.publicValue.data[j]);
  4077. }
  4078. fputs(buf, dsaresp);
  4079. continue;
  4080. }
  4081. /* R = ... */
  4082. if (buf[0] == 'R') {
  4083. memset(sig, 0, sizeof sig);
  4084. i = 1;
  4085. while (isspace(buf[i]) || buf[i] == '=') {
  4086. i++;
  4087. }
  4088. for (j=0; j< DSA_SUBPRIME_LEN; i+=2,j++) {
  4089. hex_to_byteval(&buf[i], &sig[j]);
  4090. }
  4091. fputs(buf, dsaresp);
  4092. continue;
  4093. }
  4094. /* S = ... */
  4095. if (buf[0] == 'S') {
  4096. i = 1;
  4097. while (isspace(buf[i]) || buf[i] == '=') {
  4098. i++;
  4099. }
  4100. for (j=DSA_SUBPRIME_LEN; j< DSA_SIGNATURE_LEN; i+=2,j++) {
  4101. hex_to_byteval(&buf[i], &sig[j]);
  4102. }
  4103. fputs(buf, dsaresp);
  4104. digest.type = siBuffer;
  4105. digest.data = sha1;
  4106. digest.len = sizeof sha1;
  4107. signature.type = siBuffer;
  4108. signature.data = sig;
  4109. signature.len = sizeof sig;
  4110. if (DSA_VerifyDigest(&pubkey, &signature, &digest) == SECSuccess) {
  4111. fprintf(dsaresp, "Result = P\n");
  4112. } else {
  4113. fprintf(dsaresp, "Result = F\n");
  4114. }
  4115. continue;
  4116. }
  4117. }
  4118. loser:
  4119. fclose(dsareq);
  4120. if (pubkey.params.prime.data) { /* P */
  4121. SECITEM_ZfreeItem(&pubkey.params.prime, PR_FALSE);
  4122. }
  4123. if (pubkey.params.subPrime.data) { /* Q */
  4124. SECITEM_ZfreeItem(&pubkey.params.subPrime, PR_FALSE);
  4125. }
  4126. if (pubkey.params.base.data) { /* G */
  4127. SECITEM_ZfreeItem(&pubkey.params.base, PR_FALSE);
  4128. }
  4129. if (pubkey.publicValue.data) { /* Y */
  4130. SECITEM_ZfreeItem(&pubkey.publicValue, PR_FALSE);
  4131. }
  4132. }
  4133. /*
  4134. * Perform the RSA Signature Generation Test.
  4135. *
  4136. * reqfn is the pathname of the REQUEST file.
  4137. *
  4138. * The output RESPONSE file is written to stdout.
  4139. */
  4140. void
  4141. rsa_siggen_test(char *reqfn)
  4142. {
  4143. char buf[2*RSA_MAX_TEST_MODULUS_BYTES+1];
  4144. /* buf holds one line from the input REQUEST file
  4145. * or to the output RESPONSE file.
  4146. * 2x for HEX output + 1 for \n
  4147. */
  4148. FILE *rsareq; /* input stream from the REQUEST file */
  4149. FILE *rsaresp; /* output stream to the RESPONSE file */
  4150. int i, j;
  4151. unsigned char sha[HASH_LENGTH_MAX]; /* SHA digest */
  4152. unsigned int shaLength = 0; /* length of SHA */
  4153. HASH_HashType shaAlg = HASH_AlgNULL; /* type of SHA Alg */
  4154. SECOidTag shaOid = SEC_OID_UNKNOWN;
  4155. int modulus; /* the Modulus size */
  4156. int publicExponent = DEFAULT_RSA_PUBLIC_EXPONENT;
  4157. SECItem pe = {0, 0, 0 };
  4158. unsigned char pubEx[4];
  4159. int peCount = 0;
  4160. RSAPrivateKey *rsaBlapiPrivKey = NULL; /* holds RSA private and
  4161. * public keys */
  4162. RSAPublicKey *rsaBlapiPublicKey = NULL; /* hold RSA public key */
  4163. rsareq = fopen(reqfn, "r");
  4164. rsaresp = stdout;
  4165. /* calculate the exponent */
  4166. for (i=0; i < 4; i++) {
  4167. if (peCount || (publicExponent &
  4168. ((unsigned long)0xff000000L >> (i*8)))) {
  4169. pubEx[peCount] =
  4170. (unsigned char)((publicExponent >> (3-i)*8) & 0xff);
  4171. peCount++;
  4172. }
  4173. }
  4174. pe.len = peCount;
  4175. pe.data = &pubEx[0];
  4176. pe.type = siBuffer;
  4177. while (fgets(buf, sizeof buf, rsareq) != NULL) {
  4178. /* a comment or blank line */
  4179. if (buf[0] == '#' || buf[0] == '\n') {
  4180. fputs(buf, rsaresp);
  4181. continue;
  4182. }
  4183. /* [mod = ...] */
  4184. if (buf[0] == '[') {
  4185. if (sscanf(buf, "[mod = %d]", &modulus) != 1) {
  4186. goto loser;
  4187. }
  4188. if (modulus > RSA_MAX_TEST_MODULUS_BITS) {
  4189. fprintf(rsaresp,"ERROR: modulus greater than test maximum\n");
  4190. goto loser;
  4191. }
  4192. fputs(buf, rsaresp);
  4193. if (rsaBlapiPrivKey != NULL) {
  4194. PORT_FreeArena(rsaBlapiPrivKey->arena, PR_TRUE);
  4195. rsaBlapiPrivKey = NULL;
  4196. rsaBlapiPublicKey = NULL;
  4197. }
  4198. rsaBlapiPrivKey = RSA_NewKey(modulus, &pe);
  4199. if (rsaBlapiPrivKey == NULL) {
  4200. fprintf(rsaresp, "Error unable to create RSA key\n");
  4201. goto loser;
  4202. }
  4203. to_hex_str(buf, rsaBlapiPrivKey->modulus.data,
  4204. rsaBlapiPrivKey->modulus.len);
  4205. fprintf(rsaresp, "\nn = %s\n\n", buf);
  4206. to_hex_str(buf, rsaBlapiPrivKey->publicExponent.data,
  4207. rsaBlapiPrivKey->publicExponent.len);
  4208. fprintf(rsaresp, "e = %s\n", buf);
  4209. /* convert private key to public key. Memory
  4210. * is freed with private key's arena */
  4211. rsaBlapiPublicKey = (RSAPublicKey *)PORT_ArenaAlloc(
  4212. rsaBlapiPrivKey->arena,
  4213. sizeof(RSAPublicKey));
  4214. rsaBlapiPublicKey->modulus.len = rsaBlapiPrivKey->modulus.len;
  4215. rsaBlapiPublicKey->modulus.data = rsaBlapiPrivKey->modulus.data;
  4216. rsaBlapiPublicKey->publicExponent.len =
  4217. rsaBlapiPrivKey->publicExponent.len;
  4218. rsaBlapiPublicKey->publicExponent.data =
  4219. rsaBlapiPrivKey->publicExponent.data;
  4220. continue;
  4221. }
  4222. /* SHAAlg = ... */
  4223. if (strncmp(buf, "SHAAlg", 6) == 0) {
  4224. i = 6;
  4225. while (isspace(buf[i]) || buf[i] == '=') {
  4226. i++;
  4227. }
  4228. /* set the SHA Algorithm */
  4229. if (strncmp(&buf[i], "SHA1", 4) == 0) {
  4230. shaAlg = HASH_AlgSHA1;
  4231. } else if (strncmp(&buf[i], "SHA256", 6) == 0) {
  4232. shaAlg = HASH_AlgSHA256;
  4233. } else if (strncmp(&buf[i], "SHA384", 6)== 0) {
  4234. shaAlg = HASH_AlgSHA384;
  4235. } else if (strncmp(&buf[i], "SHA512", 6) == 0) {
  4236. shaAlg = HASH_AlgSHA512;
  4237. } else {
  4238. fprintf(rsaresp, "ERROR: Unable to find SHAAlg type");
  4239. goto loser;
  4240. }
  4241. fputs(buf, rsaresp);
  4242. continue;
  4243. }
  4244. /* Msg = ... */
  4245. if (strncmp(buf, "Msg", 3) == 0) {
  4246. unsigned char msg[128]; /* MAX msg 128 */
  4247. unsigned int rsa_bytes_signed;
  4248. unsigned char rsa_computed_signature[RSA_MAX_TEST_MODULUS_BYTES];
  4249. SECStatus rv = SECFailure;
  4250. NSSLOWKEYPublicKey * rsa_public_key;
  4251. NSSLOWKEYPrivateKey * rsa_private_key;
  4252. NSSLOWKEYPrivateKey low_RSA_private_key = { NULL,
  4253. NSSLOWKEYRSAKey, };
  4254. NSSLOWKEYPublicKey low_RSA_public_key = { NULL,
  4255. NSSLOWKEYRSAKey, };
  4256. low_RSA_private_key.u.rsa = *rsaBlapiPrivKey;
  4257. low_RSA_public_key.u.rsa = *rsaBlapiPublicKey;
  4258. rsa_private_key = &low_RSA_private_key;
  4259. rsa_public_key = &low_RSA_public_key;
  4260. memset(sha, 0, sizeof sha);
  4261. memset(msg, 0, sizeof msg);
  4262. rsa_bytes_signed = 0;
  4263. memset(rsa_computed_signature, 0, sizeof rsa_computed_signature);
  4264. i = 3;
  4265. while (isspace(buf[i]) || buf[i] == '=') {
  4266. i++;
  4267. }
  4268. for (j=0; isxdigit(buf[i]) && j < sizeof(msg); i+=2,j++) {
  4269. hex_to_byteval(&buf[i], &msg[j]);
  4270. }
  4271. if (shaAlg == HASH_AlgSHA1) {
  4272. if (SHA1_HashBuf(sha, msg, j) != SECSuccess) {
  4273. fprintf(rsaresp, "ERROR: Unable to generate SHA1");
  4274. goto loser;
  4275. }
  4276. shaLength = SHA1_LENGTH;
  4277. shaOid = SEC_OID_SHA1;
  4278. } else if (shaAlg == HASH_AlgSHA256) {
  4279. if (SHA256_HashBuf(sha, msg, j) != SECSuccess) {
  4280. fprintf(rsaresp, "ERROR: Unable to generate SHA256");
  4281. goto loser;
  4282. }
  4283. shaLength = SHA256_LENGTH;
  4284. shaOid = SEC_OID_SHA256;
  4285. } else if (shaAlg == HASH_AlgSHA384) {
  4286. if (SHA384_HashBuf(sha, msg, j) != SECSuccess) {
  4287. fprintf(rsaresp, "ERROR: Unable to generate SHA384");
  4288. goto loser;
  4289. }
  4290. shaLength = SHA384_LENGTH;
  4291. shaOid = SEC_OID_SHA384;
  4292. } else if (shaAlg == HASH_AlgSHA512) {
  4293. if (SHA512_HashBuf(sha, msg, j) != SECSuccess) {
  4294. fprintf(rsaresp, "ERROR: Unable to generate SHA512");
  4295. goto loser;
  4296. }
  4297. shaLength = SHA512_LENGTH;
  4298. shaOid = SEC_OID_SHA512;
  4299. } else {
  4300. fprintf(rsaresp, "ERROR: SHAAlg not defined.");
  4301. goto loser;
  4302. }
  4303. /* Perform RSA signature with the RSA private key. */
  4304. rv = RSA_HashSign( shaOid,
  4305. rsa_private_key,
  4306. rsa_computed_signature,
  4307. &rsa_bytes_signed,
  4308. nsslowkey_PrivateModulusLen(rsa_private_key),
  4309. sha,
  4310. shaLength);
  4311. if( rv != SECSuccess ) {
  4312. fprintf(rsaresp, "ERROR: RSA_HashSign failed");
  4313. goto loser;
  4314. }
  4315. /* Output the signature */
  4316. fputs(buf, rsaresp);
  4317. to_hex_str(buf, rsa_computed_signature, rsa_bytes_signed);
  4318. fprintf(rsaresp, "S = %s\n", buf);
  4319. /* Perform RSA verification with the RSA public key. */
  4320. rv = RSA_HashCheckSign( shaOid,
  4321. rsa_public_key,
  4322. rsa_computed_signature,
  4323. rsa_bytes_signed,
  4324. sha,
  4325. shaLength);
  4326. if( rv != SECSuccess ) {
  4327. fprintf(rsaresp, "ERROR: RSA_HashCheckSign failed");
  4328. goto loser;
  4329. }
  4330. continue;
  4331. }
  4332. }
  4333. loser:
  4334. fclose(rsareq);
  4335. if (rsaBlapiPrivKey != NULL) {
  4336. /* frees private and public key */
  4337. PORT_FreeArena(rsaBlapiPrivKey->arena, PR_TRUE);
  4338. rsaBlapiPrivKey = NULL;
  4339. rsaBlapiPublicKey = NULL;
  4340. }
  4341. }
  4342. /*
  4343. * Perform the RSA Signature Verification Test.
  4344. *
  4345. * reqfn is the pathname of the REQUEST file.
  4346. *
  4347. * The output RESPONSE file is written to stdout.
  4348. */
  4349. void
  4350. rsa_sigver_test(char *reqfn)
  4351. {
  4352. char buf[2*RSA_MAX_TEST_MODULUS_BYTES+7];
  4353. /* buf holds one line from the input REQUEST file
  4354. * or to the output RESPONSE file.
  4355. * s = 2x for HEX output + 1 for \n
  4356. */
  4357. FILE *rsareq; /* input stream from the REQUEST file */
  4358. FILE *rsaresp; /* output stream to the RESPONSE file */
  4359. int i, j;
  4360. unsigned char sha[HASH_LENGTH_MAX]; /* SHA digest */
  4361. unsigned int shaLength = 0; /* actual length of the digest */
  4362. HASH_HashType shaAlg = HASH_AlgNULL;
  4363. SECOidTag shaOid = SEC_OID_UNKNOWN;
  4364. int modulus = 0; /* the Modulus size */
  4365. unsigned char signature[513]; /* largest signature size + '\n' */
  4366. unsigned int signatureLength = 0; /* actual length of the signature */
  4367. PRBool keyvalid = PR_TRUE;
  4368. RSAPublicKey rsaBlapiPublicKey; /* hold RSA public key */
  4369. rsareq = fopen(reqfn, "r");
  4370. rsaresp = stdout;
  4371. memset(&rsaBlapiPublicKey, 0, sizeof(RSAPublicKey));
  4372. while (fgets(buf, sizeof buf, rsareq) != NULL) {
  4373. /* a comment or blank line */
  4374. if (buf[0] == '#' || buf[0] == '\n') {
  4375. fputs(buf, rsaresp);
  4376. continue;
  4377. }
  4378. /* [Mod = ...] */
  4379. if (buf[0] == '[') {
  4380. unsigned int flen; /* length in bytes of the field size */
  4381. if (rsaBlapiPublicKey.modulus.data) { /* n */
  4382. SECITEM_ZfreeItem(&rsaBlapiPublicKey.modulus, PR_FALSE);
  4383. }
  4384. if (sscanf(buf, "[mod = %d]", &modulus) != 1) {
  4385. goto loser;
  4386. }
  4387. if (modulus > RSA_MAX_TEST_MODULUS_BITS) {
  4388. fprintf(rsaresp,"ERROR: modulus greater than test maximum\n");
  4389. goto loser;
  4390. }
  4391. fputs(buf, rsaresp);
  4392. signatureLength = flen = modulus/8;
  4393. SECITEM_AllocItem(NULL, &rsaBlapiPublicKey.modulus, flen);
  4394. if (rsaBlapiPublicKey.modulus.data == NULL) {
  4395. goto loser;
  4396. }
  4397. continue;
  4398. }
  4399. /* n = ... modulus */
  4400. if (buf[0] == 'n') {
  4401. i = 1;
  4402. while (isspace(buf[i]) || buf[i] == '=') {
  4403. i++;
  4404. }
  4405. keyvalid = from_hex_str(&rsaBlapiPublicKey.modulus.data[0],
  4406. rsaBlapiPublicKey.modulus.len,
  4407. &buf[i]);
  4408. if (!keyvalid) {
  4409. fprintf(rsaresp, "ERROR: rsa_sigver n not valid.\n");
  4410. goto loser;
  4411. }
  4412. fputs(buf, rsaresp);
  4413. continue;
  4414. }
  4415. /* SHAAlg = ... */
  4416. if (strncmp(buf, "SHAAlg", 6) == 0) {
  4417. i = 6;
  4418. while (isspace(buf[i]) || buf[i] == '=') {
  4419. i++;
  4420. }
  4421. /* set the SHA Algorithm */
  4422. if (strncmp(&buf[i], "SHA1", 4) == 0) {
  4423. shaAlg = HASH_AlgSHA1;
  4424. } else if (strncmp(&buf[i], "SHA256", 6) == 0) {
  4425. shaAlg = HASH_AlgSHA256;
  4426. } else if (strncmp(&buf[i], "SHA384", 6) == 0) {
  4427. shaAlg = HASH_AlgSHA384;
  4428. } else if (strncmp(&buf[i], "SHA512", 6) == 0) {
  4429. shaAlg = HASH_AlgSHA512;
  4430. } else {
  4431. fprintf(rsaresp, "ERROR: Unable to find SHAAlg type");
  4432. goto loser;
  4433. }
  4434. fputs(buf, rsaresp);
  4435. continue;
  4436. }
  4437. /* e = ... public Key */
  4438. if (buf[0] == 'e') {
  4439. unsigned char data[RSA_MAX_TEST_EXPONENT_BYTES];
  4440. unsigned char t;
  4441. memset(data, 0, sizeof data);
  4442. if (rsaBlapiPublicKey.publicExponent.data) { /* e */
  4443. SECITEM_ZfreeItem(&rsaBlapiPublicKey.publicExponent, PR_FALSE);
  4444. }
  4445. i = 1;
  4446. while (isspace(buf[i]) || buf[i] == '=') {
  4447. i++;
  4448. }
  4449. /* skip leading zero's */
  4450. while (isxdigit(buf[i])) {
  4451. hex_to_byteval(&buf[i], &t);
  4452. if (t == 0) {
  4453. i+=2;
  4454. } else break;
  4455. }
  4456. /* get the exponent */
  4457. for (j=0; isxdigit(buf[i]) && j < sizeof data; i+=2,j++) {
  4458. hex_to_byteval(&buf[i], &data[j]);
  4459. }
  4460. if (j == 0) { j = 1; } /* to handle 1 byte length exponents */
  4461. SECITEM_AllocItem(NULL, &rsaBlapiPublicKey.publicExponent, j);
  4462. if (rsaBlapiPublicKey.publicExponent.data == NULL) {
  4463. goto loser;
  4464. }
  4465. for (i=0; i < j; i++) {
  4466. rsaBlapiPublicKey.publicExponent.data[i] = data[i];
  4467. }
  4468. fputs(buf, rsaresp);
  4469. continue;
  4470. }
  4471. /* Msg = ... */
  4472. if (strncmp(buf, "Msg", 3) == 0) {
  4473. unsigned char msg[128]; /* MAX msg 128 */
  4474. memset(sha, 0, sizeof sha);
  4475. memset(msg, 0, sizeof msg);
  4476. i = 3;
  4477. while (isspace(buf[i]) || buf[i] == '=') {
  4478. i++;
  4479. }
  4480. for (j=0; isxdigit(buf[i]) && j < sizeof msg; i+=2,j++) {
  4481. hex_to_byteval(&buf[i], &msg[j]);
  4482. }
  4483. if (shaAlg == HASH_AlgSHA1) {
  4484. if (SHA1_HashBuf(sha, msg, j) != SECSuccess) {
  4485. fprintf(rsaresp, "ERROR: Unable to generate SHA1");
  4486. goto loser;
  4487. }
  4488. shaLength = SHA1_LENGTH;
  4489. shaOid = SEC_OID_SHA1;
  4490. } else if (shaAlg == HASH_AlgSHA256) {
  4491. if (SHA256_HashBuf(sha, msg, j) != SECSuccess) {
  4492. fprintf(rsaresp, "ERROR: Unable to generate SHA256");
  4493. goto loser;
  4494. }
  4495. shaLength = SHA256_LENGTH;
  4496. shaOid = SEC_OID_SHA256;
  4497. } else if (shaAlg == HASH_AlgSHA384) {
  4498. if (SHA384_HashBuf(sha, msg, j) != SECSuccess) {
  4499. fprintf(rsaresp, "ERROR: Unable to generate SHA384");
  4500. goto loser;
  4501. }
  4502. shaLength = SHA384_LENGTH;
  4503. shaOid = SEC_OID_SHA384;
  4504. } else if (shaAlg == HASH_AlgSHA512) {
  4505. if (SHA512_HashBuf(sha, msg, j) != SECSuccess) {
  4506. fprintf(rsaresp, "ERROR: Unable to generate SHA512");
  4507. goto loser;
  4508. }
  4509. shaLength = SHA512_LENGTH;
  4510. shaOid = SEC_OID_SHA512;
  4511. } else {
  4512. fprintf(rsaresp, "ERROR: SHAAlg not defined.");
  4513. goto loser;
  4514. }
  4515. fputs(buf, rsaresp);
  4516. continue;
  4517. }
  4518. /* S = ... */
  4519. if (buf[0] == 'S') {
  4520. SECStatus rv = SECFailure;
  4521. NSSLOWKEYPublicKey * rsa_public_key;
  4522. NSSLOWKEYPublicKey low_RSA_public_key = { NULL,
  4523. NSSLOWKEYRSAKey, };
  4524. /* convert to a low RSA public key */
  4525. low_RSA_public_key.u.rsa = rsaBlapiPublicKey;
  4526. rsa_public_key = &low_RSA_public_key;
  4527. memset(signature, 0, sizeof(signature));
  4528. i = 1;
  4529. while (isspace(buf[i]) || buf[i] == '=') {
  4530. i++;
  4531. }
  4532. for (j=0; isxdigit(buf[i]) && j < sizeof signature; i+=2,j++) {
  4533. hex_to_byteval(&buf[i], &signature[j]);
  4534. }
  4535. signatureLength = j;
  4536. fputs(buf, rsaresp);
  4537. /* Perform RSA verification with the RSA public key. */
  4538. rv = RSA_HashCheckSign( shaOid,
  4539. rsa_public_key,
  4540. signature,
  4541. signatureLength,
  4542. sha,
  4543. shaLength);
  4544. if( rv == SECSuccess ) {
  4545. fputs("Result = P\n", rsaresp);
  4546. } else {
  4547. fputs("Result = F\n", rsaresp);
  4548. }
  4549. continue;
  4550. }
  4551. }
  4552. loser:
  4553. fclose(rsareq);
  4554. if (rsaBlapiPublicKey.modulus.data) { /* n */
  4555. SECITEM_ZfreeItem(&rsaBlapiPublicKey.modulus, PR_FALSE);
  4556. }
  4557. if (rsaBlapiPublicKey.publicExponent.data) { /* e */
  4558. SECITEM_ZfreeItem(&rsaBlapiPublicKey.publicExponent, PR_FALSE);
  4559. }
  4560. }
  4561. int main(int argc, char **argv)
  4562. {
  4563. if (argc < 2) exit (-1);
  4564. /*************/
  4565. /* TDEA */
  4566. /*************/
  4567. if (strcmp(argv[1], "tdea") == 0) {
  4568. /* argv[2]=kat|mmt|mct argv[3]=ecb|cbc argv[4]=<test name>.req */
  4569. if (strcmp(argv[2], "kat") == 0) {
  4570. /* Known Answer Test (KAT) */
  4571. tdea_kat_mmt(argv[4]);
  4572. } else if (strcmp(argv[2], "mmt") == 0) {
  4573. /* Multi-block Message Test (MMT) */
  4574. tdea_kat_mmt(argv[4]);
  4575. } else if (strcmp(argv[2], "mct") == 0) {
  4576. /* Monte Carlo Test (MCT) */
  4577. if (strcmp(argv[3], "ecb") == 0) {
  4578. /* ECB mode */
  4579. tdea_mct(NSS_DES_EDE3, argv[4]);
  4580. } else if (strcmp(argv[3], "cbc") == 0) {
  4581. /* CBC mode */
  4582. tdea_mct(NSS_DES_EDE3_CBC, argv[4]);
  4583. }
  4584. }
  4585. /*************/
  4586. /* AES */
  4587. /*************/
  4588. } else if (strcmp(argv[1], "aes") == 0) {
  4589. /* argv[2]=kat|mmt|mct argv[3]=ecb|cbc argv[4]=<test name>.req */
  4590. if ( strcmp(argv[2], "kat") == 0) {
  4591. /* Known Answer Test (KAT) */
  4592. aes_kat_mmt(argv[4]);
  4593. } else if (strcmp(argv[2], "mmt") == 0) {
  4594. /* Multi-block Message Test (MMT) */
  4595. aes_kat_mmt(argv[4]);
  4596. } else if (strcmp(argv[2], "mct") == 0) {
  4597. /* Monte Carlo Test (MCT) */
  4598. if ( strcmp(argv[3], "ecb") == 0) {
  4599. /* ECB mode */
  4600. aes_ecb_mct(argv[4]);
  4601. } else if (strcmp(argv[3], "cbc") == 0) {
  4602. /* CBC mode */
  4603. aes_cbc_mct(argv[4]);
  4604. }
  4605. }
  4606. /*************/
  4607. /* SHA */
  4608. /*************/
  4609. } else if (strcmp(argv[1], "sha") == 0) {
  4610. sha_test(argv[2]);
  4611. /*************/
  4612. /* RSA */
  4613. /*************/
  4614. } else if (strcmp(argv[1], "rsa") == 0) {
  4615. /* argv[2]=siggen|sigver */
  4616. /* argv[3]=<test name>.req */
  4617. if (strcmp(argv[2], "siggen") == 0) {
  4618. /* Signature Generation Test */
  4619. rsa_siggen_test(argv[3]);
  4620. } else if (strcmp(argv[2], "sigver") == 0) {
  4621. /* Signature Verification Test */
  4622. rsa_sigver_test(argv[3]);
  4623. }
  4624. /*************/
  4625. /* HMAC */
  4626. /*************/
  4627. } else if (strcmp(argv[1], "hmac") == 0) {
  4628. hmac_test(argv[2]);
  4629. /*************/
  4630. /* DSA */
  4631. /*************/
  4632. } else if (strcmp(argv[1], "dsa") == 0) {
  4633. /* argv[2]=keypair|pqggen|pqgver|siggen|sigver */
  4634. /* argv[3]=<test name>.req */
  4635. if (strcmp(argv[2], "keypair") == 0) {
  4636. /* Key Pair Generation Test */
  4637. dsa_keypair_test(argv[3]);
  4638. } else if (strcmp(argv[2], "pqggen") == 0) {
  4639. /* Domain Parameter Generation Test */
  4640. dsa_pqggen_test(argv[3]);
  4641. } else if (strcmp(argv[2], "pqgver") == 0) {
  4642. /* Domain Parameter Validation Test */
  4643. dsa_pqgver_test(argv[3]);
  4644. } else if (strcmp(argv[2], "siggen") == 0) {
  4645. /* Signature Generation Test */
  4646. dsa_siggen_test(argv[3]);
  4647. } else if (strcmp(argv[2], "sigver") == 0) {
  4648. /* Signature Verification Test */
  4649. dsa_sigver_test(argv[3]);
  4650. }
  4651. #ifdef NSS_ENABLE_ECC
  4652. /*************/
  4653. /* ECDSA */
  4654. /*************/
  4655. } else if (strcmp(argv[1], "ecdsa") == 0) {
  4656. /* argv[2]=keypair|pkv|siggen|sigver argv[3]=<test name>.req */
  4657. if ( strcmp(argv[2], "keypair") == 0) {
  4658. /* Key Pair Generation Test */
  4659. ecdsa_keypair_test(argv[3]);
  4660. } else if (strcmp(argv[2], "pkv") == 0) {
  4661. /* Public Key Validation Test */
  4662. ecdsa_pkv_test(argv[3]);
  4663. } else if (strcmp(argv[2], "siggen") == 0) {
  4664. /* Signature Generation Test */
  4665. ecdsa_siggen_test(argv[3]);
  4666. } else if (strcmp(argv[2], "sigver") == 0) {
  4667. /* Signature Verification Test */
  4668. ecdsa_sigver_test(argv[3]);
  4669. }
  4670. #endif /* NSS_ENABLE_ECC */
  4671. /*************/
  4672. /* RNG */
  4673. /*************/
  4674. } else if (strcmp(argv[1], "rng") == 0) {
  4675. /* argv[2]=vst|mct argv[3]=<test name>.req */
  4676. if ( strcmp(argv[2], "vst") == 0) {
  4677. /* Variable Seed Test */
  4678. rng_vst(argv[3]);
  4679. } else if (strcmp(argv[2], "mct") == 0) {
  4680. /* Monte Carlo Test */
  4681. rng_mct(argv[3]);
  4682. }
  4683. } else if (strcmp(argv[1], "drbg") == 0) {
  4684. /* Variable Seed Test */
  4685. drbg(argv[2]);
  4686. } else if (strcmp(argv[1], "ddrbg") == 0) {
  4687. debug = 1;
  4688. drbg(argv[2]);
  4689. }
  4690. return 0;
  4691. }