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

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

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

Powered by Google App Engine
This is Rietveld 408576698