crypto_kernel.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596
  1. /*
  2. * crypto_kernel.c
  3. *
  4. * header for the cryptographic kernel
  5. *
  6. * David A. McGrew
  7. * Cisco Systems, Inc.
  8. */
  9. /*
  10. *
  11. * Copyright(c) 2001-2006,2013 Cisco Systems, Inc.
  12. * All rights reserved.
  13. *
  14. * Redistribution and use in source and binary forms, with or without
  15. * modification, are permitted provided that the following conditions
  16. * are met:
  17. *
  18. * Redistributions of source code must retain the above copyright
  19. * notice, this list of conditions and the following disclaimer.
  20. *
  21. * Redistributions in binary form must reproduce the above
  22. * copyright notice, this list of conditions and the following
  23. * disclaimer in the documentation and/or other materials provided
  24. * with the distribution.
  25. *
  26. * Neither the name of the Cisco Systems, Inc. nor the names of its
  27. * contributors may be used to endorse or promote products derived
  28. * from this software without specific prior written permission.
  29. *
  30. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  31. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  32. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  33. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  34. * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
  35. * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  36. * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  37. * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  38. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  39. * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  40. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
  41. * OF THE POSSIBILITY OF SUCH DAMAGE.
  42. *
  43. */
  44. #include "alloc.h"
  45. #include "crypto_kernel.h"
  46. /* the debug module for the crypto_kernel */
  47. debug_module_t mod_crypto_kernel = {
  48. 0, /* debugging is off by default */
  49. "crypto kernel" /* printable name for module */
  50. };
  51. /*
  52. * other debug modules that can be included in the kernel
  53. */
  54. extern debug_module_t mod_auth;
  55. extern debug_module_t mod_cipher;
  56. extern debug_module_t mod_stat;
  57. extern debug_module_t mod_alloc;
  58. /*
  59. * cipher types that can be included in the kernel
  60. */
  61. extern cipher_type_t null_cipher;
  62. extern cipher_type_t aes_icm;
  63. #ifndef OPENSSL
  64. extern cipher_type_t aes_cbc;
  65. #else
  66. extern cipher_type_t aes_gcm_128_openssl;
  67. extern cipher_type_t aes_gcm_256_openssl;
  68. #endif
  69. /*
  70. * auth func types that can be included in the kernel
  71. */
  72. extern auth_type_t null_auth;
  73. extern auth_type_t hmac;
  74. /* crypto_kernel is a global variable, the only one of its datatype */
  75. crypto_kernel_t
  76. crypto_kernel = {
  77. crypto_kernel_state_insecure, /* start off in insecure state */
  78. NULL, /* no cipher types yet */
  79. NULL, /* no auth types yet */
  80. NULL /* no debug modules yet */
  81. };
  82. #define MAX_RNG_TRIALS 25
  83. err_status_t
  84. crypto_kernel_init() {
  85. err_status_t status;
  86. /* check the security state */
  87. if (crypto_kernel.state == crypto_kernel_state_secure) {
  88. /*
  89. * we're already in the secure state, but we've been asked to
  90. * re-initialize, so we just re-run the self-tests and then return
  91. */
  92. return crypto_kernel_status();
  93. }
  94. /* initialize error reporting system */
  95. status = err_reporting_init("crypto");
  96. if (status)
  97. return status;
  98. /* load debug modules */
  99. status = crypto_kernel_load_debug_module(&mod_crypto_kernel);
  100. if (status)
  101. return status;
  102. status = crypto_kernel_load_debug_module(&mod_auth);
  103. if (status)
  104. return status;
  105. status = crypto_kernel_load_debug_module(&mod_cipher);
  106. if (status)
  107. return status;
  108. status = crypto_kernel_load_debug_module(&mod_stat);
  109. if (status)
  110. return status;
  111. status = crypto_kernel_load_debug_module(&mod_alloc);
  112. if (status)
  113. return status;
  114. /* initialize random number generator */
  115. status = rand_source_init();
  116. if (status)
  117. return status;
  118. /* run FIPS-140 statistical tests on rand_source */
  119. status = stat_test_rand_source_with_repetition(rand_source_get_octet_string, MAX_RNG_TRIALS);
  120. if (status)
  121. return status;
  122. #ifndef OPENSSL
  123. /* initialize pseudorandom number generator */
  124. status = ctr_prng_init(rand_source_get_octet_string);
  125. if (status)
  126. return status;
  127. /* run FIPS-140 statistical tests on ctr_prng */
  128. status = stat_test_rand_source_with_repetition(ctr_prng_get_octet_string, MAX_RNG_TRIALS);
  129. if (status)
  130. return status;
  131. #endif
  132. /* load cipher types */
  133. status = crypto_kernel_load_cipher_type(&null_cipher, NULL_CIPHER);
  134. if (status)
  135. return status;
  136. status = crypto_kernel_load_cipher_type(&aes_icm, AES_ICM);
  137. if (status)
  138. return status;
  139. #ifndef OPENSSL
  140. status = crypto_kernel_load_cipher_type(&aes_cbc, AES_CBC);
  141. if (status)
  142. return status;
  143. #else
  144. status = crypto_kernel_load_cipher_type(&aes_gcm_128_openssl, AES_128_GCM);
  145. if (status) {
  146. return status;
  147. }
  148. status = crypto_kernel_load_cipher_type(&aes_gcm_256_openssl, AES_256_GCM);
  149. if (status) {
  150. return status;
  151. }
  152. #endif
  153. /* load auth func types */
  154. status = crypto_kernel_load_auth_type(&null_auth, NULL_AUTH);
  155. if (status)
  156. return status;
  157. status = crypto_kernel_load_auth_type(&hmac, HMAC_SHA1);
  158. if (status)
  159. return status;
  160. /* change state to secure */
  161. crypto_kernel.state = crypto_kernel_state_secure;
  162. return err_status_ok;
  163. }
  164. err_status_t
  165. crypto_kernel_status() {
  166. err_status_t status;
  167. kernel_cipher_type_t *ctype = crypto_kernel.cipher_type_list;
  168. kernel_auth_type_t *atype = crypto_kernel.auth_type_list;
  169. kernel_debug_module_t *dm = crypto_kernel.debug_module_list;
  170. /* run FIPS-140 statistical tests on rand_source */
  171. printf("testing rand_source...");
  172. status = stat_test_rand_source_with_repetition(rand_source_get_octet_string, MAX_RNG_TRIALS);
  173. if (status) {
  174. printf("failed\n");
  175. crypto_kernel.state = crypto_kernel_state_insecure;
  176. return status;
  177. }
  178. printf("passed\n");
  179. /* for each cipher type, describe and test */
  180. while(ctype != NULL) {
  181. printf("cipher: %s\n", ctype->cipher_type->description);
  182. printf(" instance count: %d\n", ctype->cipher_type->ref_count);
  183. printf(" self-test: ");
  184. status = cipher_type_self_test(ctype->cipher_type);
  185. if (status) {
  186. printf("failed with error code %d\n", status);
  187. exit(status);
  188. }
  189. printf("passed\n");
  190. ctype = ctype->next;
  191. }
  192. /* for each auth type, describe and test */
  193. while(atype != NULL) {
  194. printf("auth func: %s\n", atype->auth_type->description);
  195. printf(" instance count: %d\n", atype->auth_type->ref_count);
  196. printf(" self-test: ");
  197. status = auth_type_self_test(atype->auth_type);
  198. if (status) {
  199. printf("failed with error code %d\n", status);
  200. exit(status);
  201. }
  202. printf("passed\n");
  203. atype = atype->next;
  204. }
  205. /* describe each debug module */
  206. printf("debug modules loaded:\n");
  207. while (dm != NULL) {
  208. printf(" %s ", dm->mod->name);
  209. if (dm->mod->on)
  210. printf("(on)\n");
  211. else
  212. printf("(off)\n");
  213. dm = dm->next;
  214. }
  215. return err_status_ok;
  216. }
  217. err_status_t
  218. crypto_kernel_list_debug_modules() {
  219. kernel_debug_module_t *dm = crypto_kernel.debug_module_list;
  220. /* describe each debug module */
  221. printf("debug modules loaded:\n");
  222. while (dm != NULL) {
  223. printf(" %s ", dm->mod->name);
  224. if (dm->mod->on)
  225. printf("(on)\n");
  226. else
  227. printf("(off)\n");
  228. dm = dm->next;
  229. }
  230. return err_status_ok;
  231. }
  232. err_status_t
  233. crypto_kernel_shutdown() {
  234. err_status_t status;
  235. /*
  236. * free dynamic memory used in crypto_kernel at present
  237. */
  238. /* walk down cipher type list, freeing memory */
  239. while (crypto_kernel.cipher_type_list != NULL) {
  240. kernel_cipher_type_t *ctype = crypto_kernel.cipher_type_list;
  241. crypto_kernel.cipher_type_list = ctype->next;
  242. debug_print(mod_crypto_kernel,
  243. "freeing memory for cipher %s",
  244. ctype->cipher_type->description);
  245. crypto_free(ctype);
  246. }
  247. /* walk down authetication module list, freeing memory */
  248. while (crypto_kernel.auth_type_list != NULL) {
  249. kernel_auth_type_t *atype = crypto_kernel.auth_type_list;
  250. crypto_kernel.auth_type_list = atype->next;
  251. debug_print(mod_crypto_kernel,
  252. "freeing memory for authentication %s",
  253. atype->auth_type->description);
  254. crypto_free(atype);
  255. }
  256. /* walk down debug module list, freeing memory */
  257. while (crypto_kernel.debug_module_list != NULL) {
  258. kernel_debug_module_t *kdm = crypto_kernel.debug_module_list;
  259. crypto_kernel.debug_module_list = kdm->next;
  260. debug_print(mod_crypto_kernel,
  261. "freeing memory for debug module %s",
  262. kdm->mod->name);
  263. crypto_free(kdm);
  264. }
  265. /* de-initialize random number generator */ status = rand_source_deinit();
  266. if (status)
  267. return status;
  268. /* return to insecure state */
  269. crypto_kernel.state = crypto_kernel_state_insecure;
  270. return err_status_ok;
  271. }
  272. static inline err_status_t
  273. crypto_kernel_do_load_cipher_type(cipher_type_t *new_ct, cipher_type_id_t id,
  274. int replace) {
  275. kernel_cipher_type_t *ctype, *new_ctype = 0;
  276. err_status_t status;
  277. /* defensive coding */
  278. if (new_ct == NULL)
  279. return err_status_bad_param;
  280. if (new_ct->id != id)
  281. return err_status_bad_param;
  282. /* check cipher type by running self-test */
  283. status = cipher_type_self_test(new_ct);
  284. if (status) {
  285. return status;
  286. }
  287. /* walk down list, checking if this type is in the list already */
  288. ctype = crypto_kernel.cipher_type_list;
  289. while (ctype != NULL) {
  290. if (id == ctype->id) {
  291. if (!replace)
  292. return err_status_bad_param;
  293. status = cipher_type_test(new_ct, ctype->cipher_type->test_data);
  294. if (status)
  295. return status;
  296. new_ctype = ctype;
  297. break;
  298. }
  299. else if (new_ct == ctype->cipher_type)
  300. return err_status_bad_param;
  301. ctype = ctype->next;
  302. }
  303. /* if not found, put new_ct at the head of the list */
  304. if (ctype == NULL) {
  305. /* allocate memory */
  306. new_ctype = (kernel_cipher_type_t *) crypto_alloc(sizeof(kernel_cipher_type_t));
  307. if (new_ctype == NULL)
  308. return err_status_alloc_fail;
  309. new_ctype->next = crypto_kernel.cipher_type_list;
  310. /* set head of list to new cipher type */
  311. crypto_kernel.cipher_type_list = new_ctype;
  312. }
  313. /* set fields */
  314. new_ctype->cipher_type = new_ct;
  315. new_ctype->id = id;
  316. /* load debug module, if there is one present */
  317. if (new_ct->debug != NULL)
  318. crypto_kernel_load_debug_module(new_ct->debug);
  319. /* we could check for errors here */
  320. return err_status_ok;
  321. }
  322. err_status_t
  323. crypto_kernel_load_cipher_type(cipher_type_t *new_ct, cipher_type_id_t id) {
  324. return crypto_kernel_do_load_cipher_type(new_ct, id, 0);
  325. }
  326. err_status_t
  327. crypto_kernel_replace_cipher_type(cipher_type_t *new_ct, cipher_type_id_t id) {
  328. return crypto_kernel_do_load_cipher_type(new_ct, id, 1);
  329. }
  330. err_status_t
  331. crypto_kernel_do_load_auth_type(auth_type_t *new_at, auth_type_id_t id,
  332. int replace) {
  333. kernel_auth_type_t *atype, *new_atype = 0;
  334. err_status_t status;
  335. /* defensive coding */
  336. if (new_at == NULL)
  337. return err_status_bad_param;
  338. if (new_at->id != id)
  339. return err_status_bad_param;
  340. /* check auth type by running self-test */
  341. status = auth_type_self_test(new_at);
  342. if (status) {
  343. return status;
  344. }
  345. /* walk down list, checking if this type is in the list already */
  346. atype = crypto_kernel.auth_type_list;
  347. while (atype != NULL) {
  348. if (id == atype->id) {
  349. if (!replace)
  350. return err_status_bad_param;
  351. status = auth_type_test(new_at, atype->auth_type->test_data);
  352. if (status)
  353. return status;
  354. new_atype = atype;
  355. break;
  356. }
  357. else if (new_at == atype->auth_type)
  358. return err_status_bad_param;
  359. atype = atype->next;
  360. }
  361. /* if not found, put new_at at the head of the list */
  362. if (atype == NULL) {
  363. /* allocate memory */
  364. new_atype = (kernel_auth_type_t *)crypto_alloc(sizeof(kernel_auth_type_t));
  365. if (new_atype == NULL)
  366. return err_status_alloc_fail;
  367. new_atype->next = crypto_kernel.auth_type_list;
  368. /* set head of list to new auth type */
  369. crypto_kernel.auth_type_list = new_atype;
  370. }
  371. /* set fields */
  372. new_atype->auth_type = new_at;
  373. new_atype->id = id;
  374. /* load debug module, if there is one present */
  375. if (new_at->debug != NULL)
  376. crypto_kernel_load_debug_module(new_at->debug);
  377. /* we could check for errors here */
  378. return err_status_ok;
  379. }
  380. err_status_t
  381. crypto_kernel_load_auth_type(auth_type_t *new_at, auth_type_id_t id) {
  382. return crypto_kernel_do_load_auth_type(new_at, id, 0);
  383. }
  384. err_status_t
  385. crypto_kernel_replace_auth_type(auth_type_t *new_at, auth_type_id_t id) {
  386. return crypto_kernel_do_load_auth_type(new_at, id, 1);
  387. }
  388. cipher_type_t *
  389. crypto_kernel_get_cipher_type(cipher_type_id_t id) {
  390. kernel_cipher_type_t *ctype;
  391. /* walk down list, looking for id */
  392. ctype = crypto_kernel.cipher_type_list;
  393. while (ctype != NULL) {
  394. if (id == ctype->id)
  395. return ctype->cipher_type;
  396. ctype = ctype->next;
  397. }
  398. /* haven't found the right one, indicate failure by returning NULL */
  399. return NULL;
  400. }
  401. err_status_t
  402. crypto_kernel_alloc_cipher(cipher_type_id_t id,
  403. cipher_pointer_t *cp,
  404. int key_len,
  405. int tag_len) {
  406. cipher_type_t *ct;
  407. /*
  408. * if the crypto_kernel is not yet initialized, we refuse to allocate
  409. * any ciphers - this is a bit extra-paranoid
  410. */
  411. if (crypto_kernel.state != crypto_kernel_state_secure)
  412. return err_status_init_fail;
  413. ct = crypto_kernel_get_cipher_type(id);
  414. if (!ct)
  415. return err_status_fail;
  416. return ((ct)->alloc(cp, key_len, tag_len));
  417. }
  418. auth_type_t *
  419. crypto_kernel_get_auth_type(auth_type_id_t id) {
  420. kernel_auth_type_t *atype;
  421. /* walk down list, looking for id */
  422. atype = crypto_kernel.auth_type_list;
  423. while (atype != NULL) {
  424. if (id == atype->id)
  425. return atype->auth_type;
  426. atype = atype->next;
  427. }
  428. /* haven't found the right one, indicate failure by returning NULL */
  429. return NULL;
  430. }
  431. err_status_t
  432. crypto_kernel_alloc_auth(auth_type_id_t id,
  433. auth_pointer_t *ap,
  434. int key_len,
  435. int tag_len) {
  436. auth_type_t *at;
  437. /*
  438. * if the crypto_kernel is not yet initialized, we refuse to allocate
  439. * any auth functions - this is a bit extra-paranoid
  440. */
  441. if (crypto_kernel.state != crypto_kernel_state_secure)
  442. return err_status_init_fail;
  443. at = crypto_kernel_get_auth_type(id);
  444. if (!at)
  445. return err_status_fail;
  446. return ((at)->alloc(ap, key_len, tag_len));
  447. }
  448. err_status_t
  449. crypto_kernel_load_debug_module(debug_module_t *new_dm) {
  450. kernel_debug_module_t *kdm, *new;
  451. /* defensive coding */
  452. if (new_dm == NULL)
  453. return err_status_bad_param;
  454. /* walk down list, checking if this type is in the list already */
  455. kdm = crypto_kernel.debug_module_list;
  456. while (kdm != NULL) {
  457. if (strncmp(new_dm->name, kdm->mod->name, 64) == 0)
  458. return err_status_bad_param;
  459. kdm = kdm->next;
  460. }
  461. /* put new_dm at the head of the list */
  462. /* allocate memory */
  463. new = (kernel_debug_module_t *)crypto_alloc(sizeof(kernel_debug_module_t));
  464. if (new == NULL)
  465. return err_status_alloc_fail;
  466. /* set fields */
  467. new->mod = new_dm;
  468. new->next = crypto_kernel.debug_module_list;
  469. /* set head of list to new cipher type */
  470. crypto_kernel.debug_module_list = new;
  471. return err_status_ok;
  472. }
  473. err_status_t
  474. crypto_kernel_set_debug_module(char *name, int on) {
  475. kernel_debug_module_t *kdm;
  476. /* walk down list, checking if this type is in the list already */
  477. kdm = crypto_kernel.debug_module_list;
  478. while (kdm != NULL) {
  479. if (strncmp(name, kdm->mod->name, 64) == 0) {
  480. kdm->mod->on = on;
  481. return err_status_ok;
  482. }
  483. kdm = kdm->next;
  484. }
  485. return err_status_fail;
  486. }
  487. err_status_t
  488. crypto_get_random(unsigned char *buffer, unsigned int length) {
  489. if (crypto_kernel.state == crypto_kernel_state_secure)
  490. #ifdef OPENSSL
  491. return rand_source_get_octet_string(buffer, length);
  492. #else
  493. return ctr_prng_get_octet_string(buffer, length);
  494. #endif
  495. else
  496. return err_status_fail;
  497. }