fips_dssvs.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492
  1. #include <openssl/opensslconf.h>
  2. #ifndef OPENSSL_FIPS
  3. # include <stdio.h>
  4. int main(int argc, char **argv)
  5. {
  6. printf("No FIPS DSA support\n");
  7. return (0);
  8. }
  9. #else
  10. # include <openssl/bn.h>
  11. # include <openssl/dsa.h>
  12. # include <openssl/fips.h>
  13. # include <openssl/err.h>
  14. # include <openssl/evp.h>
  15. # include <string.h>
  16. # include <ctype.h>
  17. # include "fips_utl.h"
  18. static void pbn(const char *name, BIGNUM *bn)
  19. {
  20. int len, i;
  21. unsigned char *tmp;
  22. len = BN_num_bytes(bn);
  23. tmp = OPENSSL_malloc(len);
  24. if (!tmp) {
  25. fprintf(stderr, "Memory allocation error\n");
  26. return;
  27. }
  28. BN_bn2bin(bn, tmp);
  29. printf("%s = ", name);
  30. for (i = 0; i < len; i++)
  31. printf("%02X", tmp[i]);
  32. fputs("\n", stdout);
  33. OPENSSL_free(tmp);
  34. return;
  35. }
  36. static void primes()
  37. {
  38. char buf[10240];
  39. char lbuf[10240];
  40. char *keyword, *value;
  41. while (fgets(buf, sizeof buf, stdin) != NULL) {
  42. fputs(buf, stdout);
  43. if (!parse_line(&keyword, &value, lbuf, buf))
  44. continue;
  45. if (!strcmp(keyword, "Prime")) {
  46. BIGNUM *pp;
  47. pp = BN_new();
  48. do_hex2bn(&pp, value);
  49. printf("result= %c\n",
  50. BN_is_prime_ex(pp, 20, NULL, NULL) ? 'P' : 'F');
  51. }
  52. }
  53. }
  54. static void pqg()
  55. {
  56. char buf[1024];
  57. char lbuf[1024];
  58. char *keyword, *value;
  59. int nmod = 0;
  60. while (fgets(buf, sizeof buf, stdin) != NULL) {
  61. if (!parse_line(&keyword, &value, lbuf, buf)) {
  62. fputs(buf, stdout);
  63. continue;
  64. }
  65. if (!strcmp(keyword, "[mod"))
  66. nmod = atoi(value);
  67. else if (!strcmp(keyword, "N")) {
  68. int n = atoi(value);
  69. printf("[mod = %d]\n\n", nmod);
  70. while (n--) {
  71. unsigned char seed[20];
  72. DSA *dsa;
  73. int counter;
  74. unsigned long h;
  75. dsa = FIPS_dsa_new();
  76. if (!DSA_generate_parameters_ex
  77. (dsa, nmod, seed, 0, &counter, &h, NULL)) {
  78. do_print_errors();
  79. exit(1);
  80. }
  81. pbn("P", dsa->p);
  82. pbn("Q", dsa->q);
  83. pbn("G", dsa->g);
  84. pv("Seed", seed, 20);
  85. printf("c = %d\n", counter);
  86. printf("H = %lx\n", h);
  87. putc('\n', stdout);
  88. }
  89. } else
  90. fputs(buf, stdout);
  91. }
  92. }
  93. static void pqgver()
  94. {
  95. char buf[1024];
  96. char lbuf[1024];
  97. char *keyword, *value;
  98. BIGNUM *p = NULL, *q = NULL, *g = NULL;
  99. int counter, counter2;
  100. unsigned long h, h2;
  101. DSA *dsa = NULL;
  102. int nmod = 0;
  103. unsigned char seed[1024];
  104. while (fgets(buf, sizeof buf, stdin) != NULL) {
  105. if (!parse_line(&keyword, &value, lbuf, buf)) {
  106. fputs(buf, stdout);
  107. continue;
  108. }
  109. fputs(buf, stdout);
  110. if (!strcmp(keyword, "[mod"))
  111. nmod = atoi(value);
  112. else if (!strcmp(keyword, "P"))
  113. p = hex2bn(value);
  114. else if (!strcmp(keyword, "Q"))
  115. q = hex2bn(value);
  116. else if (!strcmp(keyword, "G"))
  117. g = hex2bn(value);
  118. else if (!strcmp(keyword, "Seed")) {
  119. int slen = hex2bin(value, seed);
  120. if (slen != 20) {
  121. fprintf(stderr, "Seed parse length error\n");
  122. exit(1);
  123. }
  124. } else if (!strcmp(keyword, "c"))
  125. counter = atoi(buf + 4);
  126. else if (!strcmp(keyword, "H")) {
  127. h = atoi(value);
  128. if (!p || !q || !g) {
  129. fprintf(stderr, "Parse Error\n");
  130. exit(1);
  131. }
  132. dsa = FIPS_dsa_new();
  133. if (!DSA_generate_parameters_ex
  134. (dsa, nmod, seed, 20, &counter2, &h2, NULL)) {
  135. do_print_errors();
  136. exit(1);
  137. }
  138. if (BN_cmp(dsa->p, p) || BN_cmp(dsa->q, q) || BN_cmp(dsa->g, g)
  139. || (counter != counter2) || (h != h2))
  140. printf("Result = F\n");
  141. else
  142. printf("Result = P\n");
  143. BN_free(p);
  144. BN_free(q);
  145. BN_free(g);
  146. p = NULL;
  147. q = NULL;
  148. g = NULL;
  149. FIPS_dsa_free(dsa);
  150. dsa = NULL;
  151. }
  152. }
  153. }
  154. /*
  155. * Keypair verification routine. NB: this isn't part of the standard
  156. * FIPS140-2 algorithm tests. It is an additional test to perform sanity
  157. * checks on the output of the KeyPair test.
  158. */
  159. static int dss_paramcheck(int nmod, BIGNUM *p, BIGNUM *q, BIGNUM *g,
  160. BN_CTX *ctx)
  161. {
  162. BIGNUM *rem = NULL;
  163. if (BN_num_bits(p) != nmod)
  164. return 0;
  165. if (BN_num_bits(q) != 160)
  166. return 0;
  167. if (BN_is_prime_ex(p, BN_prime_checks, ctx, NULL) != 1)
  168. return 0;
  169. if (BN_is_prime_ex(q, BN_prime_checks, ctx, NULL) != 1)
  170. return 0;
  171. rem = BN_new();
  172. if (!BN_mod(rem, p, q, ctx) || !BN_is_one(rem)
  173. || (BN_cmp(g, BN_value_one()) <= 0)
  174. || !BN_mod_exp(rem, g, q, p, ctx) || !BN_is_one(rem)) {
  175. BN_free(rem);
  176. return 0;
  177. }
  178. /* Todo: check g */
  179. BN_free(rem);
  180. return 1;
  181. }
  182. static void keyver()
  183. {
  184. char buf[1024];
  185. char lbuf[1024];
  186. char *keyword, *value;
  187. BIGNUM *p = NULL, *q = NULL, *g = NULL, *X = NULL, *Y = NULL;
  188. BIGNUM *Y2;
  189. BN_CTX *ctx = NULL;
  190. int nmod = 0, paramcheck = 0;
  191. ctx = BN_CTX_new();
  192. Y2 = BN_new();
  193. while (fgets(buf, sizeof buf, stdin) != NULL) {
  194. if (!parse_line(&keyword, &value, lbuf, buf)) {
  195. fputs(buf, stdout);
  196. continue;
  197. }
  198. if (!strcmp(keyword, "[mod")) {
  199. if (p)
  200. BN_free(p);
  201. p = NULL;
  202. if (q)
  203. BN_free(q);
  204. q = NULL;
  205. if (g)
  206. BN_free(g);
  207. g = NULL;
  208. paramcheck = 0;
  209. nmod = atoi(value);
  210. } else if (!strcmp(keyword, "P"))
  211. p = hex2bn(value);
  212. else if (!strcmp(keyword, "Q"))
  213. q = hex2bn(value);
  214. else if (!strcmp(keyword, "G"))
  215. g = hex2bn(value);
  216. else if (!strcmp(keyword, "X"))
  217. X = hex2bn(value);
  218. else if (!strcmp(keyword, "Y")) {
  219. Y = hex2bn(value);
  220. if (!p || !q || !g || !X || !Y) {
  221. fprintf(stderr, "Parse Error\n");
  222. exit(1);
  223. }
  224. pbn("P", p);
  225. pbn("Q", q);
  226. pbn("G", g);
  227. pbn("X", X);
  228. pbn("Y", Y);
  229. if (!paramcheck) {
  230. if (dss_paramcheck(nmod, p, q, g, ctx))
  231. paramcheck = 1;
  232. else
  233. paramcheck = -1;
  234. }
  235. if (paramcheck != 1)
  236. printf("Result = F\n");
  237. else {
  238. if (!BN_mod_exp(Y2, g, X, p, ctx) || BN_cmp(Y2, Y))
  239. printf("Result = F\n");
  240. else
  241. printf("Result = P\n");
  242. }
  243. BN_free(X);
  244. BN_free(Y);
  245. X = NULL;
  246. Y = NULL;
  247. }
  248. }
  249. if (p)
  250. BN_free(p);
  251. if (q)
  252. BN_free(q);
  253. if (g)
  254. BN_free(g);
  255. if (Y2)
  256. BN_free(Y2);
  257. }
  258. static void keypair()
  259. {
  260. char buf[1024];
  261. char lbuf[1024];
  262. char *keyword, *value;
  263. int nmod = 0;
  264. while (fgets(buf, sizeof buf, stdin) != NULL) {
  265. if (!parse_line(&keyword, &value, lbuf, buf)) {
  266. fputs(buf, stdout);
  267. continue;
  268. }
  269. if (!strcmp(keyword, "[mod"))
  270. nmod = atoi(value);
  271. else if (!strcmp(keyword, "N")) {
  272. DSA *dsa;
  273. int n = atoi(value);
  274. printf("[mod = %d]\n\n", nmod);
  275. dsa = FIPS_dsa_new();
  276. if (!DSA_generate_parameters_ex
  277. (dsa, nmod, NULL, 0, NULL, NULL, NULL)) {
  278. do_print_errors();
  279. exit(1);
  280. }
  281. pbn("P", dsa->p);
  282. pbn("Q", dsa->q);
  283. pbn("G", dsa->g);
  284. putc('\n', stdout);
  285. while (n--) {
  286. if (!DSA_generate_key(dsa)) {
  287. do_print_errors();
  288. exit(1);
  289. }
  290. pbn("X", dsa->priv_key);
  291. pbn("Y", dsa->pub_key);
  292. putc('\n', stdout);
  293. }
  294. }
  295. }
  296. }
  297. static void siggen()
  298. {
  299. char buf[1024];
  300. char lbuf[1024];
  301. char *keyword, *value;
  302. int nmod = 0;
  303. DSA *dsa = NULL;
  304. while (fgets(buf, sizeof buf, stdin) != NULL) {
  305. if (!parse_line(&keyword, &value, lbuf, buf)) {
  306. fputs(buf, stdout);
  307. continue;
  308. }
  309. if (!strcmp(keyword, "[mod")) {
  310. nmod = atoi(value);
  311. printf("[mod = %d]\n\n", nmod);
  312. if (dsa)
  313. FIPS_dsa_free(dsa);
  314. dsa = FIPS_dsa_new();
  315. if (!DSA_generate_parameters_ex
  316. (dsa, nmod, NULL, 0, NULL, NULL, NULL)) {
  317. do_print_errors();
  318. exit(1);
  319. }
  320. pbn("P", dsa->p);
  321. pbn("Q", dsa->q);
  322. pbn("G", dsa->g);
  323. putc('\n', stdout);
  324. } else if (!strcmp(keyword, "Msg")) {
  325. unsigned char msg[1024];
  326. unsigned char sbuf[60];
  327. unsigned int slen;
  328. int n;
  329. EVP_PKEY pk;
  330. EVP_MD_CTX mctx;
  331. DSA_SIG *sig;
  332. EVP_MD_CTX_init(&mctx);
  333. n = hex2bin(value, msg);
  334. pv("Msg", msg, n);
  335. if (!DSA_generate_key(dsa)) {
  336. do_print_errors();
  337. exit(1);
  338. }
  339. pk.type = EVP_PKEY_DSA;
  340. pk.pkey.dsa = dsa;
  341. pbn("Y", dsa->pub_key);
  342. EVP_SignInit_ex(&mctx, EVP_dss1(), NULL);
  343. EVP_SignUpdate(&mctx, msg, n);
  344. EVP_SignFinal(&mctx, sbuf, &slen, &pk);
  345. sig = DSA_SIG_new();
  346. FIPS_dsa_sig_decode(sig, sbuf, slen);
  347. pbn("R", sig->r);
  348. pbn("S", sig->s);
  349. putc('\n', stdout);
  350. DSA_SIG_free(sig);
  351. EVP_MD_CTX_cleanup(&mctx);
  352. }
  353. }
  354. if (dsa)
  355. FIPS_dsa_free(dsa);
  356. }
  357. static void sigver()
  358. {
  359. DSA *dsa = NULL;
  360. char buf[1024];
  361. char lbuf[1024];
  362. unsigned char msg[1024];
  363. char *keyword, *value;
  364. int nmod = 0, n = 0;
  365. DSA_SIG sg, *sig = &sg;
  366. sig->r = NULL;
  367. sig->s = NULL;
  368. while (fgets(buf, sizeof buf, stdin) != NULL) {
  369. if (!parse_line(&keyword, &value, lbuf, buf)) {
  370. fputs(buf, stdout);
  371. continue;
  372. }
  373. if (!strcmp(keyword, "[mod")) {
  374. nmod = atoi(value);
  375. if (dsa)
  376. FIPS_dsa_free(dsa);
  377. dsa = FIPS_dsa_new();
  378. } else if (!strcmp(keyword, "P"))
  379. dsa->p = hex2bn(value);
  380. else if (!strcmp(keyword, "Q"))
  381. dsa->q = hex2bn(value);
  382. else if (!strcmp(keyword, "G")) {
  383. dsa->g = hex2bn(value);
  384. printf("[mod = %d]\n\n", nmod);
  385. pbn("P", dsa->p);
  386. pbn("Q", dsa->q);
  387. pbn("G", dsa->g);
  388. putc('\n', stdout);
  389. } else if (!strcmp(keyword, "Msg")) {
  390. n = hex2bin(value, msg);
  391. pv("Msg", msg, n);
  392. } else if (!strcmp(keyword, "Y"))
  393. dsa->pub_key = hex2bn(value);
  394. else if (!strcmp(keyword, "R"))
  395. sig->r = hex2bn(value);
  396. else if (!strcmp(keyword, "S")) {
  397. EVP_MD_CTX mctx;
  398. EVP_PKEY pk;
  399. unsigned char sigbuf[60];
  400. unsigned int slen;
  401. int r;
  402. EVP_MD_CTX_init(&mctx);
  403. pk.type = EVP_PKEY_DSA;
  404. pk.pkey.dsa = dsa;
  405. sig->s = hex2bn(value);
  406. pbn("Y", dsa->pub_key);
  407. pbn("R", sig->r);
  408. pbn("S", sig->s);
  409. slen = FIPS_dsa_sig_encode(sigbuf, sig);
  410. EVP_VerifyInit_ex(&mctx, EVP_dss1(), NULL);
  411. EVP_VerifyUpdate(&mctx, msg, n);
  412. r = EVP_VerifyFinal(&mctx, sigbuf, slen, &pk);
  413. EVP_MD_CTX_cleanup(&mctx);
  414. printf("Result = %c\n", r == 1 ? 'P' : 'F');
  415. putc('\n', stdout);
  416. }
  417. }
  418. }
  419. int main(int argc, char **argv)
  420. {
  421. if (argc != 2) {
  422. fprintf(stderr, "%s [prime|pqg|pqgver|keypair|siggen|sigver]\n",
  423. argv[0]);
  424. exit(1);
  425. }
  426. if (!FIPS_mode_set(1)) {
  427. do_print_errors();
  428. exit(1);
  429. }
  430. if (!strcmp(argv[1], "prime"))
  431. primes();
  432. else if (!strcmp(argv[1], "pqg"))
  433. pqg();
  434. else if (!strcmp(argv[1], "pqgver"))
  435. pqgver();
  436. else if (!strcmp(argv[1], "keypair"))
  437. keypair();
  438. else if (!strcmp(argv[1], "keyver"))
  439. keyver();
  440. else if (!strcmp(argv[1], "siggen"))
  441. siggen();
  442. else if (!strcmp(argv[1], "sigver"))
  443. sigver();
  444. else {
  445. fprintf(stderr, "Don't know how to %s.\n", argv[1]);
  446. exit(1);
  447. }
  448. return 0;
  449. }
  450. #endif