Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(11)

Side by Side Diff: srtp/crypto/kernel/crypto_kernel.c

Issue 2344973002: Update libsrtp to version 2.0 (Closed)
Patch Set: Add '.' back to include_dirs Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « srtp/crypto/kernel/alloc.c ('k') | srtp/crypto/kernel/err.c » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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
45
46 #ifdef HAVE_CONFIG_H
47 #include <config.h>
48 #endif
49
50 #include "alloc.h"
51
52 #include "crypto_kernel.h"
53
54 /* the debug module for the crypto_kernel */
55
56 debug_module_t mod_crypto_kernel = {
57 0, /* debugging is off by default */
58 "crypto kernel" /* printable name for module */
59 };
60
61 /*
62 * other debug modules that can be included in the kernel
63 */
64
65 extern debug_module_t mod_auth;
66 extern debug_module_t mod_cipher;
67 extern debug_module_t mod_stat;
68 extern debug_module_t mod_alloc;
69
70 /*
71 * cipher types that can be included in the kernel
72 */
73
74 extern cipher_type_t null_cipher;
75 extern cipher_type_t aes_icm;
76 #ifndef OPENSSL
77 extern cipher_type_t aes_cbc;
78 #else
79 #ifndef SRTP_NO_AES192
80 extern cipher_type_t aes_icm_192;
81 #endif
82 extern cipher_type_t aes_icm_256;
83 extern cipher_type_t aes_gcm_128_openssl;
84 extern cipher_type_t aes_gcm_256_openssl;
85 #endif
86
87
88 /*
89 * auth func types that can be included in the kernel
90 */
91
92 extern auth_type_t null_auth;
93 extern auth_type_t hmac;
94
95 /* crypto_kernel is a global variable, the only one of its datatype */
96
97 crypto_kernel_t
98 crypto_kernel = {
99 crypto_kernel_state_insecure, /* start off in insecure state */
100 NULL, /* no cipher types yet */
101 NULL, /* no auth types yet */
102 NULL /* no debug modules yet */
103 };
104
105 #define MAX_RNG_TRIALS 25
106
107 err_status_t
108 crypto_kernel_init() {
109 err_status_t status;
110
111 /* check the security state */
112 if (crypto_kernel.state == crypto_kernel_state_secure) {
113
114 /*
115 * we're already in the secure state, but we've been asked to
116 * re-initialize, so we just re-run the self-tests and then return
117 */
118 return crypto_kernel_status();
119 }
120
121 /* initialize error reporting system */
122 status = err_reporting_init("crypto");
123 if (status)
124 return status;
125
126 /* load debug modules */
127 status = crypto_kernel_load_debug_module(&mod_crypto_kernel);
128 if (status)
129 return status;
130 status = crypto_kernel_load_debug_module(&mod_auth);
131 if (status)
132 return status;
133 status = crypto_kernel_load_debug_module(&mod_cipher);
134 if (status)
135 return status;
136 status = crypto_kernel_load_debug_module(&mod_stat);
137 if (status)
138 return status;
139 status = crypto_kernel_load_debug_module(&mod_alloc);
140 if (status)
141 return status;
142
143 /* initialize random number generator */
144 status = rand_source_init();
145 if (status)
146 return status;
147
148 /* run FIPS-140 statistical tests on rand_source */
149 status = stat_test_rand_source_with_repetition(rand_source_get_octet_string, M AX_RNG_TRIALS);
150 if (status)
151 return status;
152
153 #ifndef OPENSSL
154 /* initialize pseudorandom number generator */
155 status = ctr_prng_init(rand_source_get_octet_string);
156 if (status)
157 return status;
158
159 /* run FIPS-140 statistical tests on ctr_prng */
160 status = stat_test_rand_source_with_repetition(ctr_prng_get_octet_string, MAX_ RNG_TRIALS);
161 if (status)
162 return status;
163 #endif
164
165 /* load cipher types */
166 status = crypto_kernel_load_cipher_type(&null_cipher, NULL_CIPHER);
167 if (status)
168 return status;
169 status = crypto_kernel_load_cipher_type(&aes_icm, AES_ICM);
170 if (status)
171 return status;
172 #ifndef OPENSSL
173 status = crypto_kernel_load_cipher_type(&aes_cbc, AES_CBC);
174 if (status)
175 return status;
176 #else
177 #ifndef SRTP_NO_AES192
178 status = crypto_kernel_load_cipher_type(&aes_icm_192, AES_192_ICM);
179 if (status) {
180 return status;
181 }
182 #endif
183 status = crypto_kernel_load_cipher_type(&aes_icm_256, AES_256_ICM);
184 if (status) {
185 return status;
186 }
187 status = crypto_kernel_load_cipher_type(&aes_gcm_128_openssl, AES_128_GCM);
188 if (status) {
189 return status;
190 }
191 status = crypto_kernel_load_cipher_type(&aes_gcm_256_openssl, AES_256_GCM);
192 if (status) {
193 return status;
194 }
195 #endif
196
197 /* load auth func types */
198 status = crypto_kernel_load_auth_type(&null_auth, NULL_AUTH);
199 if (status)
200 return status;
201 status = crypto_kernel_load_auth_type(&hmac, HMAC_SHA1);
202 if (status)
203 return status;
204
205 /* change state to secure */
206 crypto_kernel.state = crypto_kernel_state_secure;
207
208 return err_status_ok;
209 }
210
211 err_status_t
212 crypto_kernel_status() {
213 err_status_t status;
214 kernel_cipher_type_t *ctype = crypto_kernel.cipher_type_list;
215 kernel_auth_type_t *atype = crypto_kernel.auth_type_list;
216 kernel_debug_module_t *dm = crypto_kernel.debug_module_list;
217
218 /* run FIPS-140 statistical tests on rand_source */
219 printf("testing rand_source...");
220 status = stat_test_rand_source_with_repetition(rand_source_get_octet_string, M AX_RNG_TRIALS);
221 if (status) {
222 printf("failed\n");
223 crypto_kernel.state = crypto_kernel_state_insecure;
224 return status;
225 }
226 printf("passed\n");
227
228 /* for each cipher type, describe and test */
229 while(ctype != NULL) {
230 printf("cipher: %s\n", ctype->cipher_type->description);
231 printf(" instance count: %d\n", ctype->cipher_type->ref_count);
232 printf(" self-test: ");
233 status = cipher_type_self_test(ctype->cipher_type);
234 if (status) {
235 printf("failed with error code %d\n", status);
236 exit(status);
237 }
238 printf("passed\n");
239 ctype = ctype->next;
240 }
241
242 /* for each auth type, describe and test */
243 while(atype != NULL) {
244 printf("auth func: %s\n", atype->auth_type->description);
245 printf(" instance count: %d\n", atype->auth_type->ref_count);
246 printf(" self-test: ");
247 status = auth_type_self_test(atype->auth_type);
248 if (status) {
249 printf("failed with error code %d\n", status);
250 exit(status);
251 }
252 printf("passed\n");
253 atype = atype->next;
254 }
255
256 /* describe each debug module */
257 printf("debug modules loaded:\n");
258 while (dm != NULL) {
259 printf(" %s ", dm->mod->name);
260 if (dm->mod->on)
261 printf("(on)\n");
262 else
263 printf("(off)\n");
264 dm = dm->next;
265 }
266
267 return err_status_ok;
268 }
269
270 err_status_t
271 crypto_kernel_list_debug_modules() {
272 kernel_debug_module_t *dm = crypto_kernel.debug_module_list;
273
274 /* describe each debug module */
275 printf("debug modules loaded:\n");
276 while (dm != NULL) {
277 printf(" %s ", dm->mod->name);
278 if (dm->mod->on)
279 printf("(on)\n");
280 else
281 printf("(off)\n");
282 dm = dm->next;
283 }
284
285 return err_status_ok;
286 }
287
288 err_status_t
289 crypto_kernel_shutdown() {
290 err_status_t status;
291
292 /*
293 * free dynamic memory used in crypto_kernel at present
294 */
295
296 /* walk down cipher type list, freeing memory */
297 while (crypto_kernel.cipher_type_list != NULL) {
298 kernel_cipher_type_t *ctype = crypto_kernel.cipher_type_list;
299 crypto_kernel.cipher_type_list = ctype->next;
300 debug_print(mod_crypto_kernel,
301 "freeing memory for cipher %s",
302 ctype->cipher_type->description);
303 crypto_free(ctype);
304 }
305
306 /* walk down authetication module list, freeing memory */
307 while (crypto_kernel.auth_type_list != NULL) {
308 kernel_auth_type_t *atype = crypto_kernel.auth_type_list;
309 crypto_kernel.auth_type_list = atype->next;
310 debug_print(mod_crypto_kernel,
311 "freeing memory for authentication %s",
312 atype->auth_type->description);
313 crypto_free(atype);
314 }
315
316 /* walk down debug module list, freeing memory */
317 while (crypto_kernel.debug_module_list != NULL) {
318 kernel_debug_module_t *kdm = crypto_kernel.debug_module_list;
319 crypto_kernel.debug_module_list = kdm->next;
320 debug_print(mod_crypto_kernel,
321 "freeing memory for debug module %s",
322 kdm->mod->name);
323 crypto_free(kdm);
324 }
325
326 /* de-initialize random number generator */ status = rand_source_deinit();
327 if (status)
328 return status;
329
330 /* return to insecure state */
331 crypto_kernel.state = crypto_kernel_state_insecure;
332
333 return err_status_ok;
334 }
335
336 static inline err_status_t
337 crypto_kernel_do_load_cipher_type(cipher_type_t *new_ct, cipher_type_id_t id,
338 int replace) {
339 kernel_cipher_type_t *ctype, *new_ctype;
340 err_status_t status;
341
342 /* defensive coding */
343 if (new_ct == NULL)
344 return err_status_bad_param;
345
346 if (new_ct->id != id)
347 return err_status_bad_param;
348
349 /* check cipher type by running self-test */
350 status = cipher_type_self_test(new_ct);
351 if (status) {
352 return status;
353 }
354
355 /* walk down list, checking if this type is in the list already */
356 ctype = crypto_kernel.cipher_type_list;
357 while (ctype != NULL) {
358 if (id == ctype->id) {
359 if (!replace)
360 return err_status_bad_param;
361 status = cipher_type_test(new_ct, ctype->cipher_type->test_data);
362 if (status)
363 return status;
364 new_ctype = ctype;
365 break;
366 }
367 else if (new_ct == ctype->cipher_type)
368 return err_status_bad_param;
369 ctype = ctype->next;
370 }
371
372 /* if not found, put new_ct at the head of the list */
373 if (ctype == NULL) {
374 /* allocate memory */
375 new_ctype = (kernel_cipher_type_t *) crypto_alloc(sizeof(kernel_cipher_type_ t));
376 if (new_ctype == NULL)
377 return err_status_alloc_fail;
378 new_ctype->next = crypto_kernel.cipher_type_list;
379
380 /* set head of list to new cipher type */
381 crypto_kernel.cipher_type_list = new_ctype;
382 }
383
384 /* set fields */
385 new_ctype->cipher_type = new_ct;
386 new_ctype->id = id;
387
388 /* load debug module, if there is one present */
389 if (new_ct->debug != NULL)
390 crypto_kernel_load_debug_module(new_ct->debug);
391 /* we could check for errors here */
392
393 return err_status_ok;
394 }
395
396 err_status_t
397 crypto_kernel_load_cipher_type(cipher_type_t *new_ct, cipher_type_id_t id) {
398 return crypto_kernel_do_load_cipher_type(new_ct, id, 0);
399 }
400
401 err_status_t
402 crypto_kernel_replace_cipher_type(cipher_type_t *new_ct, cipher_type_id_t id) {
403 return crypto_kernel_do_load_cipher_type(new_ct, id, 1);
404 }
405
406 err_status_t
407 crypto_kernel_do_load_auth_type(auth_type_t *new_at, auth_type_id_t id,
408 int replace) {
409 kernel_auth_type_t *atype, *new_atype;
410 err_status_t status;
411
412 /* defensive coding */
413 if (new_at == NULL)
414 return err_status_bad_param;
415
416 if (new_at->id != id)
417 return err_status_bad_param;
418
419 /* check auth type by running self-test */
420 status = auth_type_self_test(new_at);
421 if (status) {
422 return status;
423 }
424
425 /* walk down list, checking if this type is in the list already */
426 atype = crypto_kernel.auth_type_list;
427 while (atype != NULL) {
428 if (id == atype->id) {
429 if (!replace)
430 return err_status_bad_param;
431 status = auth_type_test(new_at, atype->auth_type->test_data);
432 if (status)
433 return status;
434 new_atype = atype;
435 break;
436 }
437 else if (new_at == atype->auth_type)
438 return err_status_bad_param;
439 atype = atype->next;
440 }
441
442 /* if not found, put new_at at the head of the list */
443 if (atype == NULL) {
444 /* allocate memory */
445 new_atype = (kernel_auth_type_t *)crypto_alloc(sizeof(kernel_auth_type_t));
446 if (new_atype == NULL)
447 return err_status_alloc_fail;
448
449 new_atype->next = crypto_kernel.auth_type_list;
450 /* set head of list to new auth type */
451 crypto_kernel.auth_type_list = new_atype;
452 }
453
454 /* set fields */
455 new_atype->auth_type = new_at;
456 new_atype->id = id;
457
458 /* load debug module, if there is one present */
459 if (new_at->debug != NULL)
460 crypto_kernel_load_debug_module(new_at->debug);
461 /* we could check for errors here */
462
463 return err_status_ok;
464
465 }
466
467 err_status_t
468 crypto_kernel_load_auth_type(auth_type_t *new_at, auth_type_id_t id) {
469 return crypto_kernel_do_load_auth_type(new_at, id, 0);
470 }
471
472 err_status_t
473 crypto_kernel_replace_auth_type(auth_type_t *new_at, auth_type_id_t id) {
474 return crypto_kernel_do_load_auth_type(new_at, id, 1);
475 }
476
477
478 cipher_type_t *
479 crypto_kernel_get_cipher_type(cipher_type_id_t id) {
480 kernel_cipher_type_t *ctype;
481
482 /* walk down list, looking for id */
483 ctype = crypto_kernel.cipher_type_list;
484 while (ctype != NULL) {
485 if (id == ctype->id)
486 return ctype->cipher_type;
487 ctype = ctype->next;
488 }
489
490 /* haven't found the right one, indicate failure by returning NULL */
491 return NULL;
492 }
493
494
495 err_status_t
496 crypto_kernel_alloc_cipher(cipher_type_id_t id,
497 cipher_pointer_t *cp,
498 int key_len,
499 int tag_len) {
500 cipher_type_t *ct;
501
502 /*
503 * if the crypto_kernel is not yet initialized, we refuse to allocate
504 * any ciphers - this is a bit extra-paranoid
505 */
506 if (crypto_kernel.state != crypto_kernel_state_secure)
507 return err_status_init_fail;
508
509 ct = crypto_kernel_get_cipher_type(id);
510 if (!ct)
511 return err_status_fail;
512
513 return ((ct)->alloc(cp, key_len, tag_len));
514 }
515
516
517
518 auth_type_t *
519 crypto_kernel_get_auth_type(auth_type_id_t id) {
520 kernel_auth_type_t *atype;
521
522 /* walk down list, looking for id */
523 atype = crypto_kernel.auth_type_list;
524 while (atype != NULL) {
525 if (id == atype->id)
526 return atype->auth_type;
527 atype = atype->next;
528 }
529
530 /* haven't found the right one, indicate failure by returning NULL */
531 return NULL;
532 }
533
534 err_status_t
535 crypto_kernel_alloc_auth(auth_type_id_t id,
536 auth_pointer_t *ap,
537 int key_len,
538 int tag_len) {
539 auth_type_t *at;
540
541 /*
542 * if the crypto_kernel is not yet initialized, we refuse to allocate
543 * any auth functions - this is a bit extra-paranoid
544 */
545 if (crypto_kernel.state != crypto_kernel_state_secure)
546 return err_status_init_fail;
547
548 at = crypto_kernel_get_auth_type(id);
549 if (!at)
550 return err_status_fail;
551
552 return ((at)->alloc(ap, key_len, tag_len));
553 }
554
555 err_status_t
556 crypto_kernel_load_debug_module(debug_module_t *new_dm) {
557 kernel_debug_module_t *kdm, *new;
558
559 /* defensive coding */
560 if (new_dm == NULL)
561 return err_status_bad_param;
562
563 /* walk down list, checking if this type is in the list already */
564 kdm = crypto_kernel.debug_module_list;
565 while (kdm != NULL) {
566 if (strncmp(new_dm->name, kdm->mod->name, 64) == 0)
567 return err_status_bad_param;
568 kdm = kdm->next;
569 }
570
571 /* put new_dm at the head of the list */
572 /* allocate memory */
573 new = (kernel_debug_module_t *)crypto_alloc(sizeof(kernel_debug_module_t));
574 if (new == NULL)
575 return err_status_alloc_fail;
576
577 /* set fields */
578 new->mod = new_dm;
579 new->next = crypto_kernel.debug_module_list;
580
581 /* set head of list to new cipher type */
582 crypto_kernel.debug_module_list = new;
583
584 return err_status_ok;
585 }
586
587 err_status_t
588 crypto_kernel_set_debug_module(char *name, int on) {
589 kernel_debug_module_t *kdm;
590
591 /* walk down list, checking if this type is in the list already */
592 kdm = crypto_kernel.debug_module_list;
593 while (kdm != NULL) {
594 if (strncmp(name, kdm->mod->name, 64) == 0) {
595 kdm->mod->on = on;
596 return err_status_ok;
597 }
598 kdm = kdm->next;
599 }
600
601 return err_status_fail;
602 }
603
604 err_status_t
605 crypto_get_random(unsigned char *buffer, unsigned int length) {
606 if (crypto_kernel.state == crypto_kernel_state_secure)
607 #ifdef OPENSSL
608 return rand_source_get_octet_string(buffer, length);
609 #else
610 return ctr_prng_get_octet_string(buffer, length);
611 #endif
612 else
613 return err_status_fail;
614 }
OLDNEW
« no previous file with comments | « srtp/crypto/kernel/alloc.c ('k') | srtp/crypto/kernel/err.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698