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