fips_gcmtest.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562
  1. /* fips/aes/fips_gcmtest.c */
  2. /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
  3. * project.
  4. */
  5. /* ====================================================================
  6. * Copyright (c) 2011 The OpenSSL Project. All rights reserved.
  7. *
  8. * Redistribution and use in source and binary forms, with or without
  9. * modification, are permitted provided that the following conditions
  10. * are met:
  11. *
  12. * 1. Redistributions of source code must retain the above copyright
  13. * notice, this list of conditions and the following disclaimer.
  14. *
  15. * 2. Redistributions in binary form must reproduce the above copyright
  16. * notice, this list of conditions and the following disclaimer in
  17. * the documentation and/or other materials provided with the
  18. * distribution.
  19. *
  20. * 3. All advertising materials mentioning features or use of this
  21. * software must display the following acknowledgment:
  22. * "This product includes software developed by the OpenSSL Project
  23. * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
  24. *
  25. * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
  26. * endorse or promote products derived from this software without
  27. * prior written permission. For written permission, please contact
  28. * licensing@OpenSSL.org.
  29. *
  30. * 5. Products derived from this software may not be called "OpenSSL"
  31. * nor may "OpenSSL" appear in their names without prior written
  32. * permission of the OpenSSL Project.
  33. *
  34. * 6. Redistributions of any form whatsoever must retain the following
  35. * acknowledgment:
  36. * "This product includes software developed by the OpenSSL Project
  37. * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
  38. *
  39. * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
  40. * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  41. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  42. * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
  43. * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  44. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  45. * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  46. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  47. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  48. * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  49. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
  50. * OF THE POSSIBILITY OF SUCH DAMAGE.
  51. * ====================================================================
  52. */
  53. #define OPENSSL_FIPSAPI
  54. #include <openssl/opensslconf.h>
  55. #ifndef OPENSSL_FIPS
  56. #include <stdio.h>
  57. int main(int argc, char **argv)
  58. {
  59. printf("No FIPS GCM support\n");
  60. return(0);
  61. }
  62. #else
  63. #include <openssl/bn.h>
  64. #include <openssl/dsa.h>
  65. #include <openssl/fips.h>
  66. #include <openssl/err.h>
  67. #include <openssl/evp.h>
  68. #include <string.h>
  69. #include <ctype.h>
  70. #include "fips_utl.h"
  71. static void gcmtest(FILE *in, FILE *out, int encrypt)
  72. {
  73. char buf[2048];
  74. char lbuf[2048];
  75. char *keyword, *value;
  76. int keylen = -1, ivlen = -1, aadlen = -1, taglen = -1, ptlen = -1;
  77. int rv;
  78. long l;
  79. unsigned char *key = NULL, *iv = NULL, *aad = NULL, *tag = NULL;
  80. unsigned char *ct = NULL, *pt = NULL;
  81. EVP_CIPHER_CTX ctx;
  82. const EVP_CIPHER *gcm = NULL;
  83. FIPS_cipher_ctx_init(&ctx);
  84. while(fgets(buf,sizeof buf,in) != NULL)
  85. {
  86. fputs(buf,out);
  87. if (!parse_line(&keyword, &value, lbuf, buf))
  88. continue;
  89. if(!strcmp(keyword,"[Keylen"))
  90. {
  91. keylen = atoi(value);
  92. if (keylen == 128)
  93. gcm = EVP_aes_128_gcm();
  94. else if (keylen == 192)
  95. gcm = EVP_aes_192_gcm();
  96. else if (keylen == 256)
  97. gcm = EVP_aes_256_gcm();
  98. else
  99. {
  100. fprintf(stderr, "Unsupported keylen %d\n",
  101. keylen);
  102. }
  103. keylen >>= 3;
  104. }
  105. else if (!strcmp(keyword, "[IVlen"))
  106. ivlen = atoi(value) >> 3;
  107. else if (!strcmp(keyword, "[AADlen"))
  108. aadlen = atoi(value) >> 3;
  109. else if (!strcmp(keyword, "[Taglen"))
  110. taglen = atoi(value) >> 3;
  111. else if (!strcmp(keyword, "[PTlen"))
  112. ptlen = atoi(value) >> 3;
  113. else if(!strcmp(keyword,"Key"))
  114. {
  115. key = hex2bin_m(value, &l);
  116. if (l != keylen)
  117. {
  118. fprintf(stderr, "Inconsistent Key length\n");
  119. exit(1);
  120. }
  121. }
  122. else if(!strcmp(keyword,"IV"))
  123. {
  124. iv = hex2bin_m(value, &l);
  125. if (l != ivlen)
  126. {
  127. fprintf(stderr, "Inconsistent IV length\n");
  128. exit(1);
  129. }
  130. }
  131. else if(!strcmp(keyword,"PT"))
  132. {
  133. pt = hex2bin_m(value, &l);
  134. if (l != ptlen)
  135. {
  136. fprintf(stderr, "Inconsistent PT length\n");
  137. exit(1);
  138. }
  139. }
  140. else if(!strcmp(keyword,"CT"))
  141. {
  142. ct = hex2bin_m(value, &l);
  143. if (l != ptlen)
  144. {
  145. fprintf(stderr, "Inconsistent CT length\n");
  146. exit(1);
  147. }
  148. }
  149. else if(!strcmp(keyword,"AAD"))
  150. {
  151. aad = hex2bin_m(value, &l);
  152. if (l != aadlen)
  153. {
  154. fprintf(stderr, "Inconsistent AAD length\n");
  155. exit(1);
  156. }
  157. }
  158. else if(!strcmp(keyword,"Tag"))
  159. {
  160. tag = hex2bin_m(value, &l);
  161. if (l != taglen)
  162. {
  163. fprintf(stderr, "Inconsistent Tag length\n");
  164. exit(1);
  165. }
  166. }
  167. if (encrypt && pt && aad && (iv || encrypt==1))
  168. {
  169. tag = OPENSSL_malloc(taglen);
  170. FIPS_cipherinit(&ctx, gcm, NULL, NULL, 1);
  171. /* Relax FIPS constraints for testing */
  172. M_EVP_CIPHER_CTX_set_flags(&ctx, EVP_CIPH_FLAG_NON_FIPS_ALLOW);
  173. FIPS_cipher_ctx_ctrl(&ctx, EVP_CTRL_GCM_SET_IVLEN, ivlen, 0);
  174. if (encrypt == 1)
  175. {
  176. static unsigned char iv_fixed[4] = {1,2,3,4};
  177. if (!iv)
  178. iv = OPENSSL_malloc(ivlen);
  179. FIPS_cipherinit(&ctx, NULL, key, NULL, 1);
  180. FIPS_cipher_ctx_ctrl(&ctx,
  181. EVP_CTRL_GCM_SET_IV_FIXED,
  182. 4, iv_fixed);
  183. if (!FIPS_cipher_ctx_ctrl(&ctx,
  184. EVP_CTRL_GCM_IV_GEN, 0, iv))
  185. {
  186. fprintf(stderr, "IV gen error\n");
  187. exit(1);
  188. }
  189. OutputValue("IV", iv, ivlen, out, 0);
  190. }
  191. else
  192. FIPS_cipherinit(&ctx, NULL, key, iv, 1);
  193. if (aadlen)
  194. FIPS_cipher(&ctx, NULL, aad, aadlen);
  195. if (ptlen)
  196. {
  197. ct = OPENSSL_malloc(ptlen);
  198. rv = FIPS_cipher(&ctx, ct, pt, ptlen);
  199. }
  200. FIPS_cipher(&ctx, NULL, NULL, 0);
  201. FIPS_cipher_ctx_ctrl(&ctx, EVP_CTRL_GCM_GET_TAG,
  202. taglen, tag);
  203. OutputValue("CT", ct, ptlen, out, 0);
  204. OutputValue("Tag", tag, taglen, out, 0);
  205. if (iv)
  206. OPENSSL_free(iv);
  207. if (aad)
  208. OPENSSL_free(aad);
  209. if (ct)
  210. OPENSSL_free(ct);
  211. if (pt)
  212. OPENSSL_free(pt);
  213. if (key)
  214. OPENSSL_free(key);
  215. if (tag)
  216. OPENSSL_free(tag);
  217. iv = aad = ct = pt = key = tag = NULL;
  218. }
  219. if (!encrypt && tag)
  220. {
  221. FIPS_cipherinit(&ctx, gcm, NULL, NULL, 0);
  222. /* Relax FIPS constraints for testing */
  223. M_EVP_CIPHER_CTX_set_flags(&ctx, EVP_CIPH_FLAG_NON_FIPS_ALLOW);
  224. FIPS_cipher_ctx_ctrl(&ctx, EVP_CTRL_GCM_SET_IVLEN, ivlen, 0);
  225. FIPS_cipherinit(&ctx, NULL, key, iv, 0);
  226. FIPS_cipher_ctx_ctrl(&ctx, EVP_CTRL_GCM_SET_TAG, taglen, tag);
  227. if (aadlen)
  228. FIPS_cipher(&ctx, NULL, aad, aadlen);
  229. if (ptlen)
  230. {
  231. pt = OPENSSL_malloc(ptlen);
  232. rv = FIPS_cipher(&ctx, pt, ct, ptlen);
  233. }
  234. rv = FIPS_cipher(&ctx, NULL, NULL, 0);
  235. if (rv < 0)
  236. fprintf(out, "FAIL\n");
  237. else
  238. OutputValue("PT", pt, ptlen, out, 0);
  239. if (iv)
  240. OPENSSL_free(iv);
  241. if (aad)
  242. OPENSSL_free(aad);
  243. if (ct)
  244. OPENSSL_free(ct);
  245. if (pt)
  246. OPENSSL_free(pt);
  247. if (key)
  248. OPENSSL_free(key);
  249. if (tag)
  250. OPENSSL_free(tag);
  251. iv = aad = ct = pt = key = tag = NULL;
  252. }
  253. }
  254. }
  255. static void xtstest(FILE *in, FILE *out)
  256. {
  257. char buf[204800];
  258. char lbuf[204800];
  259. char *keyword, *value;
  260. int inlen;
  261. int encrypt = 0;
  262. int rv;
  263. long l;
  264. unsigned char *key = NULL, *iv = NULL;
  265. unsigned char *inbuf = NULL, *outbuf = NULL;
  266. EVP_CIPHER_CTX ctx;
  267. const EVP_CIPHER *xts = NULL;
  268. FIPS_cipher_ctx_init(&ctx);
  269. while(fgets(buf,sizeof buf,in) != NULL)
  270. {
  271. fputs(buf,out);
  272. if (buf[0] == '[' && strlen(buf) >= 9)
  273. {
  274. if(!strncmp(buf,"[ENCRYPT]", 9))
  275. encrypt = 1;
  276. else if(!strncmp(buf,"[DECRYPT]", 9))
  277. encrypt = 0;
  278. }
  279. if (!parse_line(&keyword, &value, lbuf, buf))
  280. continue;
  281. else if(!strcmp(keyword,"Key"))
  282. {
  283. key = hex2bin_m(value, &l);
  284. if (l == 32)
  285. xts = EVP_aes_128_xts();
  286. else if (l == 64)
  287. xts = EVP_aes_256_xts();
  288. else
  289. {
  290. fprintf(stderr, "Inconsistent Key length\n");
  291. exit(1);
  292. }
  293. }
  294. else if(!strcmp(keyword,"i"))
  295. {
  296. iv = hex2bin_m(value, &l);
  297. if (l != 16)
  298. {
  299. fprintf(stderr, "Inconsistent i length\n");
  300. exit(1);
  301. }
  302. }
  303. else if(encrypt && !strcmp(keyword,"PT"))
  304. {
  305. inbuf = hex2bin_m(value, &l);
  306. inlen = l;
  307. }
  308. else if(!encrypt && !strcmp(keyword,"CT"))
  309. {
  310. inbuf = hex2bin_m(value, &l);
  311. inlen = l;
  312. }
  313. if (inbuf)
  314. {
  315. FIPS_cipherinit(&ctx, xts, key, iv, encrypt);
  316. outbuf = OPENSSL_malloc(inlen);
  317. rv = FIPS_cipher(&ctx, outbuf, inbuf, inlen);
  318. OutputValue(encrypt ? "CT":"PT", outbuf, inlen, out, 0);
  319. OPENSSL_free(inbuf);
  320. OPENSSL_free(outbuf);
  321. OPENSSL_free(key);
  322. OPENSSL_free(iv);
  323. iv = key = inbuf = outbuf = NULL;
  324. }
  325. }
  326. }
  327. static void ccmtest(FILE *in, FILE *out)
  328. {
  329. char buf[200048];
  330. char lbuf[200048];
  331. char *keyword, *value;
  332. long l;
  333. unsigned char *Key = NULL, *Nonce = NULL;
  334. unsigned char *Adata = NULL, *Payload = NULL;
  335. unsigned char *CT = NULL;
  336. int Plen = -1, Nlen = -1, Tlen = -1, Alen = -1;
  337. int decr = 0;
  338. EVP_CIPHER_CTX ctx;
  339. const EVP_CIPHER *ccm = NULL;
  340. FIPS_cipher_ctx_init(&ctx);
  341. while(fgets(buf,sizeof buf,in) != NULL)
  342. {
  343. char *p;
  344. fputs(buf,out);
  345. redo:
  346. if (!parse_line(&keyword, &value, lbuf, buf))
  347. continue;
  348. /* If surrounded by square brackets zap them */
  349. if (keyword[0] == '[')
  350. {
  351. keyword++;
  352. p = strchr(value, ']');
  353. if (p)
  354. *p = 0;
  355. }
  356. /* See if we have a comma separated list of parameters
  357. * if so copy rest of line back to buffer and redo later.
  358. */
  359. p = strchr(value, ',');
  360. if (p)
  361. {
  362. *p = 0;
  363. strcpy(buf, p + 1);
  364. strcat(buf, "\n");
  365. decr = 1;
  366. }
  367. if (!strcmp(keyword,"Plen"))
  368. Plen = atoi(value);
  369. else if (!strcmp(keyword,"Nlen"))
  370. Nlen = atoi(value);
  371. else if (!strcmp(keyword,"Tlen"))
  372. Tlen = atoi(value);
  373. else if (!strcmp(keyword,"Alen"))
  374. Alen = atoi(value);
  375. if (p)
  376. goto redo;
  377. if (!strcmp(keyword,"Key"))
  378. {
  379. if (Key)
  380. OPENSSL_free(Key);
  381. Key = hex2bin_m(value, &l);
  382. if (l == 16)
  383. ccm = EVP_aes_128_ccm();
  384. else if (l == 24)
  385. ccm = EVP_aes_192_ccm();
  386. else if (l == 32)
  387. ccm = EVP_aes_256_ccm();
  388. else
  389. {
  390. fprintf(stderr, "Inconsistent Key length\n");
  391. exit(1);
  392. }
  393. }
  394. else if (!strcmp(keyword,"Nonce"))
  395. {
  396. if (Nonce)
  397. OPENSSL_free(Nonce);
  398. Nonce = hex2bin_m(value, &l);
  399. if (l != Nlen)
  400. {
  401. fprintf(stderr, "Inconsistent nonce length\n");
  402. exit(1);
  403. }
  404. }
  405. else if (!strcmp(keyword,"Payload") && !decr)
  406. {
  407. Payload = hex2bin_m(value, &l);
  408. if (Plen && l != Plen)
  409. {
  410. fprintf(stderr, "Inconsistent Payload length\n");
  411. exit(1);
  412. }
  413. }
  414. else if (!strcmp(keyword,"Adata"))
  415. {
  416. Adata = hex2bin_m(value, &l);
  417. if (Alen && l != Alen)
  418. {
  419. fprintf(stderr, "Inconsistent Payload length\n");
  420. exit(1);
  421. }
  422. }
  423. else if (!strcmp(keyword,"CT") && decr)
  424. {
  425. CT = hex2bin_m(value, &l);
  426. if (l != (Plen + Tlen))
  427. {
  428. fprintf(stderr, "Inconsistent CT length\n");
  429. exit(1);
  430. }
  431. }
  432. if (Payload)
  433. {
  434. FIPS_cipherinit(&ctx, ccm, NULL, NULL, 1);
  435. FIPS_cipher_ctx_ctrl(&ctx, EVP_CTRL_CCM_SET_IVLEN, Nlen, 0);
  436. FIPS_cipher_ctx_ctrl(&ctx, EVP_CTRL_CCM_SET_TAG, Tlen, 0);
  437. FIPS_cipherinit(&ctx, NULL, Key, Nonce, 1);
  438. FIPS_cipher(&ctx, NULL, NULL, Plen);
  439. FIPS_cipher(&ctx, NULL, Adata, Alen);
  440. CT = OPENSSL_malloc(Plen + Tlen);
  441. FIPS_cipher(&ctx, CT, Payload, Plen);
  442. FIPS_cipher_ctx_ctrl(&ctx, EVP_CTRL_CCM_GET_TAG, Tlen,
  443. CT + Plen);
  444. OutputValue("CT", CT, Plen + Tlen, out, 0);
  445. OPENSSL_free(CT);
  446. OPENSSL_free(Payload);
  447. CT = Payload = NULL;
  448. }
  449. if (CT)
  450. {
  451. int rv;
  452. int len = Plen == 0 ? 1: Plen;
  453. FIPS_cipherinit(&ctx, ccm, NULL, NULL, 0);
  454. FIPS_cipher_ctx_ctrl(&ctx, EVP_CTRL_CCM_SET_IVLEN, Nlen, 0);
  455. FIPS_cipher_ctx_ctrl(&ctx, EVP_CTRL_CCM_SET_TAG,
  456. Tlen, CT + Plen);
  457. FIPS_cipherinit(&ctx, NULL, Key, Nonce, 0);
  458. FIPS_cipher(&ctx, NULL, NULL, Plen);
  459. FIPS_cipher(&ctx, NULL, Adata, Alen);
  460. Payload = OPENSSL_malloc(len);
  461. rv = FIPS_cipher(&ctx, Payload, CT, Plen);
  462. if (rv >= 0)
  463. {
  464. if (rv == 0)
  465. Payload[0] = 0;
  466. fputs("Result = Pass\n", out);
  467. OutputValue("Payload", Payload, len, out, 0);
  468. }
  469. else
  470. fputs("Result = Fail\n", out);
  471. OPENSSL_free(CT);
  472. OPENSSL_free(Payload);
  473. CT = Payload = NULL;
  474. }
  475. }
  476. if (Key)
  477. OPENSSL_free(Key);
  478. if (Nonce)
  479. OPENSSL_free(Nonce);
  480. FIPS_cipher_ctx_cleanup(&ctx);
  481. }
  482. int main(int argc,char **argv)
  483. {
  484. int encrypt;
  485. int xts = 0, ccm = 0;
  486. FILE *in, *out;
  487. if (argc == 4)
  488. {
  489. in = fopen(argv[2], "r");
  490. if (!in)
  491. {
  492. fprintf(stderr, "Error opening input file\n");
  493. exit(1);
  494. }
  495. out = fopen(argv[3], "w");
  496. if (!out)
  497. {
  498. fprintf(stderr, "Error opening output file\n");
  499. exit(1);
  500. }
  501. }
  502. else if (argc == 2)
  503. {
  504. in = stdin;
  505. out = stdout;
  506. }
  507. else
  508. {
  509. fprintf(stderr,"%s [-encrypt|-decrypt]\n",argv[0]);
  510. exit(1);
  511. }
  512. fips_algtest_init();
  513. if(!strcmp(argv[1],"-encrypt"))
  514. encrypt = 1;
  515. else if(!strcmp(argv[1],"-encryptIVext"))
  516. encrypt = 2;
  517. else if(!strcmp(argv[1],"-decrypt"))
  518. encrypt = 0;
  519. else if(!strcmp(argv[1],"-ccm"))
  520. ccm = 1;
  521. else if(!strcmp(argv[1],"-xts"))
  522. xts = 1;
  523. else
  524. {
  525. fprintf(stderr,"Don't know how to %s.\n",argv[1]);
  526. exit(1);
  527. }
  528. if (ccm)
  529. ccmtest(in, out);
  530. else if (xts)
  531. xtstest(in, out);
  532. else
  533. gcmtest(in, out, encrypt);
  534. if (argc == 4)
  535. {
  536. fclose(in);
  537. fclose(out);
  538. }
  539. return 0;
  540. }
  541. #endif