2
0

crypto_kernel.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559
  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-2017 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. #ifdef HAVE_CONFIG_H
  45. #include <config.h>
  46. #endif
  47. #include "alloc.h"
  48. #include "crypto_kernel.h"
  49. #include "cipher_types.h"
  50. /* the debug module for the crypto_kernel */
  51. srtp_debug_module_t srtp_mod_crypto_kernel = {
  52. 0, /* debugging is off by default */
  53. "crypto kernel" /* printable name for module */
  54. };
  55. /* crypto_kernel is a global variable, the only one of its datatype */
  56. srtp_crypto_kernel_t crypto_kernel = {
  57. srtp_crypto_kernel_state_insecure, /* start off in insecure state */
  58. NULL, /* no cipher types yet */
  59. NULL, /* no auth types yet */
  60. NULL /* no debug modules yet */
  61. };
  62. #define MAX_RNG_TRIALS 25
  63. srtp_err_status_t srtp_crypto_kernel_init()
  64. {
  65. srtp_err_status_t status;
  66. /* check the security state */
  67. if (crypto_kernel.state == srtp_crypto_kernel_state_secure) {
  68. /*
  69. * we're already in the secure state, but we've been asked to
  70. * re-initialize, so we just re-run the self-tests and then return
  71. */
  72. return srtp_crypto_kernel_status();
  73. }
  74. /* initialize error reporting system */
  75. status = srtp_err_reporting_init();
  76. if (status) {
  77. return status;
  78. }
  79. /* load debug modules */
  80. status = srtp_crypto_kernel_load_debug_module(&srtp_mod_crypto_kernel);
  81. if (status) {
  82. return status;
  83. }
  84. status = srtp_crypto_kernel_load_debug_module(&srtp_mod_auth);
  85. if (status) {
  86. return status;
  87. }
  88. status = srtp_crypto_kernel_load_debug_module(&srtp_mod_cipher);
  89. if (status) {
  90. return status;
  91. }
  92. status = srtp_crypto_kernel_load_debug_module(&srtp_mod_alloc);
  93. if (status) {
  94. return status;
  95. }
  96. /* load cipher types */
  97. status = srtp_crypto_kernel_load_cipher_type(&srtp_null_cipher,
  98. SRTP_NULL_CIPHER);
  99. if (status) {
  100. return status;
  101. }
  102. status = srtp_crypto_kernel_load_cipher_type(&srtp_aes_icm_128,
  103. SRTP_AES_ICM_128);
  104. if (status) {
  105. return status;
  106. }
  107. status = srtp_crypto_kernel_load_cipher_type(&srtp_aes_icm_256,
  108. SRTP_AES_ICM_256);
  109. if (status) {
  110. return status;
  111. }
  112. status = srtp_crypto_kernel_load_debug_module(&srtp_mod_aes_icm);
  113. if (status) {
  114. return status;
  115. }
  116. #ifdef GCM
  117. status = srtp_crypto_kernel_load_cipher_type(&srtp_aes_icm_192,
  118. SRTP_AES_ICM_192);
  119. if (status) {
  120. return status;
  121. }
  122. status = srtp_crypto_kernel_load_cipher_type(&srtp_aes_gcm_128,
  123. SRTP_AES_GCM_128);
  124. if (status) {
  125. return status;
  126. }
  127. status = srtp_crypto_kernel_load_cipher_type(&srtp_aes_gcm_256,
  128. SRTP_AES_GCM_256);
  129. if (status) {
  130. return status;
  131. }
  132. status = srtp_crypto_kernel_load_debug_module(&srtp_mod_aes_gcm);
  133. if (status) {
  134. return status;
  135. }
  136. #endif
  137. /* load auth func types */
  138. status = srtp_crypto_kernel_load_auth_type(&srtp_null_auth, SRTP_NULL_AUTH);
  139. if (status) {
  140. return status;
  141. }
  142. status = srtp_crypto_kernel_load_auth_type(&srtp_hmac, SRTP_HMAC_SHA1);
  143. if (status) {
  144. return status;
  145. }
  146. status = srtp_crypto_kernel_load_debug_module(&srtp_mod_hmac);
  147. if (status) {
  148. return status;
  149. }
  150. /* change state to secure */
  151. crypto_kernel.state = srtp_crypto_kernel_state_secure;
  152. return srtp_err_status_ok;
  153. }
  154. srtp_err_status_t srtp_crypto_kernel_status()
  155. {
  156. srtp_err_status_t status;
  157. srtp_kernel_cipher_type_t *ctype = crypto_kernel.cipher_type_list;
  158. srtp_kernel_auth_type_t *atype = crypto_kernel.auth_type_list;
  159. /* for each cipher type, describe and test */
  160. while (ctype != NULL) {
  161. srtp_err_report(srtp_err_level_info, "cipher: %s\n",
  162. ctype->cipher_type->description);
  163. srtp_err_report(srtp_err_level_info, " self-test: ");
  164. status = srtp_cipher_type_self_test(ctype->cipher_type);
  165. if (status) {
  166. srtp_err_report(srtp_err_level_error, "failed with error code %d\n",
  167. status);
  168. exit(status);
  169. }
  170. srtp_err_report(srtp_err_level_info, "passed\n");
  171. ctype = ctype->next;
  172. }
  173. /* for each auth type, describe and test */
  174. while (atype != NULL) {
  175. srtp_err_report(srtp_err_level_info, "auth func: %s\n",
  176. atype->auth_type->description);
  177. srtp_err_report(srtp_err_level_info, " self-test: ");
  178. status = srtp_auth_type_self_test(atype->auth_type);
  179. if (status) {
  180. srtp_err_report(srtp_err_level_error, "failed with error code %d\n",
  181. status);
  182. exit(status);
  183. }
  184. srtp_err_report(srtp_err_level_info, "passed\n");
  185. atype = atype->next;
  186. }
  187. srtp_crypto_kernel_list_debug_modules();
  188. return srtp_err_status_ok;
  189. }
  190. srtp_err_status_t srtp_crypto_kernel_list_debug_modules()
  191. {
  192. srtp_kernel_debug_module_t *dm = crypto_kernel.debug_module_list;
  193. /* describe each debug module */
  194. srtp_err_report(srtp_err_level_info, "debug modules loaded:\n");
  195. while (dm != NULL) {
  196. srtp_err_report(srtp_err_level_info, " %s ", dm->mod->name);
  197. if (dm->mod->on) {
  198. srtp_err_report(srtp_err_level_info, "(on)\n");
  199. } else {
  200. srtp_err_report(srtp_err_level_info, "(off)\n");
  201. }
  202. dm = dm->next;
  203. }
  204. return srtp_err_status_ok;
  205. }
  206. srtp_err_status_t srtp_crypto_kernel_shutdown()
  207. {
  208. /*
  209. * free dynamic memory used in crypto_kernel at present
  210. */
  211. /* walk down cipher type list, freeing memory */
  212. while (crypto_kernel.cipher_type_list != NULL) {
  213. srtp_kernel_cipher_type_t *ctype = crypto_kernel.cipher_type_list;
  214. crypto_kernel.cipher_type_list = ctype->next;
  215. debug_print(srtp_mod_crypto_kernel, "freeing memory for cipher %s",
  216. ctype->cipher_type->description);
  217. srtp_crypto_free(ctype);
  218. }
  219. /* walk down authetication module list, freeing memory */
  220. while (crypto_kernel.auth_type_list != NULL) {
  221. srtp_kernel_auth_type_t *atype = crypto_kernel.auth_type_list;
  222. crypto_kernel.auth_type_list = atype->next;
  223. debug_print(srtp_mod_crypto_kernel,
  224. "freeing memory for authentication %s",
  225. atype->auth_type->description);
  226. srtp_crypto_free(atype);
  227. }
  228. /* walk down debug module list, freeing memory */
  229. while (crypto_kernel.debug_module_list != NULL) {
  230. srtp_kernel_debug_module_t *kdm = crypto_kernel.debug_module_list;
  231. crypto_kernel.debug_module_list = kdm->next;
  232. debug_print(srtp_mod_crypto_kernel,
  233. "freeing memory for debug module %s", kdm->mod->name);
  234. srtp_crypto_free(kdm);
  235. }
  236. /* return to insecure state */
  237. crypto_kernel.state = srtp_crypto_kernel_state_insecure;
  238. return srtp_err_status_ok;
  239. }
  240. static inline srtp_err_status_t srtp_crypto_kernel_do_load_cipher_type(
  241. const srtp_cipher_type_t *new_ct,
  242. srtp_cipher_type_id_t id,
  243. int replace)
  244. {
  245. srtp_kernel_cipher_type_t *ctype;
  246. srtp_kernel_cipher_type_t *new_ctype = NULL;
  247. srtp_err_status_t status;
  248. /* defensive coding */
  249. if (new_ct == NULL) {
  250. return srtp_err_status_bad_param;
  251. }
  252. if (new_ct->id != id) {
  253. return srtp_err_status_bad_param;
  254. }
  255. /* check cipher type by running self-test */
  256. status = srtp_cipher_type_self_test(new_ct);
  257. if (status) {
  258. return status;
  259. }
  260. /* walk down list, checking if this type is in the list already */
  261. ctype = crypto_kernel.cipher_type_list;
  262. while (ctype != NULL) {
  263. if (id == ctype->id) {
  264. if (!replace) {
  265. return srtp_err_status_bad_param;
  266. }
  267. status =
  268. srtp_cipher_type_test(new_ct, ctype->cipher_type->test_data);
  269. if (status) {
  270. return status;
  271. }
  272. new_ctype = ctype;
  273. break;
  274. } else if (new_ct == ctype->cipher_type) {
  275. return srtp_err_status_bad_param;
  276. }
  277. ctype = ctype->next;
  278. }
  279. /* if not found, put new_ct at the head of the list */
  280. if (ctype == NULL) {
  281. /* allocate memory */
  282. new_ctype = (srtp_kernel_cipher_type_t *)srtp_crypto_alloc(
  283. sizeof(srtp_kernel_cipher_type_t));
  284. if (new_ctype == NULL) {
  285. return srtp_err_status_alloc_fail;
  286. }
  287. new_ctype->next = crypto_kernel.cipher_type_list;
  288. /* set head of list to new cipher type */
  289. crypto_kernel.cipher_type_list = new_ctype;
  290. }
  291. /* set fields */
  292. new_ctype->cipher_type = new_ct;
  293. new_ctype->id = id;
  294. return srtp_err_status_ok;
  295. }
  296. srtp_err_status_t srtp_crypto_kernel_load_cipher_type(
  297. const srtp_cipher_type_t *new_ct,
  298. srtp_cipher_type_id_t id)
  299. {
  300. return srtp_crypto_kernel_do_load_cipher_type(new_ct, id, 0);
  301. }
  302. srtp_err_status_t srtp_replace_cipher_type(const srtp_cipher_type_t *new_ct,
  303. srtp_cipher_type_id_t id)
  304. {
  305. return srtp_crypto_kernel_do_load_cipher_type(new_ct, id, 1);
  306. }
  307. srtp_err_status_t srtp_crypto_kernel_do_load_auth_type(
  308. const srtp_auth_type_t *new_at,
  309. srtp_auth_type_id_t id,
  310. int replace)
  311. {
  312. srtp_kernel_auth_type_t *atype;
  313. srtp_kernel_auth_type_t *new_atype = NULL;
  314. srtp_err_status_t status;
  315. /* defensive coding */
  316. if (new_at == NULL) {
  317. return srtp_err_status_bad_param;
  318. }
  319. if (new_at->id != id) {
  320. return srtp_err_status_bad_param;
  321. }
  322. /* check auth type by running self-test */
  323. status = srtp_auth_type_self_test(new_at);
  324. if (status) {
  325. return status;
  326. }
  327. /* walk down list, checking if this type is in the list already */
  328. atype = crypto_kernel.auth_type_list;
  329. while (atype != NULL) {
  330. if (id == atype->id) {
  331. if (!replace) {
  332. return srtp_err_status_bad_param;
  333. }
  334. status = srtp_auth_type_test(new_at, atype->auth_type->test_data);
  335. if (status) {
  336. return status;
  337. }
  338. new_atype = atype;
  339. break;
  340. } else if (new_at == atype->auth_type) {
  341. return srtp_err_status_bad_param;
  342. }
  343. atype = atype->next;
  344. }
  345. /* if not found, put new_at at the head of the list */
  346. if (atype == NULL) {
  347. /* allocate memory */
  348. new_atype = (srtp_kernel_auth_type_t *)srtp_crypto_alloc(
  349. sizeof(srtp_kernel_auth_type_t));
  350. if (new_atype == NULL) {
  351. return srtp_err_status_alloc_fail;
  352. }
  353. new_atype->next = crypto_kernel.auth_type_list;
  354. /* set head of list to new auth type */
  355. crypto_kernel.auth_type_list = new_atype;
  356. }
  357. /* set fields */
  358. new_atype->auth_type = new_at;
  359. new_atype->id = id;
  360. return srtp_err_status_ok;
  361. }
  362. srtp_err_status_t srtp_crypto_kernel_load_auth_type(
  363. const srtp_auth_type_t *new_at,
  364. srtp_auth_type_id_t id)
  365. {
  366. return srtp_crypto_kernel_do_load_auth_type(new_at, id, 0);
  367. }
  368. srtp_err_status_t srtp_replace_auth_type(const srtp_auth_type_t *new_at,
  369. srtp_auth_type_id_t id)
  370. {
  371. return srtp_crypto_kernel_do_load_auth_type(new_at, id, 1);
  372. }
  373. const srtp_cipher_type_t *srtp_crypto_kernel_get_cipher_type(
  374. srtp_cipher_type_id_t id)
  375. {
  376. srtp_kernel_cipher_type_t *ctype;
  377. /* walk down list, looking for id */
  378. ctype = crypto_kernel.cipher_type_list;
  379. while (ctype != NULL) {
  380. if (id == ctype->id) {
  381. return ctype->cipher_type;
  382. }
  383. ctype = ctype->next;
  384. }
  385. /* haven't found the right one, indicate failure by returning NULL */
  386. return NULL;
  387. }
  388. srtp_err_status_t srtp_crypto_kernel_alloc_cipher(srtp_cipher_type_id_t id,
  389. srtp_cipher_pointer_t *cp,
  390. int key_len,
  391. int tag_len)
  392. {
  393. const srtp_cipher_type_t *ct;
  394. /*
  395. * if the crypto_kernel is not yet initialized, we refuse to allocate
  396. * any ciphers - this is a bit extra-paranoid
  397. */
  398. if (crypto_kernel.state != srtp_crypto_kernel_state_secure) {
  399. return srtp_err_status_init_fail;
  400. }
  401. ct = srtp_crypto_kernel_get_cipher_type(id);
  402. if (!ct) {
  403. return srtp_err_status_fail;
  404. }
  405. return ((ct)->alloc(cp, key_len, tag_len));
  406. }
  407. const srtp_auth_type_t *srtp_crypto_kernel_get_auth_type(srtp_auth_type_id_t id)
  408. {
  409. srtp_kernel_auth_type_t *atype;
  410. /* walk down list, looking for id */
  411. atype = crypto_kernel.auth_type_list;
  412. while (atype != NULL) {
  413. if (id == atype->id) {
  414. return atype->auth_type;
  415. }
  416. atype = atype->next;
  417. }
  418. /* haven't found the right one, indicate failure by returning NULL */
  419. return NULL;
  420. }
  421. srtp_err_status_t srtp_crypto_kernel_alloc_auth(srtp_auth_type_id_t id,
  422. srtp_auth_pointer_t *ap,
  423. int key_len,
  424. int tag_len)
  425. {
  426. const srtp_auth_type_t *at;
  427. /*
  428. * if the crypto_kernel is not yet initialized, we refuse to allocate
  429. * any auth functions - this is a bit extra-paranoid
  430. */
  431. if (crypto_kernel.state != srtp_crypto_kernel_state_secure) {
  432. return srtp_err_status_init_fail;
  433. }
  434. at = srtp_crypto_kernel_get_auth_type(id);
  435. if (!at) {
  436. return srtp_err_status_fail;
  437. }
  438. return ((at)->alloc(ap, key_len, tag_len));
  439. }
  440. srtp_err_status_t srtp_crypto_kernel_load_debug_module(
  441. srtp_debug_module_t *new_dm)
  442. {
  443. srtp_kernel_debug_module_t *kdm, *new;
  444. /* defensive coding */
  445. if (new_dm == NULL || new_dm->name == NULL) {
  446. return srtp_err_status_bad_param;
  447. }
  448. /* walk down list, checking if this type is in the list already */
  449. kdm = crypto_kernel.debug_module_list;
  450. while (kdm != NULL) {
  451. if (strncmp(new_dm->name, kdm->mod->name, 64) == 0) {
  452. return srtp_err_status_bad_param;
  453. }
  454. kdm = kdm->next;
  455. }
  456. /* put new_dm at the head of the list */
  457. /* allocate memory */
  458. new = (srtp_kernel_debug_module_t *)srtp_crypto_alloc(
  459. sizeof(srtp_kernel_debug_module_t));
  460. if (new == NULL) {
  461. return srtp_err_status_alloc_fail;
  462. }
  463. /* set fields */
  464. new->mod = new_dm;
  465. new->next = crypto_kernel.debug_module_list;
  466. /* set head of list to new cipher type */
  467. crypto_kernel.debug_module_list = new;
  468. return srtp_err_status_ok;
  469. }
  470. srtp_err_status_t srtp_crypto_kernel_set_debug_module(const char *name, int on)
  471. {
  472. srtp_kernel_debug_module_t *kdm;
  473. /* walk down list, checking if this type is in the list already */
  474. kdm = crypto_kernel.debug_module_list;
  475. while (kdm != NULL) {
  476. if (strncmp(name, kdm->mod->name, 64) == 0) {
  477. kdm->mod->on = on;
  478. return srtp_err_status_ok;
  479. }
  480. kdm = kdm->next;
  481. }
  482. return srtp_err_status_fail;
  483. }