~ubuntu-branches/ubuntu/wily/sflphone/wily

« back to all changes in this revision

Viewing changes to daemon/libs/pjproject-2.0.1/third_party/srtp/crypto/kernel/crypto_kernel.c

  • Committer: Package Import Robot
  • Author(s): Mark Purcell
  • Date: 2014-01-28 18:23:36 UTC
  • mfrom: (1.1.11)
  • mto: This revision was merged to the branch mainline in revision 24.
  • Revision ID: package-import@ubuntu.com-20140128182336-3xenud1kbnwmf3mz
* New upstream release 
  - Fixes "New Upstream Release" (Closes: #735846)
  - Fixes "Ringtone does not stop" (Closes: #727164)
  - Fixes "[sflphone-kde] crash on startup" (Closes: #718178)
  - Fixes "sflphone GUI crashes when call is hung up" (Closes: #736583)
* Build-Depends: ensure GnuTLS 2.6
  - libucommon-dev (>= 6.0.7-1.1), libccrtp-dev (>= 2.0.6-3)
  - Fixes "FTBFS Build-Depends libgnutls{26,28}-dev" (Closes: #722040)
* Fix "boost 1.49 is going away" unversioned Build-Depends: (Closes: #736746)
* Add Build-Depends: libsndfile-dev, nepomuk-core-dev

Show diffs side-by-side

added added

removed removed

Lines of Context:
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, MAX_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_128_ICM);
155
 
  if (status)
156
 
    return status;
157
 
  status = crypto_kernel_load_cipher_type(&aes_cbc, AES_128_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, MAX_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
 
err_status_t
301
 
crypto_kernel_load_cipher_type(cipher_type_t *new_ct, cipher_type_id_t id) {
302
 
  kernel_cipher_type_t *ctype, *new_ctype;
303
 
  err_status_t status;
304
 
 
305
 
  /* defensive coding */
306
 
  if (new_ct == NULL)
307
 
    return err_status_bad_param;
308
 
 
309
 
  /* check cipher type by running self-test */
310
 
  status = cipher_type_self_test(new_ct);
311
 
  if (status) {
312
 
    return status;
313
 
  }
314
 
 
315
 
  /* walk down list, checking if this type is in the list already  */
316
 
  ctype = crypto_kernel.cipher_type_list;
317
 
  while (ctype != NULL) {
318
 
    if ((new_ct == ctype->cipher_type) || (id == ctype->id))
319
 
      return err_status_bad_param;
320
 
    ctype = ctype->next;
321
 
  }
322
 
 
323
 
  /* put new_ct at the head of the list */
324
 
  /* allocate memory */
325
 
  new_ctype = (kernel_cipher_type_t *) crypto_alloc(sizeof(kernel_cipher_type_t));
326
 
  if (new_ctype == NULL)
327
 
    return err_status_alloc_fail;
328
 
 
329
 
  /* set fields */
330
 
  new_ctype->cipher_type = new_ct;
331
 
  new_ctype->id = id;
332
 
  new_ctype->next = crypto_kernel.cipher_type_list;
333
 
 
334
 
  /* set head of list to new cipher type */
335
 
  crypto_kernel.cipher_type_list = new_ctype;
336
 
 
337
 
  /* load debug module, if there is one present */
338
 
  if (new_ct->debug != NULL)
339
 
    crypto_kernel_load_debug_module(new_ct->debug);
340
 
  /* we could check for errors here */
341
 
 
342
 
  return err_status_ok;
343
 
}
344
 
 
345
 
err_status_t
346
 
crypto_kernel_load_auth_type(auth_type_t *new_at, auth_type_id_t id) {
347
 
  kernel_auth_type_t *atype, *new_atype;
348
 
  err_status_t status;
349
 
 
350
 
  /* defensive coding */
351
 
  if (new_at == NULL)
352
 
    return err_status_bad_param;
353
 
 
354
 
  /* check auth type by running self-test */
355
 
  status = auth_type_self_test(new_at);
356
 
  if (status) {
357
 
    return status;
358
 
  }
359
 
 
360
 
  /* walk down list, checking if this type is in the list already  */
361
 
  atype = crypto_kernel.auth_type_list;
362
 
  while (atype != NULL) {
363
 
    if ((new_at == atype->auth_type) || (id == atype->id))
364
 
      return err_status_bad_param;
365
 
    atype = atype->next;
366
 
  }
367
 
 
368
 
  /* put new_at at the head of the list */
369
 
  /* allocate memory */
370
 
  new_atype = (kernel_auth_type_t *)crypto_alloc(sizeof(kernel_auth_type_t));
371
 
  if (new_atype == NULL)
372
 
    return err_status_alloc_fail;
373
 
 
374
 
  /* set fields */
375
 
  new_atype->auth_type = new_at;
376
 
  new_atype->id = id;
377
 
  new_atype->next = crypto_kernel.auth_type_list;
378
 
 
379
 
  /* set head of list to new auth type */
380
 
  crypto_kernel.auth_type_list = new_atype;
381
 
 
382
 
  /* load debug module, if there is one present */
383
 
  if (new_at->debug != NULL)
384
 
    crypto_kernel_load_debug_module(new_at->debug);
385
 
  /* we could check for errors here */
386
 
 
387
 
  return err_status_ok;
388
 
 
389
 
}
390
 
 
391
 
 
392
 
cipher_type_t *
393
 
crypto_kernel_get_cipher_type(cipher_type_id_t id) {
394
 
  kernel_cipher_type_t *ctype;
395
 
 
396
 
  /* walk down list, looking for id  */
397
 
  ctype = crypto_kernel.cipher_type_list;
398
 
  while (ctype != NULL) {
399
 
    if (id == ctype->id)
400
 
      return ctype->cipher_type;
401
 
    ctype = ctype->next;
402
 
  }
403
 
 
404
 
  /* haven't found the right one, indicate failure by returning NULL */
405
 
  return NULL;
406
 
}
407
 
 
408
 
 
409
 
err_status_t
410
 
crypto_kernel_alloc_cipher(cipher_type_id_t id,
411
 
                              cipher_pointer_t *cp,
412
 
                              int key_len) {
413
 
  cipher_type_t *ct;
414
 
 
415
 
  /*
416
 
   * if the crypto_kernel is not yet initialized, we refuse to allocate
417
 
   * any ciphers - this is a bit extra-paranoid
418
 
   */
419
 
  if (crypto_kernel.state != crypto_kernel_state_secure)
420
 
    return err_status_init_fail;
421
 
 
422
 
  ct = crypto_kernel_get_cipher_type(id);
423
 
  if (!ct)
424
 
    return err_status_fail;
425
 
 
426
 
  return ((ct)->alloc(cp, key_len));
427
 
}
428
 
 
429
 
 
430
 
 
431
 
auth_type_t *
432
 
crypto_kernel_get_auth_type(auth_type_id_t id) {
433
 
  kernel_auth_type_t *atype;
434
 
 
435
 
  /* walk down list, looking for id  */
436
 
  atype = crypto_kernel.auth_type_list;
437
 
  while (atype != NULL) {
438
 
    if (id == atype->id)
439
 
      return atype->auth_type;
440
 
    atype = atype->next;
441
 
  }
442
 
 
443
 
  /* haven't found the right one, indicate failure by returning NULL */
444
 
  return NULL;
445
 
}
446
 
 
447
 
err_status_t
448
 
crypto_kernel_alloc_auth(auth_type_id_t id,
449
 
                         auth_pointer_t *ap,
450
 
                         int key_len,
451
 
                         int tag_len) {
452
 
  auth_type_t *at;
453
 
 
454
 
  /*
455
 
   * if the crypto_kernel is not yet initialized, we refuse to allocate
456
 
   * any auth functions - this is a bit extra-paranoid
457
 
   */
458
 
  if (crypto_kernel.state != crypto_kernel_state_secure)
459
 
    return err_status_init_fail;
460
 
 
461
 
  at = crypto_kernel_get_auth_type(id);
462
 
  if (!at)
463
 
    return err_status_fail;
464
 
 
465
 
  return ((at)->alloc(ap, key_len, tag_len));
466
 
}
467
 
 
468
 
err_status_t
469
 
crypto_kernel_load_debug_module(debug_module_t *new_dm) {
470
 
  kernel_debug_module_t *kdm, *new;
471
 
 
472
 
  /* defensive coding */
473
 
  if (new_dm == NULL)
474
 
    return err_status_bad_param;
475
 
 
476
 
  /* walk down list, checking if this type is in the list already  */
477
 
  kdm = crypto_kernel.debug_module_list;
478
 
  while (kdm != NULL) {
479
 
    if (strncmp(new_dm->name, kdm->mod->name, 64) == 0)
480
 
      return err_status_bad_param;
481
 
    kdm = kdm->next;
482
 
  }
483
 
 
484
 
  /* put new_dm at the head of the list */
485
 
  /* allocate memory */
486
 
  new = (kernel_debug_module_t *)crypto_alloc(sizeof(kernel_debug_module_t));
487
 
  if (new == NULL)
488
 
    return err_status_alloc_fail;
489
 
 
490
 
  /* set fields */
491
 
  new->mod = new_dm;
492
 
  new->next = crypto_kernel.debug_module_list;
493
 
 
494
 
  /* set head of list to new cipher type */
495
 
  crypto_kernel.debug_module_list = new;
496
 
 
497
 
  return err_status_ok;
498
 
}
499
 
 
500
 
err_status_t
501
 
crypto_kernel_set_debug_module(char *name, int on) {
502
 
  kernel_debug_module_t *kdm;
503
 
 
504
 
  /* walk down list, checking if this type is in the list already  */
505
 
  kdm = crypto_kernel.debug_module_list;
506
 
  while (kdm != NULL) {
507
 
    if (strncmp(name, kdm->mod->name, 64) == 0) {
508
 
      kdm->mod->on = on;
509
 
      return err_status_ok;
510
 
    }
511
 
    kdm = kdm->next;
512
 
  }
513
 
 
514
 
  return err_status_fail;
515
 
}
516
 
 
517
 
err_status_t
518
 
crypto_get_random(unsigned char *buffer, unsigned int length) {
519
 
  if (crypto_kernel.state == crypto_kernel_state_secure)
520
 
    return ctr_prng_get_octet_string(buffer, length);
521
 
  else
522
 
    return err_status_fail;
523
 
}