• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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