fips_drbgvs.c 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336
  1. /* fips/rand/fips_drbgvs.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 DRBG 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/fips_rand.h>
  67. #include <openssl/err.h>
  68. #include <openssl/evp.h>
  69. #include <string.h>
  70. #include <ctype.h>
  71. #include "fips_utl.h"
  72. static int parse_md(char *str)
  73. {
  74. switch(atoi(str + 5))
  75. {
  76. case 1:
  77. return NID_sha1;
  78. case 224:
  79. return NID_sha224;
  80. case 256:
  81. return NID_sha256;
  82. case 384:
  83. return NID_sha384;
  84. case 512:
  85. return NID_sha512;
  86. }
  87. return NID_undef;
  88. }
  89. static int parse_aes(char *str, int *pdf)
  90. {
  91. if (!strncmp(str + 9, "no", 2))
  92. *pdf = 0;
  93. else
  94. *pdf = DRBG_FLAG_CTR_USE_DF;
  95. switch(atoi(str + 5))
  96. {
  97. case 128:
  98. return NID_aes_128_ctr;
  99. case 192:
  100. return NID_aes_192_ctr;
  101. case 256:
  102. return NID_aes_256_ctr;
  103. default:
  104. return NID_undef;
  105. }
  106. return NID_undef;
  107. }
  108. typedef struct
  109. {
  110. unsigned char *ent;
  111. size_t entlen;
  112. unsigned char *nonce;
  113. size_t noncelen;
  114. } TEST_ENT;
  115. static size_t test_entropy(DRBG_CTX *dctx, unsigned char **pout,
  116. int entropy, size_t min_len, size_t max_len)
  117. {
  118. TEST_ENT *t = FIPS_drbg_get_app_data(dctx);
  119. *pout = (unsigned char *)t->ent;
  120. return t->entlen;
  121. }
  122. static size_t test_nonce(DRBG_CTX *dctx, unsigned char **pout,
  123. int entropy, size_t min_len, size_t max_len)
  124. {
  125. TEST_ENT *t = FIPS_drbg_get_app_data(dctx);
  126. *pout = (unsigned char *)t->nonce;
  127. return t->noncelen;
  128. }
  129. int main(int argc,char **argv)
  130. {
  131. FILE *in, *out;
  132. DRBG_CTX *dctx = NULL;
  133. TEST_ENT t;
  134. int r, nid = 0;
  135. int pr = 0;
  136. char buf[2048], lbuf[2048];
  137. unsigned char randout[2048];
  138. char *keyword = NULL, *value = NULL;
  139. unsigned char *ent = NULL, *nonce = NULL, *pers = NULL, *adin = NULL;
  140. long entlen, noncelen, perslen, adinlen;
  141. int df = 0;
  142. int randoutlen = 0;
  143. int gen = 0;
  144. fips_algtest_init();
  145. if (argc == 3)
  146. {
  147. in = fopen(argv[1], "r");
  148. if (!in)
  149. {
  150. fprintf(stderr, "Error opening input file\n");
  151. exit(1);
  152. }
  153. out = fopen(argv[2], "w");
  154. if (!out)
  155. {
  156. fprintf(stderr, "Error opening output file\n");
  157. exit(1);
  158. }
  159. }
  160. else if (argc == 1)
  161. {
  162. in = stdin;
  163. out = stdout;
  164. }
  165. else
  166. {
  167. fprintf(stderr,"%s (infile outfile)\n",argv[0]);
  168. exit(1);
  169. }
  170. while (fgets(buf, sizeof(buf), in) != NULL)
  171. {
  172. fputs(buf, out);
  173. if (strlen(buf) > 4 && !strncmp(buf, "[SHA-", 5))
  174. {
  175. nid = parse_md(buf);
  176. if (nid == NID_undef)
  177. exit(1);
  178. }
  179. if (strlen(buf) > 12 && !strncmp(buf, "[AES-", 5))
  180. {
  181. nid = parse_aes(buf, &df);
  182. if (nid == NID_undef)
  183. exit(1);
  184. }
  185. if (!parse_line(&keyword, &value, lbuf, buf))
  186. continue;
  187. if (!strcmp(keyword, "[PredictionResistance"))
  188. {
  189. if (!strcmp(value, "True]"))
  190. pr = 1;
  191. else if (!strcmp(value, "False]"))
  192. pr = 0;
  193. else
  194. exit(1);
  195. }
  196. if (!strcmp(keyword, "EntropyInput"))
  197. {
  198. ent = hex2bin_m(value, &entlen);
  199. t.ent = ent;
  200. t.entlen = entlen;
  201. }
  202. if (!strcmp(keyword, "Nonce"))
  203. {
  204. nonce = hex2bin_m(value, &noncelen);
  205. t.nonce = nonce;
  206. t.noncelen = noncelen;
  207. }
  208. if (!strcmp(keyword, "PersonalizationString"))
  209. {
  210. pers = hex2bin_m(value, &perslen);
  211. dctx = FIPS_drbg_new(nid, df | DRBG_FLAG_TEST);
  212. if (!dctx)
  213. exit (1);
  214. FIPS_drbg_set_callbacks(dctx, test_entropy, 0, 0,
  215. test_nonce, 0);
  216. FIPS_drbg_set_app_data(dctx, &t);
  217. randoutlen = (int)FIPS_drbg_get_blocklength(dctx);
  218. r = FIPS_drbg_instantiate(dctx, pers, perslen);
  219. if (!r)
  220. {
  221. fprintf(stderr, "Error instantiating DRBG\n");
  222. exit(1);
  223. }
  224. OPENSSL_free(pers);
  225. OPENSSL_free(ent);
  226. OPENSSL_free(nonce);
  227. ent = nonce = pers = NULL;
  228. gen = 0;
  229. }
  230. if (!strcmp(keyword, "AdditionalInput"))
  231. {
  232. adin = hex2bin_m(value, &adinlen);
  233. if (pr)
  234. continue;
  235. r = FIPS_drbg_generate(dctx, randout, randoutlen, 0, 0,
  236. adin, adinlen);
  237. if (!r)
  238. {
  239. fprintf(stderr, "Error generating DRBG bits\n");
  240. exit(1);
  241. }
  242. if (!r)
  243. exit(1);
  244. OPENSSL_free(adin);
  245. adin = NULL;
  246. gen++;
  247. }
  248. if (pr)
  249. {
  250. if (!strcmp(keyword, "EntropyInputPR"))
  251. {
  252. ent = hex2bin_m(value, &entlen);
  253. t.ent = ent;
  254. t.entlen = entlen;
  255. r = FIPS_drbg_generate(dctx,
  256. randout, randoutlen,
  257. 0, 1, adin, adinlen);
  258. if (!r)
  259. {
  260. fprintf(stderr,
  261. "Error generating DRBG bits\n");
  262. exit(1);
  263. }
  264. OPENSSL_free(adin);
  265. OPENSSL_free(ent);
  266. adin = ent = NULL;
  267. gen++;
  268. }
  269. }
  270. if (!strcmp(keyword, "EntropyInputReseed"))
  271. {
  272. ent = hex2bin_m(value, &entlen);
  273. t.ent = ent;
  274. t.entlen = entlen;
  275. }
  276. if (!strcmp(keyword, "AdditionalInputReseed"))
  277. {
  278. adin = hex2bin_m(value, &adinlen);
  279. FIPS_drbg_reseed(dctx, adin, adinlen);
  280. OPENSSL_free(ent);
  281. OPENSSL_free(adin);
  282. ent = adin = NULL;
  283. }
  284. if (gen == 2)
  285. {
  286. OutputValue("ReturnedBits", randout, randoutlen,
  287. out, 0);
  288. FIPS_drbg_free(dctx);
  289. dctx = NULL;
  290. gen = 0;
  291. }
  292. }
  293. return 0;
  294. }
  295. #endif