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